2026-02-06 16:03:32 +08:00

9.7 KiB
Raw Blame History

name, description
name description
PRD-to-Flutter 从 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、悬浮工具栏
动画过渡 页面切换动画、组件进出场动画

生成清单格式:

## 页面清单
- [ ] 首页 (home_page.dart)
  - [ ] 正常状态
  - [ ] 加载状态(骨架屏)
  - [ ] 空状态
  - [ ] 错误状态
- [ ] 详情页 (detail_page.dart)
- [ ] 登录弹窗 (login_dialog.dart)
- [ ] 分享底部弹层 (share_bottom_sheet.dart)
- [ ] 操作成功 Toast
- [ ] 网络错误提示
...

1.3 提取设计 Token

从 PRD 中提取所有设计规范,生成 design_tokens.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. 没有违反任何禁止行为

输出报告

完成后,生成还原报告:

# 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
...

## 验证截图
(附上关键页面和弹窗的截图)