修复支付取消与成功统计

This commit is contained in:
yml
2026-06-14 23:58:39 +08:00
parent 3ff8c1de88
commit a275a006eb
11 changed files with 412 additions and 7 deletions
@@ -2,12 +2,14 @@ package order
import (
"context"
"encoding/json"
"time"
"hfb_sys/backend/internal/model"
"hfb_sys/backend/internal/modules/chat"
"hfb_sys/backend/internal/modules/notification"
"gorm.io/datatypes"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
@@ -264,6 +266,9 @@ func (r *Repository) Cancel(ctx context.Context, userID uint64, orderID uint64)
return err
}
releaseAssetsForRental(listing, account)
if err := closePendingOrderPayments(tx, order.ID, "order_cancel"); err != nil {
return err
}
if err := tx.Save(&order).Error; err != nil {
return err
}
@@ -279,6 +284,23 @@ func (r *Repository) Cancel(ctx context.Context, userID uint64, orderID uint64)
return nil
}
// closePendingOrderPayments 在订单取消时关闭仍未完成的下单支付流水,避免后台一直显示“支付中”。
func closePendingOrderPayments(tx *gorm.DB, orderID uint64, source string) error {
raw, err := json.Marshal(map[string]string{
"source": source,
"reason": "订单已取消,关闭未完成支付单",
})
if err != nil {
return err
}
return tx.Model(&model.PaymentOrder{}).
Where("order_id = ? AND biz_type = ? AND status IN ?", orderID, "order_pay", []string{"created", "paying"}).
Updates(map[string]any{
"status": "closed",
"raw_response": datatypes.JSON(raw),
}).Error
}
func (r *Repository) ConfirmReceive(ctx context.Context, userID uint64, orderID uint64) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var order model.RentalOrder
@@ -24,6 +24,8 @@ func setupOrderTestDB(t *testing.T) *gorm.DB {
&model.GameAccount{},
&model.RentalListing{},
&model.RentalOrder{},
&model.PaymentOrder{},
&model.Notification{},
&model.HandoffRecord{},
&model.OrderCheckout{},
); err != nil {
@@ -375,3 +377,78 @@ func TestOrderDurationHoursUsesDefault(t *testing.T) {
t.Fatalf("hours = %d, want %d", hours, internalOrderHours)
}
}
// TestCancelClosesPendingPaymentOrder 验证租客取消待支付订单时,未完成支付流水会同步关闭。
func TestCancelClosesPendingPaymentOrder(t *testing.T) {
db := setupOrderTestDB(t)
repo := NewRepository(db)
owner := model.User{Phone: "13800001001"}
renter := model.User{Phone: "13900001001"}
if err := db.Create(&owner).Error; err != nil {
t.Fatalf("create owner failed: %v", err)
}
if err := db.Create(&renter).Error; err != nil {
t.Fatalf("create renter failed: %v", err)
}
account := model.GameAccount{
OwnerID: owner.ID,
Status: "rented",
ServerRegion: "国服",
LoginPlatform: "steam",
Title: "测试账号",
}
if err := db.Create(&account).Error; err != nil {
t.Fatalf("create account failed: %v", err)
}
listing := model.RentalListing{
ListingNo: "LST-CANCEL-001",
OwnerID: owner.ID,
AccountID: account.ID,
Status: "published",
ReviewStatus: "approved",
InTransaction: true,
PriceCent: 1000,
}
if err := db.Create(&listing).Error; err != nil {
t.Fatalf("create listing failed: %v", err)
}
order := model.RentalOrder{
OrderNo: "ORD-CANCEL-001",
ListingID: listing.ID,
AccountID: account.ID,
OwnerID: owner.ID,
RenterID: renter.ID,
RentAmountCent: 1000,
Status: "pending_payment",
HandoffStatus: "none",
}
if err := db.Create(&order).Error; err != nil {
t.Fatalf("create order failed: %v", err)
}
payment := model.PaymentOrder{
PaymentNo: "PAY-CANCEL-001",
OrderID: order.ID,
OrderNo: order.OrderNo,
UserID: renter.ID,
Provider: "lakala",
ThirdOrderID: "PAY-CANCEL-001",
AmountCent: 1000,
BizType: "order_pay",
Status: "paying",
}
if err := db.Create(&payment).Error; err != nil {
t.Fatalf("create payment failed: %v", err)
}
if err := repo.Cancel(t.Context(), renter.ID, order.ID); err != nil {
t.Fatalf("Cancel() error = %v", err)
}
var latestPayment model.PaymentOrder
if err := db.First(&latestPayment, payment.ID).Error; err != nil {
t.Fatalf("find payment failed: %v", err)
}
if latestPayment.Status != "closed" {
t.Fatalf("payment status = %q, want closed", latestPayment.Status)
}
}