package main import ( "log" "time" "sale/internal/api/routes" "sale/internal/config" "sale/internal/models" "sale/internal/utils" "github.com/gin-gonic/gin" ) func main() { config.Load() utils.InitDB() utils.InitLogger() utils.AutoMigrate() if config.AppConfig.Server.Mode == "release" { gin.SetMode(gin.ReleaseMode) } // 启动订单过期检查定时任务 go startOrderExpiryChecker() r := gin.Default() routes.SetupRoutes(r) addr := ":" + config.AppConfig.Server.Port log.Printf("Server starting on %s", addr) if err := r.Run(addr); err != nil { 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) } }