@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Amqp\Consumer;
|
||||||
|
|
||||||
|
use App\Model\MessageIm;
|
||||||
|
use Extend\Alibaba\Oss;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Hyperf\Amqp\Annotation\Consumer;
|
||||||
|
use Hyperf\Amqp\Message\ConsumerMessage;
|
||||||
|
use Hyperf\Amqp\Result;
|
||||||
|
use PhpAmqpLib\Message\AMQPMessage;
|
||||||
|
use App\Utils\Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IM 多媒体文件异步处理消费者
|
||||||
|
*/
|
||||||
|
#[Consumer(exchange: 'amqp.direct', routingKey: 'UploadImMedia', queue: 'UploadImMediaQueue', name: "UploadImMediaConsumer", nums: 1)]
|
||||||
|
class UploadImMediaConsumer extends ConsumerMessage
|
||||||
|
{
|
||||||
|
public function consumeMessage($data, AMQPMessage $message): string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$messageKey = $data['message_key'];
|
||||||
|
$msgType = $data['msg_type'];
|
||||||
|
$msgContent = $data['msg_content'];
|
||||||
|
|
||||||
|
// 初始化 Http Client 和 OSS
|
||||||
|
$client = new Client(['verify' => 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Amqp\Producer;
|
||||||
|
|
||||||
|
use Hyperf\Amqp\Annotation\Producer;
|
||||||
|
use Hyperf\Amqp\Message\ProducerMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IM 多媒体文件异步下载并上传 OSS
|
||||||
|
*/
|
||||||
|
#[Producer(exchange: 'amqp.direct', routingKey: 'UploadImMedia')]
|
||||||
|
class UploadImMediaProducer extends ProducerMessage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* [
|
||||||
|
* "message_key" => "消息唯一ID",
|
||||||
|
* "msg_type" => "消息类型",
|
||||||
|
* "msg_content" => "消息具体内容(数组)"
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
$this->payload = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,6 +89,12 @@ class TestController extends AbstractController
|
|||||||
// 疾病名称
|
// 疾病名称
|
||||||
protected string $icd_name;
|
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(){
|
public function test(){
|
||||||
// $this->test_8();
|
// $this->test_8();
|
||||||
// $this->test_3();
|
// $this->test_3();
|
||||||
|
|||||||
@@ -880,10 +880,6 @@ class UserDoctorService extends BaseService
|
|||||||
$page = $this->request->input('page', 1);
|
$page = $this->request->input('page', 1);
|
||||||
$per_page = $this->request->input('per_page', 10);
|
$per_page = $this->request->input('per_page', 10);
|
||||||
|
|
||||||
if (empty($user_info)) {
|
|
||||||
return fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4-5分为好评、3分为中评、2-1分为差评
|
// 4-5分为好评、3分为中评、2-1分为差评
|
||||||
if ($evaluation_type == 1) {
|
if ($evaluation_type == 1) {
|
||||||
// 全部
|
// 全部
|
||||||
@@ -2492,15 +2488,12 @@ class UserDoctorService extends BaseService
|
|||||||
|
|
||||||
$user_info = $this->request->getAttribute("userInfo") ?? [];
|
$user_info = $this->request->getAttribute("userInfo") ?? [];
|
||||||
|
|
||||||
if (empty($user_info)){
|
|
||||||
return fail(HttpEnumCode::HTTP_SUCCESS, "请登录");
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
$result['hospital'] = [];
|
$result['hospital'] = [];
|
||||||
$result['days'] = 0;
|
$result['days'] = 0;
|
||||||
$result['doctor_inquiry_config'] = [];
|
$result['doctor_inquiry_config'] = [];
|
||||||
$result['is_online'] = 0;
|
$result['is_online'] = 0;
|
||||||
|
$result['follow'] = false;
|
||||||
|
|
||||||
$fields = [
|
$fields = [
|
||||||
"doctor_id",
|
"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 = array();
|
||||||
$params['patient_id'] = $user_info['client_user_id'];
|
$params['patient_id'] = $user_info['client_user_id'];
|
||||||
@@ -2626,10 +2619,6 @@ class UserDoctorService extends BaseService
|
|||||||
|
|
||||||
$user_info = $this->request->getAttribute("userInfo") ?? [];
|
$user_info = $this->request->getAttribute("userInfo") ?? [];
|
||||||
|
|
||||||
if (empty($user_info)){
|
|
||||||
return fail(HttpEnumCode::HTTP_SUCCESS, "请登录");
|
|
||||||
}
|
|
||||||
|
|
||||||
$fields = [
|
$fields = [
|
||||||
"doctor_id",
|
"doctor_id",
|
||||||
"user_id",
|
"user_id",
|
||||||
|
|||||||
@@ -1232,6 +1232,23 @@ class UserService extends BaseService
|
|||||||
return $result;
|
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消息通知
|
// im消息通知
|
||||||
if ($is_system == 0 && isset($message_send_result) && isset($order_inquiry_id)){
|
if ($is_system == 0 && isset($message_send_result) && isset($order_inquiry_id)){
|
||||||
try {
|
try {
|
||||||
|
|||||||
+9
-1
@@ -19,7 +19,14 @@ class Auth
|
|||||||
"/login/wechat_mobile_login" => "post", // 微信登陆
|
"/login/wechat_mobile_login" => "post", // 微信登陆
|
||||||
"/login/mobile_login" => "post", // 手机号登陆
|
"/login/mobile_login" => "post", // 手机号登陆
|
||||||
"/code/phone" => "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/province" => "get",// 获取省份信息
|
||||||
"/area/city" => "get", // 获取城市信息
|
"/area/city" => "get", // 获取城市信息
|
||||||
"/area/county" => "get", // 获取区县信息
|
"/area/county" => "get", // 获取区县信息
|
||||||
@@ -39,6 +46,7 @@ class Auth
|
|||||||
"/basic/keyword/search" => "get", // 获取热门搜索关键词
|
"/basic/keyword/search" => "get", // 获取热门搜索关键词
|
||||||
"/test/uninquiry" => "get", // 获取未接诊的医生
|
"/test/uninquiry" => "get", // 获取未接诊的医生
|
||||||
"/test/refund" => "post", // 测试退款
|
"/test/refund" => "post", // 测试退款
|
||||||
|
"/test/error" => "get", // 测试报错
|
||||||
"/test" => "get", // 测试
|
"/test" => "get", // 测试
|
||||||
"/callback/detection" => "post", // 检测所结果回调
|
"/callback/detection" => "post", // 检测所结果回调
|
||||||
"/callback/video/trtc" => "post", // 音视频回调
|
"/callback/video/trtc" => "post", // 音视频回调
|
||||||
|
|||||||
@@ -912,6 +912,7 @@ Router::addGroup('/case', function () {
|
|||||||
// 测试使用
|
// 测试使用
|
||||||
Router::addGroup('/test', function () {
|
Router::addGroup('/test', function () {
|
||||||
Router::get('', [TestController::class, 'test']);
|
Router::get('', [TestController::class, 'test']);
|
||||||
|
Router::get('/error', [TestController::class, 'testError']);
|
||||||
|
|
||||||
// 获取未接诊的医生
|
// 获取未接诊的医生
|
||||||
Router::get('/uninquiry', [TestController::class, 'uninquiry']);
|
Router::get('/uninquiry', [TestController::class, 'uninquiry']);
|
||||||
|
|||||||
Reference in New Issue
Block a user