You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

13 KiB

call-client 迁移到 Tauri 技术文档

1. 目标

将当前基于 Electron + Vue 3 + TypeScript + electron-vite 的桌面应用迁移为 Tauri + Vue 3 + TypeScript在尽量保留现有前端业务代码的前提下替换主进程、窗口管理、IPC、配置与日志等宿主能力。

迁移完成后应满足:

  • 保持现有登录、主叫号、票号列表、服务地址配置等业务功能不变
  • 保持 Linux麒麟打包能力优先支持 x64 / arm64
  • 保持本地配置与日志的 XDG 规范行为
  • 保持多窗口、原生确认框、菜单、前后端通信能力
  • 为后续减小安装包体积、降低内存占用、提高跨平台一致性做准备

2. 当前项目现状

当前项目目录与能力大致如下:

  • 前端:Vue 3 + vue-router + element-plus + axios
  • 宿主:Electron
  • 构建:electron-vite + electron-builder
  • 主进程入口:src/main/index.ts
  • 窗口创建:src/main/window.ts
  • 预加载桥接:src/preload/index.ts
  • 本地配置:src/main/app-config.ts
  • 文件日志:src/main/file-logger.ts
  • 渲染层类型声明:src/renderer/src/env.d.ts

当前渲染层大量依赖 window.xxx 能力:

  • window.winControl
  • window.contextMenu
  • window.pauseMenu
  • window.session
  • window.appLogger
  • window.appConfig
  • window.nativeDialog
  • window.ticketToMain
  • window.mainTicketEvents

这意味着迁移的核心不是 Vue 页面重写,而是把这些 Electron 注入能力改造成 Tauri 的命令、事件和窗口 API。


3. 为什么适合迁移到 Tauri

当前项目业务逻辑主要集中在前端,宿主层职责相对清晰:

  • 管理窗口
  • 提供原生菜单和对话框
  • 管理会话状态
  • 提供配置读写
  • 提供文件日志
  • 在多个窗口之间转发事件

这些能力都可以在 Tauri 中找到对应实现,因此该项目具备较好的迁移可行性。

适合迁移的原因:

  • 前端已是标准 Vite/Vue 结构Tauri 可直接复用
  • 本地能力边界清晰,便于逐项替换
  • Linux 发行打包对 Tauri 更友好
  • 当前没有深度依赖 Electron 的 BrowserViewdesktopCapturerwebContents 高级能力

4. Electron 到 Tauri 能力映射

4.1 窗口

当前 Electron

  • createLoginWindow()
  • createMainWindow()
  • createTicketWindow()
  • 运行时调用 show()focus()restore()minimize()

Tauri 对应方案:

  • 主窗口由 Tauri 启动时创建
  • 其它窗口通过 WebviewWindow 或 Rust 端创建
  • 窗口最小化、关闭、显示、聚焦使用 @tauri-apps/api/window

建议:

  • loginmainticketList 改为具名 Tauri 窗口
  • 窗口路由仍保留 hash 路由,降低前端改造成本

4.2 IPC / 桥接

当前 Electron

  • ipcMain.handle
  • ipcRenderer.invoke
  • ipcRenderer.send/on
  • contextBridge.exposeInMainWorld

Tauri 对应方案:

  • invoke() 调用 Rust #[tauri::command]
  • emit/listen 做窗口间事件通信
  • 直接在前端封装 src/renderer/src/tauri-api/* 替代 window.xxx

建议:

  • 不再保留 window.xxx 直挂模式
  • 改为前端统一封装模块,例如:
    • src/renderer/src/host/session.ts
    • src/renderer/src/host/config.ts
    • src/renderer/src/host/logger.ts
    • src/renderer/src/host/window.ts
    • src/renderer/src/host/menu.ts

4.3 原生菜单

当前 Electron

  • 主进程动态构建菜单
  • 用于“办税员窗口 / 票号列表 / 退出程序”
  • 暂停菜单用于选择暂停原因

Tauri 对应方案:

  • Rust 菜单 API
  • 或前端自绘菜单 + Rust 命令
  • 简单场景也可直接使用前端弹层替代原生菜单

建议:

  • “系统/上下文菜单”优先保留原生
  • “暂停原因菜单”可以迁移成前端 Element Plus 下拉/弹窗,降低 Rust 复杂度

4.4 原生确认框

当前 Electron

  • dialog.showMessageBox

Tauri 对应方案:

  • @tauri-apps/plugin-dialog

建议:

  • window.nativeDialog.confirm() 改为前端封装 confirmNative()
  • 接口签名保持一致,减少页面改动

4.5 配置文件

当前 Electron

  • src/main/app-config.ts
  • Linux 下遵循 XDG_CONFIG_HOME
  • 使用 JSON 文件持久化

Tauri 对应方案:

  • Rust 命令自己读写 JSON 文件
  • 目录使用 tauri::api::path 或 Tauri 2 对应 path API

建议:

  • 继续保持当前配置文件结构不变
  • 继续使用 config.json
  • 路径规则继续保持:
    • Linux$XDG_CONFIG_HOME/<app>~/.config/<app>
    • 其他平台:应用数据目录

4.6 文件日志

当前 Electron

  • src/main/file-logger.ts
  • Linux 遵循 XDG_STATE_HOME
  • 纯文本
  • 100MB 轮转
  • 7 天清理

Tauri 对应方案:

  • Rust 端实现同样的文件日志模块

建议:

  • 日志逻辑直接迁移到 Rust
  • 保持现有文件命名、轮转、保留策略不变
  • 渲染层仍使用统一 log(level, message) 接口

4.7 Session 状态

当前 Electron

  • 主进程内存维护 sessionState
  • 渲染层通过 IPC 获取/设置

Tauri 对应方案:

  • Rust State<T> 保存内存会话
  • 通过 command 获取/设置

建议:

  • 维持现有结构:
    • empUid
    • winUid
    • queueToken

4.8 多窗口事件转发

当前 Electron

  • ticket:main-action
  • main:ticket-action

Tauri 对应方案:

  • 指定窗口 emit_to
  • 目标窗口 listen

建议:

  • 保持当前事件模型:
    • ticket -> main 呼叫
    • ticket -> main 评价
  • 仅把传输媒介从 Electron IPC 改为 Tauri Event

5. 迁移范围拆解

5.1 前端可直接复用部分

这些部分原则上可以原样保留:

  • src/renderer/src/views/*.vue
  • src/renderer/src/router/index.ts
  • src/renderer/src/api/index.ts
  • src/renderer/src/utils/service.ts
  • 大部分 TypeScript 类型定义
  • Axios 与后端接口封装

需要改动的地方主要是所有 window.xxx 调用。

5.2 必须重写的部分

这些 Electron 专属模块需要全部替换:

  • src/main/index.ts
  • src/main/window.ts
  • src/preload/index.ts
  • src/renderer/src/env.d.ts 中的 Electron 全局声明
  • electron.vite.config.ts
  • electron-builder.yml
  • package.json 中 Electron 构建脚本和依赖

5.3 可迁移但建议重构的部分

  • pauseMenu 建议从原生菜单改成前端弹窗
  • contextMenu 可按实际需要决定是否保留原生
  • window.winControl.loginSuccess() 可重构为前端路由 + 新窗口显示逻辑

6. 推荐的 Tauri 目标结构

建议最终目录结构:

call-client/
├─ src/
│  ├─ renderer/
│  │  └─ src/
│  │     ├─ api/
│  │     ├─ host/
│  │     │  ├─ session.ts
│  │     │  ├─ config.ts
│  │     │  ├─ logger.ts
│  │     │  ├─ window.ts
│  │     │  ├─ dialog.ts
│  │     │  └─ events.ts
│  │     ├─ router/
│  │     ├─ views/
│  │     └─ ...
│  └─ shared/
├─ src-tauri/
│  ├─ src/
│  │  ├─ main.rs
│  │  ├─ commands/
│  │  │  ├─ session.rs
│  │  │  ├─ config.rs
│  │  │  ├─ logger.rs
│  │  │  ├─ window.rs
│  │  │  ├─ dialog.rs
│  │  │  └─ events.rs
│  │  └─ state.rs
│  ├─ tauri.conf.json
│  └─ Cargo.toml
└─ package.json

7. 前端接口替换清单

当前前端依赖的 Electron 注入接口,需要替换为 Tauri 封装:

7.1 window.winControl

当前能力:

  • windowMinimize()
  • windowClose()
  • loginSuccess()

Tauri 替代:

  • getCurrentWindow().minimize()
  • getCurrentWindow().close()
  • 登录成功后触发:
    • 显示主窗口
    • 关闭登录窗口
    • 或仅路由切换,视最终窗口方案而定

7.2 window.contextMenu

当前能力:

  • 打开上下文菜单

Tauri 替代:

  • Rust 菜单
  • 或前端菜单组件

7.3 window.pauseMenu

当前能力:

  • 弹出暂停原因菜单
  • 回传用户选中的原因

建议替代:

  • 使用前端对话框/选择器,避免专门做 Rust 菜单事件回传

7.4 window.session

当前能力:

  • get()
  • set()
  • clear()

Tauri 替代:

  • invoke('session_get')
  • invoke('session_set', { ... })
  • invoke('session_clear')

7.5 window.appLogger

当前能力:

  • log(level, message)

Tauri 替代:

  • invoke('app_log', { level, message })

7.6 window.appConfig

当前能力:

  • getAll()
  • set(partial)

Tauri 替代:

  • invoke('config_get_all')
  • invoke('config_merge', { partial })

7.7 window.nativeDialog

当前能力:

  • confirm({ title, message, okLabel, cancelLabel })

Tauri 替代:

  • 封装 plugin-dialog

7.8 window.ticketToMain / window.mainTicketEvents

当前能力:

  • 票号列表窗口通知主窗口执行呼叫/评价

Tauri 替代:

  • emitTo('main', 'ticket-action', payload)
  • 主窗口 listen('ticket-action', ...)

8. 后端 API 层迁移影响

后端 API 请求层基本不需要因为迁移到 Tauri 而重写。

现有:

  • axios
  • src/renderer/src/api/index.ts
  • src/renderer/src/utils/service.ts

保留原则:

  • 所有 /auth/login/call-terminal/*/isRank/getQueueCount 保持不变
  • 仅调整“token 获取来源”和“应用配置读取来源”

需要注意:

  • 目前 service.tswindow.session.get() 中拿 queueToken
  • 迁移后应改成 host/session.ts 封装

9. 打包与发布迁移

当前:

  • 使用 electron-builder
  • 面向 deb / AppImage

迁移到 Tauri 后:

  • 使用 tauri build
  • Linux 侧通常可生成 deb / AppImage

建议:

  • 保留现有 resources/call_icon.png
  • 重新配置 Tauri 的:
    • 应用名
    • 图标
    • 窗口尺寸
    • 标题栏/装饰策略

10. 重点风险

10.1 多窗口迁移复杂度

当前项目不是单窗口,而是至少有:

  • 登录窗口
  • 主窗口
  • 票号列表窗口

这在 Tauri 可以实现,但实现方式与 Electron 不同,需要提前设计窗口生命周期和事件路由。

10.2 原生菜单差异

Electron 菜单 API 较成熟Tauri 菜单方案和事件模型不同,暂停菜单与上下文菜单可能需要重构。

10.3 文件系统逻辑要从 Node 改到 Rust

以下逻辑不能直接复用:

  • fs
  • path
  • os
  • app.getPath()

需要改写为 Rust。

10.4 前端大量 window.xxx 依赖

虽然页面 UI 可复用,但所有页面中使用的宿主能力都需要替换接口。

建议先做适配层,不要在页面里直接写 Tauri API。

10.5 开发流程变化

从:

  • electron-vite dev

改为:

  • tauri dev

工程脚本、CI、打包环境都要同步调整。


11. 推荐迁移策略

建议使用“分阶段替换”,不要一次性推倒重来。

阶段 1建立 Tauri 空壳

目标:

  • 保留现有 Vue 前端
  • 新建 src-tauri
  • 跑通 tauri dev
  • 页面能正常打开

产出:

  • src-tauri/
  • tauri.conf.json
  • 基础窗口配置

阶段 2建立宿主适配层

目标:

  • 新建前端 host/* 封装
  • 暂时不改页面业务,只改调用入口

例如将:

  • window.appConfig.getAll()

替换为:

  • hostConfig.getAll()

这样后续无论是 Electron 还是 Tauri都能通过适配层承接。

阶段 3迁移配置、日志、session

优先迁移最基础的宿主能力:

  • 配置文件
  • 日志
  • 会话状态

因为这些能力会被多个页面依赖。

阶段 4迁移窗口与事件

迁移:

  • 登录成功切主窗口
  • 票号列表子窗口
  • 主窗口与子窗口之间动作事件

阶段 5迁移原生菜单/对话框

迁移:

  • 确认框
  • 上下文菜单
  • 暂停菜单

此阶段可顺便评估哪些能力改成前端组件更合适。

阶段 6移除 Electron 依赖

删除:

  • electron
  • electron-builder
  • electron-vite
  • src/main/*
  • src/preload/*

并重写 package.json 脚本。


12. 预计工作量

按当前项目规模估算:

  • 前端页面复用:高
  • 宿主层重写:中到高
  • 多窗口与事件:中
  • 打包与环境:中

大致可按以下量级评估:

  • 基础可运行 Tauri 版本1 到 2 天
  • 功能完整迁移3 到 7 天
  • 打包与麒麟环境联调1 到 3 天

实际取决于:

  • 是否保留原生菜单
  • 是否保留多窗口
  • 是否要求与当前行为完全一致

13. 最小可行迁移方案

如果目标是“尽快落地”,建议先做最小版本:

  • 保留单主窗口
  • ticketList 改为路由页/弹层,而不是独立窗口
  • 暂停菜单改为前端弹窗
  • 原生确认框使用 Tauri dialog 插件
  • 配置、日志、session 用 Rust 命令重写

这样能明显降低迁移复杂度。


14. 结论

该项目适合迁移到 Tauri且前端业务代码可大量复用。真正的迁移重点在于

  • 宿主能力替换
  • 多窗口与事件通信重构
  • 本地配置/日志/session 的 Rust 实现
  • 打包链路从 Electron Builder 迁移到 Tauri Build

推荐实施顺序:

  1. 先建立 Tauri 壳与前端适配层
  2. 再迁移配置、日志、session
  3. 再迁移窗口、事件、对话框、菜单
  4. 最后移除 Electron

15. 下一步建议

如果你确认要开始迁移,下一份文档建议继续输出:

  • TAURI-MIGRATION-TASKS.md

内容包括:

  • 逐文件改造清单
  • Electron API 到 Tauri API 映射表
  • src-tauri 初始代码结构
  • package.json 新脚本方案
  • 每一步验收标准