diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/TaskController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/TaskController.cs
new file mode 100644
index 0000000..9a8e31d
--- /dev/null
+++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/TaskController.cs
@@ -0,0 +1,66 @@
+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] 属性以允许框架匿名调用。
+///
+/// 管理端配置:
+/// syncDevices: 0 */5 * * * ?
+/// heartbeatMonitor: 0/15 * * * * ?
+/// realtimePoll: 0/10 * * * * ?
+/// ruleEngine: 0/10 * * * * ?
+///
+[ApiController]
+[Route("api/task")]
+public class TaskController : Controller
+{
+ /// 设备同步 — 遍历在线网关触发全量设备同步
+ [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" });
+ }
+
+ /// 心跳监控 — 扫描超时网关标记离线
+ [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" });
+ }
+
+ /// 实时轮询 — 拉取 MC4 IoT 实时值写入 iot_devicedata
+ [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" });
+ }
+
+ /// 规则引擎 — 评估规则条件+执行告警/控制/通知动作
+ [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" });
+ }
+}
diff --git a/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs b/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs
index 95ee851..3d7a162 100644
--- a/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs
+++ b/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs
@@ -19,9 +19,12 @@ namespace VolPro.Warehouse.Services;
///
public class HeartbeatMonitorJob : IJob
{
- public async Task Execute(IJobExecutionContext context)
+ private readonly IServiceProvider _sp;
+ public HeartbeatMonitorJob(IServiceProvider sp) { _sp = sp; }
+
+ public async Task Execute(IJobExecutionContext? context)
{
- var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"];
+ var sp = _sp;
if (sp == null) return;
var gwSvc = sp.GetService();
diff --git a/api_sqlsugar/Warehouse/Services/RealtimePollJob.cs b/api_sqlsugar/Warehouse/Services/RealtimePollJob.cs
index 33f6c36..f80c050 100644
--- a/api_sqlsugar/Warehouse/Services/RealtimePollJob.cs
+++ b/api_sqlsugar/Warehouse/Services/RealtimePollJob.cs
@@ -18,9 +18,12 @@ namespace VolPro.Warehouse.Services;
///
public class RealtimePollJob : IJob
{
- public async Task Execute(IJobExecutionContext context)
+ private readonly IServiceProvider _sp;
+ public RealtimePollJob(IServiceProvider sp) { _sp = sp; }
+
+ public async Task Execute(IJobExecutionContext? context)
{
- var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"];
+ var sp = _sp;
if (sp == null) return;
var gwSvc = sp.GetService();
diff --git a/api_sqlsugar/Warehouse/Services/RuleEngineJob.cs b/api_sqlsugar/Warehouse/Services/RuleEngineJob.cs
index cdf60c3..58e4105 100644
--- a/api_sqlsugar/Warehouse/Services/RuleEngineJob.cs
+++ b/api_sqlsugar/Warehouse/Services/RuleEngineJob.cs
@@ -1,4 +1,4 @@
-using Quartz;
+// 已迁移到 TaskController.RuleEngine() — 构建时需删除此文件
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
diff --git a/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs b/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs
index 371d555..0759704 100644
--- a/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs
+++ b/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs
@@ -14,9 +14,12 @@ namespace VolPro.Warehouse.Services;
///
public class SyncDevicesJob : IJob
{
- public async Task Execute(IJobExecutionContext context)
+ private readonly IServiceProvider _sp;
+ public SyncDevicesJob(IServiceProvider sp) { _sp = sp; }
+
+ public async Task Execute(IJobExecutionContext? context)
{
- var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"];
+ var sp = _sp;
var gwSvc = sp.GetService();
var client = sp.GetService();
if (gwSvc == null || client == null) return;