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']=='


'){ $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("操作成功"); } }