FriendsListUnreadMsgService.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <?php
  2. /**
  3. * 好友列表未读消息通知
  4. * 「收到心动邀请未读 + 发出心动邀请被接受未读 + 相互心动未读」
  5. * User: easyboom
  6. * Date: 2019/5/22
  7. * Time: 上午10:04
  8. */
  9. namespace App\Services\Notice;
  10. use App\Http\Controllers\Miniprogram\Core;
  11. use App\Http\Controllers\Wechat\Kfaccount;
  12. use App\Models\Deed\EachLikeModel;
  13. use App\Models\Deed\InvitationCardModel;
  14. use App\Models\User\Openid;
  15. use App\Models\User\UserModel;
  16. use App\Services\Deed\FriendService;
  17. use App\Services\Log\NoticeLogService;
  18. use App\Services\Service;
  19. use Illuminate\Support\Facades\Redis;
  20. class FriendsListUnreadMsgService extends Service
  21. {
  22. // 每天2点加载(如:5-5)
  23. public function loadSendQueue()
  24. {
  25. $arrays = array();
  26. // 获取三天前(5-1)未读的消息
  27. $day = mktime(0, 0, 0) - 86400 * 4;
  28. EachLikeModel::where([['state', 1], ['read_at', 0]])->whereBetween('updated_at', [$day, $day + 86400])
  29. ->get()->map(function ($eachlike) use (&$arrays) {
  30. $arrays[$eachlike->tuid]['uid'] = $eachlike->tuid;
  31. empty($arrays[$eachlike->tuid]['eachlike']) && $arrays[$eachlike->tuid]['eachlike'] = [];
  32. array_push($arrays[$eachlike->tuid]['eachlike'], $eachlike->id);
  33. });
  34. InvitationCardModel::where([['send_read', 0]])->whereBetween('created_at', [$day, $day + 86400])
  35. ->get()->map(function ($send_invite) use (&$arrays) {
  36. $arrays[$send_invite->uid]['uid'] = $send_invite->uid;
  37. empty($arrays[$send_invite->uid]['send_invite']) && $arrays[$send_invite->uid]['send_invite'] = [];
  38. array_push($arrays[$send_invite->uid]['send_invite'], $send_invite->id);
  39. });
  40. // 获取两天前(5-2)未读的消息
  41. $day = mktime(0, 0, 0) - 86400 * 3;
  42. EachLikeModel::where([['state', 1], ['read_at', 0]])->whereBetween('updated_at', [$day, $day + 86400])
  43. ->get()->map(function ($eachlike) use (&$arrays) {
  44. $arrays[$eachlike->tuid]['uid'] = $eachlike->tuid;
  45. empty($arrays[$eachlike->tuid]['eachlike']) && $arrays[$eachlike->tuid]['eachlike'] = [];
  46. array_push($arrays[$eachlike->tuid]['eachlike'], $eachlike->id);
  47. });
  48. InvitationCardModel::where([['send_read', 0]])->whereBetween('created_at', [$day, $day + 86400])
  49. ->get()->map(function ($send_invite) use (&$arrays) {
  50. $arrays[$send_invite->uid]['uid'] = $send_invite->uid;
  51. empty($arrays[$send_invite->uid]['send_invite']) && $arrays[$send_invite->uid]['send_invite'] = [];
  52. array_push($arrays[$send_invite->uid]['send_invite'], $send_invite->id);
  53. });
  54. // 获取一天前(5-3)未读的消息
  55. $day = mktime(0, 0, 0) - 86400 * 2;
  56. EachLikeModel::where([['state', 1], ['read_at', 0]])->whereBetween('updated_at', [$day, $day + 86400])
  57. ->get()->map(function ($eachlike) use (&$arrays) {
  58. $arrays[$eachlike->tuid]['uid'] = $eachlike->tuid;
  59. empty($arrays[$eachlike->tuid]['eachlike']) && $arrays[$eachlike->tuid]['eachlike'] = [];
  60. array_push($arrays[$eachlike->tuid]['eachlike'], $eachlike->id);
  61. });
  62. ;
  63. InvitationCardModel::where([['send_read', 0]])->whereBetween('created_at', [$day, $day + 86400])
  64. ->get()->map(function ($send_invite) use (&$arrays) {
  65. $arrays[$send_invite->uid]['uid'] = $send_invite->uid;
  66. empty($arrays[$send_invite->uid]['send_invite']) && $arrays[$send_invite->uid]['send_invite'] = [];
  67. array_push($arrays[$send_invite->uid]['send_invite'], $send_invite->id);
  68. });
  69. InvitationCardModel::where([['read', 0], ['state', 0], ['expired_at', '>', time()]])->whereBetween(
  70. 'created_at',
  71. [$day, $day + 86400]
  72. )
  73. ->get()->map(function ($invite) use (&$arrays) {
  74. $arrays[$invite->invite_uid]['uid'] = $invite->invite_uid;
  75. empty($arrays[$invite->invite_uid]['invite_me']) && $arrays[$invite->invite_uid]['invite_me'] = [];
  76. array_push($arrays[$invite->invite_uid]['invite_me'], $invite->id);
  77. });
  78. foreach ($arrays as $array) {
  79. Redis::rpush("{friendslist:unreadnotice:load}", json_encode($array));
  80. }
  81. Redis::set("friendslist:unreadnotice:total", count($arrays));
  82. Redis::expire("{friendslist:unreadnotice:load}", mktime(23, 30, 0) - time());
  83. Redis::expire("friendslist:unreadnotice:total", mktime(23, 30, 0) - time());
  84. }
  85. public function push()
  86. {
  87. $total = Redis::get("friendslist:unreadnotice:total") ?? 0;
  88. $sendCnt = intval(ceil($total / (15 * 1 * 12)));
  89. dump($sendCnt);
  90. for (
  91. $i = 0; $i < $sendCnt; $i++
  92. ) {
  93. $toJson = Redis::lpop("{friendslist:unreadnotice:load}");
  94. if (is_null($toJson)) {
  95. return false;
  96. }
  97. try {
  98. $toData = json_decode($toJson, true);
  99. dump($toData);
  100. list($bool, $nickname) = $this->isCanPush($toData);
  101. if (!$bool) {
  102. dump($bool);
  103. continue;
  104. }
  105. $to_uid = $toData['uid'];
  106. $user = UserModel::findOrFail($to_uid);
  107. $sex = (1 == $user->sex) ? "铁汁" : "小姐姐";
  108. $title = "好友列表未读消息激活通知";
  109. $uuid = uuid();
  110. $noticeLog = new NoticeLogService();
  111. try {
  112. $fs = new FriendService();
  113. $cntData = $fs->getListCnt($to_uid);
  114. $cnt = $cntData['all'];
  115. $openid = Openid::ofPublic($to_uid)->value('openid');
  116. $page = "pages/starter/starter?log_type=notice&log_id={$uuid}&launch_type=free&url=%2Fpages%2Ffriend%2Ffriend";
  117. // 客服消息
  118. $kfcontent = "有来自{$nickname}的{$cnt}条好友消息待查看\n厉害了{$sex},又扩列啦!\n\n<a data-miniprogram-appid='wx4c1722a4055bd229' data-miniprogram-path='{$page}'>点此查看</a>";
  119. $response = Kfaccount::text([
  120. 'touser' => $openid,
  121. 'content' => $kfcontent,
  122. 'kf_account' => 'notice@admin',
  123. ]);
  124. if ($response['code'] == 0) {
  125. $noticeLog->record($to_uid, $title, "公众号客服消息", $uuid, 1, $kfcontent);
  126. continue;
  127. }
  128. // 服务号模版消息
  129. $public_id = config('wechat.fpdx.public_id');
  130. $template_id = "vj03Lys62tcWH0BAx2bKdDbzxBnhwe4Fhs3GXqbxkTg";
  131. $data = [
  132. 'first' => [
  133. 'value' => "{$user->nickname}的心动通知\n",
  134. ],
  135. 'keyword1' => [
  136. 'value' => "有来自{$nickname}的{$cnt}条好友消息待查看",
  137. ],
  138. 'keyword2' => [
  139. 'value' => "恭喜{$sex},又扩列啦! \n",
  140. ],
  141. 'remark' => [
  142. 'value' => "点此查看",
  143. "color" => "#FF7E98",
  144. ],
  145. ];
  146. $core = new Core();
  147. $result = $core->template($to_uid, $template_id, $public_id, $page, $data);
  148. if ($result) {
  149. $noticeLog->record($to_uid, $title, "公众号模板消息", $uuid, 1, $data);
  150. continue;
  151. }
  152. // 小程序模板消息
  153. $templates = array(
  154. [
  155. 'template' => 'lNEemth7Kml5ZmOvBcbo842h3whkYMM2c8d2YJOQlEU',
  156. 'data' => [
  157. 'keyword1' => array(
  158. 'value' => "{$user->nickname}的心动通知",
  159. ),
  160. 'keyword2' => array(
  161. 'value' => "有来自{$nickname}的{$cnt}条好友消息待查看",
  162. ),
  163. 'keyword3' => array(
  164. 'value' => "厉害了{$sex},又扩列啦!快去查看吧~",
  165. ),
  166. ],
  167. ],
  168. [
  169. 'template' => 'Xcp8AnnJr-cJmDMcr9WyIQmKgpN4qu6q6lStS0ZAiqs',
  170. 'data' => [
  171. 'keyword1' => array(
  172. 'value' => "{$user->nickname}的心动通知",
  173. ),
  174. 'keyword2' => array(
  175. 'value' => "有来自{$nickname}的{$cnt}条好友消息待查看",
  176. ),
  177. 'keyword3' => array(
  178. 'value' => "厉害了{$sex},又扩列啦!快去查看吧~",
  179. ),
  180. ],
  181. ],
  182. [
  183. 'template' => 'fsptIIrBoCB6ftxT_6-ApQeqGoE_rJsC5VBDPUbdScg',
  184. 'data' => [
  185. 'keyword1' => array(
  186. 'value' => "{$user->nickname}的心动通知",
  187. ),
  188. 'keyword2' => array(
  189. 'value' => "有来自{$nickname}的{$cnt}条好友消息待查看",
  190. ),
  191. 'keyword3' => array(
  192. 'value' => "厉害了{$sex},又扩列啦!快去查看吧~",
  193. ),
  194. ],
  195. ],
  196. );
  197. $template = $templates[rand(0, count($templates) - 1)];
  198. $core = new Core();
  199. $bool = $core->miniTemplate(
  200. $to_uid,
  201. $template['template'],
  202. "gh_01c089b58dda",
  203. $page,
  204. $template['data']
  205. );
  206. if ($bool) {
  207. $noticeLog->record($to_uid, $title, "小程序模板消息", $uuid, 1, $template['data']);
  208. continue;
  209. }
  210. } catch (\Exception $exception) {
  211. dump($exception);
  212. }
  213. $noticeLog->record($to_uid, $title, "发送失败", $uuid);
  214. } catch (\Exception $exception) {
  215. dump($exception);
  216. continue;
  217. }
  218. }
  219. return true;
  220. }
  221. // 判断是否发送
  222. public function isCanPush(array $data): array
  223. {
  224. try {
  225. if (isset($data['eachlike'])) {
  226. foreach ($data['eachlike'] as $eachlike_id) {
  227. $eachlike = EachLikeModel::findOrFail($eachlike_id);
  228. if (0 == $eachlike->read_at && 1 == $eachlike->state) {
  229. $user = UserModel::findOrFail($eachlike->uid);
  230. return [true, $user->nickname];
  231. }
  232. }
  233. }
  234. if (isset($data['send_invite'])) {
  235. foreach ($data['send_invite'] as $invite_id) {
  236. $invite = InvitationCardModel::findOrFail($invite_id);
  237. if (0 == $invite->send_read) {
  238. $user = UserModel::findOrFail($invite->invite_uid);
  239. return [true, $user->nickname];
  240. }
  241. }
  242. }
  243. if (isset($data['invite_me'])) {
  244. foreach ($data['invite_me'] as $invite_id) {
  245. $invite = InvitationCardModel::findOrFail($invite_id);
  246. if (0 == $invite->read && time() < $invite->expired_at) {
  247. $user = UserModel::findOrFail($invite->uid);
  248. return [true, $user->nickname];
  249. }
  250. }
  251. }
  252. } catch (\Exception $exception) {
  253. }
  254. return [false, null];
  255. }
  256. }