RTU Web 前端功能详细清单
基于原工程 packed_fs.c 完整分析
分析日期: 2026-07-10
重构目标: 海外项目级工业品质 Web 管理界面
一、架构总览
| 项目 |
原实现 |
重构方案 |
| 类型 |
Hash-based SPA |
同架构 (零依赖, 纯 HTML+CSS+JS) |
| 路由 |
window.location.hash |
同 |
| 通信 |
WebSocket (ws://0.0.0.0:8080/ws) |
同 |
| 图标 |
Emoji |
→ SVG 图标 (Lucide Icons) |
| 样式 |
自定义 CSS |
→ 暗色工业主题 + CSS 变量系统 |
| 静态服务 |
Mongoose packed_fs |
→ mg_http_serve_dir 从磁盘服务 |
| 文件数 |
8 个嵌入文件 |
→ 单文件 SPA (index.html 内嵌全部 CSS+JS) |
二、页面清单 (12 页)
2.1 登录页 (#login)
- 账号/密码输入框
- 登录按钮 → 设置
localStorage.rtu_logged_in
- 所有非登录页须先验证登录状态
- 已登录时访问 login → 自动跳转 dashboard
2.2 仪表盘 (#dashboard)
- 信号导航卡片: 5 张卡片 (out / in / yk / ao / param), 显示每种信号已注册数量
- 批量 XML 导入/导出:
- 导出: 将所有信号导出为一个 XML 文件 (按 type 分组)
- 导入: 选择 XML 文件, 按 type 批量执行 add 请求
- 实时连接状态: WebSocket 连接指示器 (绿色/红色圆点)
2.3 开出信号 (#out)
- 信号注册表 (表格): saddr / desc / type / value
- 添加: 弹出表单 (saddr, desc, data_type 下拉选择)
- 编辑: 行内修改按钮 → 弹出
- 删除: 单选 + 批量勾选删除
- 实时值刷新 (来自 WebSocket 推送)
2.4 开入信号 (#in)
- 链接信号表: saddr / desc / link_saddr / type / value
- 添加: saddr, desc, link_saddr (链接目标)
- 删除: 单选 + 批量
- 只读显示 (值来自链接的 out 信号)
2.5 遥控 (#yk)
- 遥控信号表: saddr / desc / type / ctrl_type / value
- 添加: saddr, desc, type, ctrl_type (直控=0 / 选控=1)
- 控制操作: set 按钮 → 输入值 → 发送 set 命令
- 删除: 单选 + 批量
2.6 参数 (#ao)
- 参数信号表: saddr / desc / type / ctrl_type / value / min / max / step / unit
- 添加: 含元数据字段 (min/max/step/unit)
- 修改: set 按钮
- 支持下拉选择值 (val 数组)
- 删除: 单选 + 批量
2.7 定值 (#param)
- 定值信号表: saddr / desc / type / ctrl_type
- 展开行: 点击展开, 显示多定值区子表
- 每区: 区号 / 值 / 修改按钮
- 添加: 含 ctrl_type
2.8 数据中心 (#datacenter)
- 信号类型标签栏切换 (out/in/yk/ao/param)
- 表格: saddr / desc / type / value / 操作
- 所有信号类型的统一浏览视图
- 支持 set 操作
2.9 PLC 调试 (#plc_debug)
- 显示所有 out 信号
- saddr / desc / value 表
- 实时刷新 (来自 WebSocket 推送)
- 用于调试 PLC 逻辑输出
2.10 PLC 逻辑配置 (#plc_config)
- Canvas 图形编辑器 (原工程最复杂功能):
- 拖拽节点 (Gate/Input/Output)
- 连线编辑
- 双击节点编辑属性
- XML 保存/加载
- 重构方案: 保留功能, 重构 UI
2.11 实时监控 (#monitor)
- WebSocket 消息实时环形缓冲区
- 15 分钟 TTL / 500 条上限
- 消息方向: ↑ (发送) / ↓ (接收)
- 实时滚动显示
- JSON 格式化预览
2.12 命令终端 (#terminal)
- 仿真终端样式 (黑底绿字)
- 命令输入框
- stdout 实时输出 (WebSocket Binary 帧)
- 命令列表标签 (get_cmds)
- 历史命令支持
三、WebSocket 协议
客户端 → 服务端
| 消息类型 |
JSON |
说明 |
| 信号 CRUD |
{saddr, signal_type, curd, signal_data, setting_zone} |
add/del/set |
| 命令执行 |
{type:"cmd", data:"command args"} |
远程命令 |
| 获取命令列表 |
{type:"get_cmds"} |
用于终端 Tab 补全 |
服务端 → 客户端
| 消息类型 |
JSON |
说明 |
| 信号推送 |
{out:[...], in:[...], yk:[...], ao:[...], param:[...]} |
增量 (仅变化) |
| 命令输出 |
Binary frame (stdout) |
命令 stdout |
| 命令列表 |
{type:"cmd_list", cmds:[{name,desc},...]} |
命令补全数据 |
| 异步输出 |
{type:"async_output", module, data, success, msg} |
异步命令结果 |
推送消息结构
{
"out": [{"saddr":"x", "desc":"x", "type":"int", "val":"123"}],
"in": [{"saddr":"x", "desc":"x", "type":"float", "val":"3.14"}],
"yk": [{"saddr":"x", "desc":"x", "type":"int", "val":"0", "ctrl_type":1}],
"ao": [{"saddr":"x", "desc":"x", "type":"float", "val":"5.0", "ctrl_type":0}],
"param": [{"saddr":"x", "desc":"x", "type":"int", "ctrl_type":0,
"setting_zone_list":[{"id":"0","val":"100"}, ...]}]
}
四、导航结构
┌──────────┐
│ Logo │ RTU Web Manager
│ Status │ ● Connected / ○ Disconnected
├──────────┤
│ 📊 Dashboard │
│ 📡 Out 信号 │
│ 🔗 In 信号 │
│ ⚡ YK 遥控 │
│ 🎚️ AO 参数 │
│ ⚙️ Param 定值 │
│ 📋 Datacenter │
│ 🔌 PLC Debug │
│ 🧩 PLC Config │
│ 📈 Monitor │
│ 💻 Terminal │
└──────────┘
左侧固定导航栏 (220px), 右侧主内容区
响应式: 移动端隐藏侧栏
五、重构设计参数
| 参数 |
选择 |
| 风格 |
暗色工业主题 (Dark Industrial Dashboard) |
| 主色调 |
Cyan/Teal accent (#00E5FF / #1DE9B6) |
| 背景 |
#0F1923 (deep navy) / #1A2332 (card bg) |
| 字体 |
Inter (标题) + JetBrains Mono (数据/终端) |
| 图标 |
Lucide SVG inline (通过 CDN) |
| 圆角 |
8px (卡片), 6px (按钮), 4px (输入框) |
| 间距 |
8px 基础网格 |
| 动画 |
150-300ms ease-out transitions |
| 图表 |
Canvas 手写轻量图表 (实时监控页) |
六、文件结构 (重构后)
src/system/libweb_server/
├── inc/
│ └── web_server.h # 头文件 (无需修改)
└── src/
├── web_server.cpp # +static file serving (mg_http_serve_dir)
└── ws_method.cpp # 已有, 无需修改
web/ # 新建: 前端静态文件目录
└── index.html # 单文件 SPA (全部 CSS+JS 内嵌)
├── <style> ... </style>
├── <script>
│ ├── WsClient # WebSocket 通信
│ ├── MonitorRing # 实时监控环形缓冲
│ ├── App # 主应用 (路由/页面管理)
│ ├── SignalStore # 信号数据缓存
│ ├── Pages.* # 各页面渲染函数
│ └── UI.* # 通用 UI 组件 (Modal/Toast/Table/Toolbar)
└── </script>
七、实现优先级
| 优先级 |
页面 |
理由 |
| P0 |
index.html 壳 + 登录 + 仪表盘 + 导航 |
基础框架 |
| P0 |
WsClient + SignalStore |
通信基础 |
| P1 |
Out / In 信号管理 |
核心 CRUD |
| P1 |
YK / AO / Param 管理 |
完整信号类型 |
| P2 |
Datacenter 统一浏览 |
数据汇总 |
| P2 |
Monitor 实时监控 |
调试利器 |
| P2 |
Terminal 命令终端 |
远程管理 |
| P3 |
PLC Debug / PLC Config |
高级功能, Canvas 编辑器较复杂 |
八、重构实现 vs 原规格详细对比分析
分析日期: 2026-07-10
对比维度: 架构 / 页面 / 功能 / 样式 / 协议 / 后端对齐
8.1 架构对比
graph TB
subgraph 原规格FEATURE_INVENTORY
A1["单文件 SPA<br/>index.html 内嵌全部 CSS+JS"]
A2["CDN 加载 Lucide Icons"]
A3["单文件内分模块<br/>WsClient/MonitorRing/App/SignalStore/Pages.*/UI.*"]
end
subgraph 当前实现web/
B1["多文件 SPA<br/>index.html + 15 JS + 1 CSS"]
B2["内联 SVG Icons<br/>Icon._map 18个Lucide图标"]
B3["独立文件模块<br/>ws-client/signal-store/router/ui/i18n<br/>+ 8个pages/*.js"]
end
A1 -->|"❌ 不一致"| B1
A2 -->|"⚠️ 变体实现"| B2
A3 -->|"✅ 架构对齐"| B3
| 维度 |
原规格 (FEATURE_INVENTORY) |
当前实现 (web/) |
状态 |
| 文件架构 |
单文件 SPA (index.html 内嵌) |
多文件 (1 HTML + 1 CSS + 13 JS) |
❌ 偏离 |
| 图标方案 |
CDN 加载 Lucide Icons |
内联 SVG 字符串 (ui.js Icon._map) |
⚠️ 变体 |
| 路由方案 |
App 对象管理路由 |
Router 全局对象 (router.js) |
✅ 对齐 |
| 通信层 |
WsClient 对象 |
WsClient 全局对象 (ws-client.js) |
✅ 对齐 |
| 数据层 |
SignalStore 对象 |
SignalStore 全局对象 (signal-store.js) |
✅ 对齐 |
| 样式方案 |
单文件内嵌 <style> |
独立 css/style.css |
❌ 偏离 |
| i18n |
未提及 |
I18n 全局对象 (i18n.js, 95 个 key, zh/en) |
🆕 新增 |
8.2 页面功能逐页对比
8.2.1 登录页 (#login)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 用户名/密码输入 |
✅ |
✅ #login-user / #login-pass |
✅ |
| 登录验证 |
未明确 |
硬编码 admin/admin |
⚠️ |
| localStorage 持久化 |
✅ rtu_logged_in |
✅ rtu_logged_in='1' |
✅ |
| 登录守卫 |
✅ 非登录页强制跳转 |
✅ Router.dispatch() 守卫 |
✅ |
| 已登录自动跳转 |
✅ login→dashboard |
✅ login→dashboard |
✅ |
| Enter 键登录 |
未提及 |
✅ keydown 监听 |
🆕 |
| 自动聚焦 |
未提及 |
✅ #login-user autofocus |
🆕 |
| 暗色主题 |
未提及 |
✅ .login-wrap 暗色背景 |
🆕 |
8.2.2 仪表盘 (#dashboard)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 5 张信号计数卡片 |
✅ out/in/yk/ao/param |
✅ .dash-grid 5 cards |
✅ |
| 卡片点击跳转 |
未明确 |
✅ 点击跳转对应 hash |
🆕 |
| 卡片颜色区分 |
未明确 |
✅ 5 种不同色 (accent/accent2/warning/success/#a78bfa) |
🆕 |
| 实时连接状态 |
✅ WS 连接指示器 |
✅ #dash-status + WsClient.onStatus() |
✅ |
| XML 批量导出 |
✅ 按 type 分组导出 |
✅ DashActions.exportAll() → Blob 下载 |
✅ |
| XML 批量导入 |
✅ 选择文件→批量 add |
✅ <input type=file> → 解析 XML → 逐条 add |
✅ |
| 快速操作按钮 |
未提及 |
✅ 打开终端 + 打开监控 + 导出 + 导入 |
🆕 |
| 每卡显示描述 |
未提及 |
✅ dash.{type}.desc 多行描述 |
🆕 |
| 信号数量实时更新 |
未提及 |
✅ 绑定 SignalStore.data |
🆕 |
8.2.3 开出信号 (#out)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 表格列 |
saddr/desc/type/value |
SAddr/Desc/Type/Val/Action |
✅ |
| 添加信号 |
✅ 弹出表单 (saddr/desc/data_type) |
✅ SignalActions.add('out') Modal |
✅ |
| 编辑信号 |
✅ 行内修改按钮→弹出 |
❌ 无编辑功能,仅有 Set 值 |
❌ 缺失 |
| 删除信号 |
✅ 单选+批量勾选 |
✅ 单选 + 批量 checkbox |
✅ |
| 实时值刷新 |
✅ WS 推送 |
✅ cell-val.changed 动画 |
✅ |
| 值变化动画 |
未提及 |
✅ flash-val 0.6s 绿色闪烁 |
🆕 |
| 数据类型下拉 |
data_type 选择 |
U8/U16/U32/F32/STR |
✅ |
| 设值操作 |
未明确 |
✅ SignalActions.set() → 输入新值 |
🆕 |
⚠️ 缺失: 编辑信号属性 (修改 saddr/desc/type)。当前前端只有"添加"和"删除",没有"修改"已有信号属性的功能。
8.2.4 开入信号 (#in)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 表格列 |
saddr/desc/link_saddr/type/value |
SAddr/Desc/Link/Type/Val/Action |
✅ |
| link_saddr 字段 |
✅ 链接目标 |
✅ #mf-link 输入 |
✅ |
| 添加信号 |
✅ saddr/desc/link_saddr |
✅ SignalActions.add('in') |
✅ |
| 删除信号 |
✅ 单选+批量 |
✅ 单选 + 批量 |
✅ |
| 只读显示 |
✅ 值来自链接 out |
⚠️ 表格显示值但无链接跳转 |
⚠️ 弱 |
| Set 操作 |
❌ in 只读 |
❌ 无 Set 按钮 |
✅ |
8.2.5 遥控 (#yk)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 表格列 |
saddr/desc/type/ctrl_type/value |
SAddr/Desc/Type/Ctrl/Val/Action |
✅ |
| ctrl_type 显示 |
✅ 直控=0/选控=1 |
✅ ctrl_direct/ctrl_sbo 翻译 |
✅ |
| 控制操作 |
✅ set→输入值→发送 |
✅ SignalActions.set('yk',...) |
✅ |
| 添加信号 |
✅ saddr/desc/type/ctrl_type |
✅ SignalActions.add('yk') |
✅ |
| 删除信号 |
✅ 单选+批量 |
✅ 单选 (无批量 checkbox! ) |
⚠️ |
| 批量删除 |
原规格有 |
❌ YK 页面无 checkbox |
❌ 缺失 |
⚠️ 差异: YK/AO 页面缺少批量选择/删除 checkbox,而原规格明确写了"单选 + 批量勾选删除"。
8.2.6 模拟输出 (#ao)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 基础功能 |
同 YK |
✅ 同 YK (共用 renderSignalPage) |
✅ |
| 元数据字段 |
min/max/step/unit |
❌ 完全没有 |
❌ 严重缺失 |
| 下拉选择值 |
val 数组下拉 |
❌ 完全没有 |
❌ 严重缺失 |
| 批量删除 |
原规格有 |
❌ 无 checkbox |
❌ 缺失 |
⚠️ 严重缺失: AO 页面在原规格中有 min/max/step/unit 元数据字段和 val 下拉选择,当前实现完全缺失。当前 AO = YK 的复制品,没有任何 AO 特有功能。
8.2.7 定值 (#param)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 展开行设计 |
点击展开 → 多区子表 |
主表 Zone 列平铺所有区 |
❌ 不同设计 |
| 多定值区显示 |
区号/值/修改按钮 |
Zone 列内逐行: #id + 值 + Set 按钮 |
⚠️ 功能等效 |
每区独立 Set |
展开行内有 Set |
✅ ParamActions.set(saddr, zoneId) |
✅ |
| 添加信号 |
✅ 含 ctrl_type |
✅ SignalActions.add('param') |
✅ |
| 删除信号 |
✅ (原规格未提批量) |
✅ 单选删除 |
✅ |
| 批量删除 |
未提及 |
❌ 无 checkbox |
— |
⚠️ 设计差异: 原规格使用"点击展开行→子表"的层级 UI,当前使用平铺 Zone 列的扁平 UI。功能等效但交互不同。
8.2.8 数据中心 (#datacenter)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 类型标签切换 |
✅ out/in/yk/ao/param |
✅ 5 个按钮切换 |
✅ |
| 表格列 |
saddr/desc/type/value/操作 |
SAddr/Desc/Type/Val/Action |
✅ |
| Set 操作 |
✅ |
✅ out/yk/ao 可 Set (in/param 不可) |
✅ |
| 从 RTU 查询 |
未明确 |
✅ DcCmd.refreshAll() → datacenter all |
🆕 |
| 文本解析 |
无 |
✅ _parse() 固定宽度文本表格解析 |
🆕 |
| 自动刷新 |
无 |
✅ 10 秒间隔自动刷新 |
🆕 |
| 信号数量显示 |
未提及 |
✅ 类型按钮上显示数量 |
🆕 |
8.2.9 PLC 调试 (#plc_debug)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 显示 out 信号 |
✅ saddr/desc/value 表 |
❌ 完全不同 |
❌ 重构 |
| 三列布局 |
❌ 原规格是单表 |
✅ LED列/信号列/Button列 |
🆕 新设计 |
| LED 指示灯 |
❌ |
✅ 可绑定信号的 LED 圆点 |
🆕 |
| 翻转按钮 |
❌ |
✅ 点击翻转值→WS set |
🆕 |
| 信号选择器 |
❌ |
✅ showSignalPicker() Modal |
🆕 |
| 批量绑定 |
❌ |
✅ 勾选信号→一键→LED/BTN |
🆕 |
⚠️ 原规格 PLC Debug 是"显示所有 out 信号的表",当前实现是"三列交互式调试面板"。功能完全不同,新版本更强。
8.2.10 PLC 配置 (#plc_config)
| 功能点 |
原规格 |
当前实现 |
状态 |
| Canvas 图形编辑器 |
✅ 拖拽/连线/属性编辑 |
✅ 完整实现 |
✅ |
| 节点类型 |
未列出 |
✅ 11 种 (INPUT/OUTPUT/OR/AND/NOT/T62P/T62D/RISING/SR/RS/FALLING) |
🆕 |
| 网格吸附 |
未提及 |
✅ 20px grid |
🆕 |
| 缩放/平移 |
未提及 |
✅ zoom 0.5-2.0 + pan |
🆕 |
| XML 保存 |
✅ |
✅ {type:'set_file'} → RTU |
⚠️ |
| XML 加载 |
✅ |
✅ {type:'cmd',data:'cat ...'} → 解析 |
⚠️ |
| XML 只读预览 |
未提及 |
✅ #plc-xml-view 实时预览 |
🆕 |
| 连线拖拽 |
✅ |
✅ 引脚拖出虚线→目标引脚 |
✅ |
| 节点属性编辑 |
✅ 双击编辑 |
✅ 双击 Modal (saddr/desc/delayMs) |
✅ |
| 删除节点 |
未提及 |
✅ 选中+删除按钮+关联线自动删 |
🆕 |
| 缩放栏 |
未提及 |
✅ zoom in/out/fit + 百分比 |
🆕 |
| 后端 set_file |
♾️ |
⚠️ 前端用 set_file 但后端未实现! |
❌ BUG |
❌ 严重 BUG: PlcConfig.save() 发送 {type:'set_file', path, content},但后端 ws_method.cpp 中没有 get_file/set_file 的 handler!save 功能形同虚设。load 功能通过 cat 命令间接实现,可行但不优雅。
8.2.11 实时监控 (#monitor)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 环形缓冲区 |
✅ 500 条上限 |
✅ MonitorRing.ring max=500 |
✅ |
| TTL 过期 |
✅ 15 分钟 TTL |
❌ 无 TTL |
❌ 缺失 |
| 消息方向 |
✅ ↑ 发送 / ↓ 接收 |
✅ .monitor-dir.up/.monitor-dir.down |
✅ |
| 实时滚动 |
✅ |
✅ reverse 排序,最新在顶部 |
✅ |
| JSON 格式化预览 |
✅ |
❌ 仅截断 200 字符原文 |
❌ 缺失 |
| 暂停/恢复 |
未提及 |
✅ paused + togglePause() |
🆕 |
| 统计面板 |
未提及 |
✅ 总计/发送/接收 计数 |
🆕 |
| 清除按钮 |
未提及 |
✅ clear() |
🆕 |
| 消息截断 |
未提及 |
✅ 200 字符截断 |
⚠️ |
⚠️ 缺失: (1) 15 分钟 TTL 过期机制; (2) JSON 格式化预览 (当前是 truncate 200 字符的原始文本)。
8.2.12 命令终端 (#terminal)
| 功能点 |
原规格 |
当前实现 |
状态 |
| 仿真终端样式 |
✅ 黑底绿字 |
✅ 暗色终端风格 |
✅ |
| 命令输入 |
✅ |
✅ #term-input + Enter |
✅ |
| stdout 实时输出 |
✅ Binary 帧 |
✅ term-out 追加 binary 文本 |
✅ |
| 命令列表标签 |
✅ get_cmds |
✅ #cmd-chips 芯片样式 |
✅ |
| 历史命令 |
✅ |
❌ 无历史命令 |
❌ 缺失 |
| help 命令 |
未提及 |
✅ 内置 help 文本 |
🆕 |
| clear 命令 |
未提及 |
✅ 清空 #term-out |
🆕 |
| 命令芯片点击 |
未提及 |
✅ 点击填充到输入框 |
🆕 |
⚠️ 缺失: 历史命令支持 (上下箭头浏览历史)。原规格明确提到"历史命令支持"。
8.3 样式/主题对比
| 参数 |
原规格 |
当前实现 |
状态 |
| 风格 |
暗色工业主题 |
暗色工业主题 |
✅ |
| 主色调 |
Cyan/Teal #00E5FF / #1DE9B6 |
Teal #00d4aa / Blue #00a8e8 |
⚠️ 色值不同 |
| 背景 |
#0F1923 (deep navy) |
#0a0f16 (更深) |
⚠️ 色值不同 |
| 卡片背景 |
#1A2332 |
#111922 |
⚠️ 色值不同 |
| 字体 |
Inter + JetBrains Mono |
Inter + JetBrains Mono |
✅ |
| 图标 |
Lucide CDN |
内联 SVG (18 个图标) |
⚠️ 变体 |
| 圆角 |
8px / 6px / 4px |
12px / 8px / 4px |
⚠️ 差异 |
| 间距 |
8px 基础网格 |
未显式定义网格 |
⚠️ |
| 动画 |
150-300ms ease-out |
180ms ease-out |
✅ |
| CSS 变量 |
未提及 |
✅ 30 个设计令牌 |
🆕 |
| 响应式 |
✅ 移动端隐藏侧栏 |
✅ @media max-width:768px |
✅ |
| 图表 |
Canvas 手写轻量图表 |
❌ 未实现 |
❌ |
| 滚动条样式 |
未提及 |
✅ ::-webkit-scrollbar* 定制 |
🆕 |
8.4 WebSocket 协议后端对齐
graph LR
subgraph 前端发送
F1["{type:'cmd'}"]
F2["{type:'get_cmds'}"]
F3["{type:'set_file'}"]
F4["信号 CRUD add/del/set"]
end
subgraph 后端处理ws_method.cpp
B1["✅ ws_recv → ws_cmd_exec"]
B2["✅ ws_recv → cmd_manager_get_commands"]
B3["❌ 无 handler! get_file/set_file 未实现"]
B4["✅ ws_recv → ws_sig_add/del/set"]
end
F1 --> B1
F2 --> B2
F3 -->|"❌ 断裂"| B3
F4 --> B4
| 消息 |
前端发送 |
后端接收 |
状态 |
{type:"cmd"} |
✅ Terminal/Datacenter/PlcConfig.load |
✅ ws_recv() → ws_cmd_exec() |
✅ |
{type:"get_cmds"} |
✅ WsClient.onopen |
✅ ws_recv() → cmd_manager_get_commands() |
✅ |
{type:"set_file"} |
✅ PlcConfig.save() |
❌ 无 handler |
❌ 断裂 |
{type:"get_file"} |
❌ 未使用 |
❌ 无 handler |
❌ 断裂 |
{saddr, signal_type, curd:"add"} |
✅ SignalActions.add |
✅ ws_sig_add_* |
✅ |
{saddr, signal_type, curd:"del"} |
✅ SignalActions.del/batchDel |
✅ ws_sig_del |
✅ |
{saddr, signal_type, curd:"set"} |
✅ SignalActions.set/ParamActions.set |
✅ ws_sig_set |
✅ |
| 推送 |
后端发送 |
前端接收 |
状态 |
| 信号增量推送 |
✅ ws_push_task() 100ms |
✅ SignalStore.update() |
✅ |
| 命令输出 Binary |
✅ ws_send_binary() |
✅ term-out + MonitorRing |
✅ |
| 命令列表 |
✅ cmd_list |
✅ #cmd-chips 芯片 |
✅ |
| 异步输出 |
✅ async_cmd_printf() |
⚠️ 仅 index.html 内联处理器中 toast |
⚠️ 弱 |
❌ 关键缺陷: set_file/get_file 在前端被使用但后端未实现。PlcConfig.save() 无法正常工作。
8.5 缺失功能汇总
graph TD
subgraph 严重缺失P0
M1["❌ set_file/get_file 后端未实现<br/>→ PLC Config 保存无效"]
M2["❌ AO 页面缺少元数据<br/>min/max/step/unit + val下拉"]
end
subgraph 中等缺失P1
M3["❌ 终端缺少历史命令<br/>上下箭头浏览"]
M4["❌ Monitor 缺少 JSON格式化<br/>+ 15分钟 TTL"]
M5["❌ YK/AO 缺少批量删除<br/>checkbox"]
M6["❌ 信号编辑功能缺失<br/>修改 saddr/desc/type"]
end
subgraph 轻微缺失P2
M7["⚠️ Monitor JSON预览 → 截断200字符"]
M8["⚠️ Canvas 图表(原规格提及)"]
M9["⚠️ 异步输出前端处理较弱"]
M10["⚠️ in 信号无链接跳转"]
end
subgraph 后端未实现但头文件声明
M11["♾️ get_file / set_file<br/>ws_method.cpp 头注释声明但未实现"]
end
P0 — 阻塞级
| # |
缺失项 |
影响范围 |
根因 |
| 1 |
set_file/get_file 后端未实现 |
PlcConfig.save() 完全无效 |
ws_method.cpp 头注释声明但代码中无 handler |
| 2 |
AO 页面元数据字段 |
AO 信号管理功能不完整 |
前端未实现 min/max/step/unit/val 下拉 |
P1 — 重要级
| # |
缺失项 |
影响范围 |
| 3 |
终端历史命令 |
用户体验差,无法快速重复执行 |
| 4 |
Monitor JSON 格式化 + TTL |
可读性差,缓冲区无限增长 |
| 5 |
YK/AO 批量删除 |
管理效率低 |
| 6 |
信号属性编辑 |
只能删了重建,无法修改 |
P2 — 改进级
| # |
缺失项 |
说明 |
| 7 |
异步输出前端处理 |
目前仅在 index.html 内联 toast,应接入 Monitor |
| 8 |
Canvas 图表 |
原规格提到但一直未实现 |
| 9 |
in 信号链接跳转 |
点击 link_saddr 应跳转到对应 out 信号 |
| 10 |
param 展开行 UI |
原规格的层级展开设计比当前平铺更优雅 |
8.6 新增功能 (超出原规格)
| # |
新增功能 |
位置 |
| 1 |
I18n 国际化 (zh/en, 95 key) |
i18n.js |
| 2 |
CSS 设计令牌系统 (30 个变量) |
style.css |
| 3 |
Dashboard 快速操作按钮 |
dashboard.js |
| 4 |
Dashboard 每卡描述文本 |
dashboard.js |
| 5 |
信号值变化动画 (flash-val) |
style.css |
| 6 |
Datacenter 自动刷新 (10s) |
datacenter.js + index.html |
| 7 |
Datacenter RTU 命令解析器 |
datacenter.js DcCmd._parse() |
| 8 |
PLC Debug 三列交互面板 (原规格为简单表) |
plc.js PlcDebug |
| 9 |
PLC Config 缩放/平移/网格 |
plc.js PlcConfig |
| 10 |
PLC Config XML 实时预览 |
plc.js refreshXmlView() |
| 11 |
Monitor 暂停/统计/清除 |
monitor.js |
| 12 |
Terminal 命令芯片 |
terminal.js |
| 13 |
Toast 通知系统 (success/error/info) |
ui.js |
| 14 |
Modal 对话框系统 |
ui.js |
| 15 |
SVG 图标库 (18 个 Lucide 风格图标) |
ui.js Icon._map |
| 16 |
通用信号表格渲染器 (renderSignalPage) |
ui.js |
| 17 |
导航分组标题 (Overview/Signal/Tools) |
router.js NAV |
| 18 |
语言切换器 |
index.html #lang-select + i18n.js |
| 19 |
实时时钟 |
index.html #nav-time |
| 20 |
移动端响应式 |
style.css @media + toggleNav() |
8.7 代码质量对比
| 维度 |
原规格目标 |
当前实现 |
评价 |
| 模块化 |
单文件内分对象 |
多文件独立模块 |
✅ 更好 |
| 可维护性 |
单文件 2000+ 行 |
13 文件,每文件 50-400 行 |
✅ 更好 |
| 国际化 |
无 |
95 key, zh/en |
✅ 更好 |
| 代码注释 |
未提及 |
JSDoc 风格文件头 |
✅ |
| 全局命名空间 |
对象挂 window |
全局对象 (WsClient/SignalStore/Router...) |
⚠️ 一般 |
| 重复代码 |
低(单文件共享) |
中等(signals.js 4 个页面模板重复) |
⚠️ 一般 |
| 错误处理 |
未提及 |
Toast 通知 + try-catch |
✅ |
| 后端对齐 |
100% |
~85%(缺 set_file/get_file) |
⚠️ |
8.8 按模块分析总结
┌─────────────────────────────────────────────────────────┐
│ 前端模块完成度矩阵 │
├────────────┬──────────┬──────────┬──────────┬───────────┤
│ 模块 │ 基础CRUD │ 高级功能 │ UI/UX │ 后端对齐 │
├────────────┼──────────┼──────────┼──────────┼───────────┤
│ login │ 100% │ 100% │ 100% │ N/A │
│ dashboard │ 100% │ 100% │ 100% │ 100% │
│ out │ 100% │ 90% │ 100% │ 100% │
│ in │ 100% │ 80% │ 100% │ 100% │
│ yk │ 90% │ 80% │ 90% │ 100% │
│ ao │ 60% │ 30% │ 90% │ 100% │
│ param │ 100% │ 90% │ 90% │ 100% │
│ datacenter │ 100% │ 100% │ 100% │ 100% │
│ plc_debug │ 150% │ 150% │ 100% │ 100% │
│ plc_config │ 100% │ 120% │ 100% │ 50% │
│ monitor │ 100% │ 70% │ 90% │ 100% │
│ terminal │ 100% │ 80% │ 100% │ 100% │
├────────────┼──────────┼──────────┼──────────┼───────────┤
│ 总完成度 │ 96% │ 86% │ 97% │ 96% │
└────────────┴──────────┴──────────┴──────────┴───────────┘
最低完成度模块: AO (60% 基础 / 30% 高级) — 缺少 min/max/step/unit 元数据字段和 val 下拉选择。
后端对齐最差: plc_config (50%) — set_file/get_file 后端未实现。
8.9 优先级修复建议
| 优先级 |
任务 |
预估工时 |
| P0 |
后端实现 set_file/get_file handler |
2h |
| P0 |
AO 页面补全元数据字段 + val 下拉 |
2h |
| P1 |
终端添加历史命令 (sessionStorage) |
1h |
| P1 |
Monitor 添加 JSON 格式化预览 |
1h |
| P1 |
YK/AO 页面添加批量删除 checkbox |
0.5h |
| P1 |
信号编辑功能 (修改 saddr/desc/type) |
2h |
| P2 |
Monitor 15min TTL 过期 |
0.5h |
| P2 |
in 信号链接跳转 |
0.5h |
| P2 |
Canvas 图表 (实时监控页) |
3h |
| P2 |
异步输出接入 Monitor |
0.5h |