feat: 实现订单超时自动取消功能,支持钱包余额解冻和 Asynq Scheduler 统一调度
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m58s

- 新增 expires_at 字段和复合索引,待支付订单 30 分钟超时自动取消
- 实现 cancelOrder/unfreezeWalletForCancel 钱包余额解冻逻辑
- 创建 Asynq 定时任务(order_expire/alert_check/data_cleanup)
- 将原有 time.Ticker 轮询迁移至 Asynq Scheduler 统一调度
- 同步 delta specs 到 main specs 并归档变更
This commit is contained in:
2026-02-28 17:16:15 +08:00
parent 5bb0ff0ddf
commit e661b59bb9
35 changed files with 1157 additions and 314 deletions

View File

@@ -29,8 +29,8 @@ type StandaloneIotCardResponse struct {
IMSI string `json:"imsi,omitempty" description:"IMSI"`
MSISDN string `json:"msisdn,omitempty" description:"卡接入号"`
BatchNo string `json:"batch_no,omitempty" description:"批次号"`
Supplier string `json:"supplier,omitempty" description:"供应商"`
Status int `json:"status" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
Supplier string `json:"supplier,omitempty" description:"供应商"`
Status int `json:"status" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
ShopID *uint `json:"shop_id,omitempty" description:"店铺ID"`
ShopName string `json:"shop_name,omitempty" description:"店铺名称"`
ActivatedAt *time.Time `json:"activated_at,omitempty" description:"激活时间"`

View File

@@ -28,6 +28,7 @@ type OrderListRequest struct {
PurchaseRole string `json:"purchase_role" query:"purchase_role" validate:"omitempty,oneof=self_purchase purchased_by_parent purchased_by_platform purchase_for_subordinate" description:"订单角色 (self_purchase:自己购买, purchased_by_parent:上级代理购买, purchased_by_platform:平台代购, purchase_for_subordinate:给下级购买)"`
StartTime *time.Time `json:"start_time" query:"start_time" description:"创建时间起始"`
EndTime *time.Time `json:"end_time" query:"end_time" description:"创建时间结束"`
IsExpired *bool `json:"is_expired" query:"is_expired" description:"是否已过期 (true:已过期, false:未过期)"`
}
type PayOrderRequest struct {
@@ -44,21 +45,21 @@ type OrderItemResponse struct {
}
type OrderResponse struct {
ID uint `json:"id" description:"订单ID"`
OrderNo string `json:"order_no" description:"订单号"`
OrderType string `json:"order_type" description:"订单类型 (single_card:单卡购买, device:设备购买)"`
BuyerType string `json:"buyer_type" description:"买家类型 (personal:个人客户, agent:代理商)"`
BuyerID uint `json:"buyer_id" description:"买家ID"`
IotCardID *uint `json:"iot_card_id,omitempty" description:"IoT卡ID"`
DeviceID *uint `json:"device_id,omitempty" description:"设备ID"`
TotalAmount int64 `json:"total_amount" description:"订单总金额(分)"`
PaymentMethod string `json:"payment_method,omitempty" description:"支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付)"`
PaymentStatus int `json:"payment_status" description:"支付状态 (1:待支付, 2:已支付, 3:已取消, 4:已退款)"`
PaymentStatusText string `json:"payment_status_text" description:"支付状态文本"`
PaidAt *time.Time `json:"paid_at,omitempty" description:"支付时间"`
IsPurchaseOnBehalf bool `json:"is_purchase_on_behalf" description:"是否为代购订单"`
CommissionStatus int `json:"commission_status" description:"佣金状态 (1:待计算, 2:已计算)"`
CommissionConfigVersion int `json:"commission_config_version" description:"佣金配置版本"`
ID uint `json:"id" description:"订单ID"`
OrderNo string `json:"order_no" description:"订单号"`
OrderType string `json:"order_type" description:"订单类型 (single_card:单卡购买, device:设备购买)"`
BuyerType string `json:"buyer_type" description:"买家类型 (personal:个人客户, agent:代理商)"`
BuyerID uint `json:"buyer_id" description:"买家ID"`
IotCardID *uint `json:"iot_card_id,omitempty" description:"IoT卡ID"`
DeviceID *uint `json:"device_id,omitempty" description:"设备ID"`
TotalAmount int64 `json:"total_amount" description:"订单总金额(分)"`
PaymentMethod string `json:"payment_method,omitempty" description:"支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付)"`
PaymentStatus int `json:"payment_status" description:"支付状态 (1:待支付, 2:已支付, 3:已取消, 4:已退款)"`
PaymentStatusText string `json:"payment_status_text" description:"支付状态文本"`
PaidAt *time.Time `json:"paid_at,omitempty" description:"支付时间"`
IsPurchaseOnBehalf bool `json:"is_purchase_on_behalf" description:"是否为代购订单"`
CommissionStatus int `json:"commission_status" description:"佣金状态 (1:待计算, 2:已计算)"`
CommissionConfigVersion int `json:"commission_config_version" description:"佣金配置版本"`
// 操作者信息
OperatorID *uint `json:"operator_id,omitempty" description:"操作者ID"`
@@ -74,6 +75,10 @@ type OrderResponse struct {
Items []*OrderItemResponse `json:"items" description:"订单明细列表"`
CreatedAt time.Time `json:"created_at" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
// 订单超时信息
ExpiresAt *time.Time `json:"expires_at,omitempty" description:"订单过期时间"`
IsExpired bool `json:"is_expired" description:"是否已过期"`
}
type OrderListResponse struct {