1. 增加自检

2. 去掉device的gin索引
This commit is contained in:
2025-09-29 17:06:21 +08:00
parent facbbfe6a1
commit 1df1bf2e75
2 changed files with 47 additions and 13 deletions

View File

@@ -240,13 +240,13 @@ func (ps *PostgresStorage) creatingIndex() error {
ps.logger.Info("成功为 tasks 的 parameters 字段创建 GIN 索引 (或已存在)") ps.logger.Info("成功为 tasks 的 parameters 字段创建 GIN 索引 (或已存在)")
// 为 devices 表的 properties 字段创建 GIN 索引 // 为 devices 表的 properties 字段创建 GIN 索引
ps.logger.Info("正在为 devices 表的 properties 字段创建 GIN 索引") //ps.logger.Info("正在为 devices 表的 properties 字段创建 GIN 索引")
ginDevicePropertiesIndexSQL := "CREATE INDEX IF NOT EXISTS idx_devices_properties_gin ON devices USING GIN (properties);" //ginDevicePropertiesIndexSQL := "CREATE INDEX IF NOT EXISTS idx_devices_properties_gin ON devices USING GIN (properties);"
if err := ps.db.Exec(ginDevicePropertiesIndexSQL).Error; err != nil { //if err := ps.db.Exec(ginDevicePropertiesIndexSQL).Error; err != nil {
ps.logger.Errorw("为 devices 的 properties 字段创建 GIN 索引失败", "error", err) // ps.logger.Errorw("为 devices 的 properties 字段创建 GIN 索引失败", "error", err)
return fmt.Errorf("为 devices 的 properties 字段创建 GIN 索引失败: %w", err) // return fmt.Errorf("为 devices 的 properties 字段创建 GIN 索引失败: %w", err)
} //}
ps.logger.Info("成功为 devices 的 properties 字段创建 GIN 索引 (或已存在)") //ps.logger.Info("成功为 devices 的 properties 字段创建 GIN 索引 (或已存在)")
return nil return nil
} }

View File

@@ -3,6 +3,7 @@ package models
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"strings"
"gorm.io/datatypes" "gorm.io/datatypes"
"gorm.io/gorm" "gorm.io/gorm"
@@ -31,7 +32,6 @@ type LoraProperties struct {
type BusProperties struct { type BusProperties struct {
BusID int `json:"bus_id"` // 485 总线号 BusID int `json:"bus_id"` // 485 总线号
BusAddress int `json:"bus_address"` // 485 总线地址 BusAddress int `json:"bus_address"` // 485 总线地址
RelayChannel int `json:"relay_channel"` // 继电器通道号
} }
// AreaController 是一个LoRa转总线(如485)的通信网关 // AreaController 是一个LoRa转总线(如485)的通信网关
@@ -55,6 +55,14 @@ type AreaController struct {
Properties datatypes.JSON `json:"properties"` Properties datatypes.JSON `json:"properties"`
} }
// SelfCheck 对 AreaController 的关键字段进行业务逻辑验证。
func (ac *AreaController) SelfCheck() error {
if strings.TrimSpace(ac.NetworkID) == "" {
return errors.New("区域主控的 NetworkID 不能为空")
}
return nil
}
// TableName 自定义 GORM 使用的数据库表名 // TableName 自定义 GORM 使用的数据库表名
func (AreaController) TableName() string { func (AreaController) TableName() string {
return "area_controllers" return "area_controllers"
@@ -68,9 +76,6 @@ type Device struct {
// Name 是设备的业务名称,应清晰可读,例如 "1号猪舍温度传感器" // Name 是设备的业务名称,应清晰可读,例如 "1号猪舍温度传感器"
Name string `gorm:"not null" json:"name"` Name string `gorm:"not null" json:"name"`
// Location 描述了设备的物理安装位置,例如 "1号猪舍东侧",方便运维。建立索引以优化按位置查询。
Location string `gorm:"index" json:"location"`
// DeviceTemplateID 是设备模板的外键 // DeviceTemplateID 是设备模板的外键
DeviceTemplateID uint `gorm:"not null;index" json:"device_template_id"` DeviceTemplateID uint `gorm:"not null;index" json:"device_template_id"`
@@ -83,11 +88,40 @@ type Device struct {
// AreaController 是设备所属的区域主控 // AreaController 是设备所属的区域主控
AreaController AreaController `json:"area_controller"` AreaController AreaController `json:"area_controller"`
// Location 描述了设备的物理安装位置,例如 "1号猪舍东侧",方便运维。建立索引以优化按位置查询。
Location string `gorm:"index" json:"location"`
// Properties 用于存储特定类型设备的独有属性采用JSON格式。 // Properties 用于存储特定类型设备的独有属性采用JSON格式。
// 建议在应用层为不同子类型的设备定义专用的属性结构体(如 LoraProperties, BusProperties以保证数据一致性。 // 建议在应用层为不同子类型的设备定义专用的属性结构体(如 LoraProperties, BusProperties以保证数据一致性。
Properties datatypes.JSON `json:"properties"` Properties datatypes.JSON `json:"properties"`
} }
// SelfCheck 对 Device 的关键字段和属性进行业务逻辑验证。
func (d *Device) SelfCheck() error {
if d.AreaControllerID == 0 {
return errors.New("设备必须关联一个区域主控 (AreaControllerID不能为0)")
}
if d.DeviceTemplateID == 0 {
return errors.New("设备必须关联一个设备模板 (DeviceTemplateID不能为0)")
}
// 验证 Properties 是否包含必要的总线地址信息
if d.Properties == nil {
return errors.New("设备属性 (Properties) 不能为空")
}
var props map[string]interface{}
if err := json.Unmarshal(d.Properties, &props); err != nil {
return errors.New("无法解析设备属性 (Properties)")
}
if _, ok := props[BusAddress]; !ok {
return errors.New("设备属性 (Properties) 中缺少总线地址 (bus_address)")
}
return nil
}
// TableName 自定义 GORM 使用的数据库表名 // TableName 自定义 GORM 使用的数据库表名
func (Device) TableName() string { func (Device) TableName() string {
return "devices" return "devices"