package model import ( "database/sql/driver" "encoding/json" "time" "gorm.io/gorm" ) // PackageSnapshot 套餐快照,记录换卡时的套餐信息 type PackageSnapshot struct { PackageID uint `json:"package_id"` // 套餐ID PackageName string `json:"package_name"` // 套餐名称 PackageType string `json:"package_type"` // 套餐类型 DataQuota int64 `json:"data_quota"` // 流量额度(KB) DataUsed int64 `json:"data_used"` // 已使用流量(KB) ValidFrom time.Time `json:"valid_from"` // 生效时间 ValidTo time.Time `json:"valid_to"` // 失效时间 Price int64 `json:"price"` // 套餐价格(分) RemainingDays int `json:"remaining_days"` // 剩余天数 TransferReason string `json:"transfer_reason,omitempty"` // 转移原因 } // Value 实现 driver.Valuer 接口 func (p PackageSnapshot) Value() (driver.Value, error) { return json.Marshal(p) } // Scan 实现 sql.Scanner 接口 func (p *PackageSnapshot) Scan(value interface{}) error { if value == nil { return nil } bytes, ok := value.([]byte) if !ok { return nil } return json.Unmarshal(bytes, p) } // CardReplacementRecord 换卡记录模型 // 记录物联卡更换历史,包含套餐快照便于追溯 // 支持损坏、丢失、故障等多种换卡原因,需要审批流程 type CardReplacementRecord struct { gorm.Model BaseModel `gorm:"embedded"` ReplacementNo string `gorm:"column:replacement_no;type:varchar(50);not null;uniqueIndex:idx_card_replacement_no,where:deleted_at IS NULL;comment:换卡单号" json:"replacement_no"` OldCardID uint `gorm:"column:old_card_id;not null;index:idx_card_replacement_old_card;comment:老卡ID" json:"old_card_id"` OldIccid string `gorm:"column:old_iccid;type:varchar(50);not null;comment:老卡ICCID" json:"old_iccid"` NewCardID uint `gorm:"column:new_card_id;not null;index:idx_card_replacement_new_card;comment:新卡ID" json:"new_card_id"` NewIccid string `gorm:"column:new_iccid;type:varchar(50);not null;comment:新卡ICCID" json:"new_iccid"` OldOwnerType string `gorm:"column:old_owner_type;type:varchar(20);not null;index:idx_card_replacement_old_owner,priority:1;comment:老卡所有者类型" json:"old_owner_type"` OldOwnerID uint `gorm:"column:old_owner_id;not null;index:idx_card_replacement_old_owner,priority:2;comment:老卡所有者ID" json:"old_owner_id"` OldAgentID *uint `gorm:"column:old_agent_id;comment:老卡代理ID" json:"old_agent_id,omitempty"` NewOwnerType string `gorm:"column:new_owner_type;type:varchar(20);not null;index:idx_card_replacement_new_owner,priority:1;comment:新卡所有者类型" json:"new_owner_type"` NewOwnerID uint `gorm:"column:new_owner_id;not null;index:idx_card_replacement_new_owner,priority:2;comment:新卡所有者ID" json:"new_owner_id"` NewAgentID *uint `gorm:"column:new_agent_id;comment:新卡代理ID" json:"new_agent_id,omitempty"` PackageSnapshot *PackageSnapshot `gorm:"column:package_snapshot;type:jsonb;comment:套餐快照" json:"package_snapshot,omitempty"` ReplacementReason string `gorm:"column:replacement_reason;type:varchar(20);not null;comment:换卡原因 damaged-损坏 lost-丢失 malfunction-故障 upgrade-升级 other-其他" json:"replacement_reason"` Remark *string `gorm:"column:remark;type:text;comment:备注" json:"remark,omitempty"` Status int `gorm:"column:status;type:int;not null;default:1;index:idx_card_replacement_status;comment:换卡状态 1-待审批 2-已通过 3-已拒绝 4-已完成" json:"status"` ApprovedBy *uint `gorm:"column:approved_by;comment:审批人ID" json:"approved_by,omitempty"` ApprovedAt *time.Time `gorm:"column:approved_at;comment:审批时间" json:"approved_at,omitempty"` CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at,omitempty"` } // TableName 指定表名 func (CardReplacementRecord) TableName() string { return "tb_card_replacement_record" }