添加订单押金暂扣与归还

This commit is contained in:
yml2213
2026-07-05 19:35:57 +08:00
parent 9ef0843eb0
commit 090a90a268
17 changed files with 587 additions and 36 deletions
+54 -18
View File
@@ -38,7 +38,9 @@ func (r *Repository) AdminClose(ctx context.Context, adminID uint64, orderID uin
archiveAssets(listing, account)
if beforeOrderStatus != orderStatusPendingPayment {
totalCent := order.RentAmountCent + order.DepositAmountCent
action, err := r.prepareRefund(order, totalCent, refundBizAdminClose, "客服关闭订单原路退款")
// 押金暂扣:若订单已暂扣,拦截退款中的押金部分挂起不退,其余照常原路退。
refundAmountCent := order.ApplyDepositHold(totalCent, order.DepositAmountCent)
action, err := r.prepareRefund(order, refundAmountCent, refundBizAdminClose, "客服关闭订单原路退款")
if err != nil {
return err
}
@@ -307,26 +309,50 @@ func resetTargetForOrder(order model.RentalOrder) (adminResetTarget, bool) {
// AdminRefund 触发后台人工退款,退款由 payment 模块走渠道原路退回。
func (r *Repository) AdminRefund(ctx context.Context, orderID uint64) (*RefundStatusDTO, error) {
var order model.RentalOrder
db := r.db.WithContext(ctx)
if err := db.First(&order, orderID).Error; err != nil {
return nil, err
}
if order.RefundStatus == refundStatusRefunded {
return r.buildRefundStatusDTO(&order), nil
}
if r.refundStarter == nil {
return nil, ErrDependencyUnavailable
}
totalCent := order.RentAmountCent + order.DepositAmountCent
if totalCent <= 0 {
return nil, ErrInvalidCheckoutAmount
}
status, err := r.refundStarter.StartRefund(ctx, orderID, totalCent, refundBizAdmin, "后台人工退款")
var refund *refundAction
err := db.Transaction(func(tx *gorm.DB) error {
var order model.RentalOrder
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&order, orderID).Error; err != nil {
return err
}
if order.RefundStatus == refundStatusRefunded {
return nil
}
totalCent := order.RentAmountCent + order.DepositAmountCent
if totalCent <= 0 {
return ErrInvalidCheckoutAmount
}
// 押金暂扣:人工退款也必须尊重暂扣状态,避免绕过押金挂起直接全额退款。
refundAmountCent := order.ApplyDepositHold(totalCent, order.DepositAmountCent)
if refundAmountCent <= 0 {
order.RefundStatus = "none"
order.RefundAmountCent = 0
return tx.Save(&order).Error
}
if r.refundStarter == nil {
return ErrDependencyUnavailable
}
action, err := r.prepareRefund(&order, refundAmountCent, refundBizAdmin, "后台人工退款")
if err != nil {
return err
}
refund = action
return tx.Save(&order).Error
})
if err != nil {
return nil, err
}
status := ""
if refund != nil {
var err error
status, err = r.refundStarter.StartRefund(ctx, refund.OrderID, refund.RefundAmountCent, refund.BizType, refund.Remark)
if err != nil {
return nil, err
}
}
// 重新读取订单,拿到 payment 模块更新后的退款字段。
var order model.RentalOrder
if err := db.First(&order, orderID).Error; err != nil {
return nil, err
}
@@ -371,7 +397,15 @@ func (r *Repository) AdminApproveRefund(ctx context.Context, orderID uint64) err
if order.RefundAmountCent <= 0 {
return errors.New("退款金额无效")
}
action, err := r.prepareRefund(&order, order.RefundAmountCent, refundBizCancel, "取消订单原路退款(客服审核通过)")
// 押金暂扣:若订单已暂扣,拦截退款中的押金部分挂起不退,其余照常原路退。
refundAmountCent := order.ApplyDepositHold(order.RefundAmountCent, order.DepositAmountCent)
if refundAmountCent <= 0 {
// 全部押金被暂扣且无其他可退金额,直接标记为已处理,等待后续手动退押金。
order.RefundStatus = "none"
order.RefundAmountCent = 0
return tx.Save(&order).Error
}
action, err := r.prepareRefund(&order, refundAmountCent, refundBizCancel, "取消订单原路退款(客服审核通过)")
if err != nil {
return err
}
@@ -469,7 +503,9 @@ func (r *Repository) AdminSeal(ctx context.Context, adminID uint64, orderID uint
sealAssets(listing, account)
if beforeOrderStatus != orderStatusPendingPayment {
totalCent := order.RentAmountCent + order.DepositAmountCent
action, err := r.prepareRefund(order, totalCent, refundBizAdminSeal, "客服封存订单原路退款")
// 押金暂扣:若订单已暂扣,拦截退款中的押金部分挂起不退,其余照常原路退。
refundAmountCent := order.ApplyDepositHold(totalCent, order.DepositAmountCent)
action, err := r.prepareRefund(order, refundAmountCent, refundBizAdminSeal, "客服封存订单原路退款")
if err != nil {
return err
}