ThinkAdmin/docs/architecture/plugin-standard.md
Anyon 6f4056f64d docs(architecture): 完善 v8 架构与迁移说明
补充 v8 重构后的架构文档、组件说明和迁移记录,方便后续维护者理解插件边界。

主要内容:

- 更新根 README,说明 v8 插件分层、系统模块、交付命令和验证流程。

- 新增组件明细、插件边界、路由分发、软删除和稳定性文档。

- 记录 Storage 合并到 System、旧 View 移除和 Helper 并入 System 的决策。

- 补充文档注释报告和后续重构计划,便于持续演进。
2026-05-08 15:31:22 +08:00

7.6 KiB

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 只描述应用级元数据。 必填:codename 可选:prefix / prefixes / alias / space / document / description / platforms / license / icon / cover / super
  • versionhomepage 等标准包字段继续使用 Composer 顶层定义,不再放到 extra.xadmin.app
  • extra.xadmin.menu 按需描述菜单显示、根节点、菜单项与存在性检测。
  • extra.xadmin.migrate 按需描述主迁移脚本信息。
  • extra.xadmin.publish.copy 按需描述资源发布规则,统一使用 copy 清单。

运行时插件最小 composer.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.mdreadme.api.md
  • readme.md 只描述插件定位、边界、依赖与入口,不堆放接口明细、迁移细节或大段历史说明。
  • readme.api.md 统一描述接口标准与接口列表。
  • HTTP 插件在 readme.api.md 中按 路由 + 请求方式 + 参数 JSONC 组织,参数字段必须逐项写注释。
  • HTTP 插件的 readme.api.md 必须补充标准 JSON 响应结构,至少说明 codeinfodata 字段和常用状态码 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. 动态切换

  • _pluginX-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 能力。
  • 业务插件不应重新把共享基础能力耦回 systemlibrary

测试要求

  • 新增插件必须通过安装边界、路由边界、目录边界和迁移边界测试。
  • 菜单、入口、迁移和 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. 补齐最小安装与路由测试。