图片恢复支持对象存储(R2);专题也改成归人不归数据集

R2 上的图怎么救:库里的行没了就只剩桶里有那些键,不列桶无从得知它们叫什么。
给 internal/media 加了 ListObjects(ListObjectsV2 + SigV4 + 自动翻页 + XML 解析):
- 路径式访问、请求只到桶;查询串必须**先百分号编码再签名**(canonicalQuery 按原样取
  RawQuery,两边得是同一份字节,prefix 里的 / 要写成 %2F)。
- ⚠️ R2 的 API Token 默认只给对象读写,没有 s3:ListBucket 就 403。列桶失败**不让整个
  恢复失败**:本地那半照救,原因进 Warnings、页面用红色提示条显示(否则站长会以为恢复完了)。
- 候选对象 = 本地目录 ∪ 桶里 .webp(同键以本地为准);行的 storage 按「对象实际在哪」写,
  bytes 用桶里报的 Size。另加一条 warning:挂回了却没配 s3_public_base ⇒ 行有了页面空白,
  这比「没恢复」更难懂。

专题(用户拍板「一并做」):topics.dataset_id 同样带 CASCADE,删数据集带走专题,而专题
只存在这张表里、没有恢复来源。外键摘掉,所有查询 dataset_id → user_id(loadTopics、
topicPage、保存/删除/开关、pageBase.HasTopics);**内容仍照当前生效数据集算**
(topicContent 不动)——变的是「这份定义归谁」。Dataset 补 UserID 供前台按属主定位
用户级数据;管理专题不再要求有生效数据集。

导出链路未改动:place_images / topics / Dataset.UserID 都不参与 .rondbackup 导出,
全量验收(含导出保真、ZRAW 夹取、编号对齐那批)PASS=331 FAIL=0 SKIP=0。
This commit is contained in:
tamakyi
2026-09-30 23:31:17 +08:00
parent 496c992e5e
commit 770e752a7a
13 changed files with 622 additions and 60 deletions
+9 -4
View File
@@ -161,11 +161,16 @@ go build -o rond .
- ⚠️ **早期版本图片记录挂在数据集上**(`place_images.dataset_id` 带 `ON DELETE CASCADE`),
于是「删掉旧数据集」会把图片记录一起删掉,**而文件还留在磁盘上**——读取按坐标键、行却按数据集级联,
两套口径打架,实测丢过一批图。现在外键已摘掉,删数据集不再带走图片;已经丢掉的那批可以恢复:
后台首页「图片挂载恢复 → 扫描并恢复」,它按坐标把盘上还在的文件挂回当前数据集的地点上
(只插记录、不动文件、可反复执行)。认地点要用旧数据集留下的底座库(`<data_dir>/baselines/<id>.sqlite`)
来还原「地点号 → 坐标」,**所以别删那个文件**;底座也没了就认不出来了,报告里会列出来。
后台首页「图片挂载恢复 → 扫描并恢复」,它按坐标把还在的对象挂回当前数据集的地点上
(只插记录、不动对象、可反复执行)。**本地磁盘与对象存储都扫**:
本地走目录遍历,对象存储走 ListObjectsV2 列桶——行没了就只剩桶里有那些键,不列桶无从得知它们叫什么。
⚠️ 列桶需要凭据上有 **`s3:ListBucket`** 权限(R2 的 API Token 默认只给对象读写),
没权限时本地那半照救,页面会把该开哪个权限说明白。
认地点要用旧数据集留下的底座库(`<data_dir>/baselines/<id>.sqlite`)来还原「地点号 → 坐标」,
**所以别删那个文件**;底座也没了就认不出来了,报告里会列出来。
- **删除数据集**只清掉从备份导来的记录与原始行留档;备注、结论、图片按坐标键保留。
专题(`topics`)目前仍旧随数据集删除——同一个数据集删掉后要重建。
- **专题归人不归数据集**:专题是「一段时间 + 一块区域」的定义,换数据集之后照旧成立
(内容照当前生效数据集算),删掉旧数据集不会再把它带走。
## 照片导入(补录没有轨迹的时间段)