mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-14 12:23:39 +00:00
v3.0.0 init
This commit is contained in:
Binary file not shown.
@@ -1,222 +0,0 @@
|
||||
## RuoYi-AI 后端部署教程(Docker 部署版)
|
||||
|
||||
### 一、前置条件
|
||||
|
||||
在部署前,请确保系统已满足以下条件:
|
||||
|
||||
#### ✅ 系统环境要求
|
||||
|
||||
- 操作系统:Linux / MacOS(推荐 Linux 服务器)
|
||||
- CPU:4 核以上
|
||||
- 内存:≥ 4GB
|
||||
- 磁盘空间:≥ 10GB(建议 20GB+)
|
||||
|
||||
#### ✅ 已安装软件
|
||||
|
||||
- **Docker**
|
||||
- **Docker Compose**
|
||||
|
||||
验证命令是否可用:
|
||||
|
||||
```
|
||||
docker -v
|
||||
docker compose version
|
||||
```
|
||||
|
||||
若无输出或提示“command not found”,请先安装 Docker 及 Compose。
|
||||
|
||||
------
|
||||
|
||||
### 二、目录结构配置
|
||||
|
||||
#### 1️⃣ 创建部署目录
|
||||
|
||||
在目标服务器执行以下命令:
|
||||
|
||||
```
|
||||
# 第一级目录
|
||||
mkdir /ruoyi-ai
|
||||
cd /ruoyi-ai
|
||||
|
||||
# 第二级目录
|
||||
mkdir deploy
|
||||
cd deploy
|
||||
|
||||
# 第三级目录
|
||||
mkdir data mysql-init
|
||||
|
||||
# 第四级目录
|
||||
mkdir logs minio minio-config mysql redis weaviate
|
||||
```
|
||||
|
||||
> 💡 `data` 目录用于挂载容器运行期间生成的数据文件。
|
||||
|
||||
最终目录结构示例:
|
||||
|
||||
```
|
||||
/ruoyi-ai
|
||||
└── deploy
|
||||
├── data/
|
||||
├── mysql-init/
|
||||
├── logs/
|
||||
├── minio/
|
||||
├── minio-config/
|
||||
├── mysql/
|
||||
├── redis/
|
||||
├── weaviate/
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
### 三、上传配置文件
|
||||
|
||||
将以下配置文件上传到 `/ruoyi-ai/deploy` 目录:
|
||||
|
||||
- `docker-compose.yaml`
|
||||
- `.env`
|
||||
- `ruoyi-ai.sql`
|
||||
- `Dockerfile`
|
||||
|
||||
> 📂 这些文件在项目目录 `/script/deploy/deploy` 下。
|
||||
> 上传后请检查文件路径是否与上方目录结构一致。
|
||||
|
||||
------
|
||||
|
||||
### 四、构建 Jar 包
|
||||
|
||||
1. 打开 IDEA 或其他构建工具
|
||||
2. 选择 **Maven 构建配置**,勾选 `prod` 环境,取消 `dev` 环境
|
||||
3. 点击 `package` 进行打包
|
||||
4. **注意:** 在构建前请将 `application-prod.yml` 拖入
|
||||
`ruoyi-admin/src/main/resources` 目录中
|
||||
|
||||
构建完成后会在:
|
||||
|
||||
```
|
||||
ruoyi-admin/target/ruoyi-admin.jar
|
||||
```
|
||||
|
||||
生成打包文件。
|
||||
|
||||
------
|
||||
|
||||
### 五、上传 Jar 包至服务器
|
||||
|
||||
将生成的 `ruoyi-admin.jar` 上传到服务器 `/ruoyi-ai/deploy` 目录下。
|
||||
确保与 `Dockerfile` 同目录。
|
||||
|
||||
------
|
||||
|
||||
### 六、构建 Docker 镜像
|
||||
|
||||
`Dockerfile` 内容如下:
|
||||
|
||||
```
|
||||
FROM openjdk:17-jdk
|
||||
|
||||
RUN mkdir -p /ruoyi/server/logs \
|
||||
/ruoyi/server/temp
|
||||
|
||||
WORKDIR /ruoyi/server
|
||||
COPY ruoyi-admin.jar ruoyi-admin.jar
|
||||
|
||||
ENTRYPOINT ["java","-jar","ruoyi-admin.jar"]
|
||||
```
|
||||
|
||||
在 `/ruoyi-ai/deploy` 目录执行以下命令:
|
||||
|
||||
```
|
||||
# 构建镜像
|
||||
docker build -t ruoyi-ai-backend:v20251013 .
|
||||
|
||||
# 查看镜像是否构建成功
|
||||
docker image ls
|
||||
```
|
||||
|
||||
然后在 `docker-compose.yaml` 文件中,将对应服务的镜像名修改为:
|
||||
|
||||
```
|
||||
image: ruoyi-ai-backend:v20251013
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
### 七、启动容器服务
|
||||
|
||||
在启动前请确认:
|
||||
|
||||
- `.env` 中端口号、数据库密码、环境变量已正确配置
|
||||
- `docker-compose.yaml` 中 MySQL 的端口已开放(用于导入数据)
|
||||
|
||||
如示例:
|
||||
|
||||
```
|
||||
ports:
|
||||
- "3306:3306"
|
||||
```
|
||||
|
||||
#### 启动命令:
|
||||
|
||||
```
|
||||
cd /ruoyi-ai/deploy
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
#### 查看运行状态:
|
||||
|
||||
```
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
#### 查看日志:
|
||||
|
||||
```
|
||||
docker logs -f <容器名称>
|
||||
```
|
||||
|
||||
> ⚠️ 初次启动时可仅运行 `ruoyi-admin`(后端)模块,将前端 `ruoyi-web` 服务暂时注释,确认后端服务正常后再启用前端容器。
|
||||
|
||||
------
|
||||
|
||||
### 八、数据库初始化
|
||||
|
||||
启动 MySQL 容器后,执行以下操作:
|
||||
|
||||
```
|
||||
docker exec -it <mysql_container_name> bash
|
||||
mysql -uroot -p
|
||||
source /docker-entrypoint-initdb.d/ruoyi-ai.sql;
|
||||
```
|
||||
|
||||
或手动在客户端中导入 `/ruoyi-ai/deploy/ruoyi-ai.sql` 文件。
|
||||
|
||||
------
|
||||
|
||||
### 九、常用 Docker 命令
|
||||
|
||||
| 功能 | 命令 |
|
||||
|-----------|-----------------------------------|
|
||||
| 查看容器状态 | `docker ps -a` |
|
||||
| 查看日志 | `docker logs -f <容器名>` |
|
||||
| 停止服务 | `docker compose down` |
|
||||
| 重启服务 | `docker compose restart` |
|
||||
| 重新构建镜像 | `docker compose build --no-cache` |
|
||||
| 清理无用镜像/容器 | `docker system prune -a` |
|
||||
|
||||
------
|
||||
|
||||
### 🔍 十、部署验证
|
||||
|
||||
1. 检查容器是否全部启动成功:
|
||||
|
||||
```
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
2. 访问后端接口:
|
||||
|
||||
```
|
||||
http://<服务器IP>:<后端端口>
|
||||
```
|
||||
|
||||
3. 检查日志输出无异常。
|
||||
BIN
docs/image/logo.png
Normal file
BIN
docs/image/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
BIN
docs/image/qq.png
Normal file
BIN
docs/image/qq.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 193 KiB |
BIN
docs/image/wx.png
Normal file
BIN
docs/image/wx.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
0
docs/script/docker/database.yml
Normal file
0
docs/script/docker/database.yml
Normal file
0
docs/script/docker/docker-compose.yml
Normal file
0
docs/script/docker/docker-compose.yml
Normal file
161
docs/script/docker/nginx/conf/nginx.conf
Normal file
161
docs/script/docker/nginx/conf/nginx.conf
Normal file
@@ -0,0 +1,161 @@
|
||||
worker_processes 1;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
# 可以根据业务并发量适当调高
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
# 高效传输文件
|
||||
sendfile on;
|
||||
# 长连接超时时间
|
||||
keepalive_timeout 65;
|
||||
# 单连接最大请求数,提高长连接复用率
|
||||
keepalive_requests 100000;
|
||||
# 限制body大小
|
||||
client_max_body_size 100m;
|
||||
client_header_buffer_size 32k;
|
||||
client_body_buffer_size 512k;
|
||||
# 开启静态资源压缩
|
||||
gzip_static on;
|
||||
# 连接数限制 (防御类配置) 10m 一般够用了,能存储上万 IP 的计数
|
||||
limit_conn_zone $binary_remote_addr zone=perip:10m;
|
||||
limit_conn_zone $server_name zone=perserver:10m;
|
||||
# 隐藏 nginx 版本号,防止暴露版本信息
|
||||
server_tokens off;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
upstream server {
|
||||
ip_hash;
|
||||
server 127.0.0.1:8080;
|
||||
server 127.0.0.1:8081;
|
||||
}
|
||||
|
||||
upstream monitor-admin {
|
||||
server 127.0.0.1:9090;
|
||||
}
|
||||
|
||||
upstream snailjob-server {
|
||||
server 127.0.0.1:8800;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# https配置参考 start
|
||||
#listen 443 ssl;
|
||||
|
||||
# 证书直接存放 /docker/nginx/cert/ 目录下即可 更改证书名称即可 无需更改证书路径
|
||||
#ssl on;
|
||||
#ssl_certificate /etc/nginx/cert/xxx.local.crt; # /etc/nginx/cert/ 为docker映射路径 不允许更改
|
||||
#ssl_certificate_key /etc/nginx/cert/xxx.local.key; # /etc/nginx/cert/ 为docker映射路径 不允许更改
|
||||
#ssl_session_timeout 5m;
|
||||
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
|
||||
#ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
|
||||
#ssl_prefer_server_ciphers on;
|
||||
# https配置参考 end
|
||||
|
||||
# 演示环境配置 拦截除 GET POST 之外的所有请求
|
||||
# if ($request_method !~* GET|POST) {
|
||||
# rewrite ^/(.*)$ /403;
|
||||
# }
|
||||
|
||||
# location = /403 {
|
||||
# default_type application/json;
|
||||
# return 200 '{"msg":"演示模式,不允许操作","code":500}';
|
||||
# }
|
||||
|
||||
# 限制外网访问内网 actuator 相关路径
|
||||
location ~ ^(/[^/]*)?/actuator.*(/.*)?$ {
|
||||
return 403;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html; # docker映射路径 不允许更改
|
||||
try_files $uri $uri/ /index.html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /prod-api/ {
|
||||
# 设置客户端请求头中的 Host 信息(保持原始 Host)
|
||||
proxy_set_header Host $http_host;
|
||||
# 获取客户端真实 IP
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
# 自定义头 REMOTE-HOST,记录客户端 IP
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
# 获取完整的客户端 IP 链(经过多级代理时)
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# 设置后端响应超时时间(这里是 24 小时,适合长连接/SSE)
|
||||
proxy_read_timeout 86400s;
|
||||
# SSE (Server-Sent Events) 与 WebSocket 支持参数
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
# 禁用代理缓冲,数据直接传给客户端
|
||||
proxy_buffering off;
|
||||
# 禁用代理缓存
|
||||
proxy_cache off;
|
||||
# 按 IP 限制连接数(防 CC 攻击) 小型站:10~20 就够 中型站:50~100
|
||||
limit_conn perip 20;
|
||||
|
||||
# 按 Server 限制总并发连接数 根据服务器的最大并发处理能力来定 太小会限制合法用户访问,太大会占满服务器资源
|
||||
limit_conn perserver 500;
|
||||
proxy_pass http://server/;
|
||||
}
|
||||
|
||||
# https 会拦截内链所有的 http 请求 造成功能无法使用
|
||||
# 解决方案1 将 admin 服务 也配置成 https
|
||||
# 解决方案2 将菜单配置为外链访问 走独立页面 http 访问
|
||||
location /admin/ {
|
||||
# 设置客户端请求头中的 Host 信息(保持原始 Host)
|
||||
proxy_set_header Host $http_host;
|
||||
# 获取客户端真实 IP
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
# 自定义头 REMOTE-HOST,记录客户端 IP
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
# 获取完整的客户端 IP 链(经过多级代理时)
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# 禁用代理缓冲,数据直接传给客户端
|
||||
proxy_buffering off;
|
||||
# 禁用代理缓存
|
||||
proxy_cache off;
|
||||
proxy_pass http://monitor-admin/admin/;
|
||||
}
|
||||
|
||||
location /snail-job/ {
|
||||
# 设置客户端请求头中的 Host 信息(保持原始 Host)
|
||||
proxy_set_header Host $http_host;
|
||||
# 获取客户端真实 IP
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
# 自定义头 REMOTE-HOST,记录客户端 IP
|
||||
proxy_set_header REMOTE-HOST $remote_addr;
|
||||
# 获取完整的客户端 IP 链(经过多级代理时)
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# SSE (Server-Sent Events) 与 WebSocket 支持参数
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
# 禁用代理缓冲,直接传输给客户端
|
||||
proxy_buffering off;
|
||||
# 禁用代理缓存
|
||||
proxy_cache off;
|
||||
proxy_pass http://snailjob-server/snail-job/;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
docs/script/docker/redis/conf/redis.conf
Normal file
28
docs/script/docker/redis/conf/redis.conf
Normal file
@@ -0,0 +1,28 @@
|
||||
# redis 密码
|
||||
requirepass ruoyi123
|
||||
|
||||
# key 监听器配置
|
||||
# notify-keyspace-events Ex
|
||||
|
||||
# 配置持久化文件存储路径
|
||||
dir /redis/data
|
||||
# 配置rdb
|
||||
# 15分钟内有至少1个key被更改则进行快照
|
||||
save 900 1
|
||||
# 5分钟内有至少10个key被更改则进行快照
|
||||
save 300 10
|
||||
# 1分钟内有至少10000个key被更改则进行快照
|
||||
save 60 10000
|
||||
# 开启压缩
|
||||
rdbcompression yes
|
||||
# rdb文件名 用默认的即可
|
||||
dbfilename dump.rdb
|
||||
|
||||
# 开启aof
|
||||
appendonly yes
|
||||
# 文件名
|
||||
appendfilename "appendonly.aof"
|
||||
# 持久化策略,no:不同步,everysec:每秒一次,always:总是同步,速度比较慢
|
||||
# appendfsync always
|
||||
appendfsync everysec
|
||||
# appendfsync no
|
||||
1
docs/script/docker/redis/data/README.md
Normal file
1
docs/script/docker/redis/data/README.md
Normal file
@@ -0,0 +1 @@
|
||||
数据目录 请执行 `chmod 777 /docker/redis/data` 赋予读写权限 否则将无法写入数据
|
||||
129
docs/script/leave/leave1.json
Normal file
129
docs/script/leave/leave1.json
Normal file
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "d5ee3ddf-3968-4379-a86f-9ceabde5faac",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "200,200|200,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "d5ee3ddf-3968-4379-a86f-9ceabde5faac",
|
||||
"nextNodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42",
|
||||
"coordinate": "220,200;310,200"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,copy\"}]",
|
||||
"coordinate": "360,200|360,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "dd515cdd-59f6-446f-94ca-25ca062afb42",
|
||||
"nextNodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf",
|
||||
"coordinate": "410,200;490,200"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf",
|
||||
"nodeName": "组长",
|
||||
"permissionFlag": "role:1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,copy,transfer,trust,file\"}]",
|
||||
"coordinate": "540,200|540,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "78fa8e5b-e809-44ed-978a-41092409ebcf",
|
||||
"nextNodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe",
|
||||
"coordinate": "590,200;670,200"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe",
|
||||
"nodeName": "部门主管",
|
||||
"permissionFlag": "role:3@@role:4",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,copy,transfer,trust,file\"}]",
|
||||
"coordinate": "720,200|720,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "a8abf15f-b83e-428a-86cc-033555ea9bbe",
|
||||
"nextNodeCode": "8b82b7d7-8660-455e-b880-d6d22ea3eb6d",
|
||||
"coordinate": "770,200;880,200"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "8b82b7d7-8660-455e-b880-d6d22ea3eb6d",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "900,200|900,200",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
}
|
||||
],
|
||||
"flowCode": "leave1",
|
||||
"flowName": "请假申请-普通",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
187
docs/script/leave/leave2.json
Normal file
187
docs/script/leave/leave2.json
Normal file
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "300,240|300,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a",
|
||||
"nextNodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd",
|
||||
"coordinate": "320,240;390,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]",
|
||||
"coordinate": "440,240|440,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "fdcae93b-b69c-498a-b231-09255e74bcbd",
|
||||
"nextNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e",
|
||||
"coordinate": "490,240;535,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "3",
|
||||
"nodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "560,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": "le@@leaveDays|2",
|
||||
"skipName": null,
|
||||
"nowNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e",
|
||||
"nextNodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86",
|
||||
"coordinate": "560,265;560,320;670,320"
|
||||
},
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": "gt@@leaveDays|2",
|
||||
"skipName": "大于两天",
|
||||
"nowNodeCode": "7b8c7ead-7dc8-4951-a7f3-f0c41995909e",
|
||||
"nextNodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605",
|
||||
"coordinate": "560,215;560,160;670,160|560,187"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86",
|
||||
"nodeName": "组长",
|
||||
"permissionFlag": "3@@4",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "720,320|720,320",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "b3528155-dcb7-4445-bbdf-3d00e3499e86",
|
||||
"nextNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869",
|
||||
"coordinate": "770,320;860,320;860,280"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869",
|
||||
"nodeName": "总经理",
|
||||
"permissionFlag": "role:1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "860,240|860,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869",
|
||||
"nextNodeCode": "40aa65fd-0712-4d23-b6f7-d0432b920fd1",
|
||||
"coordinate": "910,240;980,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "40aa65fd-0712-4d23-b6f7-d0432b920fd1",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1000,240|1000,240",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605",
|
||||
"nodeName": "部门领导",
|
||||
"permissionFlag": "role:1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "720,160|720,160",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "5ed2362b-fc0c-4d52-831f-95208b830605",
|
||||
"nextNodeCode": "c9fa6d7d-2a74-4e78-b947-0cad8a6af869",
|
||||
"nextNodeType": "1",
|
||||
"coordinate": "770,160;860,160;860,200"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"flowCode": "leave2",
|
||||
"flowName": "请假申请-排他网关",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
211
docs/script/leave/leave3.json
Normal file
211
docs/script/leave/leave3.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "a80ecf9f-f465-4ae5-a429-e30ec5d0f957",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "380,220|380,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "a80ecf9f-f465-4ae5-a429-e30ec5d0f957",
|
||||
"nextNodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99",
|
||||
"coordinate": "400,220;470,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]",
|
||||
"coordinate": "520,220|520,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "b7bbb571-06de-455c-8083-f83c07bf0b99",
|
||||
"nextNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a",
|
||||
"coordinate": "570,220;655,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "680,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a",
|
||||
"nextNodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe",
|
||||
"coordinate": "680,195;680,140;750,140"
|
||||
},
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a",
|
||||
"nextNodeCode": "762cb975-37d8-4276-b6db-79a4c3606394",
|
||||
"coordinate": "680,245;680,300;750,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe",
|
||||
"nodeName": "市场部",
|
||||
"permissionFlag": "role:1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "800,140|800,140",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "4b7743cd-940c-431b-926f-e7b614fbf1fe",
|
||||
"nextNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2",
|
||||
"coordinate": "850,140;920,140;920,195"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "920,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2",
|
||||
"nextNodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6",
|
||||
"coordinate": "945,220;975,220;975,220;960,220;960,220;990,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6",
|
||||
"nodeName": "CEO",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "1040,220|1040,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "23e7429e-2b47-4431-b93e-40db7c431ce6",
|
||||
"nextNodeCode": "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1",
|
||||
"coordinate": "1090,220;1140,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1160,220|1160,220",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "762cb975-37d8-4276-b6db-79a4c3606394",
|
||||
"nodeName": "综合部",
|
||||
"permissionFlag": "role:3@@role:4",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "800,300|800,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "762cb975-37d8-4276-b6db-79a4c3606394",
|
||||
"nextNodeCode": "b66b6563-f9fe-41cc-a782-f7837bb6f3d2",
|
||||
"nextNodeType": "4",
|
||||
"coordinate": "850,300;920,300;920,245"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"flowCode": "leave3",
|
||||
"flowName": "请假申请-并行网关",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
154
docs/script/leave/leave4.json
Normal file
154
docs/script/leave/leave4.json
Normal file
@@ -0,0 +1,154 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "9ce8bf00-f25b-4fc6-91b8-827082fc4876",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "320,240|320,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "9ce8bf00-f25b-4fc6-91b8-827082fc4876",
|
||||
"nextNodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f",
|
||||
"coordinate": "340,240;410,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]",
|
||||
"coordinate": "460,240|460,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "e90b98ef-35b4-410c-a663-bae8b7624b9f",
|
||||
"nextNodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045",
|
||||
"coordinate": "510,240;590,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045",
|
||||
"nodeName": "百分之60通过",
|
||||
"permissionFlag": "${userList}",
|
||||
"nodeRatio": "60.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]",
|
||||
"coordinate": "640,240|640,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "768b5b1a-6726-4d67-8853-4cc70d5b1045",
|
||||
"nextNodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1",
|
||||
"coordinate": "690,240;770,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1",
|
||||
"nodeName": "全部审批通过",
|
||||
"permissionFlag": "role:1@@role:3",
|
||||
"nodeRatio": "100.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]",
|
||||
"coordinate": "820,240|820,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "2f9f2e21-9bcf-42a3-a07c-13037aad22d1",
|
||||
"nextNodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f",
|
||||
"coordinate": "870,240;950,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f",
|
||||
"nodeName": "CEO",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "1000,240|1000,240",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "27461e01-3d9f-4530-8fe3-bd5ec7f9571f",
|
||||
"nextNodeCode": "b62b88c3-8d8d-4969-911e-2aaea219e7fc",
|
||||
"coordinate": "1050,240;1080,240;1080,240;1070,240;1070,240;1100,240"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "b62b88c3-8d8d-4969-911e-2aaea219e7fc",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1120,240|1120,240",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
}
|
||||
],
|
||||
"flowCode": "leave4",
|
||||
"flowName": "请假申请-会签",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
211
docs/script/leave/leave5.json
Normal file
211
docs/script/leave/leave5.json
Normal file
@@ -0,0 +1,211 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "ebebaf26-9cb6-497e-8119-4c9fed4c597c",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "300,220|300,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "ebebaf26-9cb6-497e-8119-4c9fed4c597c",
|
||||
"nextNodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374",
|
||||
"coordinate": "320,220;350,220;350,220;340,220;340,220;370,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]",
|
||||
"coordinate": "420,220|420,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "e1b04e96-dc81-4858-a309-2fe945d2f374",
|
||||
"nextNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9",
|
||||
"coordinate": "470,220;535,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "560,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9",
|
||||
"nextNodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862",
|
||||
"coordinate": "560,245;560,320;650,320"
|
||||
},
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "3e743f4f-51ca-41d4-8e94-21f5dd9b59c9",
|
||||
"nextNodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4",
|
||||
"coordinate": "560,195;560,120;650,120"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862",
|
||||
"nodeName": "会签",
|
||||
"permissionFlag": "role:1@@role:3",
|
||||
"nodeRatio": "100.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]",
|
||||
"coordinate": "700,320|700,320",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "c80f273e-1f17-4bd8-9ad1-04a4a94ea862",
|
||||
"nextNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b",
|
||||
"coordinate": "750,320;860,320;860,245"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "860,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b",
|
||||
"nextNodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9",
|
||||
"coordinate": "885,220;950,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9",
|
||||
"nodeName": "CEO",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,transfer,trust,copy\"}]",
|
||||
"coordinate": "1000,220|1000,220",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "7a8f0473-e409-442e-a843-5c2b813d00e9",
|
||||
"nextNodeCode": "03c4d2bc-58b5-4408-a2e4-65afb046f169",
|
||||
"coordinate": "1050,220;1120,220"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "03c4d2bc-58b5-4408-a2e4-65afb046f169",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1140,220|1140,220",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4",
|
||||
"nodeName": "百分之60票签",
|
||||
"permissionFlag": "${userList}",
|
||||
"nodeRatio": "60.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file,addSign,subSign\"}]",
|
||||
"coordinate": "700,120|700,120",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4",
|
||||
"nextNodeCode": "1a20169e-3d82-4926-a151-e2daad28de1b",
|
||||
"nextNodeType": "4",
|
||||
"coordinate": "750,120;860,120;860,195"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"flowCode": "leave5",
|
||||
"flowName": "请假申请-并行会签网关",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
368
docs/script/leave/leave6.json
Normal file
368
docs/script/leave/leave6.json
Normal file
@@ -0,0 +1,368 @@
|
||||
{
|
||||
"nodeList": [
|
||||
{
|
||||
"nodeType": "0",
|
||||
"nodeCode": "122b89a5-7c6f-40a3-aa09-7a263f902054",
|
||||
"nodeName": "开始",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "240,300|240,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "122b89a5-7c6f-40a3-aa09-7a263f902054",
|
||||
"nextNodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd",
|
||||
"coordinate": "260,300;350,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd",
|
||||
"nodeName": "申请人",
|
||||
"permissionFlag": "",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,file\"}]",
|
||||
"coordinate": "400,300|400,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "c25a0e86-fdd1-4f03-8e22-14db70389dbd",
|
||||
"nextNodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742",
|
||||
"coordinate": "450,300;510,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9",
|
||||
"nodeName": "副经理",
|
||||
"permissionFlag": "role:1@@role:3@@role:4",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]",
|
||||
"coordinate": "860,200|860,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9",
|
||||
"nextNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32",
|
||||
"coordinate": "910,200;1000,200;1000,275"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60",
|
||||
"nodeName": "组长",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]",
|
||||
"coordinate": "860,400|860,400",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60",
|
||||
"nextNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32",
|
||||
"coordinate": "910,400;1000,400;1000,325"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742",
|
||||
"nodeName": "副组长",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,transfer,copy,pop\"}]",
|
||||
"coordinate": "560,300|560,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "07ecda1d-7a0a-47b5-8a91-6186c9473742",
|
||||
"nextNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13",
|
||||
"coordinate": "610,300;675,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "3",
|
||||
"nodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "700,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": "default@@${leaveDays > 2}",
|
||||
"skipName": "大于两天",
|
||||
"nowNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13",
|
||||
"nextNodeCode": "2bfa3919-78cf-4bc1-b59b-df463a4546f9",
|
||||
"nextNodeType": "1",
|
||||
"coordinate": "700,275;700,200;810,200|700,237"
|
||||
},
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": "spel@@#{@testLeaveServiceImpl.eval(#leaveDays)}",
|
||||
"skipName": null,
|
||||
"nowNodeCode": "48117e2c-6328-406b-b102-c4a9d115bb13",
|
||||
"nextNodeCode": "ec17f60e-94e0-4d96-a3ce-3417e9d32d60",
|
||||
"nextNodeType": "1",
|
||||
"coordinate": "700,325;700,400;810,400"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "3",
|
||||
"nodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1000,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "394e1cc8-b8b2-4189-9f81-44448e88ac32",
|
||||
"nextNodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496",
|
||||
"coordinate": "1025,300;1130,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496",
|
||||
"nodeName": "经理会签",
|
||||
"permissionFlag": "1@@3",
|
||||
"nodeRatio": "100.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination,pop,addSign,subSign\"}]",
|
||||
"coordinate": "1180,300|1180,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "9c93a195-cff2-4e17-ab0a-a4f264191496",
|
||||
"nextNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992",
|
||||
"coordinate": "1230,300;1315,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1340,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992",
|
||||
"nextNodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5",
|
||||
"coordinate": "1340,325;1340,400;1430,400"
|
||||
},
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "a1a42056-afd1-4e90-88bc-36cbf5a66992",
|
||||
"nextNodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4",
|
||||
"coordinate": "1340,275;1340,200;1430,200"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4",
|
||||
"nodeName": "总经理",
|
||||
"permissionFlag": "3@@1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]",
|
||||
"coordinate": "1480,200|1480,200",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "350dfa0c-a77c-4efa-8527-10efa02d8be4",
|
||||
"nextNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519",
|
||||
"coordinate": "1530,200;1640,200;1640,275"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5",
|
||||
"nodeName": "副总经理",
|
||||
"permissionFlag": "1@@3",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]",
|
||||
"coordinate": "1480,400|1480,400",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "fcfdd9f6-f526-4c1a-b71d-88afa31aebc5",
|
||||
"nextNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519",
|
||||
"coordinate": "1530,400;1640,400;1640,325"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "4",
|
||||
"nodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1640,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "c36a46ef-04f9-463f-bad7-4b395c818519",
|
||||
"nextNodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828",
|
||||
"coordinate": "1665,300;1770,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "1",
|
||||
"nodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828",
|
||||
"nodeName": "董事",
|
||||
"permissionFlag": "1",
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": "",
|
||||
"listenerPath": "",
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[{\"code\":\"ButtonPermissionEnum\",\"value\":\"back,termination\"}]",
|
||||
"coordinate": "1820,300|1820,300",
|
||||
"version": "1",
|
||||
"skipList": [
|
||||
{
|
||||
"skipType": "PASS",
|
||||
"skipCondition": null,
|
||||
"skipName": null,
|
||||
"nowNodeCode": "3fcea762-b53a-4ae1-8365-7bec90444828",
|
||||
"nextNodeCode": "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31",
|
||||
"coordinate": "1870,300;1960,300"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeType": "2",
|
||||
"nodeCode": "9cfbfd3e-6c04-41d6-9fc2-6787a7d2cd31",
|
||||
"nodeName": "结束",
|
||||
"permissionFlag": null,
|
||||
"nodeRatio": "0.000",
|
||||
"anyNodeSkip": null,
|
||||
"listenerType": null,
|
||||
"listenerPath": null,
|
||||
"formCustom": "N",
|
||||
"formPath": null,
|
||||
"ext": "[]",
|
||||
"coordinate": "1980,300|1980,300",
|
||||
"version": "1",
|
||||
"skipList": []
|
||||
}
|
||||
],
|
||||
"flowCode": "leave6",
|
||||
"flowName": "请假申请-排他并行会签",
|
||||
"modelValue": "CLASSICS",
|
||||
"category": "103",
|
||||
"version": "1",
|
||||
"formCustom": "N",
|
||||
"formPath": "/workflow/leaveEdit/index",
|
||||
"listenerType": null,
|
||||
"listenerPath": null
|
||||
}
|
||||
3649
docs/script/sql/ruoyi-ai-v3_mysql8.sql
Normal file
3649
docs/script/sql/ruoyi-ai-v3_mysql8.sql
Normal file
File diff suppressed because one or more lines are too long
452
docs/工作流模块说明.md
452
docs/工作流模块说明.md
@@ -1,452 +0,0 @@
|
||||
# Ruoyi-AI 工作流模块详细说明文档
|
||||
|
||||
## 概述
|
||||
|
||||
Ruoyi-AI 工作流模块是一个基于 LangGraph4j 的智能工作流引擎,支持可视化工作流设计、AI 模型集成、条件分支、人机交互等高级功能。该模块采用微服务架构,提供完整的
|
||||
RESTful API 和流式响应支持。
|
||||
|
||||
## 模块架构
|
||||
|
||||
### 1. 模块结构
|
||||
|
||||
```
|
||||
ruoyi-ai/
|
||||
├── ruoyi-modules/
|
||||
│ └── ruoyi-workflow/ # 工作流核心模块
|
||||
│ ├── pom.xml
|
||||
│ └── src/main/java/org/ruoyi/workflow/
|
||||
│ └── controller/ # 控制器层
|
||||
│ ├── WorkflowController.java
|
||||
│ ├── WorkflowRuntimeController.java
|
||||
│ └── admin/ # 管理端控制器
|
||||
│ ├── AdminWorkflowController.java
|
||||
│ └── AdminWorkflowComponentController.java
|
||||
└── ruoyi-modules-api/
|
||||
└── ruoyi-workflow-api/ # 工作流API模块
|
||||
├── pom.xml
|
||||
└── src/main/java/org/ruoyi/workflow/
|
||||
├── entity/ # 实体类
|
||||
├── dto/ # 数据传输对象
|
||||
├── service/ # 服务接口
|
||||
├── mapper/ # 数据访问层
|
||||
├── workflow/ # 工作流核心逻辑
|
||||
├── enums/ # 枚举类
|
||||
├── util/ # 工具类
|
||||
└── exception/ # 异常处理
|
||||
```
|
||||
|
||||
### 2. 核心依赖
|
||||
|
||||
- **LangGraph4j**: 1.5.3 - 工作流图执行引擎
|
||||
- **LangChain4j**: 1.2.0 - AI 模型集成框架
|
||||
- **Spring Boot**: 3.x - 应用框架
|
||||
- **MyBatis Plus**: 数据访问层
|
||||
- **Redis**: 缓存和状态管理
|
||||
- **Swagger/OpenAPI**: API 文档
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 工作流管理
|
||||
|
||||
#### 1.1 工作流定义
|
||||
|
||||
- **创建工作流**: 支持自定义标题、描述、公开性设置
|
||||
- **编辑工作流**: 可视化节点编辑、连接线配置
|
||||
- **版本控制**: 支持工作流的版本管理和回滚
|
||||
- **权限管理**: 支持公开/私有工作流设置
|
||||
|
||||
#### 1.2 工作流执行
|
||||
|
||||
- **流式执行**: 基于 SSE 的实时流式响应
|
||||
- **状态管理**: 完整的执行状态跟踪
|
||||
- **错误处理**: 详细的错误信息和异常处理
|
||||
- **中断恢复**: 支持工作流中断和恢复执行
|
||||
|
||||
### 2. 节点类型
|
||||
|
||||
#### 2.1 基础节点
|
||||
|
||||
- **Start**: 开始节点,定义工作流入口
|
||||
- **End**: 结束节点,定义工作流出口
|
||||
|
||||
#### 2.2 AI 模型节点
|
||||
|
||||
- **Answer**: 大语言模型问答节点
|
||||
- **Dalle3**: DALL-E 3 图像生成
|
||||
- **Tongyiwanx**: 通义万相图像生成
|
||||
- **Classifier**: 内容分类节点
|
||||
|
||||
#### 2.3 数据处理节点
|
||||
|
||||
- **DocumentExtractor**: 文档信息提取
|
||||
- **KeywordExtractor**: 关键词提取
|
||||
- **FaqExtractor**: 常见问题提取
|
||||
- **KnowledgeRetrieval**: 知识库检索
|
||||
|
||||
#### 2.4 控制流节点
|
||||
|
||||
- **Switcher**: 条件分支节点
|
||||
- **HumanFeedback**: 人机交互节点
|
||||
|
||||
#### 2.5 外部集成节点
|
||||
|
||||
- **Google**: Google 搜索集成
|
||||
- **MailSend**: 邮件发送
|
||||
- **HttpRequest**: HTTP 请求
|
||||
- **Template**: 模板转换
|
||||
|
||||
### 3. 数据流管理
|
||||
|
||||
#### 3.1 输入输出定义
|
||||
|
||||
```java
|
||||
// 节点输入输出数据结构
|
||||
public class NodeIOData {
|
||||
private String name; // 参数名称
|
||||
private NodeIODataContent content; // 参数内容
|
||||
}
|
||||
|
||||
// 支持的数据类型
|
||||
public enum WfIODataTypeEnum {
|
||||
TEXT, // 文本
|
||||
NUMBER, // 数字
|
||||
BOOLEAN, // 布尔值
|
||||
FILES, // 文件
|
||||
OPTIONS // 选项
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 参数引用
|
||||
|
||||
- **节点间引用**: 支持上游节点输出作为下游节点输入
|
||||
- **参数映射**: 自动处理参数名称映射
|
||||
- **类型转换**: 自动进行数据类型转换
|
||||
|
||||
## 数据库设计
|
||||
|
||||
### 1. 核心表结构
|
||||
|
||||
#### 1.1 工作流定义表 (t_workflow)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
title VARCHAR(100) NOT NULL DEFAULT '',
|
||||
remark TEXT NOT NULL DEFAULT '',
|
||||
user_id BIGINT NOT NULL DEFAULT 0,
|
||||
is_public TINYINT(1) NOT NULL DEFAULT 0,
|
||||
is_enable TINYINT(1) NOT NULL DEFAULT 1,
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_deleted TINYINT(1) NOT NULL DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
#### 1.2 工作流节点表 (t_workflow_node)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_node (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
workflow_id BIGINT NOT NULL DEFAULT 0,
|
||||
workflow_component_id BIGINT NOT NULL DEFAULT 0,
|
||||
user_id BIGINT NOT NULL DEFAULT 0,
|
||||
title VARCHAR(100) NOT NULL DEFAULT '',
|
||||
remark VARCHAR(500) NOT NULL DEFAULT '',
|
||||
input_config JSON NOT NULL DEFAULT ('{}'),
|
||||
node_config JSON NOT NULL DEFAULT ('{}'),
|
||||
position_x DOUBLE NOT NULL DEFAULT 0,
|
||||
position_y DOUBLE NOT NULL DEFAULT 0,
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_deleted TINYINT(1) NOT NULL DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
#### 1.3 工作流边表 (t_workflow_edge)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_edge (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
workflow_id BIGINT NOT NULL DEFAULT 0,
|
||||
source_node_uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
source_handle VARCHAR(32) NOT NULL DEFAULT '',
|
||||
target_node_uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_deleted TINYINT(1) NOT NULL DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
#### 1.4 工作流运行时表 (t_workflow_runtime)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_runtime (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
uuid VARCHAR(32) NOT NULL DEFAULT '',
|
||||
user_id BIGINT NOT NULL DEFAULT 0,
|
||||
workflow_id BIGINT NOT NULL DEFAULT 0,
|
||||
input JSON NOT NULL DEFAULT ('{}'),
|
||||
output JSON NOT NULL DEFAULT ('{}'),
|
||||
status SMALLINT NOT NULL DEFAULT 1,
|
||||
status_remark VARCHAR(250) NOT NULL DEFAULT '',
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_deleted TINYINT(1) NOT NULL DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
#### 1.5 工作流组件表 (t_workflow_component)
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_workflow_component (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
uuid VARCHAR(32) DEFAULT '' NOT NULL,
|
||||
name VARCHAR(32) DEFAULT '' NOT NULL,
|
||||
title VARCHAR(100) DEFAULT '' NOT NULL,
|
||||
remark TEXT NOT NULL,
|
||||
display_order INT DEFAULT 0 NOT NULL,
|
||||
is_enable TINYINT(1) DEFAULT 0 NOT NULL,
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
is_deleted TINYINT(1) DEFAULT 0 NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
## API 接口
|
||||
|
||||
### 1. 工作流管理接口
|
||||
|
||||
#### 1.1 基础操作
|
||||
|
||||
```http
|
||||
# 创建工作流
|
||||
POST /workflow/add
|
||||
Content-Type: application/json
|
||||
{
|
||||
"title": "工作流标题",
|
||||
"remark": "工作流描述",
|
||||
"isPublic": false
|
||||
}
|
||||
|
||||
# 更新工作流
|
||||
POST /workflow/update
|
||||
Content-Type: application/json
|
||||
{
|
||||
"uuid": "工作流UUID",
|
||||
"title": "新标题",
|
||||
"remark": "新描述"
|
||||
}
|
||||
|
||||
# 删除工作流
|
||||
POST /workflow/del/{uuid}
|
||||
|
||||
# 启用/禁用工作流
|
||||
POST /workflow/enable/{uuid}?enable=true
|
||||
```
|
||||
|
||||
#### 1.2 搜索和查询
|
||||
|
||||
```http
|
||||
# 搜索我的工作流
|
||||
GET /workflow/mine/search?keyword=关键词&isPublic=true¤tPage=1&pageSize=10
|
||||
|
||||
# 搜索公开工作流
|
||||
GET /workflow/public/search?keyword=关键词¤tPage=1&pageSize=10
|
||||
|
||||
# 获取工作流组件列表
|
||||
GET /workflow/public/component/list
|
||||
```
|
||||
|
||||
### 2. 工作流执行接口
|
||||
|
||||
#### 2.1 流式执行
|
||||
|
||||
```http
|
||||
# 流式执行工作流
|
||||
POST /workflow/run
|
||||
Content-Type: application/json
|
||||
Accept: text/event-stream
|
||||
{
|
||||
"uuid": "工作流UUID",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "input",
|
||||
"content": {
|
||||
"type": 1,
|
||||
"textContent": "用户输入内容"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 运行时管理
|
||||
|
||||
```http
|
||||
# 恢复中断的工作流
|
||||
POST /workflow/runtime/resume/{runtimeUuid}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"feedbackContent": "用户反馈内容"
|
||||
}
|
||||
|
||||
# 查询工作流执行历史
|
||||
GET /workflow/runtime/page?wfUuid=工作流UUID¤tPage=1&pageSize=10
|
||||
|
||||
# 查询运行时节点详情
|
||||
GET /workflow/runtime/nodes/{runtimeUuid}
|
||||
|
||||
# 清理运行时数据
|
||||
POST /workflow/runtime/clear?wfUuid=工作流UUID
|
||||
```
|
||||
|
||||
### 3. 管理端接口
|
||||
|
||||
#### 3.1 工作流管理
|
||||
|
||||
```http
|
||||
# 搜索所有工作流
|
||||
POST /admin/workflow/search
|
||||
Content-Type: application/json
|
||||
{
|
||||
"title": "搜索关键词",
|
||||
"isPublic": true,
|
||||
"isEnable": true
|
||||
}
|
||||
|
||||
# 启用/禁用工作流
|
||||
POST /admin/workflow/enable?uuid=工作流UUID&isEnable=true
|
||||
```
|
||||
|
||||
## 核心实现
|
||||
|
||||
### 1. 工作流引擎 (WorkflowEngine)
|
||||
|
||||
工作流引擎是整个模块的核心,负责:
|
||||
|
||||
- 工作流图的构建和编译
|
||||
- 节点执行调度
|
||||
- 状态管理和持久化
|
||||
- 流式输出处理
|
||||
|
||||
```java
|
||||
public class WorkflowEngine {
|
||||
// 核心执行方法
|
||||
public void run(User user, List<ObjectNode> userInputs, SseEmitter sseEmitter) {
|
||||
// 1. 验证工作流状态
|
||||
// 2. 创建运行时实例
|
||||
// 3. 构建状态图
|
||||
// 4. 执行工作流
|
||||
// 5. 处理流式输出
|
||||
}
|
||||
|
||||
// 恢复执行方法
|
||||
public void resume(String userInput) {
|
||||
// 1. 更新状态
|
||||
// 2. 继续执行
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 节点工厂 (WfNodeFactory)
|
||||
|
||||
节点工厂负责根据组件类型创建对应的节点实例:
|
||||
|
||||
```java
|
||||
public class WfNodeFactory {
|
||||
public static AbstractWfNode create(WorkflowComponent component,
|
||||
WorkflowNode node,
|
||||
WfState wfState,
|
||||
WfNodeState nodeState) {
|
||||
// 根据组件类型创建对应的节点实例
|
||||
switch (component.getName()) {
|
||||
case "Answer":
|
||||
return new LLMAnswerNode(component, node, wfState, nodeState);
|
||||
case "Switcher":
|
||||
return new SwitcherNode(component, node, wfState, nodeState);
|
||||
// ... 其他节点类型
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 图构建器 (WorkflowGraphBuilder)
|
||||
|
||||
图构建器负责将工作流定义转换为可执行的状态图:
|
||||
|
||||
```java
|
||||
public class WorkflowGraphBuilder {
|
||||
public StateGraph<WfNodeState> build(WorkflowNode startNode) {
|
||||
// 1. 构建编译节点树
|
||||
// 2. 转换为状态图
|
||||
// 3. 添加节点和边
|
||||
// 4. 处理条件分支
|
||||
// 5. 处理并行执行
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 流式响应机制
|
||||
|
||||
### 1. SSE 事件类型
|
||||
|
||||
工作流执行过程中会发送多种类型的 SSE 事件:
|
||||
|
||||
```javascript
|
||||
// 节点开始执行
|
||||
[NODE_RUN_节点UUID] - 节点执行开始事件
|
||||
|
||||
// 节点输入数据
|
||||
[NODE_INPUT_节点UUID] - 节点输入数据事件
|
||||
|
||||
// 节点输出数据
|
||||
[NODE_OUTPUT_节点UUID] - 节点输出数据事件
|
||||
|
||||
// 流式内容块
|
||||
[NODE_CHUNK_节点UUID] - 流式内容块事件
|
||||
|
||||
// 等待用户输入
|
||||
[NODE_WAIT_FEEDBACK_BY_节点UUID] - 等待用户输入事件
|
||||
```
|
||||
|
||||
### 2. 流式处理流程
|
||||
|
||||
1. **初始化**: 创建工作流运行时实例
|
||||
2. **节点执行**: 逐个执行工作流节点
|
||||
3. **实时输出**: 通过 SSE 实时推送执行结果
|
||||
4. **状态更新**: 实时更新节点和工作流状态
|
||||
5. **错误处理**: 捕获并处理执行过程中的错误
|
||||
|
||||
## 扩展开发
|
||||
|
||||
### 1. 自定义节点开发
|
||||
|
||||
要开发自定义工作流节点,需要:
|
||||
|
||||
1. **创建节点类**:继承 `AbstractWfNode`
|
||||
2. **实现处理逻辑**:重写 `onProcess()` 方法
|
||||
3. **定义配置类**:创建节点配置类
|
||||
4. **注册组件**:在组件表中注册新组件
|
||||
|
||||
```java
|
||||
public class CustomNode extends AbstractWfNode {
|
||||
@Override
|
||||
protected NodeProcessResult onProcess() {
|
||||
// 实现自定义处理逻辑
|
||||
List<NodeIOData> outputs = new ArrayList<>();
|
||||
// ... 处理逻辑
|
||||
return NodeProcessResult.success(outputs);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 自定义组件注册
|
||||
|
||||
```sql
|
||||
-- 在 t_workflow_component 表中添加新组件
|
||||
INSERT INTO t_workflow_component (uuid, name, title, remark, is_enable)
|
||||
VALUES (REPLACE(UUID(), '-', ''), 'CustomNode', '自定义节点', '自定义节点描述', true);
|
||||
```
|
||||
Reference in New Issue
Block a user