修改总结-多定时规则支持.md 10 KB

多定时规则支持 - 修改总结

一、修改概述

根据需求"定时轮灌的模式A和模式B是可以同时存在的,也可以多条",对系统进行了全面改造,实现了以下功能:

  • ✅ 一个任务可以同时配置多个定时规则
  • ✅ CRON 模式(模式A)和 SIMPLE 模式(模式B)可以共存
  • ✅ 每种模式都可以配置多条规则
  • ✅ 每个规则可独立启用/禁用
  • ✅ 规则之间互不干扰,独立调度

二、修改内容

1. 数据库层修改

1.1 新增表:wfauto_v2_task_schedule_rule

CREATE TABLE `wfauto_v2_task_schedule_rule` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `task_id` BIGINT NOT NULL,
  `rule_name` VARCHAR(100),
  `schedule_type` VARCHAR(20) NOT NULL,
  `cron_expression` VARCHAR(100),
  `start_time` DATETIME,
  `interval_days` INT,
  `total_times` INT,
  `executed_count` INT DEFAULT 0,
  `enabled` TINYINT(1) DEFAULT 1,
  `status` VARCHAR(20) DEFAULT 'ACTIVE',
  `quartz_job_name` VARCHAR(100),
  `quartz_trigger_name` VARCHAR(100),
  -- 其他字段...
  PRIMARY KEY (`id`),
  KEY `idx_task_id` (`task_id`)
);

1.2 调整表:wfauto_v2_irrigation_task

删除了以下字段:

  • schedule_type
  • cron_expression
  • start_time
  • interval_days
  • total_times
  • executed_count

2. 实体类修改

2.1 IrrigationTask.java

  • ✅ 删除了定时相关字段
  • ✅ 删除了相关业务方法(reachedExecutionLimit(), incrementExecutedCount()

2.2 新增 TaskScheduleRule.java

  • ✅ 包含所有定时规则相关字段
  • ✅ 提供业务方法:isCronMode(), isSimpleMode(), reachedExecutionLimit(), isActive()
  • ✅ 提供工具方法:generateJobName(), generateTriggerName(), fillQuartzNames()

3. 数据访问层修改

3.1 新增 Mapper

  • TaskScheduleRuleMapper.java - 定时规则数据访问接口

3.2 新增 Repository

  • TaskScheduleRuleRepository.java - 定时规则仓储接口
  • TaskScheduleRuleRepositoryImpl.java - 定时规则仓储实现

4. API层修改

4.1 CreateTaskRequest DTO

修改前:

private String scheduleType;
private String cronExpression;
private Integer intervalDays;
private Integer totalTimes;

修改后:

private List<ScheduleRuleDTO> scheduleRules;

public static class ScheduleRuleDTO {
    private String ruleName;
    private String scheduleType;
    private String cronExpression;
    private LocalDateTime startTime;
    private Integer intervalDays;
    private Integer totalTimes;
    private Boolean enabled;
}

5. 业务逻辑层修改

5.1 IrrigationScheduledJob.java

  • ✅ 添加 PARAM_RULE_ID 参数
  • ✅ 修改 executeInternal() 方法,支持 ruleId 参数
  • ✅ 调用 taskTriggerService.scheduledTrigger(taskId, ruleId)

5.2 QuartzManagementService.java

新增方法:

  • scheduleTaskRule(IrrigationTask, TaskScheduleRule) - 为单个规则创建调度
  • scheduleAllTaskRules(Long taskId) - 为任务的所有启用规则创建调度
  • unscheduleTaskRule(TaskScheduleRule) - 删除单个规则的调度
  • unscheduleAllTaskRules(Long taskId) - 删除任务的所有规则调度
  • pauseTaskRule(TaskScheduleRule) - 暂停规则调度
  • resumeTaskRule(TaskScheduleRule) - 恢复规则调度
  • triggerRuleNow(TaskScheduleRule) - 立即触发规则
  • ruleJobExists(TaskScheduleRule) - 检查规则调度是否存在

废弃方法:

  • addCronJob(Long, String) - 已废弃
  • addSimpleJob(Long, int, int) - 已废弃
  • pauseJob(Long) - 已废弃
  • resumeJob(Long) - 已废弃
  • triggerJobNow(Long) - 已废弃
  • jobExists(Long) - 已废弃

5.3 IrrigationTaskController.java

修改的方法:

  1. createTask() - 支持创建多个定时规则

    // 保存定时规则
    if (request.getScheduleRules() != null && !request.getScheduleRules().isEmpty()) {
       for (ScheduleRuleDTO ruleDTO : request.getScheduleRules()) {
           // 创建规则
           // 创建Quartz调度
       }
    }
    
  2. deleteTask() - 删除所有规则的调度

    quartzManagementService.unscheduleAllTaskRules(id);
    taskScheduleRuleMapper.deleteByTaskId(id);
    
  3. enableTask() - 启用所有规则

    quartzManagementService.scheduleAllTaskRules(id);
    
  4. disableTask() - 禁用所有规则

    quartzManagementService.unscheduleAllTaskRules(id);
    
  5. executeNow() - 已删除(废弃)

三、数据迁移

3.1 迁移脚本

已创建迁移脚本:docs/migration-multi-schedule-rules.sql

3.2 迁移步骤

  1. 备份数据库
  2. 执行迁移脚本中的"创建表"部分
  3. 执行"数据迁移"部分,将旧配置迁移到新表
  4. 验证迁移结果
  5. 执行"删除旧字段"部分(可选,建议先测试)

3.3 迁移逻辑

  • 为每个有定时配置的任务创建对应的定时规则
  • 规则名称:迁移规则-{任务名称}
  • 自动填充 quartz_job_namequartz_trigger_name
  • SIMPLE 模式下,如果已达到执行次数上限,状态设为 COMPLETED

四、API 使用示例

4.1 创建任务(多个定时规则)

POST /api/tasks
Content-Type: application/json

{
  "taskName": "农场A区智能轮灌",
  "triggerType": "SCHEDULED",
  "scheduleRules": [
    {
      "ruleName": "每周一三五凌晨2点",
      "scheduleType": "CRON",
      "cronExpression": "0 0 2 ? * MON,WED,FRI",
      "enabled": true
    },
    {
      "ruleName": "每月1号和15号",
      "scheduleType": "CRON",
      "cronExpression": "0 0 2 1,15 * ?",
      "enabled": true
    },
    {
      "ruleName": "连续10天灌溉计划",
      "scheduleType": "SIMPLE",
      "startTime": "2026-03-10 06:00:00",
      "intervalDays": 1,
      "totalTimes": 10,
      "enabled": true
    }
  ],
  "pumpId": "pump-001",
  "pressureMode": "PUMP_UNIFIED",
  "targetPressureKpa": 300,
  "groupConfigs": [
    {
      "groupId": 101,
      "sortOrder": 1,
      "irrigationDurationMinutes": 30
    }
  ],
  "tenantId": 1
}

4.2 查询任务的定时规则

SELECT * FROM wfauto_v2_task_schedule_rule
WHERE task_id = 1 AND deleted = 0
ORDER BY id;

4.3 查询规则执行状态

SELECT
  r.id,
  r.rule_name,
  r.schedule_type,
  r.enabled,
  r.status,
  r.executed_count,
  r.total_times,
  CASE
    WHEN r.schedule_type = 'CRON' THEN r.cron_expression
    WHEN r.schedule_type = 'SIMPLE' THEN CONCAT('每', r.interval_days, '天执行')
  END AS schedule_info
FROM wfauto_v2_task_schedule_rule r
WHERE r.task_id = 1 AND r.deleted = 0;

五、技术优势

5.1 灵活性

  • ✅ 支持同时配置多个 CRON 规则和 SIMPLE 规则
  • ✅ 每个规则可独立启用/禁用
  • ✅ 规则可动态增删改

5.2 可维护性

  • ✅ 定时规则独立管理,职责清晰
  • ✅ 符合关系型数据库设计规范
  • ✅ 便于后续扩展(如增加规则优先级、规则分组等)

5.3 向后兼容

  • ✅ 提供数据迁移脚本
  • ✅ 旧版API标记为 @Deprecated
  • ✅ 旧版deleteJob()方法映射到新的unscheduleAllTaskRules()

5.4 性能

  • ✅ 每个规则对应一个独立的 Quartz Job
  • ✅ 互不干扰,任一规则故障不影响其他规则
  • ✅ 并发触发防护机制确保同一任务不会重复执行

5.5 安全性

  • ✅ 所有规则触发共享同一并发防护锁(Redis)
  • ✅ 同一任务同时只能有一个执行实例
  • ✅ 规则触发失败不影响其他规则

六、注意事项

6.1 数据迁移

  • ⚠️ 执行迁移前务必备份数据库
  • ⚠️ 建议先在测试环境验证
  • ⚠️ 迁移后需重启应用,让Quartz重新注册Job

6.2 并发触发

  • ⚠️ 同一任务配置多个规则时,如果触发时间重叠,只有先触发的会执行
  • ⚠️ 后续触发会被并发防护机制拒绝,记录在日志中

6.3 SIMPLE 模式

  • ⚠️ SIMPLE 模式达到执行次数上限后,规则状态自动变为 COMPLETED
  • ⚠️ Quartz Job 会被自动删除
  • ⚠️ 如需重新执行,需更新规则状态为 ACTIVE 并重建调度

6.4 TaskTriggerService 依赖

  • ⚠️ IrrigationScheduledJob 现在调用 scheduledTrigger(taskId, ruleId)
  • ⚠️ 需要确保 TaskTriggerService 支持 ruleId 参数
  • ⚠️ 如果 TaskTriggerService 还未更新,需要同步修改

七、后续优化建议

7.1 功能扩展

  • 支持规则优先级
  • 支持规则分组
  • 支持规则生效时间范围(有效期)
  • 支持规则执行历史查询

7.2 UI 改进

  • 可视化规则管理界面
  • 规则执行状态实时展示
  • 规则冲突检测提示

7.3 性能优化

  • 规则数量较多时的分页查询
  • 规则缓存机制
  • 批量操作支持

八、文件清单

8.1 新增文件

  • src/main/java/cn/sciento/farm/automationv2/domain/entity/TaskScheduleRule.java
  • src/main/java/cn/sciento/farm/automationv2/domain/repository/TaskScheduleRuleRepository.java
  • src/main/java/cn/sciento/farm/automationv2/infra/repository/impl/TaskScheduleRuleRepositoryImpl.java
  • src/main/java/cn/sciento/farm/automationv2/infra/mapper/TaskScheduleRuleMapper.java
  • docs/migration-multi-schedule-rules.sql

8.2 修改文件

  • src/main/java/cn/sciento/farm/automationv2/domain/entity/IrrigationTask.java
  • src/main/java/cn/sciento/farm/automationv2/api/dto/CreateTaskRequest.java
  • src/main/java/cn/sciento/farm/automationv2/api/controller/IrrigationTaskController.java
  • src/main/java/cn/sciento/farm/automationv2/app/job/IrrigationScheduledJob.java
  • src/main/java/cn/sciento/farm/automationv2/app/service/QuartzManagementService.java
  • docs/球阀轮灌技术方案.md

九、测试建议

9.1 单元测试

  • TaskScheduleRule 实体类业务方法测试
  • TaskScheduleRuleMapper 数据访问测试
  • QuartzManagementService 调度管理测试

9.2 集成测试

  • 创建任务(多个规则)测试
  • 启用/禁用任务测试
  • 删除任务测试
  • 规则独立触发测试
  • 并发触发防护测试

9.3 端到端测试

  • 多规则同时触发场景
  • SIMPLE 规则达到上限自动停用
  • 规则故障不影响其他规则
  • 数据迁移验证

修改完成时间: 2026-03-02 修改人: Claude Sonnet 4.5 版本: v2.0