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/Controller/TestController.php b/app/Controller/TestController.php index 762ad0a..cd31530 100644 --- a/app/Controller/TestController.php +++ b/app/Controller/TestController.php @@ -89,6 +89,12 @@ class TestController extends AbstractController // 疾病名称 protected string $icd_name; + public function testError() + { + // 模拟触发 SQLSTATE[42S22]: Column not found 数据库报错 + Db::select("SELECT nonexistent_column_test FROM gdxz_user_ca_cert LIMIT 1"); + } + public function test(){ // $this->test_8(); // $this->test_3(); diff --git a/app/Services/UserDoctorService.php b/app/Services/UserDoctorService.php index da8b96b..b321dee 100644 --- a/app/Services/UserDoctorService.php +++ b/app/Services/UserDoctorService.php @@ -880,10 +880,6 @@ class UserDoctorService extends BaseService $page = $this->request->input('page', 1); $per_page = $this->request->input('per_page', 10); - if (empty($user_info)) { - return fail(); - } - // 4-5分为好评、3分为中评、2-1分为差评 if ($evaluation_type == 1) { // 全部 @@ -2492,15 +2488,12 @@ class UserDoctorService extends BaseService $user_info = $this->request->getAttribute("userInfo") ?? []; - if (empty($user_info)){ - return fail(HttpEnumCode::HTTP_SUCCESS, "请登录"); - } - $result = array(); $result['hospital'] = []; $result['days'] = 0; $result['doctor_inquiry_config'] = []; $result['is_online'] = 0; + $result['follow'] = false; $fields = [ "doctor_id", @@ -2549,7 +2542,7 @@ class UserDoctorService extends BaseService } // 患者 - if ($user_info['user_type'] == 1){ + if (!empty($user_info) && $user_info['user_type'] == 1){ // 获取服务天数 $params = array(); $params['patient_id'] = $user_info['client_user_id']; @@ -2626,10 +2619,6 @@ class UserDoctorService extends BaseService $user_info = $this->request->getAttribute("userInfo") ?? []; - if (empty($user_info)){ - return fail(HttpEnumCode::HTTP_SUCCESS, "请登录"); - } - $fields = [ "doctor_id", "user_id", 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 0ddcb95..6d55da1 100644 --- a/app/Utils/Auth.php +++ b/app/Utils/Auth.php @@ -19,7 +19,14 @@ class Auth "/login/wechat_mobile_login" => "post", // 微信登陆 "/login/mobile_login" => "post", // 手机号登陆 "/code/phone" => "post",// 获取手机号验证码 - "/disease/expertise" => "get",// 疾病专长列表-搜索使用 + "/patient/doctor/inquiry" => "get", // 获取问诊医生列表 + "/doctor/info/inquiry/" => "get", // 获取医生详情-问诊 + "/doctor/inquiry/service/" => "get", // 获取医生开启的服务列表 + "/patient/doctor/evaluation/" => "get", // 获取医生评价 + "/basic/disease/expertise" => "get",// 疾病专长列表-搜索使用 + "/patient/article/science" => "get", // 科普文章分页 + "/patient/article/science/list" => "get", // 科普文章列表 + "/evaluation" => "get", // 获取医生评价列表 "/area/province" => "get",// 获取省份信息 "/area/city" => "get", // 获取城市信息 "/area/county" => "get", // 获取区县信息 @@ -39,6 +46,7 @@ class Auth "/basic/keyword/search" => "get", // 获取热门搜索关键词 "/test/uninquiry" => "get", // 获取未接诊的医生 "/test/refund" => "post", // 测试退款 + "/test/error" => "get", // 测试报错 "/test" => "get", // 测试 "/callback/detection" => "post", // 检测所结果回调 "/callback/video/trtc" => "post", // 音视频回调 diff --git a/config/routes.php b/config/routes.php index 6b23d14..1ffdbde 100644 --- a/config/routes.php +++ b/config/routes.php @@ -912,6 +912,7 @@ Router::addGroup('/case', function () { // 测试使用 Router::addGroup('/test', function () { Router::get('', [TestController::class, 'test']); + Router::get('/error', [TestController::class, 'testError']); // 获取未接诊的医生 Router::get('/uninquiry', [TestController::class, 'uninquiry']);