图片恢复支持对象存储(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
+10 -1
View File
@@ -373,10 +373,15 @@ END $$;
-- 专题:把某段时间内、某个区域里的足迹(地点 + 迷雾)打包成一个可对外展示的页面。
-- 区域用「中心点 + 半径」,半径为 0 表示不限区域(时间范围内的地点画到哪算哪)。
--
-- ⚠️ dataset_id **故意不带外键**(早期版本带 ON DELETE CASCADE)。
-- 专题是「一段时间 + 一块区域」的**定义**,不是备份里的数据:换数据集之后它照旧成立
-- (内容照当前生效数据集算),删掉旧数据集不该把它带走。带 CASCADE 时实测丢过一批专题,
-- 而且没有恢复来源(专题只存在这张表里)。dataset_id 退化为「当初在哪份数据上建的」。
CREATE TABLE IF NOT EXISTS topics (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
dataset_id BIGINT NOT NULL REFERENCES datasets(id) ON DELETE CASCADE,
dataset_id BIGINT NOT NULL,
title TEXT NOT NULL,
subtitle TEXT NOT NULL DEFAULT '',
description TEXT NOT NULL DEFAULT '',
@@ -393,6 +398,10 @@ CREATE TABLE IF NOT EXISTS topics (
);
CREATE INDEX IF NOT EXISTS idx_topics_user ON topics(user_id, sort_order, id);
-- 老库摘掉那根外键(新库上面的 CREATE 里就没有)。幂等:约束不在时什么都不做。
-- 摘掉之后删数据集不再带走专题——它们只存在这张表里,删了就没有别的恢复来源了。
ALTER TABLE topics DROP CONSTRAINT IF EXISTS topics_dataset_id_fkey;
-- fog of world 快照里「非已探索层」的原始瓦片文件(Model/~ 与 Model/#)。
-- 站点只用已探索层渲染,但导出必须原样写回这两层,否则重导出的快照会丢掉约 55% 的内容。
-- data 存的是原始(zlib 压缩后的)字节,一个字节都不动。