3.7 KiB
3.7 KiB
设备与任务多对多关联模型设计
需求背景
用户需要为系统中的“设备”和“任务”增加多对多关联,即一个设备可以执行多个任务,一个任务可以被多个设备执行。
现有模型分析
internal/infra/models/device.go
Device 模型定义:
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 模型定义:
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 的标准模型字段。
// 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。
// 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。
// Task 代表计划中的一个任务,具有执行顺序
type Task struct {
// ... 其他现有字段 ...
// Devices 是与此任务关联的设备列表,通过 DeviceTask 关联表实现多对多关系
Devices []Device `gorm:"many2many:device_tasks;" json:"devices"`
}
总结
通过上述修改,我们将在数据库中创建一个名为 device_tasks 的中间表,用于存储 Device 和 Task 之间的关联关系。在 Go 代码层面,Device 和 Task 模型将能够直接通过 Tasks 和 Devices 字段进行多对多关系的查询和操作。