Files
ele-HeiXiu/PROJECT.md

411 lines
26 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.
# 项目概览
- 本项目使用 Vite + React 19 + TypeScript + Electron 重构现有 Python Qt
桌面应用打造跨平台Windows/macOS的多窗口桌面程序。
- 核心界面为单页应用SPA同时支持通过 Electron 打开独立窗口以承载子功能。
# 核心需求
- 完整还原原有 Qt 应用的业务逻辑与视觉体验,并对交互进行现代化改造。
- 必须支持 多窗口(主窗口 + 可动态创建的辅助窗口),窗口间需通过事件/消息进行低耦合通信。
- 适配 Windows 与 macOS处理好快捷键、托盘、菜单、窗口边框等平台差异。
- 采用 离线优先 架构,保障本地数据处理性能,合理使用本地存储(如 electron-store 或 SQLite
- 所有对系统底层能力的调用必须通过 Electron 主进程,严禁在渲染进程直接使用 Node.js API除非通过 preload 安全暴露)。
# 技术架构
## 整体分层
- 主进程Main ProcessElectron 主进程管理窗口生命周期、系统菜单、托盘、IPC 事件调度、本地文件/数据库操作。
- 预加载脚本Preload桥接渲染进程与主进程使用 contextBridge 安全暴露有限 API。
- 渲染进程Renderer基于 React 19 的 SPA主窗口与独立窗口的 React 入口,负责 UI 展示与用户交互。
- 共享层Shared进程间共享的 TypeScript 类型、常量、工具函数、事件名称枚举。
## 前端架构原则
- 组件化:以函数组件 + Hooks 为唯一组件形式UI 拆分为展示组件与容器组件。
- 单向数据流:全局状态使用 Context + Provider 模式AppContext / ThemeContext / SettingsContext
遵循 Provider → Context → Comsumer 单向流动。组件内部状态使用 useState/useReducer不污染全局 Context。
- 事件驱动EDA
1. 主进程与渲染进程通信基于 Electron IPCipcMain/ipcRenderer定义明确的事件通道与载荷类型。
2. 渲染进程内跨组件通信优先使用 Context需要解耦的场景使用自定义事件总线src/utils/event-bus.ts
所有 emit 调用自动记录到日志文件用于审计追踪。
3. 自定义错误体系RequestError / RefreshError通过事件总线解耦请求拦截器抛出自定义错误 →
全局捕获 → emit 事件 → UI 层响应。
4. 窗口间通信统一通过主进程转发(或使用 MessagePort 等 Electron 支持的机制),保持窗口独立性。
- 路由与导航:主窗口为单页应用,不使用 React Router。所有页面切换通过事件总线 + PageDispatcher 实现:
- 叠加层(设置、公告、素材库等)→ Modal/Drawer + 事件总线驱动,主页面不卸载
- NavBar 导航项点击 → `emit(OPEN_PAGE, { target, modalType })` → PageDispatcher 按 `PAGE_MAP` 注册表渲染对应容器
- 每个页面路径在 `PageDispatcher.PAGE_MAP` 中注册一行target → { component, modalType, width, height }
- 需跨页保持的状态放 Provider 或 localStorage
- 辅助窗口(设置、预览、导入导出等)以 Modal/Drawer 叠加在主窗口之上,不与主窗口共享 DOM但保持在同一个 React 组件树中以确保状态一致性。
# 目录结构
> 每个文件夹下均有 `README.md` 说明该目录的职责与代码边界(自动生成,不进 Git
```md
├── electron/ # Electron 主进程 + 预加载
│ ├── main.ts # 入口编排:窗口创建 / IPC 注册 / 生命周期
│ ├── preload.ts # contextBridge向渲染进程暴露安全 API
│ ├── electron-env.d.ts # 类型声明APP_ROOT、Window 扩展)
│ └── main/ # 主进程核心模块
│ │ ├── load-env.ts # .env.{mode} + .env.local 加载器
│ │ ├── logger.ts # 日志核心JSON Lines / 每日轮转 / 批量冲刷
│ │ ├── log-ipc.ts # 渲染进程日志 → 主进程日志桥接
│ │ ├── net-request.ts # Electron net.request 的 axios 风格封装
│ │ ├── safe-storage-ipc.ts # safeStorage 加密/解密 IPC handler
│ │ ├── storage-ipc.ts # 沙箱文件存储 IPC handlerheixiu-data/
│ │ ├── updater.ts # 自动更新:自定义 Provider + 平台 Updater
│ │ ├── menu/index.ts # 系统菜单macOS Edit / Win 无菜单)
│ │ └── utils/ # 平台判断 / 图标路径
│ └── preload/ # 预加载脚本contextBridge 桥接层)
│ ├── device.ts # 硬件指纹采集wmic/powershell | ioreg/sysctl
│ └── device_service.ts # 设备信息缓存层(机器码/IP/MAC
├── src/ # 渲染进程React 19 + Vite + TypeScript
│ ├── main.tsx # React 挂载 + Provider 嵌套 + 全局错误捕获
│ ├── App.tsx # 根组件:叠加层编排(登录/设置/页面调度)
│ ├── vite-env.d.ts # Vite 类型声明
│ ├── components/ # 通用组件层
│ │ ├── providers/ # 全局 Context Provider
│ │ │ ├── AppProvider.tsx # 认证状态login/logout/Token 刷新)
│ │ │ ├── ThemeProvider.tsx # 亮/暗主题切换 + antd ConfigProvider
│ │ │ └── SettingsProvider.tsx # 本地持久化设置(存储路径等)
│ │ ├── shell/ # 应用外壳
│ │ │ ├── Layout.tsx # 全高 flex 列布局壳
│ │ │ ├── PageDispatcher.tsx # 通用页面调度器Modal/Drawer/FloatingPanel
│ │ │ └── navbar/ # 导航栏nav-config → NavBar → NavItem
│ │ └── ui/ # 通用 UI 原子组件
│ │ ├── FloatingPanel.tsx # 可拖拽非模态浮动面板
│ │ └── LegalTextModal.tsx # 法律/协议文本 Modal
│ ├── hooks/ # 自定义 Hooks
│ │ ├── use-async.ts # 通用异步基础设施(竞态/取消/门控)
│ │ ├── use-api.ts # 业务 API HooksBanner/模型/任务/账户/财务)
│ │ └── use-updater.ts # 更新状态机(单例 IPC 监听)
│ ├── infrastructure/ # 基础设施层
│ │ └── storage/ # 本地加密数据库sql.js + safeStorage + IPC
│ │ ├── db-core.ts # sql.js WASM 初始化 + 通用 CRUD
│ │ ├── db-encrypt.ts # 序列化 → safeStorage 加密 → IPC 写磁盘
│ │ ├── schema.ts # 6 张业务表 DDL含索引
│ │ ├── task-store.ts # 任务记录本地 CRUD
│ │ ├── order-store.ts # 订单记录本地 CRUD充值 + VIP
│ │ ├── param-store.ts # 参数历史快照(每模型最多 20 条)
│ │ ├── media-store.ts # 媒体缓存元数据管理
│ │ ├── media-loader.ts # 媒体下载与三级缓存策略
│ │ ├── settings-store.ts # 应用设置 key-value 存储
│ │ ├── sync-manager.ts # 分页同步游标管理
│ │ ├── user-scope.ts # 用户作用域隔离JWT user_id
│ │ ├── ipc-file.ts # 渲染进程端文件操作桥接
│ │ └── index.ts # 统一入口init/clear/stats
│ ├── pages/ # 业务页面(按功能模块组织)
│ │ ├── auth/ # 认证模块
│ │ │ ├── index.tsx # LoginPage Modal登录/注册 Tabs
│ │ │ ├── components/ # 表单组件LoginForm/RegisterForm/FormField/改密/忘记密码)
│ │ │ ├── config/ # 字段配置login-fields/register-fields+ 校验函数库
│ │ │ └── hooks/ # use-auth-state偏好/ use-sms-cooldown短信冷却
│ │ ├── home/ # 首页主工作区
│ │ │ ├── HomePage.tsx # 首页入口
│ │ │ ├── HomeContent.tsx # 三列可拖拽面板 + HomeContext.Provider
│ │ │ ├── HomeContext.tsx # 共享状态(选中模型/任务/分页)
│ │ │ ├── panels/ # 三列面板容器Left/Center/Right
│ │ │ ├── features/ # 功能模块Banner/ModelSelector/ModelInputForm/TaskHistory/OutputPreview
│ │ │ ├── controls/ # Widget 控件体系12 种 Qt→React 映射 + WIDGET_MAP
│ │ │ └── hooks/ # useModelUIparam_schema → UIFieldConfig
│ │ ├── panels/ # NavBar 触发的功能面板页
│ │ │ ├── AccountInfo.tsx # 账户信息(用户/积分/套餐/统计)
│ │ │ ├── BillingInfo.tsx # 财务信息(余额 + 账单流水)
│ │ │ ├── OrdersPage.tsx # 订单明细(充值/VIP 双 Tab + 轮询)
│ │ │ ├── RechargePage.tsx # 积分充值(预设/自定义金额 + 支付追踪)
│ │ │ ├── VipPage.tsx # VIP 开通(激活码/套餐选购/权益预览)
│ │ │ └── WechatWorkPage.tsx # 企业微信二维码
│ │ └── settings/ # 设置页面
│ │ ├── SettingsPage.tsx # 设置 Modal 主页面
│ │ └── sections/ # 6 个设置分区(主题/系统/更新/路径/密码/数据)
│ ├── services/ # 服务层HTTP 请求封装)
│ │ ├── request.ts # Axios 实例:拦截器 + Token 注入 + 401 刷新队列
│ │ ├── auth-token.ts # Token 生命周期refresh_token 持久化/主动刷新)
│ │ ├── auth-persistence.ts # 登录表单偏好(用户名回填/记住密码/自动登录)
│ │ ├── types.ts # 通用 API 类型ApiResponse/RequestError/RefreshError
│ │ ├── cache/ # 客户端缓存
│ │ │ └── model-cache.ts # 模型列表加密本地缓存
│ │ └── modules/ # API 模块(按业务域拆分)
│ │ ├── auth.ts # 认证 API登录/注册/刷新/用户/改密/短信)
│ │ ├── models.ts # 模型 API + 分类常量
│ │ ├── task.ts # 任务 APICRUD + 批量状态 + CSV + 轮询常量)
│ │ ├── banner.ts # Banner/轮播图 API
│ │ ├── billing.ts # 财务 API余额/账单/导出)
│ │ ├── payments.ts # 支付 API订单 CRUD + 状态映射)
│ │ ├── vip-api.ts # VIP API激活/等级/订单)
│ │ └── announcement.ts # 公告 API + 类型标签颜色
│ ├── theme/ # 主题系统
│ │ ├── tokens.ts # TypeScript 设计令牌
│ │ ├── tokens.css # CSS 设计令牌Tailwind @theme + CSS 变量亮/暗)
│ │ ├── antd-theme.ts # Ant Design ConfigProvider 主题配置(亮/暗)
│ │ ├── transitions.css # 主题切换过渡View Transitions API + CSS fallback
│ │ ├── base.css # 全局重置(盒模型/滚动条/聚焦环/拖拽区域)
│ │ └── globals.css # 入口文件(按序导入以上 CSS
│ └── utils/ # 渲染进程工具函数
│ ├── event-bus.ts # 事件总线on/off/emit + 日志审计钩子)
│ ├── ipc.ts # IPC 安全守卫hasIpc → safeIpcOn/send/invoke
│ ├── logger.ts # 渲染进程日志IPC 转发 | DEV 控制台)
│ ├── platform.ts # 平台判定isMacOS/isWindows/isLinux
│ ├── device.ts # 设备 ID 生成与持久化UUID v4
│ ├── safe-storage.ts # 加密 localStorage 封装safeStorage 桥接)
│ ├── logo.ts # Logo 资产 URL 解析
│ ├── pricing.ts # 成本计算Python 六种定价模式移植)
│ ├── enum-resolver.ts # 枚举外观模式7 模块标签/颜色统一解析)
│ ├── display.ts # 金额/日期格式化
│ └── type.ts # Nullable<T> 类型别名
├── shared/ # 主进程 & 渲染进程共享
│ ├── constants/
│ │ ├── app.ts # 应用名称/版本类型/窗口标题
│ │ ├── ipc-channels.ts # 全部 IPC 通道名称(三类命名空间)
│ │ └── version.ts # 从 package.json 读取版本号
│ ├── types/
│ │ ├── index.ts # 通用类型Platform/Theme/Edition/Update/Window
│ │ └── logging.ts # 日志类型LogLevel/LogCategory/LogEntry
│ └── utils/
│ ├── index.ts # 纯工具函数debounce/throttle/compareVersions/deepClone
│ └── sanitize.ts # 日志脱敏token/密码/邮箱/手机/ID/金额)
├── scripts/ # 构建与发布脚本
│ ├── clean.mjs # 清理构建产物
│ ├── generate-update-info.mjs # 生成 update-info.jsonSHA512 + CHANGELOG
│ ├── upload-oss.mjs # 上传安装包到阿里云 OSS
│ └── publish-release.mjs # 发布版本到后端 API
├── build.mjs # electron-builder 构建总管
├── vite.config.ts # Vite 构建配置
├── package.json # 含 electron-builder 打包配置
└── pnpm-workspace.yaml
```
# 多窗口与平台判定
- 窗口管理由 `electron/main.ts` 统一负责:`createMainWindow()` 创建主窗口,`BrowserWindow` 通过 `contextIsolation: true` + `nodeIntegration: false` 运行沙箱化渲染进程。辅助窗口通过 `RENDERER_TO_MAIN.OPEN_SUB_WINDOW` IPC 通道按需创建。
- 平台判定双端各有一份:`electron/main/utils/platform.ts`(主进程,直接使用 `process.platform`)和 `src/utils/platform.ts`(渲染进程,优先 `process.platform`,降级 `navigator.userAgent`)。
- 打包配置 (`package.json` build 字段) 须针对平台设置不同的图标、签名策略、安装包格式。
# 代码风格
## TypeScript
- 所有语句必须以分号 ; 结尾,缺失分号将被视为错误。
- 启用 strict 模式,禁止隐式 any优先使用 interface 定义对象类型,复杂类型可适度使用 type。
- 文件名使用小写短横线连接kebab-case如 use-window-state.ts组件文件名与组件名保持一致PascalCase
ThemeAdapter.tsx。
- 导入顺序:第三方库 → 项目内共享模块 → 相对路径模块,中间用空行分隔。
## React
- 只允许函数组件与 Hooks禁止使用类组件。
- 每个组件必须有明确的 Props 类型,使用 React.FC<Props> 或直接标注函数参数类型(推荐直接标注)。
- 事件处理函数命名以 handle 开头(如 handleClick自定义 Hook 以 use 开头。
- 避免直接操作 DOM除非封装在自定义 Hook 中(如焦点管理)。
- 使用 React.memo、useMemo、useCallback 优化性能,但不要过早优化。
## 状态管理
- 使用 React Context + Provider 模式管理全局状态按领域拆分AppContext平台/登录、ThemeContext主题
SettingsContext设置项。各 Context 定义与 Provider 合并在 `components/providers/` 目录下,避免引入 Redux 等重量级方案。
- Provider 在 main.tsx 中按层级嵌套挂载:
AppProvider → ThemeProvider → SettingsProvider → AntdApp → App
- 各模块通过自定义 Hook 消费useAppContext / useTheme / useSettingsHook 内部做 null 检查并抛出明确错误信息。
- 页面级状态(如首页的 selectedModel / selectedTask / 分页)放在 HomeContext 中,由 HomeContent 提供,遵循与全局 Provider 相同的 Context + Provider + Hook 模式。
## 日志系统
- 双端日志主进程直接写文件electron/main/logger.ts渲染进程通过 IPC send 上报src/utils/logger.ts
两端暴露一致的 API`logger.debug / info / warn / error(category, message, error?, context?)`
- 文件存储JSON Lines 格式(每行一个 JSON路径 `{userData}/logs/app-YYYY-MM-DD.log`
每日轮转 + 7 天自动清理。
- 事件总线联动event-bus.ts 暴露 `setEventLogListener` 钩子logger 注册后所有 emit 自动记录 DEBUG 日志。
- 错误日志request.ts 拦截器根据错误类型自动分级记录AUTH_EXPIRED → debug5xx → error其余 → warn
- 401 判断策略HTTP 401 拦截处双重校验——同时检查 HTTP 状态码和响应体中的业务码 `data.code`
`status === 401 && data?.code === 401` 才走 token 刷新流程;其他业务码(如密码错误)穿透到正常错误处理,
透传后端的 `data.message`。这确保登录接口返回的"账号或密码错误"不被 RefreshError("登录已过期") 覆盖。
- 脱敏shared/utils/sanitize.ts 在日志写入前自动处理 ID哈希、邮箱/手机/名称/Token 等字段。
# 安全与认证
## Token 加密存储
- `access_token``refresh_token` 通过 Electron `safeStorage` API 加密存储,不落明文:
- macOS → Keychain
- Windows → DPAPI
- Linux → libsecret
- 实现文件:
- `electron/main/safe-storage-ipc.ts` — 主进程加密/解密 IPC 处理(`BIDIRECTIONAL.SAFESTORAGE_ENCRYPT / DECRYPT`
- `src/utils/safe-storage.ts` — 渲染进程桥接层(`initSafeStore / getSafeStore / setSafeStore / clearSafeStore`
- `src/services/request.ts` — token 存取通过 `getSafeStore / setSafeStore`,无需感知加密细节
- `src/services/auth-token.ts` — refresh_token 同理通过 safeStorage 存取
## 双 Token 机制
- `access_token`(短效)+ `refresh_token`(长效),登录成功同时下发
- 请求拦截器自动附加 `Authorization: Bearer <access_token>`
- 401 响应 → 双重校验HTTP `status` + 业务 `data.code`)→ 仅 `code === 401` 时触发刷新
- 刷新期间并发请求排队(`failedQueue`),刷新完成后批量重试
- refresh 接口自身 401 直接拒绝防死循环login 接口 401 穿透透传后端 `message`
- 启动时 `refresh_token` 静默续期(自动登录),失败仅清除标记不影响用户名回填
- 登录/退出通过事件总线解耦(`LOGIN_SUCCESS` / `LOGOUT` / `AUTH_REQUIRED`
## 日志脱敏
- `shared/utils/sanitize.ts` 在日志写入前自动脱敏处理
- 覆盖字段:用户 IDSHA256 哈希)、邮箱(`***@domain`、手机号掩码、用户名称、Token截断
- 主进程 `electron/main/logger.ts` 和渲染进程 `src/utils/logger.ts` 均写入前调用 `sanitizeLogEntry()`
# 样式与主题
- 优先使用 Tailwind 工具类完成布局与常规样式。自定义设计令牌在 `src/theme/tokens.css``@theme` 块中定义Tailwind v4 语法),自动生成 `bg-primary-500``text-secondary` 等工具类。
- Ant Design 组件样式通过 ConfigProvider 的 theme 属性覆盖,确保与 Tailwind 主题令牌同步。
`ConfigProvider` 同时配置 `locale={zhCN}` 实现全局中文(分页器"条/页"等无需逐个组件设置)。
在 src/theme/ 中创建 antd-theme.ts导出主题配置对象引用 tokens.ts 中的设计变量。
组件级 token如 Pagination.itemActiveColor / itemActiveBg在 sharedComponents 中统一管理,
亮色/暗色主题共享,避免 CSS !important hack。
- 禁止在组件中硬编码颜色、字号等设计令牌,一律使用主题变量或 Tailwind 类名。
- 全局样式文件 globals.css 只引入 Tailwind 指令和必要的重置样式,不堆积组件样式。
# 事件与 IPC
- 所有 IPC 通道名称定义在 shared/constants/ipc-channels.ts 中,分为三类:
MAIN_TO_RENDERER / RENDERER_TO_MAIN / BIDIRECTIONAL。
- 渲染进程通过 src/utils/ipc.ts 中的安全守卫访问 IPChasIpc 检查 → safeIpcOn / send / invoke
非 Electron 环境下静默跳过,保证浏览器预览不崩溃。
- 主进程事件处理函数需做好错误捕获与日志记录,渲染进程调用 IPC 时使用 try-catch 并处理超时。
- 窗口间通信走主进程转发:发送窗口 safeIpcSend主进程接收后定位目标窗口并 webContents.send。
# 开发与构建命令
- 开发模式npm run dev 或 yarn dev同时启动 Vite 与 Electron支持热重载
- 构建npm run build 编译渲染进程 → 打包 Electron 应用。
- 代码检查npm run lintESLint + Prettier规则已配置为强制分号、单引号等
- 类型检查npm run typechecktsc --noEmit
# 自动更新系统
## 架构
```
客户端 (Electron 主进程)
checkForUpdates()
├─ ① HeiXiuProvider.getLatestVersion() → 调用自有版本检查 API
│ └─ hasUpdate=false → 直接 IPC 通知 UI不经过 electron-updater
└─ ② hasUpdate=true → electron-updater.checkForUpdates()
├─ HeiXiuProvider.getLatestVersion() → TTL 缓存命中,不重复请求
├─ emit 'update-available'(含 releaseNotes→ UI 展示版本信息
└─ 用户点击"下载更新" → downloadUpdate()
├─ 差分下载(对比 .blockmap仅下载变更区块
├─ SHA512 校验
└─ 下载完成 → 用户点击"安装更新" → NSIS/DMG/AppImage 执行
```
| 模块 | 位置 | 职责 |
|-------------------|-----------------------------------------------|------------------------------------------|
| `HeiXiuProvider` | `electron/main/updater.ts` | 自定义 Provider调用自有 API无更新返回 APP_VERSION |
| `checkForUpdates` | `electron/main/updater.ts` | 预检版本 → 无更新直发 IPC / 有更新交 electron-updater |
| `downloadUpdate` | `electron/main/updater.ts` | 用户确认后触发下载(从 checkForUpdates 分离) |
| `netRequest` | `electron/main/net-request.ts` | Electron net.request 的 axios 风格封装 |
| `useUpdater` | `src/hooks/use-updater.ts` | 渲染进程更新状态 Hook单例 IPC 监听) |
| `UpdateSetting` | `src/pages/settings/blocks/UpdateSetting.tsx` | 设置页更新区块(含"查看详情"弹窗) |
| `server.py` | `test-server/server.py` | 本地测试服务器,扫描 release/ 目录,语义版本排序 |
## 增量更新(差分下载)
- `package.json` 配置 `"differentialPackage": true`electron-builder 打包时自动生成 `.exe.blockmap` 文件
- 自定义 Provider 模式:`HeiXiuNsisUpdater extends NsisUpdater` / `HeiXiuMacUpdater extends MacUpdater` /
`HeiXiuAppImageUpdater extends AppImageUpdater`
- 三平台 Updater 均覆盖 `getUpdateInfoAndProvider()` 注入 `HeiXiuProvider`(自定义 API 版本检查),差分下载由
electron-updater 父类原生处理
- blockmap 文件流程:
- `scripts/generate-update-info.mjs` — 扫描 blockmap 文件,写 `blockmap.url` + `blockmap.size``update-info.json`
- `scripts/upload-oss.mjs` — 安装包 + blockmap 文件一并上传 OSS支持 Node.js 直传和 ossutil 两种模式)
- `scripts/publish-release.mjs` — 通过 `--blockmap-url` 参数将 blockmap 信息发布到后端 API
- 效果:日常更新仅下载变更区块,预计节省 60%~90% 流量
## 环境变量加载机制(主进程)
加载顺序后者覆盖前者OS 环境变量始终优先):
```
① OS 环境变量set KEY=VALUE && .\app.exe ← 最高优先级
② .env.local不进 git个人覆盖用
③ .env.{mode}dev→.env.developmentbuild→.env.production
④ updater.ts 硬编码默认值https://www.heixiu.com
```
| 文件 | 何时生效 | 进 git | 用途 |
|--------------------|---------------------|:-----:|--------------------|
| `.env.development` | `npm run dev` | ✅ | 本地开发API → 测试服务器) |
| `.env.production` | `npm run build:xxx` | ❌ | 构建时参考API → 生产服务器) |
| `.env.local` | 始终(后加载) | ❌ | 个人特殊配置(打包后连本地测试) |
> `.env.production` 和 `.env.local` 不打包进 ASAR。打包后无这些文件时自动使用代码默认值。
## 测试工作流
```powershell
# 1. 构建两个版本
npm run build:win # → release/0.0.3/
# 改 package.json version = "0.0.4"
npm run build:win # → release/0.0.4/
# 2. 启动测试服务器
cd test-server && python server.py --release-dir ../release --port 8000
# 3. 启动旧版本客户端
set UPDATE_API_URL=http://127.0.0.1:8000 && .\release\0.0.3\win-unpacked\船长·HeiXiu.exe
# → 5 秒后自动检测到 0.0.4 → 差分下载 → 提示安装
```
相关文档:[UpdateA.md](UpdateA.md)、[test-server/README.md](test-server/README.md)
# 与其他 AI 协作的补充说明
- 所有生成的代码片段必须放在完整的文件上下文中,并注明所属文件路径。
- 若涉及跨平台逻辑,必须同时给出 Windows 与 macOS 的兼容实现或判断分支。
- 新增窗口时,需同步说明窗口入口、预加载脚本、主进程创建逻辑及 IPC 通道注册。
- 修改主题令牌时,需同步更新 tokens.ts、tokens.css 及 antd-theme.ts确保三处一致。