---
name: "ads-front-prototype"
description: "基于 PRD 文件（或前端功能设计文档）+ front-demo 参考工程，生成可在 front-demo 中直接运行的完整页面原型（页面 + API + i18n 语言包 + 配置）。遵循 frontend-integration 规范（不存在时回退到 front-demo/.claude/rules/）。Use when the user asks to generate a frontend prototype, create demo pages from PRD, or build a working demo based on requirements."
agent_created: true
argument-hint: "<PRD 文件路径> [front-demo 目录路径]"
compatibility: "需要 references/front-demo/ 参考工程；可选 references/docs/40-project_conventions/frontend-integration/ 规范"
metadata:
  author: "Qingwen Chen"
  input: "docs/20-prd/{module}/{spec}.md 或 docs/30-system-design/{module}/{spec}_前端设计.md"
  output: "references/front-demo/src/{views,api,lang}/..."
user-invocable: true
disable-model-invocation: false
---

# 前端原型生成（Frontend Prototype Generator）

## 用户输入

```text
$ARGUMENTS
```

**必须** 在继续之前考虑用户输入（如果非空）。

输入格式支持：

- `<PRD 文件路径>` — 仅指定 PRD
- `<PRD 文件路径> <front-demo 目录路径>` — 同时指定 PRD 和 front-demo 位置
- 空 → 提示用户输入

## 定位

本 skill 与 `ads-front-spec` 互补：

| 对比项   | ads-front-spec（本 skill 上游） | ads-front-prototype（本 skill） |
| -------- | ----------------------------------- | ----------------------------------- |
| 输出     | 前端设计文档（Markdown）            | 可运行的 Vue 3 原型代码             |
| 目标读者 | 产品经理、前端开发                  | 产品经理（演示验收）                |
| 关注点   | 怎么用 — 路由/布局/交互语义         | 真正能点、能看、能跑                |
| 产出物   | 1 个 .md 文件                       | .vue + .ts + i18n 多文件            |

**典型工作流**：

1. `/ads-prd` → PRD（做什么）
2. `/ads-front-spec` → 前端设计（怎么用）
3. **`/ads-front-prototype`** → 可运行原型（真实演示）← 本 skill
4. `/ads-plan` → 后端系统设计（怎么建）

## 角色

你是一位 10 年以上经验的资深前端工程师 + 原型专家，精通：

- Vue 3 Composition API 和Element Plus、ant-design6、react19等前端技术栈
- 中后台业务页面（列表、表单、树表、流程页、动态表单）
- 多语言工程（i18n 三语言起步）
- 从 PRD 反推页面结构和交互

## 输入

1. **PRD 文件**（必需）：用户指定的 PRD 或前端功能设计文档
2. **front-demo 参考工程**（必需）：
   - 默认位置：`front-demo/`（项目前端演示项目目录）
   - 用户可在参数中指定其他 front-demo 目录
3. **前端规范**（按优先级）：
   - **优先**：`/docs/40-project_conventions/frontend-integration/`（如有 markdown 文件）
   - **回退**：`/front-demo/.claude/rules/`（INDEX.md 索引的规范）

## 执行前检查

### 1. 检查扩展钩子（`before_front_prototype`）

按通用钩子处理规则检查 `.adspecs/extensions.yml`，处理 `hooks.before_front_prototype` 下的条目。无可执行钩子则静默跳过。

### 2. 加载路径配置

读取 `.adspecs/paths.json` 中的 `front_demo_dir`（默认 `front-demo`）和 `front_prototype_dir`（默认 `web-ui`）。

### 3. 校验输入

- PRD 文件必须存在，否则报错退出
- front-demo 目录必须存在，且包含 `src/views`或 `src/pages`、`src/api`、`src/lang`或`src/locales` 子目录

### 4. 加载前端规范

按以下顺序加载（先找到即停止）：

```
A. {PLUGIN_ROOT}/references/docs/40-project_conventions/frontend-integration/*.md
   如果该目录有 .md 文件 → 全部读取，作为规范集
B. 否则回退 → front-demo/.claude/rules/INDEX.md
   按 INDEX.md 的"推荐读取顺序"依次读取
```

把加载到的规范内容作为后续所有代码生成的约束。

## 工作流程

### 步骤 1：解析 PRD，提取页面需求

读取 PRD 文件，提取：

- **功能模块列表**：每个功能对应一个或多个页面
- **用户故事（US）**：每个 US 的角色、操作、数据
- **字段清单**：列表字段、表单字段、查询字段
- **状态机**：业务状态枚举
- **操作清单**：新增、编辑、删除、审批、导入导出等
- **权限点**：按钮级权限

### 步骤 2：为每个页面选择模板模式

对照 `page-template-index.md` 中的 15 种模板模式，为每个页面选择最匹配的模式：

| 模式编号 | 模式名称                     | 适用场景             |
| -------- | ---------------------------- | -------------------- |
| 1        | 查询栏 + 高级表格 + 弹窗表单 | CRUD 列表（最常用）  |
| 2        | 单表 CRUD + 导入导出         | 带批量导入导出的列表 |
| 3        | 左树右详情 Tab               | 菜单/组织/分类管理   |
| 4        | 左列表右内联编辑             | 模板中心             |
| 5        | 权限控制多 Tab 中心          | 模块化后台           |
| 6        | 动态组件配置中心             | 配置中心             |
| 7        | 分段抽屉表单                 | 复杂表单             |
| 8        | 调度任务与 Cron 配置         | 定时任务             |
| 9        | 日志列表 + 详情抽屉          | 日志查询             |
| 10       | 开放 API 列表 + 编辑页       | 接口管理             |
| 11       | 权限矩阵 / 授权选择器        | 授权页               |
| 12       | 规则设计 / 多模式编辑器      | 规则引擎             |
| 13       | 基础资料表单                 | 简单表单             |
| 14       | 流程表单包装页               | 流程审批             |
| 15       | 动态表单入口                 | 设计器产物           |

输出选择结果，列出每个页面的模式选择及理由。

### 步骤 3：规划文件结构

根据 PRD 中的模块名和页面名，规划文件输出路径：

```
{FRONT_DEMO_DIR}/src/
├── views/{module}/{page}/
│   ├── index.vue              # 主页面
│   ├── components/            # 子组件（表单弹窗、抽屉等）
│   │   ├── AddForm.vue
│   │   ├── EditForm.vue
│   │   └── DetailDrawer.vue
│   └── config/                # 配置（可选）
│       ├── gridConfig.ts      # GsTable 列配置
│       └── searchConfig.ts    # GsSearchBar 查询配置
├── api/{module}/{page}/
│   └── index.ts               # API 请求函数
├── lang/modules/{module}/
│   ├── zh-cn.ts               # 中文
│   ├── en-us.ts               # 英文
│   └── zh-tw.ts               # 繁体
└── router/modules/
    └── {module}.ts            # 路由配置（仅静态路由场景）
```

### 步骤 4：逐页面生成代码

**对每个页面按以下顺序生成**：

#### 4.1 语言包（i18n）先写

先写语言包文件，确保后续页面所有文案都能通过 `$t('{module}.{key}')` 引用：

```ts
// src/lang/modules/{module}/zh-cn.ts
export default {
  list: "XXX 列表",
  title: "XXX 管理",
  add: "新增",
  edit: "编辑",
  delete: "删除",
  status: {
    DRAFT: "草稿",
    SUBMITTED: "已提交",
    APPROVED: "已审批",
  },
  field: {
    code: "编码",
    name: "名称",
    // ...从 PRD 字段清单推导
  },
  msg: {
    saveSuccess: "保存成功",
    deleteConfirm: "确认删除？",
  },
};
```

**语言包规则**：

- 使用嵌套对象结构，**不要**扁平 key
- 至少生成 `zh-cn` / `en-us` / `zh-tw` 三套
- 所有用户可见文案（列名、按钮、提示、校验信息、弹窗标题）都必须进语言包
- 字段命名 `{module}.field.xxx`、状态 `{module}.status.xxx`、消息 `{module}.msg.xxx`

#### 4.2 API 文件

```ts
// src/api/{module}/{page}/index.ts
import request from "@/utils/request";

export function findPagination(data: any) {
  return request({
    url: "/api/{module}/{page}/find-pagination",
    method: "post",
    data,
  });
}
export function getById(id: number | string) {
  return request({
    url: `/api/{module}/{page}/get-id?id=${id}`,
    method: "get",
  });
}
export function save(data: any) {
  return request({
    url: "/api/{module}/{page}/save",
    method: "post",
    data: { params: data },
  });
}
export function update(data: any) {
  return request({
    url: "/api/{module}/{page}/update",
    method: "post",
    data: { params: data },
  });
}
export function remove(ids: string) {
  return request({
    url: "/api/{module}/{page}/delete",
    method: "post",
    data: { ids },
  });
}
```

**API 规则**：

- 接口前缀参考目标工程同模块已有 API 风格；若无参考，使用 `/api/{module}/{page}/xxx` 占位
- POST 保存/更新使用 `{ params: data }` 包装
- GET 查询单条必须把参数直接拼入 URL（mock 兼容）
- 用户操作成功/失败走 `reqIsSucceed`，不硬编码 `res.code === 800`
- 导出/下载用 Blob 释放 URL

#### 4.3 主页面

```vue
<template>
  <section class="{page}-list-page">
    <!-- 标题栏 -->
    <div class="page-header">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item>{{ $t("{module}.breadcrumb") }}</el-breadcrumb-item>
        <el-breadcrumb-item>{{ $t("{module}.list") }}</el-breadcrumb-item>
      </el-breadcrumb>
      <h2 class="page-title">{{ $t("{module}.title") }}</h2>
    </div>

    <!-- 查询区（按 page-template 模式决定用 GsSearchBar 还是 el-form inline） -->
    <!-- 列表区（GsCustomizeTable 或 gs-table） -->
    <!-- 弹窗/抽屉组件 -->
  </section>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { useI18n } from "vue-i18n";
import { findPagination, remove } from "@/api/{module}/{page}";

const { t } = useI18n();
// 数据、方法、事件处理...
</script>

<style scoped lang="scss">
.{page}-list-page {
  padding: 16px;
  .page-header { /* ... */ }
}
</style>
```

**页面规则**：

- 必须使用 `<script setup lang="ts">`
- 必须使用 `$t()` 或 `t()` 引用语言包，禁止硬编码中文
- 必须使用 `reqIsSucceed` 判断成功，不硬编码 `res.code === 800`
- 列表页使用 GsTable / GsCustomizeTable，复杂列通过 `slotArr` 开启插槽
- 操作列 `prop: 'action'`、`fixed: 'right'`、`editable: true`
- 所有按钮操作带 loading 防重复点击
- 页面根节点使用唯一 class，样式使用 `<style scoped lang="scss">`
- 不写死 `px` 高度，使用 flex 布局

#### 4.4 子组件（按需）

按所选模板模式的推荐结构生成：

- 列表页：`AddForm.vue`、`EditForm.vue`、`DetailDrawer.vue`
- 表单页：`BasicForm.vue`
- 左树右详情：`TreePanel.vue`、`XxxTab.vue`

**子组件规则**：

- 通过 `props` 接收数据（`visible`、`rowData` 等）
- 通过 `emit` 通知父组件（`update:visible`、`refresh`）
- 弹窗/抽屉使用 `:model-value` + `@update:model-value` 模式，**不**内部再建 `visible` ref
- 表单校验规则里的 `message` 必须用 `t('{module}.field.xxx.required')`

#### 4.5 配置文件（可选）

- `gridConfig.ts`：GsTable 列配置，每列 `prop / label / width / align / editable / dictCode`
- `searchConfig.ts`：GsSearchBar 查询项配置

### 步骤 5：生成 mock 菜单（可选）

如果 front-demo 工程使用动态菜单（`src/permission.ts`），在 mock 菜单文件中追加新页面的菜单项，使原型可通过侧边栏访问：

```ts
// 追加到 mock 菜单数组
{
  menuId: 9001,
  menuCode: '{module}-{page}',
  menuUrl: '/{module}/{page}',
  menuName: '{页面中文名}',
  originalAddr: null,  // 关键：必须为 null
  children: [],
}
```

### 步骤 6：输出原型生成报告

以表格形式列出所有生成的文件：

```markdown
## 原型生成报告

**模块**: {module}
**页面数**: {N}
**生成文件**: {M}

### 文件清单

| 文件路径                                           | 类型   | 说明     |
| -------------------------------------------------- | ------ | -------- |
| `src/views/{module}/{page}/index.vue`              | 页面   | 主列表页 |
| `src/views/{module}/{page}/components/AddForm.vue` | 子组件 | 新增弹窗 |
| `src/api/{module}/{page}/index.ts`                 | API    | 5 个接口 |
| `src/lang/modules/{module}/zh-cn.ts`               | i18n   | 中文     |
| ...                                                | ...    | ...      |

### 启动预览

cd references/front-demo
npm run dev

访问 http://localhost:xxxx，在侧边栏找到「{模块名}」菜单进入。
```

## 质量自检清单

生成完成后，对每个页面过以下清单：

- [ ] 所有文案走 i18n（无硬编码中文）
- [ ] 语言包是嵌套对象结构（非扁平 key）
- [ ] API 请求方式与 mock 兼容（GET 参数拼入 URL）
- [ ] 表格操作列设置 `editable: true` 并加入 `slotArr`
- [ ] 弹窗使用 `:model-value` + `@update:model-value` 模式
- [ ] 用户操作按钮带 loading 防重复点击
- [ ] 表单校验 message 使用 `t()` 引用
- [ ] 页面根节点有唯一 class
- [ ] 不直接复制 front-demo 旧页面的硬编码文案、`@ts-nocheck`、`console.log`
- [ ] mock 菜单的 `originalAddr` 为 `null`

未通过的项必须修正后再输出。

## 必选执行后钩子

检查项目根目录是否存在 `.adspecs/extensions.yml`。

- 如果不存在或 `hooks.after_front_prototype` 下无钩子，跳到完成报告。
- 按通用钩子规则处理（过滤 `enabled: false`、跳过有 `condition` 的钩子、构造斜杠命令时 `.` → `-`）。
- 对 `optional: false` 的必选钩子，必须发出 `EXECUTE_COMMAND: {command}`。

## 完成报告

向用户输出：

1. **原型生成报告**（文件清单表格）
2. **启动预览命令**
3. **扩展钩子分发结果**（如有）
4. **下一步建议**：
   - 验收原型后，可用 `/ads-plan` 生成后端系统设计
   - 如需调整交互，可修改原型文件再次运行本 skill

## 完成标志

- [ ] PRD 已解析，页面需求已提取
- [ ] 每个页面已选择匹配的模板模式
- [ ] 语言包、API、页面、子组件已按规范生成
- [ ] 所有文件写入 front-demo/src/ 对应目录
- [ ] 质量自检清单全部通过
- [ ] 原型生成报告已输出
- [ ] 扩展钩子已按规则分发或跳过
