应用截图展示 是做什么的?
真实截图是事实的源头。切勿捏造、重绘、润色或“改进”应用UI。切勿更改截图内的文本。
两种设备类型。 报告、审查和解决是市民移动应用截图
(device: "mobile",在 PhoneFrame 中渲染,竖屏)。分配和响应发生在
运营中心的 网页视图 中,而非移动应用(device: "web",在
BrowserFrame 中渲染,横屏)—— 参见 sos-content-accuracy 中的“已验证产品事实”。
在接收时就要搞清楚:将网页仪表板截图强行放入手机框架会歪曲产品。
文件存放位置
| 内容 | 放置位置(用户) | 输出(生成) |
|---|---|---|
| 应用截图(PNG/JPG,全分辨率) | assets/screenshots-raw/ | public/screenshots/<id>.webp(+ .avif) |
| 标志、应用图标、品牌标记 | assets/brand-raw/ | public/brand/ |
| Open Graph 图像(1200×630) | assets/brand-raw/og-image.png | public/brand/og-image.jpg |
assets/ 不会被部署。只有 public/ 中的优化文件才会发布。
命名约定
<序号>-<屏幕用途>.png,小写短横线命名法,例如
01-home.png、02-category-select.png、03-report-form.png、04-report-submitted.png、06-welcome.png、07-register.png、08-verify.png、09-login.png。
如果用户的文件是随意命名的,请检查每个文件并根据用途重命名。
当前清单 ID 及其应包含的内容:
| ID(文件名基础) | 设备 | 屏幕 |
|---|---|---|
hero-primary | mobile | 首页屏幕 |
hero-secondary | mobile | 类别选择屏幕 |
how-report | mobile | 报告表单(捕获/提交事件) |
how-review | mobile | 提交后的确认屏幕 |
how-assign | web | 运营中心网页视图 — 报告正在分配 |
how-respond | web | 运营中心网页视图 — 响应者路线指引/位置 |
how-resolve | mobile | 显示已解决报告的状态屏幕 |
register-welcome | mobile | 欢迎/首次打开屏幕 |
register-form | mobile | 注册详细信息屏幕 |
register-verify | mobile | 验证屏幕(如果应用没有则省略) |
register-home | mobile | 登录屏幕 |
移动截图:竖屏,直接从手机获取,未经裁剪。网页截图
(how-assign、how-respond):运营中心视图的横屏浏览器捕获,未经裁剪。
接收工作流程(每批新文件)
- 检查 每个图像(打开它)。确定用途:欢迎、注册、验证、登录、首页、类别选择器、报告表单、相机/捕获、确认、状态/跟踪、通知、响应者视图、地图/路线、其他。
- 隐私审查 — 查找真实姓名、电话号码、电子邮件、地址、面孔、车牌号、精确的家庭位置、身份证件、令牌。如果发现:停止并请求用户提供清理后的版本。除非用户明确要求,否则不要自行模糊/编辑,且仅模糊,绝不改变UI。
- 记录尺寸 和宽高比。绝不裁剪掉UI或拉伸。状态栏可以保持原样。
- 优化:
npm run optimize:screenshots(Sharp):输出 WebP 质量≈82 和 AVIF 质量≈60,最大宽度 1080px,保持原始宽高比,剥离元数据(EXIF/GPS)。保持文本清晰可读 — 放大检查压缩后的小UI文本。 - 注册 在
src/config/screenshots.ts中(请参见下面的模式)。 - 放置 使用映射表;如果不明确,向用户提出一个简短列表中的放置建议。
- 验证 布局在 320/768/1440 下,无 CLS,存在替代文本,仅英雄图像使用
priority。 - 更新
docs/assets-guide.md接收日志。
清单模式
// src/config/screenshots.ts
export type ScreenPurpose =
| "welcome" | "register" | "verify" | "login" | "home"
| "category" | "report-form" | "capture" | "submitted"
| "status" | "notifications" | "responder" | "map" | "other";
export type Slot =
| "hero-primary" | "hero-secondary"
| "how-report" | "how-review" | "how-assign" | "how-respond" | "how-resolve"
| "showcase" | "register-welcome" | "register-form" | "register-verify" | "register-home"
| "tracking";
export type Device = "mobile" | "web"; // mobile → PhoneFrame, web → BrowserFrame
export interface Screenshot {
id: string; // "03-report-form"
src: string | null; // "/screenshots/03-report-form.webp"; null = 占位符
width: number; height: number; // 优化文件的内在像素
alt: string; // 描述屏幕显示的内容,基于事实
purpose: ScreenPurpose;
slots: Slot[];
device: Device;
caption?: string;
privacyChecked: boolean; // 在生产环境中 src 非 null 前必须为 true
}
export const screenshots: Screenshot[] = [ /* ... */ ];
export const bySlot = (slot: Slot) => screenshots.filter(s => s.slots.includes(slot));
- 默认占位符比例:
device: "mobile"为 1179×2556(≈ 9:19.5);device: "web"为 1600×1000 (≈ 16:10)—— 直到获知实际尺寸。 - 如果截图的
src非 null 但privacyChecked: false,构建应发出警告(在开发控制台中)。
放置映射
| 屏幕用途 | 插槽 | 设备 |
|---|---|---|
| home | hero-primary, register-home, showcase | mobile |
| category | hero-secondary, how-report, showcase | mobile |
| report-form / capture | how-report, showcase | mobile |
| submitted | how-review, showcase | mobile |
| status | tracking, how-resolve, showcase | mobile |
| notifications (assign) | how-assign | web |
| map/route (respond) | how-respond | web |
| welcome | register-welcome | mobile |
| register | register-form | mobile |
| verify | register-verify(如果没有此屏幕则完全省略步骤) | mobile |
| login | register-home | mobile |
showcase 仅包含移动应用截图(报告、审查、解决)—— 它是市民应用展示区,而不是运营中心网页视图的展示位置。
替代文本规则
描述可见内容,而非营销宣传。好:“类别选择屏幕,列出救援、警察、消防和其他报告类型。”坏:“快速、简单的报告!”装饰性重复内容(例如反射)使用 alt=""。
PhoneFrame / BrowserFrame / DeviceFrame 组件
PhoneFrame:纯 CSS 框架,圆角矩形(ink-raised),1px 内部高光,细屏幕内边距,可选的灵动岛药丸形状。没有 PNG 设备模型。BrowserFrame:纯 CSS 浏览器窗口框架(相同的表面语言),三个纯色 Chrome 圆点,没有虚假的 URL 栏或伪造的浏览器 UI。用于device: "web"屏幕(分配、响应)。DeviceFrame:根据screenshot.device选择PhoneFrame和BrowserFrame—— 在通用渲染阶段/插槽的调用点使用(例如工作原理),而不是硬编码一种框架类型。- 子元素:使用清单中的显式
width/height的next/image,设置sizes(例如(min-width:1024px) 320px, 70vw),loading="lazy",但英雄主图像除外(priority、fetchPriority="high")。 - 占位符模式(
src === null):中性渐变屏幕,小标签“截图插槽: — 等待真实应用屏幕”,正确的宽高比。没有虚假的 UI 元素,没有虚假的按钮或文本。 - 屏幕内容必须保持直立且可读:最大 rotateY 18°,切勿镜像。
- 移动端(< 1024px):无 3D 旋转;平面手机,原生水平滚动吸附画廊(
snap-x snap-mandatory、scroll-padding),可见滚动提示,键盘可聚焦区域,带aria-label。
每批检查清单
- 每个图像已检查且用途已确定
- 没有可见的个人数据(或者用户已确认是虚拟数据)
- 优化文件每个 < ~180KB,文本仍然可读
- 清单条目完整:尺寸、替代文本、用途、插槽、设备、privacyChecked
- 页面上只有一个
priority图像 - 无布局偏移;宽高比保持不变
- 未使用的占位符插槽仍然诚实地显示标签
- 集成后重新运行 Lighthouse 移动端测试