package model import ( "database/sql/driver" "encoding/json" "time" "gorm.io/gorm" ) type IotCardImportTask struct { gorm.Model BaseModel `gorm:"embedded"` TaskNo string `gorm:"column:task_no;type:varchar(50);uniqueIndex:idx_import_task_no,where:deleted_at IS NULL;not null;comment:任务编号(IMP-YYYYMMDD-XXXXXX)" json:"task_no"` Status int `gorm:"column:status;type:int;default:1;not null;comment:任务状态 1-待处理 2-处理中 3-已完成 4-失败" json:"status"` CarrierID uint `gorm:"column:carrier_id;index;not null;comment:运营商ID" json:"carrier_id"` CarrierType string `gorm:"column:carrier_type;type:varchar(20);not null;comment:运营商类型(CMCC/CUCC/CTCC/CBN)" json:"carrier_type"` BatchNo string `gorm:"column:batch_no;type:varchar(100);comment:批次号" json:"batch_no"` FileName string `gorm:"column:file_name;type:varchar(255);comment:原始文件名" json:"file_name"` TotalCount int `gorm:"column:total_count;type:int;default:0;not null;comment:总数" json:"total_count"` SuccessCount int `gorm:"column:success_count;type:int;default:0;not null;comment:成功数" json:"success_count"` SkipCount int `gorm:"column:skip_count;type:int;default:0;not null;comment:跳过数" json:"skip_count"` FailCount int `gorm:"column:fail_count;type:int;default:0;not null;comment:失败数" json:"fail_count"` SkippedItems ImportResultItems `gorm:"column:skipped_items;type:jsonb;comment:跳过记录详情" json:"skipped_items"` FailedItems ImportResultItems `gorm:"column:failed_items;type:jsonb;comment:失败记录详情" json:"failed_items"` StartedAt *time.Time `gorm:"column:started_at;comment:开始处理时间" json:"started_at"` CompletedAt *time.Time `gorm:"column:completed_at;comment:完成时间" json:"completed_at"` ErrorMessage string `gorm:"column:error_message;type:text;comment:任务级错误信息" json:"error_message"` ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(发起导入的店铺)" json:"shop_id,omitempty"` CardList CardListJSON `gorm:"column:card_list;type:jsonb;comment:待导入卡列表[{iccid,msisdn}]" json:"-"` StorageBucket string `gorm:"column:storage_bucket;type:varchar(100);comment:对象存储桶名" json:"storage_bucket,omitempty"` StorageKey string `gorm:"column:storage_key;type:varchar(500);comment:对象存储文件路径" json:"storage_key,omitempty"` } // CardItem 卡信息(ICCID + MSISDN) type CardItem struct { ICCID string `json:"iccid"` MSISDN string `json:"msisdn"` } type CardListJSON []CardItem func (list CardListJSON) Value() (driver.Value, error) { if list == nil { return "[]", nil } return json.Marshal(list) } func (list *CardListJSON) Scan(value any) error { if value == nil { *list = CardListJSON{} return nil } bytes, ok := value.([]byte) if !ok { return nil } return json.Unmarshal(bytes, list) } func (IotCardImportTask) TableName() string { return "tb_iot_card_import_task" } type ImportResultItem struct { Line int `json:"line"` ICCID string `json:"iccid"` MSISDN string `json:"msisdn,omitempty"` Reason string `json:"reason"` } type ImportResultItems []ImportResultItem func (items ImportResultItems) Value() (driver.Value, error) { if items == nil { return "[]", nil } return json.Marshal(items) } func (items *ImportResultItems) Scan(value any) error { if value == nil { *items = ImportResultItems{} return nil } bytes, ok := value.([]byte) if !ok { return nil } return json.Unmarshal(bytes, items) } const ( ImportTaskStatusPending = 1 ImportTaskStatusProcessing = 2 ImportTaskStatusCompleted = 3 ImportTaskStatusFailed = 4 )