增加两个批量查询接口
This commit is contained in:
@@ -38,6 +38,29 @@ type ListPlansOptions struct {
|
||||
PlanType PlanTypeFilter
|
||||
}
|
||||
|
||||
// TaskListOptions 定义了查询任务时的可选参数
|
||||
type TaskListOptions struct {
|
||||
// --- 通用筛选 ---
|
||||
Name *string // 按任务名称进行模糊查询
|
||||
PlanID *uint32 // 按所属的计划ID进行精确查询
|
||||
Type *models.TaskType // 按任务类型精确查询
|
||||
|
||||
// --- 关联筛选 ---
|
||||
// 用于通过 device_tasks 关联表筛选与特定设备ID关联的任务
|
||||
DeviceID *uint32
|
||||
|
||||
// --- JSON 参数内筛选 (仅对特定任务类型有效) ---
|
||||
// 用于筛选 TaskTypeAreaCollectorThresholdCheck 类型的任务
|
||||
AreaControllerID *uint32
|
||||
// 用于筛选 TaskTypeDeviceThresholdCheck 和 TaskTypeAreaCollectorThresholdCheck 类型的任务
|
||||
SensorType *models.SensorType
|
||||
// 用于筛选 TaskTypeDeviceThresholdCheck 和 TaskTypeAreaCollectorThresholdCheck 类型的任务
|
||||
Level *models.SeverityLevel
|
||||
|
||||
// --- 排序 ---
|
||||
OrderBy string // 例如 "id desc"
|
||||
}
|
||||
|
||||
// PlanRepository 定义了与计划模型相关的数据库操作接口
|
||||
// 这是为了让业务逻辑层依赖于抽象,而不是具体的数据库实现
|
||||
type PlanRepository interface {
|
||||
@@ -89,6 +112,8 @@ type PlanRepository interface {
|
||||
UpdatePlanStateAfterExecution(ctx context.Context, planID uint32, newCount uint32, newStatus models.PlanStatus) error
|
||||
// ListTasksByDeviceID 根据设备ID获取关联任务列表
|
||||
ListTasksByDeviceID(ctx context.Context, deviceID uint32) ([]*models.Task, error)
|
||||
// ListTasks 支持分页和过滤的任务列表查询
|
||||
ListTasks(ctx context.Context, opts TaskListOptions, page, pageSize int) ([]models.Task, int64, error)
|
||||
}
|
||||
|
||||
// gormPlanRepository 是 PlanRepository 的 GORM 实现
|
||||
@@ -896,3 +921,74 @@ func (r *gormPlanRepository) ListTasksByDeviceID(ctx context.Context, deviceID u
|
||||
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
// ListTasks 实现了分页和过滤查询任务的功能,并优化了 JOIN 后的计数逻辑
|
||||
func (r *gormPlanRepository) ListTasks(ctx context.Context, opts TaskListOptions, page, pageSize int) ([]models.Task, int64, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListTasks")
|
||||
if page <= 0 || pageSize <= 0 {
|
||||
return nil, 0, ErrInvalidPagination
|
||||
}
|
||||
|
||||
var results []models.Task
|
||||
var total int64
|
||||
|
||||
// 1. 构建基础查询,应用所有筛选条件
|
||||
query := r.db.WithContext(repoCtx).Model(&models.Task{})
|
||||
|
||||
if opts.Name != nil && *opts.Name != "" {
|
||||
query = query.Where("tasks.name LIKE ?", "%"+*opts.Name+"%")
|
||||
}
|
||||
if opts.PlanID != nil {
|
||||
query = query.Where("tasks.plan_id = ?", *opts.PlanID)
|
||||
}
|
||||
if opts.Type != nil {
|
||||
query = query.Where("tasks.type = ?", *opts.Type)
|
||||
}
|
||||
|
||||
// --- JSON 字段查询 ---
|
||||
if opts.AreaControllerID != nil {
|
||||
// 使用 ->> 操作符查询 JSON 字段的值(作为文本)
|
||||
query = query.Where("parameters->>'area_controller_id' = ?", *opts.AreaControllerID)
|
||||
}
|
||||
if opts.SensorType != nil {
|
||||
query = query.Where("parameters->>'sensor_type' = ?", *opts.SensorType)
|
||||
}
|
||||
if opts.Level != nil {
|
||||
query = query.Where("parameters->>'level' = ?", *opts.Level)
|
||||
}
|
||||
// --- 结束 ---
|
||||
|
||||
if opts.DeviceID != nil {
|
||||
query = query.Joins("JOIN device_tasks ON device_tasks.task_id = tasks.id").Where("device_tasks.device_id = ?", *opts.DeviceID)
|
||||
}
|
||||
|
||||
// 2. 执行计数查询
|
||||
countQuery := query
|
||||
if opts.DeviceID != nil {
|
||||
if err := countQuery.Distinct("tasks.id").Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
} else {
|
||||
if err := countQuery.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
return []models.Task{}, 0, nil
|
||||
}
|
||||
|
||||
// 3. 为数据查询应用排序、分页和预加载
|
||||
orderBy := "tasks.id DESC"
|
||||
if opts.OrderBy != "" {
|
||||
orderBy = opts.OrderBy
|
||||
}
|
||||
|
||||
err := query.Order(orderBy).
|
||||
Limit(pageSize).
|
||||
Offset((page - 1) * pageSize).
|
||||
Preload("Devices").
|
||||
Find(&results).Error
|
||||
|
||||
return results, total, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user