更新记录

1.0.0(2026-11-10)

首个版本。

  • 按 _id 游标分批导出与快照,避开 skip 深分页超时
  • 定时触发自动快照,按天数与份数双重轮转
  • 字段名与值级双层脱敏(含中文键名)
  • 令牌与集合白名单强制校验,内部集合名不可覆盖
  • 第一版不提供自动恢复,避免高危误操作

平台兼容性

云端兼容性

支付宝云 腾讯云 阿里云
× √ √

uniCloud 云数据库快照与导出工具

零第三方依赖的 uniCloud 云端一体工具:按游标分页导出集合、生成时间点快照、保留策略自动清理、字段与值双层脱敏,附一个开箱即用的管理页。

适合:需要在 uniCloud 控制台之外做日常备份、把某个集合导成 JSON / CSV 交付、上线前留一份可回滚的数据底稿、或者给定时快照配自动轮转的项目。

第一版不提供自动恢复 / 一键回滚。 恢复是高危操作,误操作代价远大于手动导入,所以这一版只负责「安全地取出来」,恢复请人工核对后再导入。

特性

  • 游标式分页:每批默认 100 条,单次云函数最多推进 20 批,大集合不会因为超时或内存被截断;未跑完返回 nextCursor,调用方继续即可
  • 时间点快照:快照元数据与数据行分两个集合存放,记录源集合、筛选条件、条数、字段摘要、脱敏标记、生成与完成时间
  • 保留策略:按天数和最大份数双重轮转,定时触发时自动清理,不会无限吃掉服务空间
  • 双层脱敏:字段名匹配(password / token / 身份证 / 手机号 / 邮箱等)之外,还有手机号、身份证号、JWT 的值级兜底;导出与快照都生效,可显式关闭并自行承担后果
  • 强制鉴权与白名单:SNAPSHOT_TOKEN 未配置时拒绝一切读写;SNAPSHOT_COLLECTIONS 白名单之外的集合一律拒绝;令牌和集合名只能从环境变量读取,请求侧改不了
  • 数据不出空间:所有快照只写在使用者自己的 uniCloud 服务空间,不向任何第三方服务器发送
  • 零依赖:只用 uniCloud.database(),不引 npm 包、扩展库或云存储 SDK
  • 自带管理页:创建快照、查看列表、下载 JSON / CSV、删除,全部点选完成

目录结构

uni_modules/aliang-db-snapshot/
├── package.json                       插件配置(含价格与加密清单,只列 1 个 js)
├── pages_init.json                    自动注册管理页
├── readme.md / changelog.md
├── uniCloud/
│   ├── cloudfunctions/aliang-db-snapshot/
│   │   ├── index.js                   单文件云函数(配置/脱敏/CSV/存储/动作/入口 六个分区)
│   │   └── package.json
│   └── database/
│       ├── cloud_snapshot_meta.schema.json    快照批次元数据
│       └── cloud_snapshot_data.schema.json    快照数据行
└── pages/snapshot/list.vue            管理页

插件内 uniCloud 不带 -aliyun / -tcb 后缀,导入工程后 HBuilderX 会虚拟合并到项目根目录的 uniCloud 中。

云函数刻意做成单文件:付费普通授权版的加密清单按文件配置,多文件结构一旦漏配某个 lib,那个文件会明文留在项目里且不会有任何报错。单文件让加密清单只有一项,不可能漏。

五分钟接入

第 0 步(必须先做):在 uniCloud 服务空间的环境变量里配置:

SNAPSHOT_TOKEN = 一个足够长的随机字符串
SNAPSHOT_COLLECTIONS = orders,users,goods

未配置 SNAPSHOT_TOKEN 时,除了 ping 以外所有 action 都会返回 token-required;未配置白名单时拒绝导出任何集合。这是默认安全,不是故障。

  1. 从插件市场导入本插件到 uni-app 项目。
  2. 上传 uniCloud/database/ 下两个 .schema.json 到服务空间,生成 cloud_snapshot_meta 与 cloud_snapshot_data 集合。
  3. 右键 uniCloud/cloudfunctions/aliang-db-snapshot → 上传部署。
  4. pages_init.json 会自动提示把「数据快照与导出」页注册进 pages.json,确认即可。
  5. 打开管理页,填入第 0 步的令牌和集合名,点「检查」看配置,再点「创建快照」。

环境变量

变量 默认 说明
SNAPSHOT_TOKEN 空(必填) 所有 action 的令牌,只从环境变量读
SNAPSHOT_COLLECTIONS 空(必填) 允许导出的集合白名单,逗号分隔;* 表示允许全部非保留集合
SNAPSHOT_CRON_COLLECTIONS 空(必填才会生效) 定时触发时要快照的集合,逗号分隔。不配则 cron 什么都不做,不会继承 SNAPSHOT_COLLECTIONS
SNAPSHOT_META_COLLECTION cloud_snapshot_meta 元数据集合名,只从环境变量读
SNAPSHOT_DATA_COLLECTION cloud_snapshot_data 数据行集合名,只从环境变量读
SNAPSHOT_PAGE_SIZE 100 每批条数,1~500
SNAPSHOT_MAX_BATCHES 20 单次调用最多推进多少批,防止云函数超时
SNAPSHOT_RETENTION_DAYS 7 快照保留天数
SNAPSHOT_MAX_SNAPSHOTS 10 最多保留多少份
SNAPSHOT_MAX_STRING / MAX_ARRAY / MAX_DEPTH 4000 / 50 / 5 截断与递归限制

pageSize / maxBatches / retentionDays / maxSnapshots 及三个截断参数可用单次请求的 data.config 覆盖;令牌、白名单、两个集合名不接受请求侧覆盖,否则调用方能把读写指向任意业务集合。

API 参考

云函数名:aliang-db-snapshot。统一返回 { errCode: 0 | 字符串, errMsg, data },失败错误码以 aliang-db-snapshot- 开头。

action 说明 主要参数 需要 token
ping 健康检查,返回配置状态(不含数据) — 否
export 按游标直接导出线上集合 collection cursor limit where format fields redact 是
create 创建快照 / 按游标续跑 首次 collection where redact;续跑 snapshotId 是
list 快照列表 page pageSize 是
detail 快照元数据 snapshotId 是
download 按游标读回快照内容 snapshotId cursor format fields 是
delete 删除批次及其全部数据行 snapshotId 是
cron 按配置批量创建快照并清理过期 — 是

导出示例:

let cursor = 0
const rows = []
while (true) {
  const res = await uniCloud.callFunction({
    name: 'aliang-db-snapshot',
    data: {
      action: 'export', token: '你的令牌',
      collection: 'orders', format: 'json',
      where: { status: 'paid' }, cursor
    }
  })
  const d = res.result.data
  rows.push(...d.rows)
  if (d.done) break
  cursor = d.nextCursor
}
console.log(rows.length)

format: 'csv' 时返回 csv 片段:第一批带表头,后续批次不带,按顺序用 \r\n 拼接即可。

CSV 的列以第一批取到的字段为准,后续批次新增的字段会补在行尾但表头已经发出去了。同一集合里字段结构不一致时,建议用 JSON 导出。

创建快照:create 单次最多推进 maxBatches 批,返回 done: false 时带上返回的 snapshotId 再调一次即可续跑,直到 done: true。管理页已经自动做了这个循环。

错误码:

errCode 含义
...-token-required 服务空间没配 SNAPSHOT_TOKEN
...-unauthorized 令牌不对
...-no-collection-allowed / ...-collection-not-allowed 白名单未配置或集合不在白名单
...-forbidden-collection 试图导出插件自身的快照集合
...-not-found / ...-not-ready 快照不存在 / 尚未完成
...-invalid-param / ...-invalid-action 参数或 action 不合法
...-collection-missing 两个 Schema 没上传
...-internal 其他异常

定时快照

在 uniCloud 控制台给 aliang-db-snapshot 云函数加一个定时触发(cron 表达式即可,比如每天凌晨 2 点 0 0 2 * * *),触发器里不需要也不能填参数。

云函数通过 event.Type === 'Timer' 识别定时触发,自动执行 cron:给 SNAPSHOT_CRON_COLLECTIONS 里的每个集合各创建一份快照(单次各推进 maxBatches 批,集合很大时下一次触发接着跑),完成后按 SNAPSHOT_RETENTION_DAYS 和 SNAPSHOT_MAX_SNAPSHOTS 清理旧快照。

必须先在环境变量里配 SNAPSHOT_CRON_COLLECTIONS(逗号分隔)。不配的话 cron 什么都不做——这是刻意的:如果默认继承 SNAPSHOT_COLLECTIONS,你白名单里配了多少集合,定时任务就会全量快照多少,几天就把服务空间塞满。

为什么不是「触发参数里带 token」:uniCloud 的定时触发器 config 字段只接受 cron 表达式,触发时云函数收到的 event 只有 Time / TriggerName / Type 三个系统字段,传不了自定义参数。早期版本照着这个思路设计,结果定时快照一次都没跑起来,还不报错。

现在的做法是靠 Type 识别、cron 免令牌。为了让这个判断不被滥用,cron 只做「建快照 + 清理过期」两件事,都不向外传数据;即使有人伪造 Type 触发,最多多生成几份会被轮转清掉的快照。真正能导出数据的 export / download 仍然必须带令牌。

安全与隐私

  • 令牌、集合白名单、两个内部集合名只从环境变量读取,请求侧无法覆盖。
  • where 只接受基础类型的等值条件,拒绝 $ 操作符和嵌套对象,避免把数据库命令从外部注入。
  • 两个快照集合的 permission 全部为 false,前端无法直连,只能走云函数。
  • 默认脱敏字段名(子串匹配):password / passwd / pwd / secret / token / authorization / cookie / session / apikey / privatekey / credential / idcard / identity / phone / mobile / email / bankcard / cardno / cvv / signature,以及中文键名 手机号 / 身份证 / 姓名 / 住址 / 地址 / 病历号 / 住院号;值级再兜一层手机号、身份证号、JWT。redact: false 可关闭,请自行承担合规责任。
  • 数据全部写在你自己的服务空间,插件不向第三方服务器发送任何内容。
  • 脱敏是兜底,不是合规豁免:涉及个人信息的集合,请先自行评估是否可以导出。
  • 管理页只应放在后台,不要把令牌和页面入口暴露给终端用户。

容量与限制

  • 快照数据写回同一个服务空间的数据库集合,会占用空间。默认保留 7 天 / 10 份,可按实际调整。
  • 单次 export / download 一批最多 500 条;单次 create 最多推进 100 批。大集合靠游标循环,不要试图一次拉全量。
  • 建议给 cloud_snapshot_data.snapshot_id、cloud_snapshot_meta.create_time 建索引(uniCloud 控制台手动创建)。
  • 插件自身两个集合不允许被导出,避免递归快照。

常见问题

Q:报 token-required / unauthorized。 A:服务空间没配 SNAPSHOT_TOKEN,或管理页里填的与环境变量不一致。可用 action: 'ping' 确认配置状态。

Q:报 collection-not-allowed。 A:SNAPSHOT_COLLECTIONS 白名单里没有这个集合名,注意大小写和逗号分隔。

Q:报 collection-missing。 A:两个 DB Schema 没上传。上传后重新部署云函数。

Q:Schema 会帮我校验写入的字段类型吗? A:不会。uniCloud 的 DB Schema 只在 JQL 下生效,本插件用的是云函数原生数据库接口,permission、required、bsonType 这些对云函数写入都不起作用。上传这两个 Schema 只是为了创建集合并让控制台有字段说明。字段规范由云函数自己保证——比如 create_time 存的是毫秒时间戳数字,不是日期类型。

Q:快照一直是 running。 A:正常,说明集合还没跑完。再调一次 create 并带上 snapshotId 续跑,管理页会自动循环。

Q:怎么恢复数据? A:第一版不提供自动恢复。请用「下载 JSON」拿到数据,人工核对后再用 uniCloud 控制台或自己的脚本导入。

Q:支持 uni-app x / 小程序吗? A:云函数与 API 是纯 JS,各端可用;自带管理页是 vue 页面,仅用于 uni-app 项目。H5 下点下载会直接生成文件,App / 小程序端会把内容复制到剪贴板,自行粘贴保存。

版本要求

  • HBuilderX 3.6.0+,uniCloud 阿里云 / 腾讯云服务空间
  • JavaScript 普通云函数(CommonJS),不需要任何扩展库
  • 付费普通授权版按服务空间 spaceId 绑定,提供 7 天试用

授权

购买后按 DCloud 插件市场的标准授权条款使用,可用于自己的任意商业项目,项目数量不限。普通授权版不含源码,请勿反编译或二次分发。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件把使用者指定集合的数据快照与导出结果,写入同一个 uniCloud 服务空间下的 cloud_snapshot_meta 与 cloud_snapshot_data 两个集合,字段包含源集合名、筛选条件、状态、条数、字段摘要、行数据。不向任何第三方服务器发送数据,不内置统计或上报 SDK。默认对字段名与值做双层脱敏(password/token/身份证/手机号/邮箱/JWT 等),且必须通过 SNAPSHOT_COLLECTIONS 白名单与 SNAPSHOT_TOKEN 才能读写。第一版不提供自动恢复。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。