380 lines
12 KiB
Go
Raw Permalink 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.

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
// 加载问诊病例
g.LoadOrderInquiryCase(orderInquiryCase)
// 加载处方数据
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
}