463 lines
16 KiB
Go
463 lines
16 KiB
Go
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
|
||
}
|