Skill v1.0.1
currentAutomated scan96/100+5 new
version: "1.0.1" 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/ 内建组件;确实需要改内建组件时先征得用户确认。