docs: 迁入第一迭代过程报告并建立进展看板
- 新增 development/iterations/iteration-1/:15 份角色报告 + 进展看板(已完成/未闭环/下一步),作为双人协作的进度事实来源 - 新增 ADR-006:测试与交付容器化策略(Testcontainers / 交付 Docker 包 / 本机库仅个人联调) - Git 工作流规范补充:敏感信息只进忽略文件或 sample、测试数据不入库、测试代码限标准测试目录 - 门禁:mkdocs build --strict 通过(零警告)
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# 08 · Flutter 主题迁移与登录组件实现报告
|
||||
|
||||
> 作者:Frontend Developer
|
||||
> 日期:2026-09-03
|
||||
> 依据:ADR-005(patbond-doc/docs/architecture/decisions.md)、04-ui-login-design-spec.md
|
||||
|
||||
## 1. 完成内容
|
||||
|
||||
1. `lib/core/theme/app_theme.dart` 重写为语义 token 组织(`AppColors` + 新增 `AppRadius`),落地珊瑚橙正典色板;补齐 `filledButtonTheme`(高 52、圆角 16、`primaryStrong` 填充、显式 disabled 色)、`errorBorder` / `focusedErrorBorder` / `errorStyle`、`colorScheme.error` 覆盖。主题仍集中在单一文件。
|
||||
2. 五个 Tab 页面及公共组件逐处替换旧靛蓝/冷灰硬编码色值为语义 token,仅换色、未动布局。
|
||||
3. 新建 5 个可复用组件于 `lib/core/widgets/`:`BrandMark`、`AppTextField`、`PrimaryButton`(含 isLoading)、`InlineErrorBanner`、`AuthScaffold`。本次未建登录页面(等后端契约冻结)。
|
||||
4. 为 `PrimaryButton`、`AppTextField` 各写 3 个 widget 测试。
|
||||
|
||||
## 2. Token 映射表(旧 → 新)
|
||||
|
||||
### 2.1 AppColors 字段值变化(字段名不变,引用处无需改)
|
||||
|
||||
| Token | 旧值(脚手架靛蓝) | 新值(珊瑚橙正典) |
|
||||
| --- | --- | --- |
|
||||
| `primary` | `#4F46E5` | `#FF6F4C`(仅装饰/图标,不承载实心填充上的文字) |
|
||||
| `canvas` | `#F8FAFC` | `#FFF7ED` 奶油底 |
|
||||
| `ink` | `#0F172A` | `#3E2A1F` |
|
||||
| `muted` | `#64748B` | `#9C8977` |
|
||||
| `border` | `#E2E8F0` | `#F0DCC8` |
|
||||
| `success` | `#10B981` | `#7FA88A` sage |
|
||||
| `warning` | `#F59E0B` | `#F59E0B`(不变) |
|
||||
|
||||
### 2.2 新增 token
|
||||
|
||||
| Token | 值 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `primaryStrong` | `#D6431A` | 实心按钮填充、可点击文字链接(白字 ≈4.5:1,WCAG AA) |
|
||||
| `primaryDark` | `#7A2E12` | 浅色底上的强调文字 |
|
||||
| `accent` / `accentDark` | `#FFB648` / `#7A4B0A` | 渐变终点、徽章 / amber 底文字 |
|
||||
| `surface` | `#FFFFFF` | 卡片、输入框背景(原为字面量 `Colors.white`) |
|
||||
| `surfaceTint` | `#FFE8D6` peach | 图标底、占位块、选中指示 |
|
||||
| `successInk` / `successSurface` | `#3F5744` / `#E8F0E8` | 成功提示的文字 / 底色 |
|
||||
| `error` | `#D0342C` | 错误文字、错误描边(白底 ≈5.4:1,AA) |
|
||||
| `brandGradient` | 135° `#FF6F4C → #FFB648` | 品牌渐变(装饰,不承载正文文字) |
|
||||
| `AppRadius.sm/md/lg/xl/pill` | 12 / 16 / 18 / 24 / 999 | 圆角刻度(§1.3) |
|
||||
|
||||
### 2.3 页面内硬编码旧色值 → token
|
||||
|
||||
| 旧硬编码 | 新写法 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| `#F1F5F9`(图片占位底) | `AppColors.surfaceTint` | common.dart ×2 |
|
||||
| `#EEF2FF`(indigo-50 图标底) | `AppColors.surfaceTint` | home ×2、profile |
|
||||
| `#E0E7FF`(导航指示/渐变上副文字) | `AppColors.surfaceTint` / `Colors.white` | 主题、home 促销卡 |
|
||||
| `[#4F46E5→#8B5CF6]`、`[primary→#7C3AED]` 渐变 | `AppColors.brandGradient` | home 故事环、促销卡 |
|
||||
| `#ECFDF5→#FFF7ED` 问候卡渐变 | `surfaceTint → canvas` | home |
|
||||
| `0x224F46E5` 装饰爪印 | `primary.withAlpha(34)` | home |
|
||||
| `#475569`(slate 次级文字/阴天色) | `AppColors.primaryDark` / `AppColors.ink` | home |
|
||||
| `#64748B`、`#F59E0B`(多云/晴天) | `AppColors.muted` / `AppColors.warning` | home 天气色 |
|
||||
| `0xCC0F172A` 图片压暗渐变 | `ink.withAlpha(204)` | create |
|
||||
| `#E2E8F0`(scrim 上副文字/进度轨道) | `Colors.white70` / `AppColors.border` | create、pets |
|
||||
| `#ECFDF5` / `#A7F3D0` / `#047857` 健康提醒卡 | `successSurface` / `success.withAlpha(140)` / `successInk` | pets |
|
||||
| `#A5B4FC` / `#334155` / `#94A3B8`(深色卡上) | `AppColors.accent` / `Colors.white24` / `Colors.white70` | profile |
|
||||
| 促销卡反白按钮前景 `primary` | `primaryStrong`(AA) | home |
|
||||
| 导航选中 label `primary` | `primaryStrong`(11px 文字保 AA) | 主题 |
|
||||
|
||||
保留未动:天气雨/雪的功能性蓝色(`#0284C7`、`#0891B2`,非旧品牌色)、点赞红、卡片主题 `#F1F5F9` 描边改为 `AppColors.border`。
|
||||
|
||||
## 3. 改动文件清单
|
||||
|
||||
修改(7):
|
||||
- `patbond-flutter/lib/core/theme/app_theme.dart`(重写)
|
||||
- `patbond-flutter/lib/widgets/common.dart`
|
||||
- `patbond-flutter/lib/features/home/home_page.dart`
|
||||
- `patbond-flutter/lib/features/create/create_page.dart`
|
||||
- `patbond-flutter/lib/features/pets/pets_page.dart`
|
||||
- `patbond-flutter/lib/features/profile/profile_page.dart`
|
||||
- (services / post_detail / main_shell 仅引用 token 字段,值随主题自动切换,无需改动)
|
||||
|
||||
新增(7):
|
||||
- `patbond-flutter/lib/core/widgets/brand_mark.dart`
|
||||
- `patbond-flutter/lib/core/widgets/app_text_field.dart`
|
||||
- `patbond-flutter/lib/core/widgets/primary_button.dart`
|
||||
- `patbond-flutter/lib/core/widgets/inline_error_banner.dart`
|
||||
- `patbond-flutter/lib/core/widgets/auth_scaffold.dart`
|
||||
- `patbond-flutter/test/core/widgets/primary_button_test.dart`
|
||||
- `patbond-flutter/test/core/widgets/app_text_field_test.dart`
|
||||
|
||||
## 4. 验收命令输出摘要
|
||||
|
||||
```text
|
||||
$ dart format --output=none --set-exit-if-changed lib test
|
||||
Formatted 22 files (0 changed) in 0.15 seconds. # exit 0
|
||||
|
||||
$ flutter analyze
|
||||
Analyzing patbond-flutter...
|
||||
No issues found! (ran in 0.7s) # 无 error、无 warning
|
||||
|
||||
$ flutter test
|
||||
00:01 +7: All tests passed! # 含原有导航冒烟测试,未改断言
|
||||
```
|
||||
|
||||
## 5. 实现说明与遗留问题
|
||||
|
||||
1. **filledButtonTheme 的 minimumSize 用了 `Size(64, 52)` 而非规范建议的 `Size.fromHeight(52)`**:后者会给所有 FilledButton 无限最小宽度,令 Row 内既有按钮(首页促销卡「去使用」、服务页「立即预约」、对话框「确认恢复」)布局异常。改为仅约束高度 52;登录页的全宽由 `PrimaryButton` 自身 `width: double.infinity` 保证。副作用:既有小按钮从默认 40 高变为 52 高,视觉更厚重但协调,未破坏布局。
|
||||
2. **PrimaryButton 的 loading 态**通过 `disabledBackgroundColor: primaryStrong` 保持珊瑚填充(规范 §4.3/§4.4:loading 不是置灰禁用态),已有测试锁定该行为。
|
||||
3. **`ColorScheme.fromSeed` 仍以 `#FF6F4C` 为种子**,Material 组件(Chip、SegmentedButton、tonal 按钮等)使用生成的暖色调色板,与正典色板协调但非逐一指定;`error` 已显式覆盖为 `#D0342C`。若后续设计对某组件色不满意,在主题内补对应 componentTheme 即可。
|
||||
4. **天气语义色**:雨 `#0284C7`、雪 `#0891B2` 为功能色保留硬编码;阴天映射为 `ink`、多云映射为 `muted`,如需更细的天气色阶可后续补 token。
|
||||
5. **品牌字体(Baloo 2 / 圆润中文标题体)未引入**,规范允许后置;`BrandMark` 字标暂用系统字体 32/w700。
|
||||
6. **成功色 sage `#7FA88A` 作 11px TagPill 文字对比度偏弱**(约 2.4:1,沿用既有 TagPill 模式);正文类成功文字请用 `successInk`。此为设计规范自带取舍,未在本次擅改。
|
||||
7. Splash / 登录 / 注册页、认证状态机、flutter_secure_storage 依赖均未实现,按计划等后端契约冻结后进行。
|
||||
|
||||
---
|
||||
**Frontend Developer** · 2026-09-03
|
||||
Reference in New Issue
Block a user