131 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package models
 | 
						|
 | 
						|
import (
 | 
						|
	"database/sql/driver"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// GetAllModels 返回一个包含所有数据库模型实例的切片。
 | 
						|
// 这个函数用于在数据库初始化时自动迁移所有的表结构。
 | 
						|
func GetAllModels() []interface{} {
 | 
						|
	return []interface{}{
 | 
						|
		// Core Models
 | 
						|
		&User{},
 | 
						|
		&UserActionLog{},
 | 
						|
 | 
						|
		// Device Models
 | 
						|
		&Device{},
 | 
						|
		&AreaController{},
 | 
						|
		&DeviceTemplate{},
 | 
						|
		&SensorData{},
 | 
						|
		&DeviceCommandLog{},
 | 
						|
 | 
						|
		// Plan & Task Models
 | 
						|
		&Plan{},
 | 
						|
		&SubPlan{},
 | 
						|
		&Task{},
 | 
						|
		&PlanExecutionLog{},
 | 
						|
		&TaskExecutionLog{},
 | 
						|
		&PendingTask{},
 | 
						|
		&PendingCollection{},
 | 
						|
 | 
						|
		// Farm Asset Models
 | 
						|
		&PigHouse{},
 | 
						|
		&Pen{},
 | 
						|
 | 
						|
		// Pig & Batch Models
 | 
						|
		&PigBatch{},
 | 
						|
		&PigBatchLog{},
 | 
						|
		&WeighingBatch{},
 | 
						|
		&WeighingRecord{},
 | 
						|
		&PigTransferLog{},
 | 
						|
		&PigSickLog{},
 | 
						|
 | 
						|
		// Pig Buy & Sell
 | 
						|
		&PigPurchase{},
 | 
						|
		&PigSale{},
 | 
						|
 | 
						|
		// Feed Models
 | 
						|
		&RawMaterial{},
 | 
						|
		&RawMaterialPurchase{},
 | 
						|
		&RawMaterialStockLog{},
 | 
						|
		&FeedFormula{},
 | 
						|
		&FeedFormulaComponent{},
 | 
						|
		&FeedUsageRecord{},
 | 
						|
 | 
						|
		// Medication Models
 | 
						|
		&Medication{},
 | 
						|
		&MedicationLog{},
 | 
						|
 | 
						|
		// Notification Models
 | 
						|
		&Notification{},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// UintArray 是一个自定义类型,代表 uint 的切片。
 | 
						|
// 它实现了 gorm.Scanner 和 driver.Valuer 接口,
 | 
						|
// 以便能与数据库的 bigint[] 类型进行原生映射。
 | 
						|
type UintArray []uint
 | 
						|
 | 
						|
// Value 实现了 driver.Valuer 接口。
 | 
						|
// 它告诉 GORM 如何将 UintArray ([]) 转换为数据库能够理解的格式。
 | 
						|
func (a UintArray) Value() (driver.Value, error) {
 | 
						|
	if a == nil {
 | 
						|
		return "{}", nil
 | 
						|
	}
 | 
						|
 | 
						|
	var b strings.Builder
 | 
						|
	b.WriteString("{")
 | 
						|
	for i, v := range a {
 | 
						|
		if i > 0 {
 | 
						|
			b.WriteString(",")
 | 
						|
		}
 | 
						|
		b.WriteString(strconv.FormatUint(uint64(v), 10))
 | 
						|
	}
 | 
						|
	b.WriteString("}")
 | 
						|
	return b.String(), nil
 | 
						|
}
 | 
						|
 | 
						|
// Scan 实现了 gorm.Scanner 接口。
 | 
						|
// 它告诉 GORM 如何将从数据库读取的数据转换为我们的 UintArray ([])。
 | 
						|
func (a *UintArray) Scan(src interface{}) error {
 | 
						|
	if src == nil {
 | 
						|
		*a = nil
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	var srcStr string
 | 
						|
	switch v := src.(type) {
 | 
						|
	case []byte:
 | 
						|
		srcStr = string(v)
 | 
						|
	case string:
 | 
						|
		srcStr = v
 | 
						|
	default:
 | 
						|
		return errors.New("无法扫描非字符串或字节类型的源到 UintArray")
 | 
						|
	}
 | 
						|
 | 
						|
	// 去掉花括号
 | 
						|
	srcStr = strings.Trim(srcStr, "{}")
 | 
						|
	if srcStr == "" {
 | 
						|
		*a = []uint{}
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	// 按逗号分割
 | 
						|
	parts := strings.Split(srcStr, ",")
 | 
						|
	arr := make([]uint, len(parts))
 | 
						|
	for i, p := range parts {
 | 
						|
		val, err := strconv.ParseUint(p, 10, 64)
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("解析 UintArray 元素失败: %w", err)
 | 
						|
		}
 | 
						|
		arr[i] = uint(val)
 | 
						|
	}
 | 
						|
 | 
						|
	*a = arr
 | 
						|
	return nil
 | 
						|
}
 |