快速开始
本文是 1.x 的归档文档(冻结于 1.x)。该分支只接收勘误修正, 内容基本不再变动;文中的源码路径、配置项与版本号均以 1.x 为准,不建议用于新项目。
新项目请查看 5.x 最新文档。已在 1.x 上运行的项目,本文仍是可靠依据。
这一页带你从零做出第一个插件:新建骨架 → 构建后端 → 热加载 → 验证接口 → 构建前端 → 打包。
示例插件叫 demo,它自带一张 demo_item 表和一个标准 CRUD 页面。全程不需要改平台代码。
0. 准备环境(一次性)
| 工具 | 版本 | 用途 |
|---|---|---|
| JDK | 17+ | 构建插件、签名 |
| Maven | 3.9+ | 构建后端 jar |
| Node.js | 18+(仓库要求 20+) | 生成骨架、构建前端 |
| pnpm | 10.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本机还没有密钥时,不要临时生成一把新的——宿主不认,上传会验签失败。 先生成密钥并把公钥同步进宿主,步骤见密钥与签名。
然后在后台走安装:
应用上架 → 应用管理 → 版本管理 → 安装包上传 → 保存版本 → 发布 → 上架 → 安装
安装过程会:
- 把后端 jar 与前端产物落位到宿主目录;
- 执行
migrations/下未执行过的 SQL(建表 + 种子数据); - 把
app.json里的菜单与按钮权限写入sys_menu; - 给当前租户建立安装记录。
装完之后刷新后台(必要时重新登录),菜单「演示应用 → 数据」出现,页面能打开。 这一步只需要做一次,之后的迭代都用热加载。
只想先在开发库验证 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 | 同上,看 rows | 2 条种子数据 |
| 鉴权兜底 | 不带 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 后走安装 / 升级(或同步菜单) |
更多排查见故障排查。