增加AreaControllerProperties
This commit is contained in:
@@ -3,6 +3,7 @@ package models
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
@@ -16,6 +17,11 @@ type Bus485Properties struct {
|
||||
BusAddress uint8 `json:"bus_address"` // 485 总线地址
|
||||
}
|
||||
|
||||
// AreaControllerProperties 定义了区域主控的特有属性
|
||||
type AreaControllerProperties struct {
|
||||
FirmwareVersion string `json:"firmware_version,omitempty"` // 主控程序版本
|
||||
}
|
||||
|
||||
// AreaController 是一个LoRa转总线(如485)的通信网关
|
||||
type AreaController struct {
|
||||
Model
|
||||
@@ -45,6 +51,29 @@ func (ac *AreaController) SelfCheck() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseProperties 解析 JSON 属性到一个具体的结构体中。
|
||||
// 调用方需要传入一个指向目标结构体实例的指针。
|
||||
func (ac *AreaController) ParseProperties(v interface{}) error {
|
||||
if ac.Properties == nil {
|
||||
return errors.New("区域主控属性为空,无法解析")
|
||||
}
|
||||
return json.Unmarshal(ac.Properties, v)
|
||||
}
|
||||
|
||||
// SetProperties 将一个结构体编码为 JSON 并设置到 Properties 字段。
|
||||
func (ac *AreaController) SetProperties(v interface{}) error {
|
||||
if v == nil {
|
||||
ac.Properties = nil
|
||||
return nil
|
||||
}
|
||||
jsonBytes, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("无法编码区域主控的属性 (Properties): %w", err)
|
||||
}
|
||||
ac.Properties = jsonBytes
|
||||
return nil
|
||||
}
|
||||
|
||||
// TableName 自定义 GORM 使用的数据库表名
|
||||
func (AreaController) TableName() string {
|
||||
return "area_controllers"
|
||||
|
||||
@@ -18,6 +18,8 @@ type AreaControllerRepository interface {
|
||||
Create(ctx context.Context, ac *models.AreaController) error
|
||||
ListAll(ctx context.Context) ([]*models.AreaController, error)
|
||||
Update(ctx context.Context, ac *models.AreaController) error
|
||||
// UpdateFirmwareVersion 更新指定ID的区域主控的固件版本号。
|
||||
UpdateFirmwareVersion(ctx context.Context, id uint32, version string) error
|
||||
Delete(ctx context.Context, id uint32) error
|
||||
// IsAreaControllerUsedByTasks 检查区域主控是否被特定任务类型使用,可以忽略指定任务类型
|
||||
IsAreaControllerUsedByTasks(ctx context.Context, areaControllerID uint32, ignoredTaskTypes []models.TaskType) (bool, error)
|
||||
@@ -59,6 +61,25 @@ func (r *gormAreaControllerRepository) Update(ctx context.Context, ac *models.Ar
|
||||
return r.db.WithContext(repoCtx).Save(ac).Error
|
||||
}
|
||||
|
||||
// UpdateFirmwareVersion 使用 jsonb_set 函数原子性地更新 properties 字段中的固件版本号。
|
||||
func (r *gormAreaControllerRepository) UpdateFirmwareVersion(ctx context.Context, id uint32, version string) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdateFirmwareVersion")
|
||||
|
||||
// 使用 gorm.Expr 包装 PostgreSQL 的 jsonb_set 函数
|
||||
// jsonb_set(properties, '{firmware_version}', '"new_version"', true)
|
||||
// 注意:jsonb_set 的第三个参数需要是有效的 JSON 值,所以字符串需要被双引号包围。
|
||||
jsonbExpr := gorm.Expr(`jsonb_set(COALESCE(properties, '{}'::jsonb), '{firmware_version}', ?::jsonb)`, fmt.Sprintf(`"%s"`, version))
|
||||
|
||||
result := r.db.WithContext(repoCtx).Model(&models.AreaController{}).Where("id = ?", id).Update("properties", jsonbExpr)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return fmt.Errorf("更新固件版本失败:未找到ID为 %d 的区域主控", id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除一个 AreaController 记录。
|
||||
func (r *gormAreaControllerRepository) Delete(ctx context.Context, id uint32) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "Delete")
|
||||
|
||||
Reference in New Issue
Block a user