新增订单待支付与支付确认后端流程
This commit is contained in:
@@ -22,6 +22,7 @@ type Job struct {
|
||||
}
|
||||
|
||||
type thresholds struct {
|
||||
PendingPaymentTimeoutMinutes int
|
||||
OwnerSubmitTimeoutMinutes int
|
||||
RenterConfirmTimeoutMinutes int
|
||||
ReturnOverdueGraceMinutes int
|
||||
@@ -66,6 +67,7 @@ func (j *Job) run(ctx context.Context) {
|
||||
}
|
||||
now := time.Now()
|
||||
handlers := []func(context.Context, time.Time, thresholds) (int, error){
|
||||
j.handlePendingPaymentTimeout,
|
||||
j.handleOwnerSubmitTimeout,
|
||||
j.handleRenterConfirmTimeout,
|
||||
j.handleReturnOverdue,
|
||||
@@ -87,6 +89,7 @@ func (j *Job) run(ctx context.Context) {
|
||||
|
||||
func (j *Job) loadThresholds(ctx context.Context) (thresholds, error) {
|
||||
cfg := thresholds{
|
||||
PendingPaymentTimeoutMinutes: 15,
|
||||
OwnerSubmitTimeoutMinutes: 30,
|
||||
RenterConfirmTimeoutMinutes: 30,
|
||||
ReturnOverdueGraceMinutes: 10,
|
||||
@@ -97,6 +100,7 @@ func (j *Job) loadThresholds(ctx context.Context) (thresholds, error) {
|
||||
Where("`key` IN ?", []string{
|
||||
"handoff.owner_submit_timeout_minutes",
|
||||
"handoff.renter_confirm_timeout_minutes",
|
||||
"order.pending_payment_timeout_minutes",
|
||||
"order.return_overdue_grace_minutes",
|
||||
"handoff.owner_return_confirm_timeout_minutes",
|
||||
}).
|
||||
@@ -114,6 +118,8 @@ func (j *Job) loadThresholds(ctx context.Context) (thresholds, error) {
|
||||
cfg.OwnerSubmitTimeoutMinutes = value
|
||||
case "handoff.renter_confirm_timeout_minutes":
|
||||
cfg.RenterConfirmTimeoutMinutes = value
|
||||
case "order.pending_payment_timeout_minutes":
|
||||
cfg.PendingPaymentTimeoutMinutes = value
|
||||
case "order.return_overdue_grace_minutes":
|
||||
cfg.ReturnOverdueGraceMinutes = value
|
||||
case "handoff.owner_return_confirm_timeout_minutes":
|
||||
@@ -123,6 +129,65 @@ func (j *Job) loadThresholds(ctx context.Context) (thresholds, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (j *Job) handlePendingPaymentTimeout(ctx context.Context, now time.Time, cfg thresholds) (int, error) {
|
||||
var rows []model.RentalOrder
|
||||
err := j.db.WithContext(ctx).
|
||||
Where("status = ? AND created_at <= ?", "pending_payment", now.Add(-time.Duration(cfg.PendingPaymentTimeoutMinutes)*time.Minute)).
|
||||
Order("id ASC").
|
||||
Limit(100).
|
||||
Find(&rows).Error
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
count := 0
|
||||
for _, row := range rows {
|
||||
if err := j.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var order model.RentalOrder
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&order, row.ID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if order.Status != "pending_payment" {
|
||||
return nil
|
||||
}
|
||||
before := snapshot(&order)
|
||||
var listing model.RentalListing
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&listing, order.ListingID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
order.Status = "cancelled"
|
||||
order.HandoffStatus = "cancelled"
|
||||
listing.InTransaction = false
|
||||
orderID := order.ID
|
||||
if err := notification.Append(tx, notification.Entry{
|
||||
UserID: order.RenterID,
|
||||
Type: "timeout",
|
||||
Title: "订单支付超时",
|
||||
Content: "订单未在规定时间内完成支付,已自动取消。",
|
||||
BizType: "order",
|
||||
BizID: &orderID,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Save(&order).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Save(&listing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return appendAuditLog(tx, "order.timeout.pending_payment", order.ID, map[string]any{
|
||||
"order_id": order.ID,
|
||||
"order_no": order.OrderNo,
|
||||
"before": before,
|
||||
"after": snapshot(&order),
|
||||
})
|
||||
}); err != nil {
|
||||
return count, err
|
||||
}
|
||||
count++
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (j *Job) handleOwnerSubmitTimeout(ctx context.Context, now time.Time, cfg thresholds) (int, error) {
|
||||
var rows []model.RentalOrder
|
||||
err := j.db.WithContext(ctx).
|
||||
|
||||
Reference in New Issue
Block a user