# ElaCom **Repository Path**: ichliebedich-DaCapo/ElaCom ## Basic Information - **Project Name**: ElaCom - **Description**: 串口调试助手(Tauri v2 + Rust + React) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-12 - **Last Updated**: 2026-08-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ElaCom 一个基于 `Tauri v2 + Rust + Vue 3 + TypeScript` 的桌面串口调试助手,面向日常协议联调、产线测试、自动化脚本调试和曲线观察场景。 **注意:个人用的调试工具,请合理使用!** ## 功能概览 - 串口参数配置:端口(含 USB VID/PID/描述)、波特率、数据位、校验位、停止位、读超时 - 自动波特率检测:候选采样 + 文本可读性评分 - 收发统一窗口:按时间线查看 RX/TX,支持文本/HEX 切换、ANSI 颜色与转义字符、多选/批量删除、保存记录 - 发送区:文本/HEX、17 种编码(含 GBK)、尾部追加、HEX 自动分组、循环发送(固定/随机/启动即发) - 脚本工作台:JavaScript 钩子(onStart/onStop/onConnect/onDisconnect/onFrame)+ 14 个 API + 应答自动发送 - 实时曲线:自动解析数值 + 脚本主动推送(uPlot),可调最大点数、采样开关 - 内置虚拟串口:`TEST-LOOPBACK`(回环)、`TEST-SIM-DATA`(模拟测量数据流),无硬件也能自测 - 运行日志抽屉:TXT / CSV 导出 - IAP 固件升级:分页发送、页头/页尾、应答匹配、超时重试 - 校验和计算器(SUM8/XOR8/CRC16-Modbus/CRC32)与协议模板(Modbus RTU/AT) - 历史数据图表窗口:加载已保存收发记录并重建曲线 - 主题:浅色 / 深色 / 跟随系统;三栏布局可拖动且持久化 - 在线更新:Gitee Releases API 静默检查 + `--replace` 自更新安装 (新 exe 独立进程等待旧进程退出后替换并重启,无 bat 脚本依赖) ## 技术栈 | 层 | 选型 | |----|------| | 桌面容器 | Tauri v2(WebView2) | | 后端 | Rust(serialport / encoding_rs / reqwest / crossbeam-channel) | | 前端 | Vue 3.5 + Pinia + TypeScript + Vite(自 v1.1.0 起;状态管理见下方性能说明) | | 图表 | uPlot | | 状态 | Zustand | | UI | 手写 CSS 变量设计系统(浅/深/跟随系统) | ## 项目结构 ```text ElaCom/ ├─ index.html ├─ package.json # 前端依赖与脚本 ├─ src/ │ ├─ App.tsx # 主应用:布局 + 事件接线 + 数据管线 │ ├─ components/ # 串口配置/收发窗口/发送区/脚本/曲线/IAP 等组件 │ ├─ lib/ # backend 封装 / 类型 / store / ANSI / 脚本运行时 │ ├─ styles/ # 主题变量与组件样式 │ └─ windows/ # 辅助窗口页面(脚本帮助/使用说明/历史图表) ├─ src-tauri/ │ ├─ Cargo.toml │ ├─ tauri.conf.json │ └─ src/ # Rust 后端:serial/virtual_port/encoding/iap/update 等 └─ docs/ ├─ requirements.md # 需求基线 └─ releases/ # 版本发布说明 ``` ## 开发 ```bash # 安装依赖 npm install cd src-tauri && cargo build # 开发调试(自动启动 vite + cargo run) npm run tauri dev # 构建前端 + 测试 npm run build cargo test --manifest-path src-tauri/Cargo.toml npm test # 前端 Vitest 单元测试 # 打包(生成安装器/exe,产物在 src-tauri/target/release/bundle/) npm run tauri build # 仅出便携 exe(跳过 NSIS/MSI 打包,更快) npm run tauri build -- --no-bundle ``` > **构建纪律**:交付/验证用的 exe 必须由 tauri CLI 构建。裸 `cargo build --release` > 产物是 dev 变体(缺 `custom-protocol` feature),双击会显示"localhost 拒绝连接"。 > 产物自检:`grep -ac "assets/index-" elacom.exe` 为 0 即坏,>0 才内嵌了前端资产; > 再跑 `elacom.exe --selftest` 验证功能层。根因详见 > `~/.agents/skills/tauri/references/Tauri交付exe连接localhost问题.md`。 ## 开发约定(verify 工作流) 任何改动满足以下全部条件才算完成,缺一不可: 1. `npm run verify` 全绿(= vue-tsc 类型检查 + vitest 前端测试 + cargo test 后端测试) 2. 修复 bug:必须先新增能复现该 bug 的测试并确认失败,再修复并确认转绿 3. 新功能:必须附带测试(核心逻辑用单元/集成测试,用户可见行为用组件/E2E 测试) 4. 禁止为通过测试而修改或删除既有测试;确需修改必须说明理由 工作流程: - 每次修改后主动运行 verify,交付回复中附上结果摘要 - verify 失败时先修复再交付,禁止带病交付 - 修改 Rust command 签名或数据结构时,必须同步前端 `src/lib/types.ts` 类型绑定 (`src-tauri/tests/type_sync_test.rs` 会自动校验 serde 字段名与 types.ts 一致, 忘改会在 verify 阶段暴露) - 测试必须相互独立、可重复(不依赖执行顺序、不共享状态;pinia 每用例 `setActivePinia(createPinia())`,模块级可变状态提供 reset 钩子) - 构建交付的产物自检:`Built application` 行出现 + exe 时间戳更新 + `grep -ac "assets/index-"` > 0 + `elacom.exe --selftest` 全绿 ## 测试体系 | 层级 | 工具 | 覆盖 | |------|------|------| | Rust 单元测试 | `cargo test`(src/tests.rs) | HEX 解析、编码往返、CRC 标准向量、波特率评分、虚拟口行为 | | 前端单元测试 | `npm test`(Vitest) | ANSI 解析、脚本编译/自动解析、store 环形截断与状态流转 | | 功能级集成测试 | `cargo test --test selftest_test` | MockRuntime + 内置虚拟串口跑完整链路(连接/回环收发/HEX/校验后缀/GBK 编码/统计/速率事件/信号线/循环发送/文件发送/IAP 回环应答/模拟设备/断开原因),13 项检查 | | exe 自检 | `elacom.exe --selftest` | 与集成测试共享同一检查序列;输出逐项报告到终端(无控制台则写 `%TEMP%/elacom-selftest.txt`),退出码 0=全部通过,可用于每次构建后快速验证产物 | | 组件交互测试 | `npx vitest run`(src/components/__tests__) | @vue/test-utils 挂载真实组件模拟用户操作:重连取消入口、发送历史 ↑↓、HEX 过滤、搜索/方向过滤、冻结显示 | | 类型绑定同步 | `cargo test --test type_sync_test` | serde 序列化 JSON 字段名必须存在于前端 types.ts,防止改 Rust 结构忘改前端 | 测试基建说明: - `SerialManager` 已泛型化 `Runtime`(生产 `Wry`,测试注入 `tauri::test` 的 MockRuntime),功能代码零分叉 - `src-tauri/build.rs` 为测试目标嵌入 comctl32 v6 清单(否则 MockRuntime 的 `DefSubclassProc` 导入在无清单测试 exe 上报 `STATUS_ENTRYPOINT_NOT_FOUND`) ## 在线更新与发布 应用内更新采用 **Tauri 官方 updater 插件**(`tauri-plugin-updater` + `tauri-plugin-process`): - 更新通道:仓库 `updater/latest.json`(Gitee raw 直链),声明最新版本号、发布说明与 NSIS 安装包下载地址 + minisign 签名 - 签名:构建时经 `TAURI_SIGNING_PRIVATE_KEY` 环境变量(私钥内容)对安装包签名,插件下载后 **强制公钥校验**(公钥固化在 `tauri.conf.json`),杜绝篡改 - 安装:Windows 走 NSIS 静默模式(passive),完成后应用内提示重启 **签名密钥(丢失无法补救,务必备份)**: - 私钥:`C:\Users\fairy\.tauri\elacom-updater.key`(空密码,勿入仓库、勿泄露) - 公钥:同目录 `.key.pub`(内容已写入 `tauri.conf.json` 的 `plugins.updater.pubkey`) - 一旦用该密钥发布过版本,私钥永久保管;丢失则旧版本无法升级到新版本,只能换密钥重发 发布新版本流程: 1. 更新 `src-tauri/Cargo.toml`、`src-tauri/tauri.conf.json`、`package.json` 的 version 2. 在 `docs/releases/vX.Y.Z.md` 编写发布说明 3. 签名构建: `TAURI_SIGNING_PRIVATE_KEY="$(cat ~/.tauri/elacom-updater.key)" npm run tauri build` 产物:`bundle/nsis/ElaCom_X.Y.Z_x64-setup.exe` + 同名 `.sig` 签名文件 4. 在 Gitee 创建 tag 为 `vX.Y.Z` 的发行版,上传 setup.exe 附件 5. 更新 `updater/latest.json`:version / pub_date / notes, `platforms.windows-x86_64.signature` 填 `.sig` 文件内容(一行), `url` 填该版本 Gitee 附件下载链接,提交推送 main 6. 旧版本应用内「关于/版本 → 检查更新」即可签名校验升级 > 注意:发布仓库必须为公开仓库(raw 与附件匿名可下载)。 > Gitee 发布 API 经验见全局文档库 `D:\Projects\Docs\dev\Gitee发布API经验.md`,令牌严禁写入本项目。 ## 已知限制 - serialport crate 不支持 mark/space 校验与 1.5 停止位,配置项已相应裁剪 - 脚本 onFrame 返回值仅同步处理(返回 Promise 时忽略,保持管线顺序) - 收发记录默认保存为文本格式(txt),历史图表窗口可加载 txt/csv/bin ## 核心能力 - 性能:Rust 端 RX 时间窗口合帧(50ms/256KB 上限)+ serial:state 事件 120ms 节流, 高吞吐流下 IPC 事件量降低一个数量级;读循环不再持有管理器锁,多端口互不阻塞 - 流控:支持 RTS/CTS 硬件流控与 XON/XOFF 软件流控 - RTS/DTR 运行时开关 + CTS/DSR/CD 输入信号灯 - 自动校验后缀:发送时按 CRC16-Modbus/CRC16-CCITT/CRC32/CRC8/SUM8/XOR8/LRC8/BCC8 自动计算追加,多字节算法可选字节序 - 文件发送:任意文件按原始字节分块发送,带进度与取消 - 意外断开自动重连(可关闭)、实时收发速率(B/s)统计 - 接收编码真正生效(17 种编码解码,切换即时生效);串口参数/发送历史/多条发送队列持久化 - 接收区搜索过滤(Ctrl+F)+ 方向过滤 + 冻结显示 + 暂停接收 + 单帧/可见帧复制