package model import ( "time" "gorm.io/gorm" ) // Rock 相关常量 const ( // RockDefaultBaseURL 是 Rock 上游平台的默认地址,只作为「初始值 / 兜底值」。 // 运行期一律以 rock_configs.base_url 为准:启动时由 // RockService.ApplyConfigToClient 同步到 HTTP 客户端,否则后台改过的地址 // 会在进程重启后失效。 // // 注意:迁移文件 012_rock_fulfillment.sql 中的默认值受 checksum 保护, // 不能为了统一而修改它,否则已有部署会因 checksum mismatch 启动失败。 RockDefaultBaseURL = "https://0666.pro" RockColorBlack = "black" RockColorBlue = "blue" RockStatusAvailable = "available" // 可用库存 RockStatusUsing = "using" // 已分配给订单,正在提货扫码 RockStatusBound = "bound" // 扫码绑定成功 RockStatusRedeemed = "redeemed" // 发货完成 RockStatusMismatch = "mismatch" // UID 校验不符阻断(绑错) RockStatusAbnormal = "abnormal" // 异常/作废 RockSKUBlackTshirt = "rock_black_tshirt" RockSKUBlueSportswear = "rock_blue_sportswear" RockSkinBlackTshirt = "黑色ROCK长袖T恤" RockSkinBlueSportswear = "蓝色运动服上衣" ) // RockConfig 平台配置项 type RockConfig struct { ID uint `gorm:"primaryKey;default:1" json:"id"` AutoDeliveryEnabled bool `gorm:"not null;default:true" json:"auto_delivery_enabled"` // 全局自动发货总开关 BaseURL string `gorm:"size:255;not null;default:'https://0666.pro'" json:"base_url"` // 默认值见 RockDefaultBaseURL BearerToken string `gorm:"type:text;not null;default:''" json:"bearer_token"` Username string `gorm:"size:128;not null;default:''" json:"username"` Points float64 `gorm:"type:numeric(12,2);not null;default:0.00" json:"points"` MinPointsWarning float64 `gorm:"type:numeric(12,2);not null;default:1050.00" json:"min_points_warning"` BlackTokenCost float64 `gorm:"type:numeric(12,2);not null;default:20.00" json:"black_token_cost"` TokenWarningStock int `gorm:"not null;default:10" json:"token_warning_stock"` UsingWarnDays int `gorm:"not null;default:3" json:"using_warn_days"` // 使用中超过 N 天橙色预警 UsingDangerDays int `gorm:"not null;default:5" json:"using_danger_days"` // 使用中超过 N 天红色预警 AutoPurchaseEnabled bool `gorm:"not null;default:false" json:"auto_purchase_enabled"` AutoPurchaseCount int `gorm:"not null;default:50" json:"auto_purchase_count"` PurchaseCooldownMinutes int `gorm:"not null;default:10" json:"purchase_cooldown_minutes"` LastPurchasedAt *time.Time `json:"last_purchased_at"` LastAttemptAt *time.Time `json:"last_attempt_at,omitempty"` // 最近一次采购尝试(成功/失败)时间,用于失败冷却 LastError string `gorm:"type:text;not null;default:''" json:"last_error"` // 最近一次补货/打包错误,成功后清空 LastErrorAt *time.Time `json:"last_error_at,omitempty"` LastHeartbeatAt *time.Time `json:"last_heartbeat_at"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (RockConfig) TableName() string { return "rock_configs" } // RockToken 通用 Token 本地库存池记录 type RockToken struct { ID uint `gorm:"primaryKey" json:"id"` UpstreamTokenID string `gorm:"size:64;not null;default:''" json:"upstream_token_id"` Token string `gorm:"type:text;not null" json:"-"` RedeemCode string `gorm:"size:64;not null;index" json:"redeem_code"` Color string `gorm:"size:32;not null;default:'black';index" json:"color"` Region string `gorm:"size:64;not null;default:'Q/V可用'" json:"region"` Status string `gorm:"size:32;not null;default:'available';index" json:"status"` PackageID *int64 `gorm:"index" json:"package_id,omitempty"` PackageShareCode string `gorm:"size:64;not null;default:''" json:"package_share_code"` AssignedOrderNo string `gorm:"size:128;index" json:"assigned_order_no"` ClientOrderNo string `gorm:"-" json:"client_order_no,omitempty"` // 关联的创建订单商户单号 TokenCode string `gorm:"-" json:"token,omitempty"` // 提取码,仅管理端响应展示,不持久化 ExpectedUID string `gorm:"size:64" json:"expected_uid"` ActualRoleName string `gorm:"size:128" json:"actual_role_name"` ActualRoleID string `gorm:"size:64" json:"actual_role_id"` ActualChannel string `gorm:"size:64" json:"actual_channel"` InitialBoundSnapshot string `gorm:"type:text" json:"-"` // 分配时初始旧数据快照 JSON UpstreamFulfillID int64 `json:"upstream_fulfill_id"` TargetSkin string `gorm:"size:128" json:"target_skin"` TargetCurrency string `gorm:"size:64;not null;default:'幸运币'" json:"target_currency"` TargetCurrencyQuantity int `gorm:"not null;default:0" json:"target_currency_quantity"` MismatchAt *time.Time `gorm:"index" json:"mismatch_at"` MismatchReason string `gorm:"size:255" json:"mismatch_reason"` Remark string `gorm:"type:text;not null;default:''" json:"remark"` RawData string `gorm:"type:text;not null;default:''" json:"raw_data,omitempty"` Source string `gorm:"size:32;not null;default:'purchase';index" json:"source"` ClaimedAt *time.Time `json:"claimed_at"` UsingAt *time.Time `gorm:"index" json:"using_at"` // 变为 using 的时间,超时预警起点 BoundAt *time.Time `json:"bound_at"` RedeemedAt *time.Time `json:"redeemed_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` DeletedAtText string `gorm:"-" json:"deleted_at,omitempty"` // 回收站展示用,仅管理端响应返回 CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (RockToken) TableName() string { return "rock_tokens" } // RockPurchaseLog 是一次采购尝试的主记录。 // 每一次真正进入采购流程的尝试都会落一条,包含降级原因与各阶段汇总。 type RockPurchaseLog struct { ID uint `gorm:"primaryKey" json:"id"` TriggerType string `gorm:"size:16;not null;default:'auto';index:idx_rock_purchase_logs_trigger_status" json:"trigger_type"` // auto / manual Status string `gorm:"size:16;not null;default:'running'" json:"status"` // running / success / partial / failed / skipped RequestedCount int `gorm:"not null;default:0" json:"requested_count"` PlannedCount int `gorm:"not null;default:0" json:"planned_count"` ClaimedCount int `gorm:"not null;default:0" json:"claimed_count"` ImportedCount int `gorm:"not null;default:0" json:"imported_count"` UpstreamAvailable int `gorm:"not null;default:0" json:"upstream_available"` PointsBefore float64 `gorm:"type:numeric(12,2);not null;default:0" json:"points_before"` UnitCost float64 `gorm:"type:numeric(12,2);not null;default:0" json:"unit_cost"` MaxByPoints int `gorm:"not null;default:0" json:"max_by_points"` MaxByStock int `gorm:"not null;default:0" json:"max_by_stock"` LimitReason string `gorm:"size:32;not null;default:''" json:"limit_reason"` // points / upstream_stock / points_and_stock PointsSource string `gorm:"size:16;not null;default:''" json:"points_source"` // live / snapshot Stage string `gorm:"size:32;not null;default:''" json:"stage"` ErrorMessage string `gorm:"type:text;not null;default:''" json:"error_message"` PackageID *int64 `json:"package_id,omitempty"` ShareCode string `gorm:"size:64;not null;default:''" json:"share_code"` DurationMs int `gorm:"not null;default:0" json:"duration_ms"` StartedAt time.Time `json:"started_at"` FinishedAt *time.Time `json:"finished_at,omitempty"` CreatedAt time.Time `json:"created_at"` } func (RockPurchaseLog) TableName() string { return "rock_purchase_logs" } // RockPurchaseStage 记录一次采购中单个上游调用的原始请求与响应。 // ResponseBody 保存上游返回的原始 JSON 原文;超过 512KB 时截断并置 Truncated。 type RockPurchaseStage struct { ID uint `gorm:"primaryKey" json:"id"` LogID uint `gorm:"not null;index:idx_rock_purchase_stages_log_id" json:"log_id"` Seq int `gorm:"not null;default:0" json:"seq"` Stage string `gorm:"size:32;not null" json:"stage"` Method string `gorm:"size:8;not null;default:''" json:"method"` URL string `gorm:"type:text;not null;default:''" json:"url"` RequestBody string `gorm:"type:text;not null;default:''" json:"request_body"` HTTPStatus int `gorm:"not null;default:0" json:"http_status"` ResponseBody string `gorm:"type:text;not null;default:''" json:"response_body"` Truncated bool `gorm:"not null;default:false" json:"truncated"` DurationMs int `gorm:"not null;default:0" json:"duration_ms"` ErrorMessage string `gorm:"type:text;not null;default:''" json:"error_message"` CreatedAt time.Time `json:"created_at"` } func (RockPurchaseStage) TableName() string { return "rock_purchase_stages" }