修正了取消订单等操作

This commit is contained in:
2024-08-09 14:31:29 +08:00
parent 6137740b13
commit c235e1f293
11 changed files with 369 additions and 60 deletions
+144 -13
View File
@@ -13,6 +13,7 @@ import (
"hepa-calc-admin-api/extend/weChat"
"hepa-calc-admin-api/global"
"hepa-calc-admin-api/utils"
"strconv"
"time"
)
@@ -21,9 +22,9 @@ type OrderMemberService struct {
// CancelOrderMember 取消会员订单
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, orderMember *model.OrderMember, refundAmount *float64, cancelReason int) (bool, error) {
// 检测多次请求
redisKey := "CancelOrderMember" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
redisKey := "CancelOrderMember" + fmt.Sprintf("%d", orderMember.UserId) + fmt.Sprintf("%d", orderMember.OrderId)
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
if res != "" {
return false, errors.New("请勿重复操作")
@@ -39,15 +40,6 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
return false, errors.New("取消订单失败")
}
// 获取订单数据
orderMemberDao := dao.OrderMemberDao{}
maps := make(map[string]interface{})
maps["order_id"] = orderId
orderMember, err := orderMemberDao.GetOrderMember(maps)
if err != nil {
return false, errors.New("订单异常")
}
// 订单状态(1:待支付 2:已完成 3:已取消)
if orderMember.OrderStatus == 2 {
return false, errors.New("订单已完成,无法取消")
@@ -95,7 +87,9 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
orderMemberData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
orderMemberData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
orderMemberData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
err = orderMemberDao.EditOrderMemberById(tx, orderId, orderMemberData)
orderMemberDao := dao.OrderMemberDao{}
err = orderMemberDao.EditOrderMemberById(tx, orderMember.OrderId, orderMemberData)
if err != nil {
return false, errors.New("订单取消失败")
}
@@ -104,7 +98,7 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
if orderMember.CouponAmountTotal != 0 {
// 获取订单优惠卷数据
orderMemberCouponDao := dao.OrderMemberCouponDao{}
orderMemberCoupon, err := orderMemberCouponDao.GetOrderMemberCouponByOrderId(orderId)
orderMemberCoupon, err := orderMemberCouponDao.GetOrderMemberCouponByOrderId(orderMember.OrderId)
if err != nil {
tx.Rollback()
return false, errors.New("订单取消失败")
@@ -114,6 +108,20 @@ func (r *OrderMemberService) CancelOrderMember(tx *gorm.DB, userId, orderId int6
userCouponService.ReturnUserCoupon(tx, orderMemberCoupon.UserCouponId)
}
// 退还订单优惠卷
err = r.OrderCouponRefund(tx, orderMember)
if err != nil {
tx.Rollback()
return false, err
}
// 订单退款
_, err = r.OrderRefund(tx, orderMember, refundAmount, utils.OrderCancelReasonToString(cancelReason))
if err != nil {
tx.Rollback()
return false, err
}
return true, nil
}
@@ -183,3 +191,126 @@ func (r *OrderMemberService) GetAppPrepay(m *model.OrderMember) (prepay *app.Pre
return prepay, nil
}
// OrderRefund 订单退款
func (r *OrderMemberService) OrderRefund(tx *gorm.DB, order *model.OrderMember, refundAmount *float64, refundReason string) (*model.OrderMemberRefund, error) {
var refundStatus int
var successTime time.Time
var refundId string
// 判断订单支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
if order.PayStatus != 2 {
// 非已支付,无需退款
return nil, nil
}
// 检测退款金额
if *refundAmount > order.PaymentAmountTotal {
return nil, errors.New("退款金额不可超过实付金额")
}
// 退款编号
refundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
// 退款金额为0
if *refundAmount <= 0 {
// 支付金额为0,模拟退款
refundId = "模拟退款:" + strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
refundStatus = 3
successTime = time.Now()
}
// 退款金额大于0
if *refundAmount > 0 {
refundRequest := weChat.RefundRequest{
TransactionId: order.EscrowTradeNo,
OutTradeNo: order.OrderNo,
OutRefundNo: refundNo,
Reason: refundReason,
RefundAmount: int64(*refundAmount * 100),
PaymentAmountTotal: int64(order.PaymentAmountTotal * 100),
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
}
refund, err := refundRequest.Refund()
if err != nil {
return nil, err
}
if refund.Status == nil {
return nil, errors.New("退款状态错误")
}
// 处理订单状态
switch *refund.Status {
case "SUCCESS": // 退款成功
refundStatus = 3
if refund.SuccessTime != nil {
successTime = *refund.SuccessTime
}
case "CLOSED": // 退款关闭
refundStatus = 5
case "PROCESSING": // 退款处理中
refundStatus = 2
case "ABNORMAL": // 退款异常
return nil, errors.New("退款状态错误")
default:
return nil, errors.New("退款状态错误")
}
if refund.RefundId == nil {
return nil, errors.New("缺少退款订单编号")
}
// 退款编号
refundId = *refund.RefundId
}
// 新增退款表
orderRefund := &model.OrderMemberRefund{
UserId: order.UserId,
OrderId: order.OrderId,
OrderNo: order.OrderNo,
RefundNo: refundNo,
RefundId: refundId,
RefundStatus: refundStatus,
RefundTotal: *refundAmount,
RefundReason: refundReason,
}
if refundStatus == 3 && !successTime.IsZero() {
t := model.LocalTime(successTime)
orderRefund.SuccessTime = &t
}
orderMemberRefundDao := dao.OrderMemberRefundDao{}
orderMemberRefund, err := orderMemberRefundDao.AddOrderMemberRefund(tx, orderRefund)
if err != nil || orderMemberRefund == nil {
return nil, errors.New(err.Error())
}
return orderMemberRefund, nil
}
// OrderCouponRefund 订单优惠卷退还
func (r *OrderMemberService) OrderCouponRefund(tx *gorm.DB, order *model.OrderMember) error {
// 订单优惠金额为0,无需退还优惠卷
if order.CouponAmountTotal == 0 {
return nil
}
// 获取订单优惠卷数据
orderMemberCouponDao := dao.OrderMemberCouponDao{}
orderMemberCoupons, err := orderMemberCouponDao.GetOrderMemberCouponListByOrderId(order.OrderId)
if err != nil {
return errors.New("优惠卷数据错误")
}
userCouponService := &UserCouponService{}
for _, coupon := range orderMemberCoupons {
_ = userCouponService.ReturnUserCoupon(tx, coupon.UserCouponId)
}
return nil
}
+139 -22
View File
@@ -13,6 +13,7 @@ import (
"hepa-calc-admin-api/extend/weChat"
"hepa-calc-admin-api/global"
"hepa-calc-admin-api/utils"
"strconv"
"time"
)
@@ -21,9 +22,9 @@ type OrderSingleService struct {
// CancelOrderSingle 取消单项订单
// cancelReason:订单取消原因(1:主动取消 2:后台取消 3:支付超时取消)
func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int64, cancelReason int) (bool, error) {
func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, orderSingle *model.OrderSingle, refundAmount *float64, cancelReason int) (bool, error) {
// 检测多次请求
redisKey := "CancelOrderSingle" + fmt.Sprintf("%d", userId) + fmt.Sprintf("%d", orderId)
redisKey := "CancelOrderSingle" + fmt.Sprintf("%d", orderSingle.UserId) + fmt.Sprintf("%d", orderSingle.OrderId)
res, _ := global.Redis.Get(context.Background(), redisKey).Result()
if res != "" {
return false, errors.New("请勿重复操作")
@@ -39,15 +40,6 @@ func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int6
return false, errors.New("取消订单失败")
}
// 获取订单数据
orderSingleDao := dao.OrderSingleDao{}
maps := make(map[string]interface{})
maps["order_id"] = orderId
orderSingle, err := orderSingleDao.GetOrderSingle(maps)
if err != nil {
return false, errors.New("订单异常")
}
// 订单状态(1:待支付 2:已完成 3:已取消)
if orderSingle.OrderStatus == 2 {
return false, errors.New("订单已完成,无法取消")
@@ -95,23 +87,25 @@ func (r *OrderSingleService) CancelOrderSingle(tx *gorm.DB, userId, orderId int6
orderSingleData["cancel_time"] = time.Now().Format("2006-01-02 15:04:05")
orderSingleData["cancel_remarks"] = utils.OrderCancelReasonToString(cancelReason)
orderSingleData["updated_at"] = time.Now().Format("2006-01-02 15:04:05")
err = orderSingleDao.EditOrderSingleById(tx, orderId, orderSingleData)
orderSingleDao := dao.OrderSingleDao{}
err = orderSingleDao.EditOrderSingleById(tx, orderSingle.OrderId, orderSingleData)
if err != nil {
return false, errors.New("订单取消失败")
}
// 退还订单优惠卷
if orderSingle.CouponAmountTotal != 0 {
// 获取订单优惠卷数据
orderSingleCouponDao := dao.OrderSingleCouponDao{}
orderSingleCoupon, err := orderSingleCouponDao.GetOrderSingleCouponByOrderId(orderId)
if err != nil {
tx.Rollback()
return false, errors.New("订单取消失败")
}
err = r.OrderCouponRefund(tx, orderSingle)
if err != nil {
tx.Rollback()
return false, err
}
userCouponService := &UserCouponService{}
userCouponService.ReturnUserCoupon(tx, orderSingleCoupon.UserCouponId)
// 订单退款
_, err = r.OrderRefund(tx, orderSingle, refundAmount, utils.OrderCancelReasonToString(cancelReason))
if err != nil {
tx.Rollback()
return false, err
}
return true, nil
@@ -223,3 +217,126 @@ func (r *OrderSingleService) CompleteUnPayOrderSingle(tx *gorm.DB, userId int64)
return true, nil
}
// OrderRefund 订单退款
func (r *OrderSingleService) OrderRefund(tx *gorm.DB, order *model.OrderSingle, refundAmount *float64, refundReason string) (*model.OrderSingleRefund, error) {
var refundStatus int
var successTime time.Time
var refundId string
// 判断订单支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
if order.PayStatus != 2 {
// 非已支付,无需退款
return nil, nil
}
// 检测退款金额
if *refundAmount > order.PaymentAmountTotal {
return nil, errors.New("退款金额不可超过实付金额")
}
// 退款编号
refundNo := strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
// 退款金额为0
if *refundAmount <= 0 {
// 支付金额为0,模拟退款
refundId = "模拟退款:" + strconv.FormatInt(global.Snowflake.Generate().Int64(), 10)
refundStatus = 3
successTime = time.Now()
}
// 退款金额大于0
if *refundAmount > 0 {
refundRequest := weChat.RefundRequest{
TransactionId: order.EscrowTradeNo,
OutTradeNo: order.OrderNo,
OutRefundNo: refundNo,
Reason: refundReason,
RefundAmount: int64(*refundAmount * 100),
PaymentAmountTotal: int64(order.PaymentAmountTotal * 100),
NotifyUrl: config.C.Wechat.RefundNotifyDomain + config.C.Wechat.RefundNotifyUrl,
}
refund, err := refundRequest.Refund()
if err != nil {
return nil, err
}
if refund.Status == nil {
return nil, errors.New("退款状态错误")
}
// 处理订单状态
switch *refund.Status {
case "SUCCESS": // 退款成功
refundStatus = 3
if refund.SuccessTime != nil {
successTime = *refund.SuccessTime
}
case "CLOSED": // 退款关闭
refundStatus = 5
case "PROCESSING": // 退款处理中
refundStatus = 2
case "ABNORMAL": // 退款异常
return nil, errors.New("退款状态错误")
default:
return nil, errors.New("退款状态错误")
}
if refund.RefundId == nil {
return nil, errors.New("缺少退款订单编号")
}
// 退款编号
refundId = *refund.RefundId
}
// 新增退款表
orderRefund := &model.OrderSingleRefund{
UserId: order.UserId,
OrderId: order.OrderId,
OrderNo: order.OrderNo,
RefundNo: refundNo,
RefundId: refundId,
RefundStatus: refundStatus,
RefundTotal: *refundAmount,
RefundReason: refundReason,
}
if refundStatus == 3 && !successTime.IsZero() {
t := model.LocalTime(successTime)
orderRefund.SuccessTime = &t
}
orderSingleRefundDao := dao.OrderSingleRefundDao{}
orderSingleRefund, err := orderSingleRefundDao.AddOrderSingleRefund(tx, orderRefund)
if err != nil || orderSingleRefund == nil {
return nil, errors.New(err.Error())
}
return orderSingleRefund, nil
}
// OrderCouponRefund 订单优惠卷退还
func (r *OrderSingleService) OrderCouponRefund(tx *gorm.DB, order *model.OrderSingle) error {
// 订单优惠金额为0,无需退还优惠卷
if order.CouponAmountTotal == 0 {
return nil
}
// 获取订单优惠卷数据
orderSingleCouponDao := dao.OrderSingleCouponDao{}
orderSingleCoupons, err := orderSingleCouponDao.GetOrderSingleCouponListByOrderId(order.OrderId)
if err != nil {
return errors.New("优惠卷数据错误")
}
userCouponService := &UserCouponService{}
for _, coupon := range orderSingleCoupons {
_ = userCouponService.ReturnUserCoupon(tx, coupon.UserCouponId)
}
return nil
}