Files
hospital-admin-api/api/service/orderProduct.go
T
2026-01-04 15:52:07 +08:00

395 lines
13 KiB
Go

package service
import (
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/dto"
"hospital-admin-api/api/model"
"hospital-admin-api/api/requests"
"hospital-admin-api/config"
"hospital-admin-api/extend/weChat"
"hospital-admin-api/global"
"strconv"
"time"
)
type OrderProductService struct {
}
// GetOrderProduct 药品订单详情
func (r *OrderProductService) GetOrderProduct(orderProductId int64) (g *dto.OrderProductDto, err error) {
// 获取药品订单数据
orderProductDao := dao.OrderProductDao{}
orderProduct, err := orderProductDao.GetOrderProductPreloadById(orderProductId)
if err != nil || orderProduct == nil {
return nil, errors.New(err.Error())
}
// 获取退款数据
orderProductRefundDao := dao.OrderProductRefundDao{}
orderProductRefund, err := orderProductRefundDao.GetOrderProductRefundByOrderProductId(orderProductId)
// 获取商品数据
orderProductItemDao := dao.OrderProductItemDao{}
orderProductItems, err := orderProductItemDao.GetOrderProductItemByOrderProductId(orderProductId)
if err != nil || len(orderProductItems) == 0 {
return nil, errors.New("数据错误,无药品数据")
}
// 获取物流数据
orderProductLogisticsDao := dao.OrderProductLogisticsDao{}
orderProductLogistics, err := orderProductLogisticsDao.GetOrderProductLogisticsByOrderProductId(orderProductId)
// 获取处方数据
orderPrescriptionDao := dao.OrderPrescriptionDao{}
orderPrescription, err := orderPrescriptionDao.GetById(orderProduct.OrderPrescriptionId)
// 获取问诊病例
orderInquiryCaseDao := dao.OrderInquiryCaseDao{}
orderInquiryCase, err := orderInquiryCaseDao.GetOrderInquiryCaseByOrderInquiryId(orderProduct.OrderInquiryId)
if orderInquiryCase == nil {
return nil, errors.New("数据错误,无问诊病例")
}
// 医生数据
userDoctorService := UserDoctorService{}
userDoctor, err := userDoctorService.GetUserDoctorById(orderProduct.DoctorId)
if err != nil {
return nil, errors.New(err.Error())
}
// 获取药品订单优惠卷
orderProductCouponDao := dao.OrderProductCouponDao{}
orderProductCoupon, err := orderProductCouponDao.GetOrderProductCouponByOrderProductId(orderProduct.OrderProductId)
// 处理返回值
g = dto.GetOrderProductDto(orderProduct)
// 加载医生数据
g.UserDoctor = userDoctor
// 加载原始医生信息
if orderProduct.OrderInquiry != nil && orderProduct.OrderInquiry.UserDoctor != nil {
g.LoadInquiryDoctor(orderProduct.OrderInquiry.UserDoctor)
}
// 加载接受抄方的医生信息
if orderProduct.OrderInquiry != nil && orderProduct.OrderInquiry.TransferUserDoctor != nil {
g.LoadTransferUserDoctor(orderProduct.OrderInquiry.TransferUserDoctor)
}
// 加载问诊病例
g.LoadOrderInquiryCase(orderInquiryCase)
// 加载问诊类型
if orderProduct.OrderInquiry != nil && orderProduct.OrderInquiry.UserDoctor != nil && orderProduct.OrderInquiry.TransferUserDoctor != nil{
g.LoadIsTransferOrder(orderProduct.OrderInquiry.UserDoctor, orderProduct.OrderInquiry.TransferUserDoctor)
}
// 加载处方数据
g.LoadOrderPrescription(orderPrescription)
// 加载物流数据
g.LoadOrderProductLogistics(orderProductLogistics)
// 加载商品数据
g.LoadOrderProductItem(orderProductItems)
// 加载退款数据
g.LoadOrderProductRefund(orderProductRefund)
// 加载药品订单优惠卷数据
g.LoadOrderProductCoupon(orderProductCoupon)
// 计算优惠金额
g.DiscountAmount = orderProduct.AmountTotal + orderProduct.LogisticsFee - orderProduct.CouponAmountTotal - orderProduct.PaymentAmountTotal
return g, nil
}
// CancelOrderProduct 取消药品订单
func (r *OrderProductService) CancelOrderProduct(req requests.CancelOrderProduct, orderProductId, adminUserId int64) (bool, error) {
// 获取药品订单详情
orderProductDao := dao.OrderProductDao{}
orderProduct, err := orderProductDao.GetOrderProductPreloadById(orderProductId)
if err != nil || orderProduct == nil {
return false, errors.New("订单数据错误")
}
// 检测订单状态
if orderProduct.OrderProductStatus == 1 {
return false, errors.New("订单处于待支付状态,无法取消")
}
if orderProduct.OrderProductStatus == 3 {
return false, errors.New("订单已发货,无法取消")
}
if orderProduct.OrderProductStatus == 4 {
return false, errors.New("订单已签收,无法取消")
}
if orderProduct.OrderProductStatus == 5 {
return false, errors.New("订单已取消,无法取消")
}
// 已上报暂不允许取消订单
if orderProduct.ReportPreStatus == 1 {
return false, errors.New("订单已上报,暂不允许取消")
}
// 检测订单退款状态
if orderProduct.RefundStatus == 1 {
return false, errors.New("订单申请退款中,无法取消")
}
if orderProduct.RefundStatus == 2 {
return false, errors.New("订单正在退款中,无法取消")
}
if orderProduct.RefundStatus == 3 {
return false, errors.New("订单已退款成功,无法取消")
}
if orderProduct.RefundStatus == 6 {
return false, errors.New("订单退款异常,请联系技术人员")
}
// 检测订单支付状态
if orderProduct.PayStatus != 2 {
return false, errors.New("订单未支付,无需取消")
}
// 开始事务
tx := global.Db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 药品订单修改数据
orderProductData := make(map[string]interface{})
// 退款编号
refundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
// 退款状态转换
var refundStatus int
var successTime time.Time
var refundId string
if orderProduct.PaymentAmountTotal > 0 {
// 微信退款
refundRequest := weChat.RefundRequest{
TransactionId: orderProduct.EscrowTradeNo,
OutTradeNo: orderProduct.OrderProductNo,
OutRefundNo: refundNo,
Reason: "客服取消",
RefundAmount: int64(orderProduct.PaymentAmountTotal * 100),
PaymentAmountTotal: int64(orderProduct.PaymentAmountTotal * 100),
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.PatientProductRefundNotifyUrl,
}
refund, err := refundRequest.Refund(2)
if err != nil {
tx.Rollback()
return false, errors.New(err.Error())
}
if refund.Status == nil {
tx.Rollback()
return false, errors.New("退款状态错误")
}
if *refund.Status == "SUCCESS" {
// 退款成功
refundStatus = 3
if refund.SuccessTime != nil {
successTime = *refund.SuccessTime
}
} else if *refund.Status == "CLOSED" {
// 退款关闭
refundStatus = 5
} else if *refund.Status == "PROCESSING" {
// 退款处理中
refundStatus = 2
} else if *refund.Status == "ABNORMAL" {
// 退款异常
tx.Rollback()
return false, errors.New("退款状态错误")
} else {
tx.Rollback()
return false, errors.New("退款状态错误")
}
if refund.RefundId == nil {
tx.Rollback()
return false, errors.New("缺少退款订单编号")
}
// 退款编号
refundId = *refund.RefundId
} else {
// 支付金额为0,模拟退款
refundId = "模拟退款:" + strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
refundStatus = 3
successTime = time.Now()
// 模拟退款时手动退还优惠卷
if orderProduct.CouponAmountTotal > 0 {
orderService := OrderService{}
res, err := orderService.ReturnOrderCoupon(orderProduct.OrderId, tx)
if err != nil || !res {
// 退还优惠卷失败
tx.Rollback()
return false, err
}
}
}
// 修改订单为取消
orderData := make(map[string]interface{})
orderData["cancel_status"] = 1
orderData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
orderData["cancel_remarks"] = req.CancelRemarks
orderDao := dao.OrderDao{}
err = orderDao.EditOrderById(tx, orderProduct.OrderId, orderData)
if err != nil {
tx.Rollback()
return false, errors.New("取消订单失败")
}
// 修改订单退款状态
orderProductData["refund_status"] = refundStatus
orderProductData["order_product_status"] = 5 // 订单状态(1:待支付 2:待发货 3:已发货 4:已签收 5:已取消)
orderProductData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05") // 订单取消时间
orderProductData["cancel_reason"] = 4 // 订单取消原因(1:主动取消 2:复核失败/库存不足 3:支付超时 4:客服取消)
orderProductData["cancel_remarks"] = req.CancelRemarks // 取消订单备注(自动添加)
// orderProductData["report_pre_status"] = 3 // 上报处方平台状态(0:未上报 1:已上报 2:上报失败 3:上报取消)
err = orderProductDao.EditOrderProductById(tx, orderProductId, orderProductData)
if err != nil {
tx.Rollback()
return false, errors.New("取消订单失败")
}
// 新增退款表
orderRefund := &model.OrderRefund{
OrderId: orderProduct.OrderId,
PatientId: orderProduct.PatientId,
OrderNo: orderProduct.OrderProductNo,
RefundNo: refundNo,
RefundId: refundId,
RefundStatus: refundStatus,
RefundTotal: orderProduct.PaymentAmountTotal,
RefundReason: req.CancelRemarks,
}
if refundStatus == 3 && !successTime.IsZero() {
orderRefund.SuccessTime = model.LocalTime(successTime)
}
orderRefundDao := dao.OrderRefundDao{}
orderRefund, err = orderRefundDao.AddOrderRefund(tx, orderRefund)
if err != nil || orderRefund == nil {
tx.Rollback()
return false, errors.New(err.Error())
}
// 新增退款表
orderProductRefund := &model.OrderProductRefund{
PatientId: orderProduct.PatientId,
OrderProductId: orderProductId,
OrderProductNo: orderProduct.OrderProductNo,
ProductRefundNo: refundNo,
RefundId: refundId,
ProductRefundStatus: refundStatus,
RefundTotal: orderProduct.PaymentAmountTotal,
RefundReason: req.CancelRemarks,
}
if refundStatus == 3 && !successTime.IsZero() {
orderProductRefund.SuccessTime = model.LocalTime(successTime)
}
orderProductRefundDao := dao.OrderProductRefundDao{}
orderProductRefund, err = orderProductRefundDao.AddOrderProductRefund(tx, orderProductRefund)
if err != nil || orderProductRefund == nil {
tx.Rollback()
return false, errors.New(err.Error())
}
// 获取患者家庭成员进行中的服务包订单-健康包
OrderServicePackageService := OrderServicePackageService{}
patientFamilyInProgressServicePackage, err := OrderServicePackageService.GetPatientFamilyInProgressServicePackage(orderProduct.UserPatient.UserId, orderProduct.FamilyId, orderProduct.DoctorId, 1)
if patientFamilyInProgressServicePackage != nil {
// 获取药品订单列表
orderProductItemDao := dao.OrderProductItemDao{}
orderProductItems, err := orderProductItemDao.GetOrderProductItemByOrderProductId(orderProductId)
if err != nil || len(orderProductItems) <= 0 {
tx.Rollback()
return false, errors.New("订单数据错误")
}
for _, item := range orderProductItems {
orderServicePackageProductDao := dao.OrderServicePackageProductDao{}
// 回退服务包已使用药品数量
maps := make(map[string]interface{})
maps["order_service_id"] = patientFamilyInProgressServicePackage.OrderServiceId
maps["order_product_id"] = item.OrderProductId
maps["product_item_id"] = item.ProductItemId
maps["product_id"] = item.ProductId
orderServicePackageProduct, err := orderServicePackageProductDao.GetOrderServicePackageProduct(maps)
if err == nil && orderServicePackageProduct != nil {
orderServicePackageProductData := make(map[string]interface{})
orderServicePackageProductData["used_quantity"] = 0
err := orderServicePackageProductDao.EditOrderServicePackageProductById(tx, orderServicePackageProduct.ServiceProductId, orderServicePackageProductData)
if err != nil {
tx.Rollback()
return false, errors.New(err.Error())
}
}
}
}
// 记录日志
orderOperationLog := &model.OrderOperationLog{
OrderId: orderProduct.OrderProductId,
OrderNo: orderProduct.OrderProductNo,
OrderType: 2,
OperatorId: adminUserId,
OperationContent: "取消订单并退款",
}
orderOperationLogDao := dao.OrderOperationLogDao{}
orderOperationLog, err = orderOperationLogDao.AddOrderOperationLog(tx, orderOperationLog)
if err != nil || orderOperationLog == nil {
tx.Rollback()
return false, errors.New(err.Error())
}
tx.Commit()
return true, nil
}
// GetOrderProductConsignee 获取药品订单收货人数据
func (r *OrderProductService) GetOrderProductConsignee(orderProductId int64) (*dto.OrderProductConsigneeDto, error) {
// 获取药品订单数据
orderProductDao := dao.OrderProductDao{}
orderProduct, err := orderProductDao.GetOrderProductById(orderProductId)
if err != nil || orderProduct == nil {
return nil, errors.New(err.Error())
}
// 处理返回值
u := dto.GetOrderProductConsigneeDto(orderProduct)
return u, nil
}