Files
SecMPS/doc/设计文档/定时任务API化整改方案_v1.0.md

6.1 KiB
Raw Blame History

定时任务 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

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using VolPro.Core.Filters;
using Warehouse.Services;

namespace Warehouse.Controllers;

/// <summary>
/// 定时任务 API 端点。
/// VolPro 框架通过 Sys_QuartzOptions 配置 URL+Cron 定时调用。
/// 每个方法加 [ApiTask] 属性以允许框架匿名调用。
/// </summary>
[ApiController]
[Route("api/task")]
public class TaskController : Controller
{
    /// <summary>T1: 设备同步 — 遍历在线网关触发全量设备同步</summary>
    [ApiTask]
    [HttpGet, HttpPost, Route("syncDevices")]
    public async Task<IActionResult> SyncDevices()
    {
        var sp = HttpContext.RequestServices;
        var engine = sp.GetService<SyncDevicesJob>();
        if (engine != null) await engine.Execute(null!);
        return Ok(new { time = DateTime.Now, status = "ok" });
    }

    /// <summary>T2: 心跳监控 — 扫描超时网关标记离线</summary>
    [ApiTask]
    [HttpGet, HttpPost, Route("heartbeatMonitor")]
    public async Task<IActionResult> HeartbeatMonitor()
    {
        var sp = HttpContext.RequestServices;
        var engine = sp.GetService<HeartbeatMonitorJob>();
        if (engine != null) await engine.Execute(null!);
        return Ok(new { time = DateTime.Now, status = "ok" });
    }

    /// <summary>T3: 实时轮询 — 拉取 MC4 IoT 实时值</summary>
    [ApiTask]
    [HttpGet, HttpPost, Route("realtimePoll")]
    public async Task<IActionResult> RealtimePoll()
    {
        var sp = HttpContext.RequestServices;
        var engine = sp.GetService<RealtimePollJob>();
        if (engine != null) await engine.Execute(null!);
        return Ok(new { time = DateTime.Now, status = "ok" });
    }

    /// <summary>T4: 规则引擎 — 评估规则+执行动作</summary>
    [ApiTask]
    [HttpGet, HttpPost, Route("ruleEngine")]
    public async Task<IActionResult> RuleEngine()
    {
        var sp = HttpContext.RequestServices;
        var engine = sp.GetService<RuleEngineService>();
        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 中注册:

// 在 Autofac 注册块中添加
builder.RegisterType<SyncDevicesJob>().AsSelf().InstancePerLifetimeScope();
builder.RegisterType<HeartbeatMonitorJob>().AsSelf().InstancePerLifetimeScope();
builder.RegisterType<RealtimePollJob>().AsSelf().InstancePerLifetimeScope();
builder.RegisterType<RuleEngineService>().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 方法签名:

// 旧: 依赖 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<Igateway_nodesService>();
        var devRepo = _sp.GetService<Ibase_deviceRepository>();
        ...
    }
}

步骤 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 构造函数注入 IServiceProviderExecute 参数改为 nullable
HeartbeatMonitorJob.cs 同上
RealtimePollJob.cs 同上
RuleEngineJob.cs 删除RuleEngineService 本身就是普通类,不继承 IJob

RuleEngineJob.cs 可直接删除——RuleEngineService 是普通类,已被 TaskController 直接调用。