应用更新与统计方案
状态:Phase 0 已实现(版本检测 / 下载安装 / 启动静默检查),统计与官网/后台为后续规划。 相关代码:
src/services/update.service.ts、src/pages/update/index.vue、src/constants/app.ts、src/types/update.ts、src/static/version.json。
1. 背景与约束
爱生活是离线优先、隐私至上的应用(App Store 隐私标签声明"不收集任何数据"),目前:
- 无官网、无后台管理系统、无应用商店上架渠道
- H5 静态部署,Android 侧载 APK,iOS 待 TestFlight/App Store
- 同步引擎已有可插拔 Provider(WebDAV / GitHub Gist),为后续扩展提供参考模式
因此升级与统计方案遵循两条原则:
- 零后端起步:版本清单就是一个静态 JSON,托管在任何静态服务器上,不需要自建后台
- 统计默认关闭、匿名化、可透明查看:不违背产品隐私承诺
2. 升级方案(已实现:Phase 0)
2.1 核心:静态版本清单 version.json
所有平台共用一份清单(结构见 src/types/update.ts):
{
"versionName": "1.1.0",
"versionCode": 101,
"minVersionCode": 100,
"releaseDate": "2026-08-20",
"changelog": ["新增:xxx", "修复:yyy"],
"rollout": 100,
"platforms": {
"android": { "url": "https://…/ai-life-os-1.1.0.apk", "sha256": "…", "size": 26843545 },
"wgt": { "url": "https://…/app.wgt", "sha256": "…", "size": 1048576 },
"h5": { "url": "" }
}
}字段说明:
| 字段 | 说明 |
|---|---|
versionCode | 与 manifest.json 的 versionCode 对应,比较以此为准 |
minVersionCode | 低于此版本的安装 → 强制更新(全局弹窗不可"稍后再说",必须升级) |
rollout | 灰度比例 0-100;按设备稳定 ID 的 FNV-1a 哈希决定是否可见 |
platforms.android | Android 整包 APK(优先) |
platforms.wgt | wgt 资源包热更新(Android/iOS 通用,仅更 JS/页面) |
platforms.h5 | H5 更新项:有 url 跳转新地址,否则原地刷新 |
2.2 分平台更新策略
| 平台 | 更新方式 | 说明 |
|---|---|---|
| Android | 整包 APK 下载安装(platforms.android 优先) | plus.downloader 带进度下载 → 大小校验(HTTPS + 下载字节数;设备端分块 SHA-256 在部分 webview 不可靠故省略,sha256 保留供发布端审计)→ plus.runtime.install({force:true})。Android 8+ 需在 HBuilderX 云打包配置 REQUEST_INSTALL_PACKAGES 权限 |
| Android/iOS | wgt 热更新(platforms.wgt) | 紧急修复/小版本,安装后延迟 2.5s 自动重启(先关闭 SQLite 原生连接)。iOS 上 wgt 属灰色地带(Apple 禁止下载代码),仅限小修小补 |
| H5 | 重新部署 + 刷新/跳转 | Vite 构建产物带 hash,index.html 不缓存 + assets/ 长期缓存即可 |
| iOS 正式版 | TestFlight / App Store | 无自建整包分发渠道(法律与可行性限制) |
| 微信小程序 | 微信发布体系 | 不参与自更新 |
2.3 检查流程(src/services/update.service.ts)
解锁/手动触发 → getLocalVersion()(App 用 plus.runtime.getProperty 真实版本,其余用构建期注入常量)
→ fetchManifest()(地址优先级:VITE_UPDATE_MANIFEST_URL > App 内置默认公开仓库(HBuilderX 打包无需配置)> H5 同源 /static/version.json)
→ evaluateManifest():
① versionCode 比较(低于/等于本地 → 已是最新)
② rollout 灰度(hash(deviceId) % 100 >= rollout → 不提示)
③ 平台目标(android > wgt > h5;小程序不参与)
④ minVersionCode → 是否强制
→ 有更新:全局弹窗(`src/components/common/UpdatePrompt.vue`,挂在 Layout 上)
展示 changelog + 下载进度,任何页面直接弹出,不跳转触发入口:
- 解锁后自动检查:
src/App.vue监听appLocked由 true→false(解锁完成),延迟 1.2s 后调用useUpdateStore().check();同一会话「稍后再说」后不再自动弹出 - 手动检查:设置页 → 检查更新(
src/pages/update/index.vue),调用store.check(true)强制弹窗 - 安装完成后:wgt 延迟 2.5s 自动重启(等待资源落盘,避免立即重启导致运行时损坏),重启前
closeNativeDatabase()关闭 SQLite 原生连接(软重启不释放原生句柄,不关库会导致重启后数据读取失败)
2.4 版本注入
vite.config.ts构建期读取版本,define注入__APP_VERSION__/__APP_VERSION_CODE__- 版本来源优先级:
src/manifest.json(HBuilderX 打包口径)>package.json(兜底) src/constants/app.ts消费注入值(测试环境回退 1.0.0/100)- 页面显示版本统一取运行时(
getLocalVersion()→ plus.runtime):关于页、检查更新页一致,wgt 更新后保持正确
2.5 发版流程(发布者操作)
📖 完整操作手册见
docs/release-guide.md(含回滚方案、验收清单、踩坑记录)。
推荐架构:源码私有 + 发布公开双仓库
- 源码仓库
lutlelk/ai-life-os保持私有,不对外 - 另建一个公开仓库(如
lutlelk/ai-life-os-release)只放发布产物:- Release 附件(APK / wgt)→ 公开仓库附件可匿名下载(私有仓库会 403)
- 仓库根目录的
version.json→ App 端通过 raw 链接读取(无需鉴权)
- App 端无需配置环境变量:内置默认指向该公开仓库(HBuilderX 云打包不带 .env,代码内兜底;CLI 构建可用
VITE_UPDATE_MANIFEST_URL覆盖为自建服务器) - H5 端沿用同源
/static/version.json(跟随 H5 部署)
方式一:脚本一键发布(推荐) — scripts/release-gitee.mjs
# 构建产物后,一条命令完成:建 Release + 传附件 + 回写本地清单 + 推送远端清单
GITEE_TOKEN=你的令牌 node scripts/release-gitee.mjs \
--release-repo lutlelk/ai-life-os-release \
--files dist/build/app/android-release.apk dist/build/app/app.wgt \
--changelog "新增:xxx" \
--update-manifest src/static/version.json \
--push-manifest--release-repo:公开发布仓库(缺省=源码仓库);源码仓库仅用于读版本号,不写入任何内容--push-manifest:把 version.json 通过 contents API 提交到发布仓库根目录,脚本最后会打印建议的VITE_UPDATE_MANIFEST_URL- 仓库地址自动从
package.json解析,tag 默认v{version};发布仓库为私有时会红字警告 - Gitee 私人令牌:头像 → 设置 → 安全设置 → 私人令牌(勾选 releases 权限),只在生成时显示一次
- 完整用法见脚本头部注释
方式二:网页手动上传
- 仓库页 → 右侧「发行版」→「新建发行版」
- 填标签(
v1.1.0)、标题、更新说明(Markdown,即 changelog) - 「添加附件」上传 APK / wgt → 发布
- 进入发行版页,复制附件下载链接(Gitee 格式为
https://gitee.com/{owner}/{repo}/attach_files/{id}/download/{文件名},每次上传链接都会变) - 把链接填进
version.json的platforms.android.url/platforms.wgt.url(sha256 可用shasum -a 256 文件生成)
手动发版清单(两种方式通用)
① 改 manifest.json(versionCode+1、versionName)与 package.json(version)
② 构建:
- H5:npm run build:h5 → 部署 dist/build/h5(version.json 跟随 H5 同源部署)
- Android:npm run build:app-android → 签名 APK
- wgt:HBuilderX「发行 → 制作应用资源升级包」
③ 上传 APK / wgt 到 Gitee Releases(脚本或网页)
④ 更新 version.json(versionCode、changelog、下载地址、sha256、size、rollout)
⑤ git tag vx.y.z && pushCORS / 可见性注意事项:
- Gitee 附件与 raw 文件不带 CORS 头 —— App 原生下载/请求不受影响,但 H5 浏览器不能直接 fetch gitee.com 的文件 → version.json 的 H5 读取走同源
/static/version.json(跟随 H5 部署)- 私有仓库的 Release 附件无法匿名下载(403) → 发布仓库必须设为公开(源码仓库可保持私有)
- 建议
version.json的 HTTP 缓存 TTL 设短(如 60s)或 no-cache,保证检查即时生效。
2.6 环境变量
# .env.production(仅自建服务器/其它托管时需要;App 有内置默认,可省略)
# VITE_UPDATE_MANIFEST_URL=https://your-host/version.json地址优先级:VITE_UPDATE_MANIFEST_URL > App 内置默认(https://gitee.com/lutlelk/ai-life-os-release/raw/master/version.json,HBuilderX 云打包不带 .env 也能用)> H5 同源 /static/version.json(src/static/version.json 已随构建拷贝到产物 static/ 目录)。
3. 统计方案(规划:Phase 1+)
核心约束:不违背"不收集数据"的隐私承诺 → 统计必须 匿名 / 默认关闭 / 可透明查看 / 可一键删除。
方案 A:本地统计(推荐必做,零网络)
src/services/event.service.ts 已把各模块写操作统一记录到本地 lifeEvents 表 —— 本地统计的底座现成:
- 本地聚合:模块使用频率、打卡率、番茄钟完成数 → 喂给现有 AI 洞察/回顾
- 设置页「使用数据」透明页:展示、导出、一键清空
方案 B:免费第三方渠道(近零代码)
| 渠道 | 说明 |
|---|---|
| uni统计(DCloud) | uni-app 官方,HBuilderX 一键开通;页面访问 + uni.report() 事件 + 崩溃,免费 |
| 友盟+ / Bugly | 国内 App 标配,有 uni-app 集成;含留存与崩溃分析 |
| 商店后台 | 上架应用宝/华为/小米/Google Play 后,各市场自带 DAU/MAU/安装/卸载统计 |
方案 C:自建匿名遥测(完全自主可控)
- 事件仅上报
{ deviceIdHash(HMAC+盐), platform, version, event, ts },不含用户内容 - 默认关闭,设置页展示待上报队列,一键删除
- 接收端复用现有同步思路(WebDAV/Gist/静态站 + 离线脚本解析)
- H5 官网可上 Umami / Plausible / Cloudflare Web Analytics(隐私友好、免费、可自托管)
合规要点
- 苹果隐私标签一旦接统计,需从"不收集"改为声明 Analytics 收集并更新隐私政策 → 默认关闭 + 明示是关键
- 国内按《个人信息保护法》:匿名聚合数据风险低;接第三方 SDK 需在隐私政策声明
4. 官网 & 后台(规划:Phase 2)
- 官网:现有 VitePress 文档站(
docs/)扩展 Download 页(APK 下载 + H5 入口 + changelog + 隐私政策),部署 Cloudflare Pages / Gitee Pages - 后台:前期不需要管理系统 —— Git Releases + version.json 即"发布后台";需要发布管理时再加 Cloudflare Worker + KV 或云函数的极简
/api/releases/latest
5. 路线图
| Phase | 内容 | 状态 |
|---|---|---|
| 0 | 版本清单检测、Android 整包/wgt 下载安装、启动静默检查、H5 兜底清单 | ✅ 已实现 |
| 1 | uni统计 开通 + 商店渠道;「使用数据」本地透明页 | 待做 |
| 2 | VitePress 官网 + Download 页 + CI 发版流水线 | 待做 |
| 3 | 匿名遥测上报 + 轻量发布后台 | 待做 |