From 0a0f10b086f71ee27e6f83a2f40a50e25f311f22 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 14 Jul 2026 09:28:52 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E8=87=AA=E5=8A=A8=E6=A3=80=E6=9F=A5=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E4=BB=BB=E5=8A=A1(=E6=AF=8F30=E7=A7=92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/cmd/server/main.go | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) 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) + } +}