日志模块(文件持久化 + 事件总线联动 + 脱敏)
新增:
- 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 字段 / 数据库字段说明
13 KiB
13 KiB
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
node build.mjs --help # 查看完整帮助
npm run build:win # 打包 Windows 个人版(快捷命令)
npm 命令速查
# 构建(仅打包,不上传/发布)
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:快速打包(日常开发 / 内部测试)
# 1. 修改版本号
# package.json → "version": "0.1.0"
# 2. 写更新日志
# CHANGELOG.md → 顶部新增 ## 0.1.0(2026-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
# 打包
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:全自动(上传 + 发布一条龙)
# 一步到位(需先配置环境变量)
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 证书需积累下载量。
签名方式
# 方式 1:build.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)
有更新:
{
"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时启用增量下载,缺失时回退全量下载。
无更新:
{
"code": 0,
"data": {
"hasUpdate": false
}
}
POST /api/v1/releases(发布用)
{
"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>
六、数据库
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 ← 发布到 API(axios)
├ release/ ← 构建产物目录(按版本分)
│ └ 0.1.0/
│ ├ xxx-Setup.exe
│ ├ xxx-Setup.exe.blockmap ← 差分更新块映射文件
│ └ xxx-update-info.json
├ dist/ ← Vite 前端产物(构建输入)
└ dist-electron/ ← Electron 主进程产物(构建输入)
如有接口或流程变更,请同步更新此文档。