231 lines
9.5 KiB
Go
231 lines
9.5 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"database/sql/driver"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// =============================================================================
|
|
// LaserCardTemplate — 镭射卡预设模板表
|
|
// =============================================================================
|
|
|
|
// LaserCardTemplate 镭射卡预设模板
|
|
type LaserCardTemplate struct {
|
|
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
|
TemplateCode string `gorm:"type:varchar(64);not null;uniqueIndex:uk_lct_code_version;column:template_code"`
|
|
Name string `gorm:"type:varchar(100);not null;column:name"`
|
|
Description *string `gorm:"type:text;column:description"`
|
|
Status string `gorm:"type:varchar(20);not null;default:'published';index:idx_lct_status_star;column:status"`
|
|
Version int `gorm:"not null;default:1;uniqueIndex:uk_lct_code_version;column:version"`
|
|
ThumbnailOssKey *string `gorm:"type:varchar(255);column:thumbnail_oss_key"`
|
|
BackdropOptions LaserCardBackdropOptions `gorm:"type:jsonb;not null;default:'[]';column:backdrop_options"`
|
|
RenderConfig json.RawMessage `gorm:"type:jsonb;not null;default:'{}';column:render_config"`
|
|
EngineMinVersion string `gorm:"type:varchar(32);not null;default:'compositor-1.0.0';column:engine_min_version"`
|
|
SortOrder int `gorm:"not null;default:0;column:sort_order"`
|
|
StarID int64 `gorm:"not null;default:0;index:idx_lct_status_star;column:star_id"`
|
|
CreatedBy int64 `gorm:"not null;default:0;column:created_by"`
|
|
CreatedAt int64 `gorm:"not null;column:created_at"`
|
|
UpdatedAt int64 `gorm:"not null;column:updated_at"`
|
|
DeletedAt *int64 `gorm:"index;column:deleted_at"`
|
|
}
|
|
|
|
func (LaserCardTemplate) TableName() string { return "laser_card_templates" }
|
|
|
|
func (t *LaserCardTemplate) BeforeCreate(tx *gorm.DB) error {
|
|
now := time.Now().UnixMilli()
|
|
t.CreatedAt = now
|
|
t.UpdatedAt = now
|
|
return nil
|
|
}
|
|
|
|
func (t *LaserCardTemplate) BeforeUpdate(tx *gorm.DB) error {
|
|
t.UpdatedAt = time.Now().UnixMilli()
|
|
return nil
|
|
}
|
|
|
|
// LaserCardBackdropOption 底纹选项
|
|
type LaserCardBackdropOption struct {
|
|
ID string `json:"id"`
|
|
Label string `json:"label"`
|
|
OssKey string `json:"oss_key"`
|
|
}
|
|
|
|
// LaserCardBackdropOptions 底纹选项 JSON 数组
|
|
type LaserCardBackdropOptions []LaserCardBackdropOption
|
|
|
|
// Scan 实现 sql.Scanner
|
|
func (b *LaserCardBackdropOptions) Scan(value interface{}) error {
|
|
if value == nil {
|
|
*b = LaserCardBackdropOptions{}
|
|
return nil
|
|
}
|
|
bytes, ok := value.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("failed to scan LaserCardBackdropOptions: %v", value)
|
|
}
|
|
return json.Unmarshal(bytes, b)
|
|
}
|
|
|
|
// Value 实现 driver.Valuer
|
|
func (b LaserCardBackdropOptions) Value() (driver.Value, error) {
|
|
if b == nil {
|
|
return "[]", nil
|
|
}
|
|
return json.Marshal(b)
|
|
}
|
|
|
|
// 模板状态常量
|
|
const (
|
|
LaserCardTemplateStatusPublished = "published"
|
|
LaserCardTemplateStatusArchived = "archived"
|
|
)
|
|
|
|
// =============================================================================
|
|
// LaserCardInstance — 镭射卡业务实例表
|
|
// =============================================================================
|
|
|
|
// LaserCardInstance 镭射卡业务实例
|
|
type LaserCardInstance struct {
|
|
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
|
InstanceNo string `gorm:"type:varchar(32);not null;uniqueIndex:uk_lci_instance_no;column:instance_no"`
|
|
InstanceUlid string `gorm:"type:varchar(40);not null;uniqueIndex:uk_lci_instance_ulid;column:instance_ulid"`
|
|
TemplateID int64 `gorm:"not null;column:template_id"`
|
|
TemplateCode string `gorm:"type:varchar(64);not null;column:template_code"`
|
|
TemplateVersion int `gorm:"not null;column:template_version"`
|
|
OwnerUserID int64 `gorm:"not null;index:idx_lci_owner_status;column:owner_user_id"`
|
|
StarID int64 `gorm:"not null;index:idx_lci_star_created;column:star_id"`
|
|
Status string `gorm:"type:varchar(20);not null;default:'rendered';index:idx_lci_owner_status;column:status"`
|
|
ClientRequestID *string `gorm:"type:varchar(64);column:client_request_id"`
|
|
RenderConfig json.RawMessage `gorm:"type:jsonb;column:render_config"`
|
|
MaterialsSnapshot MaterialsSnapshot `gorm:"type:jsonb;not null;default:'[]';column:materials_snapshot"`
|
|
CompositeOssKey *string `gorm:"type:varchar(255);column:composite_oss_key"`
|
|
CompositeMaterialID *int64 `gorm:"column:composite_material_id"`
|
|
AssetID *int64 `gorm:"index:idx_lci_asset;column:asset_id"`
|
|
MintOrderID *string `gorm:"type:varchar(100);column:mint_order_id"`
|
|
IdempotencyKey *string `gorm:"type:varchar(64);column:idempotency_key"`
|
|
Version int `gorm:"not null;default:1;column:version"`
|
|
CreatedAt int64 `gorm:"not null;column:created_at"`
|
|
UpdatedAt int64 `gorm:"not null;column:updated_at"`
|
|
DeletedAt *int64 `gorm:"index;column:deleted_at"`
|
|
|
|
Template LaserCardTemplate `gorm:"foreignKey:TemplateID;references:ID;constraint:OnDelete:RESTRICT"`
|
|
}
|
|
|
|
func (LaserCardInstance) TableName() string { return "laser_card_instances" }
|
|
|
|
func (i *LaserCardInstance) BeforeCreate(tx *gorm.DB) error {
|
|
now := time.Now().UnixMilli()
|
|
i.CreatedAt = now
|
|
i.UpdatedAt = now
|
|
|
|
if i.InstanceNo == "" {
|
|
i.InstanceNo = generateInstanceNo(now)
|
|
}
|
|
if i.InstanceUlid == "" {
|
|
i.InstanceUlid = "lc_inst_" + i.InstanceNo
|
|
}
|
|
if i.Status == "" {
|
|
i.Status = LaserCardInstanceStatusRendered
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (i *LaserCardInstance) BeforeUpdate(tx *gorm.DB) error {
|
|
i.UpdatedAt = time.Now().UnixMilli()
|
|
return nil
|
|
}
|
|
|
|
// generateInstanceNo 生成 LC + yyyyMMddHHmmss + 6位随机的单号
|
|
func generateInstanceNo(now int64) string {
|
|
t := time.UnixMilli(now)
|
|
ts := t.Format("20060102150405")
|
|
r := rand.Intn(900000) + 100000
|
|
return fmt.Sprintf("LC%s%d", ts, r)
|
|
}
|
|
|
|
// MaterialSnapshotItem 素材快照单项
|
|
type MaterialSnapshotItem struct {
|
|
Role string `json:"role"` // source | cutout | backdrop | composite
|
|
OssKey string `json:"oss_key"`
|
|
Hash string `json:"hash,omitempty"`
|
|
Width int `json:"width,omitempty"`
|
|
Height int `json:"height,omitempty"`
|
|
MimeType string `json:"mime_type,omitempty"`
|
|
FileSize int64 `json:"file_size,omitempty"`
|
|
PresetID string `json:"preset_id,omitempty"` // 仅 composite 需要
|
|
}
|
|
|
|
// MaterialsSnapshot 素材快照 JSON 数组
|
|
type MaterialsSnapshot []MaterialSnapshotItem
|
|
|
|
func (m *MaterialsSnapshot) Scan(value interface{}) error {
|
|
if value == nil {
|
|
*m = MaterialsSnapshot{}
|
|
return nil
|
|
}
|
|
bytes, ok := value.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("failed to scan MaterialsSnapshot: %v", value)
|
|
}
|
|
return json.Unmarshal(bytes, m)
|
|
}
|
|
|
|
func (m MaterialsSnapshot) Value() (driver.Value, error) {
|
|
if m == nil {
|
|
return "[]", nil
|
|
}
|
|
return json.Marshal(m)
|
|
}
|
|
|
|
// 实例状态常量
|
|
const (
|
|
LaserCardInstanceStatusRendered = "rendered" // 已选卡,未铸造
|
|
LaserCardInstanceStatusMinting = "minting" // 铸造中
|
|
LaserCardInstanceStatusMinted = "minted" // 铸造完成
|
|
)
|
|
|
|
// =============================================================================
|
|
// LaserCardOperationLog — 镭射卡操作日志表
|
|
// =============================================================================
|
|
|
|
// LaserCardOperationLog 镭射卡操作审计日志
|
|
type LaserCardOperationLog struct {
|
|
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
|
InstanceID int64 `gorm:"not null;index:idx_lclog_instance_time;column:instance_id"`
|
|
InstanceNo string `gorm:"type:varchar(32);not null;column:instance_no"`
|
|
OperatorUserID int64 `gorm:"not null;index:idx_lclog_operator_time;column:operator_user_id"`
|
|
Action string `gorm:"type:varchar(50);not null;index:idx_lclog_action_time;column:action"`
|
|
StatusBefore *string `gorm:"type:varchar(20);column:status_before"`
|
|
StatusAfter *string `gorm:"type:varchar(20);column:status_after"`
|
|
RequestID *string `gorm:"type:varchar(64);column:request_id"`
|
|
PayloadJSON json.RawMessage `gorm:"type:jsonb;column:payload_json"`
|
|
ResultJSON json.RawMessage `gorm:"type:jsonb;column:result_json"`
|
|
IPAddress *string `gorm:"type:varchar(45);column:ip_address"`
|
|
UserAgent *string `gorm:"type:varchar(255);column:user_agent"`
|
|
LatencyMs *int `gorm:"column:latency_ms"`
|
|
ErrCode *string `gorm:"type:varchar(32);column:err_code"`
|
|
CreatedAt int64 `gorm:"not null;column:created_at"`
|
|
}
|
|
|
|
func (LaserCardOperationLog) TableName() string { return "laser_card_operation_logs" }
|
|
|
|
func (l *LaserCardOperationLog) BeforeCreate(tx *gorm.DB) error {
|
|
l.CreatedAt = time.Now().UnixMilli()
|
|
return nil
|
|
}
|
|
|
|
// 操作动作常量
|
|
const (
|
|
LaserCardActionCreateInstance = "create_instance"
|
|
LaserCardActionGenerateVariants = "generate_variants"
|
|
LaserCardActionMintStart = "mint_start"
|
|
LaserCardActionMintSuccess = "mint_success"
|
|
LaserCardActionMintFail = "mint_fail"
|
|
)
|