docs: UI-01 acceptance record and visual verification
Co-Authored-By: Claude Code <noreply@anthropic.com>
@@ -1,65 +1,152 @@
|
||||
# UI-01 App 与悬浮组件体验优化 验收记录
|
||||
|
||||
基线 commit:6754cd4 · 日期:2026-09-21 · 执行环境:Windows + Docker Desktop + MuMu 模拟器(Android 15)
|
||||
基线 commit:6754cd4 · 完成 commit:本提交(tag `ui01`)· 日期:2026-09-21 · 执行环境:Windows 11 + Docker Desktop(mysql/redis×2 + minio)+ MuMu 模拟器(Android 15,540×960@240dpi ≈ 360dp 逻辑宽)+ Playwright Chromium(1440×900 / 390×844)
|
||||
|
||||
## 基线截图索引
|
||||
## 1. 基线与完成 commit
|
||||
|
||||
| 编号 | 页面 | 文件 | 备注 |
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 基线 | 6754cd4(UI-01 实施计划提交后、U00 执行前) |
|
||||
| 完成 | Task 8 文档提交(含本记录 + after 截图),tag `ui01` |
|
||||
| 工作树 | 基线时清洁;验收提交仅含本记录、总纲注记与 after 截图目录 |
|
||||
|
||||
任务提交链:3b5f8d2 → 8f4ad11 → c94b9e5 → f6929ae → 1f67b7c → ddf26a1 → ac23a4c → 本提交,共 8 个。
|
||||
|
||||
## 2. 任务完成表(U00–U09)
|
||||
|
||||
| 任务 | 状态 | commit | 备注 |
|
||||
|---|---|---|---|
|
||||
| 01 | 登录页 | ui01-screenshots/baseline/01-login.png | Flutter App |
|
||||
| 02 | 相册列表 | ui01-screenshots/baseline/02-albums.png | 当前卡片无封面图 |
|
||||
| 03 | 相册详情(上半) | ui01-screenshots/baseline/03-album-detail.png | 字段堆叠布局 |
|
||||
| 04 | 相册详情(滚动后) | ui01-screenshots/baseline/04-album-detail-scrolled.png | 按钮均等强调 |
|
||||
| 05 | 上传队列 | ui01-screenshots/baseline/05-queue.png | 状态筛选/进度/操作 |
|
||||
| 06 | 设置 | ui01-screenshots/baseline/06-settings.png | 分组/语言/密码 |
|
||||
| 07-09 | 嵌入组件/后台 | (待采集) | Playwright 环境冲突,实施过程中补 |
|
||||
| Task 1: U00 基线 | ✅ | 3b5f8d2 | 6 张 App 基线截图;嵌入组件/后台基线因当时 Playwright 环境冲突未采集(见偏差 2) |
|
||||
| Task 2: U01 契约与数据 | ✅ | 8f4ad11 | cover/preview/scope=own/embed 新配置字段 + 权限矩阵 e2e(services/api/test/ui01-contracts.e2e-spec.ts) |
|
||||
| Task 3: U02 主题与导航 | ✅ | c94b9e5 | tokens + ColorScheme 浅/深 + 公共组件 + 三 tab 导航 + 角标 |
|
||||
| Task 4: U03 相册与照片 | ✅ | f6929ae | 封面卡片列表 / 紧凑详情 / 三列网格 / 大图查看器 / 权限操作 / URL 刷新 |
|
||||
| Task 5: U04+U05 上传与辅助页 | ✅ | 1f67b7c | 上传中心摘要+筛选+状态映射 / 深色取景 / 分组表单 / 分享分层 / 设置分组 |
|
||||
| Task 6: U06 嵌入组件 | ✅ | ddf26a1 | loader 新配置+收起重设计+destroy;轮播页组件拆分+预加载+暂停恢复+可访问性;跨源宿主测试 |
|
||||
| Task 7: U07 后台配置与预览 | ✅ | ac23a4c | 新字段表单 + 桌面/手机双预览(本地数据)+ 嵌入代码卡仅显式覆盖 |
|
||||
| Task 8: U08+U09 验收交接 | ✅ | 本提交 | 全量回归 + 13 张 after 截图 + 本记录 + 总纲注记 + tag `ui01` |
|
||||
|
||||
## 已有未提交改动
|
||||
|
||||
Git 工作树清洁(HEAD=6754cd4)。
|
||||
|
||||
## 外部关口
|
||||
|
||||
- G2 真机(未执行,不阻塞 UI-01)
|
||||
- G4/D08 用户接口(未到位,不阻塞 UI-01)
|
||||
- P5 真实部署(测试服务器已部署 219.157.255.213,UI-01 全部本地开发验证)
|
||||
|
||||
---
|
||||
|
||||
## 任务完成表
|
||||
|
||||
| 任务 | 状态 | 完成时间 | 备注 |
|
||||
|---|---|---|---|
|
||||
| Task 1: U00 基线 | ✅ | 2026-09-21 | 6 张 App 截图 |
|
||||
| Task 2: U01 契约 | 待执行 | | |
|
||||
| Task 3: U02 主题 | 待执行 | | |
|
||||
| Task 4: U03 相册照片 | 待执行 | | |
|
||||
| Task 5: U04+U05 上传辅助 | 待执行 | | |
|
||||
| Task 6: U06 嵌入组件 | 待执行 | | |
|
||||
| Task 7: U07 后台预览 | 待执行 | | |
|
||||
| Task 8: U08+U09 验收 | 待执行 | | |
|
||||
|
||||
## 验收矩阵
|
||||
## 3. 验收矩阵(方案 §9.1)
|
||||
|
||||
| 编号 | 状态 | 证据 |
|
||||
|---|---|---|
|
||||
| UI-A01 | 待验 | |
|
||||
| UI-A02 | 待验 | |
|
||||
| UI-A03 | 待验 | |
|
||||
| UI-A04 | 待验 | |
|
||||
| UI-A05 | 待验 | |
|
||||
| UI-A06 | 待验 | |
|
||||
| UI-A07 | 待验 | |
|
||||
| UI-A08 | 待验 | |
|
||||
| UI-A09 | 待验 | |
|
||||
| UI-A10 | 待验 | |
|
||||
| UI-A11 | 待验 | |
|
||||
| UI-A12 | 待验 | |
|
||||
| UI-A13 | 待验 | |
|
||||
| UI-A14 | 待验 | |
|
||||
| UI-A15 | 待验 | |
|
||||
| UI-A16 | 待验 | |
|
||||
| UI-A01 | ✅ | apps/mobile/test/app/theme_test.dart(11 用例:浅色 §3.1 精确值、深色语义对应、字阶、动效时长/reducedMotion 归零);截图 01–08(设备浅色实拍) |
|
||||
| UI-A02 | ✅ | albums_tab_test(封面有无占位、标题回退、390 单列/900 双列);截图 02(封面卡片:图→标题→时间地点→状态 badge) |
|
||||
| UI-A03 | ✅ | album_photos_page_test(350→2/390→3/800→5 列、大图切换、返回位置、角标);截图 05/06(网格 + contain 大图 1/12) |
|
||||
| UI-A04 | ✅ | services/api/test/ui01-contracts.e2e-spec.ts 权限矩阵(admin/owner/collab-own/collab-other × cover/preview/scope;隐藏照片有权限可见无权限 404;删除照片 preview=null) |
|
||||
| UI-A05 | ✅ | queue_tab_test(摘要计算、状态映射、行级进度订阅);截图 07(摘要条"今天·本设备"+ 状态 chips + 服务端历史分区) |
|
||||
| UI-A06 | ✅ | capture_page 测试(连拍模式、入队反馈不弹窗、拍摄不被上传打断)——Task 5 提交内用例 |
|
||||
| UI-A07 | ⚠️ 部分验证 | 自动化覆盖 350/390/800/900 逻辑宽(widget 测试)+ 设备 ≈360dp 实拍;**320/430 宽度与文字 1.0/1.3/2.0 缩放未系统覆盖**,列入 G2 真机清单 |
|
||||
| UI-A08 | ⚠️ 部分验证 | 窄屏 375(playwright embed.spec "narrow viewport starts collapsed and downgrades to sm size")+ 390/1440 实拍(截图 10/09)+ admin 预览 320px 框(截图 12);**320/768 宿主未逐一实拍** |
|
||||
| UI-A09 | ✅ | EmbedStage 固定 4:3 舞台 + object-fit contain(换图不跳高由舞台固定保证);失败图片保留上一张(viewer vitest);演示 12 张渐变图 contain 实拍(截图 09/11);真实全景/文字海报样本列入 G2 |
|
||||
| UI-A10 | ✅ | embed.spec 6 项暂停恢复(按钮/悬停/键盘焦点/页面隐藏/reducedMotion/收起)+ collapse 持久化;截图 10(390 默认收起)/11(展开) |
|
||||
| UI-A11 | ✅ | embed.spec(rebinding resets the feed、admin settings apply live via config message、ghost slot 404 destroy);304/签名过期刷新 viewer vitest(ETag + 受控刷新有限重试) |
|
||||
| UI-A12 | ✅ | embed-crossorigin.spec.ts(真实双端口跨源宿主 7 用例:渲染、非法 source 消息忽略、ghost destroy、多 slot 纵向 8px 间距、全局 button CSS 干扰、窄屏收起) |
|
||||
| UI-A13 | ✅ | admin e2e embed-slot-config(表单交互窗口零 /v1/ 请求);截图 12(未保存修改即时反映在本地预览,含"未保存"标记) |
|
||||
| UI-A14 | ✅ | embed-loader 单测 27 用例(缺省/显式/config 消息合并+边界+优先级 data-* > config > 后台 > 默认);v1 兼容入口保留(dist/embed/v1/loader.js);截图 13(代码卡仅含显式覆盖) |
|
||||
| UI-A15 | ✅ | P4b 三端语言守护(键集相等 + 错误码枚举全覆盖)延续有效;UI-01 新键入 arb 双语;embed.spec "lang=en renders English copy";运行时长文案无裁切由 footer 布局测试覆盖 |
|
||||
| UI-A16 | ✅ | 本记录 §8 外部关口明确列 G2/G4/P5 为待验证,未宣称生产验收完成 |
|
||||
|
||||
---
|
||||
## 4. API 新字段与权限变化(全部可选/nullable,旧客户端零 break)
|
||||
|
||||
(后续内容在实施过程中填写)
|
||||
| 契约 | 变更 | 服务端 |
|
||||
|---|---|---|
|
||||
| AlbumSummary | `cover: SignedUrl \| null` | albums 列表按页批量查 album_assets(kind=cover, effective)+ 短期签名 URL,无 N+1 |
|
||||
| AdminPhoto | `preview: {thumb: SignedUrl, browse: SignedUrl} \| null` | 管理列表按权限逐张判断(admin 全部/owner 本相册/collab 仅自己);已删除返回 null |
|
||||
| listAlbumPhotos | query `scope: 'all' \| 'own'`(默认 all 行为不变) | own=服务端过滤仅本人上传 + 成员资格逐次检查 |
|
||||
| EmbedSlotSettings | `imageFit: 'contain'\|'cover'`、`offsetX: 0-120`、`offsetBottom: 0-240`、`zIndex: 1-2147483000`(均带默认) | cn 管理 PATCH 校验 → slot-state payload → ov 公开响应投影完整传递(sync 验证) |
|
||||
|
||||
旧客户端兼容:全部字段缺省不 break(ui01-contracts.e2e-spec 含旧请求无新字段用例);ov 侧旧响应消费者不受影响。
|
||||
|
||||
## 5. 截图索引
|
||||
|
||||
基线(2026-09-21 采集,commit 3b5f8d2):`ui01-screenshots/baseline/`
|
||||
|
||||
| 编号 | 页面 | 文件 | 备注 |
|
||||
|---|---|---|---|
|
||||
| 01 | 登录页 | baseline/01-login.png | Flutter App |
|
||||
| 02 | 相册列表 | baseline/02-albums.png | 当前卡片无封面图 |
|
||||
| 03 | 相册详情(上半) | baseline/03-album-detail.png | 字段堆叠布局 |
|
||||
| 04 | 相册详情(滚动后) | baseline/04-album-detail-scrolled.png | 按钮均等强调 |
|
||||
| 05 | 上传队列 | baseline/05-queue.png | 状态筛选/进度/操作 |
|
||||
| 06 | 设置 | baseline/06-settings.png | 分组/语言/密码 |
|
||||
| 07-09 | 嵌入组件/后台 | (未采集) | 当时 Playwright 环境冲突;after 侧本次补齐,基线以 P4b 验收记录组件描述为对照 |
|
||||
|
||||
优化后(2026-09-21 采集,本次提交):`ui01-screenshots/after/`
|
||||
|
||||
| 编号 | 页面 | 文件 | 验证点 |
|
||||
|---|---|---|---|
|
||||
| 01 | 登录页 | after/01-login.png | 主题化登录(logo/品牌/输入/主按钮) |
|
||||
| 02 | 相册列表 | after/02-albums.png | 封面卡片:图→标题→时间地点→状态 badge;无 publicToken 堆叠 |
|
||||
| 03 | 相册详情 | after/03-album-detail.png | 大图封面+信息+公开/允许上传 badge+照片条预览 |
|
||||
| 04 | 详情滚动后 | after/04-album-detail-scrolled.png | 照片区(12 张·3 分类 + 管理入口)/分类 chips/底部"从相册选择 + 拍摄上传"双按钮 |
|
||||
| 05 | 照片网格 | after/05-photo-grid.png | 三列网格 + scope chips(全部/我的)+ 排序/筛选 |
|
||||
| 06 | 大图查看器 | after/06-photo-viewer.png | contain 展示 + 1/12 页码 + 深色舞台 + 操作入口 |
|
||||
| 07 | 上传中心 | after/07-queue.png | 摘要条(今天·本设备)+ 状态 chips + 服务端历史分区 |
|
||||
| 08 | 设置 | after/08-settings.png | 账号/通用/安全/上传帮助/关于分组 + 退出登录 |
|
||||
| 09 | 组件·桌面 1440 | after/09-embed-desktop-1440.png | md 320px 卡片、offsetX16/offsetBottom24、页码 1/12、收起把手、外链 |
|
||||
| 10 | 组件·390 收起 | after/10-embed-mobile-390-collapsed.png | 窄屏默认收起 + sm 尺寸把手(≥44px 高) |
|
||||
| 11 | 组件·390 展开 | after/11-embed-mobile-390-expanded.png | sm 280px 卡片无横向溢出 |
|
||||
| 12 | 后台配置+预览 | after/12-admin-slot-config.png | 新字段全套(位置/尺寸/间隔/语言/收起/适配/偏移/层级)+ 桌面 320/手机 375 双预览 + 未保存标记 |
|
||||
| 13 | 嵌入代码卡 | after/13-admin-embed-code.png | 仅 data-slot 显式覆盖 + 参数说明表 |
|
||||
|
||||
采集环境:01–08 MuMu 强杀冷启 + 本地 dev 栈(cn 8080 / ov 8081 / worker / MinIO 9000 + adb reverse);09–13 vite preview dist + 独立宿主页(http.server 8090)+ 真实跨源 loader 接入,数据为 demo-seed 12 张渐变图 + 上传封面资产。
|
||||
|
||||
## 6. 测试命令与真实结果
|
||||
|
||||
命令序列:清场(杀残留 dev 进程)→ `pnpm lint` → `pnpm typecheck` → `pnpm test` → `pnpm build` → `pnpm e2e` → `source scripts/flutter-env.sh && cd apps/mobile && flutter analyze && flutter test` → `pnpm --filter @photo/embed-loader build` + sync 校验。
|
||||
|
||||
| 门 | 结果 |
|
||||
|---|---|
|
||||
| pnpm lint | 10/10 任务通过 |
|
||||
| pnpm typecheck | 13/13 任务通过 |
|
||||
| pnpm test(单元) | 12/12 任务、**359 用例全绿**:embed-loader 27 / contracts 29 / storage 6 / api-cn 51 / worker 14 / viewer 155(20 文件)/ admin 77(14 文件) |
|
||||
| pnpm build | 10/10 任务通过 |
|
||||
| pnpm e2e | **364 全绿**(第二跑;磁盘用例计数 api-cn 255(24 套件,含 ui01-contracts)+ viewer 44(9 specs,含 embed-crossorigin)+ admin 23(7 specs,含 embed-slot-config)+ sync 27 + worker 13 = 362,运行总数含 it.each 展开) |
|
||||
| flutter analyze | No issues found!(0 问题) |
|
||||
| flutter test | **341/341 全绿**(+61 相对 P4b 280) |
|
||||
| loader build+sync | dist/v1/loader.js 与 apps/viewer/public/embed/v1/loader.js 字节一致(cmp 相同) |
|
||||
|
||||
测试统计对比(P4b 基线 → UI-01 后):
|
||||
|
||||
| 维度 | 前(P4b) | 后(UI-01) | Δ |
|
||||
|---|---|---|---|
|
||||
| Web 单元 | 316(embed-loader 11 / viewer 136 / admin 69 / 其余 100) | 359(embed-loader 27 / viewer 155 / admin 77 / 其余 100) | +43 |
|
||||
| Web e2e | 339(api-cn 247/23 套件 / viewer 32/8 / admin 20/6 / sync 27 / worker 13) | 364(api-cn 24 套件 / viewer 9 specs / admin 7 specs / sync 4 / worker 2) | +25 |
|
||||
| Mobile | 280/280 | 341/341 | +61 |
|
||||
| 合计 | 935 | 1064 | +129 |
|
||||
|
||||
性能观察(实测记录,不做百分比推算):
|
||||
|
||||
- loader 体积:dist/v1/loader.js **9462 B 原始 / 3728 B gzip**(P4b 基线未记录 gzip 值,无从对比,不编数字)
|
||||
- 相册列表封面:每页 1 次批量 album_assets 查询 + 按页签发,无 N+1(实现 + e2e 断言)
|
||||
- 组件预加载窗口:仅当前 + 下一张(2 张),decode 成功才切换
|
||||
- 轮播 intervalMs 与取数轮询(30s 基准)解耦,互不牵引
|
||||
- 组件首屏(ov 日志实测):slot-state 1 次 + visits 信标 1 次,之后按帧取图
|
||||
|
||||
## 7. 既有改动保护与外部环境
|
||||
|
||||
- 基线工作树清洁;全程未覆盖任何未提交改动。
|
||||
- 无关未跟踪文件未纳入提交:`.playwright-mcp/`、`docs/designs/`、`docs/plans/2026-09-21-UI02-*.md` 保持原状。
|
||||
- 未触碰用户自有进程(`scripts/serve.mjs` 4173 端口、Playwright MCP/Codex 进程保留);仅清理本仓库残留 dev 服务(e2e 首跑失败的根因,见偏差 3)。
|
||||
- 演示数据写入本地 dev 库(demo-seed + 封面资产),不影响任何远程/云资源。
|
||||
|
||||
## 8. 方案偏差与剩余事项
|
||||
|
||||
偏差:
|
||||
|
||||
1. **cover 契约无 width/height**:方案 Task 2 文稿为 `{url, expiresAt, width, height}`,实现为既有 `SignedUrl` 引用(url/expiresAt)。理由:卡片封面按固定宽高比占位(无图回退中性占位),客户端不需要服务端尺寸;避免契约膨胀。旧客户端零影响。
|
||||
2. **基线嵌入组件/后台截图缺失**:U00 时 Playwright 环境冲突未采集;本次 after 侧补齐(09–13),基线对照沿用 P4b 验收记录的组件行为描述。
|
||||
3. **e2e 首跑 sync 套件 9/27 失败**:根因是上一会话残留 dev:worker/dev:sync 进程消费了 BullMQ 任务与 outbox 事件(processPhoto 命中 'already' 快路径、picked 数被抢),属环境干扰非代码回归;清理后全量第二跑 364 全绿。
|
||||
4. **320/430 逻辑宽、文字 1.3/2.0 缩放、深色模式真机截图**未系统采集(A07/A08 部分验证),随 G2 真机一并执行。
|
||||
|
||||
剩余(交接):
|
||||
|
||||
- **G2 真机关口**(既定强制关口):追加 UI-01 视觉项——深色模式实拍、320/430 宽度、文字缩放 1.0/1.3/2.0、横图/竖图/全景/文字海报真实样本。
|
||||
- **G4/D08 用户接口**、**P5 真实环境接入**(G5/G6)按总纲推进;P4b 移交项(真实域名/CDN 预热/embed 页 frame-ancestors CSP/展示位授权 UI 按需/轮询参数冻结)继续有效。
|
||||
- A22 展示位授权(embed_slot_members 建而未用)维持 P4b 状态,未在 UI-01 范围。
|
||||
|
||||
## 9. 外部关口(不变)
|
||||
|
||||
- G2 真机(未执行,不阻塞 UI-01 本地验收)
|
||||
- G4/D08 用户接口(未到位,不阻塞 UI-01)
|
||||
- P5 真实部署(测试服务器 219.157.255.213 已部署;UI-01 全部为本地开发环境验证)
|
||||
|
||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 96 KiB |