mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2026-06-06 20:18:10 +08:00
补充 v8 重构后的架构文档、组件说明和迁移记录,方便后续维护者理解插件边界。 主要内容: - 更新根 README,说明 v8 插件分层、系统模块、交付命令和验证流程。 - 新增组件明细、插件边界、路由分发、软删除和稳定性文档。 - 记录 Storage 合并到 System、旧 View 移除和 Helper 并入 System 的决策。 - 补充文档注释报告和后续重构计划,便于持续演进。
189 lines
7.6 KiB
Markdown
189 lines
7.6 KiB
Markdown
# Plugin Standard
|
|
|
|
## 当前结论
|
|
- `app/*` 负责本地多应用与过渡代码。
|
|
- `plugin/*` 负责插件业务实现。
|
|
- 插件分发优先于本地应用分发。
|
|
- 默认本地应用为 `app/index`。
|
|
|
|
插件标准由以下部分共同约束:
|
|
- `think\admin\Plugin`
|
|
- `think\admin\service\AppService`
|
|
- System 内置的 `plugin\system\helper\plugin\PluginMenuService`
|
|
- System 内置的 `plugin\system\helper\migration\PhinxExtend`
|
|
- `composer.json > extra.xadmin`
|
|
- `composer.json > extra.xadmin.publish.copy`
|
|
- 架构边界与安装边界测试
|
|
|
|
## 插件包标准
|
|
|
|
### 1. Composer 类型
|
|
- 参与运行时插件分发的组件统一使用 `think-admin-plugin`。
|
|
- 纯开发、交付辅助能力统一内置到 `ThinkPlugsSystem`,不再新增独立工具包。
|
|
- 安装协调组件 `ThinkPlugsInstall` 统一使用 `composer-plugin`,负责接管 Composer 生命周期内的自动发布与按需迁移。
|
|
|
|
### 2. 服务发现
|
|
- 必须通过 `extra.think.services` 注册插件服务类。
|
|
- 标准服务类命名为 `plugin\\{name}\\Service`。
|
|
|
|
### 3. 元数据
|
|
- `extra.xadmin.app` 只描述应用级元数据。
|
|
必填:`code`、`name`
|
|
可选:`prefix / prefixes / alias / space / document / description / platforms / license / icon / cover / super`
|
|
- `version`、`homepage` 等标准包字段继续使用 Composer 顶层定义,不再放到 `extra.xadmin.app`。
|
|
- `extra.xadmin.menu` 按需描述菜单显示、根节点、菜单项与存在性检测。
|
|
- `extra.xadmin.migrate` 按需描述主迁移脚本信息。
|
|
- `extra.xadmin.publish.copy` 按需描述资源发布规则,统一使用 `copy` 清单。
|
|
|
|
运行时插件最小 `composer.json` 骨架:
|
|
|
|
```json
|
|
{
|
|
"type": "think-admin-plugin",
|
|
"name": "vendor/demo-plugin",
|
|
"description": "Demo Plugin for ThinkAdmin",
|
|
"autoload": {
|
|
"psr-4": {
|
|
"plugin\\\\demo\\\\": "src"
|
|
}
|
|
},
|
|
"extra": {
|
|
"think": {
|
|
"services": [
|
|
"plugin\\\\demo\\\\Service"
|
|
]
|
|
},
|
|
"xadmin": {
|
|
"app": {
|
|
"code": "demo",
|
|
"name": "演示插件",
|
|
"prefix": "demo"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
纯工具组件可按需保留 `type=library`,并省略 `menu / migrate / publish` 等运行时块。
|
|
|
|
## 目录标准
|
|
|
|
### 1. 插件根目录
|
|
- `composer.json`
|
|
- `readme.md`
|
|
- `readme.api.md`
|
|
- `src`
|
|
- `stc`
|
|
- `tests`
|
|
|
|
### 2. 插件文档
|
|
- 每个插件根目录只保留两份说明文档:`readme.md` 与 `readme.api.md`。
|
|
- `readme.md` 只描述插件定位、边界、依赖与入口,不堆放接口明细、迁移细节或大段历史说明。
|
|
- `readme.api.md` 统一描述接口标准与接口列表。
|
|
- HTTP 插件在 `readme.api.md` 中按 `路由 + 请求方式 + 参数 JSONC` 组织,参数字段必须逐项写注释。
|
|
- HTTP 插件的 `readme.api.md` 必须补充标准 JSON 响应结构,至少说明 `code`、`info`、`data` 字段和常用状态码 `200/401/403/404/500`。
|
|
- 命令型或发布型组件在 `readme.api.md` 中按 `命令/配置入口 + 参数 JSONC` 组织,配置字段必须逐项写注释。
|
|
- 插件目录下不再追加第三份功能说明、临时接入文档或历史迁移说明,额外专题文档统一放到仓库 `docs/`。
|
|
|
|
### 3. `src` 根目录
|
|
- 必须保留 `Service.php`。
|
|
- 只有确实需要全局函数时才保留 `common.php`。
|
|
- 不再新增职责模糊的根级文件。
|
|
|
|
### 4. 常用子目录
|
|
- `controller`
|
|
- `model`
|
|
- `service`
|
|
- `view`
|
|
- `command`
|
|
- `lang`
|
|
- `worker`
|
|
- `tests`
|
|
|
|
## 运行时标准
|
|
|
|
### 1. 路由优先级
|
|
1. 先按插件前缀匹配。
|
|
2. 再按本地应用首段匹配。
|
|
3. 再按根目录全局路由目标声明匹配。
|
|
4. 再按动态插件切换匹配。
|
|
5. 最后回退到默认本地应用。
|
|
|
|
### 2. 标准入口
|
|
- 本地应用页面:`/{app}/{controller}/{action}`
|
|
- 插件页面:`/{plugin}/...`
|
|
- 插件接口:`/api/{plugin}/{controller}/{action}`
|
|
|
|
### 3. 根路由声明
|
|
- 优先使用 `Route::bindApp()` 与 `Route::bindPlugin()`。
|
|
- 分组场景使用 `Route::appGroup()` 与 `Route::pluginGroup()`。
|
|
- 根路由里的目标地址必须写成目标应用内部的相对节点。
|
|
|
|
### 4. 动态切换
|
|
- `_plugin` 与 `X-Plugin-App` 仅作为调试入口。
|
|
- 默认关闭,不作为正式业务路由依赖。
|
|
|
|
### 5. JSON 响应标准
|
|
- HTTP JSON 接口统一返回 HTTP `200`,前后端不再使用 `1/0` 表示成功或失败。
|
|
- 业务状态统一写入 `code` 字段,不再重复返回 `status`。
|
|
- `200` 表示成功,业务数据通过 `data` 返回。
|
|
- `401` 表示未认证、登录过期、令牌无效或会话失效。
|
|
- `403` 表示已认证但无权限、账号禁用或访问被拒绝。
|
|
- `404` 表示接口或资源不存在。
|
|
- `500` 表示服务端异常或未分类业务异常。
|
|
|
|
## 插件服务标准
|
|
|
|
### 1. 基类
|
|
- 参与运行时插件发现、路由或菜单元数据注入的服务统一继承 `think\admin\Plugin`。
|
|
- 纯命令或工具组件如不参与运行时插件装配,可继续继承 `think\Service`。
|
|
|
|
### 2. 职责
|
|
- 注册插件运行时能力。
|
|
- 处理必要的中间件或路由挂载。
|
|
- 承接 `composer.json` 中声明的插件元数据与发布规则。
|
|
- 纯工具组件只承接命令注册或工程化能力,不承担运行时插件装配职责。
|
|
|
|
### 3. 非职责
|
|
- 不在服务类中堆放业务逻辑。
|
|
- 不在服务类中维护大量兼容桥接代码。
|
|
- 不在服务类中声明运行时元数据字段或 `menu()` 之类的旧入口。
|
|
|
|
## 菜单与权限标准
|
|
- 菜单数据统一来自 `composer.json > extra.xadmin.menu.items`。
|
|
- 菜单引用的控制器节点必须真实存在。
|
|
- 叶子节点必须同时声明 `@auth true` 与 `@menu true`。
|
|
- 菜单写入前必须经过 `PluginMenuService::assertMenus()` 校验。
|
|
|
|
## 数据库与发布标准
|
|
- 每个插件只保留一份最终安装迁移脚本。
|
|
- 主迁移脚本以插件内 `stc/database` 为准。
|
|
- 自动迁移开关统一来自 `composer.json > extra.xadmin.migrate`;未声明时只能提示,不能在 Composer 安装链路中强制建表。
|
|
- 发布资源统一来自 `composer.json > extra.xadmin.publish.copy`。
|
|
- 发布规则只保留 `copy`,结构化规则统一使用 `source: { to, force, exclude }` 或 `{ from, to, force, exclude }`。
|
|
- 自动发布与按需迁移统一由 `zoujingli/think-plugs-install` Composer plugin 驱动,根项目需通过 `config.allow-plugins` 显式允许。
|
|
- 首次 Composer 安装只执行发布,不自动建表;后续变更才依据 `extra.xadmin.migrate` 做自动迁移。
|
|
- 根目录 `database/migrations` 视为发布产物,不是主维护源。
|
|
- 共享表必须遵守固定归属,不允许多插件重复持有。
|
|
|
|
## 依赖标准
|
|
- 本地插件依赖统一走 Composer `path` repository。
|
|
- 依赖图必须尽量保持无环。
|
|
- `ThinkPlugsSystem` 可以依赖 `library / static / worker`,并内置 storage 与 helper 能力。
|
|
- 业务插件不应重新把共享基础能力耦回 `system` 或 `library`。
|
|
|
|
## 测试要求
|
|
- 新增插件必须通过安装边界、路由边界、目录边界和迁移边界测试。
|
|
- 菜单、入口、迁移和 URL 规则必须有最小回归覆盖。
|
|
|
|
## 新插件准入清单
|
|
1. 提供独立 `composer.json`。
|
|
2. 提供 `src/Service.php`。
|
|
3. 在 `extra.xadmin.app` 中声明 `code / prefix / name`。
|
|
4. 有后台菜单时,在 `extra.xadmin.menu` 中声明菜单元数据。
|
|
5. 需要发布资源时,在 `extra.xadmin.publish.copy` 中声明规则。
|
|
6. 需要安装表结构时,在 `stc/database` 中保留唯一主迁移脚本,并通过 `extra.xadmin.migrate` 声明主脚本。
|
|
7. 运行时插件服务继承 `think\admin\Plugin`;纯工具组件按需继承 `think\Service`。
|
|
8. 不在 `Service.php` 中声明元数据字段或 `menu()` 兼容入口。
|
|
9. 补齐最小安装与路由测试。
|