Skip to content

Frontend

Seeker32 edited this page Aug 11, 2026 · 3 revisions

React 前端(src)

结构总览

src/
├── App.tsx                 # 全局主题(AntD ConfigProvider,明暗主题)
├── main.tsx                # 入口
├── i18n.ts                 # 国际化:Locale / AppErrorInfo / translate / formatAppError / toAppError
├── i18n/
│   ├── en-US.ts            # 英文文案表
│   └── zh-CN.ts            # 中文文案表(TranslationKey 基准)
├── pages/
│   └── HomePage.tsx        # 唯一主页面:侧栏 + 标签页 + 各面板 + 设置对话框(FooterActions)
├── components/
│   ├── host/HostListSidebar.tsx   # 主机列表:搜索、分组、折叠、右键操作
│   ├── host/HostEditorDialog.tsx  # 主机编辑对话框(含分组)
│   ├── terminal/TerminalTabs.tsx  # 会话标签栏
│   ├── terminal/TerminalPane.tsx  # 会话面板容器
│   ├── terminal/XtermView.tsx     # xterm.js 渲染封装(应用终端主题)
│   ├── terminal/terminalThemes.ts # 6 套 xterm 色板(light/dark/OneDark/Dracula/Solarized×2)
│   ├── status/ServerStatusPanel.tsx # 监控面板(CPU/内存/磁盘 + 网卡选择 + 60s 趋势)
│   ├── sftp/SftpPanel.tsx         # SFTP 面板容器(目录 + 传输队列)
│   ├── sftp/FileExplorer.tsx      # 远程文件浏览(右键菜单操作)
│   ├── sftp/TransferQueue.tsx     # 传输任务队列(取消/重试)
│   └── shell/EmptyState.tsx       # 无会话空态页
├── stores/                 # Zustand stores(无业务逻辑在组件内)
│   ├── host.ts             #   主机 CRUD + 搜索过滤 + 分组聚合/重命名/删除
│   ├── session.ts          #   会话状态机(后端权威状态,无回写/无超时改写)
│   ├── monitor.ts          #   监控快照 + 网卡选择 + 趋势窗口 + 长任务 + 事件缓存补投
│   ├── sftp.ts             #   SFTP 目录 + 传输任务 + 事件缓存补投
│   ├── layout.ts           #   侧栏宽度 + 分组折叠 + 监视条折叠
│   ├── theme.ts            #   应用明暗主题
│   ├── locale.ts           #   界面语言(跟随系统 + 手动切换 + localStorage)
│   ├── log-level.ts        #   日志等级(invoke set_log_level 同步后端)
│   └── terminal-theme.ts   #   SSH 终端主题偏好(跨会话共享)
├── types/                  # TS 类型定义(与 Rust 模型 camelCase 对齐)
│   ├── host.ts · session.ts · monitor.ts · sftp.ts
└── test/                   # 单测 + 集成测试 + mocks

Store 职责(Zustand,不可变更新)

Store 状态 职责
host hosts、loading、error、searchQuery、selectedHostId 主机列表 CRUD,filterHosts / groupHosts 纯函数(搜索匹配名称/地址/分组),renameGroup / deleteGroup 逐个保存受影响主机
session sessions: Map<id, SessionInfo>、activeView、statusMessage 会话生命周期,applySessionStatus/Progress 消费后端权威事件;Connected 后初始化该会话 SFTP 根目录;closeSession 只请求后端 teardown 后清理本地投影(含 monitor/sftp 的 clearSession);事件监听入口 initListeners
monitor snapshots、selectedInterfaces、networkTrends、tasks、sessionTaskMap、pendingTaskEvents 监控快照缓存、网卡选择(只接受最新快照候选)、所选网卡 60s 趋势窗口(TREND_WINDOW_MILLIS)、长任务状态机、事件缓存补投
sftp sessionStates: Map<sessionId, SftpState>、pendingTaskEvents 目录浏览、任务队列、进度更新,监听 sftp:progress / sftp:task_status,同样带事件缓存补投
layout sidebarWidth、collapsedGroups、monitorCollapsed 侧栏拖拽宽度(clamp 到视口)、分组折叠状态持久化、监视条折叠
theme theme: 'light' 'dark'
locale locale: 'zh-CN' 'en-US'
log-level logLevel: 'error'..'trace' setLogLevel invoke set_log_level 同步后端日志过滤器并持久化
terminal-theme terminalTheme 跨会话共享的 SSH 终端主题偏好(localStorage)

关键流程

会话打开

HomePage 点击主机 → sessionStore.openSession(hostId)
  → invoke('open_session') → 写入 sessions + activeView
  → sftpStore.listDir('/') + monitorStore.startMonitoring(监控失败不阻断主流程)
  → initListeners 注册:session:status / session:progress / monitor:snapshot / task:status
  → Connected 事件到达 → 自动初始化 SFTP 根目录

会话关闭

closeSession(sessionId) → invoke('close_session')(后端统一 teardown Terminal/Monitoring/SFTP)
  → 移除本地 sessions 投影 + 重置 activeView
  → monitorStore.clearSession / sftpStore.clearSession(只清投影,不再发停止命令)

终端渲染(xterm.js)

  • XtermView 持有 xterm Terminal + FitAddon,只负责渲染;应用 terminalTheme store 的色板
  • 键盘输入 → writeTerminal(sessionId, data) → invoke write_terminal
  • 后端 terminal:data → xterm 写入缓冲区
  • 尺寸变化 → FitAddon → resizeTerminal → invoke resize_terminal

监控面板

  • monitor:snapshot 事件 → applySnapshot → ServerStatusPanel 直接消费
  • 快照内网卡列表驱动选择器;所选网卡的 RX/TX 速率样本按 60s 窗口保留为趋势;切换网卡或候选变化时重置趋势
  • task:status → applyTaskStatus(未知任务缓存,latest-wins,元数据到达后补投)
  • 前端不做任何聚合,一次更新一个完整 payload

SFTP

  • SftpPanel 展示 FileExplorer + TransferQueue;FileExplorer 支持右键菜单(下载/重命名等操作入口)
  • 上传/下载经 Tauri dialog 选文件 → sftp_upload / sftp_download 返回 TransferTask
  • sftp:progress(~500ms)更新进度条(终态任务忽略进度回退),sftp:task_status 驱动任务状态机;Done 时进度强制为总大小;Failed 展示本地化错误文案
  • 快速完成/快速失败事件先于 invoke 返回时缓存,任务元数据写入后补投,避免任务卡 Pending

设置对话框(FooterActions)

  • 侧栏底部齿轮入口,三个分区:通用(语言切换)、终端(6 套主题卡片预览选择)、日志(五档等级下拉)
  • 语言切换即时生效(所有文案经 translate(locale, key) 渲染);日志等级写入后立即 invoke 同步后端

测试策略(前端)

  • 单测:stores 状态流转(stores.test.ts,含事件缓存补投、latest-wins、clearSession 清理)、i18n(translate/formatAppError/toAppError)、log-level(读取回退)、terminal-theme(读取回退)、release-notes / release-workflow(发布说明脚本)、application-name、smoke
  • 组件测试:React Testing Library(components.test.tsx、xterm-view.test.tsx),无业务逻辑断言
  • 集成测试:homepage.integration.test.tsx —— invoke/event 契约验证
  • Mock:src/test/mocks/(tauri.ts、event.ts、dialog.ts),jsdom 环境(setup.ts)
  • E2E:Playwright + __TAURI_TEST__ 桥接(e2e/app.spec.ts),mock 后端事件驱动,覆盖分组/搜索/折叠、监视条折叠、失败重试、完整闭环

注意

  • 组件内不允许业务逻辑;只消费 store 状态与事件
  • 事件监听由各 store 的 initListeners 注册(session / monitor / sftp),统一在 HomePage useEffect 的 cleanup 中销毁
  • 前端类型必须与 Rust serde camelCase 输出严格一致;错误展示统一走 formatAppError(本地化 code + 保留 detail)

Clone this wiki locally