hospital-admin-api/api/service/OrderInquiry.go

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