新增医生设置视频预约时间 及延迟通知队列

This commit is contained in:
wucongxing 2024-01-16 14:57:01 +08:00
parent 3f81b6e73d
commit ccc4934700
6 changed files with 487 additions and 19 deletions

View File

@ -0,0 +1,187 @@
<?php
declare(strict_types=1);
namespace App\Amqp\Consumer;
use App\Model\OrderInquiry;
use App\Model\OrderInquiryVideo;
use App\Model\User;
use App\Model\UserDoctor;
use App\Services\SendSmsService;
use App\Utils\Log;
use Hyperf\Amqp\Message\ConsumerDelayedMessageTrait;
use Hyperf\Amqp\Message\ProducerDelayedMessageTrait;
use Hyperf\Amqp\Message\Type;
use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\DbConnection\Db;
use PhpAmqpLib\Message\AMQPMessage;
#[Consumer(nums: 1)]
class SendVideoNoticeDelayDirectConsumer extends ConsumerMessage
{
use ProducerDelayedMessageTrait;
use ConsumerDelayedMessageTrait;
protected string $exchange = 'amqp.delay.direct';
protected ?string $queue = 'send.video.notice.delay.queue';
protected string $type = Type::DIRECT; //Type::FANOUT;
protected string|array $routingKey = 'SendVideoNotice';
public function consumeMessage($data, AMQPMessage $message): string
{
Log::getInstance("queue-SendVideoNotice")->info("开始:" . json_encode($data, JSON_UNESCAPED_UNICODE));
// 检测参数
if (!isset($data['order_inquiry_id'])){
Log::getInstance("queue-SendVideoNotice")->error("入参错误");
return Result::DROP;
}
// 获取问诊订单数据
$params = array();
$params['order_inquiry_id'] = $data['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)){
Log::getInstance("queue-SendVideoNotice")->error("订单错误" );
return Result::ACK;
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] == 7) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance("queue-SendVideoNotice")->error("订单已取消" );
return Result::ACK;
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] == 5) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance("queue-SendVideoNotice")->error("订单已完成" );
return Result::ACK;
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] == 6) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance("queue-SendVideoNotice")->error("订单已结束" );
return Result::ACK;
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] == 3) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance("queue-SendVideoNotice")->error("订单待接诊" );
return Result::ACK;
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] == 1) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance("queue-SendVideoNotice")->error("订单待支付" );
return Result::ACK;
}
if (!in_array($order_inquiry['inquiry_refund_status'], [0, 4, 5])) {
// 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
Log::getInstance("queue-SendVideoNotice")->error("订单存在退款" );
return Result::DROP;
}
// 获取视频预约状态
$params = array();
$params['order_inquiry_id'] = $data['order_inquiry_id'];
$order_inquiry_video = OrderInquiryVideo::getOne($params);
if (empty($order_inquiry_video)){
Log::getInstance("queue-SendVideoNotice")->error("缺少视频预约数据" );
return Result::DROP;
}
if ($order_inquiry_video['is_send_reservation_notice'] == 1){
Log::getInstance("queue-SendVideoNotice")->info("已发送过一次通知,无需发送" );
return Result::ACK;
}
// 检测是否已开过视频
if ($order_inquiry_video['is_video'] == 1){
Log::getInstance("queue-SendVideoNotice")->info("已开过视频,无需发送" );
return Result::ACK;
}
// 检测通知时间
$reservation_time = strtotime($order_inquiry_video['reservation_time']);
if ($reservation_time < time()){
Log::getInstance("queue-SendVideoNotice")->info("当前时间已超过预约时间,无需发送" );
return Result::ACK;
}
// 5分钟以内
$diff_time = $reservation_time - time();
if ($diff_time > 5* 60){
Log::getInstance("queue-SendVideoNotice")->info("不在发送时间内,无需发送" );
return Result::ACK;
}
// 获取患者用户数据
$params = array();
$params['user_id'] = $order_inquiry['user_id'];
$user = User::getOne($params);
if (empty($user)){
Log::getInstance("queue-SendVideoNotice")->error("患者用户数据错误" );
return Result::ACK;
}
// 获取医生数据
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params);
if (empty($user_doctor)){
Log::getInstance("queue-SendVideoNotice")->error("医生数据错误" );
return Result::ACK;
}
// 获取医生用户表数据
$params = array();
$params['user_id'] = $user_doctor['user_id'];
$doctor_user = User::getOne($params);
if (empty($doctor_user)){
Log::getInstance("queue-SendVideoNotice")->error("医生用户数据错误" );
return Result::ACK;
}
Db::beginTransaction();
try {
// 患者-通知患者视频
$sendSmsService = new SendSmsService($user['mobile']);
$sendSmsService->noticePatientVideo($user_doctor['user_name']);
// 医生-通知医生视频
$sendSmsService = new SendSmsService($doctor_user['mobile']);
$sendSmsService->noticeDoctorVideo($order_inquiry['patient_name']);
// 修改通知表
$data = array();
$data['is_send_reservation_notice'] = 1;
$params = array();
$params['inquiry_video_id'] = $order_inquiry_video['inquiry_video_id'];
$res = OrderInquiryVideo::edit($params,$data);
if (!$res){
Db::rollBack();
Log::getInstance("queue-SendVideoNotice")->error("修改失败");
return Result::ACK;
}
}catch (\Throwable $e){
Db::rollBack();
Log::getInstance("queue-SendVideoNotice")->error($e->getMessage());
return Result::ACK;
}
return Result::ACK;
}
}

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Amqp\Producer;
use Hyperf\Amqp\Annotation\Producer;
use Hyperf\Amqp\Message\ProducerDelayedMessageTrait;
use Hyperf\Amqp\Message\ProducerMessage;
use Hyperf\Amqp\Message\Type;
/**
* 视频问诊即将开始通知
*/
#[Producer]
class SendVideoNoticeDelayDirectProducer extends ProducerMessage
{
use ProducerDelayedMessageTrait;
protected string $exchange = 'amqp.delay.direct';
protected string $type = Type::DIRECT;
protected string|array $routingKey = 'SendVideoNotice';
/**
* @param $data
* [
* "order_inquiry_id":"问诊订单id"
* ]
*/
public function __construct($data)
{
$this->payload = $data;
}
}

View File

@ -917,7 +917,7 @@ class ImService extends BaseService
}
/**
* 订单结束,提醒赠送回合数(医生端)
* 订单结束,提醒赠送回合数-发送医生
* @param array|object $order_inquiry 问诊订单数据
* @param string $doctor_user_id 医生用户id
* @param string $patient_user_id 患者用户id
@ -951,4 +951,160 @@ class ImService extends BaseService
throw new BusinessException($e->getMessage());
}
}
/**
* 新增视频预约时间-发送医生
* @param array|object $order_inquiry 问诊订单数据
* @param string $doctor_user_id 医生用户id
* @param string $patient_user_id 患者用户id
* @param string $reservation_time 预约时间
* @return void
*/
public function addVideoReservationTimeToDoctor(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id,string $reservation_time): void
{
try {
// 发送消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['is_system'] = 1;
$cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
$cloud_custom_data['inquiry_mode'] = $order_inquiry['inquiry_mode'];
$cloud_custom_data['message_rounds'] = 0;
$cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
$cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
$cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];
$date = date("Y年m月d日 H点i分",strtotime($reservation_time));
// 消息内容 医生-患者
$message_content_data = array();
$message_content_data['message_type'] = 16;
$message_content_data['title'] = "";
$message_content_data['desc'] = "您和患者已约定于{$date}进行视频问诊,请提前进入聊天页面,再约定时间发起视频";
$message_content = [
'Data' => json_encode($message_content_data, JSON_UNESCAPED_UNICODE),
];
$this->sendMessage($doctor_user_id, $patient_user_id, $message_content, "TIMCustomElem", $cloud_custom_data);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage());
}
}
/**
* 修改视频预约时间-发送医生
* @param array|object $order_inquiry 问诊订单数据
* @param string $doctor_user_id 医生用户id
* @param string $patient_user_id 患者用户id
* @param string $reservation_time 预约时间
* @return void
*/
public function modifyVideoReservationTimeToDoctor(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id,string $reservation_time): void
{
try {
// 发送消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['is_system'] = 1;
$cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
$cloud_custom_data['inquiry_mode'] = $order_inquiry['inquiry_mode'];
$cloud_custom_data['message_rounds'] = 0;
$cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
$cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
$cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];
$date = date("Y年m月d日 H点i分",strtotime($reservation_time));
// 消息内容 医生-患者
$message_content_data = array();
$message_content_data['message_type'] = 16;
$message_content_data['title'] = "";
$message_content_data['desc'] = "您和患者重新约定于{$date}进行视频问诊,请提前进入聊天页面,再约定时间发起视频";
$message_content = [
'Data' => json_encode($message_content_data, JSON_UNESCAPED_UNICODE),
];
$this->sendMessage($doctor_user_id, $patient_user_id, $message_content, "TIMCustomElem", $cloud_custom_data);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage());
}
}
/**
* 新增视频预约时间-发送患者
* @param array|object $order_inquiry 问诊订单数据
* @param string $doctor_user_id 医生用户id
* @param string $patient_user_id 患者用户id
* @param string $reservation_time 预约时间
* @return void
*/
public function addVideoReservationTimeToPatient(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id,string $reservation_time): void
{
try {
// 发送消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['is_system'] = 1;
$cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
$cloud_custom_data['inquiry_mode'] = $order_inquiry['inquiry_mode'];
$cloud_custom_data['message_rounds'] = 0;
$cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
$cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
$cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];
$date = date("Y年m月d日 H点i分",strtotime($reservation_time));
// 消息内容 医生-患者
$message_content_data = array();
$message_content_data['message_type'] = 17;
$message_content_data['title'] = "";
$message_content_data['desc'] = "您和医生已约定于{$date}进行视频问诊,请提前进入聊天页面,准备接听。";
$message_content = [
'Data' => json_encode($message_content_data, JSON_UNESCAPED_UNICODE),
];
$this->sendMessage($doctor_user_id, $patient_user_id, $message_content, "TIMCustomElem", $cloud_custom_data);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage());
}
}
/**
* 修改视频预约时间-发送患者
* @param array|object $order_inquiry 问诊订单数据
* @param string $doctor_user_id 医生用户id
* @param string $patient_user_id 患者用户id
* @param string $reservation_time 预约时间
* @return void
*/
public function modifyVideoReservationTimeToPatient(array|object $order_inquiry, string $doctor_user_id, string $patient_user_id,string $reservation_time): void
{
try {
// 发送消息
$cloud_custom_data = array();
$cloud_custom_data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$cloud_custom_data['is_system'] = 1;
$cloud_custom_data['inquiry_type'] = $order_inquiry['inquiry_type'];
$cloud_custom_data['inquiry_mode'] = $order_inquiry['inquiry_mode'];
$cloud_custom_data['message_rounds'] = 0;
$cloud_custom_data['patient_family_data']['patient_name'] = $order_inquiry['patient_name'];
$cloud_custom_data['patient_family_data']['patient_sex'] = $order_inquiry['patient_sex'];
$cloud_custom_data['patient_family_data']['patient_age'] = $order_inquiry['patient_age'];
$date = date("Y年m月d日 H点i分",strtotime($reservation_time));
// 消息内容 医生-患者
$message_content_data = array();
$message_content_data['message_type'] = 17;
$message_content_data['title'] = "";
$message_content_data['desc'] = "您和医生重新约定于{$date}进行视频问诊,请提前进入聊天页面,准备接听。";
$message_content = [
'Data' => json_encode($message_content_data, JSON_UNESCAPED_UNICODE),
];
$this->sendMessage($doctor_user_id, $patient_user_id, $message_content, "TIMCustomElem", $cloud_custom_data);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage());
}
}
}

View File

@ -5,6 +5,8 @@ namespace App\Services;
use App\Amqp\Producer\AutoFinishInquiryDelayDirectProducer;
use App\Amqp\Producer\CancelUnInquiryOrdersDelayDirectProducer;
use App\Amqp\Producer\CancelUnpayOrdersDelayDirectProducer;
use App\Amqp\Producer\SendSmsMessageProducer;
use App\Amqp\Producer\SendVideoNoticeDelayDirectProducer;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
@ -41,6 +43,7 @@ use App\Utils\PcreMatch;
use Extend\Wechat\WechatPay;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Producer;
use Hyperf\Context\ApplicationContext;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
@ -1314,8 +1317,6 @@ class InquiryService extends BaseService
/**
* 医生设置视频预约时间
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function addVideoReservationDate(): array
{
@ -1391,8 +1392,6 @@ class InquiryService extends BaseService
// 创建订单
Db::beginTransaction();
$generator = $this->container->get(IdGeneratorInterface::class);
try {
if (empty($order_inquiry_video)){
// 创建视频预约数据
@ -1433,7 +1432,15 @@ class InquiryService extends BaseService
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params);
if (empty($user_doctor)) {
return fail(HttpEnumCode::SERVER_ERROR, "赠送失败");
return fail(HttpEnumCode::SERVER_ERROR, "设置失败");
}
// 获取订单用户数据
$params = array();
$params['user_id'] = $order_inquiry['user_id'];
$user = User::getOne($params);
if (empty($user)){
return fail(HttpEnumCode::SERVER_ERROR, "设置失败");
}
// 发送im消息
@ -1441,23 +1448,33 @@ class InquiryService extends BaseService
if ($is_reservation){
// 修改
// 已成功预约视频问诊时间-医生
$imService->addVideoReservationTimeToDoctor($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id'],$reservation_time);
// 已成功预约视频问诊时间-患者
$imService->addVideoReservationTimeToPatient($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id'],$reservation_time);
}else{
// 新增
// 已成功修改视频问诊时间-医生
$imService->modifyVideoReservationTimeToDoctor($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id'],$reservation_time);
// 已成功修改视频问诊时间-患者
$imService->modifyVideoReservationTimeToPatient($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id'],$reservation_time);
}
// 发送短信-患者-视频预约成功
// 患者-通知患者视频时间
$sendSmsService = new SendSmsService($user['mobile']);
$sendSmsService->noticePatientVideoTime($user_doctor['user_name'],$reservation_time);
// 成功预约视频问诊时间
// 成功修改视频问诊时间
// 赠送回合数消息
$imService->giveFreeRounds($order_inquiry, $user_doctor['user_id'], $order_inquiry['user_id'],$times_number,$give_expiration_time);
// 发送站内、订阅失败发送短信消息-患者-赠送回合数
$MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']);
$MessagePush->doctorGiveFreeRounds($times_number,$give_expiration_time);
// 增加延迟队列通知-视频问诊即将开始
$time = strtotime($reservation_time) - 4*60;
$message = new SendVideoNoticeDelayDirectProducer($data);
$message->setDelayMs(1000 * $time);
$producer = $this->container->get(Producer::class);
$res = $producer->produce($message);
if (!$res) {
return fail(HttpEnumCode::SERVER_ERROR, "设置失败");
}
}catch (\Throwable $e){
Log::getInstance("InquiryService-addDoctorGiveInquiryOrder")->error($e->getMessage());
}

View File

@ -2607,7 +2607,7 @@ class MessagePush extends BaseService
// 短信
$sms_data = array();
$sms_data['template_code'] = "SMS_464531282";
$sms_data['template_code'] = "SMS_464725006";
$sms_data['scene_desc'] = "医生赠送免费回合数";
$sms_data['phone'] = $this->user['mobile'];
$sms_data['user_id'] = $this->user['user_id'];

View File

@ -0,0 +1,72 @@
<?php
namespace App\Services;
// 短信发送
use App\Amqp\Producer\SendSmsMessageProducer;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Utils\Log;
use Extend\Alibaba\Dysms;
use Hyperf\Amqp\Producer;
use Hyperf\Context\ApplicationContext;
class SendSmsService extends BaseService
{
public string $mobile;
public function __construct(string|int $mobile)
{
if (!empty($mobile)){
$this->mobile = $mobile;
}
}
// 患者-通知患者视频时间
public function noticePatientVideoTime(string $doctor_name,$reservation_time){
try {
// 发送短信-患者-视频预约成功
$template_code = "SMS_464481352";
$scene_desc = "通知患者视频时间";
$template_param = array();
$template_param['name'] = $doctor_name;
$template_param['time'] = date('Y-m-d H:i', strtotime($reservation_time));
Dysms::sendSms($this->mobile,$template_param,$template_code,$scene_desc);
}catch (\Throwable $e){
throw new BusinessException("短信发送失败",HttpEnumCode::CODE_FAIL);
}
}
// 患者-通知患者视频
public function noticePatientVideo(string $doctor_name){
try {
// 发送短信-患者-视频预约成功
$template_code = "SMS_464436348";
$scene_desc = "通知患者视频";
$template_param = array();
$template_param['name'] = $doctor_name;
Dysms::sendSms($this->mobile,$template_param,$template_code,$scene_desc);
}catch (\Throwable $e){
throw new BusinessException("短信发送失败",HttpEnumCode::CODE_FAIL);
}
}
// 医生-通知医生视频
public function noticeDoctorVideo(string $patient_name){
try {
// 发送短信-患者-视频预约成功
$template_code = "SMS_464486306";
$scene_desc = "通知医生视频";
$template_param = array();
$template_param['name'] = $patient_name;
Dysms::sendSms($this->mobile,$template_param,$template_code,$scene_desc);
}catch (\Throwable $e){
throw new BusinessException("短信发送失败",HttpEnumCode::CODE_FAIL);
}
}
}