Skip to content

数据迁移指南

爱生活 内置了从旧版 uni.storage 到新版 Dexie/SQLite 引擎的自动迁移机制。用户升级应用后首次启动时自动执行,无需手动干预。

1. 迁移背景

维度旧版本新版本 (v1.0.0+)
存储引擎uni.storage(键值对)Dexie (H5) / SQLite (App)
加密方式每表独立加密存储EncryptedStore 透明加密
存储格式lifeos_{tableName}关系型数据表
数据容量受 uni.storage 限制更大容量(索引查询)

2. 自动迁移流程

/src/database/migration.ts — App 启动时 db.init() 自动触发:

db.init()

migrateFromLegacy(db)

① 检查 MIGRATED_KEY === '1' ?
    ├─ 是 → 跳过迁移
    └─ 否 → 继续

② 检查是否存在旧格式数据?
    ├─ 无 → 标记已迁移,结束
    └─ 有 → 继续

③ getActiveKey() 存在?
    ├─ 是 → 使用当前密钥
    └─ 否 → 弹出密码弹窗
        ├─ 取消 → 标记已迁移(跳过)
        └─ 输入密码 → 设置 ActiveKey

④ 遍历所有表(TABLE_NAMES)

⑤ 读取 uni.storage('lifeos_{tableName}')

⑥ 检测加密格式:{e, i, a, m}

⑦ decrypt(key, e, i, algo, m) → JSON.parse

⑧ bulkPut 写入新引擎

⑨ markMigrated() → 写入 MIGRATED_KEY = '1'

关键设计决策

  • 不自动清除旧数据:迁移完成后,旧 uni.storage 数据保留。用户可手动清理(安全性考虑,防止迁移异常导致数据丢失)
  • 迁移标记lifeos_migrated_v2 = '1' 存储在 uni.storage 中,避免每次启动重复执行
  • 密码弹窗:如果启动时尚未解锁,会弹出密码输入弹窗。用户取消则跳过本次迁移(下次启动再次尝试)

3. 旧数据格式

迁移仅处理以下格式的加密数据:

json
{
  "e": "base64-encoded-ciphertext",
  "i": "base64-encoded-iv",
  "a": "gcm | cbc",
  "m": "base64-encoded-hmac"
}
字段说明
e密文(Base64)
i初始化向量
a算法标识:gcmcbc
mHMAC 校验值(仅 CBC 模式)

4. 密码遗忘场景

场景一:忘记密码 + 已迁移到新引擎

数据已通过 AES-256-GCM 加密存储在新引擎中。无法恢复。唯一途径:使用之前导出的备份文件 + 旧密码通过"合并旧数据"功能恢复。

场景二:忘记密码 + 旧数据仍在 uni.storage

若迁移被跳过(用户取消密码输入),旧数据在 uni.storage 中保留。用户可在设置中重置加密(清除旧数据后重新设置密码),此时旧数据无法恢复。

场景三:忘记密码 + 有旧备份文件

使用 数据管理 → 合并旧数据 功能:

  1. 输入旧密码解密备份
  2. 用当前密钥重新加密
  3. 导入当前数据库

5. 手动迁移

如自动迁移失败,可通过以下方法手动迁移:

导出旧数据

在旧版本中执行:

数据管理 → 导出备份 → 保存 JSON 文件

导入新版本

在新版本中执行:

数据管理 → 导入恢复 → 选择备份文件

或使用"合并旧数据":

数据管理 → 合并旧数据 → 输入旧密码 → 选择备份文件

6. 跨设备迁移

使用云端同步

  1. 旧设备:配置 WebDAV / GitHub Gist → 上传
  2. 新设备:安装爱生活 → 设置相同加密密码 → 配置相同同步服务 → 下载

使用本地备份

  1. 旧设备:导出备份 → 将 JSON 文件传输到新设备
  2. 新设备:安装爱生活 → 设置相同加密密码 → 导入恢复

重要:新旧设备必须使用相同的加密密码,否则无法解密备份中的数据。

7. 迁移日志

迁移过程中的日志通过 console.log 输出,可在调试时查看:

[Migration] 检测到旧格式数据,开始迁移...
[Migration] 需要密码解密旧数据,弹出密码弹窗...
[Migration] task: 42 items
[Migration] event: 18 items
...
[Migration] 迁移完成,共导入 256 条记录

若某张表迁移失败,日志会显示警告但不中断整体流程:

[Migration] 跳过表 unknown_table: Error: ...