diff --git a/src/.vuepress/layouts/Layout.vue b/src/.vuepress/layouts/Layout.vue
index 3d967adf9a52d4575881de3fee549f489c9c7129..5f47fb7ff0d9ce9a44a8ff5f1cb7d1f1a0c8b1c6 100644
--- a/src/.vuepress/layouts/Layout.vue
+++ b/src/.vuepress/layouts/Layout.vue
@@ -17,9 +17,6 @@ const sidebarTopArray = [
`
`,
- `
-
- `,
];
const sidebarContent = ref("");
diff --git a/src/.vuepress/navbar.ts b/src/.vuepress/navbar.ts
index e8c7355bc3e134deb8a60a23d5b3758b49e6e476..4431fabec79a6082c3ccee3a5707a2ba758330a8 100644
--- a/src/.vuepress/navbar.ts
+++ b/src/.vuepress/navbar.ts
@@ -26,6 +26,7 @@ export default navbar([
text: '历史版本',
icon: '/icons/version.svg',
children: [
+ { text: 'v1.3.1', link: '/v1.3.1/guide/started.md' },
{ text: 'v1.3.0', link: '/v1.3.0/guide/started.md' },
{ text: 'v1.2.10', link: '/v1.2.10/guide/started.md' },
{ text: 'v1.2.8', link: '/v1.2.8/guide/started.md' },
diff --git a/src/.vuepress/sidebar.ts b/src/.vuepress/sidebar.ts
index 294e8100d0cee6bd9c328f9d5e9ef6eea803bf1d..9ecc21bba96d7a4aeb919a95e7e503850f2484f2 100644
--- a/src/.vuepress/sidebar.ts
+++ b/src/.vuepress/sidebar.ts
@@ -46,6 +46,7 @@ export default sidebar({
'/common/pr.md',
'/common/dromara.md',
'/common/joingroup.md',
+ '/common/paidservice.md',
],
},
{
@@ -87,6 +88,41 @@ export default sidebar({
link: '/common/support.md',
},
],
+ "/v1.3.1/guide/": [
+ {
+ text: "基础部分",
+ icon: "bulb",
+ collapsible: false,
+ children: [
+ '/v1.3.1/guide/started.md',
+ '/v1.3.1/guide/processterm.md',
+ '/v1.3.1/guide/processrule.md',
+ '/v1.3.1/guide/processdemo.md',
+ '/v1.3.1/guide/table.md',
+ '/v1.3.1/guide/config.md',
+ '/v1.3.1/guide/api.md',
+ '/v1.3.1/guide/datafillhandler.md',
+ '/v1.3.1/guide/variable.md',
+ '/v1.3.1/guide/variableStategy.md',
+ '/v1.3.1/guide/ormusagetips.md',
+ '/v1.3.1/guide/designerIntroduced.md',
+ ],
+ },
+ {
+ text: "进阶部分",
+ icon: "/icons/advanced.svg",
+ collapsible: false,
+ children: [
+ '/v1.3.1/guide/listener.md',
+ '/v1.3.1/guide/logicdelete.md',
+ '/v1.3.1/guide/tenant.md',
+ '/v1.3.1/guide/form.md',
+ '/v1.3.1/guide/customstatus.md',
+ '/v1.3.1/guide/expression.md',
+ '/v1.3.1/guide/jsonlib.md',
+ ],
+ }
+ ],
"/v1.3.0/guide/": [
{
text: "基础部分",
diff --git a/src/README.md b/src/README.md
index e9c32d62cce3456c80d211948969db752e9eee97..eda4cc07340d12819234d11402f8ead1b98e324d 100644
--- a/src/README.md
+++ b/src/README.md
@@ -39,7 +39,7 @@ features:
- title: 监听器与流程变量
icon: '/icons/listener.svg'
- details: 支持五种监听器,可应对不同场景,灵活可扩展,参数传递,动态权限
+ details: 支持四种监听器,可应对不同场景,灵活可扩展,参数传递,动态权限
- title: 流程设计器
icon: '/icons/flowchart.svg'
@@ -70,7 +70,7 @@ features:
details: 流程引擎自身维护多租户和软删除实现,也可使用对应orm框架的实现方式
copyright: false
-footer: Copyright © 2024 warm-flow|赣ICP备2021008655号-3
+footer: © 2024 Warm-Flow Project. All Rights Reserved Designed by xiaohua Member of Dromara
赣ICP备2021008655号-3
---
## **👍友情链接**
diff --git a/src/common/companyintegration.md b/src/common/companyintegration.md
index 626ae21793e745b7b3aa59bbe281afa461ae254d..c4b708d1c8a67734b6021fecbb7fcfeda5f2797a 100644
--- a/src/common/companyintegration.md
+++ b/src/common/companyintegration.md
@@ -1,25 +1,27 @@
# 公司使用列表
-| 公司/个人 | 项目名称 | 项目介绍 | LOGO\代码地址 |
-|-----------------------|---------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 安徽数智建造研究院有限公司 | 进销存运营平台 | 中铁四局集团全资子公司,集成工作流引擎 | |
-| 杭州三之一智联科技有限公司 | 质量管理系统 | 基于工业互联网的数字化安全与质量管理平台,集风险、质量和安全为一体,以CTQ(关键质量特性)为中心,端到端全生命周期数字化安全与质量管理。 | |
-| 郑州如阳科技有限公司 | 智慧燃气平台 | 智慧燃气平台 | |
-| 山东融佑信息科技有限公司 | 融运力TMS | 融运力TMS是基于移动互联网的面向货主侧需求的订单履约类的TMS系统,兼有传统TMS的竞标、派车、跟踪、签收等功能,同时具备企业ERP级的协同功能 | |
-| 陕西物联达智能科技有限公司 | entfrm-boot | 打造免费开源低代码平台 构建信创,开放生态 | |
+| 公司/个人 | 项目名称 | 项目介绍 | LOGO\代码地址 |
+|---------------|---------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 安徽数智建造研究院有限公司 | 进销存运营平台 | 中铁四局集团全资子公司,集成工作流引擎 | |
+| 杭州三之一智联科技有限公司 | 质量管理系统 | 基于工业互联网的数字化安全与质量管理平台,集风险、质量和安全为一体,以CTQ(关键质量特性)为中心,端到端全生命周期数字化安全与质量管理。 | |
+| 郑州如阳科技有限公司 | 智慧燃气平台 | 智慧燃气平台 | |
+| 山东融佑信息科技有限公司 | 融运力TMS | 融运力TMS是基于移动互联网的面向货主侧需求的订单履约类的TMS系统,兼有传统TMS的竞标、派车、跟踪、签收等功能,同时具备企业ERP级的协同功能 | |
+| 陕西物联达智能科技有限公司 | entfrm-boot | 打造免费开源低代码平台 构建信创,开放生态 | |
| H5VE团队 | entfrm-boot | 打造免费开源低代码平台 构建信创,开放生态 | |
-| 抚顺银行 | 外围管理平台 | 行内人员使用 | |
-| 武汉数演科技有限公司 | 开源工作流 | 仿钉钉界面的开源工作流平台 | |
-| 半月无霜 | banmoon-test | 半月无霜个人项目 | https://www.banmoon.top |
-| 个人 | 海狼OA系统 | 海狼OA系统 | |
-| xx自来水股份有限公司 | 节水信息管理系统 | 当地节水系统 | |
-| 图灵谷 | 内部OA | 内部OA | |
-| 湖北建科工程 | 内部OA | 内部OA | |
-| Holly | 智慧政务 | 政务系统 | |
-| 雨巷 | OA审批系统 | 公司内部OA办公系统 | |
-| 暗影 | erp | erp | |
-| LYQ | XX单位综合信息服务系统 | 简易工作流,OA办公,数据共享等等 | |
-| 若愚 | 测试检测平台 | | |
-| starrydesert | 基于SSM的职工管理系统 | 毕业设计 | |
-| zyflzz | 基于机器学习的只能停车管理系统 | 毕业设计 | |
-| 南山客 | 基于SpringBoot的财务管理系统 | 本科毕业设计 | |
+| 抚顺银行 | 外围管理平台 | 行内人员使用 | |
+| 武汉数演科技有限公司 | 开源工作流 | 仿钉钉界面的开源工作流平台 | |
+| 半月无霜 | banmoon-test | 半月无霜个人项目 | https://www.banmoon.top |
+| 新理益智慧网络科技(重庆)有限公司 |极点OA智慧网络办公系统 | 企业综合办公管理系统 | |
+| 某某公司 | 合规管控系统 | 对各类事项进行检查,上报不合规的地方来审批整改 | |
+| 个人 | 海狼OA系统 | 海狼OA系统 | |
+| xx自来水股份有限公司 | 节水信息管理系统 | 当地节水系统 | |
+| 图灵谷 | 内部OA | 内部OA | |
+| 湖北建科工程 | 内部OA | 内部OA | |
+| Holly | 智慧政务 | 政务系统 | |
+| 雨巷 | OA审批系统 | 公司内部OA办公系统 | |
+| 暗影 | erp | erp | |
+| LYQ | XX单位综合信息服务系统 | 简易工作流,OA办公,数据共享等等 | |
+| 若愚 | 测试检测平台 | | |
+| starrydesert | 基于SSM的职工管理系统 | 毕业设计 | |
+| zyflzz | 基于机器学习的只能停车管理系统 | 毕业设计 | |
+| 南山客 | 基于SpringBoot的财务管理系统 | 本科毕业设计 | |
diff --git a/src/common/introduction.md b/src/common/introduction.md
index 30b2035b93a72a32b407dc3c8fd4b79a5c135171..bd8ecd67f426ce845ffd7f38b3d3d024d5e025cc 100644
--- a/src/common/introduction.md
+++ b/src/common/introduction.md
@@ -31,23 +31,39 @@
- 不可二次分发开源参与同类竞品,如有想法可联系290631660@qq.com商议合作。
- 若您的项目无法满足以上几点,需要更多功能代码,获取可找作者定制化开发,290631660@qq.com
-## 3、演示地址
+
+## 3、应用场景
+
+Warm-Flow作为一个国产的工作流引擎,其设计简洁轻量但功能全面,适用于多种应用场景,尤其是针对中小型项目。以下是一些典型的应用场景:
+
+1. 企业内部流程管理:用于管理企业的日常业务流程,如请假、报销、采购审批等。
+2. 项目管理:在项目管理中,Warm-Flow可以用来跟踪项目任务的状态,管理项目流程,确保项目按计划进行。
+3. 办公自动化:通过Warm-Flow,企业可以实现办公流程的自动化,提高工作效率,减少人为错误。
+4. 客户服务流程:用于管理客户服务请求,如客户咨询、投诉处理、售后服务等。
+5. 人力资源管理:在人力资源管理中,Warm-Flow可用于员工招聘、培训、绩效评估等流程的管理。
+6. 财务和会计流程:管理财务审批流程,如发票审核、预算审批等。
+7. IT服务管理:用于IT服务请求的处理,如IT支持请求、系统变更管理等。
+8. 业务流程优化:企业可以利用Warm-Flow来分析和优化现有业务流程,提高业务效率。
+9. 合规性和风险管理:帮助企业在遵守法规和标准的同时,管理风险和合规流程。
+10. 跨部门协作:Warm-Flow支持跨部门的流程协作,帮助不同部门之间更好地协调工作。
+
+
+## 4、演示地址
- admin/admin123
演示地址:http://www.hhzai.top
-## 4、特别赞助
+## 5、特别赞助
[如何成为赞助商 加群联系作者详谈](./joingroup.md)
-## 5、你可以请作者喝杯咖啡表示鼓励
+## 6、你可以请作者喝杯咖啡表示鼓励
[捐赠地址](./support.md)
-
diff --git a/src/common/joingroup.md b/src/common/joingroup.md
index ab26cccb0335e6751bbfb7a970305d78acd92511..1c3e737b02a27a5f5f494a7ed80a94664ec234bd 100644
--- a/src/common/joingroup.md
+++ b/src/common/joingroup.md
@@ -1,25 +1,9 @@
# 加入群聊
## 交流群
-**微信群 : 【warm-houhou】**
-**qq群 : 【778470567】**
-**微信公众号 : 【warm-flow工作流】**
-
-
-## VIP群(付费加群,提供工作流相关问题解答,技术分享)
-- 项目代码、文档 均开源免费可商用 遵循开源协议
-- VIP群是作者提供的私人服务 不代表着项目收费
+**微信群 : 【warm-houhou】**
-**支付后加微信号【warm-houhou】加vip群即可**
+**qq群 : 【778470567】**
-> 问问题等于做习题 听作者解答问题等于习题讲解
-> 一个人接触的问题有限 一群人接触的问题无限 早进群早接触更多的问题
-> 承诺: 看见必回复 让你感受作者有多话痨
+**微信公众号 : 【warm-flow工作流】**
-**加群扫码:99元**
-
-
- |
- |
-
-
diff --git a/src/common/paidservice.md b/src/common/paidservice.md
new file mode 100644
index 0000000000000000000000000000000000000000..7f5bc1d7a8d87fe5f45ba066088d176875569dd6
--- /dev/null
+++ b/src/common/paidservice.md
@@ -0,0 +1,37 @@
+# 有偿服务
+
+## VIP群
+
+- 项目代码、文档,均开源免费可商用,遵循开源协议,不代表着项目收费
+
+- VIP群由四名后端与一名前端工程师组成,提供问题答疑服务和技术分享等服务,欢迎加群交流
+
+
+
+**支付后加微信号【warm-houhou】,邀请进入vip群**
+
+> 问问题等于做习题 听作者解答问题等于习题讲解
+> 一个人接触的问题有限 一群人接触的问题无限 早进群早接触更多的问题
+> 承诺: 看见必回复 让你感受作者有多话痨
+
+**加群扫码: 99元**
+
+
+ |
+ |
+
+
+
+
+
+## 私人服务
+
+- 作者提供作者私人服务,提供关于Warm-Flow工作流相关问题解答,如流程引擎集成与使用,技术咨询等,包括但不限于
+
+
+
+## 特别赞助
+
+- 如需Warm-Flow官网挂广告,请加微信号【warm-houhou】联系我
+
+
diff --git a/src/common/update.md b/src/common/update.md
index 84deffc0cb838d819b2bb15c7ce4023c0c7ec721..b5baf6594a1d19bf72f7d7231b65550a33cef55e 100644
--- a/src/common/update.md
+++ b/src/common/update.md
@@ -13,35 +13,59 @@
- 可多个网关直连
- 重启流程
- 适配国产数据库
+ - 包容网关
## 开发中计划
-### v1.3.2 2024-11-18
-- 【升级注意事项】
+### v1.3.3 2024-11-18
+- 【升级指南】
- 无
- 更新日志
- 动态表单支持 @vanlin
- - 对代码通过工具进行扫描,并解决漏洞 @晓华
- - 增加单元测试 @晓华
-
-### v1.3.1 2024-11-01
-- 【升级注意事项】
+ - 流程定义数据保存支持json格式 @晓华
+ -
+### v1.3.2 2024-11-18
+- 【升级指南】
- 无
- 更新日志
- 撤销 @xiarigang
- 取回 @xiarigang
- 新增流程图元数据 @晓华
- - 流程图片清晰度调整 @晓华
- - 流程定义数据保存支持json格式 @晓华
- - 对代码通过工具进行扫描,并解决漏洞 @晓华
- - 增加单元测试 @晓华
-
+ - 流程定义数据保存支持json格式 @xiarigang
+ - 接入仿钉钉设计器 @晓华
+
## 更新日志
+### v1.3.1 2024-10-31
+- 【升级指南】
+ - 节点详情进入改为双击
+ - 终止操作的流程状态改为更合理的终止状态,如需还想按照原本的自动完成,请使用自定义流程状态
+ - FlowParams对象删除setXxx(yyy)方法,改为xxx(yyy)方法赋值
+ - 转办、委派、加签和减签方法,老方法标识即将删除, 请尽快使用新的接口
+ - 终止免校验权限改为设置ignore字段
+ - 设计器引入优化
+ - 设计器后端放行地址`/warm-flow/**`删除,不再需要
+ - 前端加载设计器代理配置,vue.config.js或者nginx中的代理,`/warm-flow-ui/`删除,不再需要
+ - iframe中访问设计器接口由`/warm-flow-ui/${definitionId}?disabled=${disabled}`,改为VUE_APP_BASE_API + `/warm-flow-ui/index.html?id=${definitionId}&disabled=${disabled}`
+ - VUE_APP_BASE_API是前端访问前缀比如`prod-api`
+
+- 更新日志
+ - [feat] 新增boot3+java17支持
+ - [feat] 流程设计器新增快捷键支持
+ - [feat] 新增流程状态枚举(终止、作废、撤销和取回)
+ - [feat] 新增转办、委派、加签和减签方法,老方法标识即将删除,接入监听器
+ - [update] 终止流程状态改为更合理的终止状态
+ - [update] 流程复制克隆改set/get赋值
+ - [refactor] 重构skip等方法通用校验
+ - [perf] 流程图清晰度调整
+ - [fix] 流程图查询异常处理
+ - [fix] 修复历史记录表,创建时间和更新时间一样的问题
+ - [remove] FlowParams对象删除setXxx(yyy)方法,改为xxx(yyy)方法赋值
+
### v1.3.0 2024-10-23
-- 【升级注意事项】
+- 【升级指南】
- 执行升级脚本【warm-flow_1.3.0.sql】
- 更新日志
@@ -54,14 +78,14 @@
- [fix] 更新时间有值时,取更新时间,不是创建时间
### v1.2.10 2024-09-26
-- 【升级注意事项】
+- 【升级指南】
- 无
- 更新日志
- [fix] 修复mybatis-plus扩展包,配置了其他id策略不生效的问题
### v1.2.8 2024-09-25
-- 【升级注意事项】
+- 【升级指南】
- 本次升级,内置json库snack3方式,改为spi方式加载,业务项目中存在哪种json就会使用哪种的实现,
支持顺序按顺序加载一种:snack3、jackson、fastjson、gson,并且目前只实现了这四种,可扩展
- 如在未集成snack3库的环境下,还需要使用snack3库,需要单独使用(原组件使用snack3库)
@@ -87,7 +111,7 @@
- [refactor] 重构id生成器,支持orm默认策略,删除数据填充默认实现类,改为匿名类
### v1.2.7 2024-09-03
-- 【升级注意事项】
+- 【升级指南】
- 无
- 更新日志
@@ -97,7 +121,7 @@
- [fix] 修复全局监听器导出失败的问题
### v1.2.6 2024-08-28
- - 【升级注意事项】
+ - 【升级指南】
- 执行升级脚本【warm-flow_1.2.6.sql】
- 流程状态字段flow_status改为string类型,业务系统需要对应修改
@@ -117,7 +141,7 @@
- [fix] 修复 并行网关三个任务分支的时候,错误结束流程的问题
### v1.2.4 2024-08-14
- - 【升级注意事项】
+ - 【升级指南】
- 执行升级脚本【warm-flow_1.2.4.sql】
- 流程定义表from_custom改为form_custom,from_path改为form_path,涉及到这两个字段的前后段都要修改
- 反显审批流程表单,改为通过task表新增的form_custom和form_path字段
@@ -170,7 +194,7 @@
- [fix] 修复保存流程xml报错问题
### v1.2.1 2024-06-28
- - 【升级注意事项】
+ - 【升级指南】
- 执行升级脚本【warm-flow_1.2.1.sql】
- 更新日志
@@ -191,7 +215,7 @@
- [fix] 修复userMapper.xml中updateLogic的某个负值错误
### v1.2.0 2024-06-13
- - 【升级注意事项】
+ - 【升级指南】
- 执行升级脚本【warm-flow_1.2.0.sql】
- 工具包路径调整
@@ -205,7 +229,7 @@
- pg适配
### v1.1.9 2024-05-08
- - 【升级注意事项】
+ - 【升级指南】
- 执行升级脚本【warm-flow_1.1.90.sql】
- 更新日志
diff --git a/src/master/guide/config.md b/src/master/guide/config.md
index 120c2b513a12b1dd11655a88842c8cbecf8dae9a..c29bbf919c292ec62f73fd99f75cf8be34138f1a 100644
--- a/src/master/guide/config.md
+++ b/src/master/guide/config.md
@@ -8,6 +8,8 @@ warm-flow:
enabled: true
# 是否显示banner图,默认是
banner: true
+ # 是否开启设计器ui,默认true
+ ui: true
# id生成器类型, 不填默认为orm扩展自带生成器或者warm-flow内置的19位雪花算法, SnowId14:14位,SnowId15:15位, SnowFlake19:19位
key_type: SnowId19
# 填充器,内部有默认实现,如果不满足实际业务,可通过此配置自定义实现
diff --git a/src/master/guide/ormusagetips.md b/src/master/guide/ormusagetips.md
index 711132652d00d82d97d794c53fd500fbaa0c8761..03844a8029557a27a408c5c7928a47934de4398c 100644
--- a/src/master/guide/ormusagetips.md
+++ b/src/master/guide/ormusagetips.md
@@ -80,4 +80,4 @@ private FlowTaskMapper taskMapper;
// 第二种方式
FlowDefinitionMapper definitionMapper = FrameInvoker.getBean(FlowDefinitionMapper.class);
-```
\ No newline at end of file
+```
diff --git a/src/master/guide/started.md b/src/master/guide/started.md
index 7a6ea01ce31c7cfad7d22b000cd32adb461d88aa..0acc15f7c61442410a77672b0a25ff1903457a11 100644
--- a/src/master/guide/started.md
+++ b/src/master/guide/started.md
@@ -33,7 +33,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -43,7 +43,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -54,7 +54,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-plus-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -64,7 +64,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-plus-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -83,7 +83,7 @@ springboot项目
io.github.minliuhua
warm-flow-jpa-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -93,7 +93,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-plus-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -104,7 +104,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-flex-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -114,7 +114,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-flex-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -125,7 +125,7 @@ springboot项目
io.github.minliuhua
warm-flow-easy-query-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -145,7 +145,7 @@ solon项目
solon.logging
- 1.3.0-m2
+ 1.3.0
```
diff --git "a/src/master/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md" "b/src/master/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md"
index 5e1cfc1f5da225f27ad181c4ec9c0f944a9706ff..0835f6dd265506173af2178692b374a747f77017 100644
--- "a/src/master/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md"
+++ "b/src/master/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md"
@@ -18,7 +18,6 @@
```
## 2. 后端放行部分路径
-> [!IMPORTANT]
> 1、这两个路径需要放行,否则无法访问,`/warm-flow-ui/**`, `/warm-flow/**`
> 2、以下是spring-security放行配置示例
@@ -42,7 +41,6 @@ protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exce
```
## 3. 前端加载设计器
-> [!IMPORTANT]
> 1、设计器页面入口地址为:`/warm-flow-ui/${definitionId}?disabled=${disabled}`
> 2、总体思路就是把前端接口(比如80)代理成后端接口(8080),去访问该地址,其他不变
> 3、或者直接通过后端接口访问该地址,可能需要处理跨域问题
@@ -61,7 +59,6 @@ server {
## 4. 设计器办理人权限数据接入
-> [!IMPORTANT]
> 给任务节点设置哪些权限的人可以办理,实现接口提供给设计器
### 4.1 办理人权限选择弹框页面
@@ -97,7 +94,6 @@ public interface HandlerSelectService {
## 5、项目介绍
-> [!IMPORTANT]
> Warm-Flow国产工作流引擎🎉,其特点简洁轻量,五脏俱全,可扩展,是一个可通过jar引入设计器的工作流。
1. 简洁易用:只有7张表,代码量少,可快速上手和集成
diff --git a/src/v1.2.10/guide/jsonlib.md b/src/v1.2.10/guide/jsonlib.md
index bdd8243c07c436b725241398cb9404992591863d..4a7b819416c8ab65791e7860d3cbd18669fd1a13 100644
--- a/src/v1.2.10/guide/jsonlib.md
+++ b/src/v1.2.10/guide/jsonlib.md
@@ -53,4 +53,4 @@ public class JsonConvertJackson implements JsonConvert {
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.10/guide/ormusagetips.md b/src/v1.2.10/guide/ormusagetips.md
index 711132652d00d82d97d794c53fd500fbaa0c8761..03844a8029557a27a408c5c7928a47934de4398c 100644
--- a/src/v1.2.10/guide/ormusagetips.md
+++ b/src/v1.2.10/guide/ormusagetips.md
@@ -80,4 +80,4 @@ private FlowTaskMapper taskMapper;
// 第二种方式
FlowDefinitionMapper definitionMapper = FrameInvoker.getBean(FlowDefinitionMapper.class);
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.3/guide/ormusagetips.md b/src/v1.2.3/guide/ormusagetips.md
index 251adcaf36e1c89f92cd3191e43986a7ac17b3f9..eaefbc9ca3b351429c8192948fa7caf0f4408fc3 100644
--- a/src/v1.2.3/guide/ormusagetips.md
+++ b/src/v1.2.3/guide/ormusagetips.md
@@ -65,4 +65,4 @@ entityManager.createQuery(criteriaUpdate).executeUpdate()
QueryWrapper queryWrapper = QueryWrapper.create();
queryWrapper.in(FlowDefinition::getFlowCode, flowCodeList);
definitionMapper.selectListByQueryAs(queryWrapper);
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.4/guide/config.md b/src/v1.2.4/guide/config.md
index a4fe33257b4538d8ca949f6a186e1c3089eecf0c..53817513caefb3f482181cd714ce94ee5967c63d 100644
--- a/src/v1.2.4/guide/config.md
+++ b/src/v1.2.4/guide/config.md
@@ -103,4 +103,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.4/guide/ormusagetips.md b/src/v1.2.4/guide/ormusagetips.md
index 256c21fc756b069d7406a051ea8aa41d325da002..906043d58f5c5c8226c368a5741aadef46206a37 100644
--- a/src/v1.2.4/guide/ormusagetips.md
+++ b/src/v1.2.4/guide/ormusagetips.md
@@ -75,4 +75,4 @@ entityManager.createQuery(criteriaUpdate).executeUpdate()
QueryWrapper queryWrapper = QueryWrapper.create();
queryWrapper.in(FlowDefinition::getFlowCode, flowCodeList);
definitionMapper.selectListByQueryAs(queryWrapper);
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.4/guide/tenant.md b/src/v1.2.4/guide/tenant.md
index b74068450dffb5a10ac13c6944af67b8e12545d2..cc1ae56cd8569978513423da530494e4595a2f4b 100644
--- a/src/v1.2.4/guide/tenant.md
+++ b/src/v1.2.4/guide/tenant.md
@@ -169,4 +169,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.6/guide/config.md b/src/v1.2.6/guide/config.md
index c3fa53d6a997577ae993c1555f4b3f41dc8990ac..68cb947073773c7e3d3a2e77fdf6fd438f4a6aa2 100644
--- a/src/v1.2.6/guide/config.md
+++ b/src/v1.2.6/guide/config.md
@@ -105,4 +105,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.6/guide/ormusagetips.md b/src/v1.2.6/guide/ormusagetips.md
index 256c21fc756b069d7406a051ea8aa41d325da002..906043d58f5c5c8226c368a5741aadef46206a37 100644
--- a/src/v1.2.6/guide/ormusagetips.md
+++ b/src/v1.2.6/guide/ormusagetips.md
@@ -75,4 +75,4 @@ entityManager.createQuery(criteriaUpdate).executeUpdate()
QueryWrapper queryWrapper = QueryWrapper.create();
queryWrapper.in(FlowDefinition::getFlowCode, flowCodeList);
definitionMapper.selectListByQueryAs(queryWrapper);
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.6/guide/tenant.md b/src/v1.2.6/guide/tenant.md
index 2c077650f16567479e4778adf1d592b2520e88c0..57c365e35f7343e4be2b52881fae9a81cf47fdd9 100644
--- a/src/v1.2.6/guide/tenant.md
+++ b/src/v1.2.6/guide/tenant.md
@@ -171,4 +171,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.7/guide/config.md b/src/v1.2.7/guide/config.md
index c3fa53d6a997577ae993c1555f4b3f41dc8990ac..68cb947073773c7e3d3a2e77fdf6fd438f4a6aa2 100644
--- a/src/v1.2.7/guide/config.md
+++ b/src/v1.2.7/guide/config.md
@@ -105,4 +105,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.7/guide/ormusagetips.md b/src/v1.2.7/guide/ormusagetips.md
index 256c21fc756b069d7406a051ea8aa41d325da002..906043d58f5c5c8226c368a5741aadef46206a37 100644
--- a/src/v1.2.7/guide/ormusagetips.md
+++ b/src/v1.2.7/guide/ormusagetips.md
@@ -75,4 +75,4 @@ entityManager.createQuery(criteriaUpdate).executeUpdate()
QueryWrapper queryWrapper = QueryWrapper.create();
queryWrapper.in(FlowDefinition::getFlowCode, flowCodeList);
definitionMapper.selectListByQueryAs(queryWrapper);
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.8/guide/config.md b/src/v1.2.8/guide/config.md
index faed2a974221ab64c77be11b0c4da5eb9bdcc1e8..ae7b54f2dd5375fbd7447e2eff7decfd07fb770a 100644
--- a/src/v1.2.8/guide/config.md
+++ b/src/v1.2.8/guide/config.md
@@ -105,4 +105,4 @@ public class WarmFlowConfig {
return new CustomTenantHandler();
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.8/guide/jsonlib.md b/src/v1.2.8/guide/jsonlib.md
index bdd8243c07c436b725241398cb9404992591863d..4a7b819416c8ab65791e7860d3cbd18669fd1a13 100644
--- a/src/v1.2.8/guide/jsonlib.md
+++ b/src/v1.2.8/guide/jsonlib.md
@@ -53,4 +53,4 @@ public class JsonConvertJackson implements JsonConvert {
}
}
-```
\ No newline at end of file
+```
diff --git a/src/v1.2.8/guide/ormusagetips.md b/src/v1.2.8/guide/ormusagetips.md
index 711132652d00d82d97d794c53fd500fbaa0c8761..03844a8029557a27a408c5c7928a47934de4398c 100644
--- a/src/v1.2.8/guide/ormusagetips.md
+++ b/src/v1.2.8/guide/ormusagetips.md
@@ -80,4 +80,4 @@ private FlowTaskMapper taskMapper;
// 第二种方式
FlowDefinitionMapper definitionMapper = FrameInvoker.getBean(FlowDefinitionMapper.class);
-```
\ No newline at end of file
+```
diff --git a/src/v1.3.0/guide/api.md b/src/v1.3.0/guide/api.md
index 534f399e1c3283c7b8c3ac382da3baedb76f9b43..1735eae684349440ce001540d265a9567cbc59ec 100644
--- a/src/v1.3.0/guide/api.md
+++ b/src/v1.3.0/guide/api.md
@@ -12,8 +12,8 @@
### 1.3、保存流程定义
`saveXml(id, xmlString)`: 传入流程定义id、流程定义xml字符串,保存流程定义数据
-- id: 流程定义id [必传]
-- xmlString: 流程定义xml字符串 [必传]
+- id: 流程定义id
+- xmlString: 流程定义xml字符串
### 1.4、导出流程定义
`exportXml(id)`: 导出流程定义xml的Document对象
@@ -55,19 +55,19 @@
### 2.2、流程跳转
`skipByInsId(instanceId, flowParams)`:传入流程实例id,流程跳转。flowParams包含如下字段:
- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
-- nodeCode: 节点编码 [如果指定节点,可任意跳转到对应节点,按需传输]
-- permissionFlag: 办理人权限标识,比如用户,角色,部门等[只有未设置办理人时可不传]
+- nodeCode: 节点编码,如果指定节点,可任意跳转到对应节点 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等 [只有未设置办理人时可不传]
- message: 审批意见 [按需传输]
- handler: 办理人唯一标识 [建议传]
- variable: 流程变量 [按需传输]
-- flowStatus: 流程状态,自定义流程状态[按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
### 2.3、终止流程
`termination(instanceId, flowParams)`:传入流程实例id,终止流程。flowParams包含如下字段:
-- message: 审批意见 [按需传输]
- handler: 办理人唯一标识 [建议传]
-- flowStatus: 流程状态,自定义流程状态[按需传输]
-- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限[按需传输]
+- message: 审批意见 [按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限 [按需传输]
### 2.4、删除流程实例
`remove(instanceIds)`:根据实例ids,删除流程
@@ -83,19 +83,19 @@
### 3.1、流程跳转
`skip(taskId, flowParams)`:传入流程任务id,流程跳转。flowParams包含如下字段:
- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
-- nodeCode: 节点编码 [如果指定节点,可任意跳转到对应节点,按需传输]
-- permissionFlag: 办理人权限标识,比如用户,角色,部门等[只有未设置办理人时可不传]
+- nodeCode: 节点编码,如果指定节点,可任意跳转到对应节点 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等 [只有未设置办理人时可不传]
- message: 审批意见 [按需传输]
- handler: 办理人唯一标识 [建议传]
- variable: 流程变量 [按需传输]
-- flowStatus: 流程状态,自定义流程状态[按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
### 3.2、终止流程
`termination(taskId, flowParams)`:传入流程任务id,终止流程。flowParams包含如下字段:
- message: 审批意见 [按需传输]
- handler: 办理人唯一标识 [建议传]
-- flowStatus: 流程状态,自定义流程状态[按需传输]
-- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限[按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限 [按需传输]
### 3.3、转办
`transfer(taskId, curUser, permissionFlag, addHandlers, message)`:转办, 默认删除当然办理用户权限,转办后,当前办理不可办理
@@ -144,77 +144,77 @@
`getNextNodeList(definitionId, nowNodeCode, anyNodeCode, skipType, variable)`:根据流程定义和当前节点code获取下一节点,如是网关跳过取下一节点,并行网关返回多个节点
- definitionId: 流程定义id [必传]
- nowNodeCode: 当前节点code [必传]
-- anyNodeCode: anyNodeCode不为空,则可跳转anyNodeCode节点(优先级最高) [按需传输]
- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
+- anyNodeCode: anyNodeCode不为空,则可跳转anyNodeCode节点(优先级最高) [按需传输]
- variable: 流程变量,下一个节点是网关需要判断跳转条件,并行网关返回多个节点 [按需传输]
## 5、公共api接口
### 5.1、根据id查询
`getById(id)`:根据id查询
-- id: 主键 [必传]
+- id: 主键
### 5.2、根据ids主键集合查询
`getByIds(ids)`:根据ids主键集合查询
-- ids: 主键集合 [必传]
+- ids: 主键集合
### 5.3、分页查询
`getById(entity, page)`:分页查询
-- entity: 查询实体 [必传]
-- page: 分页对象,支持设置排序字段 [必传]
+- entity: 查询实体
+- page: 分页对象,支持设置排序字段
### 5.4、查询列表
`list(entity)`:查询列表
-- entity: 查询实体 [必传]
+- entity: 查询实体
### 5.5、查询列表,可排序
`list(entity, query)`:查询列表,可排序
-- entity: 查询实体 [必传]
-- query: 查询代理层处理,支持设置排序字段 [必传]
+- entity: 查询实体
+- query: 查询代理层处理,支持设置排序字段
### 5.6、查询一条记录
`getOne(entity)`:查询一条记录
-- entity 查询实体 [必传]
+- entity 查询实体
### 5.7、获取总数量
`selectCount(entity)`:获取总数量
-- entity: 查询实体 [必传]
+- entity: 查询实体
### 5.8、判断是否存在
`exists(entity)`:判断是否存在
-- entity: 查询实体 [必传]
+- entity: 查询实体
### 5.8、新增
`save(entity)`:新增
-- entity: 实体 [必传]
+- entity: 实体
### 5.9、根据id修改
`updateById(entity)`:根据id修改
-- entity: 实体 [必传]
+- entity: 实体
### 5.10、根据id删除
`removeById(id)`:根据id删除
-- id: 实体 [必传]
+- id: 实体
### 5.11、根据entity删除
`remove(entity)`:根据entity删除
-- entity: 实体 [必传]
+- entity: 实体
### 5.12、根据ids批量删除
`removeByIds(ids)`:根据ids批量删除
-- ids: 实体 [必传]
+- ids: 实体
### 5.13、批量新增
`saveBatch(list)`:批量新增
-- list: 实体集合 [必传]
+- list: 实体集合
### 5.14、批量新增
`saveBatch(list, batchSize)`:批量新增
-- list: 需要插入的集合数据 [必传]
-- batchSize: 插入大小 [必传]
+- list: 需要插入的集合数据
+- batchSize: 插入大小
### 5.15、批量更新
`updateBatch(list)`:批量更新
-- list: 集合数据 [必传]
+- list: 集合数据
### 5.16、id设置正序排列
`orderById()`:id设置正序排列
@@ -227,12 +227,12 @@
### 5.19、设置正序排列
`orderByAsc(orderByField)`:设置正序排列
-- orderByField: 排序字段 [必传]
+- orderByField: 排序字段
### 5.20、设置倒序排列
`orderByDesc(orderByField)`:设置倒序排列
-- orderByField: 排序字段 [必传]
+- orderByField: 排序字段
### 5.21、用户自定义排序方案
`orderBy(orderByField)`:用户自定义排序方案
-- orderByField: 排序字段 [必传]
+- orderByField: 排序字段
diff --git a/src/v1.3.0/guide/config.md b/src/v1.3.0/guide/config.md
index 120c2b513a12b1dd11655a88842c8cbecf8dae9a..c29bbf919c292ec62f73fd99f75cf8be34138f1a 100644
--- a/src/v1.3.0/guide/config.md
+++ b/src/v1.3.0/guide/config.md
@@ -8,6 +8,8 @@ warm-flow:
enabled: true
# 是否显示banner图,默认是
banner: true
+ # 是否开启设计器ui,默认true
+ ui: true
# id生成器类型, 不填默认为orm扩展自带生成器或者warm-flow内置的19位雪花算法, SnowId14:14位,SnowId15:15位, SnowFlake19:19位
key_type: SnowId19
# 填充器,内部有默认实现,如果不满足实际业务,可通过此配置自定义实现
diff --git a/src/v1.3.0/guide/ormusagetips.md b/src/v1.3.0/guide/ormusagetips.md
index 711132652d00d82d97d794c53fd500fbaa0c8761..03844a8029557a27a408c5c7928a47934de4398c 100644
--- a/src/v1.3.0/guide/ormusagetips.md
+++ b/src/v1.3.0/guide/ormusagetips.md
@@ -80,4 +80,4 @@ private FlowTaskMapper taskMapper;
// 第二种方式
FlowDefinitionMapper definitionMapper = FrameInvoker.getBean(FlowDefinitionMapper.class);
-```
\ No newline at end of file
+```
diff --git a/src/v1.3.0/guide/started.md b/src/v1.3.0/guide/started.md
index 7a6ea01ce31c7cfad7d22b000cd32adb461d88aa..0acc15f7c61442410a77672b0a25ff1903457a11 100644
--- a/src/v1.3.0/guide/started.md
+++ b/src/v1.3.0/guide/started.md
@@ -33,7 +33,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -43,7 +43,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -54,7 +54,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-plus-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -64,7 +64,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-plus-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -83,7 +83,7 @@ springboot项目
io.github.minliuhua
warm-flow-jpa-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -93,7 +93,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-plus-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -104,7 +104,7 @@ springboot项目
io.github.minliuhua
warm-flow-mybatis-flex-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -114,7 +114,7 @@ solon项目
io.github.minliuhua
warm-flow-mybatis-flex-solon-plugin
- 1.3.0-m2
+ 1.3.0
```
@@ -125,7 +125,7 @@ springboot项目
io.github.minliuhua
warm-flow-easy-query-sb-starter
- 1.3.0-m2
+ 1.3.0
```
@@ -145,7 +145,7 @@ solon项目
solon.logging
- 1.3.0-m2
+ 1.3.0
```
diff --git a/src/v1.3.1/guide/api.md b/src/v1.3.1/guide/api.md
new file mode 100644
index 0000000000000000000000000000000000000000..6a1054c727afe81cc7441afeae3a6481b757181e
--- /dev/null
+++ b/src/v1.3.1/guide/api.md
@@ -0,0 +1,245 @@
+# 核心api
+
+## 1、DefService流程定义接口
+
+### 1.1、新增流程定义表数据,新增后需要通过saveXml接口保存流程节点和流程跳转数据
+`checkAndSave(definition)`:校验后新增
+
+### 1.1、新增流程定义、流程节点和流程跳转数据
+`importXml(is)`:导入流程定义xml的输入流
+
+### 1.2、保存流程节点和流程跳转数据
+`saveXml(def)`: 传入流程定义id、流程定义xml字符串
+- id: 流程定义id [必传]
+- xmlString: 流程定义xml字符串 [必传]
+
+### 1.3、保存流程节点和流程跳转数据
+`saveXml(id, xmlString)`: 传入流程定义id、流程定义xml字符串
+- id: 流程定义id
+- xmlString: 流程定义xml字符串
+
+### 1.4、导出流程定义
+`exportXml(id)`: 导出流程定义(流程定义、流程节点和流程跳转数据)xml的Document对象
+
+### 1.5、获取流程定义
+`xmlString(id)`: 获取流程定义xml(流程定义、流程节点和流程跳转数据)的字符串
+
+### 1.6、删除
+`removeDef(ids)`: 删除流程定义相关数据
+
+### 1.7、发布
+`publish(id)`: 发布流程定义
+
+### 1.8、取消发布
+`unPublish(id)`: 取消发布流程定义
+
+### 1.9、复制流程
+`copyDef(id)`: 复制流程定义
+
+### 1.10、获取流程图
+`flowChart(instanceId)`: 获取流程图的图片流
+
+### 1.11、激活流程
+`active(Long id)`: 激活流程
+
+### 1.12、挂起流程
+`unActive(Long id)`: 挂起流程:流程定义挂起后,相关的流程实例都无法继续流转
+
+## 2、InsService流程实例接口
+
+### 2.1、开启流程
+`start(businessId, flowParams)`:传入业务id,开启流程实例。flowParams包含如下字段:
+- flowCode: 流程编码 [必传]
+- handler: 办理人唯一标识 [建议传]
+- variable: 流程变量 [按需传输]
+- ext: 扩展字段,预留给业务系统使用 [按需传输]
+- flowStatus: 流程状态,自定义流程状态[按需传输]
+
+### 2.2、流程跳转
+`skipByInsId(instanceId, flowParams)`:传入流程实例id,流程跳转。flowParams包含如下字段:
+- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
+- nodeCode: 节点编码,如果指定节点,可任意跳转到对应节点 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等 [只有未设置办理人时可不传]
+- message: 审批意见 [按需传输]
+- handler: 办理人唯一标识 [建议传]
+- variable: 流程变量 [按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 2.3、终止流程
+`termination(instanceId, flowParams)`:传入流程实例id,终止流程。flowParams包含如下字段:
+- handler: 办理人唯一标识 [建议传]
+- message: 审批意见 [按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 2.4、删除流程实例
+`remove(instanceIds)`:根据实例ids,删除流程
+
+### 2.5、激活实例
+`active(Long id)`: 激活实例
+
+### 2.6、挂起实例
+`unActive(Long id)`: 挂起实例,流程实例挂起后,该流程实例无法继续流转
+
+## 3、TaskService待办任务接口
+
+### 3.1、流程跳转
+`skip(taskId, flowParams)`:传入流程任务id,流程跳转。flowParams包含如下字段:
+- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
+- nodeCode: 节点编码,如果指定节点,可任意跳转到对应节点 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等 [只有未设置办理人时可不传]
+- message: 审批意见 [按需传输]
+- handler: 办理人唯一标识 [建议传]
+- variable: 流程变量 [按需传输]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.2、终止流程
+`termination(taskId, flowParams)`:传入流程任务id,终止流程。flowParams包含如下字段:
+- message: 审批意见 [按需传输]
+- handler: 办理人唯一标识 [建议传]
+- flowStatus: 流程状态,自定义流程状态 [按需传输]
+- permissionFlag: 办理人权限标识,比如用户,角色,部门等,不传不校验权限 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.3、转办
+`transfer(taskId, flowParams)`:转办, 默认删除当然办理用户权限,转办后,当前办理不可办理。flowParams包含如下字段:
+- handler: 当前办理人唯一标识 [必传]
+- permissionFlag: 用户权限标识集合 [必传]
+- addHandlers: 转办对象 [必传]
+- message: 审批意见 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.4、委派
+`depute(taskId, flowParams)`:委派, 默认删除当然办理用户权限,委派后,当前办理不可办理。flowParams包含如下字段:
+- handler: 当前办理人唯一标识 [必传]
+- permissionFlag: 用户权限标识集合 [必传]
+- addHandlers: 委托对象 [必传]
+- message: 审批意见 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.5、加签
+`addSignature(taskId, flowParams)`:加签,增加办理人。flowParams包含如下字段:
+- handler: 当前办理人唯一标识 [必传]
+- permissionFlag: 用户权限标识集合 [必传]
+- addHandlers: 加签对象 [必传]
+- message: 审批意见 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.6、减签
+`reductionSignature(taskId, flowParams)`:减签,减少办理人。flowParams包含如下字段:
+- handler: 当前办理人唯一标识 [必传]
+- permissionFlag: 用户权限标识集合 [必传]
+- reductionHandlers: 减少办理人 [必传]
+- message: 审批意见 [按需传输]
+- ignore: 转办忽略权限校验,默认不忽略(true:忽略,false:不忽略)[按需传输]
+
+### 3.7、修改办理人
+`updateHandler(taskId, flowParams)`:传入流程任务id,修改办理人
+- handler: 办理人唯一标识 [按需传输]
+- permissionFlag: 用户所拥有的权限标识 [按需传输,ignore为false,则必传]
+- addHandlers: 增加办理人:加签,转办,委托 [按需传输]
+- reductionHandlers: 减少办理人:减签,委托 [按需传输]
+- message: 审批意见 [按需传输]
+- cooperateType: 协作方式(2转办 3委派 6加签 7减签)[按需传输]
+- ignore: 转办忽略权限校验(true:忽略,false:不忽略)[按需传输]
+
+## 4、NodeService节点接口
+### 4.1、获取下一个节点列表
+`getNextNodeList(definitionId, nowNodeCode, anyNodeCode, skipType, variable)`:根据流程定义和当前节点code获取下一节点,如是网关跳过取下一节点,并行网关返回多个节点
+- definitionId: 流程定义id [必传]
+- nowNodeCode: 当前节点code [必传]
+- skipType: 跳转类型(PASS审批通过 REJECT退回) [必传]
+- anyNodeCode: anyNodeCode不为空,则可跳转anyNodeCode节点(优先级最高) [按需传输]
+- variable: 流程变量,下一个节点是网关需要判断跳转条件,并行网关返回多个节点 [按需传输]
+
+## 5、公共api接口
+### 5.1、根据id查询
+`getById(id)`:根据id查询
+- id: 主键
+
+### 5.2、根据ids主键集合查询
+`getByIds(ids)`:根据ids主键集合查询
+- ids: 主键集合
+
+### 5.3、分页查询
+`getById(entity, page)`:分页查询
+- entity: 查询实体
+- page: 分页对象,支持设置排序字段
+
+### 5.4、查询列表
+`list(entity)`:查询列表
+- entity: 查询实体
+
+### 5.5、查询列表,可排序
+`list(entity, query)`:查询列表,可排序
+- entity: 查询实体
+- query: 查询代理层处理,支持设置排序字段
+
+### 5.6、查询一条记录
+`getOne(entity)`:查询一条记录
+- entity 查询实体
+
+### 5.7、获取总数量
+`selectCount(entity)`:获取总数量
+- entity: 查询实体
+
+### 5.8、判断是否存在
+`exists(entity)`:判断是否存在
+- entity: 查询实体
+
+### 5.8、新增
+`save(entity)`:新增
+- entity: 实体
+
+### 5.9、根据id修改
+`updateById(entity)`:根据id修改
+- entity: 实体
+
+### 5.10、根据id删除
+`removeById(id)`:根据id删除
+- id: 实体
+
+### 5.11、根据entity删除
+`remove(entity)`:根据entity删除
+- entity: 实体
+
+### 5.12、根据ids批量删除
+`removeByIds(ids)`:根据ids批量删除
+- ids: 实体
+
+### 5.13、批量新增
+`saveBatch(list)`:批量新增
+- list: 实体集合
+
+### 5.14、批量新增
+`saveBatch(list, batchSize)`:批量新增
+- list: 需要插入的集合数据
+- batchSize: 插入大小
+
+### 5.15、批量更新
+`updateBatch(list)`:批量更新
+- list: 集合数据
+
+### 5.16、id设置正序排列
+`orderById()`:id设置正序排列
+
+### 5.17、创建时间设置正序排列
+`orderByCreateTime()`:创建时间设置正序排列
+
+### 5.18、更新时间设置正序排列
+`orderByUpdateTime()`:更新时间设置正序排列
+
+### 5.19、设置正序排列
+`orderByAsc(orderByField)`:设置正序排列
+- orderByField: 排序字段
+
+### 5.20、设置倒序排列
+`orderByDesc(orderByField)`:设置倒序排列
+- orderByField: 排序字段
+
+### 5.21、用户自定义排序方案
+`orderBy(orderByField)`:用户自定义排序方案
+- orderByField: 排序字段
diff --git a/src/v1.3.1/guide/config.md b/src/v1.3.1/guide/config.md
new file mode 100644
index 0000000000000000000000000000000000000000..e3c1d40a98d348531bf32dc134ecc8402ab03cce
--- /dev/null
+++ b/src/v1.3.1/guide/config.md
@@ -0,0 +1,125 @@
+# 配置文件
+## 1、spring
+### 1.1、yaml配置方式
+```yml
+# warm-flow工作流配置
+warm-flow:
+ # 是否开启工作流,默认true
+ enabled: true
+ # 是否显示banner图,默认是
+ banner: true
+ # 是否开启设计器ui,默认true
+ ui: true
+ # id生成器类型, 不填默认为orm扩展自带生成器或者warm-flow内置的19位雪花算法, SnowId14:14位,SnowId15:15位, SnowFlake19:19位
+ key_type: SnowId19
+ # 填充器,内部有默认实现,如果不满足实际业务,可通过此配置自定义实现
+ data-fill-handler-path: com.ruoyi.system.handle.CustomDataFillHandler
+ # 全局租户处理器,有多租户需要,可以配置自定义实现
+ tenant_handler_path: com.ruoyi.system.handle.CustomTenantHandler
+ # 是否开启逻辑删除(orm框架本身不支持逻辑删除,可通过这种方式开启)
+ logic_delete: true
+ # 逻辑删除字段值(开启后默认为2)
+ logic_delete_value: 2
+ # 逻辑未删除字段(开启后默认为0)
+ logic_not_delete_value: 0
+ # 当使用JPA时指定JpaPersistenceProvider
+ jpa_persistence_provider: org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider
+ # 内部已实现自动获取,失效时使用此配置(在使用mybatis扩展包时, 由于各数据库sql语句存在差异, 通过此配置兼容,默认为mysql)
+ data_source_type: mysql
+```
+
+### 1.2、bean配置方式
+```java
+@Configuration
+public class WarmFlowConfig {
+
+ /**
+ * 自定义填充 (可配置文件注入,也可用@Bean/@Component方式)
+ */
+ @Bean
+ public DataFillHandler dataFillHandler() {
+ return new CustomDataFillHandler();
+ }
+
+ /**
+ * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ */
+ @Bean
+ public TenantHandler tenantHandler() {
+ return new CustomTenantHandler();
+ }
+}
+
+/**
+ * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ *
+ * @author warm
+ */
+public class CustomTenantHandler implements TenantHandler {
+
+
+ @Override
+ public String getTenantId() {
+ return "000000";
+ }
+}
+
+```
+
+## 2、solon
+### 2.1、yaml配置方式
+```yaml
+# warm-flow工作流配置
+warm-flow:
+ # 是否显示banner图,默认是
+ banner: true
+ # # 填充器,内部有默认实现,如果不满足实际业务,可通过此配置自定义实现
+ # data-fill-handler-path: org.dromara.warm.flow.core.test.handle.CustomDataFillHandler
+ # 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ # tenant_handler_path: org.dromara.warm.flow.core.test.handle.CustomTenantHandler
+ # 是否开启逻辑删除(orm框架本身不支持逻辑删除,可通过这种方式开启,比如jpa)
+ logic_delete: false
+ # 逻辑删除字段值(开启后默认为2)
+ logic_delete_value: 2
+ # 逻辑未删除字段(开启后默认为0)
+ logic_not_delete_value: 0
+
+# warm-flow-jpa 的hibernate jpa配置 此处属于固定配置
+warm-flow-jpa:
+# jpa 与 数据源绑定,此处填写数据源名称
+ datasource: db1
+# hibernate 配置配置
+ properties:
+ hibernate:
+ hbm2ddl:
+ auto: none
+ show_sql: true
+ format_sql: true
+ dialect: org.hibernate.dialect.MySQL8Dialect
+ connection:
+ isolaction: 4 # 事务隔离级别 4 可重复度
+
+```
+
+### 2.1、bean配置方式
+```java
+@Configuration
+public class WarmFlowConfig {
+
+ /**
+ * 自定义填充 (可配置文件注入,也可用@Bean/@Component方式)
+ */
+ @Bean
+ public DataFillHandler dataFillHandler() {
+ return new CustomDataFillHandler();
+ }
+
+ /**
+ * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ */
+ @Bean
+ public TenantHandler tenantHandler() {
+ return new CustomTenantHandler();
+ }
+}
+```
diff --git a/src/v1.3.1/guide/customstatus.md b/src/v1.3.1/guide/customstatus.md
new file mode 100644
index 0000000000000000000000000000000000000000..a0b1f5b8d27f5a4b1656c5c75f512c40becb269d
--- /dev/null
+++ b/src/v1.3.1/guide/customstatus.md
@@ -0,0 +1,46 @@
+# 自定义流程状态
+
+> [!IMPORTANT]
+> 1、flowStatus:流程实例表状态,当前流程状态
+> 2、hisStatus:历史任务表状态,过程状态记录,按照自身业务要求,可以语流程实例状态不同
+
+
+## 1、开启流程
+
+```java
+ public void insertTestLeave(TestLeave testLeave, Integer flowStatus)
+ {
+ String id = IdUtils.nextIdStr();
+ testLeave.setId(id);
+ LoginUser user = SecurityUtils.getLoginUser();
+ FlowParams flowParams = FlowParams.build().flowCode(getFlowType(testLeave))
+ .handler(user.getUser().getUserId().toString());
+
+ // 自定义流程状态扩展,flowStatus与hisStatus可以不同
+ if (Objects.nonNull(flowStatus)) {
+ flowParams.flowStatus(flowStatus).hisStatus(flowStatus);
+ }
+
+ Instance instance = insService.start(id, flowParams);
+ }
+```
+
+## 2、流程跳转
+
+```java
+ // 自定义流程状态扩展,flowStatus与hisStatus可以不同
+ if (Objects.nonNull(flowStatus)) {
+ flowParams.flowStatus(flowStatus).hisStatus(flowStatus);
+ }
+ Instance instance = insService.skipByInsId(testLeave.getInstanceId(), flowParams);
+```
+
+```java
+ // 自定义流程状态扩展,flowStatus与hisStatus可以不同
+ if (Objects.nonNull(flowStatus)) {
+ flowParams.flowStatus(flowStatus).hisStatus(flowStatus);
+ }
+ Instance instance = taskService.skip(taskId, flowParams);
+```
+
+## 3、其他请查阅核心api
diff --git a/src/v1.3.1/guide/datafillhandler.md b/src/v1.3.1/guide/datafillhandler.md
new file mode 100644
index 0000000000000000000000000000000000000000..c01decc95a5e3bd6272f4a544a1aea4fe0ecd767
--- /dev/null
+++ b/src/v1.3.1/guide/datafillhandler.md
@@ -0,0 +1,61 @@
+# 填充器
+> [!IMPORTANT]
+> 1、如果觉得内置的id、创建时间和更新时间自动生成规则,不符合业务要求,可通过填充器覆盖
+
+## 1、自定义填充器,并继承DataFillHandler
+```java
+public class CustomDataFillHandler implements DataFillHandler {
+
+ @Override
+ public void idFill(Object object) {
+ RootEntity entity = (RootEntity) object;
+ if (ObjectUtil.isNotNull(entity)) {
+ if (Objects.isNull(entity.getId())) {
+ entity.setId(IdUtils.nextId());
+ }
+ }
+ }
+
+ @Override
+ public void insertFill(Object object) {
+ RootEntity entity = (RootEntity) object;
+ if (ObjectUtil.isNotNull(entity)) {
+ Date date = ObjectUtil.isNotNull(entity.getCreateTime())? entity.getCreateTime() : new Date();
+ entity.setCreateTime(date);
+ entity.setUpdateTime(date);
+ }
+ }
+
+ @Override
+ public void updateFill(Object object) {
+ RootEntity entity = (RootEntity) object;
+ if (ObjectUtil.isNotNull(entity)) {
+ entity.setUpdateTime(ObjectUtil.isNotNull(entity.getUpdateTime()) ? entity.getCreateTime() : new Date());
+ }
+ }
+}
+
+```
+
+## 2、注入bean
+### 2.1、通过@Component方式注入
+
+### 2.2、yaml配置方式
+```yml
+# warm-flow工作流配置
+warm-flow:
+ # 填充器,内部有默认实现,如果不满足实际业务,可通过此配置自定义实现
+ data-fill-handler-path: com.ruoyi.system.handle.CustomDataFillHandler
+```
+
+### 2.3、@Configuration+@Bean配置方式
+```java
+@Configuration
+public class WarmFlowConfig {
+
+ @Bean
+ public DataFillHandler dataFillHandler() {
+ return new CustomDataFillHandler();
+ }
+}
+```
diff --git a/src/v1.3.1/guide/designerIntroduced.md b/src/v1.3.1/guide/designerIntroduced.md
new file mode 100644
index 0000000000000000000000000000000000000000..69b4d67f27a20095b43482011775756beb7ccee2
--- /dev/null
+++ b/src/v1.3.1/guide/designerIntroduced.md
@@ -0,0 +1,384 @@
+# 设计器引入
+> [!IMPORTANT]
+> 1、为了方便业务系统快速引入设计器,不需要搬运并且适配等工作
+> 2、可以按照本文中介绍的,使用设计器,并快速接入业务系统
+> 3、设计原理采取不分离的方式,把设计器打包的jar包中,以接口和静态资源的方式引入
+
+## 1. 引入依赖
+
+```xml
+
+ org.dromara
+ warm-flow-plugin-ui-sb-web
+ 版本号
+
+```
+
+## 2. 后端放行部分路径
+> 这个路径需要放行,否则无法访问,`/warm-flow-ui/**`
+
+### 2.1 spring-security 放行配置
+
+
+```java
+@Bean
+protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
+{
+ return httpSecurity
+ .......
+ // 注解标记允许匿名访问的url
+ .authorizeHttpRequests((requests) -> {
+ // 后端请求,静态资源,可匿名访问
+ requests.antMatchers("/warm-flow-ui/**").permitAll()
+ // 除上面外的所有请求全部需要鉴权认证
+ .anyRequest().authenticated();
+ })
+ ......
+ .build();
+}
+```
+
+
+### 2.2 shiro 放行配置
+
+
+```java
+@Configuration
+public class ShiroConfig {
+
+ /**
+ * Shiro过滤器配置
+ */
+ @Bean
+ public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
+ CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean();
+ ......
+ // 后端请求,静态资源,可匿名访问
+ LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();
+ filterChainDefinitionMap.put("/warm-flow-ui/**", "anon");
+
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
+ return shiroFilterFactoryBean;
+ }
+}
+```
+
+
+### 2.3 sa-token 放行配置
+
+```java
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+ // 注册拦截器
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
+ .addPathPatterns("/**")
+ // 以上是sa-token案例,下面才是需要排除的地址
+ .excludePathPatterns("/warm-flow-ui/**");
+ }
+}
+```
+
+## 3. 前端加载设计器
+> 1、设计器页面入口是访问后端地址(前后端不分离):`ip:port/warm-flow-ui/index?id=${definitionId}?disabled=${disabled}`
+
+### 3.2 vue2 引入
+
+- 首先传入设计器需要的流程定义definitionId和是否可编辑disabled参数
+- 本实例采用iframe方式嵌入设计器
+
+
+```vue
+
+
+
+
+
+
+
+```
+
+
+### 3.3 vue3 引入
+
+```vue
+
+
+
+
+
+
+
+
+
+
+```
+
+### 3.4 React版本 引入
+> 待完善
+
+### 3.5 前后端不分离版本
+- 可以直接访问后端接口加载页面,如:`ip:port/warm-flow-ui/index?id=${definitionId}?disabled=${disabled}`
+
+-
+```java
+@Controller
+@RequestMapping("/warm-flow")
+public class WarmFlowController
+{
+ @GetMapping()
+ public String index(String definitionId, Boolean disabled)
+ {
+ return redirect("/warm-flow-ui/index.html?id=" + definitionId + "&disabled=" + disabled);
+ }
+}
+```
+
+
+- 或者前端直接访问后端接口,如:`/warm-flow-ui/index.html?id=1839683148936663047&disabled=false`
+
+```javascript
+/*打开新的页签,加载设计器*/
+function detail(dictId) {
+ var url = prefix + '/detail/' + dictId;
+ $.modal.openTab("字典数据", "/warm-flow-ui/index.html?id=1839683148936663047&disabled=false");
+}
+
+```
+
+
+
+## 4. 设计器办理人权限数据接入
+> 给任务节点设置哪些权限的人可以办理,实现接口提供给设计器
+
+### 4.1 办理人权限选择弹框页面
+
+
+
+
+### 4.2 实现接口获取以上页面办理人权限数据
+
+#### 4.2.1 HandlerSelectService接口
+```java
+/**
+ * 流程设计器-获取办理人权限设置列表接口
+ *
+ * @author warm
+ */
+public interface HandlerSelectService {
+
+ /**
+ * 获取办理人权限设置列表tabs页签, 如:用户、角色和部门等
+ * @return tabs页签
+ */
+ List getHandlerType();
+
+ /**
+ * 获取办理人权限设置列表结果,如:用户列表、角色列表、部门列表等
+ * @param query 查询参数
+ * @return 结果
+ */
+ List getHandlerSelect(HandlerQuery query);
+}
+
+```
+
+
+#### 4.2.2 HandlerSelectServiceImpl实现类
+
+```java
+/**
+ * 流程设计器-获取办理人权限设置列表接口实现类
+ *
+ * @author warm
+ */
+@Component
+public class HandlerSelectServiceImpl implements HandlerSelectService {
+ @Autowired
+ private SysUserMapper userMapper;
+
+ @Autowired
+ private SysRoleMapper roleMapper;
+
+ @Autowired
+ private SysDeptMapper deptMapper;
+
+ /**
+ * 获取办理人权限设置列表tabs页签,如:用户、角色和部门等,可以返回其中一种或者多种,按业务需求决定
+ * @return tabs页签
+ */
+ @Override
+ public List getHandlerType() {
+ return Arrays.asList("用户", "角色", "部门");
+ }
+
+ /**
+ * 获取用户列表、角色列表、部门列表等,可以返回其中一种或者多种,按业务需求决定
+ * @param query 查询参数
+ * @return 结果
+ */
+ @Override
+ public HandlerSelectVo getHandlerSelect(HandlerQuery query) {
+
+ if ("角色".equals(query.getHandlerType())) {
+ return getRole(query);
+ }
+
+ if ("部门".equals(query.getHandlerType())) {
+ return getDept(query);
+ }
+
+ if ("用户".equals(query.getHandlerType())) {
+ return getUser(query);
+ }
+
+ return new HandlerSelectVo();
+ }
+
+ /**
+ * 获取角色列表
+ *
+ * @param query 查询条件
+ * @return HandlerSelectVo
+ */
+ private HandlerSelectVo getRole(HandlerQuery query) {
+ ......
+ // 查询角色列表
+ List roleList = roleMapper.selectRoleList(sysRole);
+ long total = new PageInfo<>(roleList).getTotal();
+
+ // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示
+ HandlerFunDto handlerFunDto = new HandlerFunDto<>(roleList, total)
+ // 以下设置获取内置变量的Function
+ .setStorageId(role -> "role:" + role.getRoleId()) // 前面拼接role: 是为了防止用户、角色的主键重复
+ .setHandlerCode(SysRole::getRoleKey) // 权限编码
+ .setHandlerName(SysRole::getRoleName) // 权限名称
+ .setCreateTime(role -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, role.getCreateTime()));
+
+ return getHandlerSelectVo(handlerFunDto);
+ }
+
+ /**
+ * 获取用户列表
+ *
+ * @param query 查询条件
+ * @return HandlerSelectVo
+ */
+ private HandlerSelectVo getDept(HandlerQuery query) {
+ ......
+ // 查询部门列表
+ List deptList = deptMapper.selectDeptList(sysDept);
+ long total = new PageInfo<>(deptList).getTotal();
+
+ // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示
+ HandlerFunDto handlerFunDto = new HandlerFunDto<>(deptList, total)
+ .setStorageId(dept -> "dept:" + dept.getDeptId()) // 前面拼接dept: 是为了防止用户、部门的主键重复
+ .setHandlerName(SysDept::getDeptName) // 权限名称
+ .setCreateTime(dept -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, dept.getCreateTime()));
+
+ return getHandlerSelectVo(handlerFunDto);
+
+ }
+
+ /**
+ * 获取用户列表, 同时构建左侧部门树状结构
+ *
+ * @param query 查询条件
+ * @return HandlerSelectVo
+ */
+ private HandlerSelectVo getUser(HandlerQuery query) {
+ ......
+ // 查询用户列表
+ List userList = userMapper.selectUserList(sysUser);
+ long total = new PageInfo<>(userList).getTotal();
+ // 查询部门列表,构建树状结构
+ List deptList = deptMapper.selectDeptList(new SysDept());
+
+ // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示
+ HandlerFunDto handlerFunDto = new HandlerFunDto<>(userList, total)
+ .setStorageId(user -> user.getUserId().toString())
+ .setHandlerCode(SysUser::getUserName) // 权限编码
+ .setHandlerName(SysUser::getNickName) // 权限名称
+ .setCreateTime(user -> DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, user.getCreateTime()))
+ .setGroupName(user -> user.getDept() != null ? user.getDept().getDeptName() : "");
+
+ // 业务系统机构,转成组件内部左侧树列表能够显示的数据
+ TreeFunDto treeFunDto = new TreeFunDto<>(deptList)
+ .setId(dept -> dept.getDeptId().toString()) // 左侧树ID
+ .setName(SysDept::getDeptName) // 左侧树名称
+ .setParentId(dept -> dept.getParentId().toString()); // 左侧树父级ID
+
+ return getHandlerSelectVo(handlerFunDto, treeFunDto);
+ }
+}
+```
diff --git a/src/v1.3.1/guide/expression.md b/src/v1.3.1/guide/expression.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3ec31d368534450a9688b4ed699d2223740cb09
--- /dev/null
+++ b/src/v1.3.1/guide/expression.md
@@ -0,0 +1,68 @@
+# 条件表达式
+
+## 1、内置表达式
+- 1、大于
+- 2、大于等于
+- 3、等于
+- 4、不等于
+- 5、小于
+- 6、小于等于
+- 7、包含
+- 8、不包含
+- 9、SpEL
+- 10、自定义表达式
+
+
+## 2、Spring Expression Language(SpEL)
+- 前端配置如`#{@user.eval(#flag)}`表达式,入库前要拼接前缀,方便区分表达式类型,最终为`@@spel@@|#{@user.eval(#flag)}`
+- `#flag`为变量和以下方法入参命名一致,可不设置入参
+
+
+
+```java
+@Component("user")
+public class User {
+
+ /**
+ * spel条件表达:判断大于等4
+ * @param flag 待判断的字符串
+ * @return boolean
+ */
+ public boolean eval(String flag) {
+ BigDecimal a = new BigDecimal(flag);
+ BigDecimal b = new BigDecimal("4");
+ return a.compareTo(b) > 0;
+ }
+}
+
+/**
+ * 新增OA 请假申请
+ *
+ * @param testLeave OA 请假申请
+ * @return 结果
+ */
+@Override
+public int insertTestLeave(TestLeave testLeave, String flowStatus)
+{
+ FlowParams flowParams = FlowParams.build().flowCode(getFlowType(testLeave));
+ // 流程变量
+ Map variable = new HashMap<>();
+ variable.put("flag", String.valueOf(testLeave.getDay()));
+ flowParams.variable(variable);
+
+ Instance instance = insService.start(id, flowParams);
+ return instance != null? 1 : 0;
+}
+```
+
+## 3、自定义表达式
+
+**1、扩展需要实现`ExpressionStrategy`接口或者继承`ExpressionStrategyAbstract`抽象类**
+**2、并且通过这个方法进行注册ExpressionUtil.setExpression**
+
+
+
+ |
+ |
+
+
diff --git a/src/v1.3.1/guide/flowchart.md b/src/v1.3.1/guide/flowchart.md
new file mode 100644
index 0000000000000000000000000000000000000000..baa51b37650026df48844d57475f3aa2df7c8bbf
--- /dev/null
+++ b/src/v1.3.1/guide/flowchart.md
@@ -0,0 +1,7 @@
+# 流程图
+
+流程图根据前端返回的节点坐标,通过后端Graphics2D进行绘制,最终返回图片给前端展示
+
+![输入图片说明](https://foruda.gitee.com/images/1703669461653266881/c3ddafb1_2218307.png "屏幕截图")
+
+![输入图片说明](https://foruda.gitee.com/images/1703669506555479009/bd1b51cf_2218307.png "屏幕截图")
\ No newline at end of file
diff --git a/src/v1.3.1/guide/form.md b/src/v1.3.1/guide/form.md
new file mode 100644
index 0000000000000000000000000000000000000000..cbb860fab1ab99c2d14469384ada0f8a2105d44c
--- /dev/null
+++ b/src/v1.3.1/guide/form.md
@@ -0,0 +1,3 @@
+# 表单管理
+
+
diff --git a/src/v1.3.1/guide/jsonlib.md b/src/v1.3.1/guide/jsonlib.md
new file mode 100644
index 0000000000000000000000000000000000000000..72ad9d0c3a71150022b80b34003197316bcb5863
--- /dev/null
+++ b/src/v1.3.1/guide/jsonlib.md
@@ -0,0 +1,56 @@
+# json库扩展
+
+> [!IMPORTANT]
+> 1、目前支持Snack3、Jackson、fastjson和Gson四种json库
+
+## json库扩展
+- 扩展json库需要实现`JsonConvert`接口,并实现`strToMap`和`mapToStr`方法
+- 并通过spi机制加载,可参照`warm-flow-plugin-json`模块
+- 在resource目录下新建`META-INF\services`文件夹,并在该文件夹下新建文件`org.dromara.warm.flow.core.json.JsonConvert`, 配置实现类的全限定名,如`org.dromara.warm.plugin.json.JsonConvertJackson`
+
+```java
+public class JsonConvertJackson implements JsonConvert {
+
+ private static final Logger log = LoggerFactory.getLogger(JsonConvertJackson.class);
+
+ /**
+ * 将字符串转为map
+ * @param jsonStr json字符串
+ * @return map
+ */
+ @Override
+ public Map strToMap(String jsonStr) {
+ if (StringUtils.isNotEmpty(jsonStr)) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ return objectMapper.readValue(jsonStr, TypeFactory.defaultInstance().constructMapType(Map.class, String.class, Object.class));
+ } catch (IOException e) {
+ log.error("json转换异常", e);
+ throw new FlowException("json转换异常");
+ }
+ }
+ return new HashMap<>();
+ }
+
+ /**
+ * 将map转为字符串
+ * @param variable map
+ * @return json字符串
+ */
+ @Override
+ public String mapToStr(Map variable) {
+ if (MapUtil.isNotEmpty(variable)) {
+ // 创建 ObjectMapper 实例
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ return objectMapper.writeValueAsString(variable);
+ } catch (Exception e) {
+ log.error("Map转换异常", e);
+ throw new FlowException("Map转换异常");
+ }
+ }
+ return null;
+ }
+
+}
+```
diff --git a/src/v1.3.1/guide/listener.md b/src/v1.3.1/guide/listener.md
new file mode 100644
index 0000000000000000000000000000000000000000..9fc3f032756c40d98d3a56a5b86385fa18716309
--- /dev/null
+++ b/src/v1.3.1/guide/listener.md
@@ -0,0 +1,216 @@
+# 监听器
+> [!IMPORTANT]
+> 1、在办理流程过程中,通过监听器,监听办理过程的不同环节,进行业务处理,功能增强。
+
+## 1、监听器类型
+> [!IMPORTANT]
+> create:创建监听器,任务创建时执行
+> start:开始监听器,任务开始办理时执行
+> permission:权限监听器,办理任务动态设置权限(后续不建议用)
+> assignment: 分派办理人监听器,动态修改代办任务信息
+> finish:结束监听器,当前任务完成后执行
+
+## 2、全局监听器和局部监听器
+> [!IMPORTANT]
+> 全局监听器和某个流程定义有关,局部监听器和某个节点有关
+> 执行顺序:优先执行局部监听器,然后执行全局监听器
+> 全局监听器:在流程定义中配置,所有节点任务都会执行
+> 局部监听器:在流程节点中配置,只有指定节点任务才会执行
+
+
+
+## 2、监听器生命周期图
+
+
+## 3、监听器使用
+### 3.1、实现以下接口
+```java
+/**
+ * 监听器接口
+ */
+public interface Listener extends Serializable {
+
+ /** 创建监听器,任务创建时执行 */
+ String LISTENER_CREATE = "create";
+
+ /** 开始监听器,任务开始办理时执行 */
+ String LISTENER_START = "start";
+
+ /**
+ * 结束监听器,当前任务完成后执行
+ */
+ String LISTENER_END = "finish";
+
+ /** 分派监听器,动态修改代办任务信息 */
+ String LISTENER_ASSIGNMENT = "assignment";
+
+ /** 权限监听器,办理任务动态设置权限(1.2.4版本后建议使用分派监听器修改办理人) */
+ String LISTENER_PERMISSION = "permission";
+
+ void notify(ListenerVariable variable);
+}
+
+```
+
+### 3.2、开始监听器实现类例子
+通过@Component或者@Bean注解注入到容器
+```java
+@Component
+public class GlobalStartListener implements Listener {
+
+
+ private static final Logger log = LoggerFactory.getLogger(GlobalStartListener.class);
+
+ /**
+ * 设置办理人id、所拥有的权限等操作,也可以放到业务代码中办理前设置,或者局部监听器
+ * @param listenerVariable 监听器变量
+ */
+ @Override
+ public void notify(ListenerVariable listenerVariable) {
+ log.info("全局开始监听器");
+
+ FlowParams flowParams = listenerVariable.getFlowParams();
+ LoginUser user = SecurityUtils.getLoginUser();
+ // 设置当前办理人id
+ flowParams.setHandler(user.getUser().getUserId().toString());
+
+ // 设置办理人所拥有的权限,比如角色、部门、用户等
+ List permissionList = flowParams.getPermissionFlag();
+ if (StringUtils.isEmpty(permissionList)) {
+ permissionList = new ArrayList<>();
+ }
+
+ List roles = user.getUser().getRoles();
+ if (Objects.nonNull(roles)) {
+ permissionList.addAll(roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList()));
+ }
+ permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId());
+ permissionList.add(user.getUser().getUserId().toString());
+ flowParams.setPermissionFlag(permissionList);
+
+ log.info("全局开始监听器结束;{}", "开启流程完成");
+ }
+}
+```
+
+### 3.3、完成监听器实现类例子
+```java
+@Component
+public class GlobalFinishListener implements Listener {
+
+
+ private static final Logger log = LoggerFactory.getLogger(GlobalFinishListener.class);
+
+ @Resource
+ private TestLeaveMapper testLeaveMapper;
+
+ /**
+ * 业务表新增或者更新操作,也可以放到业务代码中办理完成后,或者局部监听器
+ * @param listenerVariable 监听器变量
+ */
+ @Override
+ public void notify(ListenerVariable listenerVariable) {
+ log.info("全局完成监听器");
+ Instance instance = listenerVariable.getInstance();
+ Map variable = listenerVariable.getVariable();
+ Object o = variable.get("businessData");
+
+ // 更新业务数据
+ if (ObjectUtil.isNotNull(o)) {
+ // 可以统一使用一个全局监听器,不同实体类,不同的操作
+ if (o instanceof TestLeave) {
+ TestLeave testLeave = (TestLeave) o;
+ testLeave.setNodeCode(instance.getNodeCode());
+ testLeave.setNodeName(instance.getNodeName());
+ testLeave.setNodeType(instance.getNodeType());
+ testLeave.setFlowStatus(instance.getFlowStatus());
+ // 如果没有实例id,说明是新增
+ if (ObjectUtil.isNull(testLeave.getInstanceId())) {
+ testLeave.setInstanceId(instance.getId());
+ testLeaveMapper.insertTestLeave(testLeave);
+ testLeave.setCreateTime(DateUtils.getNowDate());
+ // 新增抄送人方法,也可发送通知
+ if (StringUtils.isNotNull(testLeave.getAdditionalHandler())) {
+ List users = FlowFactory.userService().structureUser(instance.getId()
+ , testLeave.getAdditionalHandler(), "4");
+ FlowFactory.userService().saveBatch(users);
+ }
+ } else {
+ testLeave.setUpdateTime(DateUtils.getNowDate());
+ testLeaveMapper.updateTestLeave(testLeave);
+ }
+ }
+ }
+
+ log.info("全局完成监听器结束;{}", "任务完成");
+ }
+}
+```
+
+### 3.4、分派监听器实现类例子
+如下图中示例可以很容易实现
+
+
+
+- 注意:
+ - 上个节点分派监听器修改:执行时修改【下个节点配置权限策略】
+ - 下个节点配置权限策略:可设置自定义权限策略,比如发起人审批,部门领导审批等
+```java
+@Component
+public class AssignmentListener implements Listener {
+
+ private static final Logger log = LoggerFactory.getLogger(AssignmentListener.class);
+
+ @Override
+ public void notify(ListenerVariable variable) {
+ log.info("分派监听器开始执行......");
+ List tasks = variable.getNextTasks();
+ Instance instance = variable.getInstance();
+ for (Task task : tasks) {
+ List permissionList = task.getPermissionList();
+ // 如果设置了发起人审批,则需要动态替换权限标识
+ for (int i = 0; i < permissionList.size(); i++) {
+ String permission = permissionList.get(i);
+ if (StringUtils.isNotEmpty(permission) && permission.contains(FlowCons.WARMFLOWINITIATOR)) {
+ permissionList.set(i, permission.replace(FlowCons.WARMFLOWINITIATOR, instance.getCreateBy()));
+ }
+ }
+ }
+ log.info("分派监听器执行结束......");
+ }
+}
+```
+
+### 3.5、创建监听器
+就是在下一个任务生成前执行,比如创建任务前需要初始化信息或者校验数据是否合法
+
+### 3.6、页面配置全局或局部监听器
+#### 3.6.1、局部监听器(流程节点配置)
+
+传递后台通过`@@`分割不同监听器,监听器类型和监听器路径,上下一一对应
+
+
+
+#### 3.6.1、全局监听器(流程定义配置)
+
+
+
+## 4、监听器参数使用
+
+页面配置监听器时加上类路径
+
+
+
+```java
+ public void notify(ListenerVariable variable) {
+ Instance instance = variable.getInstance();
+ Map variableMap = variable.getVariable();
+ // 拿到json后使用序列化可以拿到配置信息
+ Map variableMap = variable.getVariable();
+ if (MapUtil.isNotEmpty(variableMap)) {
+ Object o = variableMap.get(FlowCons.WARM_LISTENER_PARAM);
+ HashMap hashMap = JSONObject.parseObject(JSONObject.toJSONString(o), HashMap.class);
+ }
+ log.info("创建监听器结束");
+ }
+```
diff --git a/src/v1.3.1/guide/logicdelete.md b/src/v1.3.1/guide/logicdelete.md
new file mode 100644
index 0000000000000000000000000000000000000000..3220add9cb2ee29313c7652f2aec750223523241
--- /dev/null
+++ b/src/v1.3.1/guide/logicdelete.md
@@ -0,0 +1,41 @@
+# 逻辑删除
+
+## 1、Mybatis-plus
+> [!IMPORTANT]
+> 1、Mybatis-plus只支持自身的逻辑删除方式, 默认开启,目前不支持关闭
+> 2、默认逻辑未删除值:0,逻辑已删除值:1
+> 3、如需修改默认值,请参考如下配置文件中进行修改
+
+### 1.1、spring
+```yml
+# mybatis-plus配置
+mybatis-plus:
+ global-config:
+ db-config:
+ logic-delete-value: 2 # 逻辑已删除值
+ logic-not-delete-value: 0 # 逻辑未删除值
+```
+
+### 1.2、solon
+
+```yaml
+# 配置数据源对应的 mybatis 信息(要与 DataSource bean 的名字对上)
+mybatis.db1:
+ globalConfig: #全局配置(要与 GlobalConfig 类的属性一一对应)
+ banner: false
+ logicDeleteValue: 2 # 逻辑已删除值
+ logicNotDeleteValue: 0 # 逻辑未删除值
+```
+
+## 2、通用逻辑删除
+
+```yaml
+# warm-flow工作流配置
+warm-flow:
+ # 是否开启逻辑删除(orm框架本身不支持逻辑删除,可通过这种方式开启,比如jpa)
+ logic_delete: true
+ # 逻辑删除字段值(开启后默认为2)
+ logic_delete_value: 2
+ # 逻辑未删除字段(开启后默认为0)
+ logic_not_delete_value: 0
+```
diff --git a/src/v1.3.1/guide/ormusagetips.md b/src/v1.3.1/guide/ormusagetips.md
new file mode 100644
index 0000000000000000000000000000000000000000..8cd23c7ac23bb5585dc1c01c1985578d10cd706f
--- /dev/null
+++ b/src/v1.3.1/guide/ormusagetips.md
@@ -0,0 +1,83 @@
+# orm扩展包使用技巧
+- **常规增删改查可以通过注入方式,或者工具类获取service**
+```java
+// 第一种
+@Resource
+private DefService defService;
+
+// 第二种
+FlowFactory.defService()
+```
+- **但是由于不同orm框架的数据库操作的,接口使用方式不一致,所以可以通过以下方式获取对应的使用入口。**
+
+## 1、mybatis-plus
+
+**获取组件中的mapper,使用mybaits-plus的自带方法**
+```java
+
+// 第一种方式
+@Resource
+private FlowTaskMapper taskMapper;
+
+// 第二种方式
+FlowTaskMapper taskMapper = FrameInvoker.getBean(FlowTaskMapper.class);
+```
+
+## 2、JPA
+
+**注入 unitName=warm-flow-jpa EntityManager entityManager 对象**
+
+```java
+@PersistenceContext(unitName = "warm-flow-jpa")
+protected EntityManager entityManager;
+```
+**通过上述注解获取工作流组件内各Entity访问能力**
+```xml
+
+ org.dromara.warm.flow.orm.entity.FlowDefinition
+ org.dromara.warm.flow.orm.entity.FlowHisTask
+ org.dromara.warm.flow.orm.entity.FlowInstance
+ org.dromara.warm.flow.orm.entity.FlowNode
+ org.dromara.warm.flow.orm.entity.FlowSkip
+ org.dromara.warm.flow.orm.entity.FlowTask
+ org.dromara.warm.flow.orm.entity.FlowUser
+
+```
+**以下为主要接口示例,更多接口请参考 EntityManager 接口**
+```java
+@PersistenceContext(unitName = "warm-flow-jpa")
+protected EntityManager entityManager;
+
+FlowDefinition entity = dao.newEntity();
+// entity 字段填充
+// 持久化保存数据
+entityManager.persist(entity);
+
+// 通过主键查找数据
+FlowDefinition existEntity = entityManager.find(FlowDefinition.class, 1l);
+
+// 复杂查询语句通过 CriteriaQuery criteriaQuery
+CriteriaQuery criteriaQuery = ...
+// select语句获取结果
+entityManager.createQuery(criteriaQuery).getResultList();
+
+// 更新操作使用 CriteriaUpdate criteriaUpdate
+CriteriaUpdate criteriaUpdate = ...
+entityManager.createQuery(criteriaUpdate).executeUpdate()
+```
+**JPA注意事项** JPA涉及持久化操作必须开启事务 @Transactional(spring) @Tran(solon)
+
+
+## 3、mybatis-flex
+
+**获取组件中的mapper,使用mybaits-flex的自带方法**
+```java
+
+// 第一种方式
+@Resource
+private FlowTaskMapper taskMapper;
+
+// 第二种方式
+FlowDefinitionMapper definitionMapper = FrameInvoker.getBean(FlowDefinitionMapper.class);
+
+```
diff --git a/src/v1.3.1/guide/processdemo.md b/src/v1.3.1/guide/processdemo.md
new file mode 100644
index 0000000000000000000000000000000000000000..d482850f4646d1797decfcbe6e60f3f7f56fb0a6
--- /dev/null
+++ b/src/v1.3.1/guide/processdemo.md
@@ -0,0 +1,94 @@
+# 功能演示
+**以下演示基于项目示例hh-vue**
+> [!IMPORTANT]
+> 以下演示基于项目示例hh-vue
+
+## 演示图
+
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+
+
+## 1、新增定义
+
+流程编码和流程版本:确定唯一
+
+审批表单路径:记录待办任务需要显示的待办信息页面,点击待办时候获取这个路径,动态加载这个页面
+
+![输入图片说明](https://foruda.gitee.com/images/1703667450784737720/940b2bab_2218307.png "屏幕截图")
+
+## 2、流程设计
+### 2、1节点设置
+配置节点名称,协作方式(会签、票签和或签),节点权限,是否任意调整,监听器等
+
+![](../../.vuepress/public/defNode.png)
+
+### 2、2跳转线设置
+配置跳转名称,跳转类型(通过还是退回),**退回不能选择通过类型**,调整条件
+
+![](../../.vuepress/public/defSkip.png)
+![](https://foruda.gitee.com/images/1726905626290177483/195615fc_2218307.png)
+## 3、开启流程实例
+
+hh-vue项目已经准备了七套流程,以及开启流程代码,开启流程会直接执行到开始节点后一个节点
+
+![](../../.vuepress/public/addIns.png)
+
+
+## 4、提交流程
+
+提交流程后,流程流转到代表任务,由流程设计中的对应权限人去办理
+
+![输入图片说明](https://foruda.gitee.com/images/1703668493778770778/d77716b5_2218307.png "屏幕截图")
+
+
+## 5、办理流程
+
+如果是互斥网关则会判断是否满足条件
+
+![输入图片说明](https://foruda.gitee.com/images/1703668882786849328/0b9554ec_2218307.png "屏幕截图")
+![输入图片说明](https://foruda.gitee.com/images/1703668896500858952/c9dc78e1_2218307.png "屏幕截图")
+
+## 6、驳回流程
+
+![输入图片说明](https://foruda.gitee.com/images/1703669345903195445/4ba131bc_2218307.png "屏幕截图")
diff --git a/src/v1.3.1/guide/processrule.md b/src/v1.3.1/guide/processrule.md
new file mode 100644
index 0000000000000000000000000000000000000000..a23d4eecdfc7a607a93bf67945a5e34dac8475a5
--- /dev/null
+++ b/src/v1.3.1/guide/processrule.md
@@ -0,0 +1,56 @@
+# 流程规则
+
+## 1、术语
+1. 跳转类型:PASS-审批通过,REJECT-驳回。
+1. 跳转条件:根据跳转条件,判断要执行哪个分支,比如“请假天数小于4”。
+1. 节点类型:0-开始节点,1-中间节点,2-结束节点。
+1. 权限标识:权限类型:权限标识,可以多个,如“role:3” , “1,role:3,role:1”或者“1,role:3,dept:1”。
+1. 所属并行网关节点编码:离上次最近的并行网关节点编码,可传递,遇新网关重置。
+1. 协作类型:
+
+```
+APPROVAL-无:无其他协作方式
+TRANSFER-转办:任务转给其他人办理
+DEPUTE-委派:求助其他人审批,然后参照他的意见决定是否审批通过
+COUNTERSIGN-会签:和其他人一起审批通过,才算通过
+VOTE-票签:和部分人一起审批,达到一定通过率,才算通过
+ADD_SIGNATURE-加签:办理中途,希望其他人一起参与办理
+REDUCTION_SIGNATURE-减签:办理中途,希望某些人不参与办理
+
+```
+
+
+
+## 2、通用规则
+1. 开始节点和结束节点必须有。
+1. 开始节点必须有且只有一个跳转条件(跳转节点),中间和网关节点必须有跳转条件,结束节点不需要。
+1. 网关节点可不需要跳转类型,互斥网关按照跳转条件流转。
+1. 开启流程是传入租户id,就可以后续就可以根据租户id过来任务。
+1. 角色权限控制,非必填,流程定义时通过逗号隔开多个权限,流转是传入“1,role:3” , “1,role:3,role:1”或者“1,role:3,dept:1”,进行控制。
+1. 当流程有多个结束节点,有一个完成,流程实例就算完成
+1. 网关节点不可直连。
+1. 一票否决(谨慎使用),如果驳回,驳回指向节点后还存在其他正在执行的待办任务,转历史任务,状态都为失效,重走流程。
+1. 中间节点不可通过或者驳回到多个中间节点,必须先流转到网关节点
+1. 流程变量是全局都能获取,任务变量就当前任务触发的监听器时可以获取。
+
+## 3、流程状态
+1. 待提交:开启流程后的状态
+1. 审批中:提交审批后的状态
+1. 驳回:就是点击驳回后的状态
+1. 失效:是针对并行流程,流程完成后,还存在待办任务,把它转历史记录,历史记录状态无效
+1. 审批通过:是任务完成后,待办任务转为历史记录,历史记录状态为审批通过
+1. 已完成:流程结束的状态
+
+## 4、串行网关规则
+1. 以串行网关开头,只会执行后面的一条任务路线,以串行网关结尾,只需前面的一条路线完成即可往下执行(最主要限制)。
+1. 串行网关需要根据传入跳转条件去判断执行哪个任务路线。
+
+
+## 5、并行网关规则
+1. 以并行网关开头,只会必须执行后面的所有任务路线,以并行网关结尾,前面的任务路线必须都完成即可往下执行(最主要限制)。
+1. 当流程完成,并行网关范围内还存在待办任务未完成,转历史任务,状态完成。
+
+## 6、流程协作规则
+1. 或签:待办任务有一个"**审批**"/"**回退**"操作即完成当前任务,或签待办权限支持个人、部门、角色及用户自定义类型
+1. 会签:待办任务所有待办人都进行"**审批**"当前任务执行"**审批**"通过逻辑,会签中任意一待办人进行"**回退**"则整个任务执行"**回退**"逻辑,会签所有待办权限只支持个人类型
+1. 票签:此时根据"**审批**"**/**"**回退**"操作自动计算"**审批通过率(已审批人数/任务总人数)**"与"**回退驳回率(已回退人数/任务总人数)**","**审批通过率**"**大于等于**流程设计时指定的"**票签通过率**"执行"**审批**"通过逻辑,"**回退驳回率**"大于"**1-票签通过率**"执行"**回退**"逻辑,票签所有待办权限只支持个人
diff --git a/src/v1.3.1/guide/processterm.md b/src/v1.3.1/guide/processterm.md
new file mode 100644
index 0000000000000000000000000000000000000000..04aec644b5afc78ba5c9d106fd3697f5c6183dca
--- /dev/null
+++ b/src/v1.3.1/guide/processterm.md
@@ -0,0 +1,18 @@
+# 流程术语
+| 序 号 | 术语 | 术语解释 |
+|------|------|-------------------------------------------------------------------|
+| 1 | 审批 | 当前节点处理人,对当前流程节点进行审核操作,完成后进入下一节点 |
+| 2 | 回退 | 当前节点处理人,将流程驳回至之前已经处理过的任务节点,要求重新处理 |
+| 3 | 委派 | 当前节点处理人,将自己的主办或者经办权限转移委派至别的用户代为处理,处理完后回到当前处理人手中,并由当前处理人处理完后进入下一节点 |
+| 4 | 转办 | 当前节点处理人,将操作权限转给别人处理,处理完后进入下一节点(自己不再处理) |
+| 5 | 催办 | 对于时效要求高的流程,发起人可催办提醒当前节点处理人,一般以消息通知方式提醒处理人 |
+| 6 | 撤销 | 工作流中的某个节点上,允许返回到上一个节点进行修改,属于退回中的一种 |
+| 7 | 取回 | 将工作流中的某个任务退回给之前的执行者,以便进行修改或重新处理 |
+| 8 | 终止 | 当前节点处理人,终止当前流程 |
+| 9 | 抄送 | 当前节点处理人,处理完成之后将处理结果抄送给其他人 |
+| 10 | 加签 | 当前节点处理人,需要增加他人参与审批 |
+| 11 | 减签 | 当前节点处理人,需要减少他人参与审批 |
+| 12 | 会签 | 会签就是指在流程管理中发起人可以同时对多个人发起会签,多个人可以同时处理,只有所有负责人审批通过,审批节点才会通过。 |
+| 13 | 或签 | 一名负责人通过即可通过审批节点 |
+| 14 | 暂存 | 复杂表单,一次性填写不完,需要保存草稿功能,开始节点的暂存 |
+
diff --git a/src/v1.3.1/guide/started.md b/src/v1.3.1/guide/started.md
new file mode 100644
index 0000000000000000000000000000000000000000..6ced02128989a295ab97d42474f939a4aabb30e7
--- /dev/null
+++ b/src/v1.3.1/guide/started.md
@@ -0,0 +1,276 @@
+# 快速开始
+
+> [!IMPORTANT]
+> **在开始之前,我们假定您已经:**
+>
+> 1、熟悉 Java 环境配置及其开发
+> 2、熟悉 关系型 数据库,比如 MySQL
+> 3、熟悉 Spring Boot或者Solon 及相关框架
+> 4、熟悉 Java 构建工具,比如 Maven
+
+## 1、导入sql,按需求执行
+
+- 首次导入,先创建数据库,找到对应数据库的全量脚本[warm-flow-all.sql](https://gitee.com/dromara/warm-flow/tree/master/sql/mysql),执行
+- 如果版本更新,找到对应数据库的更新版本,比如xx-upgrade,[warm-flow_x.x.x.sql](https://gitee.com/dromara/warm-flow/tree/master/sql/mysql/v1-upgrade),执行
+
+
+
+ |
+ |
+
+
+
+## 2、官网流程定义案例xml
+
+[官网流程定义案例xml](https://gitee.com/dromara/warm-flow-test/tree/master/warm-flow-core-test/src/main/resources)
+
+
+## 3、maven依赖
+### 3.1、mybatis
+springboot2项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-sb-starter
+ 1.3.1
+
+```
+
+springboot3项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-sb3-starter
+ 1.3.1
+
+```
+
+solon项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-solon-plugin
+ 1.3.1
+
+```
+
+### 3.2、mybatis-plus
+springboot2项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-plus-sb-starter
+ 1.3.1
+
+```
+
+springboot3项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-plus-sb3-starter
+ 1.3.1
+
+```
+
+solon项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-plus-solon-plugin
+ 1.3.1
+
+```
+
+### 3.3、jpa
+warm-flow工作流配置
+```yml
+# warm-flow工作流配置
+warm-flow:
+ # 当使用JPA时指定JpaPersistenceProvider
+ jpa_persistence_provider: org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider
+```
+
+springboot2项目
+
+```maven
+
+ org.dromara
+ warm-flow-jpa-sb-starter
+ 1.3.1
+
+```
+
+springboot3项目
+
+```maven
+
+ org.dromara
+ warm-flow-jpa-sb3-starter
+ 1.3.1
+
+```
+
+solon项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-plus-solon-plugin
+ 1.3.1
+
+```
+
+### 3.4、mybatis-flex
+springboot2项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-flex-sb-starter
+ 1.3.1
+
+```
+
+springboot3项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-flex-sb3-starter
+ 1.3.1
+
+```
+
+solon项目
+
+```maven
+
+ org.dromara
+ warm-flow-mybatis-flex-solon-plugin
+ 1.3.1
+
+```
+
+### 3.5、easy-query
+springboot项目
+
+```maven
+
+ org.dromara
+ warm-flow-easy-query-sb-starter
+ 1.3.1
+
+```
+
+solon项目
+
+```maven
+
+ org.dromara
+ warm-flow-easy-query-solon-plugin
+
+
+ org.noear
+ solon.data
+
+
+ org.noear
+ solon.logging
+
+
+ 1.3.1
+
+```
+
+## 4、支持数据库类型
+
+* [x] mysql
+* [x] oracle
+* [x] postgresql
+* [ ] 达梦
+* [ ] 人大金仓
+* [ ] GaussDB
+* [ ] oceanbase
+* [ ] sqlserver
+* [ ] ......
+
+
+## 5、支持orm框架类型
+* [x] mybatis
+* [x] mybatis-plus
+* [x] jpa
+* [x] easy-query
+* [x] mybatis-flex
+* [ ] ......
+
+
+
+> **有想扩展其他orm框架和数据库的可加qq群联系群主**
+
+## 6、代码示例
+
+> 测试代码[warm-flow-test](https://gitee.com/dromara/warm-flow-test)项目中,warm-flow-xxx-test模块的测类
+
+
+## 7、部署流程
+
+```java
+public void deployFlow() throws Exception {
+ String path = "/Users/minliuhua/Desktop/mdata/file/IdeaProjects/min/hh-vue/hh-admin/src/main/resources/leaveFlow-serial.xml";
+ System.out.println("已部署流程的id:" + defService.importXml(new FileInputStream(path)).getId());
+ }
+```
+
+## 8、发布流程
+
+```java
+public void publish() throws Exception {
+ defService.publish(1212437969554771968L);
+ }
+```
+
+## 9、开启流程
+
+```java
+public void startFlow() {
+ System.out.println("已开启的流程实例id:" + insService.start("1", getUser()).getId());
+ }
+```
+
+## 10、流程流转
+
+```java
+public void skipFlow() throws Exception {
+ // 通过实例id流转
+ Instance instance = insService.skipByInsId(1219286332141080576L, getUser().skipType(SkipType.PASS.getKey())
+ .permissionFlag(Arrays.asList("role:1", "role:2")));
+ System.out.println("流转后流程实例:" + instance.toString());
+
+// // 通过任务id流转
+// Instance instance = insService.skip(1219286332145274880L, getUser().skipType(SkipType.PASS.getKey())
+// .permissionFlag(Arrays.asList("role:1", "role:2")));
+// System.out.println("流转后流程实例:" + instance.toString());
+ }
+
+ public void skipAnyNode() throws Exception {
+ // 跳转到指定节点
+ Instance instance = insService.skip(1219286332145274880L, getUser().skipType(SkipType.PASS.getKey())
+ .permissionFlag(Arrays.asList("role:1", "role:2")).nodeCode("4"));
+ System.out.println("流转后流程实例:" + instance.toString());
+ }
+```
+
+## 11、初学者推荐学习路线
+
+### 11.1、推荐集成案例hh-vue
+[项目地址](../../common/projectexample.md)
+
+### 11.2、推荐学习视频
+[新手教学视频,社区同学录制](https://www.bilibili.com/video/BV1Ci42117pK/)
diff --git a/src/v1.3.1/guide/table.md b/src/v1.3.1/guide/table.md
new file mode 100644
index 0000000000000000000000000000000000000000..8e4d8addb4a63f5b74c989d2e0a474600a28f5a0
--- /dev/null
+++ b/src/v1.3.1/guide/table.md
@@ -0,0 +1,178 @@
+# 表结构
+
+> [!IMPORTANT]
+>
+> 表描述
+>
+> 流程定义的相关的三张表
+> 1、集团军要对某个区域进行长期的军事演练(流程定义表)
+> 2、军事演练,有多个演练环节,需要制定任务计划 (流程节点表)
+> 3、任务的需要有先后顺序,确保演练按计划推进 (流程跳转表)
+>
+> 流程实例三张表
+> 4、今天要进行一次军事演练(流程实例表)
+> 5、首先,按照任务计划,解放军执行第一个任务(待办任务表)
+> 6、后续会根据不同情况,进行不同的军事演练任务(待办任务表)
+> 7、演练要记录过程 (历史任务表)
+> 8、任务的需要分配执行人 (流程用户表)
+> 9、最终军事演练完成,流程完成
+
+
+
+## 表清单
+
+| **#** | **数据表** | **名称** | **备注说明** |
+| ----- | --------------- | -------------- | ------------ |
+| 1 | flow_definition | 流程定义表 | |
+| 2 | flow_his_task | 历史任务记录表 | |
+| 3 | flow_instance | 流程实例表 | |
+| 4 | flow_node | 流程结点表 | |
+| 5 | flow_skip | 结点跳转关联表 | |
+| 6 | flow_task | 待办任务表 | |
+| 7 | flow_user | 流程用户表 | |
+
+
+
+## 表字段明细
+
+### **flow_definition [**流程定义表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | --------------- | --------------------------------- | --------------- | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT UNSIGNED | √ | √ | | |
+| 2 | flow_code | 流程编码 | VARCHAR(40) | | √ | | |
+| 3 | flow_name | 流程名称 | VARCHAR(100) | | √ | | |
+| 4 | version | 流程版本 | VARCHAR(20) | | √ | | |
+| 5 | is_publish | 是否发布(0未发布 1已发布 9失效) | BIT(1) | | √ | 0 | |
+| 6 | form_custom | 审批表单是否自定义(Y是 N否) | CHAR(1) | | | 'N' | |
+| 7 | form_path | 审批表单路径 | VARCHAR(100) | | | | |
+| 8 | activity_status | 流程激活状态(0挂起 1激活) | BIT(1) | | √ | 1 | |
+| 9 | listener_type | 监听器类型 | VARCHAR(100) | | | | |
+| 10 | listener_path | 监听器路径 | VARCHAR(400) | | | | |
+| 11 | ext | 业务详情 存业务表对象json字符串 | VARCHAR(500) | | | | |
+| 12 | create_time | 创建时间 | DATETIME | | | | |
+| 13 | update_time | 更新时间 | DATETIME | | | | |
+| 14 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 15 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_his_task [**历史任务记录表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | ---------------- | ------------------------------------------------------------ | --------------- | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT UNSIGNED | √ | √ | | |
+| 2 | definition_id | 对应flow_definition表的id | BIGINT | | √ | | |
+| 3 | instance_id | 对应flow_instance表的id | BIGINT | | √ | | |
+| 4 | task_id | 对应flow_task表的id | BIGINT | | √ | | |
+| 5 | node_code | 开始节点编码 | VARCHAR(100) | | | | |
+| 6 | node_name | 开始节点名称 | VARCHAR(100) | | | | |
+| 7 | node_type | 开始节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) | BIT(1) | | | | |
+| 8 | target_node_code | 目标节点编码 | VARCHAR(100) | | | | |
+| 9 | target_node_name | 结束节点名称 | VARCHAR(100) | | | | |
+| 10 | approver | 审批者 | VARCHAR(40) | | | | |
+| 11 | cooperate_type | 协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签) | BIT(1) | | √ | 0 | |
+| 12 | collaborator | 协作人 | VARCHAR(40) | | | | |
+| 13 | skip_type | 流转类型(PASS通过 REJECT退回 NONE无动作) | VARCHAR(10) | | √ | | |
+| 14 | flow_status | 流程状态(1审批中 2 审批通过 9已退回 10失效) | VARCHAR(20) | | √ | | |
+| 15 | form_custom | 审批表单是否自定义(Y是 N否) | CHAR(1) | | | 'N' | |
+| 16 | form_path | 审批表单路径 | VARCHAR(100) | | | | |
+| 17 | message | 审批意见 | VARCHAR(500) | | | | |
+| 18 | ext | 业务详情 存业务表对象json字符串 | VARCHAR(500) | | | | |
+| 19 | create_time | 开始时间 | DATETIME | | | | |
+| 20 | update_time | 完成时间 | DATETIME | | | | |
+| 21 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 22 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_instance [**流程实例表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | --------------- | ------------------------------------------------------------ | ------------ | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT | √ | √ | | |
+| 2 | definition_id | 对应flow_definition表的id | BIGINT | | √ | | |
+| 3 | business_id | 业务id | VARCHAR(40) | | √ | | |
+| 4 | node_type | 结点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) | BIT(1) | | √ | | |
+| 5 | node_code | 流程节点编码 | VARCHAR(40) | | √ | | |
+| 6 | node_name | 流程节点名称 | VARCHAR(100) | | | | |
+| 7 | variable | 任务变量 | TEXT | | | | |
+| 8 | flow_status | 流程状态(0待提交 1审批中 2 审批通过 3自动通过 8已完成 9已退回 10失效) | VARCHAR(20) | | √ | | |
+| 9 | activity_status | 流程激活状态(0挂起 1激活) | BIT(1) | | √ | 1 | |
+| 10 | create_by | 创建者 | VARCHAR(64) | | | | |
+| 11 | create_time | 创建时间 | DATETIME | | | | |
+| 12 | update_time | 更新时间 | DATETIME | | | | |
+| 13 | ext | 扩展字段,预留给业务系统使用 | VARCHAR(500) | | | | |
+| 14 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 15 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_node [**流程结点表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | --------------- | ------------------------------------------------------------ | --------------- | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT UNSIGNED | √ | √ | | |
+| 2 | node_type | 节点类型(0开始节点 1中间节点 2结束结点 3互斥网关 4并行网关) | BIT(1) | | √ | | |
+| 3 | definition_id | 流程定义id | BIGINT | | √ | | |
+| 4 | node_code | 流程节点编码 | VARCHAR(100) | | √ | | |
+| 5 | node_name | 流程节点名称 | VARCHAR(100) | | | | |
+| 6 | permission_flag | 权限标识(权限类型:权限标识,可以多个,用逗号隔开) | VARCHAR(200) | | | | |
+| 7 | node_ratio | 流程签署比例值 | DECIMAL(6,3) | | | | |
+| 8 | coordinate | 坐标 | VARCHAR(100) | | | | |
+| 9 | skip_any_node | 是否可以退回任意节点(Y是 N否) | VARCHAR(100) | | | 'N' | |
+| 10 | listener_type | 监听器类型 | VARCHAR(100) | | | | |
+| 11 | listener_path | 监听器路径 | VARCHAR(400) | | | | |
+| 12 | handler_type | 处理器类型 | VARCHAR(100) | | | | |
+| 13 | handler_path | 处理器路径 | VARCHAR(400) | | | | |
+| 14 | form_custom | 审批表单是否自定义(Y是 N否) | CHAR(1) | | | 'N' | |
+| 15 | form_path | 审批表单路径 | VARCHAR(100) | | | | |
+| 16 | version | 版本 | VARCHAR(20) | | √ | | |
+| 17 | create_time | 创建时间 | DATETIME | | | | |
+| 18 | update_time | 更新时间 | DATETIME | | | | |
+| 19 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 20 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_skip [**结点跳转关联表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | -------------- | ------------------------------------------------------------ | --------------- | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT UNSIGNED | √ | √ | | |
+| 2 | definition_id | 流程定义id | BIGINT | | √ | | |
+| 3 | now_node_code | 当前流程节点的编码 | VARCHAR(100) | | √ | | |
+| 4 | now_node_type | 当前节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) | BIT(1) | | | | |
+| 5 | next_node_code | 下一个流程节点的编码 | VARCHAR(100) | | √ | | |
+| 6 | next_node_type | 下一个节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) | BIT(1) | | | | |
+| 7 | skip_name | 跳转名称 | VARCHAR(100) | | | | |
+| 8 | skip_type | 跳转类型(PASS审批通过 REJECT退回) | VARCHAR(40) | | | | |
+| 9 | skip_condition | 跳转条件 | VARCHAR(200) | | | | |
+| 10 | coordinate | 坐标 | VARCHAR(100) | | | | |
+| 11 | create_time | 创建时间 | DATETIME | | | | |
+| 12 | update_time | 更新时间 | DATETIME | | | | |
+| 13 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 14 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_task [**待办任务表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | ------------- | ------------------------------------------------------------ | ------------ | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT | √ | √ | | |
+| 2 | definition_id | 对应flow_definition表的id | BIGINT | | √ | | |
+| 3 | instance_id | 对应flow_instance表的id | BIGINT | | √ | | |
+| 4 | node_code | 节点编码 | VARCHAR(100) | | √ | | |
+| 5 | node_name | 节点名称 | VARCHAR(100) | | | | |
+| 6 | node_type | 节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关) | BIT(1) | | √ | | |
+| 7 | form_custom | 审批表单是否自定义(Y是 N否) | CHAR(1) | | | 'N' | |
+| 8 | form_path | 审批表单路径 | VARCHAR(100) | | | | |
+| 9 | create_time | 创建时间 | DATETIME | | | | |
+| 10 | update_time | 更新时间 | DATETIME | | | | |
+| 11 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 12 | tenant_id | 租户id | VARCHAR(40) | | | | |
+
+### **flow_user [**流程用户表**]**
+
+| **#** | **字段** | **名称** | **数据类型** | **主键** | **非空** | **默认值** | **备注说明** |
+| ----- | ------------ | ------------------------------------------------------------ | --------------- | -------- | -------- | ---------- | ------------ |
+| 1 | id | 主键id | BIGINT UNSIGNED | √ | √ | | |
+| 2 | type | 人员类型(1待办任务的审批人权限 2待办任务的转办人权限 3待办任务的委托人权限) | CHAR(1) | | √ | | |
+| 3 | processed_by | 权限人 | VARCHAR(80) | | | | |
+| 4 | associated | 任务表id | BIGINT | | √ | | |
+| 5 | create_time | 创建时间 | DATETIME | | | | |
+| 6 | create_by | 创建人 | VARCHAR(80) | | | | |
+| 7 | update_time | 更新时间 | DATETIME | | | | |
+| 8 | del_flag | 删除标志 | CHAR(1) | | | '0' | |
+| 9 | tenant_id | 租户id | VARCHAR(40) | | | | |
\ No newline at end of file
diff --git a/src/v1.3.1/guide/tenant.md b/src/v1.3.1/guide/tenant.md
new file mode 100644
index 0000000000000000000000000000000000000000..c6b79883c013a2dfce92e7f2b8e22892eee28ff2
--- /dev/null
+++ b/src/v1.3.1/guide/tenant.md
@@ -0,0 +1,194 @@
+# 多租户
+
+## 1、Mybatis-plus
+> [!IMPORTANT]
+> 1、Mybatis-plus只支持自身的多租户方式
+
+### 1.1、spring
+```java
+@Component
+public class MpTenantHandler implements TenantLineHandler {
+
+ ThreadLocal threadLocal = new ThreadLocal<>();
+
+ @Override
+ public Expression getTenantId() {
+ // 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 class
+ return new LongValue(2);
+ }
+
+ @Override
+ public String getTenantIdColumn() {
+ return threadLocal.get();
+ }
+
+
+ /**
+ * 指定租户字段
+ * @param tableName 表名
+ * @return
+ */
+ @Override
+ public boolean ignoreTable(String tableName) {
+ TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
+ List fieldList = tableInfo.getFieldList();
+ fieldList.forEach(field -> {
+ // 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
+ if (field.getColumn().equals("tenant_id") || field.getColumn().equals("tenant_code")) {
+ threadLocal.set(field.getColumn());
+ }
+ });
+ // 获取表字段
+ return false;
+ }
+
+ /**
+ * 如果业务系统不开启租户,使用下面方法,指定流程表才开启
+ * @param tableName 表名
+ * @return
+ */
+ @Override
+ public boolean ignoreTable(String tableName) {
+ // 流程表
+ List flowTableName = Arrays.asList("flow_definition", "flow_his_task", "flow_instance", "flow_node"
+ ,"flow_skip", "flow_task", "flow_user");
+ TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
+ AtomicBoolean flag = new AtomicBoolean(true);
+ if (flowTableName.contains(tableInfo.getTableName())) {
+ flag.set(false);
+ }
+ List fieldList = tableInfo.getFieldList();
+ fieldList.forEach(field -> {
+ // 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
+ if (field.getColumn().equals("tenant_id")) {
+ threadLocal.set(field.getColumn());
+ }
+ });
+ // 获取表字段
+ return flag.get();
+ }
+
+}
+
+@Configuration
+public class MybatisPlusConfig {
+
+ @Resource
+ private MpTenantHandler mpTenantHandler;
+
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
+ tenantInterceptor.setTenantLineHandler(mpTenantHandler);
+ interceptor.addInnerInterceptor(tenantInterceptor);
+ return interceptor;
+ }
+}
+```
+
+### 1.2、solon
+```java
+public class MpTenantHandler implements TenantLineHandler {
+
+ ThreadLocal threadLocal = new ThreadLocal<>();
+
+ @Override
+ public Expression getTenantId() {
+ // 返回租户ID的表达式,LongValue 是 JSQLParser 中表示 bigint 类型的 class
+ return new LongValue(2);
+ }
+
+ @Override
+ public String getTenantIdColumn() {
+ return threadLocal.get();
+ }
+
+ @Override
+ public boolean ignoreTable(String tableName) {
+ TableInfo tableInfo = TableInfoHelper.getTableInfo(tableName);
+ List fieldList = tableInfo.getFieldList();
+ fieldList.forEach(field -> {
+ // 如果业务和工作流引擎中的租户字段不一致,可以通过这种方式动态切换
+ if (field.getColumn().equals("tenant_id") || field.getColumn().equals("tenant_code")) {
+ threadLocal.set(field.getColumn());
+ }
+ });
+ // 获取表字段
+ return false;
+ }
+}
+
+@Configuration
+public class WarmFlowConfig {
+ @Bean(value = "db1", typed = true)
+ public DataSource db1(@Inject("${demo.db1}") HikariDataSource ds) {
+ return ds;
+ }
+
+ /**
+ * MybatisPlus全局配置
+ *
+ * @param globalConfig 数据源
+ */
+ @Bean
+ public void db1_cfg(@Db("db1") MybatisConfiguration cfg,
+ @Db("db1") GlobalConfig globalConfig) {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ // 多租户插件 必须放到第一位
+ interceptor.addInnerInterceptor(tenantLineInnerInterceptor());
+ cfg.addInterceptor(interceptor);
+ }
+
+ /**
+ * 多租户插件
+ */
+ public TenantLineInnerInterceptor tenantLineInnerInterceptor() {
+ return new TenantLineInnerInterceptor(new MpTenantHandler());
+ }
+}
+```
+
+
+## 2、通用多租户
+### 2.1、yaml配置方式
+
+```yaml
+# warm-flow工作流配置
+warm-flow:
+ # 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ tenant_handler_path: org.dromara.warm.flow.core.test.handle.CustomTenantHandler
+```
+### 2.2、bean配置方式
+```java
+@Configuration
+public class WarmFlowConfig {
+ /**
+ * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ */
+ @Bean
+ public TenantHandler tenantHandler() {
+ return new CustomTenantHandler();
+ }
+}
+
+```
+
+### 2.3、@Component配置方式
+```java
+/**
+ * 全局租户处理器(可通过配置文件注入,也可用@Bean/@Component方式
+ *
+ * @author warm
+ */
+public class CustomTenantHandler implements TenantHandler {
+
+
+ @Override
+ public String getTenantId() {
+ // 这里返回系统中的当前办理人的租户ID,一般会有工具类获取
+ return "000000";
+ }
+}
+```
+
diff --git "a/src/v1.3.1/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md" "b/src/v1.3.1/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md"
new file mode 100644
index 0000000000000000000000000000000000000000..6cdf9fcc8e6770bd899f108637bddd2842b4390a
--- /dev/null
+++ "b/src/v1.3.1/guide/update/\344\270\200\344\270\252\350\207\252\345\270\246\346\265\201\347\250\213\350\256\276\350\256\241\345\231\250\347\232\204\345\267\245\344\275\234\346\265\201\345\274\225\346\223\216.md"
@@ -0,0 +1,105 @@
+# 一个自带流程设计器的工作流引擎
+> 终于迎来了这个激动人心的版本1.3.1,不需要在为引入设计器而烦恼了。按照以下四点,可以快速集成。
+> 另外一直被吐槽的流程图不够清晰,也在此版本得到解决。
+
+> 详细更新说明:[更新日志](http://www.warm-flow.cn/common/update.html#v1-3-1-2024-10-31)
+
+## 1. 引入依赖
+
+```xml
+
+ org.dromara
+ warm-flow-plugin-ui-sb-web
+ 1.3.1
+
+```
+
+## 2. 后端放行部分路径
+> 1、这个路径需要放行,否则无法访问,`/warm-flow-ui/**`
+> 2、以下是spring-security放行配置示例
+
+
+```java
+@Bean
+protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
+{
+ return httpSecurity
+ .......
+ // 注解标记允许匿名访问的url
+ .authorizeHttpRequests((requests) -> {
+ // 后端请求,静态资源,可匿名访问
+ requests.antMatchers("/warm-flow-ui/**").permitAll()
+ // 除上面外的所有请求全部需要鉴权认证
+ .anyRequest().authenticated();
+ })
+ ......
+ .build();
+}
+```
+
+## 3. 前端加载设计器
+> 1、设计器页面入口是访问后端地址(前后端不分离):`ip:port/warm-flow-ui/index?id=${definitionId}?disabled=${disabled}`
+
+
+## 4. 设计器办理人权限数据接入
+> 给任务节点设置哪些权限的人可以办理,实现接口提供给设计器
+
+### 4.1 办理人权限选择弹框页面
+
+
+
+
+### 4.2 实现接口获取以上页面办理人权限数据
+
+#### 4.2.1 HandlerSelectService接口
+```java
+/**
+ * 流程设计器-获取办理人权限设置列表接口
+ *
+ * @author warm
+ */
+public interface HandlerSelectService {
+
+ /**
+ * 获取办理人权限设置列表tabs页签, 如:用户、角色和部门等
+ * @return tabs页签
+ */
+ List getHandlerType();
+
+ /**
+ * 获取办理人权限设置列表结果,如:用户列表、角色列表、部门列表等
+ * @param query 查询参数
+ * @return 结果
+ */
+ List getHandlerSelect(HandlerQuery query);
+}
+```
+
+
+## 5、项目介绍
+> Warm-Flow国产工作流引擎🎉,其特点简洁轻量,五脏俱全,可扩展,是一个可通过jar引入设计器的工作流。
+
+1. 简洁易用:只有7张表,代码量少,可快速上手和集成
+2. 审批功能:支持通过、退回、任意跳转、转办、终止、会签、票签、委派和加减签、互斥和并行网关
+3. 监听器与流程变量:支持四种监听器,可应对不同场景,灵活可扩展,参数传递,动态权限
+4. 流程图:流程引擎自带流程图,可在不集成流程设计器情况下使用
+5. 流程设计器:可通过jar包形式快速集成到项目,减少繁琐代码搬运和适配
+6. 条件表达式:内置常见的和spel条件表达式,并且支持自定义扩展
+7. 办理人变量表达式:内置${handler}和spel格式的表达式,可满足不同场景,灵活可扩展
+8. orm框架扩展:目前支持MyBatis、Mybatis-Plus、Mybatis-Flex和Jpa,后续会由社区提供其他支持,扩展方便
+9. 数据库支持:目前支持MySQL 、Oracle 和PostgreSQL,后续会继续支持其他数据库或者国产数据库
+10. 多租户与软删除:流程引擎自身维护多租户和软删除实现,也可使用对应orm框架的实现方式
+11. 同时支持spring和solon
+12. 兼容java8和java17,理论11也可以
+13. 官方提供基于ruoyi-vue封装实战项目,很实用
+
+## 6、演示地址
+
+- admin/admin123
+
+演示地址:http://www.hhzai.top
+
+
+## 7、官网
+
+[http://warm-flow.cn](http://www.warm-flow.cn/)
diff --git a/src/v1.3.1/guide/variable.md b/src/v1.3.1/guide/variable.md
new file mode 100644
index 0000000000000000000000000000000000000000..04b53548ce4dad5e876b480b192f377d57e5ef2d
--- /dev/null
+++ b/src/v1.3.1/guide/variable.md
@@ -0,0 +1,39 @@
+# 流程变量
+
+> [!IMPORTANT]
+> 1、流程变量,map类型,用于流程执行中的数据转递
+> 2、在执行流程时,可以设置流程变量
+> 3、在监听器中,可以获取流程变量
+
+```java
+ public void insertTestLeave(TestLeave testLeave, Integer flowStatus)
+ {
+ String id = IdUtils.nextIdStr();
+ testLeave.setId(id);
+ LoginUser user = SecurityUtils.getLoginUser();
+ FlowParams flowParams = FlowParams.build().flowCode(getFlowType(testLeave))
+ .handler(user.getUser().getUserId().toString());
+ // 流程变量
+ Map variable = new HashMap<>();
+ variable.put("testLeave", testLeave);
+ variable.put("flag", String.valueOf(testLeave.getDay()));
+ flowParams.variable(variable);
+
+ Instance instance = insService.start(id, flowParams);
+ }
+```
+
+```java
+@Component
+public class FinishListener implements Listener {
+ private static final Logger log = LoggerFactory.getLogger(StartListener.class);
+
+ @Override
+ public void notify(ListenerVariable variable) {
+ log.info("完成监听器:{}", variable);
+ Instance instance = variable.getInstance();
+ Map testLeaveMap = variable.getVariable();
+ log.info("完成监听器结束;{}", "任务完成");
+ }
+}
+```
diff --git a/src/v1.3.1/guide/variableStategy.md b/src/v1.3.1/guide/variableStategy.md
new file mode 100644
index 0000000000000000000000000000000000000000..995e5d99e623fc509490cf2c4e3d3087569c7f1e
--- /dev/null
+++ b/src/v1.3.1/guide/variableStategy.md
@@ -0,0 +1,134 @@
+# 办理人变量设置
+
+## 1、内置表达式
+- 1、默认办理人变量策略: `@@default@@|${handler1}`
+- 2、spel办理人变量策略: `@@spel@@|#{@user.evalVar(#handler2)}`
+- 3、@@xxx@@: 标识不同策略的前缀
+
+## 2、变量替换时机
+- 1、上一个节点任务办理时,传入变量
+- 2、下一个节点任务生成时即可获取替换
+
+> 比如B-->C, C任务设置办理人变量为`@@default@@|${handler1}`,B任务办理时传入变量`handler1=100`,则C节点办理人变量为100
+
+
+## 3、默认办理人变量策略
+
+### 前端页面设置变量
+- 比如:`@@default@@|${handler1}`
+- `@@default@@|${handler1}`中@@default@@表示默认办理人变量策略,handler1是需要被流程变量中替换的标识
+
+
+
+
+
+
+### 后端代码设置变量
+```java
+
+// 流程变量
+Map variable = new HashMap<>();
+variable.put("handler1", "100");
+flowParams.variable(variable);
+
+Instance instance = insService.skipByInsId(testLeave.getInstanceId(), flowParams);
+```
+
+## 4、spel办理人变量策略
+
+### 前端页面设置变量
+- 比如:`@@spel@@|#{@user.evalVar(#handler2)}`
+- `#{@user.evalVar(#handler2)}`是spel表达式,`#handler2`是方法入参变量,可以不设置
+
+
+
+
+
+
+
+### 后端代码设置变量
+```java
+/**
+ * 用户类
+ */
+@Component("user")
+public class User {
+
+ /**
+ * spel办理人变量表达式
+ * @param handler2 办理人
+ * @return String
+ */
+ public String evalVar(String handler2) {
+ return handler2;
+ }
+}
+
+// 流程变量
+Map variable = new HashMap<>();
+variable.put("handler2", "101");
+flowParams.variable(variable);
+
+Instance instance = insService.skipByInsId(testLeave.getInstanceId(), flowParams);
+```
+
+## 5、扩展
+
+- 扩展需要实现`VariableStrategy`接口, 实现`getType和eval`方法
+- 并且通过这个方法进行注册VariableUtil.setVariable
+
+```java
+/**
+ * 变量替换策略
+ *
+ * @author warm
+ */
+public interface VariableStrategy {
+
+ /**
+ * 获取变量替换类型
+ * @return 变量替换类型
+ */
+ String getType();
+
+ /**
+ * 执行表达式
+ * @param expression 表达式
+ * @param variable 流程变量
+ * @return 执行结果
+ */
+ String eval(String expression, Map variable);
+}
+
+
+
+/**
+ * 默认变量替换策略: @@default@@|${flag}
+ *
+ * @author warm
+ */
+public class DefaultVariableStrategy implements VariableStrategy {
+
+ @Override
+ public String getType() {
+ return FlowCons.splitAt + "default" + FlowCons.splitAt;
+ }
+
+ @Override
+ public String eval(String expression, Map variable) {
+ if (StringUtils.isEmpty(expression) || MapUtil.isEmpty(variable)) {
+ return null;
+ }
+ String result = expression.replace("${", "").replace("}", "");
+ Object o = variable.get(result);
+ if (ObjectUtil.isNotNull(o)) {
+ String variableStr = (String) o;
+ if (StringUtils.isEmpty(variableStr)) {
+ return null;
+ }
+ return variableStr;
+ }
+ return null;
+ }
+}
+```