package model import ( "database/sql/driver" "encoding/json" "time" "github.com/google/uuid" "gorm.io/gorm" ) // MaterialFileType 文件类型 type MaterialFileType string const ( MaterialFileTypePDF MaterialFileType = "pdf" MaterialFileTypeWord MaterialFileType = "word" MaterialFileTypePPT MaterialFileType = "ppt" ) // MaterialStatus 资料状态 type MaterialStatus string const ( MaterialStatusActive MaterialStatus = "active" MaterialStatusInactive MaterialStatus = "inactive" ) // MaterialSubject 学科分类 type MaterialSubject struct { ID string `json:"id" gorm:"type:varchar(36);primaryKey"` Name string `json:"name" gorm:"type:varchar(100);not null"` Icon string `json:"icon" gorm:"type:varchar(50)"` // MaterialCommunityIcons name Color string `json:"color" gorm:"type:varchar(20)"` // 主题色 Description string `json:"description" gorm:"type:varchar(255)"` // 描述 SortOrder int `json:"sort_order" gorm:"default:0;index"` // 排序权重 IsActive bool `json:"is_active" gorm:"default:true;index"` // 是否启用 CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` // 关联 Materials []MaterialFile `json:"materials,omitempty" gorm:"foreignKey:SubjectID"` } // BeforeCreate 创建前生成UUID func (s *MaterialSubject) BeforeCreate(tx *gorm.DB) error { if s.ID == "" { s.ID = uuid.New().String() } return nil } func (MaterialSubject) TableName() string { return "material_subjects" } // StringArray 字符串数组类型(用于tags) type StringArray []string // Value 实现 driver.Valuer 接口 func (a StringArray) Value() (driver.Value, error) { if a == nil { return nil, nil } return json.Marshal(a) } // Scan 实现 sql.Scanner 接口 func (a *StringArray) Scan(value any) error { if value == nil { *a = nil return nil } var data []byte switch v := value.(type) { case []byte: data = v case string: data = []byte(v) default: return nil } return json.Unmarshal(data, a) } // MaterialFile 文件资料 type MaterialFile struct { ID string `json:"id" gorm:"type:varchar(36);primaryKey"` SubjectID string `json:"subject_id" gorm:"type:varchar(36);index;not null"` Title string `json:"title" gorm:"type:varchar(200);not null"` Description string `json:"description" gorm:"type:text"` FileType MaterialFileType `json:"file_type" gorm:"type:varchar(20);not null;index"` FileSize int64 `json:"file_size" gorm:"default:0"` // 文件大小(字节) FileURL string `json:"file_url" gorm:"type:text;not null"` // 文件URL FileName string `json:"file_name" gorm:"type:varchar(255)"` // 原始文件名 DownloadCount int `json:"download_count" gorm:"default:0"` // 下载次数 AuthorID string `json:"author_id" gorm:"type:varchar(36);index"` // 上传者ID Tags StringArray `json:"tags" gorm:"type:json"` // 标签 Status MaterialStatus `json:"status" gorm:"type:varchar(20);default:active;index"` // 状态 CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime;index"` UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` // 关联 Subject *MaterialSubject `json:"subject,omitempty" gorm:"foreignKey:SubjectID"` Author *User `json:"author,omitempty" gorm:"foreignKey:AuthorID"` } // BeforeCreate 创建前生成UUID func (f *MaterialFile) BeforeCreate(tx *gorm.DB) error { if f.ID == "" { f.ID = uuid.New().String() } return nil } func (MaterialFile) TableName() string { return "material_files" }