新增im回调

This commit is contained in:
wucongxing 2023-03-10 14:53:50 +08:00
parent bd49332f64
commit b03f38704d
7 changed files with 362 additions and 24 deletions

View File

@ -216,7 +216,7 @@ class AssignDoctorConsumer extends ConsumerMessage
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
$cloud_custom_data['message_type'] = 1;//1系统发送 其余:用户发送
$cloud_custom_data['message_type'] = 1;//消息类型(1系统发送 其余:用户发送
$arg['CloudCustomData'] = json_encode($cloud_custom_data,JSON_UNESCAPED_UNICODE);

View File

@ -21,7 +21,10 @@ use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\HttpMessage\Stream\SwooleFileStream;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
class CallBackController extends AbstractController
@ -111,6 +114,9 @@ class CallBackController extends AbstractController
return $this->wxPayErrorReturn($e->getMessage());
}
Log::getInstance()->info("微信支付回调处理成功");
Log::getInstance()->info("微信支付回调处理成功,开始发送系统问诊消息");
try {
if ($message['trade_state'] == "SUCCESS"){
if ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4){
@ -178,9 +184,18 @@ class CallBackController extends AbstractController
return $server->serve();
}
Log::getInstance()->info("微信支付回调处理成功,发送系统问诊消息成功");
return $server->serve();
}
/**
* 微信退款回调
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws \Throwable
*/
public function wxPayRefundCallBack(): ResponseInterface
{
try {
@ -225,10 +240,195 @@ class CallBackController extends AbstractController
)
);
}
// im回调
public function imCallBack(){
//
/**
* im回调
* @return ResponseInterface
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function imCallBack(): ResponseInterface
{
$request_params = $this->request->all();
dump($request_params);
Log::getInstance()->info(json_encode($request_params,JSON_UNESCAPED_UNICODE));
try {
Log::getInstance()->info("Im回调数据" . json_encode($request_params,JSON_UNESCAPED_UNICODE));
if (empty($request_params['RequestTime']) || empty($request_params['Sign'])){
Log::getInstance()->error("Im回调数据处理失败:缺少时间时间戳/签名字段");
return $this->ImErrorReturn("缺少时间时间戳/签名字段");
}
// 鉴定回调签名
$imService = new ImService();
$result = $imService->validateSign($request_params['RequestTime'],$request_params['Sign']);
if (!$result){
Log::getInstance()->error("Im回调数据处理失败:回调签名不匹配");
return $this->ImErrorReturn("回调签名不匹配");
}
// 验证消息内容
if (empty($request_params['MsgBody'])){
Log::getInstance()->error("Im回调数据处理失败:消息内容错误");
return $this->ImErrorReturn("消息内容错误缺少MsgBody");
}
// 验证接收方user_id
if (empty($request_params['To_Account'])){
Log::getInstance()->error("Im回调数据处理失败:接收用户错误");
return $this->ImErrorReturn("消息内容错误,接收用户错误");
}
// 验证消息唯一id
if (empty($request_params['MsgKey'])){
Log::getInstance()->error("Im回调数据处理失败:消息唯一标识错误");
return $this->ImErrorReturn("消息内容错误,消息唯一标识错误");
}
// 验证消息重复性
$params = array();
$params['message_key'] = $request_params['MsgKey'];
$message = \App\Model\Message::getExists($params);
if ($message){
// 消息重复
Log::getInstance()->info("Im回调数据处理失败:消息重复");
return $this->ImSuccessReturn();
}
// 处理发送结果
if ($request_params['message_send_result'] == 0){
// im中0表示成功
$message_send_result = 1;
}
// 验证自定义消息内容
$is_system = 0;// 是否系统操作发送0:否 1:是)
if (!empty($request_params['CloudCustomData'])){
$cloud_custom_data = json_decode($request_params['CloudCustomData'],true);
if (!empty($cloud_custom_data['order_inquiry_id'])){
// 获取订单数据
$params = array();
$params['order_inquiry_id'] = $cloud_custom_data['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)){
Log::getInstance()->error("Im回调数据处理失败:非法订单");
return $this->ImErrorReturn("消息内容错误,非法订单");
}
$order_inquiry_id = $cloud_custom_data['order_inquiry_id'];
}
if (!empty($cloud_custom_data['is_system'])){
if ($cloud_custom_data['is_system'] == 1){
// 系统发送
$is_system = 1;
}
}
}
// 入库
$data = array();
if (!empty($request_params['From_Account'])){
// 系统发送时不带参数
$data['from_user_id'] = $request_params['From_Account'];
}
$data['to_user_id'] = $request_params['To_Account'];
$data['message_key'] = $request_params['MsgKey'];
$data['message_send_time'] = $request_params['RequestTime'];
$data['message_seq'] = $request_params['MsgSeq'];
$data['message_send_result'] = $message_send_result ?? 0;
$data['send_error_info'] = $request_params['ErrorInfo'];
$data['message_type'] = $request_params['MsgBody'][0]['MsgType'] ?? "未定义";
$data['is_system'] = $is_system;
if (!empty($order_inquiry_id)){
$data['order_inquiry_id'] = $order_inquiry_id;
}
$message_content = $request_params['MsgBody'][0]['MsgContent'] ?? "";
$data['message_content'] = json_encode($message_content,JSON_UNESCAPED_UNICODE);
$data['message_custom_content'] = $request_params['CloudCustomData'] ?? "";
$message = \App\Model\Message::addMessage($data);
if (empty($message)){
Log::getInstance()->error("Im回调数据处理失败:存储数据库失败");
return $this->wxPayErrorReturn("存储数据库失败");
}
// 存储redisList
if (!empty($order_inquiry) && !empty($request_params['CloudCustomData'])){
if (!empty($cloud_custom_data['is_system'])){
if ($cloud_custom_data['is_system'] != 1){
// 非系统发送
if (!empty($cloud_custom_data['sender_user_type'])){
if ($cloud_custom_data['sender_user_type'] == 1 || $cloud_custom_data['sender_user_type'] == 2){
// 患者-医生发送
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$data['patient_name'] = $order_inquiry['patient_name'];
$data['patient_sex'] = $order_inquiry['patient_sex'];
$data['patient_age'] = $order_inquiry['patient_age'];
$data['inquiry_status'] = $order_inquiry['inquiry_status'];
$data['message_send_time'] = $request_params['RequestTime'];
$data['last_message_content'] = $request_params['MsgBody'][0]['MsgContent'] ?? "";
$imService = new ImService();
$imService->addRecentContactRecordCache($order_inquiry['doctor_id'],$order_inquiry['inquiry_type'],$order_inquiry['user_id'],$data);
}
}
}
}
}
} catch (\Exception $e) {
// 验证失败
Log::getInstance()->error("Im回调数据处理失败:" . $e->getMessage());
return $this->wxPayErrorReturn($e->getMessage());
}
Log::getInstance()->info("Im回调数据处理成功");
return $this->ImSuccessReturn();
}
/**
* im返回错误响应
* @param string $message
* @return ResponseInterface
*/
protected function ImErrorReturn(string $message): ResponseInterface
{
return $this->response
->withStatus(200)
->withBody(
new SwooleStream(
strval(
json_encode([
'ActionStatus' => 'FAIL',
'ErrorCode' => 1,
'ErrorInfo' => $message,
], JSON_UNESCAPED_UNICODE)
)
)
);
}
/**
* im返回正确响应
* @return ResponseInterface
*/
protected function ImSuccessReturn(): ResponseInterface
{
return $this->response
->withStatus(200)
->withBody(
new SwooleStream(
strval(
json_encode([
'ActionStatus' => 'OK',
'ErrorCode' => 0,
'ErrorInfo' => "",
], JSON_UNESCAPED_UNICODE)
)
)
);
}
}

View File

@ -125,7 +125,7 @@ class UserController extends AbstractController
$group = new Group();
$friend = new Friend();
$message = new Message();
$result = $account->createAccount(10009,'测试患者9',"https://img.applets.igandanyiyuan.com/applet/doctor/avatar/03dc8df2-e7c0-4ad9-b87e-5133e40e0f76.jpg");
// $result = $account->createAccount(10009,'测试患者9',"https://img.applets.igandanyiyuan.com/applet/doctor/avatar/03dc8df2-e7c0-4ad9-b87e-5133e40e0f76.jpg");
// 查询账号导入状态
// $result = $account->checkAccountStatus("123456");
@ -148,23 +148,31 @@ class UserController extends AbstractController
// $result = $friend->addFriend("123456",'1234567',"快速问诊");
// 发送消息
// $arg = array();
// $arg['From_Account'] = "1234567"; // 发送方user_id 如系统发送,无需填写
// $arg['To_Account'] = "123456"; // 接收方user_id
// $arg['ForbidCallbackControl'] = ['ForbidBeforeSendMsgCallback'];
//
// $arg['MsgBody'] = [
// [
// "MsgType" => "TIMTextElem",
// "MsgContent" => [
// "Text" => "测试消息1",
// ],
// ]
// ];
//
// $result = $message->sendMessage($arg);
$arg = array();
$arg['From_Account'] = "10000"; // 发送方user_id 如系统发送,无需填写
$arg['To_Account'] = "123456"; // 接收方user_id
$arg['ForbidCallbackControl'] = ['ForbidBeforeSendMsgCallback'];
$arg['MsgBody'] = [
[
"MsgType" => "TIMTextElem",
"MsgContent" => [
"Text" => "测试消息22",
],
]
];
// 自定义消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = 491937904055369728;
$cloud_custom_data['is_system'] = 1;
$arg['CloudCustomData'] = json_encode($cloud_custom_data,JSON_UNESCAPED_UNICODE);
$result = $message->sendMessage($arg);
// $result = $profile->getOneAccountPortraitList("123456");
$result = $profile->getOneAccountPortraitList("123456");
dump($result);

86
app/Model/Message.php Normal file
View File

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $message_id 主键id
* @property int $from_user_id 发送方user_id
* @property int $to_user_id 接收方user_id
* @property string $message_key 消息唯一标识(系统返回,撤回消息使用)
* @property string $message_send_time 消息发送时间戳
* @property int $message_seq 消息序列号(单聊消息优先使用 MsgTime 进行排序,同一秒发送的消息则按 MsgSeq 排序MsgSeq 值越大消息越靠后)
* @property int $message_send_result 消息下发结果0:失败 1:成功)
* @property string $send_error_info 消息下发失败原因
* @property string $message_type 消息类型具体查看https://cloud.tencent.com/document/product/269/2720
* @property int $is_system 是否系统操作发送0: 1:是)
* @property int $order_inquiry_id 问诊id自定义字段
* @property string $message_content 消息内容json形式
* @property string $message_custom_content 自定义消息内容json形式
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class Message extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'message';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['message_id', 'from_user_id', 'to_user_id', 'message_key', 'message_send_time', 'message_seq', 'message_send_result', 'send_error_info', 'message_type', 'is_system', 'order_inquiry_id', 'message_content', 'message_custom_content', 'created_at', 'updated_at'];
protected string $primaryKey = "message_id";
/**
* 获取是否存在
* @param array $params
* @return bool
*/
public static function getExists(array $params): bool
{
return self::where($params)->exists();
}
/**
* 获取信息-单条
* @param array $params
* @param array $fields
* @return object|null
*/
public static function getOne(array $params, array $fields = ['*']): object|null
{
return self::where($params)->first($fields);
}
/**
* 获取数据-
* @param array $params
* @param array $fields
* @return Collection|array
*/
public static function getList(array $params = [], array $fields = ['*']): Collection|array
{
return self::where($params)->get($fields);
}
/**
* 新增
* @param array $data
* @return \Hyperf\Database\Model\Model|Message
*/
public static function addMessage(array $data): \Hyperf\Database\Model\Model|Message
{
return self::create($data);
}
}

View File

@ -13,6 +13,9 @@ use App\Utils\Log;
use Extend\TencentIm\Account;
use Extend\TencentIm\Profile;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Redis\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
class ImService extends BaseService
{
@ -120,4 +123,45 @@ class ImService extends BaseService
}
/**
* 验证回调签名
* @param string $request_time 签名时间戳
* @param string $sign 签名
* @return bool
*/
public function validateSign(string $request_time,string $sign): bool
{
$token = config('im.token');
if (empty($token)){
throw new BusinessException("Im Token Config Error");
}
$sys_sign = hash("sha256", $token . $request_time);
if ($sign != $sys_sign){
return false;
}
return true;
}
/**
* 添加最近联系人会话记录缓存
* @param string $doctor_id 医生id
* @param string $inquiry_type 订单类型(自定义字段 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @param string $patient_user_id 患者用户id
* @param array $content 内容
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function addRecentContactRecordCache(string $doctor_id,string $inquiry_type,string $patient_user_id,array $content): void
{
$redis_key = "recentContact" . $doctor_id . $inquiry_type;
$hash_key = $patient_user_id;
$redis = $this->container->get(Redis::class);
$redis->hSet($redis_key,$hash_key,json_encode($content,JSON_UNESCAPED_UNICODE));
}
}

View File

@ -72,5 +72,6 @@ return [
"app_id" => "1400796919",
"secret" => "a5bcd8c583181cf004e9d91a47687d719d4b5d2a10ce33fbee95d587889447d8",
"base_url" => "https://console.tim.qq.com/",
"token" => "NDc5MzExMDMxMDY2NDMxNDg5L", // 鉴权回调使用
],
];

View File

@ -86,7 +86,6 @@ class Message extends Base
*/
public function sendMessage(array $arg): bool
{
try {
// 合并发送参数
$arg = array_merge($this->arg,$arg);