diff --git a/app/Amqp/Consumer/AssignDoctorConsumer.php b/app/Amqp/Consumer/AssignDoctorConsumer.php new file mode 100644 index 0000000..f26e1be --- /dev/null +++ b/app/Amqp/Consumer/AssignDoctorConsumer.php @@ -0,0 +1,122 @@ +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; // 重回队列 + } + } +} diff --git a/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php b/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php index 14f1ae5..e810204 100644 --- a/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php +++ b/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php @@ -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()); diff --git a/app/Amqp/Producer/AssignDoctorProducer.php b/app/Amqp/Producer/AssignDoctorProducer.php new file mode 100644 index 0000000..3489b35 --- /dev/null +++ b/app/Amqp/Producer/AssignDoctorProducer.php @@ -0,0 +1,21 @@ +payload = $data; + } +} diff --git a/app/Controller/CallBackController.php b/app/Controller/CallBackController.php index b5f27db..896f762 100644 --- a/app/Controller/CallBackController.php +++ b/app/Controller/CallBackController.php @@ -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(); diff --git a/app/Controller/UserController.php b/app/Controller/UserController.php index edb7307..c98034d 100644 --- a/app/Controller/UserController.php +++ b/app/Controller/UserController.php @@ -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); } } \ No newline at end of file diff --git a/app/Model/DoctorInquiryTime.php b/app/Model/DoctorInquiryTime.php new file mode 100644 index 0000000..3a8be81 --- /dev/null +++ b/app/Model/DoctorInquiryTime.php @@ -0,0 +1,99 @@ +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); + } + +} diff --git a/app/Model/OrderInquiry.php b/app/Model/OrderInquiry.php index 5feea30..3630782 100644 --- a/app/Model/OrderInquiry.php +++ b/app/Model/OrderInquiry.php @@ -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"; diff --git a/app/Services/InquiryService.php b/app/Services/InquiryService.php index 0e9760d..5ba735b 100644 --- a/app/Services/InquiryService.php +++ b/app/Services/InquiryService.php @@ -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; diff --git a/app/Services/UserDoctorService.php b/app/Services/UserDoctorService.php index 733d6d0..be9fde9 100644 --- a/app/Services/UserDoctorService.php +++ b/app/Services/UserDoctorService.php @@ -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 ""; } } \ No newline at end of file diff --git a/app/Utils/Auth.php b/app/Utils/Auth.php index 1ee9da9..15a2f53 100644 --- a/app/Utils/Auth.php +++ b/app/Utils/Auth.php @@ -24,6 +24,7 @@ class Auth "/area/city" => "get", // 获取城市信息 "/area/county" => "get", // 获取区县信息 "/callback/wxpay/inquiry/success" => "post", // 微信支付回调 + "/callback/wxpay/inquiry/refund" => "post", // 微信退款回调 "/testpay" => "get", // 测试 ]; } diff --git a/config/config.php b/config/config.php index 0491ab9..cb1939b 100644 --- a/config/config.php +++ b/config/config.php @@ -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'), diff --git a/extend/Wechat/WechatPay.php b/extend/Wechat/WechatPay.php index 741a60e..d49cede 100644 --- a/extend/Wechat/WechatPay.php +++ b/extend/Wechat/WechatPay.php @@ -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); + } + } } \ No newline at end of file diff --git a/hospital-deploy.sh b/hospital-deploy.sh index 7d39b21..67be045 100644 --- a/hospital-deploy.sh +++ b/hospital-deploy.sh @@ -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]