# 定时任务 API 化整改方案 v1.0 > **版本**: 1.0 > **日期**: 2026-06-04 > **背景**: VolPro 框架的 Quartz 机制基于 `[ApiTask]` + URL 调用,不支持 `IJob` 接口 > **现状**: 4 个 IJob 实现(SyncDevices/HeartbeatMonitor/RealtimePoll/RuleEngineJob)需迁移为 API 端点 --- ## 1. 影响范围 | 任务 | 当前文件 | 需改为 | 调度间隔 | |------|------|------|:---:| | 设备同步 | `SyncDevicesJob.cs` (IJob) | Controller + `[ApiTask]` | 每5分钟 | | 心跳监控 | `HeartbeatMonitorJob.cs` (IJob) | Controller + `[ApiTask]` | 每15秒 | | 实时轮询 | `RealtimePollJob.cs` (IJob) | Controller + `[ApiTask]` | 每10秒 | | 规则引擎 | `RuleEngineJob.cs` (IJob) | Controller + `[ApiTask]` | 每10秒 | --- ## 2. 整改步骤 ### 步骤 T1: 创建任务调度 Controller(预计 30min) **新建文件**: `api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/TaskController.cs` ```csharp using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using VolPro.Core.Filters; using Warehouse.Services; namespace Warehouse.Controllers; /// /// 定时任务 API 端点。 /// VolPro 框架通过 Sys_QuartzOptions 配置 URL+Cron 定时调用。 /// 每个方法加 [ApiTask] 属性以允许框架匿名调用。 /// [ApiController] [Route("api/task")] public class TaskController : Controller { /// T1: 设备同步 — 遍历在线网关触发全量设备同步 [ApiTask] [HttpGet, HttpPost, Route("syncDevices")] public async Task SyncDevices() { var sp = HttpContext.RequestServices; var engine = sp.GetService(); if (engine != null) await engine.Execute(null!); return Ok(new { time = DateTime.Now, status = "ok" }); } /// T2: 心跳监控 — 扫描超时网关标记离线 [ApiTask] [HttpGet, HttpPost, Route("heartbeatMonitor")] public async Task HeartbeatMonitor() { var sp = HttpContext.RequestServices; var engine = sp.GetService(); if (engine != null) await engine.Execute(null!); return Ok(new { time = DateTime.Now, status = "ok" }); } /// T3: 实时轮询 — 拉取 MC4 IoT 实时值 [ApiTask] [HttpGet, HttpPost, Route("realtimePoll")] public async Task RealtimePoll() { var sp = HttpContext.RequestServices; var engine = sp.GetService(); if (engine != null) await engine.Execute(null!); return Ok(new { time = DateTime.Now, status = "ok" }); } /// T4: 规则引擎 — 评估规则+执行动作 [ApiTask] [HttpGet, HttpPost, Route("ruleEngine")] public async Task RuleEngine() { var sp = HttpContext.RequestServices; var engine = sp.GetService(); if (engine != null) await engine.EvaluateAllAsync(); return Ok(new { time = DateTime.Now, status = "ok" }); } } ``` ### 步骤 T2: 注册 DI(预计 10min) **编辑文件**: `api_sqlsugar/VolPro.Core/Extensions/AutofacManager/AutofacContainerModuleExtension.cs` 或在 Warehouse 项目的 Startup/Module 中注册: ```csharp // 在 Autofac 注册块中添加 builder.RegisterType().AsSelf().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().InstancePerLifetimeScope(); ``` 如果已由 VolPro 框架自动扫描 Services 目录,则跳过此步骤。 ### 步骤 T3: 管理端配置任务(预计 15min) 在 Vol.Pro 管理端 → Quartz 管理 → 新建 4 个任务: | TaskName | ApiUrl | Cron | Method | |------|------|------|:--:| | 设备同步 | `/api/task/syncDevices` | `0 */5 * * * ?` | POST | | 心跳监控 | `/api/task/heartbeatMonitor` | `0/15 * * * * ?` | POST | | 实时轮询 | `/api/task/realtimePoll` | `0/10 * * * * ?` | POST | | 规则引擎 | `/api/task/ruleEngine` | `0/10 * * * * ?` | POST | ### 步骤 T4: 保留或删除 IJob 文件(预计 5min) **保留** IJob 实现类(`SyncDevicesJob.cs` 等)不删除——Controller 通过 DI 获取它们并调用 `Execute()`。 只需将 IJob 实现类用 `IServiceProvider` 获取(而非 Quartz 的 `JobDataMap`),因为 Controller 不传 `IJobExecutionContext`。修改 `Execute` 方法签名: ```csharp // 旧: 依赖 IJobExecutionContext.JobDataMap public async Task Execute(IJobExecutionContext context) { var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"]; ... } // 新: 注入 IServiceProvider 为构造函数参数 public class HeartbeatMonitorJob : IJob { private readonly IServiceProvider _sp; public HeartbeatMonitorJob(IServiceProvider sp) { _sp = sp; } public async Task Execute(IJobExecutionContext? context) { var gwSvc = _sp.GetService(); var devRepo = _sp.GetService(); ... } } ``` ### 步骤 T5: 编译验证(预计 10min) - [ ] `dotnet build api_sqlsugar/VolPro.WebApi` → 0 错误 - [ ] 确认 `[ApiTask]` 不与其他权限 Filter 冲突 --- ## 3. 改动文件汇总 | 步骤 | 文件 | 改动 | |:---:|------|------| | T1 | `VolPro.WebApi/Controllers/Warehouse/TaskController.cs` | 新建,4 个 `[ApiTask]` 端点 | | T2 | DI 注册 | 可能不需改动(VolPro 自动扫描) | | T3 | 管理端 Sys_QuartzOptions | 新建 4 条任务记录 | | T4 | 4 个 IJob 实现 | 构造函数改用 IServiceProvider 注入 | | T5 | 全量编译 | 0 错误 | --- ## 4. 原 IJob 文件处理方案 | 文件 | 处理 | |------|------| | `SyncDevicesJob.cs` | 构造函数注入 IServiceProvider,Execute 参数改为 nullable | | `HeartbeatMonitorJob.cs` | 同上 | | `RealtimePollJob.cs` | 同上 | | `RuleEngineJob.cs` | 删除(RuleEngineService 本身就是普通类,不继承 IJob) | > `RuleEngineJob.cs` 可直接删除——`RuleEngineService` 是普通类,已被 TaskController 直接调用。