128 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			128 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{},
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // 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
 | |
| }
 |