| name | fa-crud-page-generator |
| description | 为 Fantastic-admin 框架生成完整的 CRUD 业务模块,遵循框架标准模块结构和内建 Fa* 组件体系,使用 FaForm/FaFormItem 生成新增/编辑表单,产出列表页、详情/编辑页、DetailForm 表单组件、API 模块、fake mock 数据、可选路由。用户说:'帮我做一个商品管理页面'、'搭一个用户列表,能搜索分页新增编辑删除'、'生成订单模块'、'新建 XX 管理模块'、'快速搭一个标准模块/CRUD 页面' 时,即使没有明确说 CRUD,也应触发此技能。 |
CRUD 页面生成器
在 Fantastic-admin 框架中生成标准 CRUD 业务模块。生成时遵循框架当前标准模块结构:
列表页、独立详情页、DetailForm 表单组件、API 模块、fake mock、可选路由和 route i18n
要一次性配套生成。
优先复刻框架现有写法,而不是重新发明页面结构:列表页用 FaSearchBar + FaTable +
FaPagination,详情表单抽成 components/DetailForm/index.vue,独立详情页用
FaFixedBar 固定顶部标题和底部提交区。
生成文件清单:
apps/<app>/src/views/{path}/{module}/list.vue — 列表页
apps/<app>/src/views/{path}/{module}/detail.vue — 独立详情页,仅 router 模式需要
apps/<app>/src/views/{path}/{module}/components/DetailForm/index.vue — 新增/编辑表单
apps/<app>/src/api/modules/{fileName}.ts — API 模块
apps/<app>/src/api/fake_modules/{fileName}.fake.ts — fake mock 数据,可选
apps/<app>/src/router/modules/{routeFileName}.ts — 前端路由,可选
apps/<app>/src/locales/lang/route/{locale}.json — 路由标题 i18n,可选
先确认应用
本项目是 pnpm monorepo。开始写文件前先确认目标应用:
- 如果用户已经明确写了
apps/<app>、admin 应用、pro 应用 等目标应用,直接使用该应用。
- 如果没有明确目标应用,先执行
ls apps/ 查看可用应用,然后询问用户要生成到哪个应用,并等待回复。
- 后续所有路径都以
apps/<app>/src/ 为根。
不要默认猜测应用;生成到错误应用的返工成本很高。
信息收集
尽量一次性收集会影响文件结构的信息:
- 模块名:英文,用于目录、API 文件和路由,如
product、order、systemUser
- 模块中文名:用于标题和提示,如
商品、订单、用户
- 存放路径:位于
src/views/ 下的子路径,如 mall、system/user,可为空
- 字段清单:字段名、中文标签、类型、是否列表显示、是否搜索、是否表单显示、是否必填
- 详情展示模式:
router、modal、drawer,默认 router
- 是否启用批量删除:默认启用
- 是否支持列表高度自适应:默认生成
tableAutoHeight 代码
- 是否生成 fake mock:开发阶段默认推荐生成
- 是否生成路由和 route i18n:仅当前端路由由本地配置维护时生成
如果用户只给出模块名和很少字段,使用一个最小可运行字段:
title(标题,string,列表/搜索/表单显示,必填),并在完成后提醒用户继续替换业务字段。
命名规范
给定模块名 name 和路径 path(相对于 apps/<app>/src/views/):
| 用途 | 规则 | 示例(path 为空,name=product) |
|---|
| 视图目录 | src/views/{path}/{snake_case(name)}/ | src/views/product/ |
| API 文件名 | path 参与业务命名时使用 camelCase;普通模块用 camelCase(name) | product |
| fake 文件名 | 与 API 文件名一致,放到 src/api/fake_modules/ | product.fake.ts |
| 列表组件名 | PascalCase({path}-{name}-list) | ProductList |
| 详情组件名 | PascalCase({path}-{name}-detail) | ProductDetail |
| 路由 name | camelCase(name)List / camelCase(name)Detail | productList |
| API URL 前缀 | snake_case(path/name),无前导斜杠 | product |
snake_case 用下划线连接多个单词,如 productCategory -> product_category。
代码生成规则
详细模板见 references/templates.md。生成时按这些规则填充模板:
list.vue 使用 <script setup lang="ts">,导入 type { TableColumn } from '@fantastic-admin/components'。
- 表格列使用
computed<TableColumn<Item>[]>(...) 定义,页面模板使用 FaTable 的 :columns 与 #cell-xxx 插槽。
- 搜索区使用
FaSearchBar + FaLabel,按钮保持“重置 / 筛选 / 展开收起”的顺序。
- 工具栏通过
FaTable 的 #toolbar 插槽放“新增”和批量操作。
- 行操作用
FaButton size="icon-sm" 编辑按钮和 FaDropdown 删除菜单。
- 删除确认统一使用
useFaModal().confirm,提示成功统一使用 useFaToast().success。
router 模式在列表页通过 eventBus.on('get-data-list') 接收详情页提交后的刷新事件;卸载时 eventBus.off('get-data-list')。
modal / drawer 模式通过 useFaModal().create 或 useFaDrawer().create 渲染 DetailForm,confirm 时调用表单暴露的 submit();仅当返回 true 时刷新列表并关闭。
DetailForm 使用 FaForm/FaFormItem,表单对象使用 const model = ref<...>({...}),通过 useTemplateRef<FormExpose>('formRef') 获取表单引用,并只 defineExpose({ submit }) 给外部调用。
submit() 必须返回 Promise<boolean>:校验失败返回 false,新增/编辑成功后提示并返回 true。父级页面、modal、drawer 都必须检查返回值,避免校验失败时关闭页面或弹窗。
- fake mock 文件放在
apps/<app>/src/api/fake_modules/,不是 api/modules/。
- API 模块开启 mock 时在每个请求配置中设置
fake: true;不生成 fake 时去掉 fake: true。
路由生成
如果用户选择生成路由,优先调用或参考 fa-route-generator,并遵循最新标准模块路由模式:
- 父级路由指向
Layout,meta.title 使用 $t('route.<module>.root'),设置合适图标。
- 列表子路由
path: '',name: '<module>List',组件指向 list.vue。
- 当父级路由只作为菜单入口、列表页作为默认子页时,列表路由使用
meta.menu: false 和 breadcrumb: false;业务模块如需列表作为独立菜单项,可按用户需求保留菜单。
router 模式详情路由为 detail/:id?,meta.menu: false,activeMenu 指向列表/父菜单路径。
- 为避免列表和详情标签页状态混乱,列表路由设置
keepAlive: '<module>Detail',详情路由设置 keepAlive: true 与 noKeepAlive: '<module>List'。
- route i18n 至少同步
zh-cn、zh-tw、en 三份 src/locales/lang/route/*.json。
生成前后检查
写文件前展示将生成/修改的文件列表,确认不会覆盖用户已有业务文件。若目标文件已存在,先读取并说明将如何合并。
完成后简要说明:
- 已生成哪些文件;
- 若未生成路由,提示可继续用
fa-route-generator 添加;
- 若生成 fake mock,说明请求已配置
fake: true;
- 若字段是枚举、状态、日期、上传等复杂类型,提醒用户按业务替换控件和 mock 取值。
不要修改 packages/components/ 内建组件;确实需要改内建组件时先征得用户确认。