Files

160 lines
9.8 KiB
Go

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"
}