Files
SecMPS/doc/设计文档/SecMPS统一问题清单20260603修复方案.md

11 KiB
Raw Blame History

SecMPS 统一问题清单 2026-06-03 修复方案

版本: 1.0 日期: 2026-06-03 基准: SecMPS统一问题清单20260603.md 原则: 按优先级逐项修复,每项修复后编译验证;涉及网关/Vol.Pro 改动的放一组批量提交


修复总览

阶段 优先级 涉及项目 文件数 预计
F1 P0-1 ~ P0-3 gateway + Vol.Pro 5 2h
F2 P1-1 ~ P1-6 gateway + Vol.Pro + 库表 + 前端 8 4h
F3 P2-1 ~ P2-5 gateway + warehouse 8 2h
F4 P3-1 ~ P3-4 gateway + 文档 4 1h
合计 4 项目 25 ~9h

阶段 F1: P0 阻塞项修复(预计 2h

F1.1 [P0-1] RealtimePollJob 填充实现

  • 编辑 api_sqlsugar/Warehouse/Services/RealtimePollJob.cs
  • 注入 GatewayClient + Ibase_deviceRepository
  • Execute() 中:
    1. 查询在线 MC4 网关 (gateway_nodes WHERE IsOnline=在线 AND AdapterTypes LIKE '%MC4%')
    2. 查对应设备列表 (base_device WHERE DeviceGroup='IoT设备' AND IsOnline=在线)
    3. 对每个设备调 GatewayClient.GetRealtimeAsync(gwBaseUrl, adapterCode, sourceId)
    4. 结果写入 iot_devicedataINSERT 新记录)
  • dotnet build → 0 错误

F1.2 [P0-2] 网关 A1 自注册

  • 编辑 gateway/src/IntegrationGateway.Host/Program.cs
  • registry.InitializeAllAsync() 后加入:
    var nodeCode = gwCfg["NodeCode"] ?? "gw-default";
    var nodeToken = gwCfg["NodeToken"] ?? "";
    var adapterTypes = string.Join(",", registry.All.Select(a => a.AdapterCode));
    await clientFactory.RegisterAsync(nodeCode, nodeToken, adapterTypes, volProUrl);
    
  • dotnet build → 0 错误

F1.3 [P0-3] B 组路由认证

  • 编辑 gateway/src/IntegrationGateway.Host/Program.cs
  • app.UseCors() 之后添加中间件:
    var gatewayKey = gwCfg["GatewayKey"];
    if (!string.IsNullOrEmpty(gatewayKey))
    {
        app.Use(async (context, next) => {
            var key = context.Request.Headers["X-Gateway-Key"].FirstOrDefault();
            if (key == gatewayKey || context.Request.Path == "/") { await next(); }
            else { context.Response.StatusCode = 401; }
        });
    }
    
  • appsettings.json Gateway 段新增 "GatewayKey": null
  • Vol.Pro 端 GatewayClient 所有 HTTP 请求头自动附加 X-Gateway-Key
  • dotnet build → 0 错误

F1 提交点: Fix-P0: RealtimePollJob+A1自注册+B组认证


阶段 F2: P1 重要项修复(预计 4h

F2.1 [P1-1] 网关新增批量实时值接口

  • 编辑 gateway/src/IntegrationGateway.Host/Program.cs
  • 新增 B4-batch 路由:
    app.MapPost("/api/gateway/realtime/{adapter}/batch", async (string adapter, BatchRealtimeRequest req) =>
    {
        var a = registry.FindByCode<IHasPoints>(adapter);
        if (a == null) return Results.NotFound();
        var results = new Dictionary<string, List<PointValue>>();
        foreach (var deviceId in req.DeviceIds ?? new())
            results[deviceId] = await a.GetRealtimeValuesAsync(deviceId);
        return Results.Ok(results);
    });
    
  • 新增 record BatchRealtimeRequest(List<string>? DeviceIds);
  • dotnet build → 0 错误

F2.2 [P1-2] 批量级联离线标记

  • 编辑 api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs
  • 替换逐条 UpdateAsync 为:
    context.Repository.DbContext.Db.Ado.ExecuteCommand(
        "UPDATE base_device SET IsOnline='离线' WHERE GatewayNodeId=@id AND IsOnline='在线'",
        new { id = node.GatewayNodeId });
    
  • dotnet build → 0 错误

F2.3 [P1-3] 凭据安全化

  • 编辑 gateway/src/IntegrationGateway.Host/appsettings.json
    • NodeTokennull, 加注释 "生产环境由 SECMPS_GATEWAY_TOKEN 环境变量注入"
    • Owl Password"", 加注释
    • KMS ClientSecret"", 加注释
  • 编辑 gateway/src/IntegrationGateway.Host/Program.cs
    • gwCfg["NodeToken"]Environment.GetEnvironmentVariable("SECMPS_GATEWAY_TOKEN") ?? gwCfg["NodeToken"]
  • 编辑 .gitignore → 加 **/bin/**/obj/
  • git rm -r --cached gateway/src/IntegrationGateway.Host/bin/

F2.4 [P1-4] 前端网关地址统一化

  • 编辑 web.vite/public/index.htmlwindow.apiConfig → 加 gatewayUrl: 'http://localhost:5100'
  • 编辑 web.vite/src/views/warehouse/device_manager/base_device.vue
    • const GW = 'http://localhost:5100'const GW = window.apiConfig.gatewayUrl || 'http://localhost:5100'
  • 编辑 warehouse/src/api/gateway.ts
    • const GW_BASE = 'http://localhost:5100' → 读取 window.apiConfig.gatewayUrl
  • 编辑 warehouse/index.htmlwindow.apiConfig → 加 gatewayUrl

F2.5 [P1-5] 规则引擎增加 DeviceId 映射

  • 在规则引擎实现方案中增加 BuildDeviceMappingAsync 方法:
    var deviceIds = rules.SelectMany(r => r.Conditions).Select(c => c.DeviceId).Distinct();
    var devices = await _deviceRepo.FindAsync(d => deviceIds.Contains(d.DeviceId));
    var map = devices.ToDictionary(d => d.DeviceId, d => (d.AdapterCode, d.SourceId));
    
  • 后续调网关时用 map[cond.DeviceId] 拼装 URL

F2.6 [P1-6] 新建 warehouse_variable 表

  • 执行 SQL:
    CREATE TABLE warehouse_variable (
        VariableId   INT IDENTITY PRIMARY KEY,
        DeviceId     INT NOT NULL,
        VariableName NVARCHAR(255),     -- 温度/湿度/人数
        PointIndex   INT DEFAULT 0,     -- MC4 pointIndex
        Unit         NVARCHAR(50),      -- ℃/%/人
        SortOrder    INT DEFAULT 0
    );
    
  • 在 Vol.Pro 代码生成器选择 warehouse_variable,生成全套 CRUD 代码
  • 管理端字典 "变量列表" 绑定到 warehouse_variable.VariableName
  • 规则条件/动作的 ValueId 下拉框改为从 warehouse_variable 查询JOIN base_device.DeviceId

F2 提交点: Fix-P1: B4-batch+批量离线+凭据安全+前端地址+DeviceId映射+变量表


阶段 F3: P2 改善项修复(预计 2h

F3.1 [P2-1] 适配器异常日志

  • 编辑 gateway/src/IntegrationGateway.Adapters.Owl/OwlAdapter.cs
  • 编辑 gateway/src/IntegrationGateway.Adapters.MC4/Mc4Adapter.cs
  • 编辑 gateway/src/IntegrationGateway.Adapters.Kms/KmsAdapter.cs
  • 所有 catch { return false; }catch (Exception ex) { Console.Error.WriteLine($"[{AdapterCode}] HealthCheck: {ex.Message}"); return false; }
  • dotnet build → 0 错误

F3.2 [P2-2] 规则引擎滞后窗

  • warehouse_rulecondition 表新增字段:
    ALTER TABLE warehouse_rulecondition ADD
        RecoveryThreshold_Numeric DECIMAL(18,2) NULL,  -- 恢复阈值(下界)
        RecoveryThreshold_Switch  NVARCHAR(50) NULL;    -- 恢复开关状态
    
  • RuleEngineService.EvaluateCondition 中加逻辑:
    bool wasTriggered = cond.LastTriggered.HasValue;
    if (wasTriggered)
        return Compare(actualValue, "大于等于", cond.RecoveryThreshold_Numeric);
    else
        return Compare(actualValue, cond.CompareOperator, cond.TargetValue_Number);
    

F3.3 [P2-3] 条件级冷却

  • warehouse_rulecondition 表新增 LastTriggered DATETIME NULLLastTriggerValue DECIMAL(18,2) NULL
  • RuleEngineService.EvaluateCondition 中:
    • 如果 DateTime.Now - cond.LastTriggered < rule.CooldownSec → 跳过此条件
    • 触发时更新 LastTriggeredLastTriggerValue

F3.4 [P2-4] 生产环境移除 console.log

  • 编辑 warehouse/vite.config.ts
    build: {
      terserOptions: { compress: { drop_console: true } }
    }
    
  • 开发环境保留 console.log(仅 build 时移除)
  • npm run build → 确认无 console.log 残留

F3.5 [P2-5] 统一 gateway API 封装

  • 复制 warehouse/src/api/gateway.tsweb.vite/src/api/gateway.js
    • 修改 GW_BASEwindow.apiConfig.gatewayUrl || 'http://localhost:5100'
  • web.vite/src/views/warehouse/device_manager/base_device.vue
    • 删除内联 const GW = + fetch() → 改为 import { gwGet, gwPost } from '@/api/gateway.js'
    • 所有 fetch(\${GW}/api/gateway/...`)gwGet(...)/gwPost(...)`

F3 提交点: Fix-P2: 异常日志+滞后窗+条件冷却+console清理+API统一


阶段 F4: P3 优化项(预计 1h

F4.1 [P3-1] 规则引擎并发动作执行

  • 在规则引擎实现方案的 ExecuteActionsAsync 中:
    var tasks = actions.Select(a => ExecuteSingleActionAsync(a, rule));
    await Task.WhenAll(tasks);
    
    async Task ExecuteSingleActionAsync(Action a, Rule r) {
        using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
        try { await DoAction(a, r, cts.Token); }
        catch (OperationCanceledException) { Log($"[RuleEngine] 动作超时: {a.id}"); }
    }
    

F4.2 [P3-2] 清理 bin/obj + .gitignore

  • .gitignore 追加规则(如未在 F2.3 中完成):
    **/bin/
    **/obj/
    gateway/src/IntegrationGateway.Host/bin/
    api_sqlsugar/**/bin/
    
  • git rm -r --cached 所有 bin/obj 目录

F4.3 [P3-3] 网关 Swagger

  • 编辑 gateway/src/IntegrationGateway.Host/Program.cs:
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    // ...
    app.UseSwagger();
    app.UseSwaggerUI();
    
  • 浏览器访问 http://localhost:5100/swagger 验证

F4.4 [P3-4] 同步设计文档路由数

  • 编辑 doc/设计文档/对接网关设计文档.md → 路由表从 14 条更新为当前实际数
  • 确认以下设计文档一致: 对接网关设计文档、规则引擎方案、KMS 设计文档

F4 提交点: Fix-P3: 并发动作+清理bin+Swagger+文档同步


任务总览

编号 问题 涉及文件 预计
P0-1 RealtimePollJob 空壳 RealtimePollJob.cs 1h
P0-2 A1 自注册 Program.cs 30min
P0-3 B 组认证 Program.cs + appsettings 30min
P1-1 B4-batch Program.cs 30min
P1-2 批量离线 HeartbeatMonitorJob.cs 20min
P1-3 凭据安全 appsettings + .gitignore + bin 20min
P1-4 前端地址 base_device.vue + gateway.ts 20min
P1-5 DeviceId 映射 RuleEngineService 30min
P1-6 变量表 SQL + 代码生成 + 前端 1h
P2-1 异常日志 OwlAdapter + MC4Adapter + KmsAdapter 20min
P2-2 滞后窗 SQL + RuleEngineService 30min
P2-3 条件冷却 SQL + RuleEngineService 20min
P2-4 console 清理 vite.config.ts 10min
P2-5 API 统一 gateway.js + base_device.vue 30min
P3-1 并发动作 RuleEngineService 15min
P3-2 bin 清理 .gitignore + git rm 5min
P3-3 Swagger Program.cs 10min
P3-4 文档同步 设计文档 15min

总计: 18 项 / 25 文件 / ~9h