Enhance Scan methods in StringArray, ExtraData, MessageSegments, and SystemNotificationExtra to accept both []byte and string types from database. Uses type switch for more flexible type handling.
119 lines
3.8 KiB
Go
119 lines
3.8 KiB
Go
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"
|
||
}
|