FriendManager.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <?php
  2. namespace App\Managers;
  3. use App\Models\Fpdx\PairModel;
  4. use App\Models\Fpdx\RoomModel as PairRoomModel;
  5. use App\Models\Friends\FriendApply;
  6. use App\Models\Friends\FriendApplyModel;
  7. use App\Models\Friends\FriendContact;
  8. use App\Models\Friends\FriendModel;
  9. use App\Models\Goodnight\RoomModel as goodnightRoomModel;
  10. use App\Models\Gteam\RoomModel as gameRoomModel;
  11. use App\Models\NoticeModel;
  12. use App\Models\PraiseModel;
  13. use App\Models\User\LikeInviteQuestionModel;
  14. use App\Models\User\UserModel;
  15. use App\Models\Friends\LogModel;
  16. use App\Services\IM\CustomElem;
  17. use App\Utils\ImUtil;
  18. use Illuminate\Support\Facades\DB;
  19. use Illuminate\Support\Facades\Config;
  20. class FriendManager
  21. {
  22. public function makeZeroUnreadMsg(int $uid, int $contactUid)
  23. {
  24. FriendContact::where([
  25. array('uid', $uid), array('friend_uid', $contactUid)
  26. ])->update(['unread_cnt' => 0]);
  27. }
  28. /**
  29. * 是否可以IM通信
  30. * @param int $uid
  31. * @param int $contactUid
  32. * @return bool
  33. */
  34. public function canIm(int $uid, int $contactUid): bool
  35. {
  36. if (
  37. FriendContact::where([
  38. array('uid', $uid), array('friend_uid', $contactUid), array('is_blacklist', 1)
  39. ])->orWhere([
  40. array('uid', $contactUid), array('friend_uid', $uid), array('is_blacklist', 1)
  41. ])->exists()
  42. ) {
  43. return false;
  44. }
  45. return true;
  46. }
  47. /**
  48. * 成为普通联系人
  49. * @param int $uid
  50. * @param int $contactUid
  51. * @throws \Throwable
  52. */
  53. public function beContact(int $uid, int $contactUid)
  54. {
  55. $contact = FriendContact::where([
  56. array('uid', $uid), array('friend_uid', $contactUid)
  57. ])->first();
  58. if ($contact && $contact->friend_level == 2) {
  59. return;
  60. }
  61. DB::transaction(function () use ($uid, $contactUid) {
  62. FriendContact::updateOrCreate([
  63. 'uid' => $uid,
  64. 'friend_uid' => $contactUid
  65. ], [
  66. 'friend_level' => 1
  67. ]);
  68. FriendContact::updateOrCreate([
  69. 'uid' => $contactUid,
  70. 'friend_uid' => $uid
  71. ], [
  72. 'friend_level' => 1
  73. ]);
  74. });
  75. $imUtil = new ImUtil();
  76. $receiveUser = UserModel::find($contactUid, ['uid', 'im_account']);
  77. $message = new CustomElem('EventBeContact', ['Uid' => $contactUid, 'Contact' => $uid]);
  78. $imUtil->sendMessage("system_event", $receiveUser->im_account, [$message->toArray()]);
  79. $sendUser = UserModel::find($uid, ['uid', 'im_account']);
  80. $message = new CustomElem('EventBeContact', ['Uid' => $uid, 'Contact' => $contactUid]);
  81. $imUtil->sendMessage("system_event", $sendUser->im_account, [$message->toArray()]);
  82. }
  83. /**
  84. * 成为好友联系人
  85. * @param int $uid
  86. * @param int $contactUid
  87. * @throws \Throwable
  88. */
  89. public function beFriend(int $uid, int $contactUid)
  90. {
  91. DB::transaction(function () use ($uid, $contactUid) {
  92. FriendContact::updateOrCreate([
  93. 'uid' => $uid,
  94. 'friend_uid' => $contactUid
  95. ], [
  96. 'friend_level' => 2
  97. ]);
  98. FriendContact::updateOrCreate([
  99. 'uid' => $contactUid,
  100. 'friend_uid' => $uid
  101. ], [
  102. 'friend_level' => 2
  103. ]);
  104. // 清理好友申请
  105. FriendApply::where([
  106. array('uid', $uid), array('apply_uid', $contactUid)
  107. ])->orWhere([
  108. array('uid', $contactUid), array('apply_uid', $uid)
  109. ])->update(['handle' => 1]);
  110. });
  111. $imUtil = new ImUtil();
  112. $receiveUser = UserModel::find($contactUid, ['uid', 'im_account']);
  113. $message = new CustomElem('EventBeFriend', ['Uid' => $contactUid, 'Contact' => $uid]);
  114. $imUtil->sendMessage("system_event", $receiveUser->im_account, [$message->toArray()]);
  115. $sendUser = UserModel::find($uid, ['uid', 'im_account']);
  116. $message = new CustomElem('EventBeFriend', ['Uid' => $uid, 'Contact' => $contactUid]);
  117. $imUtil->sendMessage("system_event", $sendUser->im_account, [$message->toArray()]);
  118. }
  119. /**
  120. * 全部好友列表
  121. * @param int $uid
  122. * @param array $pages
  123. * @return array
  124. */
  125. public function getAllList(int $uid, array $pages): array
  126. {
  127. $total = FriendModel::where(array(['uid', $uid], ['is_hide', 0]))->count();
  128. $datas = FriendModel::where([['uid', $uid], ['is_hide', 0]])->orderBy('last_at', 'desc')
  129. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();
  130. $friend_uids = $datas->pluck('friend_uid')->toArray();
  131. $users = UserModel::whereIn('uid', $friend_uids)->get([
  132. 'uid',
  133. 'headimgurl',
  134. 'nickname',
  135. 'sex',
  136. 'weixin',
  137. 'qq',
  138. 'identity_auth',
  139. 'wx_auth',
  140. 'be_vip_at',
  141. 'supvip_endat'
  142. ]);
  143. $datas->map(function (/** @var FriendModel $data */ &$data) use ($users) {
  144. $data->setAttribute('friend', $users->where('uid', $data->friend_uid)->first());
  145. });
  146. return array(
  147. 'total' => $total,
  148. 'page' => $pages['page'],
  149. 'limit' => $pages['limit'],
  150. 'list' => $datas
  151. );
  152. }
  153. /**
  154. * 获取全部申请
  155. * @param int $uid
  156. * @param array $pages
  157. * @return array
  158. */
  159. public function getApplyAllList(int $uid, array $pages): array
  160. {
  161. $total = FriendApplyModel::where([['uid', $uid], ['is_hide', 0]])->count();
  162. $datas = FriendApplyModel::where([['uid', $uid], ['is_hide', 0]])
  163. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])
  164. ->orderByDesc('last_at')
  165. ->get();
  166. $applyUids = $datas->pluck('apply_uid')->toArray();
  167. $users = UserModel::whereIn('uid', $applyUids)->get([
  168. 'uid',
  169. 'headimgurl',
  170. 'nickname',
  171. 'sex',
  172. 'weixin',
  173. 'qq',
  174. 'identity_auth',
  175. 'wx_auth',
  176. 'be_vip_at',
  177. 'supvip_endat'
  178. ]);
  179. $datas->map(function (&$data) use ($users) {
  180. $data->apply_user = $users->where('uid', $data->apply_uid)->first();
  181. });
  182. return array(
  183. 'total' => $total,
  184. 'page' => $pages['page'],
  185. 'limit' => $pages['limit'],
  186. 'list' => $datas
  187. );
  188. }
  189. /**
  190. * 发出的好友申请
  191. * @param int $uid
  192. * @param array $pages
  193. * @return array
  194. */
  195. public function getSendList(int $uid, array $pages): array
  196. {
  197. $total = FriendApplyModel::where([['uid', $uid], ['is_apply', 1], ['is_hide', 0]])->count();
  198. $datas = FriendApplyModel::where([['uid', $uid], ['is_apply', 1], ['is_hide', 0]])
  199. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])
  200. ->orderByDesc('last_at')
  201. ->get();
  202. $toUids = $datas->pluck('apply_uid')->toArray();
  203. $users = UserModel::whereIn('uid', $toUids)->get([
  204. 'uid',
  205. 'headimgurl',
  206. 'nickname',
  207. 'sex',
  208. 'weixin',
  209. 'qq',
  210. 'identity_auth',
  211. 'wx_auth',
  212. 'be_vip_at',
  213. 'supvip_endat'
  214. ]);
  215. $datas->map(function (/** @var FriendApplyModel $data */ &$data) use ($users) {
  216. $data->setAttribute('apply_user', $users->where('uid', $data->apply_uid)->first());
  217. });
  218. return array(
  219. 'total' => $total,
  220. 'page' => $pages['page'],
  221. 'limit' => $pages['limit'],
  222. 'list' => $datas
  223. );
  224. }
  225. /**
  226. * 收到的好友申请
  227. * @param int $uid
  228. * @param array $pages
  229. * @return array
  230. */
  231. public function getReceiveList(int $uid, array $pages): array
  232. {
  233. $total = FriendApplyModel::where([['uid', $uid], ['is_receive', 1], ['is_hide', 0]])->count();
  234. $datas = FriendApplyModel::where([['uid', $uid], ['is_receive', 1], ['is_hide', 0]])
  235. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])
  236. ->orderByDesc('last_at')
  237. ->get();
  238. $toUids = $datas->pluck('apply_uid')->toArray();
  239. $users = UserModel::whereIn('uid', $toUids)->get([
  240. 'uid',
  241. 'headimgurl',
  242. 'nickname',
  243. 'sex',
  244. 'weixin',
  245. 'qq',
  246. 'identity_auth',
  247. 'wx_auth',
  248. 'be_vip_at',
  249. 'supvip_endat'
  250. ]);
  251. $datas->map(function (/** @var FriendApplyModel $data */ &$data) use ($users) {
  252. $data->setAttribute('apply_user', $users->where('uid', $data->apply_uid)->first());
  253. });
  254. return array(
  255. 'total' => $total,
  256. 'page' => $pages['page'],
  257. 'limit' => $pages['limit'],
  258. 'list' => $datas
  259. );
  260. }
  261. /**
  262. * 相互心动列表
  263. * @param int $uid
  264. * @param array $pages
  265. * @return array
  266. */
  267. public function getEachLikeList(int $uid, array $pages): array
  268. {
  269. $total = FriendModel::where(array(['uid', $uid], ['each_like', 1], ['is_hide', 0]))->count();
  270. $datas = FriendModel::where([['uid', $uid], ['each_like', 1], ['is_hide', 0]])->orderByDesc('last_at')
  271. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();
  272. $friend_uids = $datas->pluck('friend_uid')->toArray();
  273. $users = UserModel::whereIn('uid', $friend_uids)->get([
  274. 'uid',
  275. 'headimgurl',
  276. 'nickname',
  277. 'sex',
  278. 'weixin',
  279. 'qq',
  280. 'identity_auth',
  281. 'wx_auth',
  282. 'be_vip_at',
  283. 'supvip_endat'
  284. ]);
  285. $datas->map(function (/** @var FriendModel $data */ &$data) use ($users) {
  286. $data->setAttribute('friend', $users->where('uid', $data->friend_uid)->first());
  287. });
  288. return array(
  289. 'total' => $total,
  290. 'page' => $pages['page'],
  291. 'limit' => $pages['limit'],
  292. 'list' => $datas
  293. );
  294. }
  295. /**
  296. * 星标好友列表
  297. * @param int $uid
  298. * @param array $pages
  299. * @return array
  300. */
  301. public function getStarList(int $uid, array $pages): array
  302. {
  303. $total = FriendModel::where(array(['uid', $uid], ['star_at', '>', 0], ['is_hide', 0]))->count();
  304. $datas = FriendModel::where([['uid', $uid], ['star_at', '>', 0], ['is_hide', 0]])->orderByDesc('last_at')
  305. ->skip(($pages['page'] - 1) * $pages['limit'])->take($pages['limit'])->get();
  306. $friend_uids = $datas->pluck('friend_uid')->toArray();
  307. $users = UserModel::whereIn('uid', $friend_uids)->get([
  308. 'uid',
  309. 'headimgurl',
  310. 'nickname',
  311. 'sex',
  312. 'weixin',
  313. 'qq',
  314. 'identity_auth',
  315. 'wx_auth',
  316. 'be_vip_at',
  317. 'supvip_endat'
  318. ]);
  319. $datas->map(function (&$data) use ($users) {
  320. $data->friend = $users->where('uid', $data->friend_uid)->first();
  321. });
  322. return array(
  323. 'total' => $total,
  324. 'page' => $pages['page'],
  325. 'limit' => $pages['limit'],
  326. 'list' => $datas
  327. );
  328. }
  329. /**
  330. * 交互历史
  331. * @param int $uid
  332. * @param int $friend_uid
  333. * @param array $pages
  334. * @return array
  335. */
  336. public function getHistory(int $uid, int $friend_uid, array $pages)
  337. {
  338. $total = LogModel::where(array(['uid', $uid], ['tuid', $friend_uid]))
  339. ->orWhere(array(['uid', $friend_uid], ['tuid', $uid]))
  340. ->count();
  341. $datas = LogModel::where(array(['uid', $uid], ['tuid', $friend_uid]))
  342. ->orWhere(array(['uid', $friend_uid], ['tuid', $uid]))
  343. ->skip(($pages['page'] - 1) * $pages['limit'])
  344. ->take($pages['limit'])
  345. ->orderBy('created_at')
  346. ->get();
  347. $datas->map(function (/** @var LogModel $data */ &$data) use ($uid) {
  348. switch ($data->do) {
  349. case 0: // 相互心动
  350. $data->setAttribute('type', 'each_like');
  351. $data->setAttribute('app_type', 'each_like');
  352. if ($data->uid == $uid) {
  353. $data->setAttribute("msg", "恭喜!你们相互心动啦,已交换联系方式");
  354. } else {
  355. $data->setAttribute("msg", "恭喜!你们相互心动啦,已交换联系方式");
  356. }
  357. break;
  358. case 1: // 取消心动
  359. $data->setAttribute('type', 'each_like');
  360. $data->setAttribute('app_type', 'each_like');
  361. if ($data->uid == $uid) {
  362. $data->setAttribute("msg", "你取消了心动,好友关系解除");
  363. } else {
  364. $data->setAttribute("msg", "对方取消了心动,好友关系解除");
  365. }
  366. break;
  367. case 2: // 72h匹配
  368. $attach = $data->attach;
  369. /** @var PairRoomModel $room */
  370. $room = PairRoomModel::find($attach['room_id'], ['created_at', 'room_id', 'stage_id']);
  371. if (PairModel::where(['room_id' => $room->room_id])->value('activity_type') == 'qbj') {
  372. $data->setAttribute('type', 'qbj');
  373. } else {
  374. $data->setAttribute('type', 'pair');
  375. }
  376. $data->setAttribute('app_type', 'pair');
  377. $data->attach = $room;
  378. if ($data->uid == $uid) {
  379. $data->setAttribute("msg", "你们通过72小时CP相识,成为好友");
  380. } else {
  381. $data->setAttribute("msg", "你们通过72小时CP相识,成为好友");
  382. }
  383. break;
  384. case 3: // 好友申请
  385. if ($data->uid == $uid) {
  386. $data->setAttribute('type', 'my_invite');
  387. } else {
  388. $data->setAttribute('type', 'friend_invite');
  389. }
  390. if ($data->uid == $uid) {
  391. $data->setAttribute("msg", "你向ta发出了好友申请");
  392. } else {
  393. $data->setAttribute("msg", "你收到ta发出的好友申请");
  394. }
  395. $data->setAttribute('app_type', 'invalid');
  396. $attachs = $data->attach;
  397. if (is_array($attachs)) {
  398. foreach ($attachs as &$attach) {
  399. if (isset($attach['type'])) {
  400. switch ($attach['type']) {
  401. case 0: # 打招呼
  402. $data->setAttribute('app_type', 'friend_invite_hello');
  403. $data->setAttribute("msg", $attach['answer']['value']);
  404. break;
  405. case -1: # 无考验
  406. case 1: # 爆照
  407. break;
  408. case 2: # 问答
  409. $data->setAttribute('app_type', 'friend_invite_anwser');
  410. $data->setAttribute("msg", "我还回答了你的一个问题");
  411. $question = LikeInviteQuestionModel::withTrashed()->find($attach['question']);
  412. $question->question = json_decode($question->question, true);
  413. $attach['question'] = $question;
  414. break;
  415. case 3: # 接唱
  416. $data->setAttribute('app_type', 'friend_invite_sing');
  417. $data->setAttribute("msg", "我还给你唱了一首歌");
  418. $question = LikeInviteQuestionModel::withTrashed()->find($attach['question']);
  419. $question->question = json_decode($question->question, true);
  420. $attach['question'] = $question;
  421. break;
  422. case 4: # 走心一画
  423. $data->setAttribute('app_type', 'friend_invite_draw');
  424. $data->setAttribute("msg", "我还给你画了一幅画");
  425. break;
  426. default:
  427. $data->setAttribute('app_type', 'invalid');
  428. $question = LikeInviteQuestionModel::withTrashed()->find($attach['question']);
  429. $question->question = json_decode($question->question, true);
  430. $attach['question'] = $question;
  431. break;
  432. }
  433. } else {
  434. $attachs = [$attachs];
  435. break;
  436. }
  437. }
  438. }
  439. $data->attach = $attachs;
  440. break;
  441. case 4: // 同意好友申请
  442. $data->setAttribute('type', 'agree_apply');
  443. $data->setAttribute('app_type', 'agree_apply');
  444. if ($data->uid == $uid) {
  445. $data->setAttribute("msg", "你接受了对方的好友申请,成功交换联系方式");
  446. } else {
  447. $data->setAttribute("msg", "对方接受了你的好友申请,成功交换联系方式");
  448. }
  449. break;
  450. case 5: // 开黑-王者荣耀
  451. $data->setAttribute('type', 'game_wz');
  452. $data->setAttribute('app_type', 'game_wz');
  453. $attach = $data->attach;
  454. /** @var gameRoomModel $room */
  455. $room = gameRoomModel::find($attach['id'], ['id', 'created_at', 'type']);
  456. $data->attach = $room;
  457. if ($data->uid == $uid) {
  458. $data->setAttribute("msg", "你们通过组CP打王者相识,成为好友");
  459. } else {
  460. $data->setAttribute("msg", "你们通过组CP打王者相识,成为好友");
  461. }
  462. break;
  463. case 6: // 开黑-吃鸡
  464. $data->setAttribute('type', 'game_cj');
  465. $data->setAttribute('app_type', 'game_cj');
  466. $attach = $data->attach;
  467. /** @var gameRoomModel $room */
  468. $room = gameRoomModel::find($attach['id'], ['id', 'created_at', 'type']);
  469. $data->attach = $room;
  470. if ($data->uid == $uid) {
  471. $data->setAttribute("msg", "你们通过组CP玩吃鸡相识,成为好友");
  472. } else {
  473. $data->setAttribute("msg", "你们通过组CP玩吃鸡相识,成为好友");
  474. }
  475. break;
  476. case 7: // 晚安
  477. $data->setAttribute('type', 'goodnight');
  478. $data->setAttribute('app_type', 'goodnight');
  479. $attach = $data->attach;
  480. $room = goodnightRoomModel::find($attach['id'], ['id', 'created_at']);
  481. $data->attach = $room;
  482. if ($data->uid == $uid) {
  483. $data->setAttribute("msg", "你们通过晚安伴侣相识,成为好友");
  484. } else {
  485. $data->setAttribute("msg", "你们通过晚安伴侣相识,成为好友");
  486. }
  487. break;
  488. default:
  489. $data->setAttribute('app_type', 'invide');
  490. break;
  491. }
  492. });
  493. $apply_friend = FriendModel::applyOrFriend($uid, $friend_uid);
  494. // 清空未读标记
  495. FriendModel::where([['uid', $uid], ['friend_uid', $friend_uid]])->update(['unread_cnt' => 0]);
  496. FriendApplyModel::where([['uid', $uid], ['apply_uid', $friend_uid]])->update(['unread_cnt' => 0]);
  497. return array(
  498. 'apply_friend' => $apply_friend,
  499. 'total' => $total,
  500. 'page' => $pages['page'],
  501. 'limit' => $pages['limit'],
  502. 'list' => $datas
  503. );
  504. }
  505. /**
  506. * 好友列表数字 全部:未读 | 相互喜欢:未读 | 收到邀请:未读 | 发出邀请:未读
  507. * @param int $uid
  508. * @return array
  509. */
  510. public function getUnreadCount(int $uid)
  511. {
  512. /** @var UserModel $user */
  513. $user = UserModel::findOrFail($uid);
  514. // 喜欢我的
  515. /** @var PraiseModel $like_me */
  516. $like_me = PraiseModel::where([['read', 0], ['partner_id', $user->partner_id], ['type', 1]])->count();
  517. // 相互喜欢的
  518. /** @var FriendModel $model */
  519. $eachlike = FriendModel::where([['uid', $uid], ['each_like', 1], ['is_hide', 0]])->sum('unread_cnt');
  520. $invite_me = FriendApplyModel::where([
  521. ['uid', $uid],
  522. ['is_hide', 0]
  523. ])->sum('unread_cnt');
  524. $send_invite = 0;
  525. // 系统消息
  526. if (in_array(Config::get("platform"), ['ios', 'android'])) {
  527. // APP通知
  528. if (Config::get("version") < "2.17.6") {
  529. $shield = [20, 13, 14];
  530. } else {
  531. $shield = [20];
  532. }
  533. } else {
  534. // 小程序通知
  535. $shield = [5];
  536. }
  537. $sys_notice = NoticeModel::where([['uid', $uid], ['is_read', 0]])->whereIn('type', $shield)->count();
  538. // 全部好友
  539. $all = FriendModel::where([
  540. ['uid', $uid],
  541. ['is_hide', 0]
  542. ])->sum('unread_cnt');
  543. return array(
  544. 'all' => (int)$all,
  545. 'each_like' => (int)$eachlike,
  546. 'invite_me' => (int)$invite_me,
  547. 'send_invite' => (int)$send_invite,
  548. 'like_me' => (int)$like_me,
  549. 'sys_notice' => (int)$sys_notice
  550. );
  551. }
  552. }