feat: 重构更新流程 — 无更新不抛异常、用户决定下载、更新详情展示(md文件中的)
【核心重构】
- getLatestVersion() 不再 throw Error,无更新时返回 { version: APP_VERSION }
- checkForUpdates() 先自行预检 → 无更新直发 IPC,有更新才交 electron-updater
- 移除 NO_UPDATE_MESSAGE 常量及所有字符串匹配拦截代码
- HeiXiuProvider 增加 500ms TTL 缓存,避免预检+electron-updater 重复请求 API
【用户体验】
- 检查到新版本后不再自动下载,展示更新内容供用户决定
- 新增"下载更新"按钮(与"安装更新"分离为两步操作)
- 设置页新增"查看详情"弹窗,Markdown 格式化渲染更新日志
- available / downloading / downloaded 三个状态 UI 独立展示
【Bug 修复】
- 测试服务器版本排序:字符串序 → 语义版本序(_version_key),0.0.10 正确 > 0.0.9
- 版本比较:!= → <(_version_key),防止高版本误判为有更新
- get_best_release fallback 同样改为语义版本排序
- Windows cmd set 命令尾部空格 → Invalid URL(.trim() 修复)
- electron-updater 'error' 事件中拦截 NO_UPDATE_MESSAGE → UPDATE_NOT_AVAILABLE
【文档更新】
- CHANGELOG.md、PROJECT.md、UpdateA.md 同步更新架构图和流程说明
This commit is contained in:
162
UpdateA.md
162
UpdateA.md
@@ -25,13 +25,14 @@
|
||||
└──────────────────┘ └──────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
> **当前状态**:客户端为全量下载(`net.request` 下载完整 .exe)。`electron-builder` 打包已生成 `.exe.blockmap` 文件(`"differential": true`),但客户端尚未使用。**增量下载**(electron-updater 自定义 Provider)为规划中的优化。
|
||||
> **当前状态**:客户端已集成 `electron-updater` + 自定义 `HeiXiuProvider`,支持增量下载。`electron-builder` 打包已生成
|
||||
`.exe.blockmap` 文件。主进程通过 `netRequest` 调用自有 API 获取版本信息,electron-updater 自动处理差分下载和 SHA512 校验。
|
||||
|
||||
| 角色 | 技术 | 职责 |
|
||||
|-----|--------------------|---------------------------------|
|
||||
| 角色 | 技术 | 职责 |
|
||||
|-----|-----------------------------|--------------------------------------------|
|
||||
| 客户端 | Electron + electron-updater | 调用 API → 下载 blockmap → 差分下载 → 重建 → 校验 → 安装 |
|
||||
| ECS | 任意后端语言 | 提供版本检查 API(含 blockmap 信息) |
|
||||
| OSS | 阿里云对象存储 | 托管 .exe / .dmg / .AppImage + .blockmap |
|
||||
| ECS | 任意后端语言 | 提供版本检查 API(含 blockmap 信息) |
|
||||
| OSS | 阿里云对象存储 | 托管 .exe / .dmg / .AppImage + .blockmap |
|
||||
|
||||
---
|
||||
|
||||
@@ -156,113 +157,51 @@ CSC_LINK=/path/to/cert.pfx CSC_KEY_PASSWORD=xxx npm run build:win
|
||||
|
||||
## 五、API 接口
|
||||
|
||||
### `GET /api/v1/update/check`
|
||||
客户端调用的两个端点,完整规格见 [test-server/README.md](test-server/README.md)(可直接发给后端程序员)。
|
||||
|
||||
**参数**:`platform`(win32/darwin/linux)、`version`(三段式 semver)、`edition`(personal/enterprise)
|
||||
|
||||
**有更新**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"hasUpdate": true,
|
||||
"latestVersion": "0.1.0",
|
||||
"downloadUrl": "https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases/0.1.0/xxx.exe",
|
||||
"fileSize": 98765432,
|
||||
"sha512": "Base64...",
|
||||
"blockMapUrl": "https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases/0.1.0/xxx.exe.blockmap",
|
||||
"blockMapSize": 152340,
|
||||
"changelog": "更新日志...",
|
||||
"releaseDate": "2026-06-03",
|
||||
"forceUpdate": false,
|
||||
"minimumVersion": "0.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|:--:|------|
|
||||
| `blockMapUrl` | string | 否 | blockmap 文件 OSS 地址(客户端未支持增量时可不传,传了也不影响) |
|
||||
| `blockMapSize` | number | 否 | blockmap 文件字节数 |
|
||||
|
||||
> **向后兼容**:`blockMapUrl` / `blockMapSize` 为可选字段。旧版客户端不关心增量更新;新版客户端检测到有 `blockMapUrl` 时启用增量下载,缺失时回退全量下载。
|
||||
|
||||
**无更新**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"data": {
|
||||
"hasUpdate": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /api/v1/releases`(发布用)
|
||||
|
||||
```json
|
||||
{
|
||||
"platform": "win32",
|
||||
"edition": "personal",
|
||||
"latestVersion": "0.1.0",
|
||||
"downloadUrl": "https://...",
|
||||
"fileSize": 112910987,
|
||||
"sha512": "Base64...",
|
||||
"blockMapUrl": "https://...",
|
||||
"blockMapSize": 152340,
|
||||
"changelog": "...",
|
||||
"releaseDate": "2026-06-03",
|
||||
"forceUpdate": false,
|
||||
"minimumVersion": "0.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
> Header: `Authorization: Bearer <UPDATE_API_KEY>`
|
||||
|
||||
---
|
||||
|
||||
## 六、数据库
|
||||
|
||||
```sql
|
||||
CREATE TABLE releases
|
||||
(
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
platform VARCHAR(10) NOT NULL COMMENT 'win32 / darwin / linux',
|
||||
edition VARCHAR(10) NOT NULL COMMENT 'personal / enterprise',
|
||||
version VARCHAR(20) NOT NULL COMMENT '三段式 semver',
|
||||
file_url VARCHAR(500) NOT NULL COMMENT '安装包 OSS HTTPS 地址',
|
||||
file_size BIGINT NOT NULL COMMENT '安装包字节数',
|
||||
sha512 VARCHAR(128) NOT NULL COMMENT '安装包 SHA512 Base64',
|
||||
blockmap_url VARCHAR(500) COMMENT 'blockmap 文件 OSS 地址(增量更新用,可为空)',
|
||||
blockmap_size BIGINT COMMENT 'blockmap 文件字节数',
|
||||
changelog TEXT,
|
||||
force_update TINYINT(1) DEFAULT 0,
|
||||
min_version VARCHAR(20) DEFAULT '',
|
||||
release_date DATE NOT NULL,
|
||||
status VARCHAR(10) DEFAULT 'draft' COMMENT 'draft / published / deprecated',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE KEY uk_platform_edition_version (platform, edition, version),
|
||||
INDEX idx_platform_edition_status (platform, edition, status)
|
||||
);
|
||||
```
|
||||
|
||||
> **新字段说明**:`blockmap_url` 和 `blockmap_size` 为可选字段(DEFAULT NULL),不影响现有数据。首次发版时无需回填历史数据——客户端检测到字段为空时自动回退全量下载。
|
||||
| 端点 | 用途 |
|
||||
|----------------------------|-------------------------------------|
|
||||
| `GET /api/v1/update/check` | 客户端版本检查,返回最新版本信息(含 blockmap 用于增量更新) |
|
||||
| `POST /api/v1/releases` | 前端构建脚本发布新版本,需 Bearer Token 鉴权 |
|
||||
|
||||
---
|
||||
|
||||
## 七、客户端行为
|
||||
|
||||
| 场景 | 行为 |
|
||||
|------|-----------------------------------|
|
||||
| 启动 | 5 秒后静默检查更新(仅生产环境) |
|
||||
| 手动检查 | 点击按钮 → 调用 API → 反馈结果 |
|
||||
| 下载 | 流式写入临时目录,SHA512 实时校验,每 250ms 推送进度 |
|
||||
| 安装 | 用户确认 → spawn NSIS /S → app.quit() |
|
||||
| 强制更新 | `forceUpdate=true` 时不可跳过 |
|
||||
| 开发模式 | 跳过所有更新检查 |
|
||||
| 场景 | 行为 |
|
||||
|-------|------------------------------------------------|
|
||||
| 启动 | 5 秒后静默检查更新(仅检查,不自动下载) |
|
||||
| 手动检查 | 点击按钮 → 调用 API → 展示结果 |
|
||||
| 发现新版本 | 展示版本号 + 更新日志 + "查看详情"弹窗 + "下载更新"按钮 |
|
||||
| 下载 | 用户点击"下载更新" → electron-updater 差分下载 → SHA512 校验 |
|
||||
| 安装 | 下载完成后用户点击"安装更新" → quitAndInstall → NSIS /S |
|
||||
| 强制更新 | `forceUpdate=true` 时不可跳过 |
|
||||
| 开发模式 | 不跳过(已取消注释),通过 `.env.development` 指向测试服务器 |
|
||||
|
||||
### 环境变量加载顺序(主进程)
|
||||
|
||||
```
|
||||
① OS 环境变量(set UPDATE_API_URL=...) ← 最高优先级,不覆盖
|
||||
② .env.local(不进 git,个人覆盖用)
|
||||
③ .env.{mode}(开发→.env.development,打包→.env.production)
|
||||
④ updater.ts 硬编码默认值(https://www.heixiu.com)
|
||||
```
|
||||
|
||||
### 测试场景
|
||||
|
||||
```powershell
|
||||
# 场景 1:npm run dev 自动走 .env.development → http://127.0.0.1:8000
|
||||
|
||||
# 场景 2:打包后连本地测试(方式 A — .env.local)
|
||||
echo UPDATE_API_URL=http://127.0.0.1:8000 > .env.local
|
||||
.\release\0.0.3\win-unpacked\船长·HeiXiu.exe
|
||||
|
||||
# 场景 3:打包后连本地测试(方式 B — OS 环境变量)
|
||||
set UPDATE_API_URL=http://127.0.0.1:8000 && .\release\0.0.3\win-unpacked\船长·HeiXiu.exe
|
||||
|
||||
# 启动测试服务器
|
||||
cd test-server && python server.py --release-dir ../release --port 8000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -283,6 +222,17 @@ CREATE TABLE releases
|
||||
| `UPDATE_FORCE` | `false` | 强制更新标记(打包时) |
|
||||
| `UPDATE_CHANGELOG` | 读取 CHANGELOG.md | 覆盖更新日志(CI/CD) |
|
||||
|
||||
### .env 文件说明
|
||||
|
||||
| 文件 | 何时加载 | 进 git | 用途 |
|
||||
|--------------------|---------------------|:-----:|----------------------|
|
||||
| `.env.development` | `npm run dev` | ✅ | 开发环境(API 指向本地/测试服务器) |
|
||||
| `.env.production` | `npm run build:xxx` | ❌ | 生产构建(API 指向正式服务器) |
|
||||
| `.env.local` | 始终(后加载,覆盖前者) | ❌ | 个人特殊配置(如打包后连本地测试) |
|
||||
|
||||
> **重要**:`.env.production` 和 `.env.local` 不打包进 ASAR。打包后运行 `.exe` 时这些文件不存在,自动使用 `updater.ts`
|
||||
> 硬编码默认值。如需覆盖,使用 OS 环境变量或 `.env.local` 放在 exe 同目录(需配合 `loadEnvFile()` 的路径查找)。
|
||||
|
||||
---
|
||||
|
||||
## 九、文件结构
|
||||
|
||||
Reference in New Issue
Block a user