Wujies 无界平台
平台功能(自研)插件开发

插件快速开始

这一页带你从零做出第一个插件:新建骨架 → 构建后端 → 热加载 → 验证接口 → 构建前端 → 打包。

示例插件叫 demo,它自带一张 demo_item 表和一个标准 CRUD 页面。全程不需要改平台代码。

0. 准备环境(一次性)

工具版本用途
JDK17+构建插件、签名
Maven3.9+构建后端 jar
Node.js18+(仓库要求 20+)生成骨架、构建前端
pnpm10.x前端 workspace,corepack enable pnpm 即可
插件仓库wujies/wujies-plugins插件源码与打包脚本所在

然后在宿主 application.yml 打开开发模式,重启一次宿主:

app-market:
  plugin-runtime:
    dev-mode: true
    # 插件仓库路径;留空则自动探测 ../wujies/wujies-plugins 等常见位置
    plugin-repo: ""
    # 可选:限制只能热加载这个目录下的 jar;留空 = 不限制
    dev-base-dir: ""

重启后登录后台,能看到 「应用上架 → 插件开发」 就说明准备好了。 开关关闭时,整个开发端点不注册,页面会显示「开发模式未就绪」。

只在本机 / 内网开

开发模式会从本地路径直接加载 jar,绕过包白名单、校验和与签名校验。 能调用它的人等于能在宿主 JVM 里执行任意代码。绝不要在生产环境打开。

1. 新建插件

方式一:开发台(推荐)

打开 应用上架 → 插件开发 → 新建插件,填写:

字段示例说明
应用编码demo小写字母开头,2–32 位字母/数字;同时决定包名、表前缀、权限前缀
应用名称演示应用后台菜单显示名,最多 40 字
版本号1.0.0语义化版本
简介我的第一个插件可选
生成前端勾选不勾则只生成后端工程

点确定后,服务端会调用 scripts/new-plugin.mjs 生成工程,并自动把模块登记进插件仓库根 pom.xml。 页面会返回后端路径、前端路径和终端输出。

方式二:命令行

在插件仓库根执行,效果完全一致:

cd wujies\wujies-plugins
powershell -File new-plugin.ps1 -Code demo -Name "演示应用"

生成了什么

wujies-demo/
├── app.json                         菜单、权限、产物路径、版本
├── pom.xml                          已登记到仓库根 reactor
├── migrations/
│   └── 01-create-demo-item.sql      建表 + 2 条种子数据(幂等)
└── src/main/java/cn/wujies/demo/
    ├── controller/DemoItemController.java
    ├── domain/DemoItem.java
    ├── domain/bo/DemoItemBo.java
    ├── domain/vo/DemoItemVo.java
    ├── mapper/DemoItemMapper.java
    └── service/IDemoItemService.java + impl/DemoItemServiceImpl.java

frontend/demo-app/
├── app.json
├── vite.config.ts
└── src/
    ├── index.ts                     入口契约,视图键 item
    └── views/ItemList.vue           标准 CRUD 页面

菜单也已写好:父菜单「演示应用」→ 子菜单「数据」→ 四个按钮权限 (demo:item:query/add/edit/remove),页面组件是 remote:demo/item。

2. 构建后端并热加载

在插件仓库根构建:

mvn -B -pl wujies-demo -am package -DskipTests

产物在 wujies-demo/target/wujies-demo-plugin-1.0.0.jar(版本号来自插件仓库父 POM)。

回到开发台,在「仓库插件」里找到 demo,点 热加载。弹窗里的 jar 路径已经自动填好, 直接确定;也可以只填到 target 目录,服务端会选中里面唯一的 jar。

成功后面板会显示组件数、接口数、Mapper 数和类加载器名,列表里的 demo 也会标记为「已加载」。

等价命令
curl.exe -X POST "http://127.0.0.1:8086/app/dev/reload" `
  -H "Authorization: Bearer <token>" -H "tenant-id: 000000" `
  -H "Content-Type: application/json" `
  -d '{"appCode":"demo","path":"C:\\...\\wujies-demo\\target\\wujies-demo-plugin-1.0.0.jar"}'

token 取浏览器请求头里 Authorization 去掉 Bearer 之后的值。

热加载是幂等的:重复调用会先卸载上一代,再装载新 jar,不会累积类加载器。 但它不建表、不同步菜单、不部署前端——这三件事由安装链路负责。

3. 第一次安装(让表与菜单出现)

热加载之后接口已经挂上,但 demo_item 表还不存在,菜单也还没进数据库。第一次需要安装一次:

# 正式包(会签名),产物在 ..\.plugin-dist\demo\1.0.0\demo-1.0.0.zip
.\package.ps1 -Plugin wujies-demo -SigningKey keys\private.pem

本机还没有密钥时,不要临时生成一把新的——宿主不认,上传会验签失败。 先生成密钥并把公钥同步进宿主,步骤见密钥与签名。

然后在后台走安装:

应用上架 → 应用管理 → 版本管理 → 安装包上传 → 保存版本 → 发布 → 上架 → 安装

安装过程会:

  1. 把后端 jar 与前端产物落位到宿主目录;
  2. 执行 migrations/ 下未执行过的 SQL(建表 + 种子数据);
  3. 把 app.json 里的菜单与按钮权限写入 sys_menu;
  4. 给当前租户建立安装记录。

装完之后刷新后台(必要时重新登录),菜单「演示应用 → 数据」出现,页面能打开。 这一步只需要做一次,之后的迭代都用热加载。

只想先在开发库验证 SQL?

可以在开发库手动执行 migrations/01-create-demo-item.sql(脚本本身幂等),先把接口验通。 但菜单与前端入口仍要等安装后才生效。

4. 验证接口

# 列表:需要登录 + 权限 demo:item:list
curl.exe -s "http://127.0.0.1:8086/demo/item/list?pageNum=1&pageSize=10" `
  -H "Authorization: Bearer <token>" -H "tenant-id: 000000"

期望返回 code=200、total=2(两条种子数据)。

验什么请求期望
路由与依赖注入GET /demo/item/list(带 token)200
建表与 Mapper同上,看 rows2 条种子数据
鉴权兜底不带 token 再请求一次401
菜单与权限后台菜单「演示应用 → 数据」页面正常渲染

5. 构建前端

前端是独立的 pnpm 工程,产物要落到宿主 dev server 读取的目录:

cd wujies\wujies-plugins
$env:WUJIES_UI_DIR        = 'C:\Users\TX\Desktop\ruoyi\plus-ui'
$env:WUJIES_FRONTEND_DIST = 'C:\Users\TX\Desktop\ruoyi\plus-ui\app-market-dist\remote-apps'

pnpm --filter @wujies-plugins/demo-app run build

产物在 plus-ui/app-market-dist/remote-apps/demo/(index.js + assets/)。刷新浏览器即可看到最新页面。

  • 只改 Vue:重新执行上面两条命令,刷新浏览器。没有 HMR,这是构建产物替换,不是 dev server。
  • 页面缓存:入口 URL 带 ?v=<版本>,同版本号下必要时硬刷新(Ctrl+F5)。
  • 视图键必须对齐:src/index.ts 里的 item ↔ app.json 里的 remote:demo/item。

6. 打开发包与正式包

目的命令产物
本机联调 / 对照包结构.\package.ps1 -Plugin wujies-demo -Dev.plugin-dist\demo\dev\demo-1.0.0.zip,不签名
上传安装 / 正式发布.\package.ps1 -Plugin wujies-demo.plugin-dist\demo\1.0.0\demo-1.0.0.zip,签名
发布一个版本(打 tag).\release.ps1 -Plugin wujies-demo包 + 附注 tag demo-v1.0.0

-Dev 与 -SigningKey 互斥:开发包不签名,只适合 security.mode=warn/off 的部署, 或用于展开核对包结构。宿主是 enforce 时,未签名包在上传阶段就会被拒。 签名、换钥与校验细节见密钥与签名。

开发台里的「打开发包」只负责组装已经构建好的产物(后端 jar + 前端 dist + 迁移脚本), 不会替你跑 Maven / pnpm。先完成第 2、5 步,再点它。

接下来改哪里

想改文件
表字段migrations/ 新增脚本 + DemoItem.java / Bo / Vo
接口逻辑DemoItemServiceImpl.java / DemoItemController.java
页面frontend/demo-app/src/views/ItemList.vue
菜单、权限、版本wujies-demo/app.json(改完需安装 / 升级才同步)
页面路由与视图键frontend/demo-app/src/index.ts + app.json 的 component

更完整的写法见后端工程与前端远程应用; 日常联调的四条路径见本地开发与联调方案。

常见问题

症状原因解决
开发台显示「开发模式未就绪」dev-mode 没开或没重启改 yml 后重启宿主
新建插件报「找不到插件仓库」plugin-repo 为空且自动探测失败显式配置插件仓库绝对路径
新建插件报 node 不存在宿主机器的 PATH 里没有 Node安装 Node 18+,或在终端用 new-plugin.ps1 生成
热加载后接口 404构建的 jar 不是最新的,或路径指错看开发台行内展示的 jar 路径;重新 mvn package
接口报 Unknown column 'tenant_id'实体没有继承 TenantEntity / 表缺 tenant_id见必须遵守的不变量
菜单点开「远程视图不可用」前端产物目录名 ≠ appCode,或应用未安装确认产物在 remote-apps/demo/,且应用已安装
热加载后菜单没变热加载不同步菜单改 app.json 后走安装 / 升级(或同步菜单)

更多排查见故障排查。

界面截图

新建插件表单(截图占位)

新建插件表单(截图占位)

/images/docs/plugin-new.png

建议 1440 × 900,截应用编码、名称、版本与「生成前端」。

目录