// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\ExamAccessLogModel; use App\Models\VideoCategoryModel; use App\Models\VideoCoursesModel; use App\Models\VideoLearnLogModel; use App\Models\VideoModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; /** * 视频课服务-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class CourseService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 */ public function __construct() { $this->model = new VideoCoursesModel(); } /** * 静态入口 */ public static function make() { if (!self::$instance) { self::$instance = new static(); } return self::$instance; } /** * 获取 * @param $type * @param int $num * @return array|mixed */ public function getListByType($type, $num = 0) { $num = $num? $num : \App\Services\ConfigService::make()->getConfigByCode('show_course_num', 4); $cacheKey = "caches:videos:type_list_{$type}_{$num}"; $datas = RedisService::get($cacheKey); if($datas){ return $datas; } $datas = VideoModel::where(['type'=>$type,'status'=>1,'mark'=>1]) ->select(['id','video_name','poster','type','description','is_recommend','status']) ->orderBy('is_recommend','asc') ->orderBy('create_time','desc') ->limit($num) ->get(); $datas = $datas? $datas->toArray() : []; if($datas){ foreach ($datas as &$item){ $item['poster'] = $item['poster'] ? get_image_url($item['poster']) : ''; $item['poster_error'] = 0; } RedisService::set($cacheKey, $datas, rand(3600, 7200)); } return $datas; } /** * 获取分类下视频课 * @param int * @return array|mixed */ public function getListByCate($params) { $type = isset($params['type'])? $params['type'] : 0; $sc = isset($params['sc'])? $params['sc'] : 0; $cacheKey = "caches:videos:list_by_cate:{$type}_".md5(json_encode($params)); $datas = RedisService::get($cacheKey); // 视频课访问次数统计 if(empty($sc)){ ExamAccessLogModel::saveLog(date('Y-m-d'), $type, 20); } if($datas){ return $datas; } // $datas = VideoCategoryModel::with(['courses'=>function($query) use($params){ $kw = isset($params['keyword'])? trim($params['keyword']) : ''; if($kw){ $query->where(function($query) use($kw){ $query->where('video_name',"like","%{$kw}%") ->orwhere('description',"like","%{$kw}%"); }); } $type = isset($params['type'])? intval($params['type']) : 0; if($type>0){ $query->where('type',$type); } }])->distinct() ->from('videos_categorys as a') ->where(['a.status'=>1,'a.mark'=>1]) ->select(['a.id','a.name','a.sort','a.icon']) ->orderBy('a.sort','desc') ->get(); $datas = $datas? $datas->toArray() : []; if($datas){ foreach ($datas as &$item){ $item['icon'] = $item['icon']? get_image_url($item['icon']) : ''; } RedisService::set($cacheKey, $datas, rand(300,600)); } return $datas; } /** * 获取视频集下课程列表 * @param int * @return array|mixed */ public function getListByGroup($groupId,$params,$pageSize) { $page = isset($params['page'])? $params['page'] : 1; $type = isset($params['type'])? $params['type'] : 0; $cid = isset($params['cid'])? $params['cid'] : 0; $sc = isset($params['sc'])? $params['sc'] : 0; $cacheKey = "caches:videos:list_by_group:{$groupId}_{$page}_{$pageSize}_{$type}".md5(json_encode($params)); $datas = RedisService::get($cacheKey); // 视频课访问次数统计 if(empty($sc)){ ExamAccessLogModel::saveLog(date('Y-m-d'), $type, 20); } if($datas){ return $datas; } $list = $this->model->leftJoin('videos as b','b.id','=','videos_courses.video_id') ->with(['vip']) ->where(['videos_courses.video_id'=> $groupId,'videos_courses.status'=>1,'videos_courses.mark'=>1,'b.status'=>1,'b.mark'=>1]) ->where(function($query) use($params){ $kw = isset($params['keyword'])? trim($params['keyword']) : ''; if($kw){ $query->where('videos_courses.course_name',"like","%{$kw}%") ->orwhere('videos_courses.description',"like","%{$kw}%"); } }) ->where(function($query) use($cid){ if($cid){ $query->whereNotIn('videos_courses.id', [$cid]); } }) ->select(['videos_courses.id','videos_courses.video_id','videos_courses.course_name','videos_courses.course_url','videos_courses.fee','videos_courses.poster','videos_courses.description','videos_courses.sort']) ->withCount(['courses','learns']) ->orderBy('videos_courses.sort','desc') ->orderBy('videos_courses.id','asc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list? $list->toArray() :[]; if($list){ foreach ($list['data'] as &$item){ } } $rows = isset($list['data'])? $list['data'] : []; $datas = [ 'pageSize'=> $pageSize, 'total'=> isset($list['total'])? $list['total'] : 0, 'list'=> $rows ]; if($rows){ RedisService::set($cacheKey, $datas, rand(300,600)); } return $datas; } /** * 视频课详情 * @param $userId 用户 * @param $id 课程ID * @return array|mixed */ public function getInfo($userId, $id) { $cacheKey = "caches:videos:info_{$userId}_{$id}"; $data = RedisService::get($cacheKey, $cacheKey); if($data){ return $data; } $data = $this->model->from('videos_courses as videos_courses') ->leftJoin('videos as b','b.id','=','videos_courses.video_id') ->leftJoin('videos_learn_logs as c',function($join) use($userId){ $join->on('c.course_id','=','videos_courses.id') ->where(['c.user_id'=>$userId,'c.status'=>1,'c.mark'=>1]); }) ->with(['vip']) ->where(['videos_courses.id'=>$id,'videos_courses.status'=>1,'videos_courses.mark'=>1]) ->select(['videos_courses.id','videos_courses.video_id','videos_courses.course_name','videos_courses.course_url','videos_courses.fee','videos_courses.poster','videos_courses.description','videos_courses.sort','c.id as learn_id','b.type']) ->first(); $data = $data? $data->toArray() : []; if($data){ // 验证付费视频是否有播放权限 $fee = isset($data['fee'])? $data['fee'] : 0; $data['learn_id'] = !empty($data['learn_id'])? $data['learn_id'] : 0; $buyVipData = isset($data['vip'])? $data['vip'] : []; $data['buy_vip'] = $buyVipData? 1 : 0; $data['can_play'] = $buyVipData || $fee<=0? 1 : 0; $data['preview_time'] = ConfigService::make()->getConfigByCode('course_play_preview_time', 3); $data['courses_count'] = $this->model->where(['video_id'=> $data['video_id'],'status'=>1,'mark'=>1])->count('id'); $data['learns_count'] = VideoLearnLogModel::where(['video_id'=> $data['video_id'],'status'=>1,'mark'=>1])->count('id'); // 播放 RedisService::set($cacheKey, $data, rand(5, 10)); } $this->model->where(['id'=> $id])->increment('views', 1); return $data; } /** * 课程学习记录 * @param $userId 用户 * @param $id 课程ID * @return array|false|mixed */ public function learn($userId, $id) { $cacheKey = "caches:videos:learn_{$userId}_{$id}"; $data = RedisService::get($cacheKey, $cacheKey); if($data){ $this->error = '课程已学习过'; return $data; } $info = $this->model->where(['id'=> $id,'mark'=>1])->select(['id','video_id'])->first(); $videoId = isset($info['video_id'])? $info['video_id'] : 0; if(empty($info)){ $this->error = '课程不存在'; return false; } if($videoId<=0){ $this->error = '课程集参数错误'; return false; } // 是否已有学习记录 if($learnInfo = VideoLearnLogModel::where(['user_id'=>$userId,'course_id'=>$id,'video_id'=>$videoId])->select(['id','user_id','course_id','video_id'])->first()){ RedisService::set($cacheKey, $learnInfo->toArray(), rand(300, 600)); $this->error = '课程已学习过'; return false; } $data = ['user_id'=> $userId,'course_id'=>$id,'video_id'=>$videoId,'create_time'=>time(),'status'=>1,'mark'=>1]; $data['id'] = VideoLearnLogModel::insertGetId($data); RedisService::set($cacheKey, $data, rand(300, 600)); $this->error = '课程学习完成'; return false; } }