This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user