diff --git a/app/Amqp/Consumer/UploadImMediaConsumer.php b/app/Amqp/Consumer/UploadImMediaConsumer.php new file mode 100644 index 0000000..e878efa --- /dev/null +++ b/app/Amqp/Consumer/UploadImMediaConsumer.php @@ -0,0 +1,88 @@ + false, 'timeout' => 30]); // 设置合适的超时时间 + $oss = new Oss(); + $needUpdate = false; + $customDomain = config('alibaba.oss.custom_domain_name'); // 取 OSS 自定义域名 + + // 1. 根据不同类型提取 URL 并转存 OSS + if ($msgType === 'TIMImageElem' && isset($msgContent['ImageInfoArray'])) { + // 图片通常包含原图、大图、缩略图,根据需求替换 + foreach ($msgContent['ImageInfoArray'] as &$imageInfo) { + if (!empty($imageInfo['URL'])) { + $content = $client->get($imageInfo['URL'])->getBody()->getContents(); + $filename = "im/image/" . date('Ymd') . "/" . $messageKey . "_" . $imageInfo['Type'] . ".jpg"; + $ossFilename = $oss->putObject($filename, $content); + + $imageInfo['URL'] = rtrim($customDomain, '/') . '/' . $ossFilename; + $needUpdate = true; + } + } + } elseif ($msgType === 'TIMSoundElem' && !empty($msgContent['Url'])) { + // 语音消息 + $content = $client->get($msgContent['Url'])->getBody()->getContents(); + $filename = "im/sound/" . date('Ymd') . "/" . $messageKey . ".amr"; + $ossFilename = $oss->putObject($filename, $content); + + $msgContent['Url'] = rtrim($customDomain, '/') . '/' . $ossFilename; + $needUpdate = true; + } elseif ($msgType === 'TIMVideoFileElem') { + // 视频文件 + if (!empty($msgContent['VideoUrl'])) { + $content = $client->get($msgContent['VideoUrl'])->getBody()->getContents(); + $filename = "im/video/" . date('Ymd') . "/" . $messageKey . ".mp4"; + $ossFilename = $oss->putObject($filename, $content); + $msgContent['VideoUrl'] = rtrim($customDomain, '/') . '/' . $ossFilename; + $needUpdate = true; + } + // 视频封面图 + if (!empty($msgContent['ThumbUrl'])) { + $content = $client->get($msgContent['ThumbUrl'])->getBody()->getContents(); + $filename = "im/video_thumb/" . date('Ymd') . "/" . $messageKey . ".jpg"; + $ossFilename = $oss->putObject($filename, $content); + $msgContent['ThumbUrl'] = rtrim($customDomain, '/') . '/' . $ossFilename; + $needUpdate = true; + } + } + + // 2. 更新对应记录的 JSON 数据 + if ($needUpdate) { + MessageIm::where(['message_key' => $messageKey])->update([ + 'message_content' => json_encode($msgContent, JSON_UNESCAPED_UNICODE) + ]); + } + + return Result::ACK; // 任务成功完成 + } catch (\Throwable $e) { + Log::getInstance("UploadImMediaConsumer")->error("IM多媒体上传OSS失败: " . $e->getMessage() . ' Line: ' . $e->getLine()); + // 如果抛错可以 DROP 掉或者返回 REQUEUE 进入死信重试队列 + return Result::DROP; + } + } +} diff --git a/app/Amqp/Producer/UploadImMediaProducer.php b/app/Amqp/Producer/UploadImMediaProducer.php new file mode 100644 index 0000000..3f15e64 --- /dev/null +++ b/app/Amqp/Producer/UploadImMediaProducer.php @@ -0,0 +1,27 @@ + "消息唯一ID", + * "msg_type" => "消息类型", + * "msg_content" => "消息具体内容(数组)" + * ] + */ + public function __construct(array $data) + { + $this->payload = $data; + } +} diff --git a/app/Services/UserService.php b/app/Services/UserService.php index 4eb7d52..f7880fe 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -1232,6 +1232,23 @@ class UserService extends BaseService return $result; } + // === 新增:投递上传OSS队列 === + $mediaTypes = ['TIMImageElem', 'TIMSoundElem', 'TIMVideoFileElem', 'TIMFileElem']; + if (in_array($msg_data['MsgBody'][0]['MsgType'], $mediaTypes)) { + try { + $producer = \Hyperf\Context\ApplicationContext::getContainer()->get(\Hyperf\Amqp\Producer::class); + $producerMsg = new \App\Amqp\Producer\UploadImMediaProducer([ + 'message_key' => $msg_data['MsgKey'], + 'msg_type' => $msg_data['MsgBody'][0]['MsgType'], + 'msg_content' => $message_content, + ]); + $producer->produce($producerMsg); + } catch (\Throwable $e) { + Log::getInstance("UserService-userImAfterSendMsg")->error("投递上传OSS队列失败: " . $e->getMessage()); + } + } + // === 新增结束 === + // im消息通知 if ($is_system == 0 && isset($message_send_result) && isset($order_inquiry_id)){ try { diff --git a/app/Utils/Auth.php b/app/Utils/Auth.php index 8ff1243..ba410da 100644 --- a/app/Utils/Auth.php +++ b/app/Utils/Auth.php @@ -19,6 +19,10 @@ class Auth "/login/wechat_mobile_login" => "post", // 微信登陆 "/login/mobile_login" => "post", // 手机号登陆 "/code/phone" => "post",// 获取手机号验证码 + "/patient/doctor/inquiry" => "get", // 获取问诊医生列表 + "/doctor/info/inquiry/" => "get", // 获取医生详情-问诊 + "/doctor/inquiry/service/" => "get", // 获取医生开启的服务列表 + "/patient/doctor/evaluation/" => "get", // 获取医生评价 "/disease/expertise" => "get",// 疾病专长列表-搜索使用 "/area/province" => "get",// 获取省份信息 "/area/city" => "get", // 获取城市信息