diff --git a/docs/plans/2026-09-29-服务端历史缩略图与空态引导-设计方案.md b/docs/plans/2026-09-29-服务端历史缩略图与空态引导-设计方案.md new file mode 100644 index 0000000..05c21f7 --- /dev/null +++ b/docs/plans/2026-09-29-服务端历史缩略图与空态引导-设计方案.md @@ -0,0 +1,70 @@ +# 服务端历史缩略图 + 上传中心空态引导 + +日期:2026-09-29 | 状态:设计已确认(用户 2026-09-29 选方案 A + 追加空态引导) + +## 背景 + +App 卸载重装后本地上传记录(drift SQLite,app 私有目录)被系统清空,用户只能看 +「服务端历史」(GET /uploads)。当前两个体验缺口: + +1. **服务端历史不显示图片**:契约 `UploadSessionPhoto` 只有 photoId/ + processingState/visibility,无图片 URL;App 行首只能放中性占位图标 + (server_history_page.dart「契约无图片 URL——中性占位」)。 +2. **上传中心空态无引导**:本机 0 条记录时只有「队列空」文案,用户不知道右上角 + History 有跨设备记录。 + +## 改动一:服务端历史缩略图(契约 → 服务端 → App 三层) + +### 契约(packages/contracts/openapi.yaml) + +`UploadSessionPhoto` 增加可选字段 `preview: PhotoPreview`(复用既有 schema: +thumb/browse 两个 `SignedUrl`,均为 required)。新字段 optional,旧客户端零 break +(既有红线)。`PhotoPreview.description` 补充「亦用于上传会话历史」。 + +### 服务端(services/api uploads.service.list,仅 cn 模块) + +- 照片二次查询后增加 `photo_variants` 批量查询(photoId in 页内 id 集), + 组装 photoId → {thumb?, browse?} objectKey 映射。 +- 签发条件(uploader 视角,与管理端 previewOf 的差异登记): + - thumb 与 browse 变体齐备(处理未完成/失败 → 无变体 → 不签,App 回退占位); + - `visibility ∉ {hidden, deleted}` 不签(对齐「隐藏是运营动作」哲学;比管理端 + manager 可签更严格——避免按相册批量鉴权扇出,owner/admin 的隐藏图在历史里 + 也回退占位,可接受)。 +- 签发方式复用 photos.service 模式:`storage.presignGet(key, ttl)`(本地 HMAC + 无网络开销),TTL 同全局 signedUrlTtlSeconds(900s),过期经列表重取刷新。 + +### App(apps/mobile) + +- `UploadSessionPhoto` 模型增加 `preview`(复用 features/photos 的 PhotoPreview), + 可空。 +- server_history_page 行首 48×48 槽位:有 thumb URL → `PhotoThumbnail`(aspectRatio + 1,同隐藏照片弹层模式);无 → 现有云朵图标占位。 +- 不新增网络请求(URL 随列表下发,PhotoThumbnail 自带缓存)。 + +## 改动二:上传中心空态引导(仅 App) + +- 队列 Tab 列表空态(非「需关注」视图):`EmptyState`(现成组件,零改动)加 + subtitle「上传记录仅保存在本机,卸载重装后不可见」+ tonal 按钮「查看服务端历史」 + → `Navigator.pushNamed('/server-history')`(与右上 History 同路由)。 +- 「需关注」视图空态保持专属文案,不加引导(该空态≠本机无记录)。 +- l10n 新增 2 个 key(zh/en):空态说明 + 按钮文案。 + +## 测试 + +- 服务端 e2e(uploads spec):处理后照片(有变体)的 listUploads 条目含 + preview.thumb URL;未处理照片条目无 preview 字段。 +- App:UploadSessionPhoto 模型解析 preview;历史行有 preview → 渲染 PhotoThumbnail、 + 无 → 占位图标;队列空态显示引导文案与按钮、点击跳 /server-history。 + +## 影响面与部署 + +- 契约 + cn 服务端 + App;ov 不动(uploads 模块仅 cn)。 +- 部署顺序:本地全绿 → 契约/服务端提交 → 测试服 cn 栈滚动 + web restart → + App debug APK 重打(连测试服)。正式服与 release APK 待用户验证后。 +- 兼容性:新字段 optional——旧 App 对新服务端零影响;新 App 对旧服务端 + (preview 缺失)回退占位图标,双向安全。 + +## 不改动 + +- 上传中心主列表仍为本机数据(不合并服务端历史——改动量大,另议)。 +- 服务端历史的其它字段(filename/设备名契约本就没有)。