新增分配医生队列

This commit is contained in:
wucongxing 2023-03-07 17:54:56 +08:00
parent dcb2149815
commit 63894f37a6
13 changed files with 594 additions and 58 deletions

View File

@ -0,0 +1,122 @@
<?php
declare(strict_types=1);
namespace App\Amqp\Consumer;
use App\Model\OrderInquiry;
use App\Services\UserDoctorService;
use App\Utils\Log;
use Hyperf\Amqp\Result;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Redis\Redis;
use PhpAmqpLib\Message\AMQPMessage;
/**
* 分配医生
* 快速问诊、问诊购药等订单支付完成后,进行分配医生
*/
#[Consumer(exchange: 'amqp.direct', routingKey: 'AssignDoctor', queue: 'assign.doctor.queue', nums: 1)]
class AssignDoctorConsumer extends ConsumerMessage
{
public function consumeMessage($data, AMQPMessage $message): string
{
Log::getInstance()->error("开始执行 分配医生 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE));
try {
// 获取订单数据
$params = array();
$params['order_inquiry_id'] = $data['order_inquiry_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
Log::getInstance()->error("队列执行失败原因:未查询到对应订单数据");
return Result::DROP;// 销毁
}
// 检测订单分配状态
if (!empty($order_inquiry['doctor_id'])){
Log::getInstance()->error("队列执行失败原因:已分配医生");
return Result::DROP;// 销毁
}
// 检测订单类型
if ($order_inquiry['inquiry_type'] != 2 && $order_inquiry['inquiry_type'] != 4){
Log::getInstance()->error("队列执行失败原因:订单非快速问诊、问诊购药类型");
return Result::DROP;// 销毁
}
// 检测订单退款状态
if (in_array($order_inquiry['inquiry_refund_status'],[1,2,3])){
// 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
Log::getInstance()->error("队列执行失败原因:订单存在退款");
return Result::DROP;// 销毁
}
// 检测订单状态
if ($order_inquiry['inquiry_status'] != 2){
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
Log::getInstance()->info("订单状态错误:当前为" . $order_inquiry['inquiry_status'] . " 无法进行分配");
return Result::DROP;// 销毁
}
// 检测订单支付状态
if ($order_inquiry['inquiry_pay_status'] != 2){
// 支付状态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){
Log::getInstance()->info("订单支付状态错误:时间计算错误");
return Result::DROP;// 销毁
}
if ($diff_time > 300){
// 超出5分钟执行退款
}
$redis = $this->container->get(Redis::class);
$redis_key = $order_inquiry['order_inquiry_id'];
// 分配医生
$UserDoctorService = new UserDoctorService();
$doctor_id = $UserDoctorService->getInquiryAssignDoctor($order_inquiry['inquiry_type']);
if (empty($doctor_id)){
Log::getInstance()->error("重回队列,目前没有合适医生");
$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;
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params,$data);
Log::getInstance()->error("分配医生 队列执行成功");
return Result::ACK;
} catch (\Exception $e) {
Log::getInstance()->error("队列执行失败原因:" . $e->getMessage());
return Result::REQUEUE; // 重回队列
}
}
}

View File

@ -36,7 +36,7 @@ class CancelUnpayOrdersDelayDirectConsumer extends ConsumerMessage
public function consumeMessage($data, AMQPMessage $message): string
{
Log::getInstance()->error("开始执行队列:" . json_encode($data, JSON_UNESCAPED_UNICODE));
Log::getInstance()->error("开始执行 取消未支付订单 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE));
try {
// 获取订单数据
@ -80,7 +80,7 @@ class CancelUnpayOrdersDelayDirectConsumer extends ConsumerMessage
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params,$data);
Log::getInstance()->error("队列执行成功");
Log::getInstance()->error("取消未支付订单 队列执行成功");
return Result::ACK;
} catch (\Exception $e) {
Log::getInstance()->error("队列执行失败原因:" . $e->getMessage());

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\Amqp\Producer;
use Hyperf\Amqp\Annotation\Producer;
use Hyperf\Amqp\Message\ProducerMessage;
/**
* 分配医生
* 快速问诊、问诊购药等订单支付完成后,进行分配医生
*/
#[Producer(exchange: 'amqp.direct', routingKey: 'AssignDoctor')]
class AssignDoctorProducer extends ProducerMessage
{
public function __construct($data)
{
$this->payload = $data;
}
}

View File

@ -2,15 +2,18 @@
namespace App\Controller;
use App\Amqp\Producer\AssignDoctorProducer;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\OrderInquiry;
use App\Services\BaseService;
use App\Utils\Log;
use Extend\Wechat\WechatPay;
use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\HttpMessage\Stream\SwooleFileStream;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Utils\ApplicationContext;
use Psr\Http\Message\ResponseInterface;
class CallBackController extends AbstractController
@ -46,7 +49,6 @@ class CallBackController extends AbstractController
Log::getInstance()->info("微信支付回调数据错误");
return $server->serve();
}
dump($message);
// 查询订单
$params = array();
@ -57,7 +59,6 @@ class CallBackController extends AbstractController
Log::getInstance()->info("非法订单");
return $server->serve();
}
dump(1);
// 验证订单状态
if ($order_inquiry['inquiry_status'] != 1){
@ -66,7 +67,7 @@ class CallBackController extends AbstractController
Log::getInstance()->info("订单状态错误:当前为" . $order_inquiry['inquiry_status']);
return $server->serve();
}
dump(2);
// 支付状态无需验证,如第一次支付失败,会修改支付状态,再次支付时,会出现验证不通过的情况
// 修改支付状态
@ -75,6 +76,13 @@ class CallBackController extends AbstractController
// 支付成功
$data['inquiry_pay_status'] = 2;
$data['pay_time'] = date('Y-m-d H:i:s',strtotime($message['success_time']));// 支付时间
if ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3){
// 专家-公益
$data['inquiry_status'] = 3;// 3:待接诊
}elseif ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4){
// 快速-购药
$data['inquiry_status'] = 2;// 2:待分配
}
}elseif($message['trade_state'] == "CLOSED"){
// 已关闭
$data['inquiry_pay_status'] = 6;
@ -95,17 +103,59 @@ class CallBackController extends AbstractController
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params,$data);
dump(3);
// 处理分配医生问题
if ($message['trade_state'] == "SUCCESS"){
if ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4){
// 快速-购药
// 加入分配医生队列
$data = array();
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$message = new AssignDoctorProducer($data);
$producer = ApplicationContext::getContainer()->get(Producer::class);
$result = $producer->produce($message);
if (!$result) {
Db::rollBack();
Log::getInstance()->info("加入分配医生队列失败");
return $this->wxPayErrorReturn("加入分配医生队列失败");
}
}elseif ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3){
// 专家-公益
// 创建患者im账号
// 检测医生im账号
// 患者给医生发送im问诊消息
// 消息订阅通知队列
}
}
Db::commit();
return $server->serve();
}catch (\Exception $e) {
// 验证失败
Db::rollBack();
Log::getInstance()->error("微信支付回调数据验证失败:" . $e->getMessage());
return $this->response->withStatus(500)->withBody(new SwooleStream(strval(json_encode(['code' => 'ERROR', 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE))));
}
return $this->wxPayErrorReturn($e->getMessage());
}
}
/**
* 微信支付返回错误响应
* @param string $message
* @return ResponseInterface
*/
protected function wxPayErrorReturn(string $message): ResponseInterface
{
return $this->response
->withStatus(500)
->withBody(
new SwooleStream(
strval(
json_encode(['code' => 'ERROR', 'message' => $message], JSON_UNESCAPED_UNICODE)
)
)
);
}
// im回调
public function imCallBack(){
$request_params = $this->request->all();

View File

@ -5,6 +5,8 @@ namespace App\Controller;
use App\Amqp\Producer\PrescriptionDistributePhProducer;
use App\Constants\HttpEnumCode;
use App\Exception\BusinessException;
use App\Model\DoctorInquiryTime;
use App\Model\OrderInquiry;
use App\Request\UserRequest;
use App\Services\UserDoctorService;
use App\Services\UserService;
@ -78,21 +80,42 @@ class UserController extends AbstractController
// $wx_info_data = $weChat->codeToSession("0219AIFa1ROoUE0e4lIa1bO27I29AIF9");
// dump($wx_info_data);die;
$out_trade_no = $this->request->input('out_trade_no');
$generator = $this->container->get(IdGeneratorInterface::class);
// 发起支付
// $out_trade_no = $this->request->input('out_trade_no');
// $generator = $this->container->get(IdGeneratorInterface::class);
//
// $WechatPay = new WechatPay(1);
//
// // 获取预支付交易会话标识
// $total = 0.01 * 100;
// $prepay = $WechatPay->getJsapiPrepayId($out_trade_no,$total,"omgU35DlE-rxTAGgcBjOuc4xdcX8");
// if (empty($prepay)){
// return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
// }
//
// // 获取小程序支付配置
// $pay_config = $WechatPay->getAppletsPayConfig($prepay['prepay_id']);
// return $this->response->json($pay_config);
// 发起退款
$WechatPay = new WechatPay(1);
// 获取预支付交易会话标识
$total = 0.01 * 100;
$prepay = $WechatPay->getJsapiPrepayId($out_trade_no,$total,"omgU35DlE-rxTAGgcBjOuc4xdcX8");
if (empty($prepay)){
return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
}
$params = array();
$params['order_inquiry_id'] = 1;
$order_inquiry = OrderInquiry::getOne($params);
// 获取小程序支付配置
$pay_config = $WechatPay->getAppletsPayConfig($prepay['prepay_id']);
return $this->response->json($pay_config);
$options = array();
$options['transaction_id'] = $order_inquiry['escrow_trade_no'];
$options['out_refund_no'] = $order_inquiry['inquiry_refund_no'];
$options['reason'] = "退款原因";
$options['amount'] = [
'refund' => 0.01 * 100,
'total' => 0.01 * 100,
'currency' => "CNY",
];
$result = $WechatPay->refund($options);
dump($result);
}
}

View File

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Model;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $inquiry_time_id 主键id
* @property int $doctor_id 医生id
* @property int $inquiry_type 接诊类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @property int $inquiry_mode 接诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @property string $inquiry_date 日期(可为空)
* @property string $start_time 开始时间
* @property string $end_time 结束时间
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
*/
class DoctorInquiryTime extends Model
{
use Snowflake;
/**
* The table associated with the model.
*/
protected ?string $table = 'doctor_inquiry_time';
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['inquiry_time_id', 'doctor_id', 'inquiry_type', 'inquiry_mode', 'inquiry_date', 'start_time', 'end_time', 'created_at', 'updated_at'];
protected string $primaryKey = "inquiry_time_id";
/**
* 关联医生表
*/
public function UserDoctor(): HasOne
{
return $this->hasOne(UserDoctor::class, 'doctor_id','doctor_id');
}
/**
* 获取信息-单条
* @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 $params
* @return bool
*/
public static function getExists(array $params): bool
{
return self::where($params)->exists();
}
/**
* 获取数据-
* 关联医生表
* @param array $params
* @param array $user_doctor_params
* @param array $fields
* @return array|Collection
*/
public static function getWithDoctorList(array $params = [],array $user_doctor_params = [], array $fields = ['*']): array|Collection
{
return self::whereHas('UserDoctor' , function($query) use ($user_doctor_params){
$query->where($user_doctor_params);
})
->where($params)
->get($fields);
}
}

View File

@ -8,22 +8,24 @@ namespace App\Model;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Database\Query\Builder;
use Hyperf\Snowflake\Concern\Snowflake;
/**
* @property int $order_inquiry_id 主键id
* @property int $user_id 用户id-患者
* @property int $patient_id 患者id
* @property int $doctor_id 医生id未分配时为null
* @property int $family_id 家庭成员id就诊用户
* @property string $order_inquiry_id 主键id
* @property string $user_id 用户id-患者
* @property string $patient_id 患者id
* @property string $doctor_id 医生id未分配时为null
* @property string $family_id 家庭成员id就诊用户
* @property int $inquiry_type 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @property int $inquiry_mode 订单问诊方式1:图文 2:视频 3:语音 4:电话 5:会员)
* @property int $inquiry_status 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
* @property int $is_delete 删除状态0: 1:是)
* @property int $inquiry_refund_status 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
* @property string $inquiry_refund_no 系统退款单号
* @property int $inquiry_pay_channel 支付渠道1:小程序支付 2:微信扫码支付)
* @property int $inquiry_pay_status 支付状态1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
* @property int $inquiry_no 订单编号
* @property int $inquiry_no 系统订单编号
* @property string $escrow_trade_no 第三方支付流水号
* @property string $amount_total 订单金额
* @property string $payment_amount_total 实际付款金额
@ -43,6 +45,7 @@ use Hyperf\Snowflake\Concern\Snowflake;
* @property int $patient_age 患者年龄-就诊人
* @property \Carbon\Carbon $created_at 创建时间
* @property \Carbon\Carbon $updated_at 修改时间
* @property-read UserDoctor $UserDoctor
*/
class OrderInquiry extends Model
{
@ -56,12 +59,7 @@ class OrderInquiry extends Model
/**
* The attributes that are mass assignable.
*/
protected array $fillable = ['order_inquiry_id', 'user_id', 'patient_id', 'doctor_id', 'family_id', 'inquiry_type', 'inquiry_mode', 'inquiry_status', 'is_delete', 'inquiry_refund_status', 'inquiry_pay_channel', 'inquiry_pay_status', 'inquiry_no', 'escrow_trade_no', 'amount_total', 'payment_amount_total', 'pay_time', 'reception_time', 'complete_time', 'finish_time', 'settlement_amount_total', 'settlement_status', 'settlement_time', 'cancel_time', 'cancel_reason', 'cancel_remarks', 'patient_name', 'patient_name_mask', 'patient_sex', 'patient_age', 'created_at', 'updated_at'];
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['order_inquiry_id' => 'string', 'user_id' => 'string', 'patient_id' => 'string', 'doctor_id' => 'string', 'family_id' => 'string', 'inquiry_type' => 'integer', 'inquiry_mode' => 'integer', 'inquiry_status' => 'integer', 'is_delete' => 'integer', 'inquiry_refund_status' => 'integer', 'inquiry_pay_channel' => 'integer', 'inquiry_pay_status' => 'integer', 'inquiry_no' => 'integer', 'settlement_status' => 'integer', 'cancel_reason' => 'integer', 'patient_sex' => 'integer', 'patient_age' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];
protected array $fillable = ['order_inquiry_id', 'user_id', 'patient_id', 'doctor_id', 'family_id', 'inquiry_type', 'inquiry_mode', 'inquiry_status', 'is_delete', 'inquiry_refund_status', 'inquiry_refund_no', 'inquiry_pay_channel', 'inquiry_pay_status', 'inquiry_no', 'escrow_trade_no', 'amount_total', 'payment_amount_total', 'pay_time', 'reception_time', 'complete_time', 'finish_time', 'settlement_amount_total', 'settlement_status', 'settlement_time', 'cancel_time', 'cancel_reason', 'cancel_remarks', 'patient_name', 'patient_name_mask', 'patient_sex', 'patient_age', 'created_at', 'updated_at'];
protected string $primaryKey = "order_inquiry_id";

View File

@ -102,9 +102,9 @@ class InquiryService extends BaseService
// 确定支付渠道
// 支付渠道1:小程序支付 2:微信扫码支付)
if ($request_params['client_type'] == 1){
if ($request_params['client_type'] == 1) {
$inquiry_pay_channel = 1;
}elseif ($request_params['client_type'] == 2){
} elseif ($request_params['client_type'] == 2) {
$inquiry_pay_channel = 2;
}
@ -176,14 +176,14 @@ class InquiryService extends BaseService
}
// 增加问诊优惠卷表
if (!empty($user_coupon)){
if (!empty($user_coupon)) {
$data = array();
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];// 订单-问诊id
$data['user_coupon_id'] = $user_coupon['user_coupon_id'];
$data['coupon_name'] = $user_coupon['coupon']['coupon_name'];
$data['coupon_use_price'] = $user_coupon['coupon']['coupon_price'];
$order_inquiry_coupon = OrderInquiryCoupon::addOrderInquiryCoupon($data);
if (empty($order_inquiry_coupon)){
if (empty($order_inquiry_coupon)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
}
@ -244,9 +244,9 @@ class InquiryService extends BaseService
$WechatPay = new WechatPay(1);
// 获取预支付交易会话标识
$total = $inquiry_price * 100;
$prepay = $WechatPay->getJsapiPrepayId($order_inquiry['inquiry_no'],$total,$user_info['open_id']);
if (empty($prepay)){
$total = $inquiry_price * 100;
$prepay = $WechatPay->getJsapiPrepayId($order_inquiry['inquiry_no'], $total, $user_info['open_id']);
if (empty($prepay)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
}
@ -260,9 +260,9 @@ class InquiryService extends BaseService
$message = new CancelUnpayOrdersDelayDirectProducer($data);
$message->setDelayMs(1000 * 60 * 30);
$producer = $this->container->get(Producer::class) ;
$producer = $this->container->get(Producer::class);
$res = $producer->produce($message);
if(!$res){
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
}
@ -277,7 +277,7 @@ class InquiryService extends BaseService
$result['amount_total'] = $inquiry_price; // 订单金额
$result['inquiry_no'] = $order_inquiry['inquiry_no']; // 订单编号
$result['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; // 订单主键id
$result['created_at'] = date('Y-m-d H:i:s',strtotime($order_inquiry['created_at'])); // 创建时间
$result['created_at'] = date('Y-m-d H:i:s', strtotime($order_inquiry['created_at'])); // 创建时间
$result['inquiry_type'] = $order_inquiry['inquiry_type']; // 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
$result['pay_config'] = $pay_config; // 小程序支付配置
@ -297,7 +297,7 @@ class InquiryService extends BaseService
$params = array();
$params['inquiry_case_id'] = $inquiry_case_id;
$order_inquiry_case = OrderInquiryCase::getOne($params);
if (empty($order_inquiry_case)){
if (empty($order_inquiry_case)) {
return fail();
}
@ -336,10 +336,10 @@ class InquiryService extends BaseService
];
$params = array();
$params['inquiry_case_id'] = $order_inquiry_case['inquiry_case_id'];
$inquiry_case_product = InquiryCaseProduct::getWithProductList($params,$fields);
if (!empty($inquiry_case_product)){
foreach ($inquiry_case_product as &$item){
if (!empty($item['Product'])){
$inquiry_case_product = InquiryCaseProduct::getWithProductList($params, $fields);
if (!empty($inquiry_case_product)) {
foreach ($inquiry_case_product as &$item) {
if (!empty($item['Product'])) {
$product[] = $item['Product']['product_name'] . ' ' . $item['Product']['product_spec'] . '(' . $item['case_product_num'] . $item['Product']['packaging_unit'] . ')';
}
}
@ -349,9 +349,9 @@ class InquiryService extends BaseService
unset($inquiry_case_product);
// 复诊凭证
if (!empty($order_inquiry_case['diagnose_images'])){
$diagnose_images = explode(',',$order_inquiry_case['diagnose_images']);
foreach ($diagnose_images as &$item){
if (!empty($order_inquiry_case['diagnose_images'])) {
$diagnose_images = explode(',', $order_inquiry_case['diagnose_images']);
foreach ($diagnose_images as &$item) {
$item = addAliyunOssWebsite($item);
}
@ -386,12 +386,16 @@ class InquiryService extends BaseService
/**
* 获取医生接诊中订单数量
* @param string $doctor_id 医生id
* @param string $inquiry_type 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
* @return int
*/
public function getDoctorAcceptingInquiryNum(string $doctor_id): int
public function getDoctorAcceptingInquiryNum(string $doctor_id, string $inquiry_type = ""): int
{
$params = array();
$params['doctor_id'] = $doctor_id;
if (!empty($inquiry_type)){
$params['inquiry_type'] = $inquiry_type; // 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
}
$params['inquiry_status'] = 4; // 已接诊
$params['inquiry_refund_status'] = 0; // 无退款
@ -442,7 +446,7 @@ class InquiryService extends BaseService
* @param int $inquiry_status 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
* @return int
*/
public function getPatientInquiryWithStatus(string $patient_id,int $inquiry_status): int
public function getPatientInquiryWithStatus(string $patient_id, int $inquiry_status): int
{
$params = array();
$params['patient_id'] = $patient_id;

View File

@ -14,6 +14,7 @@ use App\Model\DoctorAccount;
use App\Model\DoctorBankCard;
use App\Model\DoctorExpertise;
use App\Model\DoctorInquiryConfig;
use App\Model\DoctorInquiryTime;
use App\Model\DoctorWord;
use App\Model\Hospital;
use App\Model\InquiryCaseProduct;
@ -25,6 +26,8 @@ use App\Model\OrderPrescriptionIcd;
use App\Model\OrderPrescriptionProduct;
use App\Model\OrderProductItem;
use App\Model\Product;
use App\Model\SystemInquiryConfig;
use App\Model\SystemInquiryTime;
use App\Model\User;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
@ -1415,12 +1418,191 @@ class UserDoctorService extends BaseService
$params[] = ['reception_time', '>', $date];
$inquiry_status_params = array();
$inquiry_status_params = [4, 5];
$order_inquiry = OrderInquiry::getInquiryStatusList($params, $inquiry_status_params);
if (empty($order_inquiry)) {
$inquiry_status_params = [4, 5];// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
$order_inquirys = OrderInquiry::getInquiryStatusList($params, $inquiry_status_params);
if (empty($order_inquirys)) {
return [];
}
return $order_inquiry->toArray();
$result = [];
foreach ($order_inquirys as $item){
$result[] = $item['UserDoctor'];
}
return $result;
}
/**
* 获取快速、购药问诊可分配医生
* @param string $inquiry_type
* @return string
*/
public function getInquiryAssignDoctor(string $inquiry_type,): string
{
// 获取问诊配置
$params = array();
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = 1;
$system_inquiry_config = SystemInquiryConfig::getOne($params);
if (empty($system_inquiry_config)){
return "";
}
// 获取系统工作时间
$params = array();
$params['system_inquiry_config_id'] = $system_inquiry_config['system_inquiry_config_id'];
$system_inquiry_time = SystemInquiryTime::getList($params);
if (empty($system_inquiry_time)){
return "";
}
// 检测当前是否坐班时间
$is_time_pass = false; // 非坐班时间
foreach ($system_inquiry_time as $item){
$now_time = date('H',time()) . date('i',time());
if ($item['start_time'] < $now_time && $item['end_time'] > $now_time){
// 符合当前时间区间
$is_time_pass = true;
}
}
if ($is_time_pass){
// 系统坐班时间
// 获取坐班时间包含当前时间的深度合作医生
$doctor_id = $this->getNowTimePlatDeepCooperationDoctorId($inquiry_type,time());
if (!empty($doctor_id)){
return $doctor_id;
}
}
// 非坐班时间
// 获取深度合作的在线医生
$params = array();
$params['status'] = 1;
$params['idcard_status'] = 1;
$params['iden_auth_status'] = 1;
$params['is_bind_bank'] = 1;
$params['is_online'] = 1;
if ($inquiry_type == 2){
// 快速问诊
$params['is_img_quick_reception'] = 1;
}elseif ($inquiry_type == 4){
// 问诊购药
$params['multi_point_status'] = 1;
}
$params['is_platform_deep_cooperation'] = 1;
$user_doctor = UserDoctor::getOne($params);
if (!empty($user_doctor)){
return $user_doctor['doctor_id'];
}
// 获取在线的自由注册医生
$params = array();
$params['status'] = 1;
$params['idcard_status'] = 1;
$params['iden_auth_status'] = 1;
$params['is_bind_bank'] = 1;
$params['is_online'] = 1;
if ($inquiry_type == 2){
// 快速问诊
$params['is_img_quick_reception'] = 1;
}elseif ($inquiry_type == 4){
// 问诊购药
$params['multi_point_status'] = 1;
}
$user_doctor = UserDoctor::getOne($params);
if (!empty($user_doctor)){
// 获取医生接诊中订单数量
$InquiryService = new InquiryService();
$accepting_inquiry_num = $InquiryService->getDoctorAcceptingInquiryNum($user_doctor['doctor_id'],$inquiry_type);
// 获取医生的最大接诊量
$params = array();
$params['doctor_id'] = $user_doctor['doctor_id'];
$params['inquiry_type'] = $inquiry_type;
$params['inquiry_mode'] = 1;
$doctor_inquiry_config = DoctorInquiryConfig::getOne($params);
if (empty($doctor_inquiry_config)){
return ""; // 未配置最大接诊量,错误数据
}
if ($accepting_inquiry_num < $doctor_inquiry_config['work_num_day']){
// 未超出最大接诊量
return $user_doctor['doctor_id'];
}
}
// 检测当前时间5分钟后坐班时间包含某时间的平台深度合作医生
$doctor_id = $this->getNowTimePlatDeepCooperationDoctorId($inquiry_type,strtotime ("+5 minute"));
if (!empty($doctor_id)){
return $doctor_id;
}
// 当前时间10分钟内接诊中医生
$doctors = $this->getBeforeCurrentTimeDoctor(10,$inquiry_type);
if (!empty($doctors)){
foreach ($doctors as $item){
// 此处不验证接诊数量
// 可能存在上方接诊数量不够的医生
return $item['doctor_id'];
}
}
// 获取当前时间30分钟前接诊中的医生
$doctors = $this->getBeforeCurrentTimeDoctor(30,$inquiry_type);
if (!empty($doctors)){
foreach ($doctors as $item){
// 此处不验证接诊数量
// 可能存在上方接诊数量不够的医生
return $item['doctor_id'];
}
}
return "";
}
/**
* 获取坐班时间包含某时间的平台深度合作医生
* @param string $inquiry_type
* @param string $time 时间戳
* @return string
*/
public function getNowTimePlatDeepCooperationDoctorId(string $inquiry_type,string $time): string
{
$params = array();
$params[] = ['inquiry_type','=',$inquiry_type];
$params[] = ['inquiry_mode','=',1];
$params[] = ['start_time','<',date('H',$time) . date('i',$time)];
$params[] = ['end_time','>',date('H',$time) . date('i',$time)];
$user_doctor_params = array();
$user_doctor_params['is_platform_deep_cooperation'] = 1;
if ($inquiry_type == 2){
// 快速问诊
$user_doctor_params['is_img_quick_reception'] = 1;
}elseif ($inquiry_type == 4){
// 问诊购药
$user_doctor_params['multi_point_status'] = 1;
}
$doctor_inquiry_times = DoctorInquiryTime::getWithDoctorList($params,$user_doctor_params);
if (!empty($doctor_inquiry_times)){
foreach ($doctor_inquiry_times as $item){
// 检测是否存在日期
if (!empty($item['inquiry_date'])){
// 获取当前日期
$now_day = date('Y-m-d',time());
if ($item['inquiry_date'] == $now_day){
return $item['doctor_id'];
}else{
continue;
}
}else{
return $item['doctor_id'];
}
}
}
return "";
}
}

View File

@ -24,6 +24,7 @@ class Auth
"/area/city" => "get", // 获取城市信息
"/area/county" => "get", // 获取区县信息
"/callback/wxpay/inquiry/success" => "post", // 微信支付回调
"/callback/wxpay/inquiry/refund" => "post", // 微信退款回调
"/testpay" => "get", // 测试
];
}

View File

@ -41,7 +41,8 @@ return [
"patient" => [
"app_id" => env('PATIENT_WECHAT_APP_ID', 'wx70a196902e0841b6'),
"secret" => env('PATIENT_WECHAT_APP_SECRET', '2671d2f4285180ddec5a5a2b16ed50f2'),
"notify_url" => env('PATIENT_WECHAT_NOTIFY_URL', 'callback/wxpay/inquiry/success'),
"pay_notify_url" => env('PATIENT_WECHAT_PAY_NOTIFY_URL', 'callback/wxpay/inquiry/success'),
"refund_notify_url" => env('PATIENT_WECHAT_REFUND_NOTIFY_URL', 'callback/wxpay/inquiry/refund'),
],
"pay" => [
"mch_id" => env('PATIENT_WECHAT_MCH_ID', '1636644248'),

View File

@ -109,7 +109,7 @@ class WechatPay
"out_trade_no" => $out_trade_no, // 商户系统内部订单号
"appid" => $this->config['app_id'],
"description" => "问诊服务",
"notify_url" => env('DOMAIN_NAME_DEV') . $this->config['notify_url'],
"notify_url" => env('DOMAIN_NAME_DEV') . $this->config['pay_notify_url'],
"amount" => [
"total" => $total,//订单总金额,单位为分。
"currency" => "CNY"
@ -144,6 +144,8 @@ class WechatPay
* 获取小程序支付配置
* @param string $prepay_id 预支付交易会话标识
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getAppletsPayConfig(string $prepay_id): array
{
@ -166,5 +168,37 @@ class WechatPay
}
}
/**
* 退款接口
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function refund(array $options)
{
try {
$app = $this->createApp();
$options = [
"notify_url " => env('DOMAIN_NAME_DEV') . $this->config['refund_notify_url'],
];
$response = $app->getClient()->postJson("v3/refund/domestic/refunds", $options);
if ($response->isFailed()) {
// 出错了,处理异常
$result = $response->toArray(false);
if(empty($result)){
// 返回值为空
throw new BusinessException("发起退款失败");
}
if (!empty($result['code'])){
throw new BusinessException($result['message']);
}
throw new BusinessException("发起退款失败");
}
return $response->toArray(false);
} catch (\Exception $e) {
throw new BusinessException($e->getMessage(), HttpEnumCode::SERVER_ERROR);
}
}
}

View File

@ -36,7 +36,8 @@ JWT_ALGO=HS256
# [WECHAT]
PATIENT_WECHAT_APP_ID=wx70a196902e0841b6
PATIENT_WECHAT_APP_SECRET=2671d2f4285180ddec5a5a2b16ed50f2
PATIENT_WECHAT_NOTIFY_URL=callback/wxpay/inquiry/success
PATIENT_WECHAT_PAY_NOTIFY_URL=callback/wxpay/inquiry/success
PATIENT_WECHAT_REFUND_NOTIFY_URL=callback/wxpay/inquiry/refund
# [DOCTOR]
# [WECHAT]