# PLC 配置页面原始功能详细规格 > 基于原工程 libplc C 引擎 + Reclose_logic.xml 完整分析 > 分析日期: 2026-07-10 > 目标: 重构前端 PLC Config 页面,做到比原工程更好 --- ## 一、PLC 系统架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ RTU 运行时 │ │ │ │ config/PLC/Reclose_logic.xml ──→ pls.cpp parse_reclose_logic │ │ (mtime 文件变化检测, stat) │ │ │ ↓ │ │ LogicGraph[] (最多4个) │ │ │ │ │ EV_TIMER3 (1s) │ │ ↓ │ │ PLC_Logic() 执行: │ │ 1. 读取 datacenter input 信号 │ │ 2. Kahn 拓扑排序 │ │ 3. 按拓扑序执行各门逻辑 │ │ 4. 写入 datacenter output 信号 │ └─────────────────────────────────────────────────────────────────┘ ``` ## 二、XML 格式完全规格 (Reclose_logic.xml) ### 顶层结构 ```xml ... ... ... ... ... ... ... ... ``` ### 关键节点类型 (10 种) | type | Name | 功能 | 参数 | 输入引脚 | 输出引脚 | |------|------|------|------|:---:|:---:| | 0 | INPUT | 硬件输入, 从 datacenter 读取值 | no=信号ID | 0 | 1 | | 1 | OUTPUT | 硬件输出, 写入 datacenter | no=信号ID | 1 | 0 | | 2 | OR | 或门, 任意输入=1→输出1 | id=门ID | 2 | 1 | | 3 | AND | 与门, 全部输入=1→输出1 | id=门ID | 2 | 1 | | 4 | NOT | 非门, 取反 | id=门ID | 1 | 1 | | 5 | T62P | 延时导通 (IN=1 等待 delayMs ms 后 OUT=1) | id, delayMs | 1 | 1 | | 6 | T62D | 延时关断 (IN=0 等待 delayMs ms 后 OUT=0) | id, delayMs | 1 | 1 | | 7 | RISING | 上升沿检测 (0→1 产生一周期脉冲) | id | 1 | 1 | | 8 | SR | SR 触发器 (S优先: S=1置位, R=1& S=0复位) | id, S, R | 2 (S=0, R=1) | 1 | | 9 | RS | RS 触发器 (R优先: R=1复位, S=1& R=0置位) | id, S, R | 2 (S=0, R=1) | 1 | | 10 | FALLING | 下降沿检测 (1→0 产生一周期脉冲) | id | 1 | 1 | ### Comb 的 C 引擎自动检测逻辑 ``` parse_xml_comb(comb_el, graph): 1. 遍历 comb_el 的子元素 (, , , ) 2. 遇到子 → 递归调用 parse_xml_comb() ← 这就是嵌套自动检测 3. 子 Comb 的 Gate 输出 → 父 Comb 的 Gate 输入 (自动连线) 4. 遇到 → 创建 HW_INPUT 节点 → 连线到同层 Gate 5. 遇到 → 创建门节点 + 解析 R/S 属性 - R="Comb#N" → 查找子 Comb 中对应 Gate 的输出 - S="Comb#N" → 同上 - R="Input#N" / S="Input#N" → 创建对应 Input 节点 6. 遇到 → 创建 HW_OUTPUT 节点 → 连线从同层 Gate 链级别 Comb 处理 (第二遍布线): 1. Comb 的 Gate 输出 → 链级 Gate 输入 2. 链级 Input → 链级 Gate 3. 链级 Gate → 链级 Output ``` **核心结论: Comb 是 XML 中天然存在的嵌套结构,C 引擎自动递归解析。前端应该:** - 加载 XML 时自动识别 Comb 嵌套关系 - 渲染为视觉分组容器 (矩形框) - 允许用户通过拖拽节点入框来创建 Comb - 不允许手动添加空 Comb --- ## 三、原工程 PLC Config 前端功能详细清单 ### 3.1 导航与入口 - Hash 路由: `#plc_config` - 导航标签: "PLC 配置" / "PLC Config" - 导航图标: 原工程用 emoji 🧩, 当前用 SVG cpu ### 3.2 多 Chain 管理 | 功能 | 描述 | 实现方式 | |------|------|---------| | **Chain 标签切换** | 顶部标签栏,每个 Chain 一个标签 | 点击切换当前编辑的 Chain | | **Chain 标签内容** | 显示 "Chain N (节点数)" | 实时更新 | | **添加 Chain** | +Chain 按钮 | 创建空 Chain, 自动切换 | | **删除 Chain** | -Chain 按钮 | 删除当前 Chain (≥2个时可用) | ### 3.3 节点类型工具栏 每种节点类型一个按钮,点击后在 Canvas 随机位置添加: ``` [+INPUT] [+OUTPUT] [+OR] [+AND] [+NOT] [+T62P] [+T62D] [+RISING] [+SR] [+RS] [+FALLING] ``` ### 3.4 Canvas 画布编辑器 | 功能 | 描述 | 交互 | |------|------|------| | **节点渲染** | 圆角矩形 + 类型名 + ID号 + 颜色区分 | 11种颜色方案 | | **引脚圆点** | 输入引脚(左, 彩色), 输出引脚(右, 绿色) | 5px 半径 | | **连线渲染** | 节点间实线, 从输出引脚→输入引脚 | 深灰 #2c3e50 | | **拖拽节点** | 按住节点拖动 | 20px 网格吸附 | | **连线操作** | 从输出引脚拖出虚线→目标输入引脚释放 | 红色虚线 | | **选中节点** | 单击节点高亮 | 白色填充 + 红色边框 | | **删除节点** | 选中 + 删除按钮 | 同时删除关联连线 + 重编号 Gate ID | | **平移画布** | 拖拽空白区域 | 平移 | | **缩放** | 滚轮缩放 0.5x-2.0x | 缩放栏显示百分比 | | **缩放栏** | [放大] [缩小] [适应] 100% | 适应 = zoom=1, pan=0 | | **双击编辑** | 双击节点弹出属性 Modal | 编辑 saddr/desc/delayMs/spin/rpin | ### 3.5 Comb 组合块 | 功能 | 描述 | |------|------| | **自动识别** | 加载 XML 时自动解析 Comb 嵌套结构 | | **视觉渲染** | 虚线圆角矩形,标签 "Comb #N" | | **嵌套 Comb** | 视觉上子 Comb 在父 Comb 内部 | | **节点归属** | Comb 内节点在视觉上位于 Comb 矩形内 | | **创建 Comb** | 选中多个节点 → "成组为 Comb" 创建 | | **解散 Comb** | 选中 Comb → "解散 Comb" → 节点回到链级别 | ### 3.6 XML 查看与持久化 | 功能 | 描述 | |------|------| | **XML 实时预览** | 只读 `
` 标签, 随编辑实时更新 |
| **加载 XML** | 从 RTU 读取 `cat config/PLC/Reclose_logic.xml` |
| **保存 XML** | 通过 WS `set_file` 写回 RTU |
| **checksum** | 根节点自动计算 XOR checksum |

### 3.7 操作按钮栏

```
[加载 XML] [保存 XML] [清空] [删除选中节点]
```

---

## 四、原工程 UI 设计参考

### 4.1 设计风格

| 参数 | 原设计值 | 当前值 |
|------|---------|--------|
| 风格 | 暗色工业主题 (Dark Industrial Dashboard) | 暗色工业主题 |
| 主色调 | Cyan/Teal (#00E5FF / #1DE9B6) | Teal (#00d4aa) |
| 背景 | #0F1923 (deep navy) | #0a0f16 (更深) |
| 卡片背景 | #1A2332 | #111922 |
| 字体 | Inter + JetBrains Mono | 同 |
| 图标 | Emoji (原工程) → SVG Lucide (重构目标) | SVG 内联 Lucide |
| Canvas 背景 | 浅色网格 (#f0f2f5) | 同 |

### 4.2 导航图标规格

| 页面 | 原 Emoji | Lucide SVG 图标名 | 说明 |
|------|---------|------------------|------|
| 仪表盘 | 📊 | dashboard | 四象限网格 |
| 开出信号 | 📡 | signal | 信号波形 |
| 开入信号 | 🔗 | link | 链接 |
| 遥控信号 | ⚡ | zap | 闪电 |
| 参数设置 | 🎚️ | sliders | 滑块 |
| 定值管理 | ⚙️ | settings | 齿轮 |
| 数据中心 | 📋 | database | 数据库 |
| PLC 调试 | 🔌 | bug | Bug/调试 |
| PLC 配置 | 🧩 | cpu | CPU/芯片 |
| 实时监控 | 📈 | activity | 心电图 |
| 命令终端 | 💻 | terminal | 终端 |

---

## 五、重构目标与要求

### 5.1 必须保留/增强的功能

- [x] 多 Chain 标签切换
- [x] 11 种节点类型完整支持
- [x] Canvas 拖拽、连线、缩放、平移
- [x] 节点属性双击编辑 (含 SR/RS R/S 引脚, T62P/D delayMs)
- [x] XML 实时预览
- [x] 从 RTU 加载/保存

### 5.2 必须修复的问题

- [ ] **Comb 改为自动识别** — 加载 XML 时检测,不允许手动添加空 Comb
- [ ] **Comb 创建方式** — 选中多个节点 → "成组为 Comb"
- [ ] **导航图标风格** — 恢复工业风格,尺寸与文字匹配
- [ ] **set_file 后端实现** — 确保保存功能真正可用

### 5.3 必须优于原工程的新功能

- [ ] Comb 视觉边界框正确嵌套
- [ ] SR/RS 引脚 S/R 标签显示
- [ ] 节点颜色方案保持一致性
- [ ] 更好的错误处理 (XML 解析失败提示)
- [ ] 键盘快捷键 (Delete 删除, Ctrl+S 保存)

---

## 六、Comb 自动检测算法 (前端)

```javascript
// 加载 XML 时的 Comb 自动检测伪代码
function detectCombsFromXml(xmlDoc):
  for each  in :
    chain.nodes = []   // 扁平存储所有节点
    chain.combs = []   // 存储 Comb 容器定义
    chain.links = []   // 存储连线

    // 1. 解析顶层元素
    parseChainElements(chainEl, chain, parentId=-1)

function parseChainElements(parentEl, chain, parentId):
  for each child in parentEl.children:
    if child.tag == 'Inputs' or 'Outputs':
      parseSignals(child, chain)
    if child.tag == 'Gate':
      parseGate(child, chain)
    if child.tag == 'Comb':
      combId = child.getAttribute('id')
      // 创建 Comb 容器 (位置由内部节点包围盒计算)
      comb = { id: combId, parentId: parentId }
      chain.combs.push(comb)
      // 递归解析 Comb 内部元素
      parseChainElements(child, chain, combId)

  // 2. Comb 位置自动计算 (后处理)
  for each comb in chain.combs:
    var nodesInComb = chain.nodes.filter(n => 位于 comb 区域)
    // 包围盒 = min/max of nodesInComb 的 x,y
    comb.x = minX - margin
    comb.y = minY - margin
    comb.w = maxX - minX + 2*margin
    comb.h = maxY - minY + 2*margin
```

### Comb 归属判断

节点属于哪个 Comb 由以下规则确定:

1. **来自 //** → 属于该 Comb
2. **来自  内子  的元素** → 属于子 Comb (嵌套)
3. **来自  顶层元素** → 不属于任何 Comb (parentId=-1)

---

## 七、节点样式与颜色方案

| 节点 | 填充色 | 描边色 | 尺寸 |
|------|--------|--------|------|
| INPUT | #e8f5e9 浅绿 | #27ae60 绿 | 110×34 |
| OUTPUT | #fce4ec 浅粉 | #e74c3c 红 | 110×34 |
| OR | #fff3e0 浅橙 | #e67e22 橙 | 76×46 |
| AND | #e3f2fd 浅蓝 | #2980b9 蓝 | 76×46 |
| NOT | #f3e5f5 浅紫 | #8e44ad 紫 | 76×46 |
| T62P | #fce4ec 浅粉 | #c0392b 深红 | 86×46 |
| T62D | #fff3e0 浅橙 | #d35400 深橙 | 86×46 |
| RISING | #e8f5e9 浅绿 | #1abc9c 青绿 | 86×46 |
| SR | #e3f2fd 浅蓝 | #3498db 亮蓝 | 86×52 |
| RS | #fce4ec 浅粉 | #9b59b6 紫 | 86×52 |
| FALLING | #fff3e0 浅橙 | #16a085 青 | 86×46 |

引脚颜色: 输入=同节点描边色, 输出=#27ae60 绿

### Comb 视觉

- 描边: #95a5a6 灰色虚线 (8px dash, 4px gap)
- 填充: rgba(149,165,166,0.05) 极浅灰
- 标签: 左上角 "Comb #N"
- 圆角: 6px

---

## 八、文件结构

```
web/js/pages/plc.js        ← PLC Debug + PLC Config (重构目标)
web/css/style.css           ← PLC 相关 CSS (.chain-tabs, .plc-canvas-wrap, etc.)
web/js/i18n.js              ← PLC 相关翻译 key
config/PLC/Reclose_logic.xml ← XML 配置文件 (数据源)
```