hospital-applets-api/app/Amqp/Consumer/AssignDoctorConsumer.php
2023-03-10 16:52:48 +08:00

236 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace App\Amqp\Consumer;
use App\Model\OrderInquiry;
use App\Model\UserDoctor;
use App\Services\ImService;
use App\Services\InquiryService;
use App\Services\UserDoctorService;
use App\Utils\Log;
use Extend\TencentIm\Message;
use Extend\Wechat\WechatPay;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
use PhpAmqpLib\Message\AMQPMessage;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
/**
* 分配医生
* 快速问诊、问诊购药等订单支付完成后,进行分配医生
*/
#[Consumer(exchange: 'amqp.direct', routingKey: 'AssignDoctor', queue: 'assign.doctor.queue', nums: 1)]
class AssignDoctorConsumer extends ConsumerMessage
{
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws GuzzleException
*/
public function consumeMessage($data, AMQPMessage $message): string
{
Log::getInstance()->error("开始执行 分配医生 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE));
Db::beginTransaction();
try {
// 获取订单数据
$params = array();
$params['order_inquiry_id'] = $data['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
Db::rollBack();
Log::getInstance()->error("队列执行失败原因:未查询到对应订单数据");
return Result::DROP;// 销毁
}
// 检测订单分配状态
if (!empty($order_inquiry['doctor_id'])){
Db::rollBack();
Log::getInstance()->error("队列执行失败原因:已分配医生");
return Result::DROP;// 销毁
}
// 检测订单类型
if ($order_inquiry['inquiry_type'] != 2 && $order_inquiry['inquiry_type'] != 4){
Db::rollBack();
Log::getInstance()->error("队列执行失败原因:订单非快速问诊、问诊购药类型");
return Result::DROP;// 销毁
}
// 检测订单退款状态
if (in_array($order_inquiry['inquiry_refund_status'],[1,2,3])){
Db::rollBack();
// 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
Log::getInstance()->error("队列执行失败原因:订单存在退款");
return Result::DROP;// 销毁
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] != 2){
Db::rollBack();
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance()->info("订单状态错误:当前为" . $order_inquiry['inquiry_status'] . " 无法进行分配");
return Result::DROP;// 销毁
}
// 检测订单支付状态
if ($order_inquiry['inquiry_pay_status'] != 2){
Db::rollBack();
// 支付状态1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
Log::getInstance()->info("订单支付状态错误:当前为" . $order_inquiry['inquiry_pay_status'] . " 无法进行分配");
return Result::DROP;// 销毁
}
// 检测订单分配时间
$pay_time = strtotime($order_inquiry['pay_time']);
$diff_time = time() - $pay_time;
if ($diff_time < 0){
Db::rollBack();
Log::getInstance()->info("订单支付状态错误:时间计算错误");
return Result::DROP;// 销毁
}
$redis = $this->container->get(Redis::class);
if ($diff_time > 300){
// 超出5分钟执行退款
Log::getInstance()->info("超出5分钟执行退款");
$redis_key = "inquiryRefund" . $order_inquiry['order_inquiry_id'];
$redis_value = $redis->get($redis_key);
if (!empty($redis_value)){
// 判断退款次数
if ($redis_value >= 3){
Log::getInstance()->info("退款取消,退款失败次数过多");
// 加入短信队列
return Result::DROP;// 销毁
}
$redis_value = $redis_value + 1;
}else{
$redis_value = 1;
}
try {
$InquiryService = new InquiryService();
$InquiryService->inquiryRefund($order_inquiry['order_inquiry_id'],"暂无医生接诊");
$redis->set($redis_key,$redis_value);
} catch (\Exception $e) {
Db::rollBack();
Log::getInstance()->error("队列执行失败原因:退款失败,原因:" . $e->getMessage());
return Result::REQUEUE; // 重回队列
}
}
// 分配医生
$UserDoctorService = new UserDoctorService();
$doctor_id = $UserDoctorService->getInquiryAssignDoctor($order_inquiry['inquiry_type']);
if (empty($doctor_id)){
Db::rollBack();
Log::getInstance()->error("重回队列,目前没有合适医生");
$redis_key = "AssignDoctor" . $order_inquiry['order_inquiry_id'];
$redis_value = $redis->get($redis_key);
if (!empty($redis_value)){
$redis_value = $redis_value + 1;
}else{
$redis_value = 1;
}
// 添加缓存添加失败情况不考虑最终都会睡眠5秒
$redis->set($redis_key,$redis_value);
// 执行睡眠,防止重复执行队列
// 执行规则第一次5秒第二次10秒。以5的倍数增加
sleep($redis_value * 5);
return Result::REQUEUE; // 重回队列
}
// 更改数据库
$data = array();
$data['doctor_id'] = $doctor_id;
$data['inquiry_status'] = 3; // 待接诊
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params,$data);
Db::commit();
Log::getInstance()->error("分配医生 队列执行成功");
} catch (\Exception $e) {
Db::rollBack();
Log::getInstance()->error("队列执行失败原因:" . $e->getMessage());
return Result::REQUEUE; // 重回队列
}
try {
// 专家-公益
$ImService = new ImService();
// 检测并创建患者账号
$ImService->createAccount($order_inquiry['user_id']);
// 获取订单医生数据
$params = array();
$params['doctor_id'] = $doctor_id;
$user_doctor = UserDoctor::getOne($params);
if (empty($user_doctor)){
Log::getInstance()->info("医生数据错误");
return Result::ACK;
}
// 检测并创建医生账号
$ImService->createAccount($doctor_id);
// 医生给患者发送消息
$message = new Message();
$arg = array();
$arg['From_Account'] = $user_doctor['user_id']; // 发送方user_id 如系统发送,无需填写
$arg['To_Account'] = $order_inquiry['user_id']; // 接收方user_id
$arg['SendMsgControl'] = ['NoUnread'];
$arg['MsgBody'] = [
[
"MsgType" => "TIMTextElem",
"MsgContent" => [
"Text" => "等待医生接诊",
],
]
];
// 自定义消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['is_system'] = 1;
$arg['CloudCustomData'] = json_encode($cloud_custom_data,JSON_UNESCAPED_UNICODE);
$message->sendMessage($arg);
}catch (\Exception $e) {
// 验证失败
Log::getInstance()->error("分配医生成功,发送系统问诊消息失败:" . $e->getMessage());
// 加入消息通知队列
return Result::ACK;
}
// 加入消息通知队列
return Result::ACK;
}
}