diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index e23b0bc..fa22b51 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -2,9 +2,11 @@ package main import ( "log" + "time" "sale/internal/api/routes" "sale/internal/config" + "sale/internal/models" "sale/internal/utils" "github.com/gin-gonic/gin" @@ -21,6 +23,9 @@ func main() { gin.SetMode(gin.ReleaseMode) } + // 启动订单过期检查定时任务 + go startOrderExpiryChecker() + r := gin.Default() routes.SetupRoutes(r) @@ -31,3 +36,63 @@ func main() { log.Fatalf("Failed to start server: %v", err) } } + +// startOrderExpiryChecker 启动定时检查过期订单 +func startOrderExpiryChecker() { + ticker := time.NewTicker(30 * time.Second) + defer ticker.Stop() + + // 立即执行一次 + checkExpiredOrders() + + for range ticker.C { + checkExpiredOrders() + } +} + +// checkExpiredOrders 检查并更新过期订单状态 +func checkExpiredOrders() { + now := time.Now() + + // 查找所有已过期但状态仍为待支付的订单 + var orders []models.Order + if err := utils.DB.Where("status = ? AND payment_expires_at IS NOT NULL AND payment_expires_at < ?", + models.OrderStatusPendingPayment, now).Find(&orders).Error; err != nil { + log.Printf("[OrderExpiry] Failed to query expired orders: %v", err) + return + } + + if len(orders) == 0 { + return + } + + log.Printf("[OrderExpiry] Found %d expired orders", len(orders)) + + for _, order := range orders { + tx := utils.DB.Begin() + + // 更新订单状态为已取消 + if err := tx.Model(&order).Update("status", models.OrderStatusCancelled).Error; err != nil { + tx.Rollback() + log.Printf("[OrderExpiry] Failed to cancel order %d: %v", order.ID, err) + continue + } + + // 恢复库存 + var orderItems []models.OrderItem + if err := tx.Where("order_id = ?", order.ID).Find(&orderItems).Error; err != nil { + tx.Rollback() + continue + } + + for _, item := range orderItems { + var inventory models.Inventory + if err := tx.Where("product_id = ?", item.ProductID).First(&inventory).Error; err == nil { + tx.Model(&inventory).UpdateColumn("quantity", inventory.Quantity+item.Quantity) + } + } + + tx.Commit() + log.Printf("[OrderExpiry] Order %d cancelled, stock restored", order.ID) + } +}