CourseService.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services\Api;
  12. use App\Models\ExamAccessLogModel;
  13. use App\Models\VideoCategoryModel;
  14. use App\Models\VideoCoursesModel;
  15. use App\Models\VideoModel;
  16. use App\Services\BaseService;
  17. use App\Services\ConfigService;
  18. use App\Services\RedisService;
  19. /**
  20. * 视频课服务-服务类
  21. * @author laravel开发员
  22. * @since 2020/11/11
  23. * @package App\Services\Api
  24. */
  25. class CourseService extends BaseService
  26. {
  27. // 静态对象
  28. protected static $instance = null;
  29. /**
  30. * 构造函数
  31. * @author laravel开发员
  32. * @since 2020/11/11
  33. */
  34. public function __construct()
  35. {
  36. $this->model = new VideoCoursesModel();
  37. }
  38. /**
  39. * 静态入口
  40. */
  41. public static function make()
  42. {
  43. if (!self::$instance) {
  44. self::$instance = new static();
  45. }
  46. return self::$instance;
  47. }
  48. /**
  49. * 获取
  50. * @param $type
  51. * @param int $num
  52. * @return array|mixed
  53. */
  54. public function getListByType($type, $num = 0)
  55. {
  56. $num = $num? $num : \App\Services\ConfigService::make()->getConfigByCode('show_course_num', 4);
  57. $cacheKey = "caches:videos:type_list_{$type}_{$num}";
  58. $datas = RedisService::get($cacheKey);
  59. if($datas){
  60. return $datas;
  61. }
  62. $datas = VideoModel::where(['type'=>$type,'status'=>1,'mark'=>1])
  63. ->select(['id','video_name','poster','type','description','is_recommend','status'])
  64. ->orderBy('is_recommend','asc')
  65. ->orderBy('create_time','desc')
  66. ->limit($num)
  67. ->get();
  68. $datas = $datas? $datas->toArray() : [];
  69. if($datas){
  70. foreach ($datas as &$item){
  71. $item['poster'] = $item['poster'] ? get_image_url($item['poster']) : '';
  72. }
  73. RedisService::set($cacheKey, $datas, rand(3600, 7200));
  74. }
  75. return $datas;
  76. }
  77. /**
  78. * 获取分类下视频课
  79. * @param int
  80. * @return array|mixed
  81. */
  82. public function getListByCate($params)
  83. {
  84. $type = isset($params['type'])? $params['type'] : 0;
  85. $sc = isset($params['sc'])? $params['sc'] : 0;
  86. $cacheKey = "caches:videos:list_by_cate:{$type}_".md5(json_encode($params));
  87. $datas = RedisService::get($cacheKey);
  88. // 视频课访问次数统计
  89. if(empty($sc)){
  90. ExamAccessLogModel::saveLog(date('Y-m-d'), $type, 20);
  91. }
  92. if($datas){
  93. return $datas;
  94. }
  95. //
  96. $datas = VideoCategoryModel::with(['courses'=>function($query) use($params){
  97. $kw = isset($params['keyword'])? trim($params['keyword']) : '';
  98. if($kw){
  99. $query->where(function($query) use($kw){
  100. $query->where('video_name',"like","%{$kw}%")
  101. ->orwhere('description',"like","%{$kw}%");
  102. });
  103. }
  104. $type = isset($params['type'])? intval($params['type']) : 0;
  105. if($type>0){
  106. $query->where('type',$type);
  107. }
  108. }])->distinct()
  109. ->from('videos_categorys as a')
  110. ->where(['a.status'=>1,'a.mark'=>1])
  111. ->select(['a.id','a.name','a.sort','a.icon'])
  112. ->orderBy('a.sort','desc')
  113. ->get();
  114. $datas = $datas? $datas->toArray() : [];
  115. if($datas){
  116. foreach ($datas as &$item){
  117. $item['icon'] = $item['icon']? get_image_url($item['icon']) : '';
  118. }
  119. RedisService::set($cacheKey, $datas, rand(300,600));
  120. }
  121. return $datas;
  122. }
  123. /**
  124. * 获取视频集下课程列表
  125. * @param int
  126. * @return array|mixed
  127. */
  128. public function getListByGroup($groupId,$params,$pageSize)
  129. {
  130. $page = isset($params['page'])? $params['page'] : 1;
  131. $type = isset($params['type'])? $params['type'] : 0;
  132. $cid = isset($params['cid'])? $params['cid'] : 0;
  133. $sc = isset($params['sc'])? $params['sc'] : 0;
  134. $cacheKey = "caches:videos:list_by_group:{$groupId}_{$page}_{$pageSize}_{$type}".md5(json_encode($params));
  135. $datas = RedisService::get($cacheKey);
  136. // 视频课访问次数统计
  137. if(empty($sc)){
  138. ExamAccessLogModel::saveLog(date('Y-m-d'), $type, 20);
  139. }
  140. if($datas){
  141. return $datas;
  142. }
  143. $list = $this->model->leftJoin('videos as b','b.id','=','videos_courses.video_id')
  144. ->with(['vip'])
  145. ->where(['videos_courses.video_id'=> $groupId,'videos_courses.status'=>1,'videos_courses.mark'=>1,'b.status'=>1,'b.mark'=>1])
  146. ->where(function($query) use($params){
  147. $kw = isset($params['keyword'])? trim($params['keyword']) : '';
  148. if($kw){
  149. $query->where('videos_courses.course_name',"like","%{$kw}%")
  150. ->orwhere('videos_courses.description',"like","%{$kw}%");
  151. }
  152. })
  153. ->where(function($query) use($cid){
  154. if($cid){
  155. $query->whereNotIn('videos_courses.id', [$cid]);
  156. }
  157. })
  158. ->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'])
  159. ->withCount(['courses','learns'])
  160. ->orderBy('videos_courses.sort','desc')
  161. ->orderBy('videos_courses.id','asc')
  162. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  163. $list = $list? $list->toArray() :[];
  164. if($list){
  165. foreach ($list['data'] as &$item){
  166. }
  167. }
  168. $rows = isset($list['data'])? $list['data'] : [];
  169. $datas = [
  170. 'pageSize'=> $pageSize,
  171. 'total'=> isset($list['total'])? $list['total'] : 0,
  172. 'list'=> $rows
  173. ];
  174. if($rows){
  175. RedisService::set($cacheKey, $datas, rand(300,600));
  176. }
  177. return $datas;
  178. }
  179. /**
  180. * 视频课详情
  181. * @param $userId 用户
  182. * @param $id 课程ID
  183. * @return array|mixed
  184. */
  185. public function getInfo($userId, $id)
  186. {
  187. $cacheKey = "caches:videos:info_{$userId}_{$id}";
  188. $data = RedisService::get($cacheKey, $cacheKey);
  189. if($data){
  190. return $data;
  191. }
  192. $data = $this->model->from('videos_courses as videos_courses')
  193. ->leftJoin('videos as b','b.id','=','videos_courses.video_id')
  194. /*->leftJoin('videos_learn_logs as c',function($join) use($userId){
  195. $join->on('c.course_id','=','videos_courses.id')
  196. ->where(['c.user_id'=>$userId,'c.status'=>1,'c.mark'=>1]);
  197. })*/
  198. ->with(['vip'])
  199. ->withCount(['courses','learns'])
  200. ->where(['videos_courses.id'=>$id,'videos_courses.status'=>1,'videos_courses.mark'=>1])
  201. ->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','b.type'])
  202. ->first();
  203. $data = $data? $data->toArray() : [];
  204. if($data){
  205. // 验证付费视频是否有播放权限
  206. $fee = isset($data['fee'])? $data['fee'] : 0;
  207. $buyVipData = isset($data['vip'])? $data['vip'] : [];
  208. $data['buy_vip'] = $buyVipData? 1 : 0;
  209. $data['can_play'] = $buyVipData || $fee<=0? 1 : 0;
  210. $data['preview_time'] = ConfigService::make()->getConfigByCode('course_play_preview_time', 3);
  211. // 播放
  212. RedisService::set($cacheKey, $data, rand(5, 10));
  213. }
  214. $this->model->where(['id'=> $id])->increment('views', 1);
  215. return $data;
  216. }
  217. }