hospital-applets-api/app/Services/PatientOrderService.php
2023-05-08 10:20:57 +08:00

1470 lines
53 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

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

<?php
namespace App\Services;
use App\Amqp\Producer\AssignDoctorDelayDirectProducer;
use App\Amqp\Producer\AssignDoctorProducer;
use App\Amqp\Producer\CancelUnpayOrdersDelayDirectProducer;
use App\Constants\DoctorTitleCode;
use App\Constants\HttpEnumCode;
use App\Model\Hospital;
use App\Model\OrderInquiry;
use App\Model\OrderInquiryCase;
use App\Model\OrderInquiryCoupon;
use App\Model\OrderPrescription;
use App\Model\OrderPrescriptionFile;
use App\Model\OrderPrescriptionProduct;
use App\Model\OrderProduct;
use App\Model\OrderProductItem;
use App\Model\OrderProductLogistic;
use App\Model\PatientFollow;
use App\Model\Product;
use App\Model\ProductPlatformAmount;
use App\Model\UserDoctor;
use App\Model\UserDoctorInfo;
use App\Model\UserPharmacistInfo;
use App\Model\UserShipAddress;
use App\Utils\Log;
use Extend\Prescription\Prescription;
use Extend\Wechat\WechatPay;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Amqp\Producer;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
/**
* 患者订单
*/
class PatientOrderService extends BaseService
{
/**
* 获取患者问诊订单列表
* @return array
*/
public function getPatientInquiryOrderList(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$inquiry_status = $this->request->input('inquiry_status', 0);
$family_id = $this->request->input('family_id');
$page = $this->request->input('page', 1);
$per_page = $this->request->input('per_page', 10);
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
if (!empty($family_id)) {
$params['family_id'] = $family_id;
}
$inquiry_status_params = [];
if (!empty($inquiry_status) && $inquiry_status != 0) {
// 问诊订单状态0:全部 1:待支付 2:待接诊 3:问诊中 4:完成/取消
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
if ($inquiry_status == 1) {
$inquiry_status_params = [1];
}
if ($inquiry_status == 2) {
$inquiry_status_params = [2, 3];
}
if ($inquiry_status == 3) {
$inquiry_status_params = [4];
}
if ($inquiry_status == 4) {
$inquiry_status_params = [5, 6, 7];
}
}
$params['is_delete'] = 0;
$fields = [
'order_inquiry_id',
'patient_id',
'doctor_id',
'family_id',
'inquiry_type',
'inquiry_mode',
'inquiry_status',
'is_delete',
'inquiry_refund_status',
'inquiry_pay_channel',
'inquiry_pay_status',
'inquiry_no',
'escrow_trade_no',
'amount_total',
'payment_amount_total',
'patient_name',
'patient_name_mask',
'patient_sex',
'patient_age',
'created_at',
];
$order_inquiry = OrderInquiry::getPatientOrderInquiryPage($params, $inquiry_status_params, $fields, $page, $per_page);
if (empty($order_inquiry['data'])) {
return success($order_inquiry);
}
foreach ($order_inquiry['data'] as &$item) {
$item['disease_desc'] = $item['OrderInquiryCase']['disease_desc'];
unset($item['OrderInquiryCase']);
// 获取医生数据
$item['user_doctor'] = [];
if (!empty($item['doctor_id'])) {
$fields = [
'doctor_id',
'user_name',
'doctor_title',
'hospital_id',
"avatar"
];
$params = array();
$params['doctor_id'] = $item['doctor_id'];
$user_doctor = UserDoctor::getOne($params, $fields);
if (empty($user_doctor)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 转换医生职称
$user_doctor['doctor_title'] = empty($user_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($user_doctor['doctor_title']);
// 获取医生医院名称
$user_doctor['hospital_name'] = "";
$user_doctor['hospital_level_name'] = "";
// 医生头像
$user_doctor['avatar'] = addAliyunOssWebsite($user_doctor['avatar']);
$fields = [
'hospital_id',
'hospital_name',
'hospital_level_name',
];
$params = array();
$params['hospital_id'] = $user_doctor['hospital_id'];
$hospital = Hospital::getOne($params, $fields);
if (!empty($hospital)) {
$user_doctor['hospital_name'] = $hospital['hospital_name'];
$user_doctor['hospital_level_name'] = $hospital['hospital_level_name'];
}
$item['user_doctor'] = $user_doctor;
unset($hospital);
unset($user_doctor);
}
}
return success($order_inquiry);
}
/**
* 获取患者问诊订单详情
* @return array
*/
public function getPatientInquiryOrderInfo(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_inquiry_id = $this->request->route('order_inquiry_id');
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_inquiry_id'] = $order_inquiry_id;
$params['is_delete'] = 0;
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
return fail();
}
// 获取病例信息
$fields = [
'disease_class_name',
'disease_desc',
];
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$order_inquiry_case = OrderInquiryCase::getOne($params, $fields);
if (empty($order_inquiry_case)) {
return fail();
}
$order_inquiry['case'] = $order_inquiry_case->toArray();
// 获取医生数据
$order_inquiry['user_doctor'] = [];
if (!empty($order_inquiry['doctor_id'])) {
$fields = [
'user_id',
'doctor_id',
'user_name',
'doctor_title',
'hospital_id',
'avatar',
'department_custom_name',
'multi_point_status',
];
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params, $fields);
if (empty($user_doctor)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 转换医生职称
$user_doctor['doctor_title'] = empty($user_doctor['doctor_title']) ? "" : DoctorTitleCode::getMessage($user_doctor['doctor_title']);
// 头像
$user_doctor['avatar'] = addAliyunOssWebsite($user_doctor['avatar']);
// 获取医生医院名称
$user_doctor['hospital_name'] = "";
$user_doctor['hospital_level_name'] = "";
$fields = [
'hospital_id',
'hospital_name',
'hospital_level_name',
];
$params = array();
$params['hospital_id'] = $user_doctor['hospital_id'];
$hospital = Hospital::getOne($params, $fields);
if (!empty($hospital)) {
$user_doctor['hospital_name'] = $hospital['hospital_name'];
$user_doctor['hospital_level_name'] = $hospital['hospital_level_name'];
}
// 获取医生关注状态
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['doctor_id'] = $user_doctor['doctor_id'];
$user_doctor['follow'] = PatientFollow::getExists($params);
$order_inquiry['user_doctor'] = $user_doctor;
unset($hospital);
unset($user_doctor);
}
return success($order_inquiry->toArray());
}
/**
* 取消患者问诊订单
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function putCancelPatientInquiryOrder(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_inquiry_id = $this->request->route('order_inquiry_id');
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_inquiry_id'] = $order_inquiry_id;
$params['is_delete'] = 0;
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
return fail();
}
$redis = $this->container->get(Redis::class);
$redis_key = "order_inquiry_lock_" . $order_inquiry_id;
$redis_lock = $redis->setnx($redis_key,1);
// 设置过期时间
$redis->expire($redis_key,3);
if (!$redis_lock){
// 设置失败,表示已经设置该值
return fail(HttpEnumCode::HTTP_SUCCESS,"请您稍后重试");
}
// 检测订单状态
if (!in_array($order_inquiry['inquiry_status'], [1, 2, 3])) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
return fail(HttpEnumCode::HTTP_ERROR, "订单无法取消");
}
if ($order_inquiry['inquiry_refund_status'] == 1) {
// 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
return fail(HttpEnumCode::HTTP_ERROR, "订单申请退款中,请您稍后取消");
}
if ($order_inquiry['inquiry_refund_status'] == 2) {
// 问诊订单退款状态0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭)
return fail(HttpEnumCode::HTTP_ERROR, "订单正在退款中,请您稍后取消");
}
// 支付状态1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
Db::beginTransaction();
try {
// 退款成功
// 修改问诊订单为取消
$data = array();
$data['inquiry_status'] = 7;
$data['cancel_time'] = date("Y-m-d H:i:s", time());
$data['cancel_reason'] = 2; // 取消订单原因1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时)
$data['updated_at'] = date("Y-m-d H:i:s", time());
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params, $data);
// 检测支付状态,判断是否需要退款处理
if ($order_inquiry['inquiry_pay_status'] == 2 && $order_inquiry['inquiry_refund_status'] != 3) {
// 需退款
$inquiryService = new InquiryService();
$inquiryService->inquiryRefund($order_inquiry['order_inquiry_id'], "取消问诊");
}
// 删除锁
$redis->del($redis_key);
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
try {
if (!empty($order_inquiry['doctor_id'])){
// 获取医生数据
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params);
if (empty($user_doctor)){
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR,"取消失败");
}
// 推送医生-患者取消问诊
$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();
}
return success();
}
/**
* 删除问诊订单
* 支付超时
* 取消问诊
* 问诊结束
* @return array
*/
public function deletePatientInquiryOrder(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_inquiry_id = $this->request->route('order_inquiry_id');
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_inquiry_id'] = $order_inquiry_id;
$params['is_delete'] = 0;
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
return fail();
}
// 检测订单状态
if (!in_array($order_inquiry['inquiry_status'], [6, 7])) {
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
return fail(HttpEnumCode::HTTP_ERROR, "订单无法删除");
}
// 修改订单删除状态
$data = array();
$data['is_delete'] = 1;
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params, $data);
return success();
}
/**
* 问诊订单取消支付
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function putPatientInquiryOrderCancelPay(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_inquiry_id = $this->request->route('order_inquiry_id');
Db::beginTransaction();
try {
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_inquiry_id'] = $order_inquiry_id;
$params['is_delete'] = 0;
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
return fail();
}
$InquiryService = new InquiryService();
$result = $InquiryService->cancelUnpayInquiryOrder($order_inquiry['inquiry_no'], 2, "主动取消");
if ($result['status'] != 1){
Db::rollBack();
return fail();
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
return success();
}
/**
* 获取药品订单列表
* @return array
*/
public function getPatientProductOrderList(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_product_status = $this->request->input('order_product_status', 0);
$family_id = $this->request->input('family_id');
$page = $this->request->input('page', 1);
$per_page = $this->request->input('per_page', 10);
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
if (!empty($family_id)) {
$params['family_id'] = $family_id;
}
if (!empty($order_product_status) && $order_product_status != 0) {
// 入参订单状态1:待支付 2:待发货 3:已发货 4:已签收 5:已取消)
// 数据库订单状态1:待支付 2:待发货 3:已发货 4:已签收 5:已取消)
$params['order_product_status'] = $order_product_status;
}
$params['is_delete'] = 0;
$fields = [
'order_product_id',
'order_inquiry_id',
'order_prescription_id',
'doctor_id',
'patient_id',
'family_id',
'order_product_status',
'pay_status',
'cancel_reason',
'logistics_no',
'remarks',
'refund_status',
'cancel_remarks',
'created_at',
];
$order_product = OrderProduct::getPatientOrderProductPage($params, $fields, $page, $per_page);
if (!empty($order_product['data'])){
foreach ($order_product['data'] as $item) {
foreach ($item['orderProductItem'] as &$product_item) {
$product_item['product_cover_img'] = addAliyunOssWebsite($product_item['product_cover_img']);
}
}
}
return success($order_product);
}
/**
* 获取药品订单详情
* @return array
*/
public function getPatientProductOrderInfo(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_product_id = $this->request->route('order_product_id');
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_product_id'] = $order_product_id;
$params['is_delete'] = 0;
$order_product = OrderProduct::getOne($params);
if (empty($order_product)) {
return fail();
}
$params = array();
$params['order_product_id'] = $order_product['order_product_id'];
$order_product_item = OrderProductItem::getList($params);
if (empty($order_product_item)) {
return fail();
}
// 处理商品图片
foreach ($order_product_item as &$item) {
$item['product_cover_img'] = addAliyunOssWebsite($item['product_cover_img']);
}
if (!empty($order_product['doctor_id'])) {
// 获取问诊医生数据
$fields = [
'doctor_id',
'user_name',
'multi_point_status',
'avatar',
'doctor_title',
'department_custom_name',
'be_good_at',
'hospital_id',
];
$params = array();
$params['doctor_id'] = $order_product['doctor_id'];
$user_doctor = UserDoctor::getWithHospitalOne($params, $fields);
if (empty($user_doctor)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
$user_doctor['avatar'] = addAliyunOssWebsite($user_doctor['avatar']);
}
$result = array();
$result['user_doctor'] = $user_doctor ?? [];
$result['order_product'] = $order_product;
$result['order_product_item'] = $order_product_item;
return success($result);
}
/**
* 药品订单取消支付
* @return array
*/
public function putPatientProductOrderCancelPay(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_product_id = $this->request->route('order_product_id');
Db::beginTransaction();
try {
// 获取药品订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_product_id'] = $order_product_id;
$params['is_delete'] = 0;
$order_product = OrderProduct::getOne($params);
if (empty($order_product)) {
Db::rollBack();
return fail();
}
$OrderProductService = new OrderProductService();
$result = $OrderProductService->cancelUnpayProductOrder($order_product['order_product_no'],1,"主动取消");
if ($result['status'] != 1){
Db::rollBack();
return fail();
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, $e->getMessage());
}
return success();
}
/**
* 删除药品订单
* 已收货
* 取消订单
* @return array
*/
public function deletePatientProductOrder(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_product_id = $this->request->route('order_product_id');
// 获取订单数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['order_product_id'] = $order_product_id;
$params['is_delete'] = 0;
$order_product = OrderProduct::getOne($params);
if (empty($order_product)) {
return fail();
}
if (!in_array($order_product['order_product_status'], [4, 5])) {
Db::rollBack();
// 订单状态1:待支付 2:待发货 3:已发货 4:已签收 5:已取消)
return fail(HttpEnumCode::HTTP_ERROR, "订单无法删除");
}
// 修改订单状态
$data = array();
$data['is_delete'] = 1;
$data['updated_at'] = date("Y-m-d H:i:s", time());
$params = array();
$params['order_product_id'] = $order_product_id;
OrderProduct::edit($params, $data);
return success();
}
/**
* 获取患者订单支付数据
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getPatientOrderPayInfo(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_type = $this->request->input('order_type');
$order_no = $this->request->input('order_no');
// 获取订单金额
$result = array();
$result['amount_total'] = 0; // 订单金额
$result['payment_amount_total'] = 0; // 实际订单金额
$result['coupon_amount_total'] = 0; // 优惠金额
$result['order_no'] = $order_no; // 订单编号
$result['order_id'] = ""; // 订单主键id问诊订单order_inquiry_id 药品订单order_product_id
$result['created_at'] = ""; // 创建时间
$result['inquiry_type'] = 0; // 订单类型1:专家问诊 2:快速问诊 3:公益问诊 4:问诊购药)
$result['pay_config'] = []; // 小程序支付配置
if ($order_type == 1) {
// 问诊订单
$params = array();
$params['inquiry_no'] = $order_no;
$params['patient_id'] = $user_info['client_user_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
return fail(HttpEnumCode::HTTP_ERROR, "非法订单");
}
// 验证订单状态
if ($order_inquiry['inquiry_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "订单状态错误");
}
// 验证订单支付状态
if ($order_inquiry['inquiry_pay_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "订单支付状态错误");
}
// 验证订单过期支付时间
$diff_time = (strtotime($order_inquiry['created_at']) - time()) / 60;
if ($diff_time >= 30){
return fail(HttpEnumCode::HTTP_ERROR, "订单已过期");
}
$result['order_id'] = $order_inquiry['order_inquiry_id'];
$result['created_at'] = $order_inquiry['created_at'];
$result['inquiry_type'] = $order_inquiry['inquiry_type'];
// 获取订单金额
$result['amount_total'] = $order_inquiry['amount_total']; // 订单金额
$result['payment_amount_total'] = $order_inquiry['payment_amount_total']; // 实际订单金额
$result['coupon_amount_total'] = $order_inquiry['coupon_amount_total'];; // 优惠金额
if ($order_inquiry['payment_amount_total'] > 0){
// 发起支付
$WechatPay = new WechatPay(1,1);
// 获取预支付交易会话标识
$prepay = $WechatPay->getJsapiPrepayId($order_no, $order_inquiry['payment_amount_total'] * 100, $user_info['open_id']);
if (empty($prepay)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 获取小程序支付配置
$pay_config = $WechatPay->getAppletsPayConfig($prepay['prepay_id']);
}
} elseif ($order_type == 2) {
// 药品订单
$params = array();
$params['order_product_no'] = $order_no;
$params['patient_id'] = $user_info['client_user_id'];
$order_product = OrderProduct::getOne($params);
if (empty($order_product)) {
return fail(HttpEnumCode::HTTP_ERROR, "非法订单");
}
// 验证订单状态
if ($order_product['order_product_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "订单状态错误");
}
// 验证订单支付状态
if ($order_product['pay_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "订单支付状态错误");
}
// 验证订单过期支付时间
$diff_time = (strtotime($order_product['created_at']) - time()) / 60;
if ($diff_time >= 30){
return fail(HttpEnumCode::HTTP_ERROR, "订单已过期");
}
$result['order_id'] = $order_product['order_product_id'];
$result['created_at'] = $order_product['created_at'];
// 获取订单金额
$result['amount_total'] = $order_product['amount_total']; // 订单金额
$result['payment_amount_total'] = $order_product['payment_amount_total']; // 实际订单金额
$result['coupon_amount_total'] = 0; // 优惠金额
if ($order_product['payment_amount_total'] > 0 ){
// 发起支付
$WechatPay = new WechatPay(1,2);
// 获取预支付交易会话标识
$prepay = $WechatPay->getJsapiPrepayId($order_no, $order_product['payment_amount_total'] * 100, $user_info['open_id']);
if (empty($prepay)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
// 获取小程序支付配置
$pay_config = $WechatPay->getAppletsPayConfig($prepay['prepay_id']);
}
} else {
return fail();
}
$result['pay_config'] = $pay_config ?? [];
return success($result);
}
/**
*模拟支付成功-金额为0时使用
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws GuzzleException
*/
public function addPatientOrderPay(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_no = $this->request->input('order_no');
Db::beginTransaction();
try {
// 问诊订单
$params = array();
$params['inquiry_no'] = $order_no;
$params['patient_id'] = $user_info['client_user_id'];
$order_inquiry = OrderInquiry::getOne($params);
if (empty($order_inquiry)) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "非法订单");
}
// 验证订单状态
if ($order_inquiry['inquiry_status'] != 1){
Db::rollBack();
// 问诊订单状态1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消)
return fail(HttpEnumCode::HTTP_ERROR, "支付失败");
}
// 验证支付金额
if ($order_inquiry['payment_amount_total'] != 0){
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "支付失败");
}
$generator = $this->container->get(IdGeneratorInterface::class);
// 修改支付状态
$data = array();
$data['inquiry_pay_channel'] = 3; // 支付渠道1:小程序支付 2:微信扫码支付 3:模拟支付)
$data['inquiry_pay_status'] = 2;
if ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3){
// 专家-公益
$data['inquiry_status'] = 3;// 3:待接诊
}elseif ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4){
// 快速-购药
$data['inquiry_status'] = 2;// 2:待分配
}
$data['escrow_trade_no'] = "GD" . $generator->generate(); // 第三方支付流水号
$data['pay_time'] = date('Y-m-d H:i:s',time());// 支付时间
$data['updated_at'] = date('Y-m-d H:i:s',time());
$params = array();
$params['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
OrderInquiry::edit($params,$data);
if ($order_inquiry['inquiry_type'] == 2 || $order_inquiry['inquiry_type'] == 4){
// 快速-购药
// 加入分配医生队列
$data = array();
$data['order_inquiry_id'] = $order_inquiry['order_inquiry_id'];
$message = new AssignDoctorDelayDirectProducer($data);
$message->setDelayMs(1000 * 5);
$producer = $this->container->get(Producer::class);
$res = $producer->produce($message);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "分配医生失败");
}
}elseif ($order_inquiry['inquiry_type'] == 1 || $order_inquiry['inquiry_type'] == 3){
// 专家-公益发送im消息
// 获取订单医生数据
$params = array();
$params['doctor_id'] = $order_inquiry['doctor_id'];
$user_doctor = UserDoctor::getOne($params);
if (empty($user_doctor)){
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "医生数据错误");
}
// 发送IM消息-等待医生接诊
$imService = new ImService();
$imService->waitDoctorInquiry($order_inquiry,$user_doctor['user_id'],$order_inquiry['user_id']);
// 发送站内、订阅失败发送短信消息-医生有新问诊
$MessagePush = new MessagePush($user_doctor['user_id'],$order_inquiry['order_inquiry_id']);
$MessagePush->doctorHaveNewInquiry();
Log::getInstance()->info("发送im消息成功");
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR,$e->getMessage());
}
return success();
}
/**
* 创建药品订单
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function addPatientProductOrder(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_prescription_id = $this->request->input('order_prescription_id');
$address_id = $this->request->input('address_id');
$product_ids = $this->request->input('product_ids');
$client_type = $this->request->input('client_type');
// 获取处方数据
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$params['patient_id'] = $user_info['client_user_id'];
$params['is_delete'] = 0;
$order_prescription = OrderPrescription::getOne($params);
if (empty($order_prescription)) {
return fail();
}
// 验证处方状态
if ($order_prescription['prescription_status'] == 1) {
return fail(HttpEnumCode::HTTP_ERROR, "处方未审核");
}
if ($order_prescription['prescription_status'] == 4) {
return fail(HttpEnumCode::HTTP_ERROR, "处方已失效");
}
if ($order_prescription['prescription_status'] == 5) {
return fail(HttpEnumCode::HTTP_ERROR, "处方已使用");
}
if ($order_prescription['pharmacist_audit_status'] != 1) {
return fail(HttpEnumCode::HTTP_ERROR, "处方未审核");
}
// 检测收货地址
$params = array();
$params['user_id'] = $user_info['user_id'];
$params['address_id'] = $address_id;
$user_ship_address = UserShipAddress::getOne($params);
if (empty($user_ship_address)) {
return fail(HttpEnumCode::HTTP_ERROR, "收货地址错误");
}
$not_enough_product_ids = [];
$amount_total = 0;
foreach ($product_ids as $value) {
// 检测药品是否存在于处方中
$params = array();
$params['order_prescription_id'] = $order_prescription['order_prescription_id'];
$params['product_id'] = $value;
$order_prescription_product = OrderPrescriptionProduct::getOne($params);
if (empty($order_prescription_product)) {
return fail(HttpEnumCode::HTTP_ERROR, "创建订单失败");
}
$params = array();
$params['product_id'] = $value;
$product = Product::getWithAmountOne($params);
if (empty($product)) {
return fail(HttpEnumCode::HTTP_ERROR, "处方存在未知药品");
}
// 检测商品库存
if (!empty($product['ProductPlatformAmount'])) {
if ($order_prescription_product['prescription_product_num'] > $product['ProductPlatformAmount']['stock']) {
// 库存不足
$not_enough_product_ids[] = $value;
continue;
}
}
// 获取订单金额
$amount_total += $product['product_price'] * $order_prescription_product['prescription_product_num'];
}
if (!empty($not_enough_product_ids)) {
return fail(HttpEnumCode::HTTP_ERROR, "存在库存不足商品", $not_enough_product_ids);
}
// 获取运费金额
$Prescription = new Prescription();
$result = $Prescription->getLogisticsFee();
if ($amount_total >= $result['drugCost']){
$logistics_fee = 0;
}else{
$logistics_fee = $result['freight'];
}
// 实际支付金额
$payment_amount_total = $amount_total + $logistics_fee;
if (env("APP_ENV") == "dev"){
$payment_amount_total = 0.01;
}
// 确定支付渠道
// 支付渠道1:小程序支付 2:微信扫码支付)
if ($client_type == 1) {
$pay_channel = 1;
} elseif ($client_type == 2) {
$pay_channel = 2;
}
Db::beginTransaction();
$generator = $this->container->get(IdGeneratorInterface::class);
try {
// 新增药品订单
$data = array();
$data['order_inquiry_id'] = $order_prescription['order_inquiry_id'];
$data['order_prescription_id'] = $order_prescription['order_prescription_id'];
$data['doctor_id'] = $order_prescription['doctor_id'];
$data['patient_id'] = $order_prescription['patient_id'];
$data['family_id'] = $order_prescription['family_id'];
$data['order_product_no'] = $generator->generate();
$data['order_product_status'] = 1; // 订单状态1:待支付 2:待发货 3:已发货 4:已签收 5:已取消)
$data['pay_channel'] = $pay_channel; // 支付渠道1:小程序支付 2:微信扫码支付)
$data['amount_total'] = $amount_total; // 订单金额
$data['payment_amount_total'] = $payment_amount_total; // 实际付款金额
$data['logistics_fee'] = $logistics_fee; // 运费金额
$data['province_id'] = $user_ship_address['province_id'];
$data['province'] = $user_ship_address['province'];
$data['city_id'] = $user_ship_address['city_id'];
$data['city'] = $user_ship_address['city'];
$data['county_id'] = $user_ship_address['county_id'];
$data['county'] = $user_ship_address['county'];
$data['address'] = $user_ship_address['address'];
$data['address_mask'] = $user_ship_address['address_mask'];
$data['consignee_name'] = $user_ship_address['consignee_name'];
$data['consignee_name_mask'] = $user_ship_address['consignee_name_mask'];
$data['consignee_tel'] = $user_ship_address['consignee_tel'];
$data['consignee_tel_mask'] = $user_ship_address['consignee_tel_mask'];
$order_product = OrderProduct::addOrderProduct($data);
if (empty($order_product)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 新增药品订单详情
foreach ($product_ids as $product_id) {
$params = array();
$params['order_prescription_id'] = $order_prescription['order_prescription_id'];
$params['product_id'] = $product_id;
$order_prescription_product = OrderPrescriptionProduct::getOne($params);
if (empty($order_prescription_product)) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "创建订单失败");
}
$params = array();
$params['product_id'] = $product_id;
$product = Product::getOne($params);
if (empty($product)) {
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "处方存在未知药品");
}
$params = array();
$params['product_platform_code'] = $product['product_platform_code'];
$product_platform_amount = ProductPlatformAmount::getSharedLockOne($params);
if (empty($product_platform_amount)){
Db::rollBack();
return fail(HttpEnumCode::HTTP_ERROR, "无商品库存数据");
}
$data = array();
$data['order_product_id'] = $order_product['order_product_id'];
$data['order_inquiry_id'] = $order_prescription['order_inquiry_id'];
$data['order_prescription_id'] = $order_prescription['order_prescription_id'];
$data['product_id'] = $product_id;
$data['product_name'] = $order_prescription_product['product_name'];
$data['product_price'] = $product['product_price'] * $order_prescription_product['prescription_product_num'];
$data['product_platform_code'] = $product['product_platform_code'];
$data['amount'] = $order_prescription_product['prescription_product_num'];
$data['manufacturer'] = $order_prescription_product['manufacturer'];
$data['product_cover_img'] = $product['product_cover_img'];
$data['product_spec'] = $order_prescription_product['product_spec'];
$order_product_item = OrderProductItem::addOrderProductItem($data);
if (empty($order_product_item)) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR);
}
// 处方药品表标记为已使用
$data = array();
$data['use_status'] = 1;
$params = array();
$params['prescription_product_id'] = $order_prescription_product['prescription_product_id'];
OrderPrescriptionProduct::edit($params, $data);
// 锁定库存
// 库存-1
$params = array();
$params['amount_id'] = $product_platform_amount['amount_id'];
ProductPlatformAmount::dec($params, 'stock', $order_prescription_product['prescription_product_num']);
}
// 修改处方为已使用
$data = array();
$data['prescription_status'] = 4;
$params = array();
$params['order_prescription_id'] = $order_prescription['order_prescription_id'];
OrderPrescription::edit($params, $data);
// 增加至取消订单延迟队列
$data = array();
$data['order_no'] = (string)$order_product['order_product_no'];
$data['order_type'] = 2;
$message = new CancelUnpayOrdersDelayDirectProducer($data);
$message->setDelayMs(1000 * 60 * 5);
$producer = $this->container->get(Producer::class);
$res = $producer->produce($message);
if (!$res) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, "订单创建失败");
}
Db::commit();
} catch (\Exception $e) {
Db::rollBack();
return fail(HttpEnumCode::SERVER_ERROR, $e->getMessage());
}
$result = array();
$result['inquiry_no'] = (string)$order_product['order_product_no']; // 订单编号
$result['order_product_id'] = (string)$order_product['order_product_id']; // 订单主键id
return success($result);
}
/**
* 获取药品订单物流数据
* @return array
*/
public function getPatientProductOrderLogistics(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_product_id = $this->request->route('order_product_id');
// 获取药品订单数据
$params = array();
$params['order_product_id'] = $order_product_id;
$params['patient_id'] = $user_info['client_user_id'];
$order_product = OrderProduct::getOne($params);
if (empty($order_product)){
return fail();
}
// 地址数据
$address = array();
$address['province_id'] = $order_product['province_id'];
$address['province'] = $order_product['province'];
$address['city_id'] = $order_product['city_id'];
$address['city'] = $order_product['city'];
$address['county_id'] = $order_product['county_id'];
$address['county'] = $order_product['county'];
$address['address'] = $order_product['address'];
$address['address_mask'] = $order_product['address_mask'];
$address['consignee_name'] = $order_product['consignee_name'];
$address['consignee_name_mask'] = $order_product['consignee_name_mask'];
$address['consignee_tel'] = $order_product['consignee_tel'];
$address['consignee_tel_mask'] = $order_product['consignee_tel_mask'];
$result = array();
$result['logistics'] = null;
$result['address'] = $address;
// 获取物流数据
$params = array();
$params['order_product_id'] = $order_product_id;
$order_product_logistics = OrderProductLogistic::getOne($params);
if (empty($order_product_logistics)){
$logistics = array();
$logistics['logistics_no'] = $order_product['logistics_no'] ?: "";
// 获取快递公司名称
return success($result);
}
$order_product_logistics = $order_product_logistics->toArray();
$order_product_logistics['logistics_content'] = json_decode($order_product_logistics['logistics_content'],true);
$result['logistics'] = $order_product_logistics;
return success($result);
}
/**
* 获取处方订单列表
* @return array
*/
public function getPatientPrescriptionOrderList(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$page = $this->request->input('page', 1);
$per_page = $this->request->input('per_page', 10);
// 获取处方数据
$params = array();
$params['patient_id'] = $user_info['client_user_id'];
$params['pharmacist_audit_status'] = 1;
$params['platform_audit_status'] = 1;
$params['is_delete'] = 0;
$order_prescription = OrderPrescription::getWithPage($params, ['*'], $page, $per_page);
if (!empty($order_prescription['data'])) {
foreach ($order_prescription['data'] as &$item) {
if (!empty($item['UserDoctor'])) {
$item['UserDoctor']['doctor_title'] = DoctorTitleCode::getMessage($item['UserDoctor']['doctor_title']);
}
}
}
return success($order_prescription);
}
/**
* 获取处方订单详情
* @return array
*/
public function getPatientPrescriptionOrderInfo(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_prescription_id = $this->request->route('order_prescription_id');
// 获取处方数据
$fields = [
'order_prescription_id',
'prescription_status',
'pharmacist_id',
'doctor_id',
];
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$params['patient_id'] = $user_info['client_user_id'];
$params['pharmacist_audit_status'] = 1;
$params['platform_audit_status'] = 1;
$params['is_delete'] = 0;
$order_prescription = OrderPrescription::getOne($params, $fields);
if (empty($order_prescription)) {
return fail();
}
// 获取处方文件数据
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$order_prescription_file = OrderPrescriptionFile::getOne($params);
if (empty($order_prescription_file)){
return fail();
}
$order_prescription['prescription_img_oss_path'] = addAliyunOssWebsite($order_prescription_file['prescription_img_oss_path']);
// 获取处方中医生签名
$params = array();
$params['doctor_id'] = $order_prescription['doctor_id'];
$user_doctor_info = UserDoctorInfo::getOne($params);
if (empty($user_doctor_info)){
return fail(HttpEnumCode::SERVER_ERROR);
}
$order_prescription['doctor_sign_image'] = addAliyunOssWebsite($user_doctor_info['sign_image']);
// 获取处方中药师签名
$params = array();
$params['pharmacist_id'] = $order_prescription['pharmacist_id'];
$user_pharmacist_info = UserPharmacistInfo::getOne($params);
if (empty($user_pharmacist_info)){
return fail(HttpEnumCode::SERVER_ERROR);
}
$order_prescription['pharmacist_sign_image'] = addAliyunOssWebsite($user_pharmacist_info['sign_image']);
// 获取处方医院签名
$order_prescription['hospital_sign_image'] = "https://img.applets.igandanyiyuan.com/basic/file/hospital_signature.png";
return success($order_prescription->toArray());
}
/**
* 获取处方订单支付页详情
* @return array
*/
public function getPatientPrescriptionOrderPayInfo(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_prescription_id = $this->request->route('order_prescription_id');
$fields = [
"order_prescription_id"
];
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$params['patient_id'] = $user_info['client_user_id'];
$params['is_delete'] = 0;
$order_prescription = OrderPrescription::getOne($params, $fields);
if (empty($order_prescription)) {
return fail();
}
// 验证处方状态
if ($order_prescription['prescription_status'] == 1) {
return fail(HttpEnumCode::HTTP_ERROR, "处方未审核");
}
if ($order_prescription['prescription_status'] == 3) {
return fail(HttpEnumCode::HTTP_ERROR, "处方已失效");
}
if ($order_prescription['prescription_status'] == 4) {
return fail(HttpEnumCode::HTTP_ERROR, "处方已使用");
}
// 获取处方药品信息
$params = array();
$params['order_prescription_id'] = $order_prescription['order_prescription_id'];
$order_prescription_product = OrderPrescriptionProduct::getList($params);
if (empty($order_prescription_product)) {
return fail(HttpEnumCode::SERVER_ERROR);
}
$amount_total = 0;
$coupon_amount_total = 0;
foreach ($order_prescription_product as &$item) {
$params = array();
$params['product_id'] = $item['product_id'];
$product = Product::getWithAmountOne($params);
if (empty($product)) {
return fail(HttpEnumCode::HTTP_ERROR, "处方存在未知药品");
}
$item['status'] = 1; // 正常
// 检测商品库存
if (!empty($product['ProductPlatformAmount'])) {
if ($item['prescription_product_num'] > $product['ProductPlatformAmount']['stock']) {
// 库存不足
$item['status'] = 2;
continue;
}
}
$amount_total += $product['product_price'] * $item['prescription_product_num'];
}
// 获取运费金额
$logistics_fee = 0;
if (env("APP_ENV") == "prod"){
$Prescription = new Prescription();
$result = $Prescription->getLogisticsFee();
if ($amount_total < $result['drugCost']){
$logistics_fee = $result['freight'];
}
}
// 实际支付金额
if (env("APP_ENV") == "dev"){
$payment_amount_total = 0.01;
}else{
$payment_amount_total = $amount_total + $logistics_fee;
}
// 获取收货地址
$params = array();
$params['user_id'] = $user_info['user_id'];
$user_ship_addresss = UserShipAddress::getList($params);
unset($item);
foreach ($user_ship_addresss as $item) {
if ($item['is_default'] == 1) {
$user_ship_address = $item;
}
}
// 无默认地址,选择第一个
if (empty($user_ship_address)) {
$user_ship_address = $user_ship_addresss[0] ?? NULL;
}
$result = array();
$result['amount_total'] = $amount_total;
$result['coupon_amount_total'] = $coupon_amount_total;
$result['payment_amount_total'] = $payment_amount_total;
$result['logistics_fee'] = $logistics_fee;
$result['user_ship_address'] = $user_ship_address;
$result['order_prescription_product'] = $order_prescription_product;
return success($result);
}
/**
* 删除处方订单记录
* @return array
*/
public function deletePatientPrescriptionOrder(): array
{
$user_info = $this->request->getAttribute("userInfo") ?? [];
$order_prescription_id = $this->request->route('order_prescription_id');
$params = array();
$params['order_prescription_id'] = $order_prescription_id;
$params['patient_id'] = $user_info['client_user_id'];
$order_prescription = OrderPrescription::getOne($params);
if (empty($order_prescription)) {
return fail();
}
// 验证处方状态
if ($order_prescription['prescription_status'] == 1) {
return fail(HttpEnumCode::HTTP_ERROR, "处方无法删除");
}
if ($order_prescription['is_delete'] == 1) {
return success();
}
$data = array();
$data['is_delete'] = 1;
$params = array();
$params['order_prescription_id'] = $order_prescription['order_prescription_id'];
OrderPrescription::edit($params, $data);
return success();
}
/**
* 获取患者未完成订单
* @param string $patient_id
* @param string|int $inquiry_type
* @param string $family_id
* @return string
*/
public function getNotFinishedOrderInquiry(string|int $inquiry_type, string $patient_id = '', string $family_id = ''): string
{
$params = array();
if (!empty($patient_id)){
$params[] = ['patient_id','=',$patient_id];
}
if (!empty($family_id)){
$params[] = ['family_id','=',$family_id];
}
$params[] = ['inquiry_type','=',$inquiry_type];
$params[] = ['inquiry_mode','=',1];
$params[] = ['inquiry_refund_status','=',0];
$order_inquiry = OrderInquiry::getOrderOne($params);
if (!empty($order_inquiry)) {
// 1:待支付 2:待分配 3:待接诊 4:已接诊
if (in_array($order_inquiry['inquiry_status'], [1,2, 3, 4])) {
return $order_inquiry['order_inquiry_id'];
}
}
return "";
}
}