diff --git a/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php b/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php index 0f49592..70688f7 100644 --- a/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php +++ b/app/Amqp/Consumer/CancelUnpayOrdersDelayDirectConsumer.php @@ -86,10 +86,10 @@ class CancelUnpayOrdersDelayDirectConsumer extends ConsumerMessage Db::commit(); Log::getInstance("queue-CancelUnpayOrders")->info("取消未支付订单 队列执行成功"); return Result::ACK; - } catch (\Exception $e) { + } catch (\Throwable $e) { Db::rollBack(); Log::getInstance("queue-CancelUnpayOrders")->error("取消未支付订单执行失败:" . $e->getMessage()); - return Result::ACK; // 重回队列 + return Result::ACK; } } diff --git a/app/Amqp/Consumer/GrantUserCouponDelayDirectConsumer.php b/app/Amqp/Consumer/GrantUserCouponDelayDirectConsumer.php new file mode 100644 index 0000000..a35031c --- /dev/null +++ b/app/Amqp/Consumer/GrantUserCouponDelayDirectConsumer.php @@ -0,0 +1,67 @@ +info("开始执行 延迟发放用户优惠卷 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + + // 获取优惠卷数据 + $params = array(); + $params['coupon_id'] = $data["coupon_id"]; + $coupon = Coupon::getOne($params); + if (empty($coupon)){ + Log::getInstance("queue-GrantUserCoupon")->error("无优惠卷数据"); + return Result::DROP; + } + + Db::beginTransaction(); + + try { + $couponService = new CouponService(); + $res = $couponService->GrantUserCoupon($data["coupon_id"],$data['user_id']); + if (!$res){ + // 发放失败 + Db::rollBack(); + Log::getInstance("queue-GrantUserCoupon")->error("发放优惠卷失败"); + return Result::DROP; + } + }catch (\Throwable $e){ + Db::rollBack(); + Log::getInstance("queue-GrantUserCoupon")->error($e->getMessage()); + return Result::DROP; + } + + Db::commit(); + + return Result::ACK; + } +} diff --git a/app/Amqp/Consumer/UserCouponExpiredDelayDirectConsumer.php b/app/Amqp/Consumer/UserCouponExpiredDelayDirectConsumer.php index f2006cf..5301390 100644 --- a/app/Amqp/Consumer/UserCouponExpiredDelayDirectConsumer.php +++ b/app/Amqp/Consumer/UserCouponExpiredDelayDirectConsumer.php @@ -7,7 +7,9 @@ namespace App\Amqp\Consumer; use App\Amqp\Producer\AutoCompleteInquiryDelayDirectProducer; use App\Amqp\Producer\UserCouponExpiredDelayDirectProducer; use App\Constants\HttpEnumCode; +use App\Model\Coupon; use App\Model\UserCoupon; +use App\Services\CouponService; use App\Utils\Log; use Hyperf\Amqp\Message\ConsumerDelayedMessageTrait; use Hyperf\Amqp\Message\ProducerDelayedMessageTrait; @@ -38,44 +40,40 @@ class UserCouponExpiredDelayDirectConsumer extends ConsumerMessage public function consumeMessage($data, AMQPMessage $message): string { - Log::getInstance()->error("开始执行 处理用户优惠卷过期 队列:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + Log::getInstance("queue-UserCouponExpired")->info("开始:" . json_encode($data, JSON_UNESCAPED_UNICODE)); + + // 检测参数 + if (!isset($data['user_coupon_id'])){ + Log::getInstance("queue-UserCouponExpired")->error("入参错误"); + return Result::DROP; + } + + // 获取优惠卷数据 + $params = array(); + $params['user_coupon_id'] = $data['user_coupon_id']; + $user_coupon = UserCoupon::getOne($params); + if (empty($user_coupon)){ + Log::getInstance("queue-UserCouponExpired")->info("用户无优惠卷,无需处理"); + return Result::DROP; + } + + // 检测优惠卷是否被使用 + if ($user_coupon['user_coupon_status'] == 1){ + Log::getInstance("queue-UserCouponExpired")->info("用户优惠卷已被使用,无需处理"); + return Result::DROP; + } + + // 检测优惠卷是否已执行过期处理 + if ($user_coupon['user_coupon_status'] == 3){ + Log::getInstance("queue-UserCouponExpired")->info("优惠卷已过期,无需处理"); + return Result::DROP; + } + + // 检测优惠卷过期时间 + $valid_end_time = strtotime($user_coupon['valid_end_time']); Db::beginTransaction(); try { - // 检测参数 - if (!isset($data['user_coupon_id'])){ - Db::rollBack(); - Log::getInstance()->error("处理用户优惠卷过期队列 执行失败:入参错误"); - return Result::DROP; - } - - // 获取优惠卷数据 - $params = array(); - $params['user_coupon_id'] = $data['user_coupon_id']; - $user_coupon = UserCoupon::getOne($params); - if (empty($user_coupon)){ - Db::rollBack(); - Log::getInstance()->info("处理用户优惠卷过期队列 执行结束:无优惠卷数据"); - return Result::DROP; - } - - // 检测优惠卷是否被使用 - if ($user_coupon['user_coupon_status'] == 1){ - Db::rollBack(); - Log::getInstance()->info("处理用户优惠卷过期队列 执行结束:优惠卷已被使用,无需处理"); - return Result::DROP; - } - - // 检测优惠卷是否已执行过期处理 - if ($user_coupon['user_coupon_status'] == 3){ - Db::rollBack(); - Log::getInstance()->info("处理用户优惠卷过期队列 执行结束:优惠卷已执行过期处理,无需处理"); - return Result::DROP; - } - - // 检测优惠卷过期时间 - $valid_end_time = strtotime($user_coupon['valid_end_time']); - // 处理未过期事件 // 先删除-重新添加队列 if ($valid_end_time > time()){ @@ -90,28 +88,66 @@ class UserCouponExpiredDelayDirectConsumer extends ConsumerMessage $res = $producer->produce($message); if (!$res) { Db::rollBack(); - Log::getInstance()->error("处理用户优惠卷过期队列 执行失败:未到过期时间,重新添加队列失败"); + Log::getInstance("queue-UserCouponExpired")->error("未到过期时间,重新添加队列失败"); return Result::REQUEUE; } return Result::DROP; } - // 处理已过期事件 + // 修改用户优惠卷表 $params = array(); $params['user_coupon_id'] = $user_coupon['user_coupon_id']; $data = array(); $data['user_coupon_status'] = 3; UserCoupon::edit($params, $data); - - Db::commit(); - Log::getInstance()->info("处理用户优惠卷过期 队列执行成功"); - return Result::ACK; - } catch (\Exception $e) { + } catch (\Throwable $e) { Db::rollBack(); - Log::getInstance()->error("处理用户优惠卷过期 队列执行失败:" . $e->getMessage()); + Log::getInstance("queue-UserCouponExpired")->error($e->getMessage()); return Result::REQUEUE; // 重回队列 } + + Db::commit(); + Log::getInstance("queue-UserCouponExpired")->info("成功"); + + Db::beginTransaction(); + try { + // 获取优惠卷数据 + $params = array(); + $params['coupon_id'] = $user_coupon["coupon_id"]; + $coupon = Coupon::getOne($params); + if (empty($coupon)){ + Db::rollBack(); + Log::getInstance("queue-UserCouponExpired")->error("无优惠卷数据"); + return Result::DROP; + } + + // 检测优惠卷状态 + if ($coupon['coupon_status'] != 1){ + Db::rollBack(); + Log::getInstance("queue-UserCouponExpired")->info("优惠卷非正常状态,停止执行"); + return Result::DROP; + } + + // 重新发放优惠卷 + if ($coupon['is_reissuable_after_expire'] == 1){ + $couponService = new CouponService(); + $res = $couponService->GrantUserCoupon($coupon['coupon_id'],$user_coupon['user_id']); + if (!$res){ + // 发放失败 + Db::rollBack(); + Log::getInstance("queue-UserCouponExpired")->error("重新发放优惠卷失败"); + return Result::DROP; + } + } + }catch (\Throwable $e){ + Db::rollBack(); + Log::getInstance("queue-UserCouponExpired")->error($e->getMessage()); + } + + Db::commit(); + + return Result::ACK; } } diff --git a/app/Amqp/Consumer/UserCouponExpiredNoticeDelayDirectConsumer.php b/app/Amqp/Consumer/UserCouponExpiredNoticeDelayDirectConsumer.php index d3ef4c7..cf23ed0 100644 --- a/app/Amqp/Consumer/UserCouponExpiredNoticeDelayDirectConsumer.php +++ b/app/Amqp/Consumer/UserCouponExpiredNoticeDelayDirectConsumer.php @@ -87,8 +87,7 @@ class UserCouponExpiredNoticeDelayDirectConsumer extends ConsumerMessage // 患者-优惠卷即将过期 $MessagePush = new MessagePush($user_coupon['user_id']); $MessagePush->patientExpireCoupon($coupon['coupon_name']); - - }catch (\Exception $e){ + }catch (\Throwable $e){ Log::getInstance("queue-UserCouponExpiredNotice")->error("错误:" . $e->getMessage()); return Result::DROP; } diff --git a/app/Amqp/Producer/GrantUserCouponDelayDirectProducer.php b/app/Amqp/Producer/GrantUserCouponDelayDirectProducer.php new file mode 100644 index 0000000..909738d --- /dev/null +++ b/app/Amqp/Producer/GrantUserCouponDelayDirectProducer.php @@ -0,0 +1,34 @@ +payload = $data; + } +} diff --git a/app/Amqp/Producer/SendStationMessageProducer.php b/app/Amqp/Producer/SendStationMessageProducer.php index a13695c..4215243 100644 --- a/app/Amqp/Producer/SendStationMessageProducer.php +++ b/app/Amqp/Producer/SendStationMessageProducer.php @@ -14,6 +14,7 @@ class SendStationMessageProducer extends ProducerMessage * @param $data * [ * "user_id":"用户id(接受者)", + * "user_type":"用户类型(接受者)", * "notice_type":"消息类型(1:医生服务通知 2:医生系统公告 3:患者系统消息)", * "notice_system_type":"系统消息类型(患者端系统消息存在 1:服务消息 2:福利消息 3:退款消息 4:物流消息)", * "inquiry_type:"问诊类型(医生端服务通知存在 1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)", diff --git a/app/Command/GrantUserCouponCommand.php b/app/Command/GrantUserCouponCommand.php new file mode 100644 index 0000000..db4cbbc --- /dev/null +++ b/app/Command/GrantUserCouponCommand.php @@ -0,0 +1,87 @@ +setDescription('发放用户优惠卷'); + } + + public function handle() + { + $this->line("开始"); + + // 获取所有状态正常用户 + $params = array(); + $params['user_type'] = 1; + $params['user_status'] = 1; + $users = User::getList($params); + if (empty($users)){ + $this->line("结束:无可执行用户"); + return; + } + + // 获取需要发放的优惠卷数据 + $params = array(); + $params['coupon_id'] = 2; + $coupon = Coupon::getOne($params); + if (empty($coupon)){ + $this->line("结束:无可执行优惠卷"); + return; + } + + foreach ($users as $user){ + // 获取用户优惠卷 + $params = array(); + $params['coupon_id'] = $coupon['coupon_id']; + $params['user_id'] = $user['user_id']; + $user_coupon = UserCoupon::getOne($params); + if (!empty($user_coupon)){ + $this->line("用户已拥有该优惠卷"); + continue; + } + + Db::beginTransaction(); + + try { + // 发放优惠卷 + $couponService = new CouponService(); + $res = $couponService->GrantUserCoupon($coupon['coupon_id'],$user['user_id']); + if (!$res){ + Db::rollBack(); + $this->line("优惠卷发放失败"); + continue; + } + }catch (\Throwable $e){ + Db::rollBack(); + $this->line($e->getMessage()); + } + + Db::commit(); + + $this->line("用户" . $user['user_name'] . "执行完毕"); + } + + $this->line("发放完毕"); + } +} diff --git a/app/Command/getPrescriptionOrderStatusCommand.php b/app/Command/getPrescriptionOrderStatusCommand.php index 93893b2..6600bd4 100644 --- a/app/Command/getPrescriptionOrderStatusCommand.php +++ b/app/Command/getPrescriptionOrderStatusCommand.php @@ -170,7 +170,7 @@ class getPrescriptionOrderStatusCommand extends HyperfCommand $this->line("获取处方平台订单数据结束:处理完毕"); Db::commit(); - } catch (\Exception $e) { + } catch (\Throwable $e) { Db::rollBack(); // 记录失败次数 $this->line("获取处方平台订单数据失败:" . $e->getMessage()); diff --git a/app/Controller/CallBackController.php b/app/Controller/CallBackController.php index 54e5c9d..5c49f5e 100644 --- a/app/Controller/CallBackController.php +++ b/app/Controller/CallBackController.php @@ -6,11 +6,13 @@ use App\Amqp\Producer\AssignDoctorDelayDirectProducer; use App\Amqp\Producer\AutoCompleteInquiryDelayDirectProducer; use App\Amqp\Producer\DetectionCompleteDelayDirectProducer; use App\Amqp\Producer\DoctorNotYetInquiryDelayDirectProducer; +use App\Amqp\Producer\GrantUserCouponDelayDirectProducer; use App\Constants\DoctorTitleCode; use App\Constants\HttpEnumCode; use App\Exception\BusinessException; use App\Model\BasicDetectionOrgan; use App\Model\BasicLogisticsCompany; +use App\Model\Coupon; use App\Model\DetectionProject; use App\Model\Hospital; use App\Model\MessageIm; @@ -23,6 +25,7 @@ use App\Model\OrderInquiryCoupon; use App\Model\OrderInquiryRefund; use App\Model\OrderPrescription; use App\Model\OrderProduct; +use App\Model\OrderProductCoupon; use App\Model\OrderProductItem; use App\Model\OrderProductLogistic; use App\Model\OrderProductRefund; @@ -39,6 +42,7 @@ use App\Services\ImService; use App\Services\InquiryService; use App\Services\MessagePush; use App\Services\OrderPrescriptionService; +use App\Services\UserCouponService; use App\Services\UserService; use App\Utils\Log; use Extend\Alibaba\Oss; @@ -250,10 +254,10 @@ class CallBackController extends AbstractController // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); - Log::getInstance()->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { - Log::getInstance()->info("微信退款回调数据错误"); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("微信退款回调数据错误"); return $server->serve(); } @@ -262,28 +266,28 @@ class CallBackController extends AbstractController $params['inquiry_no'] = $message['out_trade_no']; $order_inquiry = OrderInquiry::getOne($params); if (empty($order_inquiry)) { - Log::getInstance()->info("非法订单"); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("非法订单"); return $server->serve(); } // 验证订单状态 if ($order_inquiry['inquiry_status'] == 1) { // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) - Log::getInstance()->info("订单状态错误:当前为" . $order_inquiry['inquiry_status']); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("订单状态错误:当前为" . $order_inquiry['inquiry_status']); return $server->serve(); } // 验证订单退款状态 if ($order_inquiry['inquiry_refund_status'] == 3) { // 问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) - Log::getInstance()->info("订单退款状态错误:当前为" . $order_inquiry['inquiry_refund_status']); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("订单退款状态错误:当前为" . $order_inquiry['inquiry_refund_status']); return $server->serve(); } // 验证订单支付状态 if (in_array($order_inquiry['inquiry_pay_status'], [1, 3, 4, 5, 6, 7])) { // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) - Log::getInstance()->info("订单支付状态错误:当前为" . $order_inquiry['inquiry_pay_status']); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("订单支付状态错误:当前为" . $order_inquiry['inquiry_pay_status']); return $server->serve(); } @@ -301,7 +305,7 @@ class CallBackController extends AbstractController if (empty($inquiry_refund_status)) { // 错误,无退款状态 - Log::getInstance()->info("订单支付状态错误:未接收到退款状态"); + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->info("订单支付状态错误:未接收到退款状态"); return $this->wxPayErrorReturn("退款状态错误"); } @@ -325,8 +329,25 @@ class CallBackController extends AbstractController // 恢复优惠卷 if ($inquiry_refund_status == 3) { if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { - $InquiryService = new InquiryService(); - $InquiryService->returnInquiryCoupon($order_inquiry['order_inquiry_id'], $order_inquiry['user_id']); + // 获取该订单全部优惠卷数据 + $params = array(); + $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; + $order_inquiry_coupons = OrderInquiryCoupon::getList($params); + if (!empty($order_inquiry_coupons)){ + $userCouponService = new UserCouponService(); + foreach ($order_inquiry_coupons as $order_inquiry_coupon){ + // 退还优惠卷 + $userCouponService->returnUserCoupon($order_inquiry_coupon['user_coupon_id']); + + try { + // 发送站内消息-优惠卷退还 + $MessagePush = new MessagePush($order_inquiry['user_id']); + $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); + }catch (\Throwable $e){ + Log::getInstance("CallBackController-wxPayInquiryRefundCallBack")->error("推送消息失败:" . $e->getMessage()); + } + } + } } } @@ -348,18 +369,6 @@ class CallBackController extends AbstractController // 取消订单原因(1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时) $MessagePush->refundInquirySuccess($order_inquiry['cancel_reason']); - - if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { - // 获取用户优惠卷信息 - $params = array(); - $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; - $order_inquiry_coupon = OrderInquiryCoupon::getOne($params); - if (!empty($order_inquiry_coupon)){ - // 发送站内消息-优惠卷退还 - $MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']); - $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); - } - } } catch (\Exception $e) { // 验证失败 Log::getInstance()->error("微信退款回调处理成功,推送消息失败:" . $e->getMessage()); @@ -476,6 +485,52 @@ class CallBackController extends AbstractController } Log::getInstance()->error("药品微信支付回调数据处理成功"); + + try { + // 再次发放优惠卷数据 + if ($order_product['coupon_amount_total'] > 0){ + // 获取药品订单优惠卷数据 + $params = array(); + $params['order_product_id'] = $order_product['order_product_id']; + $order_product_coupons = OrderProductCoupon::getList($params); + if (!empty($order_product_coupons)){ + foreach ($order_product_coupons as $order_product_coupon){ + // 获取用户优惠卷数据 + $params = array(); + $params['user_coupon_id'] = $order_product_coupon['user_coupon_id']; + $user_coupon = UserCoupon::getOne($params); + if (!empty($user_coupon)){ + // 获取优惠卷数据 + $params = array(); + $params['coupon_id'] = $user_coupon['coupon_id']; + $coupon = Coupon::getOne($params); + if (!empty($coupon)){ + if ($coupon['reissue_interval_days'] > 0){ + $data = array(); + $data['coupon_id'] = $coupon['coupon_id']; + $data['user_id'] = $user_coupon['user_id']; + +// $time = $coupon['reissue_interval_days'] * 24 * 60 * 60 * 1000; + $time = 3 * 60 * 1000; + + $message = new GrantUserCouponDelayDirectProducer($data); + $message->setDelayMs($time); + $producer = $this->container->get(Producer::class); + $res = $producer->produce($message); + if (!$res) { + Log::getInstance()->error("再次发放优惠卷失败"); + } + + Log::getInstance()->info("再次发放优惠卷成功"); + } + } + } + } + } + } + }catch (\Throwable $e){ + Log::getInstance()->error("药品微信支付回调数据处理失败:" . $e->getMessage()); + } return $server->serve(); } @@ -505,10 +560,10 @@ class CallBackController extends AbstractController // 验证推送消息签名 $app->getValidator()->validate($app->getRequest()); - Log::getInstance()->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("微信退款回调数据:" . json_encode($message->toArray(), JSON_UNESCAPED_UNICODE)); if (empty($message['out_trade_no'])) { - Log::getInstance()->info("药品微信退款回调数据处理失败,缺少外部订单号"); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理失败,缺少外部订单号"); return $server->serve(); } @@ -518,28 +573,38 @@ class CallBackController extends AbstractController $order_product = OrderProduct::getOne($params); if (empty($order_product)) { Db::rollBack(); - Log::getInstance()->info("药品微信退款回调数据处理失败,无订单数据"); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理失败,无订单数据"); + return $server->serve(); + } + + // 查询患者数据 + $params = array(); + $params['patient_id'] = $order_product["patient_id"]; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)) { + Db::rollBack(); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理失败,无患者数据"); return $server->serve(); } // 验证订单状态 if ($order_product['order_product_status'] == 1) { // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消) - Log::getInstance()->info("药品微信退款回调数据处理失败,订单状态错误:当前为" . $order_product['order_product_status']); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理失败,订单状态错误:当前为" . $order_product['order_product_status']); return $server->serve(); } // 验证订单退款状态 if ($order_product['refund_status'] == 3) { // 商品订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭) - Log::getInstance()->info("药品微信退款回调数据处理失败,订单退款状态为" . $order_product['refund_status']); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理失败,订单退款状态为" . $order_product['refund_status']); return $server->serve(); } // 验证订单支付状态 if (in_array($order_product['pay_status'], [1, 3, 4, 5, 6, 7])) { // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) - Log::getInstance()->error("药品微信退款回调数据处理失败:订单未支付"); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->error("药品微信退款回调数据处理失败:订单未支付"); return $server->serve(); } @@ -557,7 +622,7 @@ class CallBackController extends AbstractController if (empty($refund_status)) { // 错误,无退款状态 - Log::getInstance()->error("药品微信退款回调数据处理失败:订单未支付"); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->error("药品微信退款回调数据处理失败:订单未支付"); return $this->wxPayErrorReturn("退款状态错误"); } @@ -578,15 +643,40 @@ class CallBackController extends AbstractController $params['order_product_id'] = $order_product['order_product_id']; OrderProductRefund::edit($params, $data); + // 恢复优惠卷 + if ($refund_status == 3) { + if (!empty($order_product['coupon_amount_total']) && $order_product['coupon_amount_total'] > 0) { + // 获取该订单全部优惠卷数据 + $params = array(); + $params['order_product_id'] = $order_product['order_product_id']; + $order_product_coupons = OrderProductCoupon::getList($params); + if (!empty($order_product_coupons)){ + $userCouponService = new UserCouponService(); + foreach ($order_product_coupons as $order_product_coupon){ + // 退还优惠卷 + $userCouponService->returnUserCoupon($order_product_coupon['user_coupon_id']); + + // 发送站内消息-优惠卷退还 + try { + $MessagePush = new MessagePush($user_patient['user_id']); + $MessagePush->patientRefundCoupon($order_product_coupon['coupon_name']); + }catch (\Throwable $e){ + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->error("推送消息失败:" . $e->getMessage()); + } + } + } + } + } + Db::commit(); } catch (\Exception $e) { // 验证失败 Db::rollBack(); - Log::getInstance()->error("药品微信退款回调数据处理失败:" . $e->getMessage()); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->error("药品微信退款回调数据处理失败:" . $e->getMessage()); return $this->wxPayErrorReturn($e->getMessage()); } - Log::getInstance()->info("药品微信退款回调数据处理成功"); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->info("药品微信退款回调数据处理成功"); // 发送推送消息 try { @@ -601,7 +691,7 @@ class CallBackController extends AbstractController } } catch (\Exception $e) { // 验证失败 - Log::getInstance()->error("微信退款回调处理成功,推送消息失败:" . $e->getMessage()); + Log::getInstance("CallBackController-wxPayProductRefundCallBack")->error("微信退款回调处理成功,推送消息失败:" . $e->getMessage()); return $server->serve(); } diff --git a/app/Controller/TestController.php b/app/Controller/TestController.php index 0ea0806..1c227d3 100644 --- a/app/Controller/TestController.php +++ b/app/Controller/TestController.php @@ -462,27 +462,40 @@ class TestController extends AbstractController } public function test_17(){ - $weChat = new Wechat(1); - $env_version = "release"; - $app_env = \Hyperf\Support\env("APP_ENV",'dev'); - if ($app_env == "dev"){ - $env_version = "trial"; - } + $re = \Hyperf\Context\ApplicationContext::getContainer()->get(CacheInterface::class); + $a = $re->set("wucongxing","1",100); + dump($a); + $b = $re->get("wucongxing"); + dump($b); - $options = [ - "scene" => "?doctor_id=516900370252341248",// query 参数 - "page" => "pages/expertDetail/expertDetail", - "check_path" => false, - "env_version" => $env_version, - ]; + $redis = \Hyperf\Context\ApplicationContext::getContainer()->get(Redis::class); + $c = $redis->get("wucongxing"); + dump($c); - $img_buffer = $weChat->getUnlimitedQRCode($options); - $oss = new Oss(); - - $filename = "applet/doctor/card/516900370252341248.jpg"; - - $oss->putObject($filename, $img_buffer); +// +// $weChat = new Wechat(1); +// +// $env_version = "release"; +// $app_env = \Hyperf\Support\env("APP_ENV",'dev'); +// if ($app_env == "dev"){ +// $env_version = "trial"; +// } +// +// $options = [ +// "scene" => "?doctor_id=516900370252341248",// query 参数 +// "page" => "pages/expertDetail/expertDetail", +// "check_path" => false, +// "env_version" => $env_version, +// ]; +// +// $img_buffer = $weChat->getUnlimitedQRCode($options); +// +// $oss = new Oss(); +// +// $filename = "applet/doctor/card/516900370252341248.jpg"; +// +// $oss->putObject($filename, $img_buffer); } } \ No newline at end of file diff --git a/app/Controller/UserPatientController.php b/app/Controller/UserPatientController.php index 1737e28..d3b6a54 100644 --- a/app/Controller/UserPatientController.php +++ b/app/Controller/UserPatientController.php @@ -43,13 +43,13 @@ class UserPatientController extends AbstractController * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function getPatientCouponlist(): ResponseInterface + public function getPatientCouponList(): ResponseInterface { $request = $this->container->get(UserPatientRequest::class); - $request->scene('getPatientCouponlist')->validateResolved(); + $request->scene('getPatientCouponList')->validateResolved(); $UserPatientService = new UserPatientService(); - $data = $UserPatientService->getPatientCouponlist(); + $data = $UserPatientService->getPatientCouponList(); return $this->response->json($data); } diff --git a/app/Model/BasicBrand.php b/app/Model/BasicBrand.php new file mode 100644 index 0000000..9d33396 --- /dev/null +++ b/app/Model/BasicBrand.php @@ -0,0 +1,55 @@ +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); + } +} diff --git a/app/Model/Coupon.php b/app/Model/Coupon.php index d4f464b..f7d18ca 100644 --- a/app/Model/Coupon.php +++ b/app/Model/Coupon.php @@ -6,28 +6,37 @@ namespace App\Model; +use Hyperf\Database\Model\Collection; use Hyperf\Snowflake\Concern\Snowflake; /** - * @property int $coupon_id 主键id + * @property string $coupon_id 主键id * @property string $coupon_name 优惠卷名称 * @property string $coupon_icon 优惠卷图片 * @property int $coupon_client 使用平台(1:小程序) - * @property int $coupon_type 优惠卷类型(1:无门槛 2:满减) - * @property int $coupon_status 状态(1:正常 2:强制失效 3:结束) - * @property int $distribution_object 发放对象(1:新注册用户 2:会员 3:近期消费 4:近期购药) - * @property int $application_scope 适用范围(1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药) + * @property int $coupon_type 优惠卷类型(1:无门槛 2:满减 3:数量) + * @property int $coupon_status 状态(1:正常 2:强制失效 3:结束 4:删除) + * @property int $distribution_object 发放对象(1:全部用户 2:新注册用户 3:会员 4:近期消费 5:近期购药 6:存量用户) + * @property int $application_scope 适用范围(1:全场通用 2:问诊 3:按品牌适用 4:按类别类别适用 5:单品使用) + * @property int $inquiry_type 关联问诊类型,适用范围为问诊时存在生效(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药 5:检测) + * @property int $brand_id 关联品牌id(如不限制品牌,此项为空) + * @property int $is_mutex 是否互斥(0:否 1:是)互斥情况下无法和其他优惠卷同时使用 * @property int $is_display 是否展示(0:否 1:是) - * @property int $distribution_with_day 发放关联时间(发放对象为近期消费等类型时规定天数) + * @property int $distribution_with_day 发放关联天数(发放对象为近期消费等类型时规定天数) + * @property int $min_usable_number 单商品最小可使用数量(默认为1,类型为数量时使用,如需限制优惠卷使用数量,请填写此处) * @property int $coupon_count 发放数量 - * @property int $coupon_take_count 领取数量 - * @property int $coupon_ used_count 使用数量 + * @property int $coupon_take_count 已领取数量 + * @property int $coupon_used_count 已使用数量 * @property string $coupon_price 优惠卷金额 * @property string $with_amount 符合满减标准金额(优惠卷类型为满减时使用) * @property int $valid_type 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效) * @property int $valid_days 自领取之日起有效天数 * @property string $valid_start_time 开始使用时间 * @property string $valid_end_time 结束使用时间 + * @property string $product_id 关联商品id,逗号分隔,指定商品时,填入此项。 + * @property int $reissue_interval_days 确认收货后的再次发放间隔天数(如果设置为 0,则表示不再次发放。当适用范围为商品时生效) + * @property int $is_reissuable_after_expire 过期之后是否允许再次发放(0:否 1:是) + * @property int $is_popup 是否首页弹窗(0:否 1:是) * @property \Carbon\Carbon $created_at 创建时间 * @property \Carbon\Carbon $updated_at 修改时间 */ @@ -43,12 +52,7 @@ class Coupon extends Model /** * The attributes that are mass assignable. */ - protected array $fillable = ['coupon_id', 'coupon_name', 'coupon_icon', 'coupon_client', 'coupon_type', 'coupon_status', 'distribution_object', 'application_scope', 'is_display', 'distribution_with_day', 'coupon_count', 'coupon_take_count', 'coupon_used_count', 'coupon_price', 'with_amount', 'valid_type', 'valid_days', 'valid_start_time', 'valid_end_time', 'created_at', 'updated_at']; - - /** - * The attributes that should be cast to native types. - */ - protected array $casts = ['coupon_id' => 'string', 'coupon_client' => 'integer', 'coupon_type' => 'integer', 'coupon_status' => 'integer', 'distribution_object' => 'integer', 'application_scope' => 'integer', 'is_display' => 'integer', 'distribution_with_day' => 'integer', 'coupon_count' => 'integer', 'coupon_take_count' => 'integer', 'coupon_used_count' => 'integer', 'valid_type' => 'integer', 'valid_days' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime']; + protected array $fillable = ['coupon_id', 'coupon_name', 'coupon_icon', 'coupon_client', 'coupon_type', 'coupon_status', 'distribution_object', 'application_scope', 'inquiry_type', 'brand_id', 'is_mutex', 'is_display', 'distribution_with_day', 'min_usable_number', 'coupon_count', 'coupon_take_count', 'coupon_used_count', 'coupon_price', 'with_amount', 'valid_type', 'valid_days', 'valid_start_time', 'valid_end_time', 'product_id', 'reissue_interval_days', 'is_reissuable_after_expire', 'is_popup', 'created_at', 'updated_at']; protected string $primaryKey = "coupon_id"; @@ -67,9 +71,9 @@ class Coupon extends Model * 获取信息-多条 * @param array $params * @param array $fields - * @return object|null + * @return Collection|array */ - public static function getList(array $params, array $fields = ['*']): object|null + public static function getList(array $params, array $fields = ['*']): Collection|array { return self::where($params)->get($fields); } @@ -97,4 +101,13 @@ class Coupon extends Model { return self::where($params)->decrement($field,$numeral); } + + // 获取注册用户可领取的优惠卷列表 + public static function getRegisterCouponList(): Collection|array + { + return self::where("coupon_client",1) + ->where("coupon_status",1) + ->whereIn("distribution_object",[1,2]) + ->get(); + } } diff --git a/app/Model/DoctorWithdrawalBank.php b/app/Model/DoctorWithdrawalBank.php new file mode 100644 index 0000000..0970d27 --- /dev/null +++ b/app/Model/DoctorWithdrawalBank.php @@ -0,0 +1,71 @@ +first($fields); + } + + /** + * 获取信息-多条 + * @param array $params + * @param array $fields + * @return object|null + */ + public static function getList(array $params, array $fields = ['*']): object|null + { + return self::where($params)->get($fields); + } + + /** + * 新增 + * @param array $data + * @return DoctorWithdrawalBank|\Hyperf\Database\Model\Model + */ + public static function addDoctorWithdrawalBank(array $data): \Hyperf\Database\Model\Model|DoctorWithdrawalBank + { + return self::create($data); + } + +} diff --git a/app/Model/OrderProduct.php b/app/Model/OrderProduct.php index f2e975c..79e806d 100644 --- a/app/Model/OrderProduct.php +++ b/app/Model/OrderProduct.php @@ -26,6 +26,7 @@ use Hyperf\Snowflake\Concern\Snowflake; * @property int $is_delete 删除状态(0:否 1:是) * @property int $cancel_reason 订单取消原因(1:主动取消 2:复核失败/库存不足 3:支付超时 4:客服取消) * @property string $amount_total 订单金额 + * @property string $coupon_amount_total 优惠卷总金额 * @property string $payment_amount_total 实际付款金额 * @property string $logistics_fee 运费金额 * @property string $logistics_no 物流编号 @@ -37,7 +38,7 @@ use Hyperf\Snowflake\Concern\Snowflake; * @property int $refund_status 商品订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常) * @property string $cancel_time 订单取消时间 * @property string $cancel_remarks 订单取消备注(自动添加) - * @property int $report_pre_status 上报处方平台状态(0:未上报 1:已上报 2:上报失败)) + * @property int $report_pre_status 上报处方平台状态(0:未上报 1:已上报 2:上报失败 3:上报取消) * @property string $report_pre_time 上报处方平台时间 * @property string $report_pre_fail_reason 上报失败原因 * @property int $province_id 省份id @@ -54,10 +55,10 @@ use Hyperf\Snowflake\Concern\Snowflake; * @property string $consignee_tel_mask 收货人电话(掩码) * @property \Carbon\Carbon $created_at 创建时间 * @property \Carbon\Carbon $updated_at 修改时间 - * @property-read OrderPrescription $OrderPrescription - * @property-read \Hyperf\Database\Model\Collection|OrderPrescriptionIcd[] $OrderPrescriptionIcd - * @property-read \Hyperf\Database\Model\Collection|OrderProductItem[] $OrderProductItem - * @property-read PatientFamily $PatientFamily + * @property-read OrderPrescription|null $OrderPrescription + * @property-read \Hyperf\Database\Model\Collection|OrderPrescriptionIcd[]|null $OrderPrescriptionIcd + * @property-read \Hyperf\Database\Model\Collection|OrderProductItem[]|null $OrderProductItem + * @property-read PatientFamily|null $PatientFamily */ class OrderProduct extends Model { @@ -71,7 +72,7 @@ class OrderProduct extends Model /** * The attributes that are mass assignable. */ - protected array $fillable = ['order_product_id', 'order_inquiry_id', 'order_prescription_id', 'doctor_id', 'patient_id', 'family_id', 'order_product_no', 'escrow_trade_no', 'order_product_status', 'pay_channel', 'pay_status', 'is_delete', 'cancel_reason', 'amount_total', 'payment_amount_total', 'logistics_fee', 'logistics_no', 'logistics_company_code', 'sub_logistics_status', 'delivery_time', 'pay_time', 'remarks', 'refund_status', 'cancel_time', 'cancel_remarks', 'report_pre_status', 'report_pre_time', 'report_pre_fail_reason', 'province_id', 'province', 'city_id', 'city', 'county_id', 'county', 'address', 'address_mask', 'consignee_name', 'consignee_name_mask', 'consignee_tel', 'consignee_tel_mask', 'created_at', 'updated_at']; + protected array $fillable = ['order_product_id', 'order_inquiry_id', 'order_prescription_id', 'doctor_id', 'patient_id', 'family_id', 'order_product_no', 'escrow_trade_no', 'order_product_status', 'pay_channel', 'pay_status', 'is_delete', 'cancel_reason', 'amount_total', 'coupon_amount_total', 'payment_amount_total', 'logistics_fee', 'logistics_no', 'logistics_company_code', 'sub_logistics_status', 'delivery_time', 'pay_time', 'remarks', 'refund_status', 'cancel_time', 'cancel_remarks', 'report_pre_status', 'report_pre_time', 'report_pre_fail_reason', 'province_id', 'province', 'city_id', 'city', 'county_id', 'county', 'address', 'address_mask', 'consignee_name', 'consignee_name_mask', 'consignee_tel', 'consignee_tel_mask', 'created_at', 'updated_at']; protected string $primaryKey = "order_product_id"; diff --git a/app/Model/OrderProductCoupon.php b/app/Model/OrderProductCoupon.php new file mode 100644 index 0000000..f0d2753 --- /dev/null +++ b/app/Model/OrderProductCoupon.php @@ -0,0 +1,67 @@ +first($fields); + } + + /** + * 获取信息-多条 + * @param array $params + * @param array $fields + * @return object|null + */ + public static function getList(array $params, array $fields = ['*']): object|null + { + return self::where($params)->get($fields); + } + + /** + * 新增 + * @param array $data + * @return OrderProductCoupon|\Hyperf\Database\Model\Model + */ + public static function addOrderProductCoupon(array $data): \Hyperf\Database\Model\Model|OrderProductCoupon + { + return self::create($data); + } +} diff --git a/app/Model/User.php b/app/Model/User.php index 9a19c85..40bc14d 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -6,6 +6,7 @@ namespace App\Model; use Hyperf\Database\Model\Builder; +use Hyperf\Database\Model\Collection; use Hyperf\Snowflake\Concern\Snowflake; /** @@ -58,6 +59,17 @@ class User extends Model return $result; } + /** + * 获取用户信息-多条 + * @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 新增数据 diff --git a/app/Model/UserCoupon.php b/app/Model/UserCoupon.php index 1be4df0..4fcd438 100644 --- a/app/Model/UserCoupon.php +++ b/app/Model/UserCoupon.php @@ -65,32 +65,15 @@ class UserCoupon extends Model * @param array $fields * @return Collection|array */ - public static function getWithCouponList(array $params,array $coupon_params,array $application_scope_params, array $fields = ['*']): Collection|array + public static function getWithCouponList(array $params,array $fields = ['*']): Collection|array { return self::with(['Coupon']) - ->whereHas('Coupon' , function($query) use ($coupon_params,$application_scope_params){ - $query->where($coupon_params)->whereIn('application_scope',$application_scope_params); + ->whereHas('Coupon' , function($query){ + $query->where("coupon_client",1)->where("coupon_status",1); }) ->where($params)->get($fields); } - /** - * 获取优惠卷信息-单条 - * @param array $params - * @param array $coupon_params - * @param array $fields - * @return object|null - */ - public static function getDateWithCouponOne(array $params, array $coupon_params, array $application_scope_params, array $fields = ['*']): object|null - { - return self::with(['Coupon']) - ->whereHas('Coupon' , function($query) use ($coupon_params,$application_scope_params){ - $query->where($coupon_params)->whereIn('application_scope',$application_scope_params); - }) - ->where($params) - ->first($fields); - } - /** * 新增用户优惠卷 * @param array $data @@ -111,4 +94,94 @@ class UserCoupon extends Model { return self::where($params)->update($data); } + + /** + * 获取患者问诊可用的优惠卷 + * @param string|int $user_id 用户id + * @param string|int $inquiry_type 关联问诊类型,application_scope=问诊时存在生效,逗号分隔(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药 5:检测) + * @param array $fields 字段 + * @return Collection|array + */ + public static function getUserInquiryUsableCoupon(string|int $user_id, string|int $inquiry_type,array $fields = ['*']): Collection|array + { + $params = array(); + $params[] = ['user_id', '=', $user_id]; + $params[] = ['user_coupon_status', '=', 0];// 状态(0:未使用 1:已使用 3:已过期) + $params[] = ['valid_start_time', '<', date('Y-m-d H:i:s', time())]; // 有效使用时间 + $params[] = ['valid_end_time', '>', date('Y-m-d H:i:s', time())]; // 过期使用时间 + + return self::with(['Coupon']) + ->whereHas('Coupon', function ($query) use ($inquiry_type) { + $query->where("coupon_client",1) + ->where("coupon_status",1) + ->where("application_scope",2) + ->where(function ($query) use ($inquiry_type) { + $query->orwhere("inquiry_type","like",'%' . $inquiry_type+1 . '%'); + $query->orwhere("inquiry_type","like",'%1%'); + }); + }) + ->where($params) + ->groupBy("coupon_id") + ->get($fields); + } + + /** + * 获取患者购药可用的优惠卷 + * @param string|int $user_id 用户id + * @param array $coupon_product_datas + * @param array $fields 字段 + * @return Collection|array + */ + public static function getUserProductUsableCoupon(string|int $user_id,array $coupon_product_datas,array $fields = ['*']): Collection|array + { + $params = array(); + $params[] = ['user_id', '=', $user_id]; + $params[] = ['user_coupon_status', '=', 0];// 状态(0:未使用 1:已使用 3:已过期) + $params[] = ['valid_start_time', '<', date('Y-m-d H:i:s', time())]; // 有效使用时间 + $params[] = ['valid_end_time', '>', date('Y-m-d H:i:s', time())]; // 过期使用时间 + + return self::with(['Coupon']) + ->whereHas('Coupon', function ($query) use ($coupon_product_datas) { + $query->where("coupon_client",1) + ->where("coupon_status",1) + ->whereIn("application_scope",[1,3,4,5]) + ->where(function ($query) use ($coupon_product_datas) { + foreach ($coupon_product_datas as $coupon_product_data){ + $query->orwhere("product_id","like",'%' . $coupon_product_data['product_id'] . '%'); + } + }); + }) + ->where($params) + ->groupBy("coupon_id") + ->get($fields); + } + + /** + * 获取患者某一类型下的可用优惠卷 + * @param string|int $user_id + * @param int $distribution_object + * @param array $fields + * @return Collection|array + */ + public static function getUserObjectTypeCoupon(string|int $user_id,int $distribution_object,array $fields = ['*']): Collection|array + { + $params = array(); + $params[] = ['user_id', '=', $user_id]; + $params[] = ['user_coupon_status', '=', 0];// 状态(0:未使用 1:已使用 3:已过期) + $params[] = ['valid_start_time', '<', date('Y-m-d H:i:s', time())]; // 有效使用时间 + $params[] = ['valid_end_time', '>', date('Y-m-d H:i:s', time())]; // 过期使用时间 + + return self::with(['Coupon']) + ->whereHas('Coupon', function ($query) use ($distribution_object) { + $query->where("coupon_client",1) + ->where("coupon_status",1) + ->where(function ($query) use ($distribution_object) { + $query->orwhere("distribution_object",$distribution_object); + }); + }) + ->where($params) + ->groupBy("coupon_id") + ->get($fields); + } + } diff --git a/app/Request/UserPatientRequest.php b/app/Request/UserPatientRequest.php index 3618d1c..bdea314 100644 --- a/app/Request/UserPatientRequest.php +++ b/app/Request/UserPatientRequest.php @@ -10,7 +10,7 @@ use Hyperf\Validation\Request\FormRequest; class UserPatientRequest extends FormRequest { protected array $scenes = [ - 'getPatientCouponlist' => [ // 获取患者优惠卷列表 + 'getPatientCouponList' => [ // 获取患者优惠卷列表 'user_coupon_status', ], 'putShoppingCart' => [ // 修改购物车药品数据 diff --git a/app/Services/CouponService.php b/app/Services/CouponService.php index e3f7efa..65473b4 100644 --- a/app/Services/CouponService.php +++ b/app/Services/CouponService.php @@ -9,6 +9,7 @@ use App\Constants\HttpEnumCode; use App\Model\Coupon; use App\Model\Popup; use App\Model\UserCoupon; +use App\Model\UserPatient; use App\Utils\Log; use Hyperf\Amqp\Producer; use Hyperf\DbConnection\Db; @@ -21,110 +22,78 @@ use Psr\Container\NotFoundExceptionInterface; class CouponService extends BaseService { /** - * 获取用户某状态全部优惠卷-列表 - * @param string|int $user_id 用户id - * @param array $inquiry_type [1,2,3,4,5]适用范围(1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药) - * @param int $user_coupon_status 状态(0:未使用 1:已使用 3:已过期) - * @return array - */ - public function getUserCouponStatusList(string|int $user_id, array $inquiry_type, int $user_coupon_status): array - { - $params = array(); - $params[] = ['user_id', '=', $user_id]; - $params[] = ['user_coupon_status', '=', $user_coupon_status];// 状态(0:未使用 1:已使用 3:已过期) - - $coupon_params = array(); - $coupon_params[] = ['coupon_client', '=', 1]; - $coupon_params[] = ['coupon_status', '=', 1]; // 状态(1:正常 2:强制失效 3:结束 4:删除) - - $application_scope_params = $inquiry_type; // 适用范围(1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药) - - $user_coupon = UserCoupon::getWithCouponList($params, $coupon_params, $application_scope_params); - if (empty($user_coupon)) { - return array(); - } - - return $user_coupon->toArray(); - } - - /** - * 获取用户可用优惠卷-单条 - * @param string|int $user_id 用户id - * @param string|int $inquiry_type 订单类型(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药) - * @param int $coupon_client 使用平台(1:小程序) - * @return array - */ - public function getUserUsableCouponOne(string|int $user_id, string|int $inquiry_type, int $coupon_client = 1): array - { - // 问诊类型需加1 - $inquiry_type = $inquiry_type + 1; - - $params = array(); - $params[] = ['user_id', '=', $user_id]; - $params[] = ['user_coupon_status', '=', 0];// 状态(0:未使用 1:已使用 3:已过期) - $params[] = ['valid_start_time', '<', date('Y-m-d H:i:s', time())]; // 有效使用时间 - $params[] = ['valid_end_time', '>', date('Y-m-d H:i:s', time())]; // 过期使用时间 - - $coupon_params = array(); - $coupon_params[] = ['coupon_client', '=', $coupon_client]; - $coupon_params[] = ['coupon_status', '=', 1]; // 状态(1:正常 2:强制失效 3:结束 4:删除) - - $application_scope_params = [1, $inquiry_type]; // 适用范围(1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药) - - $user_coupon = UserCoupon::getDateWithCouponOne($params, $coupon_params, $application_scope_params); - if (empty($user_coupon)) { - return array(); - } - - return $user_coupon->toArray(); - } - - /** - * 发放用户优惠卷 - * @param int $distribution_object 发放对象(1:新注册用户 2:会员 3:近期消费 4:近期购药) - * @param string $user_id - * @param string $patient_id - * @param int $coupon_client 使用平台(1:小程序) + * 发放优惠卷 + * @param string $coupon_id 优惠卷id + * @param string $user_id 用户id * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface */ - public function DistributeCoupon(int $distribution_object, string $user_id, string $patient_id, int $coupon_client = 1): bool + public function GrantUserCoupon(string $coupon_id,string $user_id): bool { + // 获取患者数据 $params = array(); - $params['coupon_client'] = $coupon_client; - $params['coupon_status'] = 1; - $params['distribution_object'] = $distribution_object; // 发放对象(1:新注册用户 2:会员 3:近期消费 4:近期购药) + $params['user_id'] = $user_id; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)){ + return false; + } - $coupon = Coupon::getList($params); - if (empty($coupon)) { + // 获取优惠卷数据 + $params = array(); + $params['coupon_id'] = $coupon_id; + $coupon = Coupon::getOne($params); + if (empty($coupon)){ + return false; + } + + // 判断优惠卷数量是否充足 + if ($coupon['coupon_count'] <= $coupon['coupon_take_count']){ return true; } - foreach ($coupon as $key => $value) { - // 判断发放数量 - if ($value['coupon_count'] == $value['coupon_take_count']) { - continue; + // 判断用户是否已有该优惠卷 + $params = array(); + $params['user_id'] = $user_id; + $params['coupon_id'] = $coupon['coupon_id']; + $user_coupon = UserCoupon::getOne($params); + if (!empty($user_coupon)){ + if ($user_coupon['user_coupon_status'] == 0){ + return true; } + } + // 判断该优惠卷状态 + if ($coupon['coupon_status'] != 1){ + // 优惠卷状态异常 + return true; + } + + // 判断该优惠卷过期时间 + if ($coupon['valid_type'] == 1){ + // 绝对时效 + $valid_end_time = strtotime($coupon['valid_end_time']); + + $date = time() + 60 * 10; + if ($valid_end_time < $date){ + // 超出结束使用时间 + return true; + } + } + + try { // 添加用户优惠卷表 $data = array(); $data['user_id'] = $user_id; - $data['patient_id'] = $patient_id; - $data['coupon_id'] = $value['coupon_id']; - - if ($value['valid_type'] == 1) { + $data['patient_id'] = $user_patient['patient_id']; + $data['coupon_id'] = $coupon_id; + if ($coupon['valid_type'] == 1) { // 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效) - $data['valid_start_time'] = $value['valid_start_time']; // 有效使用时间 - $data['valid_end_time'] = $value['valid_end_time']; // 过期使用时间 - } elseif ($value['valid_type'] == 2) { + $data['valid_start_time'] = $coupon['valid_start_time']; // 有效使用时间 + $data['valid_end_time'] = $coupon['valid_end_time']; // 过期使用时间 + } elseif ($coupon['valid_type'] == 2) { // 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效) $data['valid_start_time'] = date('Y-m-d H:i:s', time()); // 有效使用时间 - $data['valid_end_time'] = date("Y-m-d H:i:s", strtotime($value['valid_days'] . " day")); - } else { - return false; + $data['valid_end_time'] = date("Y-m-d H:i:s", strtotime($coupon['valid_days'] . " day")); } - $user_coupon = UserCoupon::addUserCoupon($data); if (empty($user_coupon)) { return false; @@ -132,33 +101,35 @@ class CouponService extends BaseService // 增加优惠卷发放数量 $params = array(); - $params['coupon_id'] = $value['coupon_id']; + $params['coupon_id'] = $coupon['coupon_id']; Coupon::inc($params,'coupon_take_count'); // 添加弹窗表 - $data = array(); - $data['user_id'] = $user_id; - $data['app_type'] = 1; - $data['client_type'] = 1;// 客户端类型(1:患者端 2:医生端 3:药师端) - $data['popup_type'] = 2;// 弹窗类型(1:结算费用规则 2:新优惠卷弹窗) - $data['popup_title'] = "新人红包福利"; + if ($coupon['is_popup'] == 1){ + $data = array(); + $data['user_id'] = $user_id; + $data['app_type'] = 1; + $data['client_type'] = 1;// 客户端类型(1:患者端 2:医生端 3:药师端) + $data['popup_type'] = 2;// 弹窗类型(1:结算费用规则 2:新优惠卷弹窗) + $data['popup_title'] = "新人红包福利"; - $popup_content = [ - 'user_coupon_id' => (string)$user_coupon->user_coupon_id, // 优惠卷金额 - 'coupon_price' => $value['coupon_price'], // 优惠卷金额 - 'application_scope' => $value['application_scope'], // 适用范围(1:全部 2:快速问诊 3:专家问诊 4:公益问诊 5:问诊购药) - 'valid_type' => $value['valid_type'], // 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效) - 'valid_days' => $value['valid_days'], // 自领取之日起有效天数 - 'valid_start_time' => $value['valid_start_time'], // 开始使用时间 - 'valid_end_time' => $value['valid_end_time'], // 结束使用时间 - ]; - $data['popup_content'] = json_encode($popup_content, JSON_UNESCAPED_UNICODE); - $popup = Popup::addPopup($data); - if (empty($popup)) { - return false; + $popup_content = [ + 'user_coupon_id' => (string)$user_coupon->user_coupon_id, // 优惠卷金额 + 'coupon_price' => $coupon['coupon_price'], // 优惠卷金额 + 'application_scope' => $coupon['application_scope'], // 适用范围(1:全场通用 2:问诊 3:按品牌适用 4:按类别类别适用 5:单品使用) + 'inquiry_type' => $coupon['inquiry_type'], // 关联问诊类型,application_scope=问诊时存在生效,逗号分隔(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药 5:检测) + 'valid_type' => $coupon['valid_type'], // 有效类型(1:绝对时效,xxx-xxx时间段有效 2:相对时效 n天内有效) + 'valid_days' => $coupon['valid_days'], // 自领取之日起有效天数 + 'valid_start_time' => $coupon['valid_start_time'], // 开始使用时间 + 'valid_end_time' => $coupon['valid_end_time'], // 结束使用时间 + ]; + $data['popup_content'] = json_encode($popup_content, JSON_UNESCAPED_UNICODE); + $popup = Popup::addPopup($data); + if (empty($popup)) { + return false; + } } - // 添加用户优惠卷自动过期队列 // 添加优惠卷过期队列 $valid_end_time = strtotime($user_coupon->valid_end_time); @@ -173,30 +144,55 @@ class CouponService extends BaseService if (!$res) { return false; } + }catch (\Throwable $e){ + Log::getInstance("CouponService-GrantUserCoupon")->error($e->getMessage()); + return false; + } + try { // 添加优惠卷即将过期提醒队列 - if ($time > 60 * 60 * 24 * 2) { - $time = 60 * 60 * 24 * 2; - } else { - if ($time > 60 * 60 * 5){ - $time = $time - 60 * 60 * 5; + $time = floor($time * 0.25); + + // 时间低于5小时,不进行过期提醒 + if ($time > 60 * 60 * 5){ + $message = new UserCouponExpiredNoticeDelayDirectProducer($data); + $message->setDelayMs(1000 * $time); + $producer = $this->container->get(Producer::class); + $res = $producer->produce($message); + if (!$res) { + Log::getInstance("CouponService-GrantUserCoupon")->error("添加优惠卷即将过期提醒队列"); } } - $message = new UserCouponExpiredNoticeDelayDirectProducer($data); - $message->setDelayMs(1000 * $time); - $producer = $this->container->get(Producer::class); - $res = $producer->produce($message); - if (!$res) { - return false; - } - try { - // 患者-优惠卷发放 - $MessagePush = new MessagePush($user_id); - $MessagePush->patientDistributeCoupon($value['coupon_name']); - } catch (\Exception $e) { - // 不做处理 - Log::getInstance()->error($e->getMessage()); + // 通知-患者-优惠卷发放 + $MessagePush = new MessagePush($user_id); + $MessagePush->patientDistributeCoupon($coupon['coupon_name']); + }catch (\Throwable $e){ + Log::getInstance("CouponService-GrantUserCoupon")->error($e->getMessage()); + } + + return true; + } + + /** + * 发放注册用户优惠卷 + * @param string $user_id 用户id + * @return bool + */ + public function GrantRegisterCoupon(string $user_id): bool + { + // 获取注册用户可领取的优惠卷列表 + $coupon = Coupon::getRegisterCouponList(); + if (empty($coupon)) { + return true; + } + + foreach ($coupon as $value){ + // 发放优惠卷 + $res = $this->GrantUserCoupon($value['coupon_id'],$user_id); + if (!$res){ + // 发放失败 + Log::getInstance("CouponService-GrantRegisterCoupon")->error("发放注册用户优惠卷"); } } diff --git a/app/Services/DoctorAccountService.php b/app/Services/DoctorAccountService.php index 57a9c56..cb4221e 100644 --- a/app/Services/DoctorAccountService.php +++ b/app/Services/DoctorAccountService.php @@ -8,6 +8,7 @@ use App\Model\DoctorAccount; use App\Model\DoctorAccountDay; use App\Model\DoctorBankCard; use App\Model\DoctorWithdrawal; +use App\Model\DoctorWithdrawalBank; use App\Model\DoctorWithdrawalOrder; use App\Model\OrderInquiry; use App\Model\UserDoctor; @@ -199,7 +200,7 @@ class DoctorAccountService extends BaseService $bank['bank_card_name'] = $user_doctor_info['card_name']; $bank['bank_card_name_mask'] = $user_doctor_info['card_name_mask']; - $balance_account = 0; + $amount_total = 0; $order_inquiry_id_array = []; // 获取医生账户余额 if (!empty($order_inquiry_ids)){ @@ -211,27 +212,31 @@ class DoctorAccountService extends BaseService $in_params = explode(',',$order_inquiry_ids); $order_inquiry = OrderInquiry::getInList($params,$in_params); if (!empty($order_inquiry)){ - $balance_account = array_sum(array_column($order_inquiry->toArray(),'amount_total')); + foreach ($order_inquiry as $value){ + $amount_total = bcadd($amount_total,$value["amount_total"],2); + } } $order_inquiry_id_array = $in_params; }else{ $InquiryService = new InquiryService(); $order_inquiry = $InquiryService->getDoctorCanWithdrawalInquiryOrder($user_info['client_user_id']); + if (!empty($order_inquiry)){ - $balance_account = array_sum(array_column($order_inquiry,'amount_total')); + foreach ($order_inquiry as $value){ + $amount_total = bcadd($amount_total,$value["amount_total"],2); + } $order_inquiry_id_array = array_column($order_inquiry,'order_inquiry_id'); } } - if ($balance_account > 0){ - $balance_account = floor($balance_account * 0.75 * 100) / 100; - } + $amount_total = $amount_total * 0.75; + // 计算医生个人所得税 - $income_tax = $this->computeIndividualIncomeTax($balance_account); + $income_tax = $this->computeIndividualIncomeTax($amount_total); - $withdrawal_amount = floor(($balance_account - $income_tax) * 100) / 100; + $withdrawal_amount = floor(($amount_total - $income_tax) * 100) / 100; $income_tax = floor($income_tax * 100) / 100; @@ -382,20 +387,21 @@ class DoctorAccountService extends BaseService } // 计算订单总金额 - $amount_total += $order_inquiry['amount_total']; + $amount_total = bcadd($amount_total,$order_inquiry["amount_total"],2); } - // 医生分成金额 - if ($amount_total > 0){ - $amount_total = floor($amount_total * 0.75 * 100) / 100; - } + // 提现金额 + $amount_total = $amount_total * 0.75; + // 计算医生个人所得税 $income_tax = $this->computeIndividualIncomeTax($amount_total); - // 可提现金额 - $withdrawal_amount = floor(($amount_total - $income_tax) * 100) / 100; + // 实际提现金额 + $withdrawal_amount = $amount_total - $income_tax; - $income_tax = floor($income_tax * 100) / 100; + if ($withdrawal_amount > 0){ + $withdrawal_amount = floor($withdrawal_amount * 100) / 100; + } if ($withdrawal_amount_total != $withdrawal_amount){ return fail(HttpEnumCode::SERVER_ERROR,"金额不符合"); @@ -422,13 +428,16 @@ class DoctorAccountService extends BaseService // 新增医生提现表 $data = array(); $data['doctor_id'] = $user_info['client_user_id']; - $data['bank_id'] = $doctor_bank_card['bank_id']; $data['account_name'] = $basic_bank['bank_name']; $data['bank_card_code'] = $doctor_bank_card['bank_card_code']; - $data['bank_card_code_four'] = substr($doctor_bank_card['bank_card_code'], -4);; - $data['applied_withdrawal_amount'] = $withdrawal_amount + $income_tax; // 提现金额 + $data['bank_card_code_four'] = substr($doctor_bank_card['bank_card_code'], -4); + if ($amount_total > 0){ + $data['applied_withdrawal_amount'] = floor($amount_total * 100) / 100; // 提现金额 + } $data['actual_withdrawal_amount'] = $withdrawal_amount; // 实际提现金额 - $data['income_tax'] = $income_tax; // 提现所得税金额 + if ($income_tax > 0){ + $data['income_tax'] = floor($income_tax * 100) / 100; // 提现所得税金额 + } $data['examine_status'] = 1; // 审核状态(1:审核中 2:审核通过 3:审核未通过) $doctor_withdrawal = DoctorWithdrawal::addDoctorWithdrawal($data); if (empty($doctor_withdrawal)){ @@ -436,6 +445,23 @@ class DoctorAccountService extends BaseService return fail(HttpEnumCode::SERVER_ERROR); } + // 新增医生提现表-关联银行 + $data = array(); + $data['withdrawal_id'] = $doctor_withdrawal["withdrawal_id"]; + $data['bank_id'] = $doctor_bank_card['bank_id']; + $data['bank_card_code'] = $doctor_bank_card['bank_card_code']; + $data['province_id'] = $doctor_bank_card['province_id']; + $data['province'] = $doctor_bank_card['province']; + $data['city_id'] = $doctor_bank_card['city_id']; + $data['city'] = $doctor_bank_card['city']; + $data['county_id'] = $doctor_bank_card['county_id']; + $data['county'] = $doctor_bank_card['county']; + $doctor_withdrawal_bank = DoctorWithdrawalBank::addDoctorWithdrawalBank($data); + if (empty($doctor_withdrawal_bank)){ + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); + } + foreach ($order_inquiry_id as $value){ // 新增医生提现-关联订单表 $data = array(); @@ -461,10 +487,16 @@ class DoctorAccountService extends BaseService // 账户表锁定 $params = array(); $params['doctor_id'] = $user_info['client_user_id']; + // 账户余额 DoctorAccount::dec($params,'balance_account',$amount_total); - DoctorAccount::inc($params,'applied_withdrawal_amount',$withdrawal_amount); + // 提现金额 + DoctorAccount::inc($params,'applied_withdrawal_amount',$amount_total); + // 实际提现金额 + DoctorAccount::inc($params,'actual_withdrawal_amount',$withdrawal_amount); + + // 所得税金额 DoctorAccount::inc($params,'income_tax',$income_tax); Db::commit(); @@ -517,10 +549,10 @@ class DoctorAccountService extends BaseService /** * 计算个人所得税 - * @param string|int $income - * @return float|int + * @param string|float $income + * @return float */ - protected function computeIndividualIncomeTax(string|int $income): float|int + protected function computeIndividualIncomeTax(string|float $income): float { if ($income <= 800) { return 0; @@ -531,7 +563,9 @@ class DoctorAccountService extends BaseService } // 实际纳税金额 - $income = $income * 0.8; + if ($income > 4000){ + $income = $income * 0.8; + } if ($income <= 20000) { $tax_rate = 0.2; // 税率 diff --git a/app/Services/InquiryService.php b/app/Services/InquiryService.php index 6a0e6e0..65e6847 100644 --- a/app/Services/InquiryService.php +++ b/app/Services/InquiryService.php @@ -21,6 +21,7 @@ use App\Model\OrderInquiryCase; use App\Model\OrderInquiryCoupon; use App\Model\OrderInquiryRefund; use App\Model\OrderPrescription; +use App\Model\OrderProductCoupon; use App\Model\PatientFamily; use App\Model\PatientFamilyHealth; use App\Model\PatientFamilyPersonal; @@ -150,14 +151,19 @@ class InquiryService extends BaseService return fail(HttpEnumCode::HTTP_ERROR, "当前非医生接诊时间"); } + // 定义优惠卷金额默认值 + $coupon_amount_total = 0; + // 获取问诊价格 $DoctorInquiryService = new DoctorInquiryService(); $inquiry_price = $DoctorInquiryService->getDoctorInquiryPrice($request_params['inquiry_type'], $request_params['inquiry_mode'], $request_params['doctor_id'] ?: ""); - if ($inquiry_price > 0) { - // 获取可用优惠卷 - $CouponService = new CouponService(); - $user_coupon = $CouponService->getUserUsableCouponOne($user_info['user_id'], $request_params['inquiry_type']); + // 获取患者问诊可用的优惠卷 + $userCouponService = new UserCouponService(); + $user_coupons = $userCouponService->getUserInquiryUsableCoupon($user_info['user_id'], $request_params['inquiry_type']); + + // 获取可用优惠卷总金额 + $coupon_amount_total = $userCouponService->getCouponTotalPrice($user_coupons); } // 确定支付渠道 @@ -174,8 +180,7 @@ class InquiryService extends BaseService try { // 实际付款金额 - $coupon_amount_total = $user_coupon['coupon']['coupon_price'] ?? 0; - $payment_amount_total = $inquiry_price - $coupon_amount_total; + $payment_amount_total = bcsub($inquiry_price , $coupon_amount_total,2); if ($payment_amount_total < 0) { $payment_amount_total = 0; } @@ -261,17 +266,29 @@ class InquiryService extends BaseService return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败"); } - // 增加问诊优惠卷表 - 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)) { - Db::rollBack(); - return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败"); + // 处理优惠卷数据 + if (!empty($user_coupons)) { + foreach ($user_coupons as $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_name']; + $data['coupon_use_price'] = $user_coupon['coupon_price']; + $order_inquiry_coupon = OrderInquiryCoupon::addOrderInquiryCoupon($data); + if (empty($order_inquiry_coupon)) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败"); + } + + // 修改优惠卷使用状态 + $data = array(); + $data['user_coupon_status'] = 1; + $data['coupon_use_date'] = date('Y-m-d H:i:s', time()); + + $params = array(); + $params['user_coupon_id'] = $user_coupon['user_coupon_id']; + UserCoupon::edit($params, $data); } } @@ -308,17 +325,6 @@ class InquiryService extends BaseService } } - // 修改优惠卷使用状态 - if (!empty($user_coupon)) { - $data = array(); - $data['user_coupon_status'] = 1; - $data['coupon_use_date'] = date('Y-m-d H:i:s', time()); - - $params = array(); - $params['user_coupon_id'] = $user_coupon['user_coupon_id']; - UserCoupon::edit($params, $data); - } - // 增加至未支付取消订单延迟队列 $data = array(); $data['order_no'] = $order_inquiry['inquiry_no']; @@ -989,7 +995,8 @@ class InquiryService extends BaseService $data['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $message = new AutoFinishInquiryDelayDirectProducer($data); - $message->setDelayMs(1000 * 60 * 60 * 24 * 3); +// $message->setDelayMs(1000 * 60 * 60 * 24 * 3); + $message->setDelayMs(1000 * 60 * 2); $producer = $this->container->get(Producer::class); $res = $producer->produce($message); if (!$res) { @@ -1258,8 +1265,21 @@ class InquiryService extends BaseService // 模拟退款时手动退还优惠卷 if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { - $InquiryService = new InquiryService(); - $InquiryService->returnInquiryCoupon($order_inquiry['order_inquiry_id'], $order_inquiry['user_id']); + // 获取该订单全部优惠卷数据 + $params = array(); + $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; + $order_inquiry_coupons = OrderInquiryCoupon::getList($params); + if (!empty($order_inquiry_coupons)){ + $userCouponService = new UserCouponService(); + foreach ($order_inquiry_coupons as $order_inquiry_coupon){ + // 退还优惠卷 + $userCouponService->returnUserCoupon($order_inquiry_coupon['user_coupon_id']); + + // 发送站内消息-优惠卷退还 + $MessagePush = new MessagePush($order_inquiry['user_id']); + $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); + } + } } } @@ -1372,17 +1392,20 @@ class InquiryService extends BaseService // 处理订单优惠卷 if (!empty($order_inquiry['coupon_amount_total']) && $order_inquiry['coupon_amount_total'] > 0) { - $InquiryService = new InquiryService(); - $InquiryService->returnInquiryCoupon($order_inquiry['order_inquiry_id'], $order_inquiry['user_id']); - - // 获取用户优惠卷信息 + // 获取该订单全部优惠卷数据 $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; - $order_inquiry_coupon = OrderInquiryCoupon::getOne($params); - if (!empty($order_inquiry_coupon)) { - // 发送站内消息-优惠卷退还 - $MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']); - $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); + $order_inquiry_coupons = OrderInquiryCoupon::getList($params); + if (!empty($order_inquiry_coupons)){ + $userCouponService = new UserCouponService(); + foreach ($order_inquiry_coupons as $order_inquiry_coupon){ + // 退还优惠卷 + $userCouponService->returnUserCoupon($order_inquiry_coupon['user_coupon_id']); + + // 发送站内消息-优惠卷退还 + $MessagePush = new MessagePush($order_inquiry['user_id']); + $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); + } } } @@ -1450,58 +1473,6 @@ class InquiryService extends BaseService return true; } - /** - * 退还问诊订单优惠卷 - * @param string $order_inquiry_id 问诊订单id - * @param string $patient_user_id 患者用户id - * @return bool - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function returnInquiryCoupon(string $order_inquiry_id, string $patient_user_id): bool - { - try { - // 获取用户优惠卷信息 - $params = array(); - $params['order_inquiry_id'] = $order_inquiry_id; - $order_inquiry_coupon = OrderInquiryCoupon::getOne($params); - if (empty($order_inquiry_coupon)) { - // 订单未使用优惠卷,无需退还 - return true; - } - - // 获取用户优惠卷数据 - $params = array(); - $params['user_coupon_id'] = $order_inquiry_coupon['user_coupon_id']; - $user_coupon = UserCoupon::getOne($params); - if (empty($user_coupon)) { - // 无该优惠卷数据,无需处理 - return true; - } - - // 恢复优惠卷 - $data = array(); - - // 检测优惠卷过期时间。判断是否需要退还 - if (strtotime($user_coupon['valid_end_time']) <= time()) { - // 超出过期时间,置为已过期 - $data['user_coupon_status'] = 3; - } else { - $data['user_coupon_status'] = 0; - $data['coupon_use_date'] = null; - } - - $params = array(); - $params['user_coupon_id'] = $order_inquiry_coupon['user_coupon_id']; - UserCoupon::edit($params, $data); - - return true; - } catch (\Exception $e) { - Log::getInstance()->error("退还用户优惠卷失败" . $e->getMessage()); - return false; - } - } - /** * 检测当前是否符合系统问诊时间 * @param string $inquiry_type 接诊类型(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药) diff --git a/app/Services/LoginService.php b/app/Services/LoginService.php index c733fa6..54a374a 100644 --- a/app/Services/LoginService.php +++ b/app/Services/LoginService.php @@ -38,29 +38,38 @@ class LoginService extends BaseService $wx_code = $this->request->input('wx_code'); $user_type = $this->request->input('user_type'); - $weChat = new Wechat($user_type); - - // 获取手机号 - $phone_info = $weChat->getPhone($phone_code); - - if (empty($phone_info) || empty($phone_info['phone_info']) || empty($phone_info['phone_info']['purePhoneNumber'])) { - return fail(HttpEnumCode::GET_WX_ERROR); - } - - // 获取用户openid - $wx_info_data = $weChat->codeToSession($wx_code); - if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) { - return fail(HttpEnumCode::GET_WX_ERROR); - } - - Db::beginTransaction(); - try { - // 获取用户信息 - $params = array(); - $params['mobile'] = $phone_info['phone_info']['purePhoneNumber']; - $user = UserModel::getOne($params); - if (empty($user)) { + $weChat = new Wechat($user_type); + + // 获取手机号 + $phone_info = $weChat->getPhone($phone_code); + + if (empty($phone_info) || empty($phone_info['phone_info']) || empty($phone_info['phone_info']['purePhoneNumber'])) { + return fail(HttpEnumCode::GET_WX_ERROR); + } + + // 获取用户openid + $wx_info_data = $weChat->codeToSession($wx_code); + if (empty($wx_info_data['session_key']) || empty($wx_info_data['openid'])) { + return fail(HttpEnumCode::GET_WX_ERROR); + } + }catch (\Throwable $e){ + return fail(HttpEnumCode::GET_WX_ERROR); + } + + // 定义是否新注册用户标识 + $is_new_register = 0; + + // 获取用户信息 + $params = array(); + $params['mobile'] = $phone_info['phone_info']['purePhoneNumber']; + $user = UserModel::getOne($params); + + // 新用户 + if (empty($user)){ + Db::beginTransaction(); + + try { // 处理药师特殊情况,后台添加,前台不允许注册 if ($user_type == 3) { Db::rollBack(); @@ -144,19 +153,20 @@ class LoginService extends BaseService // 创建单个账号 $account->createAccount($user->user_id, $user->user_name, addAliyunOssWebsite($avatar)); - if ($user['user_type'] == 1) { - // 发放用户优惠卷 - $CouponService = new CouponService(); + // 标识为新注册用户 + $is_new_register = 1; + }catch (\Throwable $e){ + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); + } - $res = $CouponService->DistributeCoupon(1, (string)$user->user_id, $user_patient['patient_id']); - if (!$res) { - Db::rollBack(); - return fail(HttpEnumCode::SERVER_ERROR); - } - } - } else { - // 已注册用户 - // 重复注册不同端 + Db::commit(); + }else{ + // 已注册用户 + Db::beginTransaction(); + + try { + // 判断是否重复注册不同端 if ($user_type != $user['user_type']) { Db::rollBack(); $result = UserTypeToString($user['user_type']); @@ -217,63 +227,86 @@ class LoginService extends BaseService } elseif ($user['user_type'] == 3) { $params['pharmacist_id'] = $result['pharmacist_id']; $res = UserPharmacistModel::editUserPharmacist($params, $data); + }else{ + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); } if (!$res) { Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR); } - - try { - $avatar = addAliyunOssWebsite($user['avatar']); - - $account = new Account(); - // 查询账号导入状态 - $res = $account->checkAccountStatus($user['user_id']); - if (!$res) { - // 创建单个账号 - $account->createAccount($user['user_id'], $user['user_name'], $avatar); - } - } catch (\Throwable $e) { - Log::getInstance()->error("IM账号倒入失败"); - } + }catch (\Throwable $e){ + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); } - // 记录用户登陆记录 - $Http = new Http(); - $login_ip = $Http->getIp(); - $params = array(); - $params['user_id'] = $user['user_id']; - - $data = array(); - $data['login_ip'] = $login_ip ?? ""; - $data['last_login_at'] = date('Y-m-d H:i:s', time()); - UserModel::editUser($params, $data); - - // 组合生成token的数据 - $token_user_data = array(); - $token_user_data['user_id'] = (string)$user['user_id']; // 用户id - $token_user_data['user_type'] = $user['user_type'];// 用户类型 - $token_user_data['open_id'] = $wx_info_data['openid'];// open_id - $token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id - - // 发放token - $Jwt = new Jwt(); - $token = $Jwt->encode($token_user_data); - - // 组合返回数据 - $data = array(); - $data['token'] = $token; - $data['user_id'] = (string)$user['user_id']; - $data['client_user_id'] = (string)$client_user_id; - Db::commit(); - return success($data); - } catch (\Exception $e) { + try { + $avatar = addAliyunOssWebsite($user['avatar']); + + $account = new Account(); + // 查询账号导入状态 + $res = $account->checkAccountStatus($user['user_id']); + if (!$res) { + // 创建单个账号 + $account->createAccount($user['user_id'], $user['user_name'], $avatar); + } + } catch (\Throwable $e) { + Log::getInstance()->error("IM账号导入失败"); + } + } + + // 发放优惠卷-患者 + Db::beginTransaction(); + + try { + if ($user['user_type'] == 1 && $is_new_register == 1) { + $CouponService = new CouponService(); + $res = $CouponService->GrantRegisterCoupon($user->user_id); + if (!$res) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); + } + } + }catch (\Throwable $e){ Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); } + + Db::commit(); + + // 记录用户登陆记录 + $Http = new Http(); + $login_ip = $Http->getIp(); + $params = array(); + $params['user_id'] = $user['user_id']; + + $data = array(); + $data['login_ip'] = $login_ip ?? ""; + $data['last_login_at'] = date('Y-m-d H:i:s', time()); + UserModel::editUser($params, $data); + + + // 组合生成token的数据 + $token_user_data = array(); + $token_user_data['user_id'] = (string)$user['user_id']; // 用户id + $token_user_data['user_type'] = $user['user_type'];// 用户类型 + $token_user_data['open_id'] = $wx_info_data['openid'];// open_id + $token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id + + // 发放token + $Jwt = new Jwt(); + $token = $Jwt->encode($token_user_data); + + // 组合返回数据 + $data = array(); + $data['token'] = $token; + $data['user_id'] = (string)$user['user_id']; + $data['client_user_id'] = (string)$client_user_id; + + return success($data); } /** @@ -310,19 +343,24 @@ class LoginService extends BaseService $wx_info_data = $weChat->codeToSession($wx_code); $session_key = $wx_info_data['session_key'] ?? ""; $open_id = $wx_info_data['openid'] ?? ""; - } catch (\Exception $e) { + } catch (\Throwable $e) { // 此处不进行处理 Log::getInstance()->info($e->getMessage()); } - Db::beginTransaction(); + // 定义是否新注册用户标识 + $is_new_register = 0; - try { - // 获取用户信息 - $params = array(); - $params['mobile'] = $phone; - $user = UserModel::getOne($params); - if (empty($user)) { + // 获取用户信息 + $params = array(); + $params['mobile'] = $phone; + $user = UserModel::getOne($params); + + // 新用户 + if (empty($user)) { + Db::beginTransaction(); + + try { // 处理药师特殊情况,后台添加,前台不允许注册 if ($user_type == 3) { Db::rollBack(); @@ -410,17 +448,19 @@ class LoginService extends BaseService // 创建单个账号 $account->createAccount($user->user_id, $user->user_name, addAliyunOssWebsite($avatar)); - if ($user['user_type'] == 1) { - // 发放用户优惠卷 - $CouponService = new CouponService(); + // 标识为新注册用户 + $is_new_register = 1; + }catch (\Throwable $e){ + Db::rollBack(); + return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage()); + } - $res = $CouponService->DistributeCoupon(1, (string)$user->user_id, $user_patient['patient_id']); - if (!$res) { - Db::rollBack(); - return fail(HttpEnumCode::SERVER_ERROR); - } - } - } else { + Db::commit(); + } else{ + // 已注册用户 + Db::beginTransaction(); + + try { // 已注册用户 if ($user_type != $user['user_type']) { Db::rollBack(); @@ -493,62 +533,82 @@ class LoginService extends BaseService Db::rollBack(); return fail(HttpEnumCode::SERVER_ERROR); } - - try { - $avatar = addAliyunOssWebsite($user['avatar']); - - $account = new Account(); - // 查询账号导入状态 - $res = $account->checkAccountStatus($user['user_id']); - if (!$res) { - // 创建单个账号 - $account->createAccount($user['user_id'], $user['user_name'], $avatar); - } - } catch (\Throwable $e) { - Log::getInstance()->error("IM账号倒入失败"); - } + }catch (\Throwable $e){ + Db::rollBack(); + return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage()); } - // 记录用户登陆记录 - $Http = new Http(); - $login_ip = $Http->getIp(); - $params = array(); - $params['user_id'] = $user['user_id']; - - $data = array(); - $data['login_ip'] = $login_ip ?? ""; - $data['last_login_at'] = date('Y-m-d H:i:s', time()); - UserModel::editUser($params, $data); - - // 组合生成token的数据 - $token_user_data = array(); - $token_user_data['user_id'] = (string)$user['user_id']; // 用户id - $token_user_data['user_type'] = $user['user_type'];// 用户类型 - $token_user_data['open_id'] = $open_id ?? "";// open_id - $token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id - - // 发放token - $Jwt = new Jwt(); - $token = $Jwt->encode($token_user_data); - - // 登录成功,删除验证码 - if ($app_env != 'dev') { - $redis->del("login_code" . $phone); - } - - // 组合返回数据 - $data = array(); - $data['token'] = $token; - $data['user_id'] = (string)$user['user_id']; - $data['client_user_id'] = (string)$client_user_id; - Db::commit(); - return success($data); - } catch (\Exception $e) { - Db::rollBack(); - return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage()); + try { + $avatar = addAliyunOssWebsite($user['avatar']); + + $account = new Account(); + // 查询账号导入状态 + $res = $account->checkAccountStatus($user['user_id']); + if (!$res) { + // 创建单个账号 + $account->createAccount($user['user_id'], $user['user_name'], $avatar); + } + } catch (\Throwable $e) { + Log::getInstance()->error("IM账号导入失败"); + } } + + // 发放优惠卷-患者 + Db::beginTransaction(); + + try { + if ($user['user_type'] == 1 && $is_new_register == 1) { + $CouponService = new CouponService(); + $res = $CouponService->GrantRegisterCoupon($user->user_id); + if (!$res) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR); + } + } + }catch (\Throwable $e){ + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage()); + } + + Db::commit(); + + // 记录用户登陆记录 + $Http = new Http(); + $login_ip = $Http->getIp(); + $params = array(); + $params['user_id'] = $user['user_id']; + + $data = array(); + $data['login_ip'] = $login_ip ?? ""; + $data['last_login_at'] = date('Y-m-d H:i:s', time()); + UserModel::editUser($params, $data); + + // 组合生成token的数据 + $token_user_data = array(); + $token_user_data['user_id'] = (string)$user['user_id']; // 用户id + $token_user_data['user_type'] = $user['user_type'];// 用户类型 + $token_user_data['open_id'] = $open_id ?? "";// open_id + $token_user_data['client_user_id'] = (string)$client_user_id;// 对应客户端id + + // 发放token + $Jwt = new Jwt(); + $token = $Jwt->encode($token_user_data); + + // 登录成功,删除验证码 + if ($app_env != 'dev') { + $redis->del("login_code" . $phone); + } + + // 组合返回数据 + $data = array(); + $data['token'] = $token; + $data['user_id'] = (string)$user['user_id']; + $data['client_user_id'] = (string)$client_user_id; + + Db::commit(); + return success($data); } /** diff --git a/app/Services/OrderProductService.php b/app/Services/OrderProductService.php index 0c63f39..0146835 100644 --- a/app/Services/OrderProductService.php +++ b/app/Services/OrderProductService.php @@ -4,14 +4,17 @@ namespace App\Services; use App\Constants\HttpEnumCode; use App\Exception\BusinessException; +use App\Model\OrderInquiryCoupon; use App\Model\OrderInquiryRefund; use App\Model\OrderPrescription; use App\Model\OrderPrescriptionProduct; use App\Model\OrderProduct; +use App\Model\OrderProductCoupon; use App\Model\OrderProductItem; use App\Model\OrderProductRefund; use App\Model\Product; use App\Model\ProductPlatformAmount; +use App\Model\UserPatient; use Extend\Wechat\WechatPay; use Hyperf\DbConnection\Db; use Hyperf\Snowflake\IdGeneratorInterface; @@ -41,6 +44,8 @@ class OrderProductService extends BaseService * @param string|int $cancel_reason 订单取消原因(1:主动取消 2:复核失败/库存不足 3:支付超时 * @param string $cancel_remarks 订单取消原因 * @return array + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface */ public function cancelUnpayProductOrder(string|int $order_no,string|int $cancel_reason,string $cancel_remarks): array { @@ -87,6 +92,16 @@ class OrderProductService extends BaseService return $result; } + // 获取患者数据 + $params = array(); + $params['patient_id'] = $order_product['patient_id']; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)){ + $result['status'] = 0; + $result['message'] = "取消未支付的问诊订单失败:未查询到对应用户数据"; + return $result; + } + // 取消药品订单 $data = array(); $data['order_product_status'] = 5; @@ -134,7 +149,6 @@ class OrderProductService extends BaseService return $result; } - // 库存+订单商品数量 $params = array(); $params['amount_id'] = $product_platform_amount['amount_id']; @@ -181,6 +195,25 @@ class OrderProductService extends BaseService OrderPrescriptionProduct::edit($params, $data); } + // 处理订单优惠卷 + if (!empty($order_product['coupon_amount_total']) && $order_product['coupon_amount_total'] > 0) { + // 获取该订单全部优惠卷数据 + $params = array(); + $params['order_product_id'] = $order_product['order_product_id']; + $order_product_coupons = OrderProductCoupon::getList($params); + if (!empty($order_product_coupons)){ + $userCouponService = new UserCouponService(); + foreach ($order_product_coupons as $order_product_coupon){ + // 退还优惠卷 + $userCouponService->returnUserCoupon($order_product_coupon['user_coupon_id']); + + // 发送站内消息-优惠卷退还 + $MessagePush = new MessagePush($user_patient['user_id']); + $MessagePush->patientRefundCoupon($order_product_coupon['coupon_name']); + } + } + } + return $result; } @@ -233,56 +266,60 @@ class OrderProductService extends BaseService throw new BusinessException("订单支付状态错误,无法退款"); } + // 获取患者数据 + $params = array(); + $params['patient_id'] = $order_product['patient_id']; + $user_patient = UserPatient::getOne($params); + if (empty($user_patient)){ + throw new BusinessException("未查询到对应用户数据"); + } + // 系统退款编号 $generator = $this->container->get(IdGeneratorInterface::class); $product_refund_no = $generator->generate(); // 检测订单金额 - if ($order_product['payment_amount_total'] > 0){ - // 发起退款 - $WechatPay = new WechatPay(1, 2); - - $options = array(); - $options['transaction_id'] = $order_product['escrow_trade_no']; - $options['out_refund_no'] = (string)$product_refund_no; - $options['reason'] = $refund_reason; - $options['amount'] = [ - 'refund' => (int)($order_product['payment_amount_total'] * 100), - 'total' => (int)($order_product['payment_amount_total'] * 100), - 'currency' => "CNY", - ]; - - $result = $WechatPay->refund($options); - - // 处理订单退款状态 - // 商品订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常) - $success_time = ""; - if ($result['status'] == "SUCCESS") { - // 退款成功 - $refund_status = 3; - $success_time = $result['success_time']; - } elseif ($result['status'] == "CLOSED") { - // 退款关闭 - $refund_status = 5; - } elseif ($result['status'] == "PROCESSING") { - // 退款处理中 - $refund_status = 2; - } elseif ($result['status'] == "ABNORMAL") { - // 退款异常,此情况不处理,进行短信通知 - throw new BusinessException("订单退款状态异常"); - } else { - throw new BusinessException("订单退款状态错误"); - } - - $refund_id = $result['refund_id']; - - }else{ - // 模拟退款 - $refund_status = 3; - $refund_id = "模拟退款:" . $generator->generate(); - $success_time = date("Y-m-d H:i:s", time()); + if ($order_product['payment_amount_total'] <= 0){ + throw new BusinessException("订单金额错误"); } + // 发起退款 + $WechatPay = new WechatPay(1, 2); + + $options = array(); + $options['transaction_id'] = $order_product['escrow_trade_no']; + $options['out_refund_no'] = (string)$product_refund_no; + $options['reason'] = $refund_reason; + $options['amount'] = [ + 'refund' => (int)($order_product['payment_amount_total'] * 100), + 'total' => (int)($order_product['payment_amount_total'] * 100), + 'currency' => "CNY", + ]; + + $result = $WechatPay->refund($options); + + // 处理订单退款状态 + // 商品订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常) + $success_time = ""; + if ($result['status'] == "SUCCESS") { + // 退款成功 + $refund_status = 3; + $success_time = $result['success_time']; + } elseif ($result['status'] == "CLOSED") { + // 退款关闭 + $refund_status = 5; + } elseif ($result['status'] == "PROCESSING") { + // 退款处理中 + $refund_status = 2; + } elseif ($result['status'] == "ABNORMAL") { + // 退款异常,此情况不处理,进行短信通知 + throw new BusinessException("订单退款状态异常"); + } else { + throw new BusinessException("订单退款状态错误"); + } + + $refund_id = $result['refund_id']; + // 新增退款表 $data = array(); $data['patient_id'] = $order_product['patient_id']; diff --git a/app/Services/PatientOrderService.php b/app/Services/PatientOrderService.php index bf48948..ca0078f 100644 --- a/app/Services/PatientOrderService.php +++ b/app/Services/PatientOrderService.php @@ -19,11 +19,13 @@ use App\Model\OrderPrescription; use App\Model\OrderPrescriptionFile; use App\Model\OrderPrescriptionProduct; use App\Model\OrderProduct; +use App\Model\OrderProductCoupon; use App\Model\OrderProductItem; use App\Model\OrderProductLogistic; use App\Model\PatientFollow; use App\Model\Product; use App\Model\ProductPlatformAmount; +use App\Model\UserCoupon; use App\Model\UserDoctor; use App\Model\UserDoctorInfo; use App\Model\UserPharmacistInfo; @@ -199,7 +201,7 @@ class PatientOrderService extends BaseService $order_inquiry_case = OrderInquiryCase::getOne($params, $fields); if (empty($order_inquiry_case)) { $order_inquiry['case'] = []; - }else{ + } else { $order_inquiry['case'] = $order_inquiry_case->toArray(); } @@ -262,8 +264,8 @@ class PatientOrderService extends BaseService $params['inquiry_type'] = 4; $params['inquiry_mode'] = 1; $doctor_inquiry_config = DoctorInquiryConfig::getOne($params); - if (!empty($doctor_inquiry_config)){ - if ($doctor_inquiry_config['is_enable'] == 1){ + if (!empty($doctor_inquiry_config)) { + if ($doctor_inquiry_config['is_enable'] == 1) { $user_doctor['multi_point_enable'] = 1; } } @@ -371,16 +373,6 @@ class PatientOrderService extends BaseService // 推送医生-患者取消问诊 $MessagePush = new MessagePush($user_doctor['user_id'], $order_inquiry['order_inquiry_id']); $MessagePush->patientCancelInquiryToDoctor(); - - // 获取用户优惠卷信息 - $params = array(); - $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; - $order_inquiry_coupon = OrderInquiryCoupon::getOne($params); - if (!empty($order_inquiry_coupon)) { - // 发送站内消息-优惠卷退还 - $MessagePush = new MessagePush($order_inquiry['user_id'], $order_inquiry['order_inquiry_id']); - $MessagePush->patientRefundCoupon($order_inquiry_coupon['coupon_name']); - } } } catch (\Exception $e) { return success(); @@ -592,8 +584,8 @@ class PatientOrderService extends BaseService $params['inquiry_type'] = 4; $params['inquiry_mode'] = 1; $doctor_inquiry_config = DoctorInquiryConfig::getOne($params); - if (!empty($doctor_inquiry_config)){ - if ($doctor_inquiry_config['is_enable'] == 1){ + if (!empty($doctor_inquiry_config)) { + if ($doctor_inquiry_config['is_enable'] == 1) { $user_doctor['multi_point_enable'] = 1; } } @@ -639,7 +631,7 @@ class PatientOrderService extends BaseService } Db::commit(); - } catch (\Exception $e) { + } catch (\Throwable $e) { Db::rollBack(); return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage()); } @@ -715,6 +707,7 @@ class PatientOrderService extends BaseService $result['created_at'] = ""; // 创建时间 $result['inquiry_type'] = 0; // 订单类型(1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药 5:检测) $result['pay_config'] = []; // 小程序支付配置 + $result['cannot_use_coupon_reason'] = ""; // 不可使用优惠卷原因 if ($order_type == 1) { // 问诊订单 @@ -827,7 +820,53 @@ class PatientOrderService extends BaseService // 获取订单金额 $result['amount_total'] = $order_product['amount_total']; // 订单金额 $result['payment_amount_total'] = $order_product['payment_amount_total']; // 实际订单金额 - $result['coupon_amount_total'] = 0; // 优惠金额 + $result['coupon_amount_total'] = $order_product['coupon_amount_total']; // 优惠金额 + + // 获取优惠卷不可用原因。存在优惠卷,但是未使用 + if ($order_product['coupon_amount_total'] == 0){ + // 优惠卷商品数据 + $coupon_product_datas = array(); + + // 获取药品订单关联处方商品数据 + $params = array(); + $params['order_prescription_id'] = $order_product['order_prescription_id']; + $order_prescription_products = OrderPrescriptionProduct::getList($params); + if (empty($order_prescription_products)) { + $return_result['message'] = "优惠卷数据错误"; + $return_result['data'] = $result; + $return_result['data']['order_product_id'] = $order_product['order_product_id']; + $return_result['data']['order_product_status'] = $order_product['order_product_status']; + $return_result['data']['order_pay_status'] = $order_product['pay_status']; + return success($return_result); + } + + foreach ($order_prescription_products as $order_prescription_product){ + $params = array(); + $params['product_id'] = $order_prescription_product['product_id']; + $product = Product::getWithAmountOne($params); + if (empty($product)) { + $return_result['message'] = "优惠卷数据错误"; + $return_result['data'] = $result; + $return_result['data']['order_product_id'] = $order_product['order_product_id']; + $return_result['data']['order_product_status'] = $order_product['order_product_status']; + $return_result['data']['order_pay_status'] = $order_product['pay_status']; + return success($return_result); + } + + // 优惠卷商品数据 + $coupon_product_data = array(); + $product['product_num'] = $order_prescription_product['prescription_product_num']; + $coupon_product_data = $product; + $coupon_product_datas[] = $coupon_product_data; + } + + $user_coupons = UserCoupon::getUserProductUsableCoupon($user_info['user_id'],$coupon_product_datas); + if (!empty($user_coupons)) { + foreach ($user_coupons as $user_coupon){ + $result['cannot_use_coupon_reason'] = "商品不足" . $user_coupon['coupon']['min_usable_number'] . "盒,不满足使用优惠卷条件";; // 不可使用优惠卷原因 + } + } + } if ($order_product['payment_amount_total'] > 0) { // 发起支付 @@ -947,7 +986,7 @@ class PatientOrderService extends BaseService $params = array(); $params['order_inquiry_id'] = $order_inquiry['order_inquiry_id']; $order_inquiry_case = OrderInquiryCase::getOne($params); - if (empty($order_inquiry_case)){ + if (empty($order_inquiry_case)) { Db::rollBack(); return fail(HttpEnumCode::HTTP_ERROR, "患者病例错误"); } @@ -1095,19 +1134,22 @@ class PatientOrderService extends BaseService $not_enough_product_ids = []; $amount_total = 0; - foreach ($product_ids as $value) { + + // 优惠卷商品数据 + $coupon_product_datas = array(); + + foreach ($product_ids as $product_id) { // 检测药品是否存在于处方中 $params = array(); $params['order_prescription_id'] = $order_prescription['order_prescription_id']; - $params['product_id'] = $value; + $params['product_id'] = $product_id; $order_prescription_product = OrderPrescriptionProduct::getOne($params); if (empty($order_prescription_product)) { return fail(HttpEnumCode::HTTP_ERROR, "创建订单失败"); } - $params = array(); - $params['product_id'] = $value; + $params['product_id'] = $product_id; $product = Product::getWithAmountOne($params); if (empty($product)) { return fail(HttpEnumCode::HTTP_ERROR, "处方存在未知药品"); @@ -1117,19 +1159,38 @@ class PatientOrderService extends BaseService if (!empty($product['ProductPlatformAmount'])) { if ($order_prescription_product['prescription_product_num'] > $product['ProductPlatformAmount']['stock']) { // 库存不足 - $not_enough_product_ids[] = $value; + $not_enough_product_ids[] = $product_id; continue; } } // 获取订单金额 - $amount_total += $product['product_price'] * $order_prescription_product['prescription_product_num']; + $amount_total = bcadd($amount_total, ($product['product_price'] * $order_prescription_product['prescription_product_num']), 2); + + // 优惠卷商品数据 + $coupon_product_data = array(); + $product['product_num'] = $order_prescription_product['prescription_product_num']; + $coupon_product_data = $product->toArray(); + $coupon_product_datas[] = $coupon_product_data; } if (!empty($not_enough_product_ids)) { return fail(HttpEnumCode::HTTP_ERROR, "存在库存不足商品", $not_enough_product_ids); } + // 定义优惠卷金额默认值 + $coupon_amount_total = 0; + + if (!empty($coupon_product_datas)) { + // 获取患者购药可用的优惠卷 + $userCouponService = new UserCouponService(); + $user_coupons = $userCouponService->getUserProductUsableCoupon($user_info['user_id'], $coupon_product_datas); + + // 获取可用优惠卷总金额 + $coupon_amount_total = $userCouponService->getCouponTotalPrice($user_coupons); + } + + // 处理运费数据 $app_env = config('app_env', 'prod'); if ($app_env != "dev") { // 获取运费金额 @@ -1141,16 +1202,20 @@ class PatientOrderService extends BaseService } else { $logistics_fee = $result['freight']; } - - // 实际支付金额 - $payment_amount_total = $amount_total + $logistics_fee; + } else { + $logistics_fee = 0; } + // 实际支付金额=商品总金额-优惠卷金额+运费金额 + $payment_amount_total = bcadd(bcsub($amount_total , $coupon_amount_total,2), $logistics_fee, 2); if ($app_env == "dev") { - $logistics_fee = 0; $payment_amount_total = 0.01; } + if ($payment_amount_total <= 0){ + return fail(HttpEnumCode::SERVER_ERROR); + } + // 确定支付渠道 // 支付渠道(1:小程序支付 2:微信扫码支付) if ($client_type == 1) { @@ -1175,6 +1240,7 @@ class PatientOrderService extends BaseService $data['order_product_status'] = 1; // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消) $data['pay_channel'] = $pay_channel; // 支付渠道(1:小程序支付 2:微信扫码支付) $data['amount_total'] = $amount_total; // 订单金额 + $data['coupon_amount_total'] = $coupon_amount_total; // 优惠卷总金额 $data['payment_amount_total'] = $payment_amount_total; // 实际付款金额 $data['logistics_fee'] = $logistics_fee; // 运费金额 $data['province_id'] = $user_ship_address['province_id']; @@ -1263,6 +1329,32 @@ class PatientOrderService extends BaseService $params['order_prescription_id'] = $order_prescription['order_prescription_id']; OrderPrescription::edit($params, $data); + // 处理优惠卷数据 + if (!empty($user_coupons)) { + foreach ($user_coupons as $user_coupon){ + // 增加问诊优惠卷表 + $data = array(); + $data['order_product_id'] = $order_product['order_product_id'];// 订单-商品id + $data['user_coupon_id'] = $user_coupon['user_coupon_id']; + $data['coupon_name'] = $user_coupon['coupon_name']; + $data['coupon_use_price'] = $user_coupon['coupon_price']; + $order_product_coupon = OrderProductCoupon::addOrderProductCoupon($data); + if (empty($order_product_coupon)) { + Db::rollBack(); + return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败"); + } + + // 修改优惠卷使用状态 + $data = array(); + $data['user_coupon_status'] = 1; + $data['coupon_use_date'] = date('Y-m-d H:i:s', time()); + + $params = array(); + $params['user_coupon_id'] = $user_coupon['user_coupon_id']; + UserCoupon::edit($params, $data); + } + } + // 增加至取消订单延迟队列 $data = array(); $data['order_no'] = (string)$order_product['order_product_no']; @@ -1492,7 +1584,10 @@ class PatientOrderService extends BaseService } $amount_total = 0; - $coupon_amount_total = 0; + + // 优惠卷商品数据 + $coupon_product_datas = array(); + foreach ($order_prescription_product as &$item) { $params = array(); $params['product_id'] = $item['product_id']; @@ -1512,7 +1607,25 @@ class PatientOrderService extends BaseService } } - $amount_total += $product['product_price'] * $item['prescription_product_num']; + $amount_total = bcadd($amount_total,($product['product_price'] * $item['prescription_product_num']),2); + + // 优惠卷商品数据 + $coupon_product_data = array(); + $product['product_num'] = $item['prescription_product_num']; + $coupon_product_data = $product->toArray(); + $coupon_product_datas[] = $coupon_product_data; + } + + // 定义优惠卷金额默认值 + $coupon_amount_total = 0; + + if (!empty($coupon_product_datas)) { + // 获取患者购药可用的优惠卷 + $userCouponService = new UserCouponService(); + $user_coupons = $userCouponService->getUserProductUsableCoupon($user_info['user_id'], $coupon_product_datas); + + // 获取可用优惠卷总金额 + $coupon_amount_total = $userCouponService->getCouponTotalPrice($user_coupons); } // 获取运费金额 @@ -1525,11 +1638,10 @@ class PatientOrderService extends BaseService } } - // 实际支付金额 + // 实际支付金额=商品总金额-优惠卷金额+运费金额 + $payment_amount_total = bcadd(bcsub($amount_total , $coupon_amount_total,2), $logistics_fee, 2); if (env("APP_ENV") == "dev") { $payment_amount_total = 0.01; - } else { - $payment_amount_total = $amount_total + $logistics_fee; } // 获取收货地址 @@ -1782,8 +1894,8 @@ class PatientOrderService extends BaseService $params['inquiry_type'] = 4; $params['inquiry_mode'] = 1; $doctor_inquiry_config = DoctorInquiryConfig::getOne($params); - if (!empty($doctor_inquiry_config)){ - if ($doctor_inquiry_config['is_enable'] == 1){ + if (!empty($doctor_inquiry_config)) { + if ($doctor_inquiry_config['is_enable'] == 1) { $user_doctor['multi_point_enable'] = 1; } } @@ -1795,7 +1907,7 @@ class PatientOrderService extends BaseService } // 检测管图片 - if (!empty($order_detection['detection_pic'])){ + if (!empty($order_detection['detection_pic'])) { $detection_pic = explode(',', $order_detection['detection_pic']); foreach ($detection_pic as &$value) { $value = addAliyunOssWebsite($value); @@ -1807,7 +1919,7 @@ class PatientOrderService extends BaseService $params = array(); $params['detection_project_id'] = $order_detection['detection_project_id']; $detection_project = DetectionProject::getOne($params); - if (empty($detection_project)){ + if (empty($detection_project)) { return fail(); } @@ -1815,7 +1927,7 @@ class PatientOrderService extends BaseService $order_detection['detection_result_pdf'] = addAliyunOssWebsite($order_detection['detection_result_pdf']); // 检测成功时间 - $detection_success_time = date('Y-m-d',time() + 60 * 60 * $detection_project['detection_time']); + $detection_success_time = date('Y-m-d', time() + 60 * 60 * $detection_project['detection_time']); $order_detection['detection_success_time'] = $detection_success_time; return success($order_detection); diff --git a/app/Services/UserCouponService.php b/app/Services/UserCouponService.php new file mode 100644 index 0000000..43b9a7c --- /dev/null +++ b/app/Services/UserCouponService.php @@ -0,0 +1,274 @@ +toArray(); + + $coupons = array(); + foreach ($user_coupons as $user_coupon){ + $user_coupon['coupon']['user_coupon_id'] = $user_coupon['user_coupon_id']; + $coupons[] = $user_coupon['coupon']; + } + + // 选中的优惠卷 + $selected_coupons = array(); + + // 优惠卷最高金额 + $coupon_high_price = 0; + + // 是否存在互斥卷 + $is_mutex = 0; + + // 可选择优惠卷中是否存在互斥卷 + foreach ($coupons as $coupon) { + if ($coupon['is_mutex'] == 1) { + $is_mutex = 1; + } + } + + foreach ($coupons as $coupon) { + if (empty($selected_coupon)) { + $selected_coupons[] = $coupon; // 选中的优惠卷数据 + + $coupon_high_price = $coupon['coupon_price']; + continue; + } + + // 处理存在互斥卷情况 + if ($is_mutex == 1) { + // 选择金额最高的为选中 + if ($coupon['coupon_price'] < $coupon_high_price){ + continue; + } + + if ($coupon['coupon_price'] > $coupon_high_price) { + $coupon_high_price = $coupon['coupon_price']; + + // 选中的优惠卷数据置空 + $selected_coupons = array(); + $selected_coupons[] = $coupon; + + continue; + } + } + + $selected_coupons[] = $coupon; // 选中的优惠卷数据 + } + + return $selected_coupons; + } + + /** + * 获取可用优惠卷总金额 + * @param array $coupons 优惠卷数据 + * @return int + */ + public function getCouponTotalPrice(array $coupons): int + { + $coupon_total_price = 0; + + foreach ($coupons as $coupon){ + $coupon_total_price = bcadd($coupon_total_price,$coupon['coupon_price'],2); + } + + return $coupon_total_price; + } + + /** + * 获取患者购药可用的优惠卷 + * @param string|int $user_id + * @param array $coupon_product_datas + * @return array + */ + public function getUserProductUsableCoupon(string|int $user_id, array $coupon_product_datas): array + { + $user_coupons = UserCoupon::getUserProductUsableCoupon($user_id,$coupon_product_datas); + if (empty($user_coupons)) { + return array(); + } + + $user_coupons = $user_coupons->toArray(); + + $coupons = array(); + foreach ($user_coupons as $user_coupon){ + $user_coupon['coupon']['user_coupon_id'] = $user_coupon['user_coupon_id']; + $coupons[] = $user_coupon['coupon']; + } + + // 选中的优惠卷 + $selected_coupons = array(); + + // 优惠卷最高金额 + $coupon_high_price = 0; + + // 是否存在互斥卷 + $is_mutex = 0; + + // 新增字段 + foreach ($coupons as $key => $coupon) { + $coupons[$key]['is_can_use'] = 1;// 是否可使用 + $coupons[$key]['cannot_use_coupon_reason'] = ""; // 不可使用原因 + } + + foreach ($coupons as $key => $coupon) { + // 处理优惠卷数量限制问题 + if ($coupon['coupon_type'] == 3 && !empty($coupon['product_id'])){ + // 数量是否足够标识字段 + $quantity_quantity = 0; + + foreach ($coupon_product_datas as $coupon_product_data){ + // 如该优惠卷不包含此商品,跳过 + if (!str_contains($coupon['product_id'], $coupon_product_data['product_id'])){ + continue; + } + + // 判断商品数量是否满足 + if($coupon['min_usable_number'] > $coupon_product_data['product_num']){ + continue; + } + + // 标记为数量足够 + $quantity_quantity = 1; + } + + if ($quantity_quantity == 0){ + // 此优惠卷无商品能达到规定最小数量 + $coupons[$key]['is_can_use'] = 0; + $coupons[$key]['cannot_use_coupon_reason'] = "商品不足" . $coupon['min_usable_number'] . "盒,不满足使用优惠卷条件"; + } + } + + // 处理满减金额问题 + if ($coupon['coupon_type'] == 2 && !empty($coupon['product_id'])){ + // 可共用一个优惠卷的商品金额问题 + $product_price = 0; + + foreach ($coupon_product_datas as $coupon_product_data) { + // 如该优惠卷不包含此商品,跳过 + if (!str_contains($coupon['product_id'], $coupon_product_data['product_id'])) { + continue; + } + + $product_price = bcadd($product_price,$coupon_product_data['product_price'],2); + } + + if ($coupon['with_amount'] > $product_price){ + // 此优惠卷因商品金额不足,无法使用 + $coupons[$key]['is_can_use'] = 0; + } + } + + // 判断品牌是否符合-暂无品牌 + } + + // 可选择优惠卷中是否存在互斥卷 + foreach ($coupons as $coupon) { + if ($coupon['is_can_use'] == 0){ + continue; + } + + if ($coupon['is_mutex'] == 1) { + $is_mutex = 1; + } + } + + // 处理存在互斥卷情况 + foreach ($coupons as $coupon) { + if ($coupon['is_can_use'] == 0){ + continue; + } + + if (empty($selected_coupon)) { + $selected_coupons[] = $coupon; // 选中的优惠卷数据 + + $coupon_high_price = $coupon['coupon_price']; + continue; + } + + // 处理存在互斥卷情况 + if ($is_mutex == 1) { + // 选择金额最高的为选中 + if ($coupon['coupon_price'] < $coupon_high_price){ + continue; + } + + if ($coupon['coupon_price'] > $coupon_high_price) { + $coupon_high_price = $coupon['coupon_price']; + + // 选中的优惠卷数据置空 + $selected_coupons = array(); + $selected_coupons[] = $coupon; + + continue; + } + } + + $selected_coupons[] = $coupon; // 选中的优惠卷数据 + } + + return $selected_coupons; + } + + /** + * 退还用户优惠卷 + * @param string|int $user_coupon_id + * @return bool + */ + public function returnUserCoupon(string|int $user_coupon_id): bool + { + try { + // 获取用户优惠卷数据 + $params = array(); + $params['user_coupon_id'] = $user_coupon_id; + $user_coupon = UserCoupon::getOne($params); + if (empty($user_coupon)) { + // 无该优惠卷数据,无需处理 + return true; + } + + // 恢复优惠卷 + $data = array(); + + // 检测优惠卷过期时间。判断是否需要退还 + if (strtotime($user_coupon['valid_end_time']) <= time()) { + // 超出过期时间,置为已过期 + $data['user_coupon_status'] = 3; + } else { + $data['user_coupon_status'] = 0; + $data['coupon_use_date'] = null; + } + + $params = array(); + $params['user_coupon_id'] = $user_coupon_id; + UserCoupon::edit($params, $data); + }catch (\Throwable $e){ + Log::getInstance("UserCouponService-returnUserCoupon")->error($e->getMessage()); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/app/Services/UserPatientService.php b/app/Services/UserPatientService.php index 1df621b..8fb9e27 100644 --- a/app/Services/UserPatientService.php +++ b/app/Services/UserPatientService.php @@ -45,7 +45,7 @@ class UserPatientService extends BaseService } // 获取福利数据 - $coupon = $this->getPatientAvailableCouponList($user_patient['user_id'],1); + $coupon = UserCoupon::getUserObjectTypeCoupon($user_patient['user_id'],2); // 获取问诊数量-待支付 $InquiryService = new InquiryService(); @@ -120,7 +120,7 @@ class UserPatientService extends BaseService * 获取患者优惠卷列表 * @return array */ - public function getPatientCouponlist(): array + public function getPatientCouponList(): array { $user_info = $this->request->getAttribute("userInfo") ?? []; @@ -140,9 +140,11 @@ class UserPatientService extends BaseService return fail(HttpEnumCode::HTTP_ERROR, "非法用户"); } - $CouponService = new CouponService(); - - $user_coupon = $CouponService->getUserCouponStatusList($user_patient['user_id'],[1,2,3,4,5],$user_coupon_status); + // 获取优惠卷列表 + $params = array(); + $params["user_id"] = $user_patient['user_id']; + $params["user_coupon_status"] = $user_coupon_status;// 状态(0:未使用 1:已使用 3:已过期) + $user_coupon = UserCoupon::getWithCouponList($params); $result = []; foreach ($user_coupon as $item){ @@ -165,6 +167,7 @@ class UserPatientService extends BaseService $data['coupon_name'] = $item['coupon']['coupon_name']; $data['coupon_price'] = $item['coupon']['coupon_price']; $data['application_scope'] = $item['coupon']['application_scope']; + $data['inquiry_type'] = $item['coupon']['inquiry_type']; $result[] = $data; } diff --git a/composer.json b/composer.json index f7598f0..0737866 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "hyperf/validation": "^3.0", "intervention/image": "^2.7", "tecnickcom/tcpdf": "^6.6", - "w7corp/easywechat": "^6.7" + "w7corp/easywechat": "^6.7", + "ext-bcmath": "*" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", diff --git a/config/routes.php b/config/routes.php index d9a0b37..6be0c8f 100644 --- a/config/routes.php +++ b/config/routes.php @@ -238,7 +238,7 @@ Router::addGroup('/patient', function () { // 我的福利 Router::addGroup('/coupon', function () { // 获取患者优惠卷列表 - Router::get('', [UserPatientController::class, 'getPatientCouponlist']); + Router::get('', [UserPatientController::class, 'getPatientCouponList']); }); // 问诊 diff --git a/extend/Wechat/Wechat.php b/extend/Wechat/Wechat.php index 4889b8e..d7dd1d7 100644 --- a/extend/Wechat/Wechat.php +++ b/extend/Wechat/Wechat.php @@ -22,6 +22,8 @@ use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Hyperf\Context\ApplicationContext; +use Hyperf\Guzzle\CoroutineHandler; + /** * 微信类 @@ -70,17 +72,6 @@ class Wechat // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri 'retry' => true, // 使用默认重试配置 - // 'retry' => [ - // // 仅以下状态码重试 - // 'http_codes' => [429, 500] - // // 最大重试次数 - // 'max_retries' => 3, - // // 请求间隔 (毫秒) - // 'delay' => 1000, - // // 如果设置,每次重试的等待时间都会增加这个系数 - // // (例如. 首次:1000ms; 第二次: 3 * 1000ms; etc.) - // 'multiplier' => 3 - // ], ] );