VideoCollectService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  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\MemberCollectModel;
  13. use App\Models\MemberModel;
  14. use App\Models\VideoCollectModel;
  15. use App\Models\VideoModel;
  16. use App\Services\BaseService;
  17. use App\Services\RedisService;
  18. use BN\Red;
  19. use Illuminate\Support\Facades\DB;
  20. /**
  21. * 短视频收藏点赞管理-服务类
  22. * @author laravel开发员
  23. * @since 2020/11/11
  24. * @package App\Services\Api
  25. */
  26. class VideoCollectService extends BaseService
  27. {
  28. // 静态对象
  29. protected static $instance = null;
  30. /**
  31. * 构造函数
  32. * @author laravel开发员
  33. * @since 2020/11/11
  34. * MemberCollectService constructor.
  35. */
  36. public function __construct()
  37. {
  38. $this->model = new VideoCollectModel();
  39. }
  40. /**
  41. * 静态入口
  42. * @return static|null
  43. */
  44. public static function make()
  45. {
  46. if (!self::$instance) {
  47. self::$instance = (new static());
  48. }
  49. return self::$instance;
  50. }
  51. /**
  52. * 列表数据
  53. * @param $params
  54. * @param int $pageSize
  55. * @return array
  56. */
  57. public function getDataList($userId, $params, $pageSize = 15, $field='')
  58. {
  59. $where = ['a.mark' => 1,'a.status'=>1,'b.status'=>1,'b.mark'=>1];
  60. $field = $field? $field : 'lev_a.*,lev_b.id as cid,lev_b.user_id as collect_user_id,lev_a.type as collect_type';
  61. $sortType = isset($params['sort_type']) ? $params['sort_type'] : 1;
  62. $order = 'id desc';
  63. if($sortType == 1){
  64. $order = 'lev_b.create_time desc, lev_b.id desc';
  65. }
  66. $list = $this->model->with(['member'])
  67. ->from('video_collect as b')
  68. ->leftJoin('video as a', 'a.id', '=', 'b.collect_id')
  69. ->where($where)
  70. ->where(function ($query) use ($params) {
  71. $userId = isset($params['user_id']) ? $params['user_id'] : 0;
  72. if ($userId > 0) {
  73. $query->where('a.user_id', $userId);
  74. }
  75. $collectUserId = isset($params['collect_uid']) ? $params['collect_uid'] : 0;
  76. if ($collectUserId > 0) {
  77. $query->where('a.collect_uid', $collectUserId);
  78. }
  79. $isRead = isset($params['is_read'])? $params['is_read'] : 0;
  80. $isRead = $isRead>0? $isRead : 0;
  81. if ($isRead > 0) {
  82. $query->where('a.is_read', $isRead);
  83. }
  84. $type = isset($params['type'])? $params['type'] : 0;
  85. $type = $type>0? $type : 1;
  86. if ($type > 0) {
  87. $query->where('a.type', $type);
  88. }
  89. })
  90. ->where(function ($query) use ($params) {
  91. $keyword = isset($params['kw']) ? $params['kw'] : '';
  92. if ($keyword) {
  93. $query->where('a.title', 'like', "%{$keyword}%")
  94. ->orWhere('a.tags','like',"%{$keyword}%")
  95. ->orWhere('a.description','like',"%{$keyword}%");
  96. }
  97. })
  98. ->selectRaw($field)
  99. ->orderByRaw($order)
  100. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  101. $list = $list ? $list->toArray() : [];
  102. if ($list) {
  103. foreach ($list['data'] as &$item) {
  104. $item['time_text'] = isset($item['create_time']) && $item['create_time']? dateFormat($item['create_time']) : '';
  105. $item['thumb'] = isset($item['thumb']) && $item['thumb'] ? get_image_url($item['thumb']) : '';
  106. $item['file_url'] = isset($item['file_url']) && $item['file_url'] ? get_image_url($item['file_url']) : '';
  107. if(isset($item['albums'])){
  108. $albums = $item['albums']? json_decode($item['albums'], true):[];
  109. $item['albums'] = $albums? get_images_preview($albums) : [];
  110. }
  111. if(isset($item['music_url'])){
  112. $item['music_url'] = $item['music_url']? get_image_url($item['music_url']) : '';
  113. }
  114. $member = isset($item['member'])? $item['member'] : [];
  115. if($member){
  116. $member['avatar'] = isset($member['avatar'])? get_image_url($member['avatar']) : '';
  117. }
  118. $item['tags'] = isset($item['tags']) && $item['tags']? explode(',', $item['tags']) : [];
  119. $item['like_num'] = isset($item['like_num']) && $item['like_num']? format_num($item['like_num']) : 0;
  120. $item['collect_num'] = isset($item['collect_num']) && $item['collect_num']? format_num($item['collect_num']) : 0;
  121. $item['views'] = isset($item['views']) && $item['views']? format_num($item['views']) : 0;
  122. $item['member'] = $member;
  123. }
  124. }
  125. return [
  126. 'pageSize' => $pageSize,
  127. 'total' => isset($list['total']) ? $list['total'] : 0,
  128. 'list' => isset($list['data']) ? $list['data'] : []
  129. ];
  130. }
  131. /**
  132. * 是否已经收藏或点赞过
  133. * @param $userId
  134. * @param $collectUid
  135. * @param int $type 类型:
  136. * @return array|mixed
  137. */
  138. public function checkCollect($userId, $collectId, $type=1)
  139. {
  140. $cacheKey = "caches:videos:collect:u{$userId}_c{$collectId}_{$type}";
  141. $data = RedisService::get($cacheKey);
  142. if($data){
  143. return $data? 1: 2;
  144. }
  145. $data = $this->model->where(['user_id'=> $userId,'collect_id'=> $collectId,'type'=> $type,'status'=>1,'mark'=>1])->value('id');
  146. if($data){
  147. RedisService::set($cacheKey, $data, rand(5, 10));
  148. }
  149. return $data? 1 : 2;
  150. }
  151. /**
  152. * 缓存信息
  153. * @param $userId
  154. * @param $collectId
  155. * @param $type
  156. * @return array|mixed
  157. */
  158. public function getCollectCacheInfo($userId, $collectId, $type, $sourceType=1)
  159. {
  160. $cacheKey = "caches:videos:collect:temp_{$userId}_{$collectId}_{$type}_{$sourceType}";
  161. $info = RedisService::get($cacheKey);
  162. if($info || RedisService::exists($cacheKey)){
  163. return $info;
  164. }
  165. $info = $this->model->where(['user_id'=> $userId,'collect_id'=> $collectId,'source_type'=>$sourceType,'type'=> $type])->select(['id','user_id','status'])->first();
  166. $info = $info? $info->toArray() : [];
  167. if($info){
  168. RedisService::set($cacheKey, $info, rand(10,30));
  169. }
  170. return $info;
  171. }
  172. /**
  173. * 推荐数据
  174. * @param $userId 用户
  175. * @return array|mixed
  176. */
  177. public function getRecommendData($userId, $type=1)
  178. {
  179. $cacheKey = "caches:videos:recommend:{$userId}_{$type}";
  180. $data = RedisService::get($cacheKey);
  181. if($data || RedisService::exists($cacheKey)){
  182. return $data? $data : [];
  183. }
  184. $arr = ['uids'=>[$userId],'tags'=>[],'category'=>[]];
  185. $datas = $this->model->where(['user_id'=> $userId,'source_type'=> $type,'status'=>1,'mark'=>1])
  186. ->where('collect_uid','>', 0)
  187. ->select(['collect_uid','tags','category_id'])
  188. ->orderByRaw('rand()')
  189. ->limit(rand(3,5))
  190. ->get();
  191. $datas = $datas? $datas->toArray() : [];
  192. if($datas){
  193. foreach ($datas as $item)
  194. {
  195. $uid = isset($item['collect_uid'])? $item['collect_uid'] : 0;
  196. $categoryId = isset($item['category_id'])? $item['category_id'] : 0;
  197. $tags = isset($item['tags'])? explode(',', $item['tags']) : [];
  198. if($uid){
  199. $arr['uids'][] = $uid;
  200. }
  201. if($categoryId){
  202. $arr['category'][] = $categoryId;
  203. }
  204. if($tags){
  205. $tags = array_filter($tags);
  206. $arr['tags'] = array_merge($arr['tags'], $tags);
  207. $arr['tags'] = array_unique($arr['tags']);
  208. }
  209. }
  210. RedisService::set($cacheKey, $arr, rand(3600, 7200));
  211. }
  212. return $arr;
  213. }
  214. /**
  215. * 获取直播间当前用户的打赏金额和打赏排名
  216. * @param $userId 用户ID
  217. * @param $liveId 直播ID
  218. */
  219. public function getRankData($userId, $liveId)
  220. {
  221. $datas = MemberModel::from('member as a')
  222. ->leftJoin('video_collect as b',function($join) use($liveId){
  223. $join->on('a.id','=','b.user_id')
  224. ->where(['b.type'=>1,'b.collect_id'=> $liveId,'b.source_type'=>2,'b.status'=>1,'b.mark'=>1]);
  225. })
  226. ->where(['a.status'=>1,'a.mark'=>1])
  227. ->where('b.id','>', 0)
  228. ->select(['a.id','b.create_time','b.reward_total','b.collect_id as live_id'])
  229. ->groupBy('id')
  230. ->orderBy('b.reward_total','desc')
  231. ->orderBy('b.create_time','desc')
  232. ->limit(210)
  233. ->get();
  234. $datas = $datas? $datas->toArray() : [];
  235. $rankData = ['rank'=>0,'reward_total'=>0];
  236. if($datas){
  237. foreach($datas as $k => $item)
  238. {
  239. if($item['id'] == $userId){
  240. $rankData['rank'] = ($k+1) >200? 0 : ($k+1);
  241. $rankData['reward_total'] = $item['reward_total'];
  242. }
  243. }
  244. }
  245. // 用户排名在200名外的数据
  246. if($rankData['rank'] <= 0 && $rankData['reward_total']<=0 && count($datas) > 200){
  247. $rewardTotal = $this->model->where(['user_id'=> $userId,'type'=>1,'collect_id'=> $liveId,'source_type'=>2,'status'=>1,'mark'=>1])
  248. ->value('reward_total');
  249. $rankData['reward_total'] = $rewardTotal? floatval($rewardTotal) : 0;
  250. }
  251. return $rankData;
  252. }
  253. /**
  254. * 收藏点赞
  255. * @param $userId
  256. * @param $dynamicId
  257. * @param $type
  258. * @param int $status
  259. * @return mixed
  260. */
  261. public function collect($userId, $params)
  262. {
  263. try {
  264. $collectId = isset($params['id']) ? intval($params['id']) : 0;
  265. $type = isset($params['type']) ? intval($params['type']) : 2;
  266. $status = isset($params['status']) ? intval($params['status']) : 1;
  267. if ($collectId <= 0 || !in_array($type, [2, 3]) || !in_array($status, [1, 2])) {
  268. $this->error = 2014;
  269. return false;
  270. }
  271. $collectInfo = $this->getCollectCacheInfo($userId, $collectId, $type);
  272. $id = isset($collectInfo['id']) ? $collectInfo['id'] : 0;
  273. // 信息
  274. $info = VideoModel::where(['id' => $collectId, 'mark' => 1])->select(['id', 'user_id', 'tags'])->first();
  275. $collectUid = isset($info['user_id']) ? $info['user_id'] : 0;
  276. if (empty($info)) {
  277. $this->error = 1039;
  278. return false;
  279. }
  280. $data = [
  281. 'user_id' => $userId,
  282. 'type' => $type,
  283. 'source_type' => 1,
  284. 'collect_id' => $collectId,
  285. 'collect_uid' => $collectUid,
  286. 'tags' => isset($info['tags']) ? $info['tags'] : '',
  287. 'update_time' => time(),
  288. 'status' => $status,
  289. 'mark' => 1,
  290. ];
  291. DB::beginTransaction();
  292. if (!$id) {
  293. $data['create_time'] = time();
  294. if (!$this->model->insertGetId($data)) {
  295. DB::rollBack();
  296. return false;
  297. }
  298. } else {
  299. if (!$this->model->where('id', $id)->update($data)) {
  300. DB::rollBack();
  301. return false;
  302. }
  303. }
  304. $updateData = ['update_time' => time()];
  305. if ($type == 2) {
  306. $updateData['collect_num'] = DB::raw('collect_num ' . ($status == 1 ? '+ 1' : '-1'));
  307. } else if ($type == 3) {
  308. $updateData['like_num'] = DB::raw('like_num ' . ($status == 1 ? '+ 1' : '-1'));
  309. }
  310. if (!VideoModel::where(['id' => $collectId, 'mark' => 1])->update($updateData)) {
  311. DB::rollBack();
  312. return false;
  313. }
  314. $this->error = 1002;
  315. DB::commit();
  316. // 消息
  317. if($status == 1){
  318. if($type == 2){
  319. MessageService::make()->pushMessage($collectUid, '有人收藏了你的视频','有人收藏了你的视频', 5, $userId);
  320. }else if($type == 3){
  321. MessageService::make()->pushMessage($collectUid, '有人点赞了你的视频','有人点赞了你的视频', 5, $userId);
  322. }
  323. // 收藏/点赞视频任务处理
  324. TaskService::make()->updateTask($userId,$type==2?11:6, $collectId);
  325. }
  326. RedisService::clear("caches:videos:collect:u{$userId}_c{$collectId}_{$type}");
  327. RedisService::clear("caches:videos:collect:temp_{$userId}_{$collectId}_{$type}_1");
  328. RedisService::clear("caches:videos:recommend:{$userId}_1");
  329. return true;
  330. }catch (\Exception $exception){
  331. $this->error = $exception-> getMessage();
  332. return false;
  333. }
  334. }
  335. /**
  336. * 获取(被)收藏/关注/点赞数量
  337. * @param $userId 用户ID
  338. * @param int $type 类型:1-关注,2-收藏,3-点赞喜欢
  339. * @param int $ctype 查询类型:1-被关注/收藏/点赞,2-关注/收藏/点赞
  340. * @return array|mixed
  341. */
  342. public function getCount($userId, $type=1, $ctype=1)
  343. {
  344. $cacheKey = "caches:videos:collect:{$userId}_{$type}_{$ctype}";
  345. $data = RedisService::get($cacheKey);
  346. if($data){
  347. return $data;
  348. }
  349. $field = 'collect_uid';
  350. if($ctype == 2){
  351. $field = 'user_id';
  352. }
  353. $data = $this->model->where([$field=> $userId,'type'=>$type,'status'=>1,'mark'=>1])->count('id');
  354. if($data){
  355. RedisService::set($cacheKey, $data, 3600);
  356. }
  357. return $data;
  358. }
  359. /**
  360. * 取消
  361. * @param $userId
  362. * @return bool
  363. */
  364. public function cancel($userId)
  365. {
  366. // 参数
  367. $ids = request()->post('ids','');
  368. $ids = $ids? explode(',', $ids) : [];
  369. $type = request()->post('type',0);
  370. if (empty($ids) && $type == 0) {
  371. $this->error = 1033;
  372. return false;
  373. }
  374. if($type){
  375. $this->model->where(['user_id'=> $userId,'status'=>1,'mark'=>1])->update(['status'=>2,'update_time'=>time()]);
  376. }else {
  377. $this->model->where(['user_id'=> $userId,'status'=>1,'mark'=>1])->whereIn('id', $ids)->update(['status'=>2,'update_time'=>time()]);
  378. }
  379. $this->error = 1002;
  380. return true;
  381. }
  382. }