380 lines
12 KiB
Go
380 lines
12 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
|
||
|
||
// 加载问诊病例
|
||
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
|
||
}
|