Files
ele-HeiXiu/UpdateA.md
YoungestSongMo ae733016bb feat: 日志模块 + netRequest 封装 + PROJECT.md 更新
日志模块(文件持久化 + 事件总线联动 + 脱敏)
    新增:
      - shared/types/logging.ts         — LogLevel / LogCategory / LogEntry 类型
      - electron/main/logger.ts         — 主进程日志核心(JSON Lines / 每日轮转 / 7天清理)
      - electron/main/log-ipc.ts        — 渲染进程日志 IPC 通道接收
      - src/utils/logger.ts             — 渲染进程日志器(IPC 转发 / DEV 控制台 / 事件总线钩子)
      - shared/utils/sanitize.ts        — 脱敏工具(ID哈希 / 邮箱 / 手机 / 名称 / Token)
    修改:
      - electron/main.ts                — initLogger + flushLogger + uncaughtException
      - src/main.tsx                    — renderer 全局错误捕获
      - src/utils/event-bus.ts          — setEventLogListener 钩子,emit 自动审计
      - src/services/request.ts         — 拦截器结构化错误分级记录
      - electron/main/updater.ts        — 14处 console → logger 迁移
      - src/components/AppProvider.tsx   — 登录/登出/自动登录 auth 事件日志
      - shared/constants/ipc-channels.ts — 新增 LOG_MESSAGE 通道

  netRequest 封装(Electron net.request 的 axios 风格 API)
    新增:
      - electron/main/net-request.ts     — netRequest.get/post/put/del 命名空间
    修改:
      - electron/main/updater.ts         — fetchUpdateInfo 改用 netRequest(22→12行)

  文档更新
    - PROJECT.md                       — 目录结构 / 状态管理 / 日志系统 / IPC 章节同步现状
    - TODO.md                          — 增量更新改造 + 日志模块待办
    - UpdateA.md                       — API blockmap 字段 / 数据库字段说明
2026-06-04 11:03:25 +08:00

313 lines
13 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.
# HeiXiu 构建 & 发布手册
> 面向前端发版 + 后端 API 对接
---
## 一、整体架构
```
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ 客户端 (Electron)│ │ ECS (API 服务) │ │ OSS (阿里云) │
│ │ GET │ │ │ │
│ 版本检查 ─────────┼────────▶│ /api/v1/update/ │ │ │
│ │ │ check │ │ │
│ │◀────────│ 返回 JSON │ │ │
│ │ │ (含 blockmap 信息) │ │ │
│ │ │ │ │ │
│ 增量下载(未来)────┼─────────┼──────────────────┼────────▶│ 静态文件托管 │
│ 仅下载变化块 │◀────────┼──────────────────┼─────────│ .exe + .blockmap │
│ │ │ │ │ │
│ 本地重建安装包 │ │ │ │ │
│ 校验 SHA512 │ │ │ │ │
│ NSIS /S 静默安装 │ │ │ │ │
│ → app.quit() │ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
```
> **当前状态**:客户端为全量下载(`net.request` 下载完整 .exe。`electron-builder` 打包已生成 `.exe.blockmap` 文件(`"differential": true`),但客户端尚未使用。**增量下载**electron-updater 自定义 Provider为规划中的优化。
| 角色 | 技术 | 职责 |
|-----|--------------------|---------------------------------|
| 客户端 | Electron + electron-updater | 调用 API → 下载 blockmap → 差分下载 → 重建 → 校验 → 安装 |
| ECS | 任意后端语言 | 提供版本检查 API含 blockmap 信息) |
| OSS | 阿里云对象存储 | 托管 .exe / .dmg / .AppImage + .blockmap |
---
## 二、项目脚本速查
### 总入口:`build.mjs`
```bash
node build.mjs --help # 查看完整帮助
npm run build:win # 打包 Windows 个人版(快捷命令)
```
### npm 命令速查
```bash
# 构建(仅打包,不上传/发布)
npm run build:win # Windows 个人版
npm run build:win:enterprise # Windows 企业版
npm run build:mac # macOS 个人版
npm run build:linux # Linux 个人版
# 工具
npm run build:clean # 清理 release/ + dist/ + dist-electron/
node build.mjs --win --personal --help # 查看完整 CLI 指南
# 独立脚本(需传参数)
node scripts/generate-update-info.mjs <平台> <版本类型> [版本号] [--url <url>]
node scripts/upload-oss.mjs <平台> <版本类型> [版本号]
node scripts/publish-release.mjs <平台> <版本类型> [版本号] [--url <url>]
```
### `build.mjs` 操作组合
| 操作 | 说明 |
|-------------|------------------------------------------------------|
| `--build` | 构建tsc + vite + electron-builder + update-info.json |
| `--clean` | 清理旧产物 |
| `--sign` | 代码签名(配合 `--cert` 或环境变量) |
| `--upload` | 上传 OSS |
| `--publish` | POST 版本信息到后端 API |
| `--all` | 全流程 = clean + build + sign + upload + publish |
---
## 三、发版工作流
### 路径 A快速打包日常开发 / 内部测试)
```bash
# 1. 修改版本号
# package.json → "version": "0.1.0"
# 2. 写更新日志
# CHANGELOG.md → 顶部新增 ## 0.1.02026-xx-xx...
# 3. 打包
npm run build:win && npm run build:win:enterprise
# 4. 产物在 release/0.1.0/ 下:
# - xxx-Setup.exe安装包
# - xxx-Setup.exe.blockmap块映射增量更新用
# - xxx-update-info.json所有 API 字段downloadUrl 为预判 URL
# 5. 手动上传 exe + .blockmap 到 OSS releases/0.1.0/
# 6. 将 update-info.json 内容录入数据库 releases 表
```
### 路径 B先上传再确定 URL
```bash
# 打包
npm run build:win
# 上传到 OSS自动打印实际 URL
node scripts/upload-oss.mjs win32 personal 0.1.0
# 用实际 URL 重新生成 update-info.json
node scripts/generate-update-info.mjs win32 personal 0.1.0 \
--url "https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases/0.1.0/xxx.exe"
# 将 update-info.json 录入数据库
```
### 路径 C全自动上传 + 发布一条龙)
```bash
# 一步到位(需先配置环境变量)
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com \
OSS_BUCKET=heixiu \
OSS_ACCESS_KEY_ID=xxx \
OSS_ACCESS_KEY_SECRET=xxx \
UPDATE_API_KEY=xxx \
node build.mjs --win --personal --upload --publish
```
---
## 四、代码签名
### 证书获取
| 平台 | 格式 | 渠道 | 年费 |
|---------|-------------------|---------------------------------|----------|
| Windows | `.pfx` / `.p12` | DigiCert / Sectigo / GlobalSign | $200-700 |
| macOS | `.p12` / Keychain | Apple Developer Program | $99 |
> EV 证书立即消除 SmartScreen 警告OV 证书需积累下载量。
### 签名方式
```bash
# 方式 1build.mjs 参数
node build.mjs --win --personal --sign --cert ./cert.pfx --cert-password xxx
# 方式 2环境变量CI/CD 友好)
CSC_LINK=/path/to/cert.pfx CSC_KEY_PASSWORD=xxx npm run build:win
```
> SHA512 校验值会在签名后自动计算(签名改变文件字节,必须先签后校)。
---
## 五、API 接口
### `GET /api/v1/update/check`
**参数**`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不影响现有数据。首次发版时无需回填历史数据——客户端检测到字段为空时自动回退全量下载。
---
## 七、客户端行为
| 场景 | 行为 |
|------|-----------------------------------|
| 启动 | 5 秒后静默检查更新(仅生产环境) |
| 手动检查 | 点击按钮 → 调用 API → 反馈结果 |
| 下载 | 流式写入临时目录SHA512 实时校验,每 250ms 推送进度 |
| 安装 | 用户确认 → spawn NSIS /S → app.quit() |
| 强制更新 | `forceUpdate=true` 时不可跳过 |
| 开发模式 | 跳过所有更新检查 |
---
## 八、环境变量速查
| 变量 | 默认值 | 用途 |
|-------------------------|--------------------------------------------------------|----------------------|
| `UPDATE_API_URL` | `https://www.heixiu.com` | 版本检查 API 基地址 |
| `UPDATE_API_KEY` | — | 发布 API 鉴权 Key |
| `UPDATE_DOWNLOAD_BASE` | `https://heixiu.oss-cn-hangzhou.aliyuncs.com/releases` | 预判 URL 基地址 |
| `OSS_ENDPOINT` | — | 阿里云 OSS endpoint |
| `OSS_BUCKET` | — | 阿里云 OSS bucket |
| `OSS_ACCESS_KEY_ID` | — | 阿里云 AccessKey ID |
| `OSS_ACCESS_KEY_SECRET` | — | 阿里云 AccessKey Secret |
| `OSS_BASE_PATH` | `releases` | OSS 内基路径 |
| `CSC_LINK` | — | 签名证书路径 |
| `CSC_KEY_PASSWORD` | — | 签名证书密码 |
| `UPDATE_FORCE` | `false` | 强制更新标记(打包时) |
| `UPDATE_CHANGELOG` | 读取 CHANGELOG.md | 覆盖更新日志CI/CD |
---
## 九、文件结构
```
ele-heixiu/
├ build.mjs ← 构建总管npm run build 入口)
├ CHANGELOG.md ← 更新日志(打包时自动提取)
├ UpdateA.md ← 本文档
├ package.json ← 仅保留简短的 npm 快捷命令
├ scripts/
│ ├ clean.mjs ← 清理产物
│ ├ generate-update-info.mjs ← 生成 API 信息 JSON含 blockmap 信息)
│ ├ upload-oss.mjs ← 上传 OSS安装包 + blockmap
│ └ publish-release.mjs ← 发布到 APIaxios
├ release/ ← 构建产物目录(按版本分)
│ └ 0.1.0/
│ ├ xxx-Setup.exe
│ ├ xxx-Setup.exe.blockmap ← 差分更新块映射文件
│ └ xxx-update-info.json
├ dist/ ← Vite 前端产物(构建输入)
└ dist-electron/ ← Electron 主进程产物(构建输入)
```
---
_如有接口或流程变更,请同步更新此文档。_