--- 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。 - 是否有需要用户后续处理的事项。