Files
RuoYi-Vue3-FastAPI/ruoyi-fastapi-backend/docs/plugin_development.md
T
insistence 2a055ba648 feat: 新增插件系统 (#112)
* feat: 初始化插件系统

* refactor: 收口插件系统运行时重构

* perf: 优化插件系统类型提示

* fix&perf: 修复和优化插件系统

* fix: 修复gitignore规则误忽略插件文件的问题

* fix: 修复运行时插件根路径算错的问题

* fix: 加强插件发现和路由注册的防护措施

* revert: 回滚定时任务白名单

* fix: 移除未使用的应用路由注册探测

* revert: 恢复部分代码

* perf: 优化插件系统

* docs: 新增插件开发文档

* perf: 优化插件管理模块

* perf: 提升插件系统核心能力

* refactor: 重构生命周期 step runner

* fix: 修复lint错误

* test: 清理测试用例

* test: 调整测试目录名称

* fix: 修复前后端目录硬编码的问题

* fix: 修复插件系统安全性缺口

* refactor: 重新设计插件生命周期 Migration 事务与回滚

* perf: 优化插件系统边界问题

* refactor: 重构当前插件系统的依赖体系设计

* perf: 优化代码

* perf: 优化代码

* fix: 修复代码合并问题

* fix: 修复bug

* perf: 优化代码

* perf&fix: 优化代码和修复bug

* docs: 优化文档格式

* feat: 适配Vue2版本

* docs: 更新README文档

* fix: 修复ruff lint错误

* chore: 更新后端依赖文件
2026-07-28 20:35:18 +08:00

30 KiB
Raw Blame History

插件开发手册

本文档面向插件开发者,说明如何在当前插件系统中创建、安装、启用、调试和发布插件。

1. 基本模型

插件由后端插件和可选前端插件组成。默认源码布局如下:

ruoyi-fastapi-backend/plugins/<plugin_id>/
ruoyi-fastapi-frontend/plugins/<plugin_id>/

运行时不会把前后端仓库名写死在各操作入口中。插件系统优先使用显式传入的目录,其次读取 RUOYI_PLUGIN_BACKEND_ROOT/RUOYI_BACKEND_ROOTRUOYI_PLUGIN_FRONTEND_ROOT/RUOYI_FRONTEND_ROOT,再尝试从后端同级目录中识别前端工程; 最后才按后端目录名把 backend 推断为 frontend。非默认目录名的项目,应优先配置上述环境变量或在运行时注入目录。

后端插件必须包含 plugin.yaml。插件发现、安装、菜单、依赖、配置、迁移、种子数据和定时任务都以这个文件为入口。

plugin.yaml 只描述插件能力和资源。安装、启用、停用、升级等运行态由管理端或 CLI 生命周期命令维护;生命周期状态只使用 discoveredinstalledpending_upgradeerror

2. 快速开始

进入后端项目目录:

cd ruoyi-fastapi-backend

使用脚手架创建插件:

ruoyi plugin create demo --env=dev --template=full-stack

脚手架默认使用 --frontend-version=auto,会读取目标前端 package.jsonvue 依赖,并自动生成 Vue 2Element UI、Options API、CommonJS 测试)或 Vue 3Element Plus、Composition API、ESM 测试)模板。通常无需传参;识别失败或需要覆盖时可显式指定:

ruoyi plugin create demo --env=dev --template=crud-page --frontend-version=vue2
ruoyi plugin create demo --env=dev --template=crud-page --frontend-version=vue3

后端实现应在 Vue 2/3 项目间保持一致。plugin.yaml 通常只声明两个前端都使用的业务依赖;如果插件确实依赖不同的 Vue 绑定库或构建插件,允许各项目保留不同清单,但应分别提供 Vue 2/3 测试,并根据目标前端 package.json 自动选择执行。

常用模板:

  • minimal:最小插件。
  • backend-only:只生成后端插件。
  • full-stack:生成后端和前端插件。
  • scheduled-job:包含定时任务示例。
  • crud-page:包含 CRUD 页面示例。

先预览写入计划:

ruoyi plugin create demo --env=dev --template=full-stack --dry-run

开发过程常用命令:

ruoyi plugin check demo --env=dev
ruoyi plugin check-deps demo --env=dev
ruoyi plugin allowlist-example --env=dev --dry-run
ruoyi plugin allowlist-example --env=dev --output-path config/plugin_dependency_allowlist.yaml --overwrite
ruoyi plugin lock-deps demo --env=dev --dry-run
ruoyi plugin lock-deps demo --env=dev --offline-dir artifacts/plugin-dependencies --overwrite
ruoyi plugin install-deps demo --env=dev --dry-run
ruoyi plugin install-deps demo --env=dev --yes
ruoyi plugin install demo --env=dev --yes
ruoyi plugin enable demo --env=dev --yes
ruoyi plugin health demo --env=dev
ruoyi plugin test demo --env=dev

3. 目录结构

推荐后端结构:

plugins/demo/
  plugin.yaml
  controller/
    demo_controller.py
  service/
    demo_service.py
  dao/
  entity/
    do/
    vo/
  hooks.py
  jobs.py
  migrations/
    mysql/001_init.sql
    postgresql/001_init.sql
  seeds/
    mysql/001_seed.sql
    postgresql/001_seed.sql
  README.md

推荐前端结构:

<frontend-project>/plugins/demo/
  api/
    demo.js
  views/
    index.vue
  README.md

后端 Python 模块路径必须与插件 ID 对齐。例如插件 ID 为 demo 时,backend.module 必须是 plugins.demo

4. plugin.yaml 示例

manifestVersion: 1
id: demo
name: 演示插件
version: 0.1.0
description: Demo plugin.

metadata:
  category: demo
  tags:
    - demo
    - sample
  author: RuoYi
  license: MIT
  homepage: ""
  repository: ""
  documentation: ""

backend:
  module: plugins.demo
  routers:
    autoScan: true
  migrations:
    - migrations/mysql/001_init.sql
    - migrations/postgresql/001_init.sql
  seeds:
    - seeds/mysql/001_seed.sql
    - seeds/postgresql/001_seed.sql
  hooks:
    onInstall: plugins.demo.hooks:on_install
    onStartup: plugins.demo.hooks:on_startup
  jobs:
    - id: cleanup
      name: 演示清理任务
      callable: plugins.demo.jobs.cleanup
      trigger: cron
      cronExpression: "0 0 * * * ?"
      enabled: true
      misfirePolicy: "3"
      concurrent: "1"

frontend:
  basePath: demo
  pluginId: demo
  viewsPath: views
  apiPath: api
  delivery:
    type: source
    buildRequired: true
  menus:
    - name: 演示插件
      path: demo
      component: Layout
      perms: ""
      type: M
      orderNum: 10
      icon: example
      children:
        - name: 演示页面
          path: index
          component: plugin/demo/index
          routeName: DemoIndex
          query: ""
          isFrame: 1
          isCache: 0
          perms: demo:list
          type: C
          orderNum: 1

permissions:
  - code: demo:list
    name: 演示列表
    description: 查看演示页面
  - code: demo:add
    name: 新增演示
  - code: demo:edit
    name: 修改演示
  - code: demo:remove
    name: 删除演示

dependencies:
  python:
    - requests>=2.32.0
  npm:
    - dayjs>=1.11.0
  npmDev: []
  plugins:
    - id: ai
      version: ">=0.1.0"
      description: 依赖 AI 插件能力

compatibility:
  databases:
    - mysql
    - postgresql

config:
  items:
    - key: api_url
      label: API 地址
      type: string
      default: ""
      required: true
    - key: audit_log
      label: 记录日志
      type: boolean
      default: true

注意事项:

  • id 只能使用小写字母、数字、下划线和中划线,并且必须以小写字母开头。
  • adminsystemmonitortool 是保留插件 ID。
  • permissions 中必须声明菜单使用到的权限标识。
  • 菜单权限格式使用小写冒号分隔,例如 demo:list
  • 插件组件路径必须使用 plugin/<plugin_id>/<view_path>

5. plugin.yaml 参数说明

5.1 顶层字段

字段 类型 默认值 说明
manifestVersion number 1 插件清单版本。当前支持 1
id string 必填 插件唯一标识。只能包含小写字母、数字、下划线和中划线,长度 2-64,必须以小写字母开头。不能使用 adminsystemmonitortool
name string 必填 插件展示名称。
version string 必填 插件源码版本,用于安装版本记录和升级判断。
description string "" 插件说明。
metadata object {} 插件展示元数据。
backend object 必填 后端能力声明。
frontend object {} 前端资源、菜单和交付声明。
permissions object[] | string[] [] 插件权限声明列表。推荐对象写法;字符串简写会按 code 处理。
dependencies object {} Python、npm 和插件间依赖声明。
compatibility object {} 平台兼容性版本约束。
resources object {} 插件静态、上传、临时资源目录声明。
config object {} 插件配置项声明。

5.2 metadata

字段 类型 默认值 说明
category string "" 插件分类。
tags string[] [] 插件标签,不能重复。
author string "" 插件作者。
license string "" 插件许可证。
homepage string "" 插件主页地址。
repository string "" 插件代码仓库地址。
documentation string "" 插件文档地址。

5.3 backend

字段 类型 默认值 说明
module string 必填 插件后端 Python 模块路径,必须是 plugins.<plugin_id>
routers object { autoScan: true } 控制器自动扫描声明。
health object {} 健康检查声明。
migrations string[] [] 数据库迁移 SQL 脚本相对路径列表。
seeds string[] [] 初始化数据 SQL 脚本相对路径列表。
hooks object {} 生命周期钩子声明。
jobs object[] [] 插件定时任务声明。

backend.routers

字段 类型 默认值 说明
autoScan boolean true 是否按插件模块自动扫描并注册控制器。

backend.health

字段 类型 默认值 说明
checker string | null null 健康检查 callable,格式为 <module_path>:<callable_name>,例如 plugins.demo.health:check

backend.hooks

字段 类型 默认值 说明
onInstall string | null null 插件安装完成后的钩子。
onUpgrade string | null null 插件升级完成后的钩子。
onStartup string | null null 应用启动加载插件时执行的钩子。
onShutdown string | null null 应用关闭插件时执行的钩子。
onPurge string | null null 插件物理清理时执行的钩子。

钩子路径格式统一为 <module_path>:<callable_name>,例如 plugins.demo.hooks:on_startup

backend.jobs[]

字段 类型 默认值 说明
id string 必填 插件内任务唯一标识。只能包含小写字母、数字、下划线和中划线,必须以小写字母开头。
name string | null id 任务展示名称。
callable string 必填 任务函数路径,格式为 <module_path>.<callable_name>
trigger "cron" "cron" 任务触发器类型。
cronExpression string 必填 cron 表达式,不能为空。
args string[] [] 位置参数列表。
kwargs object {} 关键字参数。
enabled boolean true 任务安装后的默认状态。
description string "" 任务说明。
misfirePolicy "1" | "2" | "3" "3" 计划执行错误策略。1 立即执行,2 执行一次,3 放弃执行。
concurrent "0" | "1" "1" 是否允许并发执行。0 允许,1 禁止。
executor "default" | "processpool" "default" 任务执行器。

5.4 frontend

字段 类型 默认值 说明
pluginId string | null id 前端插件目录名,必须与插件 ID 一致。
basePath string | null id 前端基础路径。只能包含小写字母、数字、下划线、中划线和正斜杠。
viewsPath string "views" 前端视图目录。
apiPath string "api" 前端 API 目录。
delivery object {} 前端交付声明。
menus object[] [] 插件菜单树。

frontend.delivery

字段 类型 默认值 说明
type "none" | "source" "none" 前端交付类型。存在菜单或 npm 依赖时会自动按源码交付处理。
buildRequired boolean false 前端资源是否需要构建后生效。源码交付时会自动视为需要构建。

frontend.menus[]

字段 类型 默认值 说明
name string 必填 菜单名称。
path string 必填 菜单路由路径。普通菜单只能包含小写字母、数字、下划线、中划线和正斜杠,必须以小写字母开头;外链菜单必须使用 http://https:// 地址。
component string "Layout" 组件路径。核心组件允许 LayoutParentViewInnerLink;插件页面使用 plugin/<plugin_id>/<view_path>
perms string "" 权限标识。非空时必须在顶层 permissions 中声明。
icon string "#" 菜单图标。
type "M" | "C" | "F" "C" 菜单类型。M 目录,C 菜单,F 按钮。
orderNum number 0 菜单排序值。
query string | null null 路由参数。
routeName string | null null 路由名称。
isFrame 0 | 1 1 是否为外链。沿用系统菜单字段约定,0 是,1 否。
isCache 0 | 1 0 是否缓存。沿用系统菜单字段约定,0 缓存,1 不缓存。
visible "0" | "1" "0" 菜单是否显示。沿用系统菜单字段约定。
status "0" | "1" "0" 菜单状态。沿用系统菜单字段约定。
children object[] [] 子菜单列表,结构同 frontend.menus[]

5.5 permissions

permissions 是插件声明的权限列表。菜单 perms 使用到的权限必须出现在这里。

permissions:
  - code: demo:list
    name: 演示列表
    description: 查看演示页面
  - code: demo:add
    name: 新增演示

也支持字符串简写:

permissions:
  - demo:list
  - demo:add

permissions[]

字段 类型 默认值 说明
code string 必填 权限标识。也兼容使用 permspermission 字段名。
name string | null null 权限展示名称。未显式声明为菜单的权限会自动生成按钮菜单,此字段会作为按钮菜单名称。
description string "" 权限说明。

要求:

  • 权限不能重复。
  • 权限格式为小写冒号分隔,例如 demo:listdemo:item:add

5.6 dependencies

字段 类型 默认值 说明
python string[] [] Python 依赖声明,例如 requests>=2.32.0
npm string[] [] 前端运行依赖声明,例如 dayjs>=1.11.0
npmDev string[] [] 前端开发依赖声明。
plugins object[] [] 插件间依赖声明。

dependencies.plugins[] 支持对象写法:

字段 类型 默认值 说明
id string 必填 依赖插件 ID。
version string | null null 依赖插件版本约束,例如 >=1.0.0
description string "" 依赖说明。

也支持字符串简写:

dependencies:
  plugins:
    - ai>=0.1.0

5.7 compatibility

字段 类型 默认值 说明
backendVersion string | null null 后端版本约束。
frontendVersion string | null null 前端版本约束。
pythonVersion string | null null Python 版本约束。
nodeVersion string | null null Node.js 版本约束。
databases ("mysql" | "postgresql")[] [] 插件支持的数据库类型声明,不能重复。

版本约束可以是版本号,也可以带比较操作符,例如 >=3.10^20.0.0

5.8 resources

字段 类型 默认值 说明
static string[] [] 插件静态资源相对路径列表。
uploads string[] [] 插件上传资源相对路径列表。
temp string[] [] 插件临时资源相对路径列表。

资源路径只能使用安全相对路径,不能重复。

5.9 config

config 推荐使用 items 写法:

config:
  items:
    - key: api_url
      label: API 地址
      type: string
      default: ""

也支持列表写法:

config:
  - key: api_url
    label: API 地址
    default: ""

也支持对象简写:

config:
  api_url:
    label: API 地址
    default: ""
  timeout_seconds: 30

config.items[]

字段 类型 默认值 说明
key string 必填 配置键。只能包含小写字母、数字、下划线、中划线和点号,必须以小写字母开头。
label string | null key 配置展示名称。
type string "string" 配置类型。支持 stringnumberbooleanselecttextareapasswordjsontext 会按 string 处理,switch 会按 boolean 处理。
default JSON 值 null 默认值。支持字符串、数字、布尔、对象、数组和 nullbooleannumberjson 会校验默认值类型。
required boolean false 是否必填。更新配置时会校验非空;必填但无默认值会产生检查提示。
group string "default" 配置分组,会作为配置元数据返回。
order number 0 配置排序值,会作为配置元数据返回。
placeholder string "" 输入占位提示,会作为配置元数据返回。
min number | null null 数字配置最小值,仅 number 类型更新时生效。
max number | null null 数字配置最大值,仅 number 类型更新时生效。
pattern string | null null 字符串、文本、密码配置的正则校验表达式,仅 stringtextareapassword 类型更新时生效。
description string "" 配置说明,会在管理端配置表单中作为帮助文本展示。
options object[] [] select 类型选项列表,仅 select 类型生效。
secret boolean false 是否敏感配置。敏感配置导出时默认不输出明文。

config.items[].options[]

字段 类型 默认值 说明
label string 必填 选项展示名称。
value JSON 值 必填 选项值。

select 类型必须声明 options,并且 default 必须位于 options.value 中。

配置校验和展示规则:

  • password 类型建议同时声明 secret: true,便于输入、导出和审计时统一脱敏。
  • secret: true 的配置不建议声明非空默认值。
  • required: true 会在更新配置时校验非空。
  • minmax 只对 number 生效,其他类型声明后会产生检查提示。
  • pattern 只对 stringtextareapassword 生效,其他类型声明后会产生检查提示。
  • options 只对 select 生效,其他类型声明后会产生检查提示。
  • grouporderplaceholder 会进入配置接口和导出元数据,可供插件自定义页面消费。

6. 后端开发约定

6.1 控制器

应用启动时会按 backend.module 自动扫描已启用插件的控制器。推荐将接口放在 controller/ 目录,并保持与项目原有 FastAPI 控制器风格一致。

后端插件路由采用启动期挂载模型:

  • 新启用插件的后端 controller 需要重启应用后才会挂载到当前 FastAPI app。
  • 停用插件后,已挂载的插件路由仍保留在 app 路由表中,但请求会经过插件启用状态依赖拦截。
  • 插件 controller 的 prefix 必须位于当前插件命名空间内,例如 /demo/demo/items/plugin/demo/plugin/demo/items,不能占用 /system/monitor 等平台核心路径。

示例:

from fastapi import APIRouter

demo_controller = APIRouter(prefix='/demo', tags=['demo'])


@demo_controller.get('/ping')
async def ping():
    return {'code': 200, 'msg': 'success', 'data': 'pong'}

控制器对象需要能被自动扫描发现,命名上建议延续现有 xxx_controller 风格。

6.2 数据模型、DAO 和 Service

插件业务代码尽量放在插件目录内:

  • entity/do/:数据库模型。
  • entity/vo/:请求和响应模型。
  • dao/:数据库访问。
  • service/:业务编排。

插件代码可以复用项目已有的数据库 session、响应模型、权限装饰器和工具函数,但不要修改核心模块来服务单个插件。确实需要通用能力时,先沉淀到 plugins/core 或项目公共层。

6.3 Migration 和 Seed

backend.migrationsbackend.seeds 支持声明 SQL 脚本。推荐按数据库方言拆分目录:

migrations/mysql/001_init.sql
migrations/postgresql/001_init.sql
seeds/mysql/001_seed.sql
seeds/postgresql/001_seed.sql

要求:

  • migration 用于表结构。
  • seed 用于字典、默认配置等初始化数据。
  • migration 和 seed 都必须可重复执行。MySQL DDL 会隐式提交,后续 hook 或状态写入失败时平台无法自动回滚已应用的结构变更。
  • migration 执行前会先记录 status=running;成功后记录 status=success;失败后记录 status=failed 和错误摘要。
  • running 表示上次执行已开始但未记录成功或失败,平台会阻断自动重跑,需要人工确认数据库结构后标记为成功或失败。
  • migration 成功历史只认 status=success;已成功执行的 migration 文件不能修改,checksum 变化时必须恢复原文件或新增后续 migration。
  • SQL migration 应优先使用 CREATE TABLE IF NOT EXISTS 等幂等写法;复杂 DDL、存储过程或需要条件判断的变更建议改用 Python migration。
  • SQL migration 应尽量拆小,避免单个文件包含大量不可回滚 DDL;ALTER TABLE、索引和初始化数据尤其要考虑重复执行安全。
  • SQL 文件路径必须位于插件目录内。
  • MySQL 和 PostgreSQL 差异较大时分别维护脚本。

故障恢复入口:

  • CLI 查看历史:ruoyi plugin migration-list <plugin_id> --status running
  • CLI 标记成功:ruoyi plugin mark-success <plugin_id> <migration_path> --note "已人工确认结构完成"
  • CLI 标记失败:ruoyi plugin mark-failed <plugin_id> <migration_path> --note "未完成,允许修复后重试"
  • Web 管理页:插件详情的“依赖 / 执行历史”中查看 migration 状态,并执行人工标记。

详细排障流程见 插件 Migration 故障处理手册

6.4 生命周期钩子

支持的钩子:

  • onInstall
  • onUpgrade
  • onStartup
  • onShutdown
  • onPurge

声明格式:

backend:
  hooks:
    onInstall: plugins.demo.hooks:on_install

钩子函数可以同步或异步,可以不接收参数,也可以接收 context

async def on_startup(context):
    if not context.startup_write_enabled:
        return
    # 只在启动期单写者中执行全局写操作

context 常用字段:

  • plugin_id
  • hook_name
  • discovered_plugin
  • app
  • query_db
  • startup_write_enabled

多 worker 启动时,所有 worker 都会加载运行时能力,但只有启动期单写者适合执行全局写操作。钩子里如果要写菜单、任务、配置、外部资源,应检查 context.startup_write_enabled

6.5 定时任务

定时任务在 backend.jobs 中声明:

jobs:
  - id: cleanup
    name: 清理任务
    callable: plugins.demo.jobs.cleanup
    trigger: cron
    cronExpression: "0 0 * * * ?"
    enabled: true
    misfirePolicy: "3"
    concurrent: "1"

callable 使用 <module_path>.<callable_name> 格式。任务会写入系统任务表,由调度器按原系统机制执行。

7. 前端开发约定

插件前端代码放在:

ruoyi-fastapi-frontend/plugins/<plugin_id>/

菜单组件路径和真实 Vue 文件的映射关系:

plugin/demo/index -> ruoyi-fastapi-frontend/plugins/demo/views/index.vue
plugin/demo/report/list -> ruoyi-fastapi-frontend/plugins/demo/views/report/list.vue

只允许两类组件值:

  • 核心布局组件:LayoutParentViewInnerLink
  • 插件视图组件:plugin/<plugin_id>/<view_path>

前端 API 建议放在 plugins/<plugin_id>/api/,视图放在 plugins/<plugin_id>/views/。插件页面不需要加入主工程内置路由,菜单安装后由后端返回动态路由,前端 resolver 会自动定位插件视图。

8. 配置项

插件配置写在 config.items 中。支持类型:

  • string
  • number
  • boolean
  • select
  • textarea
  • password
  • json

示例:

config:
  items:
    - key: provider
      label: 默认供应商
      type: select
      default: openai
      required: true
      options:
        - label: OpenAI
          value: openai
        - label: Mistral
          value: mistral
    - key: api_key
      label: API Key
      type: password
      default: ""
      secret: true

配置命令:

ruoyi plugin config demo get --env=dev
ruoyi plugin config demo set api_url=https://example.com --env=dev --yes
ruoyi plugin config demo export --env=dev --output-file=demo-config.json
ruoyi plugin config demo import --env=dev --input-file=demo-config.json --yes

敏感配置使用 secret: true,导出时默认不输出明文。

配置值会按类型进行序列化和反序列化:boolean 返回布尔值,number 返回数字,json 返回对象或数组。更新配置时,未在 plugin.yaml 中声明的配置键会被拒绝。

内置管理页会根据 type 渲染基础控件,支持必填校验、下拉选项、敏感输入和配置说明;更复杂的分组、排序或提示布局可以在插件自定义页面中消费配置元数据后自行实现。

9. 依赖管理

插件依赖声明在 dependencies 中:

  • pythonPython 包。
  • npm:前端运行依赖。
  • npmDev:前端开发依赖。
  • plugins:插件间依赖。

检查和安装:

ruoyi plugin check-deps demo --env=dev
ruoyi plugin allowlist-example --env=dev --dry-run
ruoyi plugin allowlist-example --env=dev --output-path config/plugin_dependency_allowlist.yaml --overwrite
ruoyi plugin lock-deps demo --env=dev --dry-run
ruoyi plugin lock-deps demo --env=dev --offline-dir artifacts/plugin-dependencies --overwrite
ruoyi plugin install-deps demo --env=dev --dry-run
ruoyi plugin install-deps demo --env=dev --yes

allowlist-example 按需生成插件依赖允许列表示例,默认输出到 config/plugin_dependency_allowlist.yaml;仓库不再默认携带 .example 文件。建议先用 --dry-run 查看模板,再写入正式 allowlist 并按团队实际批准范围调整。

lock-deps 默认生成锁文件模板,输出到 plugins/<plugin_id>/plugin.lock.yaml;如文件已存在,需要传 --overwrite 才会覆盖。默认模式不会联网解析真实版本,也不会写入 hash/integrity;如果传入 --offline-dir,命令会从已有本地 wheel/tgz 反填 resolvedVersion、Python hashes 和 npm/npmDev integrity。它仍不会下载、安装或访问 registry,未能反填的项发布前应由人工审核或 CI 流水线补齐。

如果当前终端是交互式 TTY,且输出格式为 text,也可以不传 --yes

ruoyi plugin install-deps demo --env=dev

CLI 会先输出 dry-run 预览和策略判定,再询问是否执行真实安装。非 TTY、JSON 输出和 CI 场景不会进入交互确认,真实安装应显式传 --yes

应用启动时只做默认启用插件的依赖门禁,不会提示安装,也不会执行 pip installnpm install。缺少依赖时应先使用 ruoyi plugin install-deps 显式处理。

10. 安装、启用、升级和清理

生命周期命令:

ruoyi plugin list --env=dev
ruoyi plugin info demo --env=dev
ruoyi plugin check demo --env=dev
ruoyi plugin precheck install demo --env=dev
ruoyi plugin install demo --env=dev --yes
ruoyi plugin enable demo --env=dev --yes
ruoyi plugin disable demo --env=dev --yes
ruoyi plugin upgrade demo --env=dev --yes
ruoyi plugin uninstall demo --env=dev --yes
ruoyi plugin purge demo --env=dev --yes

批量计划和批量执行:

ruoyi plugin plan install demo --env=dev
ruoyi plugin batch install demo --env=dev --yes
ruoyi plugin batch enable --env=dev --yes

命令语义:

  • install:执行 migration、seed、菜单、配置、任务安装,并记录 installed_version
  • enable:启用插件,并恢复菜单和任务状态。
  • disable:停用插件,并停用菜单和任务。
  • uninstall:安全卸载,保留可恢复数据。
  • purge:清理插件平台元数据,属于高风险操作。

生产环境执行危险操作需要显式传入 --allow-prod --yes

11. 默认启用内置插件

内置插件自动初始化名单写在环境配置中:

APP_DEFAULT_ENABLED_PLUGINS=ai,demo

规则:

  • 多个插件用英文逗号分隔。
  • 留空表示不自动初始化默认启用插件。
  • 启动期只会初始化当前环境配置中的默认启用插件。
  • 用户在管理端停用或卸载插件后,数据库状态优先。

如果插件只作为可选能力,不要加入 APP_DEFAULT_ENABLED_PLUGINS

12. 健康检查和诊断

可在 backend.health.checker 声明健康检查:

backend:
  health:
    checker: plugins.demo.health:check

格式为 <module_path>:<callable_name>。健康检查命令:

ruoyi plugin health demo --env=dev
ruoyi plugin diagnose demo --env=dev --output-file=demo-diagnose.json
ruoyi plugin docs demo --env=dev --output-file=demo.md

13. 测试和发布前检查

后端单插件测试:

ruoyi plugin test demo --env=dev

直接运行 pytest

pytest tests/plugins/demo

代码格式和 lint

ruff format plugins/demo tests/plugins/demo
ruff check plugins/demo tests/plugins/demo

发布前建议至少执行:

ruoyi plugin check demo --env=dev
ruoyi plugin check-deps demo --env=dev
ruoyi plugin precheck install demo --env=dev
ruoyi plugin install demo --env=dev --dry-run
ruoyi plugin test demo --env=dev

全栈插件还应执行前端构建检查:

cd ../ruoyi-fastapi-frontend
npm run build:prod

14. 开发规范清单

提交前确认:

  • 插件 ID、后端模块、前端插件目录三者一致。
  • 菜单权限全部声明在顶层 permissions
  • 菜单组件路径能映射到实际 Vue 文件。
  • SQL seed 可重复执行。
  • migration 和 seed 不写插件目录外文件。
  • 生命周期钩子中的全局写操作检查 startup_write_enabled
  • 依赖声明完整,并通过 check-deps
  • 插件状态只使用 status 的四个生命周期值。