开发清单 — ActDenox 智能脱硝控制系统
最后更新:2026-06-08 | 版本 v1.0.0-rc4(终局审查 + 精准重构,15 文件全量通过)
一、项目最新技术指标
| 指标 | 数值 | 备注 |
|---|---|---|
| 桌面框架 | Electron 42.x | Chromium + Node.js |
| 运行时 | Node.js (CommonJS) | 单进程 + contextBridge |
| 主进程入口 | main.js |
340 行(重构前 2,172 行,缩减 84%) |
| 核心自治模块 | 7 个 core/ 微模块 |
误差/备份/管线/健康/窗口/轮询/PID |
| 顶层工具模块 | 5 个 | 配置/变量/Modbus 工具/PID 默认值/常量 |
| IPC 通信层 | 7 个 ipc/ 文件 |
91 个安全 handler,零重复 |
| 渲染进程页面 | 12 个 pages/ |
HTML + JS(无 Node 集成,contextIsolation) |
| Modbus 工具 | modbusUtils.js (344 行) |
CRC/帧/字节重排/寄存器转换,主从共用 |
| PID 特性 | 无扰动切换 + 积分抗饱和 + 微分先行 | 位置式 PID,多实例 |
| 数据存储 | SQLite (WAL 模式) | 4 个数据库,30 天备份 + 180 天保留 |
| 代码保护 | javascript-obfuscator 4.x | 打包时自动混淆 |
| 打包 | electron-builder 26.x (NSIS) | Windows 安装包 |
二、重构后全局架构全景图
|
|
模块依赖关系图(数据流方向)
|
|
三、已实现功能全景
Modbus 通讯(主机)
- RTU/TCP 双协议,连接/断开,FC03/FC04/FC06
- 多数据类型 uint16/int16/uint32/int32/float32/float64
- 字节序 BE/LE + 字序 ABCD/BADC/CDAB/DCBA
- 报文帧 hex 调试(请求/响应,含 CRC 校验显示)
- 操作队列串行化(enqueue,防并发冲突)
- PID 写入短超时队列路径(1200ms)+ 退避保护
- 连接健康心跳(30s 独立检测)+ 智能断线重连(3 次失败触发)
- 重连冷却期保护(10 秒锁频防抖)
- 冷启动自适应超时 + PID 写入拥塞预检
Modbus 从机
- RTU 从机 (ServerSerial),主从模式可同时运行
- 解析规则表统一服务主机解析 + 从机映射
- 从机帧捕获 + RS-485 回显过滤
- 从机诊断统计 + 事件日志(最近 20 条)
- 多寄存器缓存机制(slaveRegCache*),防部分写入产生中间值
后台轮询与自动保存
- 主进程定时轮询,页面切换后继续运行
- 并发保护 + 连续失败检测 + 强制重连
- 重连冷却期(10s,防健康检查重复触发)
- 休眠唤醒后自动恢复(断开→等待 1.5s→重连→恢复轮询)
- 自动保存(独立定时器,周期性写 SQLite)
- 保存变量过滤器(只保存勾选的字段)
数据处理管线(dataPipeline)
- 自持状态:过滤器配置/补偿配置/计算变量/运行时状态全部模块内管理
- 寄存器解析(按规则表顺序 + 类型校验)
- 4 种数据过滤器:范围钳位/变化率限制/移动平均/尖峰抑制
- 仪表状态补偿(状态机模式 + 跟随模式,AND/OR 条件逻辑)
- 安全计算变量引擎(vm 沙箱,三道防线:黑名单→白名单→空原型沙箱)
- 伴生变量体系:
XXX(过滤)+XXX(补偿)+<规则名>_compensating
PID 控制(pidOrchestrator)
- 多实例 PID 控制器(增删/Tab 切换)
- 位置式 PID + 积分抗饱和 + 微分先行
- PV 低通滤波 / 死区 / 输出变化率限制
- ★ 反向作用(Reverse Action) — 脱硝等负增益过程,error = PV − SP
- ★ 前馈控制(Feed-forward) — 可测扰动直接叠加到输出
- ★ 增益调度(Gain Scheduling) — 根据工况变量动态缩放 P/I/D 系数
- ★ 史密斯预估器(Smith Predictor) — 补偿 3~15 分钟纯滞后
- 偏差模型:仅模拟频率变化量 → PV 变化量的增量关系
- ZOH 精确离散:α = exp(-Δt/T) 一阶惯性差分方程
- 纯滞后环形缓冲区(支持 τ = 180~900s)
- 派生变量
PID-1_smithPV(可存入数据库分析) - 趋势图预估 PV 曲线(紫色实线)
- 运行控制区第二行对齐显示(预估 PV | SP | 偏差)
- ★ 手动/自动无扰动切换(Bumpless Transfer)
- 自动→手动:反算积分项对齐当前输出(输出零跳变)
- 手动模式持续:积分冻结锁定(杜绝饱和累积)
- 手动→自动:积分从对齐值平滑接管(无缝过渡)
- 远程复位信号(上升沿触发,只响应 0→1)
- 补偿引擎积分冻结联动
- ECharts 实时趋势(SP/PV/预估 PV/总输出/修正 五曲线 + 偏差带虚线)
- 健康指示灯(输出饱和 + 偏差状态 + 偏离持续时长)
- 周期溢出检测 + 定时器卡死看门狗(3×采样周期强制释放)
- 启动延迟 3s(等待 Modbus 连接就绪)
内部变量系统
-
internalVariables全局数据中心(对象共享,按引用传递) - 变量元数据注册表(单例,category/description/unit/writable)
- 分类筛选:全部/Modbus/PID/手动/计算/系统
- 变量上限 500 防护(MAX_INTERNAL_VARIABLES)
- 26 个系统健康指标 (
_sys_*):内存/通讯/PID/报警/数据库
数据存储
- SQLite (WAL 模式) — datastore.sqlite / auth.db / alarm_history.sqlite / audit_log.sqlite
- 自动建列 + 数据库列管理
- 聚合查询(分钟/小时/天 AVG/MIN/MAX),动态 SQL 生成
- 每日凌晨 3:00 自动备份(文件级 SQLite 备份,含 WAL checkpoint)
- 过期数据自动清理(保留 N 天,默认 180 天)
- 每周日凌晨 4:00 数据库完整性检查 (PRAGMA integrity_check)
报警管理
- 看门狗心跳(递增计数 → 寄存器,间隔可配)
- 阈值报警:多条件 AND/OR + 三级分级(预警/报警/严重)
- 延时触发(倒计时显示)+ 滞后死区(防边界抖动)
- 报警历史 SQLite 记录 + 桌面通知
- 报警状态机:IDLE → PENDING → ACTIVE → IDLE(含滞后)
用户管理与授权
- 三角色(admin/operator/viewer)+ 可配置权限矩阵
- 硬件指纹 + AES-256-CBC 授权码激活
- 30 天试用期 + 自动激活遮罩
- 自动登录(无人值守,重启自动以 operator 运行)
- 会话超时降级(超时 → 自动切 viewer,不清除会话)
- 登录审计 + 操作审计
仪表盘
- 7 种组件:数值卡片/状态灯/折线图/柱状图/环形仪表盘/进度条/图片
- 组件注册表模式(dashboardWidgets.js)
- 增量渲染 + 拖拽交换 + 4 档尺寸(s/m/l/xl)
- 聚合模式(分钟/小时/天均值)
- 可编辑数值组件(多数据源 + 可写变量过滤)
系统与安全
- contextIsolation: true + nodeIntegration: false(进程严格隔离)
- 所有 IPC 通过 invoke/handle(无 on/send 裸通道)
- 配置原子写入(tmp + copyFile + unlink,防断电损坏)
- 系统工具页面:开机自启开关、配置文件勾选备份/恢复、数据备份触发、数据库大小查看
- 配置备份与恢复(动态扫描 data/,选择性导出/导入,默认路径为用户文档目录)
- 进程退出快照记录(模块状态完整 dump → error.log)
- 错误日志统一写入 error.log(已废弃按天滚动)
- 全局异常守卫(uncaughtException + unhandledRejection + SIGINT/SIGTERM)
- 系统托盘 + 最小化到托盘
- 电源休眠阻止 + 休眠唤醒全自动恢复 + before-quit 释放阻止器
- 代码混淆保护(javascript-obfuscator,打包时自动)
四、已闭环的安全与稳定性防线
4.1 进程隔离
- 渲染进程
contextIsolation: true,nodeIntegration: false - 所有 Node.js API 通过
preload.js的contextBridge.exposeInMainWorld暴露 - IPC 全部使用
ipcRenderer.invoke↔ipcMain.handle模式,无通配符通道 - 70+ API 通道,零
send/on裸调用
4.2 IPC deps 访问器兼容设计
- 所有 IPC 模块通过
register(deps)接收依赖注入 - main.js 的
deps对象使用 getter/setter 代理到各 core/ 模块 - 前端和 IPC 模块完全无感于底层模块拆分
- 示例:
get backgroundConfig() { return pollEngine.getBackgroundConfig(); }
4.3 Modbus 字节重排去重
modbusManage.js和modbusSlave.js原本各有 ~90 行独立的字节重排逻辑- 统一提取到
modbusUtils.js(344 行),包含:reorderBuffer()— ABCD/BADC/CDAB/DCBA 格式重排parseRegisters()— 寄存器 → 类型化数值(主机侧)valueToRegisters()— 数值 → 寄存器(从机编码)registersToValue()— 寄存器 → 数值(从机解码)
- 主从双方共享同一份实现,杜绝字节序不一致的隐蔽 bug
4.4 PID 无扰动切换(Bumpless Transfer)
- 自动→手动:
integral = clamp(manualValue - baseFreq - P - D, pidMin, pidMax) - 手动持续中:积分冻结(
freezeIntegral = true),不受补偿/DCS 冻结信号影响 - 手动→自动:积分已在上一步反算对齐,解除冻结后平滑接管
- 双重保护:手动模式下
freezeIntegral始终为true,外部冻结信号被忽略
4.5 定时器幂等清理与看门狗
- 所有
start*函数内部先clear*旧定时器再创建新定时器 - 所有
stop*函数级联清理子定时器(如 stopBackgroundPolling → stopConnectionHealthCheck) - PID 定时器卡死看门狗:
_stepRunning超过 3×采样周期 → 强制释放 - PID 周期溢出检测:跳过优于排队(
setInterval回调不 await) - 重连冷却期(10s):防止健康心跳与主轮询同时触发重连
4.6 配置原子写入
ConfigManager.save()采用三步原子写入:writeFileSync(tmpPath)— 写入临时文件copyFileSync(tmpPath → filePath)— 原子替换unlinkSync(tmpPath)— 清理临时文件
- 任意步骤失败均不影响已有配置文件完整性
4.7 全局异常守卫
uncaughtException→ error log + 退出快照unhandledRejection→ error log(不退出,仅记录)SIGINT/SIGTERM→ 退出快照 →process.exit(0)- 退出快照包含:内存使用/运行时长/轮询状态/保存状态/PID 状态/Modbus 诊断/报警状态
4.8 电源管理闭环(v1.0.0-rc2 新增)
powerSaveBlocker.start('prevent-display-sleep')返回的blockerId持久存储before-quit事件中显式调用powerSaveBlocker.stop(blockerId)- 防止进程异常残留导致用户屏幕永不熄灭
4.9 授权密钥混淆存储(v1.0.0-rc2 新增)
getSecretKey()废弃明文字符串直写,改为三部分 hex 编码存储- 运行时通过
Buffer.from(hex).toString()解码拼接 generateLicense.js同步更新密钥派生逻辑- 注意:此为代码混淆方案(提高逆向门槛),非密码学安全。生产环境建议升级为 RSA/ECDSA 非对称加密
4.10 默认密码安全(v1.0.0-rc2 新增)
- 三处
ensureDefault*函数不再调用hashPassword('plaintext')明文密码 - 改为直接写入预计算的 PBKDF2-SHA512 哈希字符串(100,000 次迭代,64 字节输出,16 字节随机盐)
- 明文密码不出现在任何源码文件或构建产物中
- 系统上线后应提示用户首次登录强制修改密码
4.11 配置备份路径修复(v1.0.0-rc2 新增)
- 配置备份导出默认路径从
__dirname(asar 内部/项目根目录)改为app.getPath('documents') - 备份文件不再污染项目根目录或 asar 归档
五、待开发功能
- PID 自整定 (auto-tuning)
- 报表自动生成(日报/月报 PDF)
- 国际化 (i18n)
- 多窗口支持
- OPC UA 协议支持
- 远程 Web 监控面板
六、已知技术债(2026-06-07 代码审查标记)
以下项目在 v1.0.0 打包审查中确认,当前架构已高度可读,本次打包不予执行,待后续版本迭代处理。
6.1 架构优化(暂缓)
- main.js 进一步拆分(当前 ~400 行,可接受):手动变量管理 →
services/manualVariableManager.js;解析规则加载 →services/parseRulesManager.js;初始化序列 →core/appInitializer.js;IPC deps 组装 →ipc/index.js - 渲染进程文件重组:JS 文件从
pages/平铺迁移至scripts/;共享工具移入shared/;CSS 移入styles/;仪表盘小组件移入widgets/ - dataDir 解析统一:4 个文件各自计算
dataDir(main.js/dataStore.js/authManager.js/alarmManager.js),应统一为services/pathResolver.js
6.2 模块内聚(暂缓)
- IPC 依赖注入一致性:
pidIpc.js/systemIpc.js/variableIpc.js内部直接requirevarRegistry 和 constants,与其他 IPC 模块的 deps 注入模式不一致 - 初始化序列显式化:
main.js初始化依赖仅靠注释和调用顺序保证,建议抽离为core/appInitializer.js并使用声明式阶段枚举
6.3 代码质量(暂缓)
- 日志级别控制:118 处
console.log/warn/error,建议引入LOG_LEVEL环境变量控制生产环境日志量 - 错误返回模式统一:部分函数返回
{success, message},部分抛 Error,部分返回 null,建议统一为{success, data, error}模式 - 渲染进程函数文档:
dashboard.js/modbusRender.js/pid.js等页面的核心函数缺少 JSDoc - 报警/PID 复杂算法流程图:报警延时触发状态机、PID 无扰动切换反算公式、补偿引擎状态机建议补充 ASCII 流程图注释
七、V1.1 版本技术债与长效架构优化清单
以下 4 项架构调整在 v1.0.0-rc4 终局审查中确认,当前系统表现完美,本次打包不予执行。待 V1.1 迭代时集中处理。
7.1 IPC deps 巨型对象分解(审计项 3.1)
-
目标:将
main.js中 63 属性的单体deps对象拆分为逻辑分组 -
方案:
1 2 3 4 5 6 7const ipcDeps = { electron: { ipcMain, BrowserWindow, dialog, shell, app }, modules: { modbus, modbusSlave, dataStore, alarmManager, authManager, ... }, config: { /* getter/setter 代理对 */ }, operations: { startBackgroundPolling, stopBackgroundPolling, ... }, state: { latestParsedItems, latestRawRegisters, ... }, }; -
收益:各 IPC 模块仅接收自己需要的分组,消除 " 全量注入 " 的隐式耦合
-
风险:涉及 7 个 IPC 文件 +
main.js的 deps 组装区,约 80 行变更 -
优先级:🟡 中 — 不影响功能,纯架构洁癖
7.2 systemIpc.js 关注点分离(审计项 3.2)
-
目标:将 272 行的
systemIpc.js(承载 9 个独立关注点)拆分为 5 个单一职责 IPC 文件 -
拆分方案:
新文件 职责 预计行数 ipc/systemHealthIpc.js健康状态聚合 + 变量元数据 ~50 ipc/configBackupIpc.js配置备份/恢复/列出/预览 ~120 ipc/dashboardIpc.js仪表盘布局读写 ~30 ipc/dialogIpc.js原生对话框 (showMessage/showConfirm) ~25 ipc/rulesFileIpc.js解析规则文件 CRUD ~35 -
收益:每个文件 ≤ 120 行,职责单一,易于独立测试和维护
-
风险:需在
main.js中新增 4 个require调用,IPC 通道名不变(对前端透明) -
优先级:🟡 中 — 当前 systemIpc.js 结构清晰,拆分非紧急
7.3 dataPipeline 内部函数暴露给 PID 层的耦合(审计项 3.4)
-
问题:
pidOrchestrator.js调用dataPipeline.applyFiltersToItems()时需构造伪 items 数组,绕过了管线的标准接口 -
方案:在
dataPipeline.js中新增专用函数:1 2 3function applyFiltersToValue(value, fieldName) { // 内部构造单元素 items,调用 applyFiltersToItems,返回过滤后的值 } -
收益:PID 层无需了解管线的内部数据结构(items 格式),通信通过语义化 API
-
风险:低 — 仅新增一个函数,不改变现有行为
-
优先级:🟢 低 — 功能正常,纯接口优化
7.4 渲染层大文件拆分(审计项 3.6)
-
目标:对渲染进程中超过 400 行的页面 JS 文件进行关注点分离
-
涉及文件(预估行数):
文件 关注点 建议拆分 pid.jsDOM 绑定 + API 调用 + ECharts 图表 + 状态轮询 pid-chart.js/pid-controls.jsmodbusRender.jsDOM 绑定 + API 调用 + 规则表编辑 + 诊断轮询 modbus-rules.js/modbus-diag.jsdashboard.js组件渲染 + 历史查询 + 拖拽 + 模板管理 dashboard-charts.js/dashboard-layout.js -
额外:8 个 HTML 文件中重复的
display: grid; grid-template-columns样式提取到index.css -
收益:单文件 ≤ 300 行,渲染进程可测试性提升
-
风险:中等 — 涉及 HTML
<script>标签变更,需逐页回归测试 -
优先级:🟢 低 — 当前渲染层运行稳定,拆分非紧急
八、版本历史
| 版本 | 日期 | 主要变更 |
|---|---|---|
| 1.0.0-rc4 | 2026-06-08 | 终局代码审查与精准重构(15 文件,全量通过 node –check):统一 dataDir 注入(4 模块废除自计算 electron require)+ alarmManager ConfigManager DI 解耦 + 电源事件监听器生命周期清理 + 关键空 catch 升级 writeErrorLog + 死代码删除(bufferToRegisterArray/loadArray/getRolePermissions)+ 密钥源去重(licenseKey.js)+ Modbus 异常码去重 + PID 写入退避逻辑从 Modbus 层上移至 PID 编排器 + 无扰动切换/Smith 预估器深度 JSDoc |
| 1.0.0-rc3 | 2026-06-07 | 史密斯预估器 + 系统工具:PID 新增史密斯预估器(FOPDT 偏差模型 + ZOH 精确离散 + 纯滞后环形缓冲区)+ 反向作用(error = PV − SP)+ 前馈控制 + 增益调度;新增系统工具页面(开机自启开关 + 配置文件勾选备份/恢复 + 数据备份触发 + 数据库大小展示);PID 趋势图新增预估 PV 紫色曲线 + 运行控制区预估 PV/SP/偏差对齐显示;派生变量 _smithPV 支持数据库存储分析;修正 Smith 初始化符号翻转 bug 及输入基准对齐;错误日志从按天滚动改为统一 error.log;data.html 风格对齐 auth.html |
| 1.0.0-rc2 | 2026-06-07 | 安全加固 + 代码审查:授权密钥三部分 hex 编码混淆存储;默认密码预计算 PBKDF2 哈希(明文密码从源码完全移除);电源休眠阻止器生命周期闭环(before-quit 释放);配置备份默认导出路径改为用户文档目录;清理 8 个残留在根目录/data 目录的临时/废弃文件;补全 pollEngine 重连退避策略文档注释;generateLicense.js 从构建混淆列表中移除 |
| 1.0.0-rc1 | 2026-06-07 | 架构重构完成:main.js 从 2,172 行缩减至 340 行(−84%);拆分为 7 个 core/ 自治模块;Modbus 工具去重统一于 modbusUtils.js;PID 新增无扰动切换;管线状态收拢至 dataPipeline.js;轮询引擎独立为 pollEngine.js;全部定时器幂等清理 + 看门狗保护 |
| 1.0.0-beta | 2026-06-01 | 初始开发完成:Modbus 主/从、PID、报警、补偿、仪表盘、用户管理、自登录、混淆保护 |