280 lines
7.8 KiB
Markdown
280 lines
7.8 KiB
Markdown
---
|
||
description: Madong 插件全流程开发执行工作流
|
||
---
|
||
|
||
# 插件开发执行 Workflow
|
||
|
||
用于按步骤执行一个 Madong 插件的完整开发流程,覆盖需求确认、目录核对、后端 CRUD、Swagger、菜单、前端模板源、安装验证,以及卸载重装防回退验证。
|
||
|
||
执行本 workflow 前,优先参考:
|
||
|
||
- `.windsurf/skills/cross-plugin-fullstack-development/SKILL.md`
|
||
|
||
## Step 1. 明确输入信息
|
||
|
||
先向用户确认以下信息,不完整时不要直接生成代码:
|
||
|
||
- 插件名,例如 `article`
|
||
- 插件显示名称
|
||
- 插件 key / 业务目录名
|
||
- 需要开发的模块列表,例如 `content`、`category`、`tag`
|
||
- 每个模块的数据库表名
|
||
- 字段定义、索引、是否软删除
|
||
- 后端路由前缀
|
||
- 权限码前缀
|
||
- 是否需要前台 API
|
||
- 是否需要菜单导入
|
||
- 是否要求卸载再安装后仍保留最新前端结构
|
||
|
||
如果用户给的是表结构或截图,先整理成统一规格后再继续。
|
||
|
||
## Step 2. 核对现有插件与参考实现
|
||
|
||
优先读取并核对以下路径:
|
||
|
||
- `backend/plugin/{plugin}/app`
|
||
- `backend/plugin/{plugin}/config`
|
||
- `backend/plugin/{plugin}/resource/menu`
|
||
- `backend/plugin/{plugin}/resource/template/admin`
|
||
- `.windsurf/skills/cross-plugin-fullstack-development/SKILL.md`
|
||
|
||
同时寻找至少一个真实参考实现:
|
||
|
||
- 同类已完成插件
|
||
- 主项目现有 `BasicCrud` 页面
|
||
- 现有 CRUD 控制器
|
||
- 现有插件菜单与语言文件
|
||
|
||
如果发现 skill 与真实项目结构不一致,先修正 skill,再继续开发。
|
||
|
||
## Step 3. 建立开发计划
|
||
|
||
将任务拆成 3 到 5 个里程碑,并保持只有一个 `in_progress`:
|
||
|
||
- 后端结构与数据层
|
||
- 控制器、Swagger 与菜单
|
||
- 前端模板源开发与安装验证
|
||
- 重装验证与收口
|
||
|
||
如任务只是补模板源或补语言文件,可用更轻量计划。
|
||
|
||
## Step 4. 搭建或核对后端数据层
|
||
|
||
按模块逐项处理:
|
||
|
||
1. 迁移文件
|
||
2. Model
|
||
3. DAO
|
||
4. Service
|
||
5. Validate
|
||
6. Request / Response Schema
|
||
|
||
检查点:
|
||
|
||
- 主键是否使用项目当前雪花 ID 写法
|
||
- 字段、索引、软删除是否与需求一致
|
||
- DAO / Service / Validate 基类是否与项目一致
|
||
- 命名空间是否在插件路径下正确展开
|
||
- DAO / Service 是否显式导入 `core\base\BaseDao` / `core\base\BaseService`
|
||
- Service 是否使用构造注入 DAO,而不是手动 `new Dao()`
|
||
- 如 DAO 重写 `selectList()`,方法签名是否与当前项目 `BaseDao` 一致
|
||
- 如果模块来自旧项目迁移,是否已确认当前项目是否仍需要 `tenant_id`
|
||
|
||
## Step 5. 实现 Admin 控制器与标准 CRUD 路由
|
||
|
||
为每个模块实现 Admin 控制器,并保证:
|
||
|
||
- 继承 `app\adminapi\controller\Crud`
|
||
- 构造函数注入 Service 与 Validate
|
||
- 标准方法优先复用父类
|
||
- 路由前缀与前端 API 一致
|
||
- 权限码与菜单按钮权限一致
|
||
|
||
如存在旧 demo 控制器,先确认是否会与新 CRUD 冲突。
|
||
|
||
## Step 6. 处理 Swagger / OpenAPI
|
||
|
||
在继续前端之前,必须先排除 Swagger 冲突。
|
||
|
||
逐项核对:
|
||
|
||
- 新旧控制器是否使用重复 `path`
|
||
- `OA\Get`、`OA\Post`、`OA\Put`、`OA\Delete` 是否唯一
|
||
- QueryRequest / FormRequest / Response Schema 是否对应
|
||
- 批量删除、详情、列表等接口注解是否与项目现有写法一致
|
||
|
||
如果旧演示接口与新接口冲突:
|
||
|
||
- 改到 `legacy` 路径
|
||
- 或迁移到单独演示控制器
|
||
- 不要直接删除未经确认的旧内容
|
||
|
||
## Step 7. 配置插件菜单与权限
|
||
|
||
核对并维护:
|
||
|
||
- `backend/plugin/{plugin}/resource/menu/admin.php`
|
||
- 菜单 `component` 路径
|
||
- 菜单 `app` 字段
|
||
- 权限码与控制器一致性
|
||
|
||
必须保证:
|
||
|
||
- 插件菜单来源于安装导入的系统菜单
|
||
- 不依赖前端自动扫描插件 routes 作为导航入口
|
||
- `component` 指向插件 views 实际路径
|
||
|
||
## Step 8. 在模板源实现前端
|
||
|
||
正式开发目录应放在:
|
||
|
||
- `backend/plugin/{plugin}/resource/template/admin/api`
|
||
- `backend/plugin/{plugin}/resource/template/admin/views`
|
||
- `backend/plugin/{plugin}/resource/template/admin/lang`
|
||
|
||
按模块实现:
|
||
|
||
1. `api/index.ts`
|
||
2. `views/{plugin_key}/{module}/index.vue`
|
||
3. `views/{plugin_key}/{module}/schemas/index.tsx`
|
||
4. `lang/zh-cn/zh.json`
|
||
5. `lang/en/en.json`
|
||
|
||
要求:
|
||
|
||
- 页面入口统一使用 `BasicCrud`
|
||
- `schemas` 使用 `CrudSchema`
|
||
- 标准接口优先接 `BaseService`
|
||
- i18n key 中英文成对补齐
|
||
- 表头索引等公共 key 必须统一
|
||
- 默认不要单独开发 `frontend/admin/src/apps/{plugin}`
|
||
- 通过安装流程生成运行目录并验证结果,而不是双份维护
|
||
|
||
## Step 9. 安装插件并生成运行目录
|
||
|
||
当模板源完成后,安装插件或执行相应同步流程,确认以下目录被生成或更新:
|
||
|
||
- `frontend/admin/src/apps/{plugin}/api`
|
||
- `frontend/admin/src/apps/{plugin}/views`
|
||
- `frontend/admin/src/apps/{plugin}/lang`
|
||
|
||
如果运行目录已存在旧文件,重点检查是否已被模板源最新内容覆盖。
|
||
|
||
## Step 10. 基于安装结果验证页面
|
||
|
||
联调时重点检查:
|
||
|
||
- 页面是否为官方 `BasicCrud` 外观
|
||
- 列表接口返回是否与 `items/total` 结构兼容
|
||
- 增删改查是否可用
|
||
- 查询参数是否与后端真实支持格式一致
|
||
- 中英文是否存在缺词
|
||
- 菜单点击是否能打开正确页面
|
||
- `format=select` 下拉是否能显示正确标签;若不显示,优先检查模型是否提供 `getNameAttribute()`
|
||
- JSON 规则字段是否支持前端 textarea 文本输入与后端数组/字符串双形态校验
|
||
|
||
默认不要直接修改运行目录。
|
||
只有在用户明确要求排查安装产物问题时,才临时查看或修补运行目录,并且必须把最终改动落实回模板源。
|
||
|
||
## Step 11. 执行模板源一致性检查
|
||
|
||
在交付前强制执行以下比对:
|
||
|
||
- 安装生成后的运行目录是否与模板源一致
|
||
- `index.vue` 是否按模板源生成
|
||
- `schemas/index.tsx` 是否按模板源生成
|
||
- `api/index.ts` 是否按模板源生成
|
||
- `lang/zh-cn/zh.json` 是否按模板源生成
|
||
- `lang/en/en.json` 是否按模板源生成
|
||
|
||
只改运行目录但未落实模板源,不算完成。
|
||
|
||
## Step 12. 卸载再安装验证
|
||
|
||
若用户明确要求“重装后不要回退”,必须做这一步。
|
||
|
||
验证目标:
|
||
|
||
- 卸载插件后重新安装
|
||
- 确认模板源再次复制到运行目录后,页面仍是最新结构
|
||
- 确认未回退到旧 demo 样式
|
||
- 确认菜单、权限、Swagger 依旧正常
|
||
|
||
如果没有时间完整执行,也要明确告诉用户:
|
||
|
||
- 当前完成的是代码层同步
|
||
- 仍建议再做一次卸载重装验证
|
||
|
||
## Step 13. 收口与交付
|
||
|
||
最终汇报时至少说明:
|
||
|
||
- 改了哪些后端文件
|
||
- 改了哪些模板源文件
|
||
- 是否通过安装方式验证了运行目录产物
|
||
- 是否补齐了菜单与语言
|
||
- 是否处理了 Swagger 冲突
|
||
- 是否完成重装防回退验证
|
||
- 是否顺手更新了相关 skill
|
||
|
||
## Step 14. 常见二次排错顺序
|
||
|
||
当插件页面已打开但接口返回 500 时,优先按以下顺序排查:
|
||
|
||
1. Service 是否显式导入 `core\base\BaseService`
|
||
2. DAO 是否显式导入 `core\base\BaseDao`
|
||
3. Service 是否错误地手动 `new Dao()`
|
||
4. DAO 重写方法签名是否与当前 `BaseDao` 一致
|
||
5. 模型关联名是否与 DAO `with([...])` 一致
|
||
6. Validate 对 JSON 字段和枚举字段的写法是否与当前项目兼容
|
||
|
||
## 常见分支处理
|
||
|
||
### 分支 A. 仅修复插件前端页面样式
|
||
|
||
执行:
|
||
|
||
- Step 2
|
||
- Step 3
|
||
- Step 8
|
||
- Step 9
|
||
- Step 10
|
||
- Step 11
|
||
- Step 13
|
||
|
||
### 分支 B. 仅修复重装后回退
|
||
|
||
执行:
|
||
|
||
- Step 2
|
||
- Step 3
|
||
- Step 8
|
||
- Step 11
|
||
- Step 12
|
||
- Step 13
|
||
|
||
### 分支 C. 修复 Swagger 冲突
|
||
|
||
执行:
|
||
|
||
- Step 2
|
||
- Step 3
|
||
- Step 5
|
||
- Step 6
|
||
- Step 13
|
||
|
||
### 分支 D. 新建完整插件模块
|
||
|
||
执行全部步骤。
|
||
|
||
## 完成判定
|
||
|
||
满足以下条件,才可判定“插件开发完成”:
|
||
|
||
- 后端 CRUD 可运行
|
||
- Swagger 无冲突
|
||
- 菜单与权限可用
|
||
- 模板源前端完整
|
||
- 运行目录联调通过
|
||
- 用户要求重装防回退时,已完成重装验证或已明确说明未验证部分
|