Modules_Api_Controllers_RelationController.proxy.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. /**
  3. * 关系api.
  4. *
  5. * @author ningque
  6. * @date 2020-02-20 02:12:58
  7. */
  8. declare (strict_types=1);
  9. namespace Modules\Api\Controllers;
  10. use App\Constants\CommonConstant;
  11. use App\Model\Mongo\UserRelationModel;
  12. use App\Model\Mongo\VideoLikeModel;
  13. use App\Model\UserModel;
  14. use App\Model\VideoModel;
  15. use App\Repositories\RelationRepository;
  16. use App\Repositories\Service\CommonService;
  17. use App\Repositories\Service\QueueService;
  18. use App\Repositories\UserLevelRelationRepository;
  19. use App\Repositories\UserRepository;
  20. use App\Repositories\Utils\M3u8CacheRepository;
  21. use Carbon\Carbon;
  22. use Hyperf\Validation\Contract\ValidatorFactoryInterface;
  23. use Modules\Api\Services\VideoService;
  24. class RelationController extends BaseController
  25. {
  26. use \Hyperf\Di\Aop\ProxyTrait;
  27. use \Hyperf\Di\Aop\PropertyHandlerTrait;
  28. function __construct()
  29. {
  30. if (method_exists(parent::class, '__construct')) {
  31. parent::__construct(...func_get_args());
  32. }
  33. $this->__handlePropertyHandler(__CLASS__);
  34. }
  35. /**
  36. * 关注/取消关注
  37. * @return mixed
  38. */
  39. public function doRelation(ValidatorFactoryInterface $validatorFactory)
  40. {
  41. $userId = $this->getUserId();
  42. $inputData = $this->getJsonData();
  43. $rules = ['to_user_id' => 'required|string'];
  44. $validator = $validatorFactory->make($inputData, $rules);
  45. if ($validator->fails()) {
  46. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  47. return json_fail($validator->errors()->first());
  48. }
  49. $toUserId = strval(data_get($inputData, 'to_user_id'));
  50. if ($userId == $toUserId) {
  51. return json_fail('自己不能关注自己');
  52. }
  53. $toUserInfo = make(UserRepository::class)->getUserInfoFromCache($toUserId);
  54. if (!$toUserInfo) {
  55. return json_fail('用户关态异常');
  56. }
  57. $favoriteKey = md5('favorite_' . $userId . '_' . $toUserId);
  58. $favoriteData = ['_id' => $favoriteKey];
  59. $favorite = make(UserRelationModel::class)->db()->countDocuments($favoriteData);
  60. $focusResult = false;
  61. if ($favorite) {
  62. //若已关注,则取消
  63. make(UserRelationModel::class)->db()->deleteOne($favoriteData);
  64. } else {
  65. $focusResult = true;
  66. //若未关注,则关注
  67. $favoriteData['from_user_id'] = $userId;
  68. $favoriteData['to_user_id'] = $toUserId;
  69. $favoriteData['date'] = Carbon::now()->toDateTimeString();
  70. make(UserRelationModel::class)->db()->insertOne($favoriteData);
  71. }
  72. make(UserRepository::class)->delUserCache($userId);
  73. make(UserRepository::class)->delUserCache($toUserId);
  74. return json_success($focusResult);
  75. }
  76. /**
  77. * 关注列表(含关注和被关注)
  78. * @return mixed
  79. */
  80. public function list(ValidatorFactoryInterface $validatorFactory)
  81. {
  82. $userId = $this->getUserId();
  83. $inputData = $this->getJsonData();
  84. $rules = ['type' => 'required|in:favorite,fans', 'page' => 'nullable|numeric', 'page_size' => 'nullable|numeric'];
  85. $validator = $validatorFactory->make($inputData, $rules);
  86. if ($validator->fails()) {
  87. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  88. return json_fail($validator->errors()->first());
  89. }
  90. $type = data_get($inputData, 'type');
  91. $page = intval(data_get($inputData, 'page', 1));
  92. $pageSize = intval(data_get($inputData, 'page_size', 10));
  93. $skip = ($page - 1) * $pageSize;
  94. if ($type == 'favorite') {
  95. $data = ['from_user_id' => $userId];
  96. } else {
  97. $data = ['to_user_id' => $userId];
  98. }
  99. $options = ['skip' => $skip, 'limit' => $pageSize, 'sort' => ['date' => -1]];
  100. $tmp = make(UserRelationModel::class)->db()->find($data, $options);
  101. $result['list'] = [];
  102. if ($tmp) {
  103. $ids = [];
  104. $needUserId = $type == 'favorite' ? 'to_user_id' : 'from_user_id';
  105. foreach ($tmp->toArray() as $t) {
  106. $ids[] = $t[$needUserId];
  107. }
  108. $result['list'] = UserModel::query()->select(['code', 'nick', 'avatar'])->whereIn('code', $ids)->get();
  109. if (!empty($result['list'])) {
  110. foreach ($result['list'] as $k => $v) {
  111. $result['list'][$k]['avatar'] = M3u8CacheRepository::getImageUrl($result['list'][$k]['avatar']);
  112. }
  113. }
  114. }
  115. return json_success($result);
  116. }
  117. /**
  118. * 我点赞过的视频分页列表.
  119. * @return mixed
  120. */
  121. public function likeVideoList(ValidatorFactoryInterface $validatorFactory)
  122. {
  123. $inputData = $this->getJsonData();
  124. $rules = [
  125. 'is_long' => 'nullable|int',
  126. // 目前只有短视频,无视这个参数.
  127. 'page' => 'nullable|numeric',
  128. 'page_size' => 'nullable|numeric',
  129. ];
  130. $validator = $validatorFactory->make($inputData, $rules);
  131. if ($validator->fails()) {
  132. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  133. return json_fail($validator->errors()->first());
  134. }
  135. $page = intval(data_get($inputData, 'page', 1));
  136. $pageSize = intval(data_get($inputData, 'page_size', 10));
  137. $skip = ($page - 1) * $pageSize;
  138. $relationRepo = make(RelationRepository::class);
  139. $userCode = $this->getUserId();
  140. $filters = ['uid' => $userCode];
  141. $amountVideo = make(VideoLikeModel::class)->db()->countDocuments($filters);
  142. $maxPages = ceil($amountVideo / $pageSize);
  143. $options = ['skip' => $skip, 'limit' => $pageSize, 'sort' => ['date' => -1]];
  144. $video_like = make(VideoLikeModel::class)->db()->find(['uid' => $userCode], $options)->toArray();
  145. $result = ['current_page' => $page, 'data' => [], 'first_page_url' => '', 'from' => null, 'last_page' => $maxPages, 'last_page_url' => '', 'next_page_url' => null, 'path' => '', 'per_page' => $pageSize, 'prev_page_url' => '', 'to' => null, 'total' => $amountVideo];
  146. $columns = ['id', 'title', 'cover', 'like', 'uid', 'coins', 'pay_type', 'mu', 'comment', 'watch', 'resolution', 'duration'];
  147. if (!empty($video_like)) {
  148. $arrIds = [];
  149. foreach ($video_like as $v) {
  150. $arrIds[] = $v['vid'];
  151. }
  152. $arrIds = array_slice($arrIds, 0, 100);
  153. // 最大100
  154. $id_str = implode(',', $arrIds);
  155. $result2 = VideoModel::query()->with(['category:type.id as type_id,type.title', 'user'])->whereIn('id', $arrIds)->where(['status' => 1])->orderByRaw('field(id,' . $id_str . ')')->get($columns);
  156. if (!empty($result2->isNotEmpty())) {
  157. $result['data'] = $result2->toArray();
  158. foreach ($result['data'] as $k => &$v) {
  159. $v['mu'] = '';
  160. // 列表干掉m3u8地址.
  161. // $v['mu'] = M3u8CacheRepository::getVideoInnerUrl($v['mu'], $userCode, $v['id'], 'video');
  162. $v['cover'] = M3u8CacheRepository::getImageUrl($v['cover']);
  163. if (!empty($v['user'])) {
  164. $v['user']['avatar'] = M3u8CacheRepository::getImageUrl($v['user']['avatar']);
  165. // $v['user']['is_focus'] = $relationRepo->userIsFocusOtherUser($userCode, $v['user']['code']);
  166. }
  167. // $v['is_my_like'] = $relationRepo->userIsLikeVideo($userCode, $v['id']);
  168. if (!empty($v['category'])) {
  169. foreach ($v['category'] as $ck => $t) {
  170. unset($v['category'][$ck]['pivot']);
  171. }
  172. }
  173. }
  174. }
  175. }
  176. return json_success($result);
  177. }
  178. /**
  179. * 视频点赞/取消点赞
  180. * @param ValidatorFactoryInterface $validatorFactory
  181. * @return mixed
  182. */
  183. public function likeVideo(ValidatorFactoryInterface $validatorFactory)
  184. {
  185. $user_code = $this->getUserId();
  186. $inputData = $this->getJsonData();
  187. $rules = ['video_id' => 'required|int'];
  188. $validator = $validatorFactory->make($inputData, $rules);
  189. if ($validator->fails()) {
  190. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  191. return json_fail($validator->errors()->first());
  192. }
  193. $videoId = intval(data_get($inputData, 'video_id', 0));
  194. $key = $user_code . '_' . $videoId;
  195. $_id = substr(md5($key), 8, 16);
  196. $data = ['_id' => $_id];
  197. $count = make(VideoLikeModel::class)->db()->countDocuments($data);
  198. if ($count) {
  199. //若已关注,则取消
  200. make(VideoLikeModel::class)->db()->deleteOne($data);
  201. make(QueueService::class)->addVideoLikeJob(['video_id' => $videoId, 'amount' => -1]);
  202. $result = 0;
  203. } else {
  204. $videoInfo = VideoModel::query()->find($videoId, ['uid'])->toArray();
  205. //若未关注,则关注
  206. $data['uid'] = $user_code;
  207. $data['vid'] = $videoId;
  208. $data['date'] = Carbon::now()->toDateTimeString();
  209. $data['video_user_uid'] = (string) $videoInfo['uid'];
  210. // 记录作者UID
  211. make(VideoLikeModel::class)->db()->insertOne($data);
  212. make(QueueService::class)->addVideoLikeJob(['video_id' => $videoId, 'amount' => 1]);
  213. $result = 1;
  214. }
  215. make(UserRepository::class)->delUserCache($user_code);
  216. return json_success($result);
  217. }
  218. public function myInvitePages(ValidatorFactoryInterface $validatorFactory)
  219. {
  220. $userCode = $this->getUserId();
  221. $inputData = $this->getJsonData();
  222. $rules = ['page' => 'nullable|numeric', 'page_size' => 'nullable|numeric'];
  223. $validator = $validatorFactory->make($inputData, $rules);
  224. if ($validator->fails()) {
  225. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  226. return json_fail($validator->errors()->first());
  227. }
  228. $page = intval(data_get($inputData, 'page', 1));
  229. $pageSize = intval(data_get($inputData, 'page_size', 10));
  230. $lists = make(UserLevelRelationRepository::class)->userInvitePages($userCode, $page, $pageSize);
  231. return json_success($lists);
  232. }
  233. public function followUserPages(ValidatorFactoryInterface $validatorFactory)
  234. {
  235. $userCode = $this->getUserId();
  236. $inputData = $this->getJsonData();
  237. $rules = ['user_code' => 'required|max:16', 'page' => 'nullable|numeric', 'page_size' => 'nullable|numeric'];
  238. $validator = $validatorFactory->make($inputData, $rules);
  239. if ($validator->fails()) {
  240. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  241. return json_fail($validator->errors()->first());
  242. }
  243. $type = 'favorite';
  244. $page = intval(data_get($inputData, 'page', 1));
  245. $pageSize = intval(data_get($inputData, 'page_size', 10));
  246. $page = format_page($page);
  247. if ($pageSize > 50) {
  248. $pageSize = CommonConstant::PAGE_SIZE;
  249. }
  250. $skip = ($page - 1) * $pageSize;
  251. $data = ['from_user_id' => $inputData['user_code']];
  252. $options = ['skip' => $skip, 'limit' => $pageSize, 'sort' => ['date' => -1]];
  253. $relationRepo = make(UserRelationModel::class);
  254. $amount = $relationRepo->db()->countDocuments($data);
  255. $lists = $relationRepo->db()->find($data, $options);
  256. $arrData = ['current_page' => $page, 'per_page' => $pageSize, 'total' => $amount, 'data' => []];
  257. if (!empty($lists)) {
  258. $arrIds = [];
  259. foreach ($lists->toArray() as $v) {
  260. $arrIds[] = $v['to_user_id'];
  261. }
  262. $columns = ['id', 'code', 'nick', 'avatar'];
  263. $users = UserModel::query()->whereIn('code', $arrIds)->get($columns);
  264. if ($users->count()) {
  265. $users = $users->toArray();
  266. foreach ($users as $v) {
  267. $videoCount = VideoModel::query()->where(['uid' => $v['code'], 'status' => 1])->count();
  268. $arrData['data'][] = ['user_code' => $v['code'], 'nick' => $v['nick'], 'avatar' => M3u8CacheRepository::getImageUrl($v['avatar']), 'video_count' => $videoCount];
  269. }
  270. }
  271. }
  272. return json_success($arrData);
  273. }
  274. }