# 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}` | 异步命令结果 |
### 推送消息结构
```json
{
"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 内嵌)
├──
├──
```
---
## 七、实现优先级
| 优先级 | 页面 | 理由 |
|--------|------|------|
| 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 架构对比
```mermaid
graph TB
subgraph 原规格FEATURE_INVENTORY
A1["单文件 SPA
index.html 内嵌全部 CSS+JS"]
A2["CDN 加载 Lucide Icons"]
A3["单文件内分模块
WsClient/MonitorRing/App/SignalStore/Pages.*/UI.*"]
end
subgraph 当前实现web/
B1["多文件 SPA
index.html + 15 JS + 1 CSS"]
B2["内联 SVG Icons
Icon._map 18个Lucide图标"]
B3["独立文件模块
ws-client/signal-store/router/ui/i18n
+ 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) | ✅ 对齐 |
| **样式方案** | 单文件内嵌 `