--- name: PRD-to-Flutter description: 从 HTML PRD 精确 1:1 还原 Flutter 代码,覆盖所有页面、弹窗、提示、状态等可视元素。 --- # PRD-to-Flutter Skill 此 Skill 用于将 HTML 格式的 PRD(产品需求文档/设计稿)**精确 1:1 还原**为 Flutter 代码。 > **核心原则**:不自由发挥,不擅自修改,严格按照 PRD 执行。 --- ## 触发条件 当用户提供 HTML PRD 文件并要求还原为 Flutter 代码时激活此 Skill。 --- ## 执行流程 ### 阶段一:完整清单提取(必须完成后才能编码) #### 1.1 阅读 PRD - 完整阅读 PRD HTML 文件 - 理解整体页面结构和交互逻辑 #### 1.2 生成页面清单 列出 PRD 中**所有**可视元素,包括: | 类型 | 必须识别的元素 | |------|----------------| | 主页面 | 所有屏幕级页面 | | 弹窗 (Dialog) | 确认框、警告框、自定义弹窗 | | 底部弹层 (BottomSheet) | 分享、选择器、筛选、操作菜单 | | Toast / Snackbar | 成功提示、错误提示、警告提示 | | 加载状态 | 骨架屏、Loading 动画、进度条 | | 空状态 | 列表为空、搜索无结果 | | 错误状态 | 网络错误、服务器错误、权限错误 | | 悬浮组件 | FAB、悬浮工具栏 | | 动画过渡 | 页面切换动画、组件进出场动画 | 生成清单格式: ```markdown ## 页面清单 - [ ] 首页 (home_page.dart) - [ ] 正常状态 - [ ] 加载状态(骨架屏) - [ ] 空状态 - [ ] 错误状态 - [ ] 详情页 (detail_page.dart) - [ ] 登录弹窗 (login_dialog.dart) - [ ] 分享底部弹层 (share_bottom_sheet.dart) - [ ] 操作成功 Toast - [ ] 网络错误提示 ... ``` #### 1.3 提取设计 Token 从 PRD 中提取所有设计规范,生成 `design_tokens.dart` 文件: ```dart // lib/theme/design_tokens.dart import 'package:flutter/material.dart'; /// 颜色定义 - 必须使用 PRD 中的精确 Hex 值 class AppColors { // 主色 static const Color primary = Color(0xFF______); static const Color primaryLight = Color(0xFF______); static const Color primaryDark = Color(0xFF______); // 文字颜色 static const Color textPrimary = Color(0xFF______); static const Color textSecondary = Color(0xFF______); static const Color textHint = Color(0xFF______); // 背景颜色 static const Color background = Color(0xFF______); static const Color surface = Color(0xFF______); static const Color card = Color(0xFF______); // 状态颜色 static const Color success = Color(0xFF______); static const Color warning = Color(0xFF______); static const Color error = Color(0xFF______); // 边框和分割线 static const Color border = Color(0xFF______); static const Color divider = Color(0xFF______); // 遮罩 static const Color overlay = Color(0x80______); } /// 字体样式 - 必须使用 PRD 中的精确字号和字重 class AppTextStyles { // 标题 static const TextStyle h1 = TextStyle( fontSize: __, fontWeight: FontWeight.w___, color: AppColors.textPrimary, ); static const TextStyle h2 = TextStyle(fontSize: __, fontWeight: FontWeight.w___); static const TextStyle h3 = TextStyle(fontSize: __, fontWeight: FontWeight.w___); // 正文 static const TextStyle bodyLarge = TextStyle(fontSize: __, fontWeight: FontWeight.w___); static const TextStyle body = TextStyle(fontSize: __, fontWeight: FontWeight.w___); static const TextStyle bodySmall = TextStyle(fontSize: __, fontWeight: FontWeight.w___); // 按钮文字 static const TextStyle button = TextStyle(fontSize: __, fontWeight: FontWeight.w___); // 辅助文字 static const TextStyle caption = TextStyle(fontSize: __, fontWeight: FontWeight.w___); } /// 间距定义 - 必须使用 PRD 中的精确数值 class AppSpacing { static const double xs = __; // 极小间距 static const double sm = __; // 小间距 static const double md = __; // 中等间距 static const double lg = __; // 大间距 static const double xl = __; // 超大间距 static const double xxl = __; // 特大间距 } /// 圆角定义 class AppRadius { static const double none = 0; static const double xs = __; static const double sm = __; static const double md = __; static const double lg = __; static const double full = 999; // 全圆角 } /// 阴影定义 class AppShadows { static const BoxShadow sm = BoxShadow( color: Color(0x1A000000), blurRadius: __, offset: Offset(0, __), ); static const BoxShadow md = BoxShadow( color: Color(0x1A000000), blurRadius: __, offset: Offset(0, __), ); } /// 动画时长 class AppDurations { static const Duration fast = Duration(milliseconds: ___); static const Duration normal = Duration(milliseconds: ___); static const Duration slow = Duration(milliseconds: ___); } ``` #### 1.4 用户确认 **必须**将页面清单和设计 Token 报告给用户确认。 **未经用户确认,禁止开始编码。** --- ### 阶段二:逐项还原 对清单中的每一项,按以下顺序执行: ``` ┌─────────────────────────────────────────────────────────────┐ │ 1. 阅读 PRD 中该元素的具体设计 │ │ ↓ │ │ 2. 编写 Flutter 代码 │ │ - 必须使用 design_tokens.dart 中的值 │ │ - 禁止硬编码任何颜色、字号、间距 │ │ ↓ │ │ 3. 运行应用,触发该元素显示 │ │ ↓ │ │ 4. 截图该元素 │ │ ↓ │ │ 5. 对比截图与 PRD │ │ ├── ✅ 一致 → 标记完成,进入下一项 │ │ └── ❌ 不一致 → 分析差异,修复代码,回到步骤 3 │ └─────────────────────────────────────────────────────────────┘ ``` --- ### 阶段三:弹窗/弹层专项检查 对于每个弹窗或弹层,必须逐项验证: | 检查项 | 验证内容 | |--------|----------| | 尺寸 | 宽度、高度、最大/最小限制是否与 PRD 一致 | | 位置 | 居中/底部/顶部/自定义位置是否正确 | | 圆角 | 各角圆角值是否与 PRD 一致 | | 背景遮罩 | 遮罩颜色、透明度是否正确 | | 弹出动画 | 动画类型(滑动/淡入/缩放)和时长是否正确 | | 关闭动画 | 关闭时的动画是否正确 | | 关闭方式 | 点击遮罩/按钮/滑动关闭是否与 PRD 一致 | | 内容布局 | 标题、正文、按钮的排列和间距是否正确 | | 按钮样式 | 按钮颜色、圆角、文字样式是否正确 | --- ### 阶段四:状态专项检查 对于每个页面,必须验证以下状态: | 状态 | 验证内容 | |------|----------| | 加载状态 | 骨架屏/Loading 动画是否与 PRD 一致 | | 空状态 | 图标、文案、按钮是否与 PRD 一致 | | 错误状态 | 图标、文案、重试按钮是否与 PRD 一致 | | 下拉刷新 | 刷新指示器样式是否正确 | | 上拉加载 | 加载更多提示是否正确 | --- ### 阶段五:交互验证 验证所有交互逻辑: | 交互类型 | 验证内容 | |----------|----------| | 按钮点击 | 点击后的行为(跳转/弹窗/请求)是否正确 | | 页面跳转 | 跳转目标页面是否正确 | | 表单提交 | 校验规则、提交行为是否正确 | | 手势操作 | 滑动、长按等手势是否正确响应 | | 键盘处理 | 键盘弹起时页面是否正确调整 | --- ## 🚫 禁止行为(红线) 以下行为**绝对禁止**,违反任何一条都需要立即修正: | 禁止行为 | 说明 | |----------|------| | ❌ 修改颜色值 | 必须使用 PRD 中定义的精确 Hex 颜色 | | ❌ 修改字号 | 必须与 PRD 完全一致 | | ❌ 修改间距/边距 | 必须使用 PRD 中定义的精确间距 | | ❌ 修改圆角值 | 必须与 PRD 一致 | | ❌ 删除 UI 元素 | PRD 中有的元素必须实现 | | ❌ 添加 UI 元素 | PRD 中没有的元素禁止添加 | | ❌ 改变组件层级 | 嵌套关系必须与 PRD 一致 | | ❌ 改变布局方式 | Row/Column/Stack 等布局必须与 PRD 一致 | | ❌ 改变交互逻辑 | 点击行为、跳转目标必须与 PRD 一致 | | ❌ 使用未定义的动画 | 动画类型和时长必须与 PRD 一致 | | ❌ 跳过任何状态 | 加载/空/错误状态都必须实现 | | ❌ 跳过任何弹窗/提示 | 所有弹窗和 Toast 都必须实现 | | ❌ 硬编码设计值 | 所有设计值必须引用 design_tokens.dart | --- ## 完成标准 只有满足以下所有条件,才能认为 PRD 还原完成: 1. ✅ 页面清单中所有项目都已标记完成 2. ✅ 每个元素都经过截图对比验证 3. ✅ 所有弹窗通过专项检查 4. ✅ 所有状态通过专项检查 5. ✅ 所有交互通过验证 6. ✅ 没有违反任何禁止行为 --- ## 输出报告 完成后,生成还原报告: ```markdown # PRD 还原报告 ## 统计 - 总页面数:X - 总弹窗数:X - 总状态数:X - 还原完成率:100% ## 文件清单 - lib/theme/design_tokens.dart - lib/pages/home_page.dart - lib/pages/detail_page.dart - lib/widgets/dialogs/login_dialog.dart - lib/widgets/sheets/share_bottom_sheet.dart ... ## 验证截图 (附上关键页面和弹窗的截图) ```