Files
amb_wechatapp/application/admin/controller/course/Course.php
T

716 lines
24 KiB
PHP

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