初始化本地仓库
This commit is contained in:
@@ -0,0 +1,476 @@
|
||||
---
|
||||
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。
|
||||
- 是否有需要用户后续处理的事项。
|
||||
Reference in New Issue
Block a user