# 设备与任务多对多关联模型设计 ## 需求背景 用户需要为系统中的“设备”和“任务”增加多对多关联,即一个设备可以执行多个任务,一个任务可以被多个设备执行。 ## 现有模型分析 ### `internal/infra/models/device.go` `Device` 模型定义: ```go type Device struct { gorm.Model Name string `gorm:"not null" json:"name"` DeviceTemplateID uint `gorm:"not null;index" json:"device_template_id"` DeviceTemplate DeviceTemplate `json:"device_template"` AreaControllerID uint `gorm:"not null;index" json:"area_controller_id"` AreaController AreaController `json:"area_controller"` Location string `gorm:"index" json:"location"` Properties datatypes.JSON `json:"properties"` } ``` ### `internal/infra/models/plan.go` `Task` 模型定义: ```go type Task struct { ID int `gorm:"primarykey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` PlanID uint `gorm:"not null;index" json:"plan_id"` Name string `gorm:"not null" json:"name"` Description string `json:"description"` ExecutionOrder int `gorm:"not null" json:"execution_order"` Type TaskType `gorm:"not null" json:"type"` Parameters datatypes.JSON `json:"parameters"` } ``` ## 方案设计 为了实现设备和任务的多对多关系,我们将引入一个中间关联模型 `DeviceTask`。考虑到 `Task` 模型定义在 `plan.go` 中,为了保持相关模型的内聚性,我们将 `DeviceTask` 模型也定义在 `internal/infra/models/plan.go` 文件中。 ### 1. 在 `internal/infra/models/plan.go` 中新增 `DeviceTask` 关联模型 `DeviceTask` 模型将包含 `DeviceID` 和 `TaskID` 作为外键,以及 GORM 的标准模型字段。 ```go // DeviceTask 是设备和任务之间的关联模型,表示一个设备可以执行多个任务,一个任务可以被多个设备执行。 type DeviceTask struct { gorm.Model DeviceID uint `gorm:"not null;index"` // 设备ID TaskID uint `gorm:"not null;index"` // 任务ID // 可选:如果需要存储关联的额外信息,可以在这里添加字段,例如: // Configuration datatypes.JSON `json:"configuration"` // 任务在特定设备上的配置 } // TableName 自定义 GORM 使用的数据库表名 func (DeviceTask) TableName() string { return "device_tasks" } ``` ### 2. 修改 `internal/infra/models/device.go` 在 `Device` 结构体中添加 `Tasks` 字段,通过 `gorm:"many2many:device_tasks;"` 标签声明与 `Task` 的多对多关系,并指定中间表名为 `device_tasks`。 ```go // Device 代表系统中的所有普通设备 type Device struct { gorm.Model // ... 其他现有字段 ... // Tasks 是与此设备关联的任务列表,通过 DeviceTask 关联表实现多对多关系 Tasks []Task `gorm:"many2many:device_tasks;" json:"tasks"` } ``` ### 3. 修改 `internal/infra/models/plan.go` 在 `Task` 结构体中添加 `Devices` 字段,通过 `gorm:"many2many:device_tasks;"` 标签声明与 `Device` 的多对多关系,并指定中间表名为 `device_tasks`。 ```go // Task 代表计划中的一个任务,具有执行顺序 type Task struct { // ... 其他现有字段 ... // Devices 是与此任务关联的设备列表,通过 DeviceTask 关联表实现多对多关系 Devices []Device `gorm:"many2many:device_tasks;" json:"devices"` } ``` ## 总结 通过上述修改,我们将在数据库中创建一个名为 `device_tasks` 的中间表,用于存储 `Device` 和 `Task` 之间的关联关系。在 Go 代码层面,`Device` 和 `Task` 模型将能够直接通过 `Tasks` 和 `Devices` 字段进行多对多关系的查询和操作。