Files
2026-08-31 11:33:59 +08:00

477 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: cross-fullstack-admin-crud-feature
description: Full-stack development workflow for Madong Admin CRUD features. Covers requirement analysis, existing implementation verification, backend migration/model/DAO/service/validate/schema/controller, frontend API/page/schema, menu permissions, migration execution, validation, and skill auto-evolution.
globs:
- "backend/app/**/*.php"
- "backend/resource/database/migrations/**/*.php"
- "backend/resource/data/menu/**/*.php"
- "frontend/admin/src/api/**/*.ts"
- "frontend/admin/src/views/**/*.vue"
- "frontend/admin/src/views/**/*.tsx"
- ".windsurf/skills/**/*.md"
---
# Madong Admin 全栈 CRUD 功能开发流程
用于开发类似“应用授权”这类后台管理功能,覆盖数据库、后端、前端、菜单权限、迁移执行与校验。
## 适用场景
- 在 Admin 后台新增一个业务管理页面。
- 需要新增数据库表、后端 CRUD、前端列表/表单/API。
- 需要菜单入口和按钮权限。
- 需要参考现有模块目录结构,例如 `/tools/delegation`、`/setting/notice`。
- 需要自动生成字段或自定义操作,例如 Access Key / Secret Key 自动生成、重置密钥。
## 总原则
1. 先核对项目真实实现,再使用 skill 或模板。
2. 以现有项目代码为准,skill 与项目不一致时先更新 skill。
3. 优先复用官方现有组件和基类。
4. 不直接照搬 Laravel Artisan 命令,当前项目使用 Webman/Madong 命令体系。
5. 数据库迁移执行前必须先 dry-run,确认会执行哪些迁移。
6. 前后端路径、权限码、菜单码必须保持一致。
## 开发前检查
### 1. 确认参考模块
优先读取用户指定的参考模块。
常见参考:
- `frontend/admin/src/views/setting/notice`
- `frontend/admin/src/views/tools/delegation`
- `frontend/admin/src/api/tools/delegation`
- `backend/app/adminapi/controller/notice/NoticeController.php`
- `backend/app/adminapi/controller/plugin/PluginMadongAuthController.php`
### 2. 确认真实项目规范
至少核对以下内容:
- 后端控制器是否继承 `app\adminapi\controller\Crud`。
- 模型是否继承 `core\base\BaseModel`。
- DAO 是否继承 `core\base\BaseDao`。
- Service 是否继承 `core\base\BaseService`。
- Validate 是否继承 `core\base\BaseValidate`。
- 前端 CRUD 是否使用 `useCrud`、`CrudSchema`、`BasicCrud`。
- 前端 API 是否使用 `BaseService` 和 `@/utils/http`。
- 表单组件名是否存在于 `frontend/admin/src/components/form/components`。
- 菜单数据是否维护在 `backend/resource/data/menu/admin.php`。
## 后端开发流程
### 1. 数据库迁移
路径:
```text
backend/resource/database/migrations/{timestamp}_create_{table}_table.php
```
当前项目雪花 ID 主键写法:
```php
$table->bigInteger('id')->primary()->comment('主键');
```
不要使用 Laravel 默认的:
```php
$table->id();
```
字段设计要求:
- 主键使用雪花 ID。
- 按需增加唯一索引、普通索引。
- 状态字段常用 `enabled`,默认 `1`。
- 时间字段按项目迁移写法使用 `timestamps()` 或项目已有封装。
- 如果模型使用软删除,迁移需包含软删除字段。
### 2. Model
路径:
```text
backend/app/model/{module}/{Model}.php
```
要求:
- 继承 `core\base\BaseModel`。
- 设置 `$table`。
- 设置 `$fillable`。
- 设置 `$casts`。
- 如项目同类模型使用软删除,则保持一致。
### 3. DAO
路径:
```text
backend/app/dao/{module}/{Model}Dao.php
```
要求:
- 继承 `core\base\BaseDao`。
- `setModel()` 返回模型类。
- 如需关键字搜索,按项目已有 DAO 实现 `getKeywordFields()`。
### 4. Service
路径:
```text
backend/app/service/admin/{module}/{Model}Service.php
```
要求:
- 继承 `core\base\BaseService`。
- 构造函数注入 DAO。
- 自定义业务逻辑放在 Service。
- 自动生成字段在 `save()` / `create()` 入口处理。
- 自定义操作单独暴露方法,例如 `resetSecret()`。
应用授权类功能示例:
- 新增时自动生成 `access_key`。
- 新增时自动生成 `secret_key`。
- 重置时只更新 `secret_key`。
- 密钥生成应使用安全随机源,例如 `random_bytes()`。
### 5. Validate
路径:
```text
backend/app/adminapi/validate/{module}/{Model}Validate.php
```
要求:
- 继承 `core\base\BaseValidate`。
- 定义 `$rule`、`$message`、`$scene`。
- `store` 场景不要求 `id`。
- `update` 场景要求 `id`。
- 自动生成字段不要暴露为必填输入。
### 6. Request / Response Schema
请求路径:
```text
backend/app/adminapi/schema/request/{module}/{Model}FormRequest.php
backend/app/adminapi/schema/request/{module}/{Model}QueryRequest.php
```
响应路径:
```text
backend/app/adminapi/schema/response/{module}/{Model}Response.php
```
要求:
- FormRequest 继承项目实际存在的表单基类。
- QueryRequest 使用项目实际存在的 `BaseQueryRequest`。
- 不要引用不存在的 `PageRequest`。
- OpenAPI 属性需与控制器 `x: [SchemaConstants::X_SCHEMA_REQUEST => ...]` 对应。
### 7. Controller
路径:
```text
backend/app/adminapi/controller/{module}/{Model}Controller.php
```
要求:
- 继承 `Crud`。
- 构造函数注入 Service 和 Validate。
- 标准接口调用 `parent::index()`、`parent::show()`、`parent::store()`、`parent::update()`、`parent::destroy()`。
- 路由通过 OpenAPI Attribute 标注。
- 权限码与前端和菜单保持一致。
推荐路由格式:
```text
GET /{module}/{resource}
GET /{module}/{resource}/{id}
POST /{module}/{resource}
PUT /{module}/{resource}/{id}
DELETE /{module}/{resource}/{id}
POST /{module}/{resource}/{id}/{custom-action}
```
应用授权示例:
```text
/plugin/application-auth
/plugin/application-auth/{id}
/plugin/application-auth/{id}/reset-secret
```
## 前端开发流程
### 1. API
路径参考用户指定目录结构。
例如参考 `/tools/delegation` 时:
```text
frontend/admin/src/api/tools/{feature}/index.ts
frontend/admin/src/api/tools/{feature}/types.ts
```
要求:
- 使用 `BaseService`。
- 使用 `@/utils/http`。
- 基础路径与后端路由一致。
- 自定义接口单独封装方法。
示例:
```ts
const baseUrl = '/plugin/application-auth'
```
### 2. 页面
路径参考用户指定目录结构。
例如参考 `/tools/delegation` 时:
```text
frontend/admin/src/views/tools/{feature}/index.vue
frontend/admin/src/views/tools/{feature}/schemas/index.tsx
```
要求:
- 使用 `useCrud` 和 `BasicCrud`。
- CRUD 配置写在 `schemas/index.tsx`。
- 不要使用项目未注册的表单组件。
- 当前项目日期时间选择使用 `DatePicker` + `componentProps.type = 'datetime'`。
- 当前项目 `CrudSchema` 列类型不支持 `type: 'operate'`,操作列由 `BasicCrud` 根据 `tableActions` / `dropDownActions` 自动生成。
### 3. 列表字段
按照用户需求定义:
- 序号:`type: 'index'`
- 名称:普通列
- Access Key:建议列表遮罩显示
- Secret Key:建议列表遮罩显示
- 失效时间:使用 `formatDateTime`
- 状态:使用 `ApiDict`
- 描述:`showOverflowTooltip`
- 创建时间:优先使用后端格式化字段,或 `formatDateTime(created_at)`
- 操作:通过 CRUD 操作配置生成
### 4. 表单字段
自动生成字段不要出现在新增表单中。
应用授权示例:
- `name`:必填
- `expired_at`:可选
- `enabled`:必填,默认 `1`
- `description`:可选
- `access_key`:后端自动生成,不手填
- `secret_key`:后端自动生成,不手填
### 5. 自定义操作
例如重置 Secret Key:
- 前端按钮放在 `dropDownActions` 或项目实际支持的操作配置中。
- 按钮增加 `auth`。
- 操作前使用 `ElMessageBox.confirm` 二次确认。
- 成功后提示新密钥并刷新列表。
## 菜单与权限
菜单数据路径:
```text
backend/resource/data/menu/admin.php
```
页面菜单示例字段:
```php
"title" => "应用授权",
"code" => "plugin:application-auth:list",
"type" => 2,
"path" => "/tools/application-auth",
"component" => "/tools/application-auth/index",
"methods" => "GET",
```
按钮权限建议补齐:
```text
plugin:application-auth:create
plugin:application-auth:delete
plugin:application-auth:update
plugin:application-auth:read
plugin:application-auth:reset-secret
```
按钮节点:
- `type` 使用 `3`。
- `is_show` 使用 `0`。
- `path`、`component`、`icon` 通常为 `null`。
- `methods` 与接口方法保持一致。
## 迁移执行流程
当前项目没有 Laravel `artisan` 文件,不使用:
```bash
php artisan migrate
php artisan migrate:status
```
当前项目使用:
```bash
php webman madong-migrate status
php webman madong-migrate up --dry-run
php webman madong-migrate up
```
### 执行前必须 dry-run
```bash
php webman madong-migrate up --dry-run
```
确认输出中将执行的迁移文件。
注意:
- `madong-migrate up` 会执行所有未执行迁移。
- 当前命令不支持 Laravel 的 `--path=` 单文件迁移参数。
- 如果只允许迁移单个文件,不要直接执行 `madong-migrate up`。
### 事务异常注意事项
如果执行迁移时出现:
```text
There is no active transaction
```
常见原因:
- MySQL DDL 会隐式提交事务。
- 迁移命令将多个 DDL 包在事务中,可能导致事务管理器提交时发现事务已结束。
处理流程:
1. 先不要重复执行迁移。
2. 检查数据表是否已经创建成功。
3. 执行 `php webman madong-migrate status` 查看迁移日志状态。
4. 如果表已创建但日志未写入,需要谨慎补齐迁移日志或修复迁移命令事务逻辑后再处理。
5. 不要盲目回滚或再次执行全部迁移,避免表已存在导致二次错误。
## 校验清单
### 后端校验
对新增 PHP 文件执行语法检查:
```bash
php -l app/model/{module}/{Model}.php
php -l app/dao/{module}/{Model}Dao.php
php -l app/service/admin/{module}/{Model}Service.php
php -l app/adminapi/validate/{module}/{Model}Validate.php
php -l app/adminapi/schema/request/{module}/{Model}FormRequest.php
php -l app/adminapi/schema/request/{module}/{Model}QueryRequest.php
php -l app/adminapi/schema/response/{module}/{Model}Response.php
php -l app/adminapi/controller/{module}/{Model}Controller.php
php -l resource/database/migrations/{migration_file}.php
php -l resource/data/menu/admin.php
```
### 前端校验
只检查新增文件:
```bash
pnpm exec eslint src/views/{module}/{feature}/index.vue src/views/{module}/{feature}/schemas/index.tsx src/api/{module}/{feature}/index.ts src/api/{module}/{feature}/types.ts
```
### 路径一致性校验
检查以下内容必须一致:
- 后端 Controller OpenAPI path。
- 前端 API `baseUrl`。
- 菜单 `path`。
- 菜单 `component`。
- 前端 view 文件路径。
- 权限码。
## Skill 自动进化规则
开发过程中如果发现 skill 与真实项目不一致,必须先更新 skill,再继续使用。
需要自动进化的典型情况:
- 迁移主键写法与项目不一致。
- 前端 API 模板导入路径不一致。
- 表单组件名不存在。
- CRUD 列类型与 TypeScript 类型不一致。
- 菜单权限结构与项目实际不一致。
- 路由路径或权限码规则与项目实际不一致。
更新要求:
- 只更新已验证的不一致点。
- 不做无关重写。
- 最终总结中说明更新了哪些 skill。
## 完整输出清单
完成一个 Admin 全栈 CRUD 功能后,应至少包含:
```text
backend/resource/database/migrations/{migration}.php
backend/app/model/{module}/{Model}.php
backend/app/dao/{module}/{Model}Dao.php
backend/app/service/admin/{module}/{Model}Service.php
backend/app/adminapi/validate/{module}/{Model}Validate.php
backend/app/adminapi/schema/request/{module}/{Model}FormRequest.php
backend/app/adminapi/schema/request/{module}/{Model}QueryRequest.php
backend/app/adminapi/schema/response/{module}/{Model}Response.php
backend/app/adminapi/controller/{module}/{Model}Controller.php
frontend/admin/src/api/{section}/{feature}/index.ts
frontend/admin/src/api/{section}/{feature}/types.ts
frontend/admin/src/views/{section}/{feature}/index.vue
frontend/admin/src/views/{section}/{feature}/schemas/index.tsx
backend/resource/data/menu/admin.php
```
## 最终回复模板
完成后向用户说明:
- 新增了哪些后端文件。
- 新增了哪些前端文件。
- 菜单和权限是否已配置。
- 迁移是否执行,执行结果如何。
- 校验命令和结果。
- 是否自动进化了 skill。
- 是否有需要用户后续处理的事项。