1. 增加自检
2. 去掉device的gin索引
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user