setName('messageMediaDispatch') ->setDescription('高级群发之处理媒体资源'); } protected function execute(Input $input, Output $output) { Request::instance()->module('admin'); //cli模式下无法获取到当前的项目模块,手动指定一下 $do = true; $messageArr = []; while ($do) { $version = substr(time(), 5) . mt_rand(1000, 9999); //设置锁 Db::execute("UPDATE send_channel_message SET version = {$version} WHERE `media_status` = 0 AND `version` = 0 ORDER BY id ASC LIMIT 50"); $channelMessages = model("SendChannelMessage")->where('version', 'eq', $version)->where('media_status', 'eq', 0)->select(); if ($channelMessages) { foreach ($channelMessages as $channelMessage) { //主消息 try { if (!isset($messageArr[$channelMessage['mass_id']])) { $message = model("SendMessage")->where('id', 'eq', $channelMessage['mass_id'])->find(); $messageArr[$channelMessage['mass_id']] = $message; } else { $message = $messageArr[$channelMessage['mass_id']]; } $contentArr = json_decode($message['message_content'], true); $content = $this->parseContent($channelMessage['channel_id'], $channelMessage['type'], $contentArr, $channelMessage); $update = [ 'version' => 1, 'media_status' => 3, 'media_updatetime' => time(), 'updatetime' => time() ]; switch ($channelMessage['type']) { case 1: if ($content) { $content = implode("\n\n", $content); $update['message_content'] = $content; } else { //内容为空 直接更新为失败 $update['send_status'] = 3; $update['media_status'] = 2; } break; case 2: if ($content) { //创建图文素材 $articles = []; foreach ($content as $item) { $articles[] = new Article($item); } $res = HigeMessageService::instance()->uploadNews($channelMessage['channel_id'], $articles); if (isset($res['errcode'])) { //判断是否是没评论权限导致失败 if ($res['errcode'] == 88000) { $newArticles = []; foreach ($content as $item) { unset($item['need_open_comment']); unset($item['only_fans_can_comment']); $newArticles[] = new Article($item); } $ress = HigeMessageService::instance()->uploadNews($channelMessage['channel_id'], $newArticles); if (isset($ress['errcode'])) { //素材处理失败 $update['media_status'] = 2; } else { $update['wx_media_id'] = $ress['media_id']; } } else { //素材处理失败 $update['media_status'] = 2; } } else { $update['wx_media_id'] = $res['media_id']; } } else { //内容为空 直接更新为失败 $update['send_status'] = 3; $update['media_status'] = 2; } break; case 3: $mediaResult = HigeMessageService::instance()->image2media($channelMessage['channel_id'], $content['img_path']); if (isset($mediaResult['errcode'])) { //素材处理失败 $update['media_status'] = 2; } else { $update['wx_media_id'] = $mediaResult['media_id']; } break; } model("SendChannelMessage")->update($update, ['id' => $channelMessage['id']]); } catch (Exception $e) { Log::error("渠道消息资源处理失败:msg: {$e->getMessage()} line : {$e->getLine()}"); } } } else { $do = false; } } //更新已完成主任务 $maps = [ 'send_status' => 2, 'message_status' => 1, ]; $massMessages = model("SendMessage")->where($maps)->field("id, subscription_ids")->select(); if ($massMessages) { foreach ($massMessages as $massMessage) { $channelIds = array_unique(array_filter(explode(',', $massMessage['subscription_ids']))); $messages = Db::query("SELECT count(media_status=0 or null) count_0, count(media_status=1 or null) count_1, count(media_status=2 or null) count_2, count(media_status=3 or null) count_3 FROM send_channel_message WHERE mass_id = {$massMessage['id']};"); $result = $messages[0] ?? []; if ($result) { if ($result['count_0'] != 0 || $result['count_1'] != 0) { continue; } elseif ($result['count_2'] == count($channelIds)) { //全部失败 model("SendMessage")->update(['send_status' => 6, 'updatetime' => time()], ['id' => $massMessage['id']]); } elseif ($result['count_3'] > 0) { //全部处理完成 model("SendMessage")->update(['send_status' => 3, 'updatetime' => time()], ['id' => $massMessage['id']]); } } } } } /** * 格式化内容 * @param $channelId * @param $msgType * @param $message * @param $channelMessage * @return array|mixed|string * @throws Exception * @throws InvalidArgumentException */ private function parseContent($channelId, $msgType, $message, $channelMessage) { if ($msgType == 1) { //文字消息 $content = ''; $str_list = []; foreach ($message as $idx => $item) { if (isset($item['url'])) { $str = ''; $str .= ""; $str .= $item['content']; $str .= ""; $str_list[] = $str; } else { if (isset($item['page']) && $item['page']){ $item['content'] = MiniProgramService::instance()->getMiniText($item['page'],$item['content'],$channelId); } $str_list[] = $item['content']; } } return $str_list; } elseif ($msgType == 2) { //图文消息 $newsData = []; $messageCount = count($message); foreach ($message as $k => $item) { //处理小程序 HigeMessageService::instance()->__setMiniBatch($item,$channelId); $article = [ 'title' => $item['title'], 'author' => $item['author'], 'thumb_media_id' => '', 'digest' => '', 'auth' => '', 'show_cover' => 0, 'content' => $this->parseContentImage($channelId, $item['content']), 'source_url' => '', 'need_open_comment' => $item['need_open_comment'] ?? 0, 'only_fans_can_comment' => $item['only_fans_can_comment'] ?? 0, ]; $url = ''; if (isset($item['type']) && $item['type'] != 4 ) { $url = HigeMessageService::instance()->buildUrl($channelId, $item); //进行打点操作 if (in_array($item['type'], [1, 3]) && empty($url)) { Log::error("error 活动状态异常 message_id: {$channelMessage['id']}"); continue; } $url = HigeMessageService::instance()->buildPointInfo($channelId, $msgType, $url, $channelMessage['send_time'], $channelMessage['id'], $k); } $article['source_url'] = $url; if ($item['cover']) { $coverResult = HigeMessageService::instance()->image2media($channelId, $item['cover'], 1); if (isset($coverResult['errcode'])) { Log::error("error:封面图上传失败 message_id: {$channelMessage['id']}"); continue; } else { $article['thumb_media_id'] = $coverResult['media_id']; } } else { Log::error("error:缺少封面图 message_id: {$channelMessage['id']}"); continue; } //if ($messageCount > 1) { $article['digest'] = (isset($item['digest']) && !empty($item['digest'])) ? $item['digest'] : mb_substr(strip_tags($item['content']), 0, 64); //} $newsData[] = $article; } return $newsData; } elseif ($msgType == 3) { //图片消息 $imgPath = current($message); return $imgPath; } } /** * 处理内容中的图片 * @param $channelId * @param $content * @return mixed * @throws Exception * @throws InvalidArgumentException */ private function parseContentImage($channelId, $content) { $imgPaths = []; if (preg_match_all("/src=['|\"]([^\s]*)['|\"]/i", $content, $m)) { $imgPaths = $m[1]; } if ($imgPaths) { $mediaArr = []; foreach ($imgPaths as $k => $imgPath) { if (isset($this->wxUrlArr[$imgPath])) { $wxUrl = $this->wxUrlArr[$imgPath]; } else { $res = HigeMessageService::instance()->image2media($channelId, $imgPath); if (isset($res['errcode'])) { Log::error("error 图片上传失败"); $wxUrl = $imgPaths; } else { $wxUrl = $res['url']; $this->wxUrlArr[$imgPath] = $res['url']; } } $mediaArr[$k] = $wxUrl; } $content = str_replace($imgPaths, $mediaArr, $content); } return $content; } }