Files
jiu/design/CONTRACT.md
T
wangjia f6154dd1d9 docs(design): CONTRACT 全量清扫收尾状态(登录/盘点/商品/公开页/Web)
记录:登录+盘点 token 化;商品列表/详情 token 净(富数据待后端);
公开页有意独立设计保持现状;Web 营销站 color.css 已对齐品牌。
应用内注册/购买流归 Phase 6 新建功能,非既有屏重建范围。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSKEiHsvauyxYUW2itzUXX
2026-07-01 20:46:52 +08:00

12 KiB
Raw Permalink Blame History

设计契约 — 岩美酒库 Flutter 还原(Phase 1 起:库存列表)

design-distill 阶段 1 产物。像素以 .superpowers/prototype/ 原型为唯一基准 token 走 codegen 单源(已在 P0 落地);还原由截图 diff 验收,不靠目测。 本文件是执行真相源(与 plan .md 同性质,机器/diff 引用),随逐屏推进增补。

阶段 0 · 归一化产物(已就位)

位置 说明
token 单源 .superpowers/prototype/tokens.css 三主题 [data-theme=a/b/c],已 snapshot 到 client/lib/core/theme/token_source/tokens.css
token codegen client/lib/core/theme/tool/gen_tokens.mjsapp_tokens.g.dart 单源生成,禁手改kTokensA/B/C + appTokensOf(key)
实现层 themes.dartbuildTheme+ context_tokens.dartcontext.tokens AppTokens ThemeExtension 挂三 ThemeData
原型清单 .superpowers/prototype/screens/*.html 桌面 + m-* 移动;viewport 桌面 1280×860 / 移动 390×844
设计铁律 .superpowers/prototype/index.htmlatoms 注册)+ tools/check-ds.mjs 颜色只走 token;组件出自已登记 atoms
验收工具 ~/.claude/skills/design-distill/tools/{shoot-prototype,diff}.mjs prototype shoot 已验证三主题可出图

主题

  • a 经典蓝(浅,diff 基准 · b 琥珀(深) · c 酒窖(暖浅)。结构/密度/字阶三套统一,只换颜色。

块 1 · token 映射表(prototype CSS var → Flutter AppTokens

颜色字段 P0 已 1:1 落地(同名)。下表为 a 主题取值(来源 tokens.cssb/c 见 app_tokens.g.dart):

原型 var a 值 AppTokens 字段 用途
--page #E7EBF1 page 最外层底
--bg #F5F7FA bg 内容区底
--surface #FFFFFF surface 卡片/工具条/表格面
--border / --border-subtle #DCE2EB / #ECEFF4 border / borderSubtle 描边
--text / --heading / --title #232934 / #1B2430 / #1B2430 text / heading / title 正文/小标题/大标题
--muted / --faint #6E7888 / #99A3B3 muted / faint 次要/极弱文字
--primary / --primary-dark / --on-primary #2563AC / #154072 / #FFFFFF primary / primaryDark / onPrimary 主操作
--brand400 / --brand50 / --accent #4F86C6 / #EEF4FB / #8B2331 brand400 / brand50 / accent 品牌/强调
--th-bg / --row-hover / --shadow #F7F9FC / #EEF4FB thBg / rowHover / shadow 表头/悬停/投影
顶栏 --top-* / 侧栏 --side-* / 用户菜单 --menu-user-* topBg…/sideBg…/menuUser* 外壳 chromeP0 已迁移)
状态徽章 .badge.b-在售/预警/缺货 success/warn/danger 系 success+okSoft / warn+warnBg / danger+dangerBg 状态色

⚠️ 缺口(鲁棒还原前需补)

AppTokens 目前仅颜色。原型还驱动:

  • 字阶 --fs-display 28 / h1 21 / h2 17 / title 15 / body 13 / sm 12 / xs 11
  • 圆角 --r-sm 4 / md 6 / lg 10 / xl 14 / pill 999
  • 间距 kpis gap 14、toolbar pad 12/14、head mb 18、searchbox 240/180 等

→ 还原前需把字阶/圆角(必要时间距)补进 token 单源 + codegenP1 第一步,禁页面里写死 px)。


块 2 · 组件清单(原型 atom → Flutter widget

原型 atom Flutter props / 状态 现状
.top(顶栏,品牌+门店+主题+通知+用户) shell/app_shell.dart 顶栏 active 项、主题选择器、通知红点、用户菜单 已有,需对齐新视觉
.side(分组导航 单据/经营/系统 + 用户页脚) shell/app_shell.dart 侧栏/Drawer 分组、active、窄屏 Drawer 已有,需分组化
.kpi / .kpi.alert.clickKPI 卡 + 图标 + 同比) widgets/kpi_card.dart icon/title/value/delta(up/down)/onTap/alert ,需新建
.toolbar + .searchbox + .chip(筛选条) widgets/ 复用 + 列头 chip 搜索/编码/状态 chip/重置 部分有
.table + .fh.filtered(列头漏斗筛选) widgets/data_table_card.dart + FilterableColumnHeader 列头内嵌筛选、可隐藏列、thBg 表头 已有
.badge.b-*(状态徽章 圆点+色) widgets/status_badge.dart 在售/预警/缺货 → ok/warn/danger 已有,校色
.qty.low(低库存染色 qty≤10 data row 单元 qty≤min_stock 染 danger 需补
.pager + .pgsize-btn(分页 + 每页条数) widgets/ 分页 页码/每页 10/20/50/100 需对齐
.ds-fab(设计期返回球) 仅原型,不还原 不实现

块 3 · 页面像素规格 — 库存列表(screens/inventory.html,桌面 1280×860

数值取自原型源码(inventory.html 内联 + atoms.css/tokens.css),非目测。

  • headalign-items:flex-end; gap:14; margin-bottom:18h1 fs-h1(21)/700/title/letter .3px.sub fs-sm(12)/muted.actions 右对齐 gap 10列设置(ghost) 导出(ghost) 新增入库(primary)。
  • kpisgrid 4×1fr gap:14 margin-bottom:20。每卡:左 .ic(圆角 r-xl 色块 info/ok/blue/alert+ .t(fs-sm muted) + .v(大数值) + .d(同比 up=success▲ / down=danger▼)。第 4 卡 alert.click → 点击筛状态=缺货;第 1 卡 click → 清筛选。
  • toolbarsurface 面、border 无下边、上圆角 r-lgpad 12/14 gap 10searchbox 240(商品名/拼音);searchbox.code 180(商品编码);chip 状态(.on 高亮 + 选中值);右侧 重置(ghost sm)。
  • tableflush-top 接 toolbar):表头 thBg;列见块 4。行 click 进商品抽屉;qty≤10low(danger)生产日期 等宽 text入库时间 等宽 mutedstatus.badge.b-{在售|预警|缺货}act 列 眼睛图标查看。空态 .empty「没有匹配的商品 · 试试调整筛选或搜索」
  • pager每页 [10▾] 条10/20/50/100 菜单) + 显示 ab,共 N + 页码 1 2 … ,当前页 .cur
  • 移动m-inventory.html390×844):表格 → MobileListCard 卡片流(复用 mobile_list_card.dart);筛选 pill 换行不横滚(原型已修)。

列定义(顺序 = 还原顺序)

商品(name+code 两行,fixed) · 规格 · 系列 · 批次号 · 库存(num,≤10染色) · 成本价(num) · 单价(num) · 生产日期(mono) · 入库时间(mono,muted) · 供应商 · 状态(filter) · 操作(fixed)

真实后端字段对齐:name=品牌 / series=型号 / spec=版本 / code=商品编号 / batch_no / production_date;状态派生 qty vs products.min_stock(在售 / 预警 / 缺货)。快照列回退 COALESCE(p.*, 快照)


块 4 · 逐屏验收清单(每屏 × 主题;diff 闸)

原型 Flutter a(基准) b c
库存列表(桌面) inventory.html inventory_list_screen.dart KPI/徽章/列/副标/toolbar 已还原 golden 自比 golden 自比
库存列表(移动) m-inventory.html 同上窄屏(卡片流) golden 自比 golden 自比 golden 自比
往来单位(桌面) partners.html partners_screen.dart 副标/状态徽章/两行名称/响应式 toolbar golden 自比 golden 自比
往来单位(移动) m-partners.html 同上窄屏(卡片流) golden 自比 golden 自比 golden 自比
入库列表(桌/移) stock-in-list.html stock_in_list_screen.dart 副标 + 共享 StatusPill(草稿/待审/已审/已拒) golden golden
出库列表(桌/移) stock-out-list.html stock_out_list_screen.dart 副标 + 共享 StatusPill golden golden
财务(桌/移) finance.html finance_screen.dart KpiCard + 类型/结清 StatusPill + 离线条 token golden golden
设备管理(桌/移) devices.html device_management_screen.dart 在线/离线 StatusPill golden golden
系统设置·参数 settings.html settings_screen.dart 主题选择器三色板 + 角色 StatusPill golden golden
关于我们(桌/移) about.html about_screen.dart 正文已 token 化(golden 锁定) golden golden

共享组件杠杆StatusBadge(入/出库单据状态)一处升级两屏受益;StatusPill/KpiCard 现已被库存/往来/入出库/财务/设备/设置/关于复用——新屏直接套,无需重做徽章/卡片。

全量清扫收尾(其余屏状态)

状态
登录 离线条 token 化 + 整屏 golden ×3
盘点 斑马行 token 化(表单屏,0 残留,无 golden:静态态不含明细)
商品列表(基础数据) 已 token 净(仅 default 金星 FFB300 为有意 accent);原型 商品档案/香型/介绍 富数据重排待后端
商品详情 主数据/价格/描述区 token 净;原型 3 KPI/仓库分布/流水 待后端聚合
公开商品/门店页 有意独立设计warm-paper/酒红 bespoke 调色板 _kPaper/_kBurgundy…),顾客扫码固定品牌页,不参与 A/B/C 主题——保持现状
Web 营销站 已对齐品牌web/assets/color.css--brand-500:#2563AC / --accent 酒红 / 灰阶 与原型令牌一致,roadmap「Web 镜像品牌」已满足

仍属「新建功能」(Phase 6,非重建既有屏)

应用内注册 / 购买·套餐·下单(设计+前端壳,支付不接)——这是 net-new 功能开发,需各自 spec→设计→实现,不在「既有屏设计语言升级」范围内。

重要发现(原型 vs 现有数据):原型是「理想态富数据重设计」,多数屏的富数据区当前后端不供给,无法一次完整还原:

  • 商品列表8 tab vs 原型 5 tab;香型字典 / 商品介绍 缺后端 → 暂缓。
  • 商品详情:原型 3 KPI(库存/货值/出库)+ 仓库分布 + 流水,getDetail 仅返回商品主数据 → 需聚合接口,暂缓。
  • 往来单位:原型 应收/应付 列,Partner 模型无该字段 → 暂缓;类型 chips 暂保留为两 Tab。

故本阶段策略 = 「设计语言升级」:把每屏视觉升到新 token/组件系(副标 / StatusPill / KpiCard〔数据够时〕/ 两行名称 / 响应式 toolbar / token 间距)+ 接 golden 闸;富数据区(应收应付 / 富 KPI / 仓库分布 / 流水 / tab 重排)等后端聚合就绪再做二期。库存屏因 KPI 可由已加载数据现算,是少数能一次到位的。

验收法(HTML→Flutter 特例)HTML(Chromium) 与 Flutter 渲染器不同,严格 0.1% pixelmatch 不适用跨渲染器(见 design-distill references/flutter-golden.md)。本项目双闸:

  1. 保真闸(人工目检)node tools/ds-compare.mjs --html .superpowers/prototype/screens/<screen>.html --prefix <prefix> → 截原型基准 + 与 Flutter golden 用 montage 并排 → design/_compare/
  2. 回归闸(自动)test/golden/<screen>_golden_test.dartpumpGolden/goldenAcrossThemestest/support/golden_harness.dart)出 A/B/C 三主题 golden,入库随 flutter test 同渲染器自比,抓串色/漏 token。
  3. token 残留闸:grep 0xFF… 该屏为 0(颜色全走 context.tokens)。

基建就位(本轮):golden 骨架 + 整屏还原闸(库存列表已接)+ ds-compare 目检编排 + design-distill skill 补全(montage/flutter-golden/跨渲染器分流/多主题 codegen)。 后续屏(商品/单据/往来/财务/系统域)逐个追加块 3 规格 + 块 4 行 + 一份 *_golden_test.dart,一屏一闭环,禁积压。