初始化项目:添加后端代码、ThinkPHP框架、前端资源
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
/**
|
||||
* 专栏内容绑定
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class Column extends Backend
|
||||
{
|
||||
|
||||
/**
|
||||
* Column模型对象
|
||||
* @var \app\admin\model\course\Column
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\ColumnBind;
|
||||
$this->courseModel = new \app\admin\model\course\Course;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//当前是否为关联查询
|
||||
$this->relationSearch = true;
|
||||
//设置过滤方法
|
||||
$this->request->filter(['strip_tags', 'trim']);
|
||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||
if ($this->request->request('keyField')) {
|
||||
return $this->selectpage();
|
||||
}
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
|
||||
$list = $this->model
|
||||
->with(['bindcourse'])
|
||||
->where($where)
|
||||
->order("column_bind.sort asc, column_bind.createtime {$order}")
|
||||
->select();
|
||||
|
||||
|
||||
if(!empty($list)){
|
||||
foreach ($list as $index => &$item){
|
||||
if($item['type'] == 1){
|
||||
if($item['bindcourse']['id']){
|
||||
$item['bindcourse'] = $this->courseModel->structrue($item['bindcourse'],'decode');
|
||||
}else{
|
||||
unset($list[$index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//重新给数组排序
|
||||
$list = array_values($list);
|
||||
}
|
||||
|
||||
return $this->success("获取成功",$list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param $ids
|
||||
* @return string
|
||||
* @throws DbException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($ids = null)
|
||||
{
|
||||
$row = $this->model->get($ids);
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
|
||||
$this->error(__('You have no permission'));
|
||||
}
|
||||
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
|
||||
if(isset($params['dir']) && $row['dir']!=$params['dir']){
|
||||
$params['sort'] = $this->model->defineSort($row['column_id'],$params['dir']);
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||
$row->validateFailException()->validate($validate);
|
||||
}
|
||||
$result = $row->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if (false === $result) {
|
||||
$this->error(__('No rows were updated'));
|
||||
}
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分组绑定内容
|
||||
* @param $groupId
|
||||
* @param $courseIds
|
||||
* @return mixed
|
||||
*/
|
||||
public function columnBindCourse($columnId=null,$courseIds=null,$type=null,$title=null,$p_id=null){
|
||||
|
||||
$courseIds = $courseIds ?: $this->request->post("course_ids/a");
|
||||
$columnId = $columnId ?: $this->request->post("column_id");
|
||||
$type = $type ?: $this->request->post("type",1);
|
||||
$title = $title ?: $this->request->post("title",'');
|
||||
$p_id = $p_id ?: $this->request->post("p_id",0);
|
||||
|
||||
$this->model->setColumnBindCourse($columnId,$courseIds,$p_id,$type,$title);
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取专栏绑定的内容ID
|
||||
* @param $columnId
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBindCourseId($id = null){
|
||||
$id = $id ?: $this->request->post("id/a");
|
||||
$ids = $this->model->getBindCourseId($id);
|
||||
return $this->success("获取成功",$ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换上下架
|
||||
* @param $ids
|
||||
* @param $status
|
||||
* @param $timing 是否为定时切换事件
|
||||
* @return void
|
||||
*/
|
||||
public function tryStatus($ids=null,$status=1){
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids");
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
|
||||
$status = $status ?: $this->request->post("status");
|
||||
|
||||
$pk = $this->model->getPk();
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
$row = [
|
||||
'try'=>$status
|
||||
];
|
||||
$this->model->where([
|
||||
'course_id'=>$item['course_id']
|
||||
])->update($row);
|
||||
$count++;
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
$this->error(__('未操作任何数据'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消绑定
|
||||
* @param $groupId
|
||||
* @param $courseIds
|
||||
* @return void
|
||||
*/
|
||||
public function cancelBind($ids){
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids/a");
|
||||
//是否同步从课程列表中删除关联的课程(1=同时删除课程,0=仅从专栏目录中移除)
|
||||
$deleteCourse = (int)$this->request->post("delete_course", 0);
|
||||
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
|
||||
$list = $this->model->where('id','in', $ids)->whereOr('p_id','in',$ids)->select();
|
||||
|
||||
//收集需要同步删除的课程ID(仅对实际绑定课程的目录项生效,目录节点 type!=1 跳过)
|
||||
$courseIdsToDelete = [];
|
||||
if ($deleteCourse && !empty($list)) {
|
||||
foreach ($list as $item) {
|
||||
if (isset($item['type']) && $item['type'] == 1 && !empty($item['course_id'])) {
|
||||
$courseIdsToDelete[] = (int)$item['course_id'];
|
||||
}
|
||||
}
|
||||
$courseIdsToDelete = array_values(array_unique($courseIdsToDelete));
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
$count += $item->delete();
|
||||
}
|
||||
//同步删除课程
|
||||
if ($deleteCourse && !empty($courseIdsToDelete)) {
|
||||
$courseModel = new \app\admin\model\course\Course();
|
||||
$courseList = $courseModel->where('id', 'in', $courseIdsToDelete)->select();
|
||||
foreach ($courseList as $courseItem) {
|
||||
$courseItem->delete();
|
||||
}
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
//清理课程相关缓存
|
||||
\app\common\library\cache\Clear::course();
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
$this->error(__('未移除任何数据'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排序
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function setSort($id,$type = 'up',$p_id = 0)
|
||||
{
|
||||
$self = $this->model->get($id);
|
||||
|
||||
if(!$self){
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$direction = $type == 'up' ? '<' : '>';
|
||||
$sort = $type == 'up' ? 'desc' : 'asc';
|
||||
|
||||
$brother = $this->model->where(['column_id'=>$self['column_id'],'p_id'=>$p_id])
|
||||
->where('sort',$direction,$self['sort'])
|
||||
->order('sort',$sort)
|
||||
->find();
|
||||
|
||||
if(!$brother){
|
||||
$this->error(__('无继续调节空间'));
|
||||
}
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$self['id']
|
||||
])->update([
|
||||
'sort'=>$brother['sort']
|
||||
]);
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$brother['id']
|
||||
])->update([
|
||||
'sort'=>$self['sort']
|
||||
]);
|
||||
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置排序(拖拽排序)
|
||||
* @param $sortList 排序数据数组,每项包含 id 和 sort
|
||||
* @return mixed
|
||||
*/
|
||||
public function batchSort()
|
||||
{
|
||||
$sortList = $this->request->post("sort_list/a");
|
||||
if (empty($sortList)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'sort_list'));
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($sortList as $item) {
|
||||
if (!isset($item['id']) || !isset($item['sort'])) {
|
||||
continue;
|
||||
}
|
||||
$this->model->where([
|
||||
'id' => $item['id']
|
||||
])->update([
|
||||
'sort' => $item['sort']
|
||||
]);
|
||||
$count++;
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
if ($count) {
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
$this->error(__('未操作任何数据'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
/**
|
||||
* 专栏目录
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class ColumnBind extends Backend
|
||||
{
|
||||
|
||||
/**
|
||||
* ColumnDir模型对象
|
||||
* @var \app\admin\model\course\ColumnDir
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\ColumnBind;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @return string
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (false === $this->request->isPost()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
$params['type'] = 2;
|
||||
$params['uniacid'] = UNIACID;
|
||||
$params['p_id'] = 0;
|
||||
$params['sort'] = $this->model->defineSort($params['column_id']);
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
|
||||
$this->model->validateFailException()->validate($validate);
|
||||
}
|
||||
$result = $this->model->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($result === false) {
|
||||
$this->error(__('No rows were inserted'));
|
||||
}
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param $ids
|
||||
* @return string
|
||||
* @throws DbException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($ids = null)
|
||||
{
|
||||
$row = $this->model->get($ids);
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
|
||||
$this->error(__('You have no permission'));
|
||||
}
|
||||
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
|
||||
if(isset($params['p_id'])){
|
||||
if($row['p_id'] != $params['p_id']){
|
||||
$params['sort'] = $this->model->defineSort($params['course_id'],$params['p_id']);
|
||||
}
|
||||
}
|
||||
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||
$row->validateFailException()->validate($validate);
|
||||
}
|
||||
$result = $row->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if (false === $result) {
|
||||
$this->error(__('No rows were updated'));
|
||||
}
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
/**
|
||||
* 专栏目录
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class ColumnDir extends Backend
|
||||
{
|
||||
|
||||
/**
|
||||
* ColumnDir模型对象
|
||||
* @var \app\admin\model\course\ColumnDir
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\ColumnDir;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取目录
|
||||
* @param $courseId
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDir($courseId = null){
|
||||
$courseId = $courseId ?: $this->request->post("course_id");
|
||||
$row = $this->model->courseIdGetList($courseId);
|
||||
return $this->success("获取成功",$row);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @return string
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
if (false === $this->request->isPost()) {
|
||||
return $this->view->fetch();
|
||||
}
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$params['sort'] = $this->model->defineSort($params['course_id'],$params['p_id']);
|
||||
|
||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||
$params[$this->dataLimitField] = $this->auth->id;
|
||||
}
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
|
||||
$this->model->validateFailException()->validate($validate);
|
||||
}
|
||||
$result = $this->model->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($result === false) {
|
||||
$this->error(__('No rows were inserted'));
|
||||
}
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param $ids
|
||||
* @return string
|
||||
* @throws DbException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($ids = null)
|
||||
{
|
||||
$row = $this->model->get($ids);
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
|
||||
$this->error(__('You have no permission'));
|
||||
}
|
||||
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
|
||||
if($row['p_id']!=$params['p_id']){
|
||||
$params['sort'] = $this->model->defineSort($params['course_id'],$params['p_id']);
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||
$row->validateFailException()->validate($validate);
|
||||
}
|
||||
$result = $row->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if (false === $result) {
|
||||
$this->error(__('No rows were updated'));
|
||||
}
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置排序
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function setSort($id,$type = 'up')
|
||||
{
|
||||
$self = $this->model->get($id);
|
||||
|
||||
if(!$self){
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$direction = $type == 'up' ? '<' : '>';
|
||||
$sort = $type == 'up' ? 'desc' : 'asc';
|
||||
|
||||
$brother = $this->model->where(['course_id'=>$self['course_id'],'p_id'=>$self['p_id']])
|
||||
->where('sort',$direction,$self['sort'])
|
||||
->order('sort',$sort)
|
||||
->find();
|
||||
|
||||
if(!$brother){
|
||||
$this->error(__('无继续调节空间'));
|
||||
}
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$self['id']
|
||||
])->update([
|
||||
'sort'=>$brother['sort']
|
||||
]);
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$brother['id']
|
||||
])->update([
|
||||
'sort'=>$self['sort']
|
||||
]);
|
||||
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param $ids
|
||||
* @return void
|
||||
* @throws DbException
|
||||
* @throws DataNotFoundException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function del($ids = null)
|
||||
{
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids");
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
$pk = $this->model->getPk();
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
$count += $this->model->del($item->id);
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
$this->error(__('No rows were deleted'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,715 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
use think\Cache;
|
||||
use think\Request;
|
||||
/**
|
||||
* 付费内容
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class Course extends Backend
|
||||
{
|
||||
|
||||
/**
|
||||
* Course模型对象
|
||||
* @var \app\admin\model\course\Course
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\Course;
|
||||
$this->orderModel = new \app\admin\model\order\Order;
|
||||
$this->columnBindModel = new \app\admin\model\course\ColumnBind();
|
||||
$this->groupBindModel = new \app\admin\model\course\GroupBind();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
|
||||
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
|
||||
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//当前是否为关联查询
|
||||
$this->relationSearch = false;
|
||||
//设置过滤方法
|
||||
$this->request->filter(['strip_tags', 'trim']);
|
||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||
if ($this->request->request('keyField')) {
|
||||
return $this->selectpage();
|
||||
}
|
||||
|
||||
//讲师数据隔离:强制只查自己关联的直播课程
|
||||
$lecturerCourseIds = null;
|
||||
if (\app\admin\library\Auth::instance()->isLecturer()) {
|
||||
$lecturerCourseIds = Db::name('live_lecturer')
|
||||
->where('admin_id', $this->auth->id)
|
||||
->column('course_id');
|
||||
//强制 type=live,覆盖前端传入的 type 筛选
|
||||
$lecturerFilter = json_decode(input('filter'), true);
|
||||
if (!is_array($lecturerFilter)) {
|
||||
$lecturerFilter = [];
|
||||
}
|
||||
$lecturerFilter['type'] = 'live';
|
||||
Request::instance()->post(['filter' => json_encode($lecturerFilter)]);
|
||||
}
|
||||
|
||||
//创建时间搜索格式转换
|
||||
$filterParams = json_decode(input('filter'),true);
|
||||
if(isset($filterParams['createtime']) && $filterParams['createtime']){
|
||||
$createtimeParams = explode(" - ",$filterParams['createtime']);
|
||||
if($createtimeParams && count($createtimeParams) == 2){
|
||||
$createtimeParams[0] = strtotime($createtimeParams[0]);
|
||||
$createtimeParams[1] = strtotime($createtimeParams[1]);
|
||||
//合并$createtimeParams
|
||||
$createtimeParams = implode(" - ",$createtimeParams);
|
||||
$filterParams['createtime'] = $createtimeParams;
|
||||
Request::instance()->post(['filter'=>json_encode($filterParams)]);
|
||||
}
|
||||
}
|
||||
|
||||
$whereOr = input('where_or/a',[]);
|
||||
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
|
||||
|
||||
$query =\app\common\model\goods\Handle::getGoodsQuery();
|
||||
if($whereOr){
|
||||
foreach ($whereOr as $orCondition){
|
||||
$query = $query->whereOr(function ($query) use ($orCondition,$where){
|
||||
$query->where($orCondition)->where($where);
|
||||
});
|
||||
}
|
||||
}else{
|
||||
$typeLimitWhere = [];
|
||||
if(!$filterParams || !isset($filterParams['type'])){
|
||||
$typeLimitWhere = [
|
||||
'type'=>['in',['column','video','audio','article','live']]
|
||||
];
|
||||
}
|
||||
$query = $query->where($where)->where($typeLimitWhere);
|
||||
}
|
||||
|
||||
//讲师数据隔离:只查询讲师关联的课程
|
||||
if ($lecturerCourseIds !== null) {
|
||||
if (!empty($lecturerCourseIds)) {
|
||||
$query = $query->where('id', 'in', $lecturerCourseIds);
|
||||
} else {
|
||||
$query = $query->where('id', 0);
|
||||
}
|
||||
}
|
||||
|
||||
$list = $query->order($sort, $order)->paginate($limit);
|
||||
|
||||
|
||||
$rows = $list->toArray();
|
||||
|
||||
if(!empty($rows['data'])){
|
||||
foreach ($rows['data'] as &$item){
|
||||
$item = $this->model->structrue($item,'decode');
|
||||
|
||||
if($item['type'] == 'vipcard'){
|
||||
$cardData = \app\admin\model\app\vip\Card::where([
|
||||
'id'=>$item['id']
|
||||
])->field('privilege_discount,privilege_free,privilege_discount_val')->find();
|
||||
|
||||
if($cardData){
|
||||
$item = array_merge($item,$cardData->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($item['type'] == 'live'){
|
||||
$liveData = $this->model->where([
|
||||
'id'=>$item['id']
|
||||
])->field('live_start_time,live_end_time')->find();
|
||||
|
||||
if($liveData){
|
||||
$item = array_merge($item,$liveData->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
$item['sales'] = $this->orderModel->getSales('course',$item['id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$result = array("total" => $rows['total'], "rows" => $rows['data']);
|
||||
return $this->success("获取成功",$result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @return string
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
//讲师无权新建课程
|
||||
if (\app\admin\library\Auth::instance()->isLecturer()) {
|
||||
$this->error("无权限操作");
|
||||
}
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
|
||||
$params = $this->model->structrue($params);
|
||||
|
||||
$params = $this->preExcludeFields($params);
|
||||
$this->checkParams($params);
|
||||
$params['status'] = $this->model->checkStatus($params);
|
||||
$params['updatetime'] = $params['createtime'] = time();
|
||||
$column = $params['column'];
|
||||
unset($params['column']);
|
||||
|
||||
$salesType = json_decode($params['sales_type'],true);
|
||||
if(empty($salesType) || !in_array('column',$salesType)){
|
||||
$column = [];
|
||||
}
|
||||
|
||||
$group = $params['group'];
|
||||
unset($params['group']);
|
||||
|
||||
if(isset($params['id'])){
|
||||
unset($params['id']);
|
||||
}
|
||||
|
||||
//提取讲师关联数据后移除,避免入库时触发"字段不存在"错误
|
||||
$lecturerIds = isset($params['lecturer_ids']) && is_array($params['lecturer_ids']) ? $params['lecturer_ids'] : [];
|
||||
unset($params['lecturers'], $params['lecturer_ids']);
|
||||
|
||||
if(isset($params['views'])){
|
||||
$params['views'] = 0;
|
||||
}
|
||||
|
||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||
$params[$this->dataLimitField] = $this->auth->id;
|
||||
}
|
||||
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
|
||||
$this->model->validateFailException()->validate($validate);
|
||||
}
|
||||
|
||||
$courserId = $this->model->allowField(true)->insertGetId($params);
|
||||
|
||||
if($params['type'] == 'live'){
|
||||
|
||||
$liveTime = $params['live_end_time'] - $params['live_start_time'];
|
||||
if($liveTime < 0){
|
||||
$this->error("直播结束时间需晚于开始时间");
|
||||
}
|
||||
|
||||
\app\admin\model\live\Room::buildRoom($courserId,$liveTime);
|
||||
|
||||
$liveRoomConfig = (new \app\admin\model\live\Config)->syncConfig($courserId);
|
||||
|
||||
if($liveRoomConfig['play_back_record'] == 1){
|
||||
(new \app\admin\model\live\Playback)->openLiveRecord($courserId);
|
||||
}
|
||||
}
|
||||
|
||||
//直播课程关联讲师
|
||||
if ($params['type'] == 'live' && !empty($lecturerIds)) {
|
||||
$insertData = [];
|
||||
$time = time();
|
||||
foreach ($lecturerIds as $lecturerId) {
|
||||
$insertData[] = [
|
||||
'course_id' => $courserId,
|
||||
'admin_id' => $lecturerId,
|
||||
'createtime' => $time
|
||||
];
|
||||
}
|
||||
Db::name('live_lecturer')->insertAll($insertData);
|
||||
}
|
||||
|
||||
$this->columnBindModel->setCourseBindColumn($courserId,$column);
|
||||
|
||||
//专栏目录场景:若前端透传 column_id 与 p_id(>0),则将本次新建课程在目标专栏中的绑定 p_id 同步更新
|
||||
//适用于抽屉内创建图文课程,自动将其归入指定目录
|
||||
$extraColumnId = (int)$this->request->post('column_id', 0);
|
||||
$extraPId = (int)$this->request->post('p_id', 0);
|
||||
if($extraColumnId > 0 && $extraPId > 0){
|
||||
\app\admin\model\course\ColumnBind::where([
|
||||
'column_id' => $extraColumnId,
|
||||
'course_id' => $courserId,
|
||||
])->update([
|
||||
'p_id' => $extraPId,
|
||||
'type' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->groupBindModel->setCourseBindGroup($courserId,$group);
|
||||
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($courserId === false) {
|
||||
$this->error(__('No rows were inserted'));
|
||||
}
|
||||
\app\common\library\cache\Clear::course();
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查提交的参数
|
||||
* @param $params
|
||||
* @return bool
|
||||
*/
|
||||
public function checkParams($params){
|
||||
if(empty($params['cover'])){
|
||||
$this->error("请完善封面再提交");
|
||||
}
|
||||
switch ($params['type']){
|
||||
case 'live':
|
||||
if($params['live_type'] == 2 && !$params['live_video_duration']){
|
||||
$this->error('请设置正确的伪直播视频时长');
|
||||
}
|
||||
if($params['live_type'] == 3 && empty($params['live_custom_url'])){
|
||||
$this->error('请设置自定义播流地址');
|
||||
}
|
||||
break;
|
||||
case 'video':
|
||||
if(empty($params['video_path']) || $params['video_path']=='""'){
|
||||
$this->error("请完善视频再提交");
|
||||
}
|
||||
break;
|
||||
case 'goods':
|
||||
if(empty($params['price']) || $params['price']<=0){
|
||||
$this->error("请完善商品价格再提交");
|
||||
}
|
||||
break;
|
||||
case 'article':
|
||||
if(empty($params['detail']) ||$params['detail']=='<p><br></p>'){
|
||||
$this->error("请完善详情再提交");
|
||||
}
|
||||
break;
|
||||
case 'audio':
|
||||
if(empty($params['audio_path']) || $params['audio_path']=='""'){
|
||||
$this->error("请完善音频再提交");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param $ids
|
||||
* @return string
|
||||
* @throws DbException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function edit($ids = null)
|
||||
{
|
||||
//讲师无权编辑课程
|
||||
if (\app\admin\library\Auth::instance()->isLecturer()) {
|
||||
$this->error("无权限操作");
|
||||
}
|
||||
$row = $this->model->get($ids);
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
|
||||
$this->error(__('You have no permission'));
|
||||
}
|
||||
|
||||
$params = $this->request->post('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
|
||||
$params = $this->model->structrue($params);
|
||||
|
||||
$this->checkParams($params);
|
||||
|
||||
$params = $this->preExcludeFields($params);
|
||||
$params['status'] = $this->model->checkStatus($params);
|
||||
$params['updatetime'] = time();
|
||||
|
||||
|
||||
$column = $params['column'];
|
||||
unset($params['column']);
|
||||
|
||||
$salesType = json_decode($params['sales_type'],true);
|
||||
if(empty($salesType) || !in_array('column',$salesType)){
|
||||
$column = [];
|
||||
}
|
||||
|
||||
$group = $params['group'];
|
||||
unset($params['group']);
|
||||
|
||||
//移除非数据表字段,避免入库时触发"字段不存在"错误
|
||||
unset($params['lecturers'], $params['lecturer_ids']);
|
||||
|
||||
if($params['unshelf_time'] != $row['unshelf_time']){
|
||||
$params['unshelf_timing'] = 0;
|
||||
}
|
||||
|
||||
if($params['shelf_time'] != $row['shelf_time']){
|
||||
$params['shelf_timing'] = 0;
|
||||
}
|
||||
$result = false;
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
|
||||
$row->validateFailException()->validate($validate);
|
||||
}
|
||||
|
||||
if($params['type'] == 'live'){
|
||||
|
||||
$liveTime = $params['live_end_time'] - $params['live_start_time'];
|
||||
if($liveTime < 0){
|
||||
$this->error("直播结束时间需晚于开始时间");
|
||||
}
|
||||
|
||||
$liveRoomConfig = (new \app\admin\model\live\Config)->syncConfig($row['id']);
|
||||
|
||||
if($liveRoomConfig['play_back_record'] == 1){
|
||||
(new \app\admin\model\live\Playback)->openLiveRecord($row['id']);
|
||||
}
|
||||
|
||||
//更新讲师关联:先删除旧关联,再根据 lecturer_ids 批量插入新关联
|
||||
$lecturerIds = $this->request->post('lecturer_ids/a', []);
|
||||
Db::name('live_lecturer')->where('course_id', $row['id'])->delete();
|
||||
if (!empty($lecturerIds)) {
|
||||
$insertData = [];
|
||||
$time = time();
|
||||
foreach ($lecturerIds as $lecturerId) {
|
||||
$insertData[] = [
|
||||
'course_id' => $row['id'],
|
||||
'admin_id' => $lecturerId,
|
||||
'createtime' => $time
|
||||
];
|
||||
}
|
||||
Db::name('live_lecturer')->insertAll($insertData);
|
||||
}
|
||||
}
|
||||
|
||||
$this->columnBindModel->setCourseBindColumn($row['id'],$column);
|
||||
|
||||
$this->groupBindModel->setCourseBindGroup($row['id'],$group);
|
||||
|
||||
$result = $row->allowField(true)->save($params);
|
||||
Db::commit();
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if (false === $result) {
|
||||
$this->error(__('No rows were updated'));
|
||||
}
|
||||
\app\common\library\cache\Clear::course();
|
||||
$this->success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取详情
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function detail($id)
|
||||
{
|
||||
$row = $this->model->get($id);
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
$row = $row->toArray();
|
||||
$row = $this->model->structrue($row, 'decode');
|
||||
|
||||
$row['column'] = $this->columnBindModel->getCourseBindColumn($id);
|
||||
$row['group'] = $this->groupBindModel->getCourseBindGroup($id);
|
||||
|
||||
//关联讲师
|
||||
$lecturerAdminIds = Db::name('live_lecturer')->where('course_id', $id)->column('admin_id');
|
||||
$lecturers = [];
|
||||
if (!empty($lecturerAdminIds)) {
|
||||
$lecturers = Db::name('admin')->where('id', 'in', $lecturerAdminIds)->field('id, username as name')->select();
|
||||
}
|
||||
$row['lecturers'] = $lecturers;
|
||||
|
||||
return $this->success("获取成功", $row);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 切换上下架
|
||||
* @param $ids
|
||||
* @param $status
|
||||
* @param $timing 是否为定时切换事件
|
||||
* @return void
|
||||
*/
|
||||
public function status($ids=null,$status=1,$timing = false){
|
||||
//讲师无权上下架课程
|
||||
if (\app\admin\library\Auth::instance()->isLecturer()) {
|
||||
$this->error("无权限操作");
|
||||
}
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids");
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
|
||||
$status = $status ?: $this->request->post("status");
|
||||
|
||||
$pk = $this->model->getPk();
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
$row = [
|
||||
'status'=>$status
|
||||
];
|
||||
|
||||
if($timing){
|
||||
if($status == 1){
|
||||
//定时上架 取消定时上架
|
||||
$row['shelf_timing'] = 1;
|
||||
}else{
|
||||
//定时下架
|
||||
$row['unshelf_timing'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$item['id']
|
||||
])->update($row);
|
||||
$count++;
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
|
||||
$this->error(__('未操作任何数据'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param $ids
|
||||
* @return void
|
||||
* @throws DbException
|
||||
* @throws DataNotFoundException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function del($ids = null)
|
||||
{
|
||||
//讲师无权删除课程
|
||||
if (\app\admin\library\Auth::instance()->isLecturer()) {
|
||||
$this->error("无权限操作");
|
||||
}
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids");
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
$pk = $this->model->getPk();
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
//取消在专栏、课程中的绑定
|
||||
|
||||
$this->columnBindModel->where([
|
||||
'course_id'=>$item->id
|
||||
])->delete();
|
||||
|
||||
$this->groupBindModel->where([
|
||||
'course_id'=>$item->id
|
||||
])->delete();
|
||||
|
||||
if($item->type == 'live'){
|
||||
//注意删除代码的先后顺序,先关闭录制配置,后删除房间
|
||||
(new \app\admin\model\live\Playback())->closeLiveRecord($item->id);
|
||||
\app\admin\model\live\Room::where(['course_id'=>$item->id])->delete();
|
||||
}
|
||||
$count += $item->delete();
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
\app\common\library\cache\Clear::course();
|
||||
$this->error(__('No rows were deleted'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量创建
|
||||
* @return void
|
||||
*/
|
||||
public function batch(){
|
||||
$form = $this->request->post('form/a');
|
||||
$type = $this->request->post('type');
|
||||
$files = $this->request->post('files/a');
|
||||
//专栏批量创建场景:将批量创建的课程加入指定专栏目录
|
||||
$columnId = (int)$this->request->post('column_id', 0);
|
||||
$pId = (int)$this->request->post('p_id', 0);
|
||||
|
||||
if (empty($form)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
if (empty($files)) {
|
||||
$this->error('文件不能为空');
|
||||
}
|
||||
|
||||
//记录本次批量创建出的课程ID,便于后续绑定到专栏目录
|
||||
$createdCourseIds = [];
|
||||
|
||||
//使用 files生成课程参数
|
||||
foreach ($files as $file){
|
||||
$params = $form;
|
||||
if($type == 'audio'){
|
||||
$params['video_path'] = "";
|
||||
$params['audio_path'] = $file;
|
||||
}else{
|
||||
$params['audio_path'] = "";
|
||||
$params['video_path'] = $file;
|
||||
$params['video_patch'] = $file['video_patch'];
|
||||
}
|
||||
|
||||
|
||||
$params['name'] = $file['name'];
|
||||
$params['cover'] = $file['cover'];
|
||||
$params['type'] = $type;
|
||||
|
||||
$params = $this->model->structrue($params);
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$this->checkParams($params);
|
||||
|
||||
$params['status'] = $this->model->checkStatus($params);
|
||||
$params['updatetime'] = $params['createtime'] = time();
|
||||
$column = $params['column'];
|
||||
unset($params['column']);
|
||||
|
||||
$salesType = json_decode($params['sales_type'],true);
|
||||
if(empty($salesType) || !in_array('column',$salesType)){
|
||||
$column = [];
|
||||
}
|
||||
|
||||
$group = $params['group'];
|
||||
unset($params['group']);
|
||||
|
||||
if(isset($params['id'])){
|
||||
unset($params['id']);
|
||||
}
|
||||
|
||||
if(isset($params['views'])){
|
||||
$params['views'] = 0;
|
||||
}
|
||||
|
||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||
$params[$this->dataLimitField] = $this->auth->id;
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
//是否采用模型验证
|
||||
if ($this->modelValidate) {
|
||||
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
|
||||
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
|
||||
$this->model->validateFailException()->validate($validate);
|
||||
}
|
||||
|
||||
$courserId = $this->model->allowField(true)->insertGetId($params);
|
||||
|
||||
$this->columnBindModel->setCourseBindColumn($courserId,$column);
|
||||
|
||||
$this->groupBindModel->setCourseBindGroup($courserId,$group);
|
||||
|
||||
Db::commit();
|
||||
|
||||
//收集成功创建的课程ID
|
||||
$createdCourseIds[] = (int)$courserId;
|
||||
} catch (ValidateException|PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//专栏批量创建场景:把新课程一次性加入指定专栏目录
|
||||
if ($columnId > 0 && !empty($createdCourseIds)) {
|
||||
//由于课程绑定专栏的逻辑在 setCourseBindColumn 中已用 p_id=0 写入了,
|
||||
//这里直接更新这批课程在目标专栏的绑定记录,使其归入指定父级目录
|
||||
\app\admin\model\course\ColumnBind::where([
|
||||
'column_id' => $columnId,
|
||||
])
|
||||
->where('course_id', 'in', $createdCourseIds)
|
||||
->update([
|
||||
'p_id' => $pId,
|
||||
'type' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
\app\common\library\cache\Clear::course();
|
||||
$this->success("提交成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 课程更新提醒
|
||||
* @return void
|
||||
*/
|
||||
public function updateNotice($id){
|
||||
|
||||
//消息推送收集
|
||||
\app\admin\library\app\msgpush\Msg::collect('course_update',['course_id'=>$id]);
|
||||
|
||||
$this->success("操作成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,443 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 课程分组管理
|
||||
*/
|
||||
class Group extends Backend
|
||||
{
|
||||
|
||||
protected $model = null;
|
||||
protected $groupBindModel = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\Group;
|
||||
$this->groupBindModel = new \app\admin\model\course\GroupBind();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->request->filter(['strip_tags', 'trim']);
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
|
||||
$list = $this->model
|
||||
->where($where)
|
||||
->where(['uniacid' => UNIACID])
|
||||
->order($sort, $order)
|
||||
->paginate($limit);
|
||||
|
||||
$rows = $list->toArray();
|
||||
|
||||
if (!empty($rows['data'])) {
|
||||
foreach ($rows['data'] as &$item) {
|
||||
$item['course_count'] = $this->groupBindModel->groupGetCourseBindCount($item['id']);
|
||||
}
|
||||
}
|
||||
|
||||
$result = array("total" => $rows['total'], "rows" => $rows['data'], 'attr' => [
|
||||
'status' => $this->model->getStatusList()
|
||||
]);
|
||||
|
||||
return $this->success("获取成功", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组树(4级)
|
||||
*/
|
||||
public function tree()
|
||||
{
|
||||
$list = $this->model
|
||||
->where(['uniacid' => UNIACID, 'parent_id' => 0])
|
||||
->order('sort', 'asc')
|
||||
->order('id', 'asc')
|
||||
->select();
|
||||
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$result[] = $this->getGroupTree($item);
|
||||
}
|
||||
|
||||
return $this->success("获取成功", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取分组树(4级)
|
||||
*/
|
||||
protected function getGroupTree($group)
|
||||
{
|
||||
$data = $group->toArray();
|
||||
$children = $this->model
|
||||
->where(['uniacid' => UNIACID, 'parent_id' => $group['id']])
|
||||
->order('sort', 'asc')
|
||||
->order('id', 'asc')
|
||||
->select();
|
||||
|
||||
if (!empty($children)) {
|
||||
$data['children'] = [];
|
||||
foreach ($children as $child) {
|
||||
$data['children'][] = $this->getGroupTree($child);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$params = $this->request->param('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$params['uniacid'] = UNIACID;
|
||||
$params['createtime'] = time();
|
||||
|
||||
if (!isset($params['sort'])) {
|
||||
$params['sort'] = $this->model->defineSort();
|
||||
}
|
||||
|
||||
$result = $this->model->allowField(true)->save($params);
|
||||
|
||||
if ($result !== false) {
|
||||
$this->success("添加成功");
|
||||
} else {
|
||||
$this->error(__('No rows were inserted'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
public function edit($ids = null)
|
||||
{
|
||||
$params = $this->request->param('row/a');
|
||||
if (empty($params)) {
|
||||
$this->error(__('Parameter %s can not be empty', ''));
|
||||
}
|
||||
$params = $this->preExcludeFields($params);
|
||||
|
||||
$row = $this->model->where('id', $ids)->where('uniacid', UNIACID)->find();
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$result = $row->allowField(true)->save($params);
|
||||
|
||||
if ($result !== false) {
|
||||
$this->success("更新成功");
|
||||
} else {
|
||||
$this->error(__('No rows were updated'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del($ids = "")
|
||||
{
|
||||
if ($ids) {
|
||||
// 检查是否有子分组
|
||||
$hasChildren = $this->model->where('parent_id', 'in', $ids)->where('uniacid', UNIACID)->find();
|
||||
if ($hasChildren) {
|
||||
$this->error('该分组下存在子分组,请先删除子分组');
|
||||
}
|
||||
|
||||
$count = $this->model->where('id', 'in', $ids)->where('uniacid', UNIACID)->delete();
|
||||
if ($count) {
|
||||
// 删除关联的课程绑定
|
||||
foreach (explode(',', $ids) as $id) {
|
||||
$this->groupBindModel->groupDelCourseBind($id);
|
||||
}
|
||||
$this->success("删除成功");
|
||||
} else {
|
||||
$this->error(__('No rows were deleted'));
|
||||
}
|
||||
}
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态列表
|
||||
*/
|
||||
public function getStatusList()
|
||||
{
|
||||
$this->success("获取成功", $this->model->getStatusList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID获取分组信息
|
||||
*/
|
||||
public function info($ids = null)
|
||||
{
|
||||
$row = $this->model
|
||||
->where('id', $ids)
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
|
||||
if (!$row) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$data = $row->toArray();
|
||||
|
||||
// 获取父级信息
|
||||
if ($data['parent_id'] > 0) {
|
||||
$parent = $this->model
|
||||
->where('id', $data['parent_id'])
|
||||
->where('uniacid', UNIACID)
|
||||
->find();
|
||||
$data['parent_name'] = $parent ? $parent['name'] : '';
|
||||
} else {
|
||||
$data['parent_name'] = '';
|
||||
}
|
||||
|
||||
$this->success("获取成功", $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存分组(前端完成所有操作后一次性提交)
|
||||
*
|
||||
* @param array original_ids 原始数据中的所有分组ID列表
|
||||
* @param array groups 完整的树形分组结构数据
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$originalIds = $this->request->param('original_ids/a', []);
|
||||
$groups = $this->request->param('groups/a', []);
|
||||
|
||||
if (empty($groups)) {
|
||||
$this->error('分组数据不能为空');
|
||||
}
|
||||
|
||||
// 提取当前提交的所有ID
|
||||
$currentIds = $this->extractAllIds($groups);
|
||||
|
||||
// 找出需要删除的ID(在original_ids中存在,但不在currentIds中)
|
||||
$toDelete = array_diff($originalIds, $currentIds);
|
||||
|
||||
// 分组处理数据,按层级分组(4级:0, 1, 2, 3)
|
||||
$toAdd = [0 => [], 1 => [], 2 => [], 3 => []];
|
||||
$toUpdate = [0 => [], 1 => [], 2 => [], 3 => []];
|
||||
|
||||
$this->categorizeDataByLevel($groups, $toAdd, $toUpdate);
|
||||
|
||||
// 开始事务
|
||||
Db::startTrans();
|
||||
$result = null;
|
||||
$error = null;
|
||||
|
||||
try {
|
||||
$addedCount = 0;
|
||||
$updatedCount = 0;
|
||||
$deletedCount = 0;
|
||||
|
||||
// 1. 先删除(从叶子节点开始,避免外键约束问题)
|
||||
if (!empty($toDelete)) {
|
||||
$deleteList = $this->model
|
||||
->where('id', 'in', $toDelete)
|
||||
->where('uniacid', UNIACID)
|
||||
->order('id', 'desc')
|
||||
->select();
|
||||
|
||||
foreach ($deleteList as $item) {
|
||||
$deletedCount += $this->deleteGroupRecursive($item['id']);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 更新现有数据(按层级顺序)
|
||||
$idMapping = [];
|
||||
|
||||
for ($level = 0; $level <= 3; $level++) {
|
||||
usort($toUpdate[$level], function ($a, $b) {
|
||||
return $a['sort'] - $b['sort'];
|
||||
});
|
||||
|
||||
foreach ($toUpdate[$level] as $item) {
|
||||
$id = $item['id'];
|
||||
unset($item['id']);
|
||||
unset($item['children']);
|
||||
unset($item['level']);
|
||||
|
||||
$this->model->where('id', $id)->where('uniacid', UNIACID)->update($item);
|
||||
$updatedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 新增数据 - 按原始树形结构顺序保存
|
||||
$this->saveAddedGroups($groups, $idMapping, $addedCount);
|
||||
|
||||
Db::commit();
|
||||
|
||||
$result = [
|
||||
'added' => $addedCount,
|
||||
'updated' => $updatedCount,
|
||||
'deleted' => $deletedCount,
|
||||
'id_mapping' => $idMapping
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$this->error('保存失败:' . $error);
|
||||
} else {
|
||||
$this->success('保存成功', $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归删除分组及其子分组
|
||||
*/
|
||||
protected function deleteGroupRecursive($groupId)
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
// 先删除子分组
|
||||
$children = $this->model
|
||||
->where('parent_id', $groupId)
|
||||
->where('uniacid', UNIACID)
|
||||
->column('id');
|
||||
|
||||
foreach ($children as $childId) {
|
||||
$count += $this->deleteGroupRecursive($childId);
|
||||
}
|
||||
|
||||
// 删除关联的课程绑定
|
||||
$this->groupBindModel->groupDelCourseBind($groupId);
|
||||
|
||||
// 再删除当前分组
|
||||
$count += $this->model->where('id', $groupId)->where('uniacid', UNIACID)->delete();
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从树形结构中提取所有ID
|
||||
*/
|
||||
protected function extractAllIds($groups)
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($groups as $item) {
|
||||
$ids[] = abs($item['id']);
|
||||
if (!empty($item['children'])) {
|
||||
$ids = array_merge($ids, $this->extractAllIds($item['children']));
|
||||
}
|
||||
}
|
||||
return array_unique($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据按层级分类为新增和更新(4级)
|
||||
*/
|
||||
protected function categorizeDataByLevel($groups, &$toAdd, &$toUpdate, $parentId = 0, $level = 0)
|
||||
{
|
||||
foreach ($groups as $item) {
|
||||
$currentParentId = $item['id'];
|
||||
|
||||
$item['parent_id'] = $parentId;
|
||||
$item['level'] = $level;
|
||||
|
||||
if ($item['id'] < 0) {
|
||||
$toAdd[$level][] = $item;
|
||||
} else {
|
||||
$toUpdate[$level][] = $item;
|
||||
}
|
||||
|
||||
if (!empty($item['children'])) {
|
||||
$this->categorizeDataByLevel($item['children'], $toAdd, $toUpdate, $currentParentId, $level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归保存新增分组(按原始树形结构顺序)
|
||||
*/
|
||||
protected function saveAddedGroups($groups, &$idMapping, &$addedCount, $parentId = 0)
|
||||
{
|
||||
usort($groups, function ($a, $b) {
|
||||
return $a['sort'] - $b['sort'];
|
||||
});
|
||||
|
||||
foreach ($groups as $item) {
|
||||
$isNew = $item['id'] < 0;
|
||||
|
||||
if ($isNew) {
|
||||
$tempId = $item['id'];
|
||||
|
||||
$data = [
|
||||
'name' => $item['name'],
|
||||
'parent_id' => $parentId,
|
||||
'status' => isset($item['status']) ? intval($item['status']) : 1,
|
||||
'sort' => isset($item['sort']) ? $item['sort'] : 0,
|
||||
'uniacid' => UNIACID,
|
||||
'createtime' => time(),
|
||||
];
|
||||
|
||||
$newId = $this->model->insertGetId($data);
|
||||
$idMapping[$tempId] = $newId;
|
||||
$addedCount++;
|
||||
|
||||
if (!empty($item['children'])) {
|
||||
$this->saveAddedGroups($item['children'], $idMapping, $addedCount, $newId);
|
||||
}
|
||||
} else {
|
||||
if (!empty($item['children'])) {
|
||||
$this->saveAddedGroups($item['children'], $idMapping, $addedCount, $item['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置排序
|
||||
*/
|
||||
public function setSort($id, $type = 'up')
|
||||
{
|
||||
$self = $this->model->where('id', $id)->where('uniacid', UNIACID)->find();
|
||||
|
||||
if (!$self) {
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$direction = $type == 'up' ? '<' : '>';
|
||||
$sort = $type == 'up' ? 'desc' : 'asc';
|
||||
|
||||
$brother = $this->model
|
||||
->where('sort', $direction, $self['sort'])
|
||||
->where('uniacid', UNIACID)
|
||||
->order('sort', $sort)
|
||||
->find();
|
||||
|
||||
if (!$brother) {
|
||||
$this->error(__('无继续调节空间'));
|
||||
}
|
||||
|
||||
$this->model->where([
|
||||
'id' => $self['id']
|
||||
])->update([
|
||||
'sort' => $brother['sort']
|
||||
]);
|
||||
|
||||
$this->model->where([
|
||||
'id' => $brother['id']
|
||||
])->update([
|
||||
'sort' => $self['sort']
|
||||
]);
|
||||
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller\course;
|
||||
|
||||
use app\common\controller\Backend;
|
||||
use think\Db;
|
||||
/**
|
||||
* 内容分组
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class GroupBind extends Backend
|
||||
{
|
||||
|
||||
protected $modelValidate = false;
|
||||
|
||||
/**
|
||||
* Group模型对象
|
||||
* @var \app\admin\model\course\Group
|
||||
*/
|
||||
protected $model = null;
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\admin\model\course\GroupBind();
|
||||
$this->courseModel = new \app\admin\model\course\Course;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function index($json = true)
|
||||
{
|
||||
//当前是否为关联查询
|
||||
$this->relationSearch = true;
|
||||
//设置过滤方法
|
||||
$this->request->filter(['strip_tags', 'trim']);
|
||||
//如果发送的来源是Selectpage,则转发到Selectpage
|
||||
if ($this->request->request('keyField')) {
|
||||
return $this->selectpage();
|
||||
}
|
||||
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
||||
|
||||
$list = $this->model
|
||||
->with(['course'])
|
||||
->where($where)
|
||||
->order($sort, $order)
|
||||
->limit($limit)
|
||||
->paginate($limit);
|
||||
$rows = $list->toArray();
|
||||
|
||||
if(!empty($rows['data'])){
|
||||
foreach ($rows['data'] as &$item){
|
||||
$item['course'] = $this->courseModel->structrue($item['course'],'decode');
|
||||
}
|
||||
}
|
||||
$result = array("total" => $rows['total'], "rows" => $rows['data']);
|
||||
|
||||
if($json){
|
||||
return $this->success("获取成功",$result);
|
||||
}else{
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置排序
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function setSort($id,$type = 'up')
|
||||
{
|
||||
$self = $this->model->get($id);
|
||||
|
||||
if(!$self){
|
||||
$this->error(__('No Results were found'));
|
||||
}
|
||||
|
||||
$direction = $type == 'up' ? '>' : '<';
|
||||
$sort = $type == 'up' ? 'asc' : 'desc';
|
||||
$brother = $this->model->where(['group_id'=>$self['group_id']])
|
||||
->where('sort',$direction,$self['sort'])
|
||||
->order('sort',$sort)
|
||||
->find();
|
||||
|
||||
if(!$brother){
|
||||
$this->error(__('无继续调节空间'));
|
||||
}
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$self['id']
|
||||
])->update([
|
||||
'sort'=>$brother['sort']
|
||||
]);
|
||||
|
||||
$this->model->where([
|
||||
'id'=>$brother['id']
|
||||
])->update([
|
||||
'sort'=>$self['sort']
|
||||
]);
|
||||
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param $ids
|
||||
* @return void
|
||||
* @throws DbException
|
||||
* @throws DataNotFoundException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function del($ids = null)
|
||||
{
|
||||
if (false === $this->request->isPost()) {
|
||||
$this->error(__("Invalid parameters"));
|
||||
}
|
||||
$ids = $ids ?: $this->request->post("ids");
|
||||
if (empty($ids)) {
|
||||
$this->error(__('Parameter %s can not be empty', 'ids'));
|
||||
}
|
||||
$pk = $this->model->getPk();
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$this->model->where($this->dataLimitField, 'in', $adminIds);
|
||||
}
|
||||
$list = $this->model->where($pk, 'in', $ids)->select();
|
||||
|
||||
$count = 0;
|
||||
Db::startTrans();
|
||||
try {
|
||||
foreach ($list as $item) {
|
||||
$count += $item->delete();
|
||||
}
|
||||
Db::commit();
|
||||
} catch (PDOException|Exception $e) {
|
||||
Db::rollback();
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
if ($count) {
|
||||
$this->success("操作成功");
|
||||
}
|
||||
$this->error(__('No rows were deleted'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分组绑定内容
|
||||
* @param $groupId
|
||||
* @param $courseIds
|
||||
* @return mixed
|
||||
*/
|
||||
public function groupBindCourse($groupId=null,$courseIds=null){
|
||||
$courseIds = $courseIds ?: $this->request->post("course_ids/a");
|
||||
$groupId = $groupId ?: $this->request->post("group_id");
|
||||
|
||||
$this->model->setGroupBindCourse($groupId,$courseIds);
|
||||
return $this->success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分组绑定的内容ID
|
||||
* @param $id 分组ID
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBindCourseIds($id)
|
||||
{
|
||||
$id = $id ?: $this->request->post("id");
|
||||
|
||||
$row = $this->model->getGroupBindCourse($id);
|
||||
|
||||
$this->success("操作成功",$row);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user