2025-09-29 19:17:42 +08:00
|
|
|
|
package repository
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2025-11-05 23:00:07 +08:00
|
|
|
|
"context"
|
2025-09-30 15:25:07 +08:00
|
|
|
|
"fmt"
|
2025-11-10 21:14:36 +08:00
|
|
|
|
"strconv"
|
2025-09-30 15:25:07 +08:00
|
|
|
|
|
2025-11-05 23:00:07 +08:00
|
|
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
2025-09-29 19:17:42 +08:00
|
|
|
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
2025-11-05 23:00:07 +08:00
|
|
|
|
|
2025-09-29 19:17:42 +08:00
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// AreaControllerRepository 定义了对 AreaController 模型的数据库操作接口
|
|
|
|
|
|
type AreaControllerRepository interface {
|
2025-11-05 23:00:07 +08:00
|
|
|
|
FindByID(ctx context.Context, id uint) (*models.AreaController, error)
|
|
|
|
|
|
FindByNetworkID(ctx context.Context, networkID string) (*models.AreaController, error)
|
|
|
|
|
|
Create(ctx context.Context, ac *models.AreaController) error
|
|
|
|
|
|
ListAll(ctx context.Context) ([]*models.AreaController, error)
|
|
|
|
|
|
Update(ctx context.Context, ac *models.AreaController) error
|
|
|
|
|
|
Delete(ctx context.Context, id uint) error
|
2025-11-10 21:14:36 +08:00
|
|
|
|
// IsAreaControllerUsedByTasks 检查区域主控是否被特定任务类型使用,可以忽略指定任务类型
|
|
|
|
|
|
IsAreaControllerUsedByTasks(ctx context.Context, areaControllerID uint, ignoredTaskTypes []models.TaskType) (bool, error)
|
2025-09-29 19:17:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// gormAreaControllerRepository 是 AreaControllerRepository 的 GORM 实现。
|
|
|
|
|
|
type gormAreaControllerRepository struct {
|
2025-11-05 23:00:07 +08:00
|
|
|
|
ctx context.Context
|
|
|
|
|
|
db *gorm.DB
|
2025-09-29 19:17:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewGormAreaControllerRepository 创建一个新的 AreaControllerRepository GORM 实现实例。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func NewGormAreaControllerRepository(ctx context.Context, db *gorm.DB) AreaControllerRepository {
|
|
|
|
|
|
return &gormAreaControllerRepository{
|
|
|
|
|
|
ctx: ctx,
|
|
|
|
|
|
db: db,
|
|
|
|
|
|
}
|
2025-09-29 19:17:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-30 15:25:07 +08:00
|
|
|
|
// Create 创建一个新的 AreaController 记录。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) Create(ctx context.Context, ac *models.AreaController) error {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "Create")
|
|
|
|
|
|
return r.db.WithContext(repoCtx).Create(ac).Error
|
2025-09-30 15:25:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ListAll 返回所有 AreaController 的列表。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) ListAll(ctx context.Context) ([]*models.AreaController, error) {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListAll")
|
2025-09-30 15:25:07 +08:00
|
|
|
|
var areaControllers []*models.AreaController
|
2025-11-05 23:00:07 +08:00
|
|
|
|
if err := r.db.WithContext(repoCtx).Find(&areaControllers).Error; err != nil {
|
2025-09-30 15:25:07 +08:00
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return areaControllers, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update 更新一个已存在的 AreaController 记录。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) Update(ctx context.Context, ac *models.AreaController) error {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "Update")
|
|
|
|
|
|
return r.db.WithContext(repoCtx).Save(ac).Error
|
2025-09-30 15:25:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Delete 删除一个 AreaController 记录。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) Delete(ctx context.Context, id uint) error {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "Delete")
|
|
|
|
|
|
if err := r.db.WithContext(repoCtx).Delete(&models.AreaController{}, id).Error; err != nil {
|
2025-11-03 17:11:51 +08:00
|
|
|
|
return fmt.Errorf("删除区域主控失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
2025-09-30 15:25:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-29 19:17:42 +08:00
|
|
|
|
// FindByID 通过 ID 查找一个 AreaController。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) FindByID(ctx context.Context, id uint) (*models.AreaController, error) {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindByID")
|
2025-09-29 19:17:42 +08:00
|
|
|
|
var areaController models.AreaController
|
2025-11-05 23:00:07 +08:00
|
|
|
|
if err := r.db.WithContext(repoCtx).First(&areaController, id).Error; err != nil {
|
2025-09-29 19:17:42 +08:00
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return &areaController, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FindByNetworkID 通过 NetworkID 查找一个 AreaController。
|
2025-11-05 23:00:07 +08:00
|
|
|
|
func (r *gormAreaControllerRepository) FindByNetworkID(ctx context.Context, networkID string) (*models.AreaController, error) {
|
|
|
|
|
|
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindByNetworkID")
|
2025-09-29 19:17:42 +08:00
|
|
|
|
var areaController models.AreaController
|
2025-11-05 23:00:07 +08:00
|
|
|
|
if err := r.db.WithContext(repoCtx).Where("network_id = ?", networkID).First(&areaController).Error; err != nil {
|
2025-09-29 19:17:42 +08:00
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return &areaController, nil
|
|
|
|
|
|
}
|
2025-11-10 21:14:36 +08:00
|
|
|
|
|
|
|
|
|
|
// IsAreaControllerUsedByTasks 检查区域主控是否被特定任务类型使用,可以忽略指定任务类型
|
|
|
|
|
|
func (r *gormAreaControllerRepository) IsAreaControllerUsedByTasks(ctx context.Context, areaControllerID uint, ignoredTaskTypes []models.TaskType) (bool, error) {
|
|
|
|
|
|
repoCtx, logger := logs.Trace(ctx, r.ctx, "IsAreaControllerUsedByTasks")
|
|
|
|
|
|
|
|
|
|
|
|
// 将 ignoredTaskTypes 转换为 map,以便高效查找
|
|
|
|
|
|
ignoredMap := make(map[models.TaskType]struct{})
|
|
|
|
|
|
for _, tt := range ignoredTaskTypes {
|
|
|
|
|
|
ignoredMap[tt] = struct{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
areaControllerIDStr := strconv.FormatUint(uint64(areaControllerID), 10)
|
|
|
|
|
|
|
|
|
|
|
|
// 定义所有可能与 AreaControllerID 相关的任务类型列表
|
|
|
|
|
|
// 方便未来扩展,如果新增任务类型与区域主控关联,只需在此处添加
|
|
|
|
|
|
relevantTaskTypes := []models.TaskType{
|
|
|
|
|
|
models.TaskTypeAreaCollectorThresholdCheck,
|
|
|
|
|
|
// TODO: 如果未来有其他任务类型通过 parameters 关联 AreaControllerID,请在此处添加
|
|
|
|
|
|
// 例如: models.TaskTypeAnotherAreaControllerTask,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, taskType := range relevantTaskTypes {
|
|
|
|
|
|
// 如果当前任务类型在忽略列表中,则跳过检查
|
|
|
|
|
|
if _, ok := ignoredMap[taskType]; ok {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var taskCount int64
|
|
|
|
|
|
var query *gorm.DB
|
|
|
|
|
|
|
|
|
|
|
|
// 根据任务类型构建不同的查询条件
|
|
|
|
|
|
switch taskType {
|
|
|
|
|
|
case models.TaskTypeAreaCollectorThresholdCheck:
|
|
|
|
|
|
// TaskTypeAreaCollectorThresholdCheck 任务的 AreaControllerID 存储在 parameters->>'AreaControllerID'
|
|
|
|
|
|
query = r.db.WithContext(repoCtx).
|
|
|
|
|
|
Model(&models.Task{}).
|
|
|
|
|
|
Where("type = ?", models.TaskTypeAreaCollectorThresholdCheck).
|
|
|
|
|
|
Where("parameters->>'AreaControllerID' = ?", areaControllerIDStr)
|
|
|
|
|
|
// TODO: 如果未来有其他任务类型通过不同的 parameters 字段关联 AreaControllerID,请在此处添加 case
|
|
|
|
|
|
// case models.TaskTypeAnotherAreaControllerTask:
|
|
|
|
|
|
// query = r.db.WithContext(repoCtx).
|
|
|
|
|
|
// Model(&models.Task{}).
|
|
|
|
|
|
// Where("type = ?", models.TaskTypeAnotherAreaControllerTask).
|
|
|
|
|
|
// Where("parameters->>'AnotherFieldForAreaControllerID' = ?", areaControllerIDStr)
|
|
|
|
|
|
default:
|
|
|
|
|
|
// 对于未明确处理的 relevantTaskTypes,可以记录警告或直接跳过
|
|
|
|
|
|
logger.Warnf(fmt.Sprintf("IsAreaControllerUsedByTasks: 未处理的区域主控相关任务类型: %s", taskType))
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if query != nil {
|
|
|
|
|
|
err := query.Count(&taskCount).Error
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return false, fmt.Errorf("查询区域主控任务使用情况失败 (任务类型: %s): %w", taskType, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
if taskCount > 0 {
|
|
|
|
|
|
return true, nil // 发现有未被忽略的任务正在使用此区域主控
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false, nil // 没有发现任何未被忽略的任务正在使用此区域主控
|
|
|
|
|
|
}
|