package service import ( "errors" "fmt" "gorm.io/gorm" "hospital-admin-api/api/dao" "hospital-admin-api/api/model" "hospital-admin-api/api/responses/orderEvaluationResponse" "hospital-admin-api/api/responses/orderInquiryCaseResponse" "hospital-admin-api/api/responses/orderInquiryCouponResponse" "hospital-admin-api/api/responses/orderInquiryRefundResponse" "hospital-admin-api/api/responses/orderInquiryResponse" "hospital-admin-api/config" "hospital-admin-api/extend/weChat" "hospital-admin-api/global" "strconv" "time" ) type OrderInquiryService struct { } // CancelOrderInquiry 取消问诊订单 func (r *OrderInquiryService) CancelOrderInquiry(orderInquiryId int64) (bool, error) { // 获取订单数据 orderInquiryDao := dao.OrderInquiryDao{} orderInquiry, err := orderInquiryDao.GetOrderInquiryById(orderInquiryId) if err != nil || orderInquiry == nil { return false, errors.New("订单数据错误") } // 检测订单状态 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) if orderInquiry.InquiryStatus == 6 { return false, errors.New("订单已结束,无法取消") } if orderInquiry.InquiryStatus == 7 { return false, errors.New("订单已取消,无法再次取消") } if orderInquiry.InquiryStatus == 1 { return false, errors.New("订单处于待支付状态,无法取消") } if orderInquiry.InquiryStatus == 2 { return false, errors.New("订单处于分配状态,无法取消") } if orderInquiry.InquiryStatus == 3 { return false, errors.New("订单处于等待接诊状态,无法取消") } // 检测订单退款状态 问诊订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常) if orderInquiry.InquiryRefundStatus == 1 { return false, errors.New("订单申请退款中,无法取消") } if orderInquiry.InquiryRefundStatus == 2 { return false, errors.New("订单正在退款中,无法取消") } if orderInquiry.InquiryRefundStatus == 3 { return false, errors.New("订单已退款成功,无法取消") } if orderInquiry.InquiryRefundStatus == 6 { return false, errors.New("订单退款异常,请联系技术人员") } // 检测支付状态 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款) if orderInquiry.InquiryPayStatus != 2 { return false, errors.New("订单未支付,无需取消") } // 订单完成时间预留5分钟进行操作 if !orderInquiry.CompleteTime.IsEmpty() { // 计算三天后的时间 threeDaysLater := time.Time(orderInquiry.CompleteTime).Add(3 * 24 * time.Hour) // 计算三天后的时间与当前时间的时间差 timeDifference := threeDaysLater.Sub(time.Now()) fmt.Println(timeDifference) if timeDifference < 0 { return false, errors.New("订单已完成,无法取消") } if 5*time.Minute > timeDifference { return false, errors.New("距离订单完成时间不足5分钟,无法取消") } } // 开始事务 tx := global.Db.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 问诊订单修改数据 orderInquiryData := make(map[string]interface{}) // 退款编号 inquiryRefundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10) // 退款状态转换 var inquiryRefundStatus int var successTime time.Time var refundId string // 发起退款 if orderInquiry.PaymentAmountTotal > 0 { refundRequest := weChat.RefundRequest{ TransactionId: orderInquiry.EscrowTradeNo, OutTradeNo: orderInquiry.InquiryNo, OutRefundNo: inquiryRefundNo, Reason: "客服取消", PaymentAmountTotal: int64(orderInquiry.PaymentAmountTotal * 100), NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.PatientInquiryRefundNotifyUrl, } refund, err := refundRequest.Refund() 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" { // 退款成功 inquiryRefundStatus = 3 if refund.SuccessTime != nil { successTime = *refund.SuccessTime } } else if *refund.Status == "CLOSED" { // 退款关闭 inquiryRefundStatus = 5 } else if *refund.Status == "PROCESSING" { // 退款处理中 inquiryRefundStatus = 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) inquiryRefundStatus = 3 successTime = time.Now() // 模拟退款时手动退还优惠卷 if orderInquiry.CouponAmountTotal > 0 { res := ReturnInquiryCoupon(tx, orderInquiry.OrderInquiryId) if !res { tx.Rollback() return false, errors.New("退还优惠卷失败") } } } orderInquiryData["inquiry_refund_status"] = inquiryRefundStatus orderInquiryData["inquiry_status"] = 7 // 问诊订单状态(1:待支付 2:待分配 3:待接诊 4:已接诊 5:已完成 6:已结束 7:已取消) orderInquiryData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05") // 订单取消时间 orderInquiryData["cancel_reason"] = 4 // 取消订单原因(1:医生未接诊 2:主动取消 3:无可分配医生 4:客服取消 5:支付超时) orderInquiryData["cancel_remarks"] = "客服取消" // 取消订单备注(自动添加) // 修改问诊订单退款状态 err = orderInquiryDao.EditOrderInquiryById(tx, orderInquiryId, orderInquiryData) if err != nil { tx.Rollback() return false, errors.New("取消订单失败") } // 新增退款表 orderInquiryRefund := &model.OrderInquiryRefund{ PatientId: orderInquiry.PatientId, OrderInquiryId: orderInquiryId, InquiryNo: orderInquiry.InquiryNo, InquiryRefundNo: inquiryRefundNo, RefundId: refundId, InquiryRefundStatus: inquiryRefundStatus, RefundTotal: orderInquiry.PaymentAmountTotal, RefundReason: "客服取消", SuccessTime: model.LocalTime(successTime), } orderInquiryRefundDao := dao.OrderInquiryRefundDao{} orderInquiryRefund, err = orderInquiryRefundDao.AddOrderInquiryRefund(tx, orderInquiryRefund) if err != nil || orderInquiryRefund == nil { tx.Rollback() return false, errors.New(err.Error()) } tx.Commit() return true, nil } // ReturnInquiryCoupon 退还问诊订单优惠卷 func ReturnInquiryCoupon(tx *gorm.DB, orderInquiryId int64) bool { orderInquiryCouponDao := dao.OrderInquiryCouponDao{} userCouponDao := dao.UserCouponDao{} // 获取用户优惠卷信息 orderInquiry, err := orderInquiryCouponDao.GetOrderInquiryCouponByOrderInquiryId(orderInquiryId) if err != nil || orderInquiry == nil { // 订单未使用优惠卷,无需退还 return true } // 获取用户优惠卷数据 userCoupon, err := userCouponDao.GetUserCouponById(orderInquiry.UserCouponId) if err != nil || userCoupon == nil { // 无该优惠卷数据,无需处理 return true } // 恢复优惠卷 userCouponData := make(map[string]interface{}) // 检测优惠卷过期时间。判断是否需要退还 if userCoupon.ValidEndTime.Before(time.Now()) { userCouponData["user_coupon_status"] = 3 } else { userCouponData["user_coupon_status"] = 0 userCouponData["coupon_use_date"] = nil } err = userCouponDao.EditUserCouponById(tx, userCoupon.UserCouponId, userCouponData) if err != nil { // 恢复优惠卷失败 return false } return true } // GetOrderInquiry 问诊订单详情 func (r *OrderInquiryService) GetOrderInquiry(orderInquiryId int64) (getOrderInquiryResponse *orderInquiryResponse.GetOrderInquiry, err error) { // 获取问诊订单数据 orderInquiryDao := dao.OrderInquiryDao{} orderInquiry, err := orderInquiryDao.GetOrderInquiryPreloadById(orderInquiryId) if err != nil || orderInquiry == nil { return nil, errors.New(err.Error()) } // 获取问诊订单优惠卷 orderInquiryCoupon, err := r.GetOrderInquiryCoupon(orderInquiryId) if err != nil { return nil, errors.New(err.Error()) } // 获取问诊病例 orderInquiryCase, err := r.GetOrderInquiryCase(orderInquiryId) if err != nil { return nil, errors.New(err.Error()) } // 获取退款数据 orderInquiryRefund, err := r.GetOrderInquiryRefund(orderInquiryId) if err != nil { return nil, errors.New(err.Error()) } // 获取订单评价 orderEvaluation, err := r.GetOrderEvaluation(orderInquiryId) if err != nil { return nil, errors.New(err.Error()) } // 医生数据 userDoctorService := UserDoctorService{} userDoctor, err := userDoctorService.GetOrderInquiryUserDoctor(orderInquiry.DoctorId) if err != nil { return nil, errors.New(err.Error()) } // 处理医生id var doctorId string if orderInquiry.DoctorId != 0 { doctorId = fmt.Sprintf("%v", orderInquiry.DoctorId) } // 处理返回值 getOrderInquiryResponse = &orderInquiryResponse.GetOrderInquiry{ OrderInquiryId: strconv.FormatInt(orderInquiry.OrderInquiryId, 10), UserId: strconv.FormatInt(orderInquiry.UserId, 10), DoctorId: doctorId, PatientId: strconv.FormatInt(orderInquiry.PatientId, 10), FamilyId: strconv.FormatInt(orderInquiry.FamilyId, 10), InquiryType: orderInquiry.InquiryType, InquiryMode: orderInquiry.InquiryMode, InquiryStatus: orderInquiry.InquiryStatus, IsDelete: orderInquiry.IsDelete, InquiryRefundStatus: orderInquiry.InquiryRefundStatus, InquiryPayChannel: orderInquiry.InquiryPayChannel, InquiryPayStatus: orderInquiry.InquiryPayStatus, InquiryNo: orderInquiry.InquiryNo, EscrowTradeNo: orderInquiry.EscrowTradeNo, AmountTotal: orderInquiry.AmountTotal, CouponAmountTotal: orderInquiry.CouponAmountTotal, PaymentAmountTotal: orderInquiry.PaymentAmountTotal, PayTime: orderInquiry.PayTime, ReceptionTime: orderInquiry.ReceptionTime, CompleteTime: orderInquiry.CompleteTime, FinishTime: orderInquiry.FinishTime, StatisticsStatus: orderInquiry.StatisticsStatus, StatisticsTime: orderInquiry.StatisticsTime, IsWithdrawal: orderInquiry.IsWithdrawal, WithdrawalTime: orderInquiry.WithdrawalTime, CancelTime: orderInquiry.CancelTime, CancelReason: orderInquiry.CancelReason, CancelRemarks: orderInquiry.CancelRemarks, PatientName: orderInquiry.PatientName, PatientNameMask: orderInquiry.PatientNameMask, PatientSex: orderInquiry.PatientSex, PatientAge: orderInquiry.PatientAge, OrderInquiryCoupon: orderInquiryCoupon, OrderInquiryCase: orderInquiryCase, OrderInquiryRefund: orderInquiryRefund, OrderEvaluation: orderEvaluation, UserDoctor: userDoctor, CreatedAt: orderInquiry.CreatedAt, UpdatedAt: orderInquiry.UpdatedAt, } return getOrderInquiryResponse, nil } // GetOrderInquiryCoupon 获取问诊订单优惠卷 func (r *OrderInquiryService) GetOrderInquiryCoupon(orderInquiryId int64) (u *orderInquiryCouponResponse.OrderInquiryCoupon, err error) { orderInquiryCouponDao := dao.OrderInquiryCouponDao{} orderInquiryCoupon, err := orderInquiryCouponDao.GetOrderInquiryCouponByOrderInquiryId(orderInquiryId) if orderInquiryCoupon == nil { return nil, nil } u = &orderInquiryCouponResponse.OrderInquiryCoupon{ OrderCouponId: strconv.FormatInt(orderInquiryCoupon.OrderCouponId, 10), OrderInquiryId: strconv.FormatInt(orderInquiryCoupon.OrderInquiryId, 10), UserCouponId: strconv.FormatInt(orderInquiryCoupon.UserCouponId, 10), CouponName: orderInquiryCoupon.CouponName, CouponUsePrice: orderInquiryCoupon.CouponUsePrice, CreatedAt: orderInquiryCoupon.CreatedAt, UpdatedAt: orderInquiryCoupon.UpdatedAt, } return u, nil } // GetOrderInquiryCase 获取问诊订单病例 func (r *OrderInquiryService) GetOrderInquiryCase(orderInquiryId int64) (u *orderInquiryCaseResponse.OrderInquiryCase, err error) { orderInquiryCaseDao := dao.OrderInquiryCaseDao{} orderInquiryCase, err := orderInquiryCaseDao.GetOrderInquiryCaseByOrderInquiryId(orderInquiryId) if orderInquiryCase == nil { return nil, errors.New("数据错误,无问诊病例") } u = &orderInquiryCaseResponse.OrderInquiryCase{ InquiryCaseId: strconv.FormatInt(orderInquiryCase.InquiryCaseId, 10), UserId: strconv.FormatInt(orderInquiryCase.UserId, 10), PatientId: strconv.FormatInt(orderInquiryCase.PatientId, 10), OrderInquiryId: strconv.FormatInt(orderInquiryCase.OrderInquiryId, 10), FamilyId: strconv.FormatInt(orderInquiryCase.FamilyId, 10), Relation: orderInquiryCase.Relation, Status: orderInquiryCase.Status, Name: orderInquiryCase.Name, Sex: orderInquiryCase.Sex, Age: orderInquiryCase.Age, Height: orderInquiryCase.Height, Weight: orderInquiryCase.Weight, DiseaseClassId: strconv.FormatInt(orderInquiryCase.DiseaseClassId, 10), DiseaseClassName: orderInquiryCase.DiseaseClassName, DiagnosisDate: orderInquiryCase.DiagnosisDate, DiseaseDesc: orderInquiryCase.DiseaseDesc, DiagnoseImages: orderInquiryCase.DiagnoseImages, IsAllergyHistory: orderInquiryCase.IsAllergyHistory, AllergyHistory: orderInquiryCase.AllergyHistory, IsFamilyHistory: orderInquiryCase.IsFamilyHistory, FamilyHistory: orderInquiryCase.FamilyHistory, IsPregnant: orderInquiryCase.IsPregnant, Pregnant: orderInquiryCase.Pregnant, IsTaboo: orderInquiryCase.IsTaboo, CreatedAt: orderInquiryCase.CreatedAt, UpdatedAt: orderInquiryCase.UpdatedAt, } return u, nil } // GetOrderInquiryRefund 获取问诊订单退款数据 func (r *OrderInquiryService) GetOrderInquiryRefund(orderInquiryId int64) (u *orderInquiryRefundResponse.OrderInquiryRefund, err error) { orderInquiryRefundDao := dao.OrderInquiryRefundDao{} orderInquiryRefund, err := orderInquiryRefundDao.GetOrderInquiryRefundByOrderInquiryId(orderInquiryId) if orderInquiryRefund == nil { return nil, nil } u = &orderInquiryRefundResponse.OrderInquiryRefund{ InquiryRefundId: strconv.FormatInt(orderInquiryRefund.InquiryRefundId, 10), PatientId: strconv.FormatInt(orderInquiryRefund.PatientId, 10), OrderInquiryId: strconv.FormatInt(orderInquiryRefund.OrderInquiryId, 10), InquiryNo: orderInquiryRefund.InquiryNo, InquiryRefundNo: orderInquiryRefund.InquiryRefundNo, RefundId: orderInquiryRefund.RefundId, InquiryRefundStatus: orderInquiryRefund.InquiryRefundStatus, RefundTotal: orderInquiryRefund.RefundTotal, RefundReason: orderInquiryRefund.RefundReason, SuccessTime: orderInquiryRefund.SuccessTime, CreatedAt: orderInquiryRefund.CreatedAt, UpdatedAt: orderInquiryRefund.UpdatedAt, } return u, nil } // GetOrderEvaluation 获取问诊订单评价数据 func (r *OrderInquiryService) GetOrderEvaluation(orderInquiryId int64) (u *orderEvaluationResponse.OrderEvaluation, err error) { orderEvaluationDao := dao.OrderEvaluationDao{} orderEvaluation, err := orderEvaluationDao.GetOrderEvaluationByOrderInquiryId(orderInquiryId) if orderEvaluation == nil { return nil, nil } u = &orderEvaluationResponse.OrderEvaluation{ EvaluationId: strconv.FormatInt(orderEvaluation.EvaluationId, 10), DoctorId: strconv.FormatInt(orderEvaluation.DoctorId, 10), PatientId: strconv.FormatInt(orderEvaluation.PatientId, 10), OrderInquiryId: strconv.FormatInt(orderEvaluation.OrderInquiryId, 10), NameMask: orderEvaluation.NameMask, ReplyQuality: orderEvaluation.ReplyQuality, ServiceAttitude: orderEvaluation.ServiceAttitude, ReplyProgress: orderEvaluation.ReplyProgress, AvgScore: orderEvaluation.AvgScore, Type: orderEvaluation.Type, Content: orderEvaluation.Content, CreatedAt: orderEvaluation.CreatedAt, UpdatedAt: orderEvaluation.UpdatedAt, } return u, nil }