getJsonData(); $rules = [ 'category_id' => 'required|int', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $videoService = make(VideoService::class); $arrAds = $videoService->getAdList(AdConstrant::VIDEO_LIST); $adStep = 1; $configRepo = make(ConfigRepoistory::class); $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频. $videoRepo = make(VideoRepository::class); $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'watch', 'resolution', 'duration']; $arrData = $result = VideoModel::query() ->with(['type:type.id as type_id,type.title']) ->where(['status' => 1, 'category_id' => $inputData['category_id']]) ->orderByDesc('online_at') ->orderByDesc('created_at') ->paginate($pageSize, $columns, 'page', $page)->toArray(); $arrData['data'] = []; if (!empty($result['data'])) { foreach ($result['data'] as $k => $v) { $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); $arrData['data'][] = [ 'type' => 'v', 'video' => $v, ]; if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) { $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds); $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : ''; unset($tmpArrPlay['id']); $arrData['data'][] = [ 'type' => 'a', 'video' => $tmpArrPlay, ]; } $adStep++; } } return json_success($arrData); } /** * 首页数据 * @return mixed */ public function home() { $videoRepo = make(VideoRepository::class); $relationRepo = make(RelationRepository::class); $userCode = $this->getUserId(); $userInfo = make(UserRepository::class)->getUserInfoFromCache($userCode); $userType = null; if (isset($userInfo['is_vip']) && $userInfo['is_vip'] == 'n') { $userType = 'no_vip'; } $maxPondNum = $videoRepo->getMaxPondNum($userType); if ($maxPondNum <= 0) { // 容错,如果系统里没有任何首页非会员视频 $userType = null; $maxPondNum = $videoRepo->getMaxPondNum($userType); } $maxNum = $maxPondNum - 1; if ($maxNum < 0) { $maxNum = 0; } // $videoRepo->clearHomeVideoGroup($groupStep); // 本地开发测试,永远清理桶缓存. $groupStep = strval(rand(0, $maxNum)); // $cacheKey = VideoConstant::HOME_GROUP_CACHE_KEY_PREFIX . $groupStep; // if ($userType == 'no_vip') { // $cacheKey = VideoConstant::HOME_NOVIP_GROUP_CACHE_KEY_PREFIX . $groupStep; // } // $cacheRepo = make(CacheInterface::class); // $arrVideos = $cacheRepo->get($cacheKey, []); $arrVideos = $videoRepo->makeOneGroup($groupStep, $userType); if (!empty($arrVideos)) { foreach ($arrVideos as $k => &$v) { if ($v['type'] == 'v') { $v['video']['mu'] = ''; // $v['video']['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['mu'], $userCode, $v['video']['id'], 'video'); $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']); if (!empty($v['video']['user'])) { $v['video']['user']['avatar'] = !empty($v['video']['user']['avatar']) ? M3u8CacheRepository::getImageUrl($v['video']['user']['avatar']) : ''; } // 优化,前端每个视频单独请求详情. // if (!empty($v['video']['user'])) { // $v['video']['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($this->getUserId(), $v['video']['user']['code']); // } // $v['video']['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['video']['id']); } elseif ($v['type'] == 'a') { if (!empty($v['video']['cover'])) { $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']); } if (!empty($v['video']['link'])) { $v['video']['link'] = M3u8CacheRepository::getLinkUrl($v['video']['link'], ['user_code' => $userCode]); } if (!empty($v['video']['play'])) { $v['video']['play'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['play'], $userCode, $v['video']['id'], 'ad'); } unset($v['video']['id']); } } } return json_success($arrVideos); } /** * 视频详情 * @return mixed */ public function info( VideoService $videoService, ValidatorFactoryInterface $validatorFactory ) { $inputData = $this->getJsonData(); $rules = [ 'video_id' => 'required|int' ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $userCode = $this->getUserId(); $result = $videoService->info($inputData['video_id'], $userCode); return json_success($result); } /** * 首页关注视频 * @return mixed */ public function recommend(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $videoService = make(VideoService::class); $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME); // $arrAds = []; $adStep = 1; $configRepo = make(ConfigRepoistory::class); $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频. $videoRepo = make(VideoRepository::class); $relationRepo = make(RelationRepository::class); $userCode = $this->getUserId(); $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration']; //查找100个关注的code $relation = make(UserRelationModel::class)->db() ->find( ['from_user_id' => $this->getUserId()], ['limit' => 100] ); $arrData = []; $arrUserIds = []; $arrRelation = $relation->toArray(); if ($arrRelation) { foreach ($arrRelation as $v) { $arrUserIds[] = $v['to_user_id']; } $arrData = $result = VideoModel::query() ->with(['category:type.id as type_id,type.title','user']) ->whereIn('uid', $arrUserIds) ->where(['status' => 1]) //->orderByRaw("field(uid," . $id_str . ")") ->orderByDesc('online_at') ->orderByDesc('created_at') ->paginate($pageSize, $columns, 'page', $page)->toArray(); $arrData['data'] = []; if (!empty($result['data'])) { foreach ($result['data'] as $k => $v) { $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } $arrData['data'][] = [ 'type' => 'v', 'video' => $v, ]; if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) { $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds); $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : ''; if (!empty($tmpArrPlay['link'])) { $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]); } if (!empty($tmpArrPlay['play'])) { $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad'); } unset($tmpArrPlay['id']); $arrData['data'][] = [ 'type' => 'a', 'video' => $tmpArrPlay, ]; } $adStep++; } } } return json_success($arrData); } /** * 搜索口味 * @return mixed */ public function searchTag(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'keywords' => 'required|string|max:64', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $userCode = $this->getUserId(); $defaultPageSize = 10; $page = !empty($inputData['page']) ? intval($inputData['page']) : 1; $pageSize = !empty($inputData['page_size']) ? intval($inputData['page_size']) : $defaultPageSize; if ($pageSize > 100) { return json_fail('参数错误'); } $page = format_page($page); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $columns = ['id', 'title', 'cover', 'description']; $data = TypeModel::query() ->withCount('video') ->where('title', 'like', '%' . $inputData['keywords'] . '%') ->paginate($pageSize, $columns, 'page', $page); $data = $data->toArray(); if (!empty($data['data'])) { foreach ($data['data'] as &$v) { $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); unset($v['created_at'], $v['updated_at']); } } // 异步记录搜索记录. $jobParams = [ 'event_name' => 'tag', 'user_code' => $userCode, 'keywords' => data_get($inputData, 'keywords', ''), 'module' => 'video', ]; dispatch_job(new RecordSearchJob($jobParams)); return json_success($data); } /** * 搜索关键词推荐 * @return mixed */ public function searchTagHot() { $data = make(CacheInterface::class)->remember( 'hot_tags', 60 * 60, function () { $arrData = []; $result = TypeModel::query()->where(['is_hot' => 1, 'status' => 1]) ->withCount('upvideo') ->orderByDesc('sort') ->take(10) ->get(['id', 'title', 'cover']); // $result = TypeModel::query() // ->select(['id','title', 'cover']) // ->where('status', 1) // ->withCount('video') // ->withCount('upvideo') // ->orderByDesc('sort') // ->get(); if ($result->count() > 0) { $result = $result->toArray(); foreach ($result as $k => $v) { $arrData[] = [ 'id' => $v['id'], 'title' => $v['title'], 'cover' => M3u8CacheRepository::getImageUrl($v['cover']), 'video_count' => !empty($v['upvideo_count']) ? intval($v['upvideo_count']) : 0, //特殊处理,取上架的视频数量,不用app发新版, ]; } } return $arrData; } ); return json_success($data); } /** * 搜索视频 * @return mixed */ public function searchVideo(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'keywords' => 'required|string|max:64', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $videoService = make(VideoService::class); // $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME); $arrAds = []; $adStep = 1; $configRepo = make(ConfigRepoistory::class); $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频. $cacheRepo = make(CacheInterface::class); $cacheTimes = 2 * 60 * 60; $cacheKey = 'search:video_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', ''); $videoRepo = make(VideoRepository::class); $relationRepo = make(RelationRepository::class); $userCode = $this->getUserId(); $cacheData = $cacheRepo->get($cacheKey, []); $arrData = []; if (empty($cacheData)) { $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'mu', 'watch', 'resolution', 'duration']; $ret = VideoModel::query() ->with(['category:type.id as type_id,type.title','user']) ->where('status', 1) ->where('title', 'like', '%'. $inputData['keywords'] .'%') ->orderByDesc('online_at') ->orderByDesc('created_at') ->paginate($pageSize, $columns, 'page', $page); if ($ret->isNotEmpty()) { $result = $ret->toArray(); if (!empty($result['data'])) { $arrData = $result; $cacheRepo->set($cacheKey, $arrData, $cacheTimes); } } } else { $arrData = $cacheData; } $arrData['data'] = []; if (!empty($cacheData['data'])) { foreach ($cacheData['data'] as $k => $v) { $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } $arrData['data'][] = [ 'type' => 'v', 'video' => $v, ]; if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) { $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds); $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : ''; if (!empty($tmpArrPlay['play'])) { $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad'); } unset($tmpArrPlay['id']); $arrData['data'][] = [ 'type' => 'a', 'video' => $tmpArrPlay, ]; } $adStep++; } } // 异步记录搜索记录. $playerTypeName = 'short'; $jobParams = [ 'event_name' => 'video_'. $playerTypeName, 'user_code' => $userCode, 'keywords' => data_get($inputData, 'keywords', ''), 'module' => 'video', ]; dispatch_job(new RecordSearchJob($jobParams)); return json_success($arrData); } /** * 搜索视频 * @return mixed */ public function searchHot(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'keywords' => 'required|string', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $relationRepo = make(RelationRepository::class); $cacheRepo = make(CacheInterface::class); $cacheTimes = 2 * 60 * 60; $cacheKey = 'search:video_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', ''); $userCode = $this->getUserId(); $cacheData = $cacheRepo->get($cacheKey, []); $result = []; if (empty($cacheData)) { $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration']; $ret = VideoModel::query() ->select() ->with(['category:type.id as type_id,type.title','user']) ->where('title', 'like', '%'. $inputData['keywords'] .'%') ->where('status', 1) ->orderByDesc('online_at') ->orderByDesc('created_at') ->paginate($pageSize, $columns, 'page', $page); if ($ret->isNotEmpty()) { $result = $ret->toArray(); $cacheRepo->set($cacheKey, $result, $cacheTimes); } } if (!empty($result['data'])) { foreach ($result['data'] as $k => $v) { $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($result[$k]['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } } } // 异步记录搜索记录. $playerTypeName = 'short'; $jobParams = [ 'event_name' => 'video_'. $playerTypeName, 'user_code' => $userCode, 'keywords' => data_get($inputData, 'keywords', ''), 'module' => 'video', ]; dispatch_job(new RecordSearchJob($jobParams)); return json_success($result); } /** * 搜索视频推荐 * @return mixed */ public function searchVideoHot() { $userCode = $this->getUserId(); $relationRepo = make(RelationRepository::class); $result = make(CacheInterface::class)->remember( 'hot_video', 60 * 60, function () use ($relationRepo) { $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration']; $arrData = []; $result = VideoModel::query() ->with(['category:type.id as type_id,type.title','user']) ->where('status', 1) ->orderByDesc('like') ->limit(200) ->get($columns)->toArray(); foreach ($result as $k => $v) { // $result[$k]['mu'] = M3u8CacheRepository::getVideoUrl($result[$k]['mu']); // $v['is_my_like'] = false; if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } $arrData[$k] = [ 'type' => 'v', 'video' => $v, ]; } unset($result); return $arrData; } ); if (!empty($result)) { foreach ($result as &$v) { if ($v['type'] == 'v') { $v['video']['mu'] = ''; // 列表干掉m3u8地址. $v['video']['cover'] = M3u8CacheRepository::getImageUrl($v['video']['cover']); if (!empty($v['video']['user'])) { $v['video']['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['video']['user']['avatar']); // $v['user']['is_focus'] = false; } // $v['video']['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['video']['mu'], $userCode, $v['video']['id'], 'video'); // if (!empty($v['video']['user'])) { // $v['video']['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['video']['user']['code']); // } // $v['video']['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['video']['id']); } } } return json_success($result); } /** * 搜索视频通过标签 * @return mixed */ public function getVideoByType(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'type_id' => 'required|int', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } // $videoService = make(VideoService::class); // $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME); $arrAds = []; $adStep = 0; $configRepo = make(ConfigRepoistory::class); $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频. $videoRepo = make(VideoRepository::class); $relationRepo = make(RelationRepository::class); $userCode = $this->getUserId(); $cacheRepo = make(CacheInterface::class); $cacheTimes = 2 * 60 * 60; $cacheKey = 'search:video_by_tag_pages_'. $pageSize .':'. $page. '_' . data_get($inputData, 'keywords', ''); $cacheData = $cacheRepo->get($cacheKey, []); $arrData = $result = []; if (empty($cacheData)) { $columns = ['video.id','video.title', 'video.cover', 'video.mu', 'video.like', 'video.uid', 'video.comment', 'video.watch','video.resolution', 'video.duration']; $ret = VideoModel::query() ->leftJoin('type_video as tv', 'video.id', '=', 'tv.video_id') ->with(['category:type.id as type_id,type.title','user']) ->where('tv.type_id', $inputData['type_id']) ->where('video.status', 1) ->orderByDesc('video.online_at') ->paginate($pageSize, $columns, 'page', $page); if ($ret->isNotEmpty()) { $arrData = $result = $ret->toArray(); $cacheRepo->set($cacheKey, $result, $cacheTimes); } } else { $arrData = $cacheData; } $arrData['data'] = []; if (!empty($result['data'])) { foreach ($result['data'] as $k => $v) { $v['mu'] = ''; // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } $arrData['data'][] = [ 'type' => 'v', 'video' => $v, ]; if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) { $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds); $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : ''; if (!empty($tmpArrPlay['link'])) { $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]); } if (!empty($tmpArrPlay['play'])) { $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad'); } unset($tmpArrPlay['id']); $arrData['data'][] = [ 'type' => 'a', 'video' => $tmpArrPlay, ]; } $adStep++; } } return json_success($arrData); } /** * 搜索视频通过用户code * @return mixed */ public function userVideoList(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'code' => 'required|string', 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; $pageSize = intval($pageSize); if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $userCode = $this->getUserId(); $relationRepo = make(RelationRepository::class); $columns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'comment', 'mu', 'watch', 'resolution', 'duration']; $result = VideoModel::query() ->with(['category:type.id as type_id,type.title','user']) ->where('uid', $inputData['code']) ->where('status', 1) ->orderByDesc('online_at') ->orderByDesc('created_at') ->paginate( $pageSize, $columns, 'page', $page )->toArray(); if (!empty($result['data'])) { foreach ($result['data'] as $k => &$v) { $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } } } return json_success($result); } /** * 推送已观看的视频. * @param ValidatorFactoryInterface $validatorFactory * @return mixed */ public function pushViewed(ValidatorFactoryInterface $validatorFactory) { $inputData = $this->getJsonData(); $rules = [ 'ids' => 'required', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $userCode = $this->getUserId(); $date = Carbon::now()->toDateString(); $arrIds = []; $ids = $inputData['ids']; if (is_string($ids)) { $arrIds = explode(',', $ids); $arrIds = array_unique($arrIds); $arrIds = array_filter($arrIds); } else { $arrIds = $ids; } $count = count($arrIds); if ($count > 100) { return json_fail('too many id'); } $userInfo = make(UserRepository::class)->getUserInfoData($userCode); // 今日剩余观影次数 $videoSurplus = isset($userInfo['video_surplus']) ? $userInfo['video_surplus'] : 0; $oldSurplus = $videoSurplus; if ($userInfo['is_vip'] == 'y') { $videoSurplus = 999999; } else { // 这里只是初略计算,真实计算考异步job完成后才能计算出来. $videoSurplus = $videoSurplus - $count; $oldSurplus = $videoSurplus; } $isNegativeSurplus = false; // 是否是负数. if ($videoSurplus < 0) { // 容错. $videoSurplus = 0; $isNegativeSurplus = true; } $jobParams = []; if (!empty($arrIds)) { $absSurplus = abs($oldSurplus); foreach ($arrIds as $k => $vid) { if ($isNegativeSurplus && $k == $absSurplus) { break; } $jobParams[] = [ 'date' => $date, 'user_id' => $userInfo['id'], 'user_code' => $userInfo['code'], 'video_id' => $vid, ]; } // 异步处理. if (!empty($jobParams)) { dispatch_job(new VideoViewedJob($jobParams)); } } $resultData = [ 'video_surplus' => $videoSurplus, ]; return json_success($resultData); } // 购买视频 public function buy() { $validatorFactory = make(ValidatorFactoryInterface::class); $videoService = make(VideoService::class); $inputData = $this->getJsonData(); $rules = [ 'video_id' => 'required|int' ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $userCode = $this->getUserId(); $videoId = intval(data_get($inputData, 'video_id', 0)); $videoObj = $videoService->buyVideo($userCode, $videoId); $playMu = M3u8CacheRepository::getVideoInnerUrl($videoObj->mu, $userCode, $videoObj->id, 'video'); $result = [ 'video_id' => $videoId, 'mu' => $playMu, ]; return json_success($result); } // 我已购买的视频 public function myBoughtPages() { $validatorFactory = make(ValidatorFactoryInterface::class); $inputData = $this->getJsonData(); $rules = [ 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); if ($pageSize <= 0) { $pageSize = CommonConstant::PAGE_SIZE; } $userCode = $this->getUserId(); $user = make(UserRepository::class)->getUserInfoData($userCode); $videoColumns = ['id','title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration', 'status', 'check']; $strVideoColumns = implode(',', $videoColumns); $lists = UserBuyVideoModel::query()->with(['video:'. $strVideoColumns, 'video.user']) ->where(['user_id' => $user['id']]) ->whereHas('video', function ($q) { $q->where(['status' => 1])->with(['user']); }) ->orderBy('id', 'DESC') ->paginate($pageSize, ['*'], 'page', $page); $lists = $lists->toArray(); if (!empty($lists['data'])) { foreach ($lists['data'] as $k => $item) { $v = $item['video']; $v['user'] = $item['video']['user'] ?? null; $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']); // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); unset($v['user']['id']); } // $item['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $videoObj->id); if (!empty($v['category'])) { foreach ($v['category'] as $ck => $t) { unset($v['category'][$ck]['pivot']); } } else { $v['category'] = null; } unset($v['status'], $v['check']); $v['buy_at'] = $item['created_at']; // 购买时间. $lists['data'][$k] = $v; } } return json_success($lists); } /** * 最新视频分页. * @return mixed * @throws \Psr\SimpleCache\InvalidArgumentException */ public function lastestPages() { $userCode = $this->getUserId(); $validatorFactory = make(ValidatorFactoryInterface::class); $inputData = $this->getJsonData(); $rules = [ 'page' => 'nullable|int', 'page_size' => 'nullable|int', ]; $validator = $validatorFactory->make($inputData, $rules); if ($validator->fails()) { // 如果有错误(可能是多个信息),这里只取第一个错误信息返回. return json_fail($validator->errors()->first()); } $page = $inputData['page'] ?? 1; $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE; if ($pageSize > 100) { $pageSize = CommonConstant::PAGE_SIZE; } $page = format_page($page); $pageSize = intval($pageSize); $videoRepo = make(VideoRepository::class); // 不让前端随意传,写死10 $pageSize = VideoConstant::LASTEST_PAGE_SIZE; $arrData = []; $lists = $videoRepo->lastestPages($page, $pageSize); if (!empty($lists['data'])) { $relationRepo = make(RelationRepository::class); $videoService = make(VideoService::class); $arrAds = $videoService->getAdList(AdConstrant::VIDEO_HOME); $adStep = 1; $configRepo = make(ConfigRepoistory::class); $stepDelimiter = intval($configRepo->get('ad_delimiter_num', 'sys', 10)); // 间隔视频几个出现视频. foreach ($lists['data'] as $k => $v) { $v['mu'] = ''; // 列表干掉m3u8地址. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video'); $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']); if (!empty($v['user'])) { $v['user']['avatar'] = !empty($v['user']['avatar']) ? M3u8CacheRepository::getImageUrl($v['user']['avatar']) : ''; } if (!empty($v['user'])) { $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']); } $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']); unset($v['status'], $v['check']); $arrData[] = [ 'type' => 'v', 'video' => $v, ]; if ($k != 0 && $adStep % $stepDelimiter == 0 && !empty($arrAds)) { $tmpArrPlay = $videoRepo->getRandAdFromAds($arrAds); $tmpArrPlay['cover'] = !empty($tmpArrPlay['cover']) ? M3u8CacheRepository::getImageUrl($tmpArrPlay['cover']) : ''; if (!empty($tmpArrPlay['link'])) { $tmpArrPlay['link'] = M3u8CacheRepository::getLinkUrl($tmpArrPlay['link'], ['user_code' => $userCode]); } if (!empty($tmpArrPlay['play'])) { $tmpArrPlay['play'] = M3u8CacheRepository::getVideoInnerUrl($tmpArrPlay['play'], $userCode, $tmpArrPlay['id'], 'ad'); } unset($tmpArrPlay['id']); $arrData[] = [ 'type' => 'a', 'video' => $tmpArrPlay, ]; } $adStep++; } $lists['data'] = $arrData; } return json_success($lists); } }