netx/web/WEB.md
oliver 00d3e95e2d Add named multi-panel traffic boards with dedicated wall tabs.
Persist board/panel layouts server-side, open each board outside the network shell so workbench reloads do not refresh walls, and fix mapped-baseline chart overlay plus fullscreen fit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 17:03:11 +08:00

165 lines
9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NetX Web 前端规范
## 技术栈
- React 19 + TypeScript + Vite
- React Router(工作台 + 模块页)
- TanStack Query(服务端状态)
- 自研 i18n(`src/i18n/`,无额外依赖)
## 目录结构
```
src/
config/modules.ts # 模块注册表(工作台卡片、路由、标题 i18n)
constants/queryKeys.ts # React Query key
components/ # 可复用 UI(无业务 API 调用)
hooks/ # 通用 hooks(Toast、窗口注册)
i18n/ # 文案 zh / en
layout/ # AppLayout、ErrorBoundary
pages/ # 页面(按路由)
services/api.ts # HTTP 封装与 API 函数
types.ts # 与后端契约类型
utils/
tabChannel.ts # 跨标签页聚焦(BroadcastChannel)
workbench.ts # 返回工作台
moduleWindows.ts # 打开/聚焦模块页签
display.ts # 纯展示辅助
```
## 路由与模块
| 路径 | 页面 | moduleId |
|------|------|----------|
| `/` | 工作台 | — |
| `/ume` | UME 同步 | `ume` |
| `/ne` | 网元管理(CRUD / 连通性) | `ne` |
| `/network` | 网络管理(左栏 + 子路由) | `network` |
| `/network/devices` | 设备列表(只读:托管 + UME) | `network` |
| `/network/alarms` | 告警信息 | `network` |
| `/network/configs` | 配置信息(同步快照) | `network` |
| `/network/webcrt` | redirect → `/webcrt`(保留 query) | — |
| `/network/topology` | redirect → `/topology` | — |
| `/network/tasks/collect` | 采集任务 | `network` |
| `/network/tasks/config-sync` | 配置同步 | `network` |
| `/network/tasks/port-traffic` | 端口流量监控(设备管理) | `network` |
| `/network/tasks/port-traffic/wall` | 流量大屏列表(打开独立页签) | `network` |
| `/port-traffic/wall/:boardId` | 流量大屏专有页签(无网络侧栏) | `port-traffic-wall` |
| `/topology` | 拓扑管理(模式化编辑器:选择/平移/拖动/连线、框选、自动布局、拖放添加) | `topology` |
| `/webcrt` | WebCRT 终端 | `webcrt` |
| `/collect` | redirect → `/network/tasks/collect` | — |
菜单树见 `config/networkNav.ts`。**新增网络子页:**
1. 在 `networkNav.ts` 增加叶子项
2. 在 `App.tsx` `/network` 下增加子 `<Route>`
3. 补充 i18n `network.*`
**新增工作台模块仍改 `config/modules.ts`:**
1. 在 `MODULES` 增加一项(`moduleId`、`path`、`section`、i18n key、`iconTone`)
2. 在 `App.tsx` 增加 `<Route path="..." element={...} />`
3. 在 `i18n/zh.ts` 与 `en.ts` 补充文案
4. 工作台卡片由 `modulesInSection` 自动生成,点击走 `openOrFocusModule`
## 跨标签页导航
- **工作台 → 模块**:`openOrFocusModule`(同 `moduleId` 仅一个标签,已打开则聚焦)
- **模块 → 工作台**:顶栏四格图标,`returnToWorkbench`(聚焦原工作台标签;已关闭则新开)
- **流量大屏**:列表在网络管理内;打开单板用 `openNewModuleWindow`(`/port-traffic/wall/:boardId`),与 `network` 单例页签隔离
- 实现:`utils/tabChannel.ts` + 命名窗口 `netx-module-{id}` / `netx-workbench`
## i18n
- 所有面向用户的文案走 `useI18n().t("dotted.key")`
- 表头/字段名等技术列可保持英文
- 语言存在 `localStorage`(`netx-locale`),顶栏 ⋯ 切换
## 数据请求
- API 仅写在 `services/api.ts`
- Query key 集中在 `constants/queryKeys.ts`
- 失效缓存用 prefix key(如 `queryKeys.umeSyncStatusAll`)
- 顶栏连接状态:`App` 轮询 `GET /v1/integrations/status`(5s),展示 **netx api** 与 **oclaw bridge**(含延迟 / 错误类型)
## 网元管理(独立于 UME)
- API:`/v1/managed-ne/*`(CRUD、导入、连通性测试)
- 环境变量:`NETX_CREDENTIAL_SECRET_KEY`(Fernet,用于加密存储 SSH 密码)
- 导入列:`device_type,ip,username,password,port,protocol,name,vendor`
- 连通性测试成功后会**始终**用探测到的设备名覆盖「名称」
## 批量采集
- API:`/v1/ne-collections/*`(仅 `connect_status=pass` 的网元可参与)
- 采集日志目录:`NETX_NE_COLLECTION_DATA_DIR`(默认 `data/ne_collections`)
- 命令每行一条,`#` 为注释;输出格式与旧版 NetX 采集 `.txt` 一致
## 配置同步
- API:`/v1/config-sync/*`(策略、看板、周期、快照)
- 存储:PostgreSQL `ne_config_snapshot` / `ne_config_history`(zlib BYTEA)
- 范围:ManagedNE + UME CLI 目标;厂商固定只读命令矩阵
- 调度:`NETX_CONFIG_SYNC_SCHEDULER_ENABLED`(默认开),周期天数策略可配(默认 3 天)
- 默认策略:`enabled=false`(首次无自动任务,需在页面手动开启周期调度或点「立即同步」)
- 单飞:同一时刻只允许一个 `running|pending|paused` 周期;上轮未结束时不会开启新周期
- 周期状态:全部任务跑完即为 `success`;单网元失败只计入 `fail_count`,不把整轮标为失败
- 崩溃续跑:启动时把中断的 `running` 任务重新入队并继续,占用单飞槽位,避免与新周期重叠
- 进程启动宽限:`NETX_CONFIG_SYNC_STARTUP_GRACE_SEC`(默认 3600)仅约束**新建**自动周期,不影响续跑
- 前端:`/network/tasks/config-sync`(看板)+ `/network/configs`(查看)
## 端口流量监控
- API:`/v1/port-traffic/devices/*`(设备 CRUD、interfaces、samples、compare、dashboard);`discover/ports` 仍按网元拉取接口
- **设备中心**:每台网元(`source`+`ne_id`)一份监控配置;周期/保留/启停挂在设备上;接口归属于该设备
- 唯一性:同一物理口 `(source, ne_id, ifname)` 全局仅允许一个 **active** 监控行,避免重复 CLI 采集
- 调度:按设备到期;一轮采集对该设备 **登录一次** 后批量 `show interface`
- 手工映射:大屏可选其它设备接口作基线叠图;可与周期偏移叠加
- 厂商:ZTE / 华为 / 思科;解析速率 **bit/s**;缺厂商 util 时按 bps/bw 回算
- 调度开关:`NETX_PORT_TRAFFIC_SCHEDULER_ENABLED`(默认开),tick `NETX_PORT_TRAFFIC_SCHEDULER_TICK_SEC`(默认 15)
- 保留:按设备 `retention_days` 清理过期 sample(周对比建议 ≥8 天)
- 前端:`/network/tasks/port-traffic`(设备列表 / 向导 / 编辑 / 采集日志);`/network/tasks/port-traffic/wall`(大屏列表);`/port-traffic/wall/:boardId`(独立大屏页签,`openNewModuleWindow`,与网络管理页签互不影响)
- 定制大屏:`/v1/port-traffic/boards*`(Board + Panel);整板 PUT panels 保存;刷新/换页不丢;图数据仍走 compare
- 采集日志:`GET /v1/port-traffic/devices/{id}/events`;失败写入 `port_traffic_event`,列表操作可查看
- 支持拓扑深链:`?ne_id=&source=managed|ume&ifname=` 打开向导并预填网元
## 拓扑管理
- 渲染:`@xyflow/react`;布局:`dagre`(层次)+ 内置力导向/网格/环形
- 工具模式:选择(框选多选)/ 平移 / 拖动 / 连线;快捷键 `V` `H` `A` `C`
- 侧栏网元可点击或拖放到画布;发现默认保留节点坐标(「显示 → 发现后自动布局」可选开启并本机记住)
- 支持对齐、网格吸附、轻量撤销/重做、链路图例
- 选中链路可手动定制颜色 / 线型(实线·虚线·点线)/ 粗细,保存后持久化;空值回退到来源默认样式(人工灰 / 发现蓝虚线 / 未发现红虚线)
- 「显示」里可改人工 / 发现 / 未发现三类默认样式(本机记住);单链路样式与端口在右键菜单中调整;网元可右键重命名
- 未保存切换地图会确认;Ctrl+S 保存;发现可取消;禁止自环与重复连线;PUT 保留 `discovered_at`;发现边键对端口名做规范化
- 发现进度主区只显示摘要与入口;点「详情」打开列表弹窗,再点设备打开链路复核弹窗
- 工具栏可搜索定位并高亮;侧栏已上图网元点击可定位
- 连线模式画布顶提示;侧栏折叠/编辑/删除使用内联 SVG 图标;名称与 IP/端口间隔统一为 ASCII ` / `(避免 Unicode 损坏)
- 链路右键可跳转端口流量(`/network/tasks/port-traffic?ne_id=&source=&ifname=`)
## WebCRT
- API:`POST /v1/webcrt/sessions`(`ne_id` 或 `ume_ne_id`)、`WS /v1/webcrt/sessions/{id}/ws`、`DELETE /v1/webcrt/sessions/{id}`
- 目标列表复用 `/v1/cli/targets`(托管 + UME,搜索分页;`source=all|managed|ume`)
- 凭据:托管走网元自身账号;UME 走 CLI 连接模板(`resolve_cli_target`)
- 前端:CRT 风格左右分栏(会话管理 + 多标签终端)
- 审计:`NETX_WEBCRT_DATA_DIR`(默认 `data/webcrt/audit.jsonl`)
- 限流:`NETX_WEBCRT_MAX_SESSIONS`、`NETX_WEBCRT_IDLE_TIMEOUT_SEC`
## Toast
- 使用 `ToastProvider`(`main.tsx`)+ `useToast()`
- 禁止页面内单独维护一套 toast 状态
## 样式
- 全局样式:`index.css`(工作台浅色主题)
- 不使用 CSS Modules;类名 BEM 风格:`app-brand__logo`、`wb-card`
## 构建
```bash
cd web && npm run build
```
开发:`npm run dev`(需后端 API 或 Vite proxy 配置)