From ae584d54a63306840172add6da2643cf93d6a234 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期一, 13 一月 2025 14:08:15 +0800
Subject: [PATCH] !635 合并 warmflow 功能分支 * update 优化 工作流设计器支持token传输 只需要放行token头获取即可 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化 无需多余set变量 * update 优化 避免重复处理 * update 优化 实体类隔离 * add 增加流程启动,办理接口 * update 调整流程驳回 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update warmflow 1.3.7 * update 增加 warmflow oracle pg sqlserver sql脚本文件 * update 增加 warmflow oracle pg sqlserver sql脚本文件 * add 新增workflow不同的sql语句 * add 新增添加租户同步默认流程定义 * update 优化 流程列表查询 删除无用mapper * update 导入流程 支持并发多文件上传 * update 调整流程定义查询 * update 优化 统一书写格式 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化发布事件增加租户ID * update 调整驳回记录 * Revert "update 获取用户简略信息,祖级部门列表,部门负责人等" * update 获取用户简略信息,祖级部门列表,部门负责人等 * update 更新warm-flow版本到v1.3.6-m1 * update 更新注释信息 * fix 临时修复 warm参数读取问题 * update warm-flow 1.3.4 => 1.3.5 优化流程图导入 * update 更新warm-flow版本到v1.3.5 2024-12-20 * update 增加抄送人名称 * update 我的抄送增加申请人以及更新时间 * update 优化监听事件注释 * update 优化流程分类名称翻译回显 * fix 修改根据流程分类id查询 * update 新增流程分类id查询 * fix 修复抄送错误 * fix 修复错误判空 * fix 修复错误判空 * update 新增删除流程事件 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整sql书写顺序 * fix 修复 抄送缺数据问题 与 已完成任务数据取错问题 * update 新增根据业务id查询流程实例详细信息 * update 调整变量参数 * update 调整分类接口 * update 统一业务id参数 * update 调整返回参数 * update 增加业务id通用查询条件 * update 优化代码 修复bug * update 优化新增流程分类判断 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整驳回 * update 优化错误注释 * update 优化流程分类sql语句 * update 调整驳回 * update 删除流程分类状态 * update 增加流程定义防重 * [fix] * update 优化代码 修复bug * update 优化流程定义增加类别树查询 * update 新增翻译根据流程分类ID查询流程分类名称 * update 根据分页对象构建表格分页数据对象 * update 优化流程定义列表名称 * update 优化流程分类校验 * update 导入流程 支持自定义类别 * update 流程案例 增加表单路径 * update 流程定义查询返回表单路径 * update 优化任务业务层 * fix 修复 请假天数不准确问题 * update 优化驳回 撤销 * update 删除类别查询权限 通用查询不需要加权限 * fix 修复 变量名修改错误 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 调整驳回 * update 表名类名统一命名 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 挑战者驳回 撤销 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * fix 修复会签 票签撤销问题 * update 调整并行环节撤销错误 增加办理校验 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 优化获取办理人 * update 优化 workflow模块增加doc依赖输出接口文档 * Revert "update 优化 删除无用方法" * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 调整代办人查询错误 增加示例 * update 优化 重构代码 * update 优化 重构代码 * update 优化 将工作流消息推送改为sse * add 添加模型 * update 调整审批记录 * update 调整请假案例 * fix 修复流程定义查询错误 * update 调整流程实例查询错误 * update 调整获取当前登录任务实例 * add 添加消息发送 * update 调整办理监听 * [add] * [fix] * update 重构 将工作流查询逻辑封装为单独的service类 * [update] * [add] * 办理附件提交 * 申请人查询修改 * update 回退优化 删除无用方法 * update 优化任务办理人翻译实现 * update 优化任务分配人枚举 * update 优化 删除无用方法 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * [add] * update 优化全局任务办理监听 * update 删除无用引入 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化激活/挂起取反逻辑 * !614 style workflow xml 格式 * style workflow xml 格式 * !612 fix FlwInstanceMapper xml错误 * fix FlwInstanceMapper xml错误 * update 优化 后端代码 * update 优化接口请求路径 * update 调整已办排序 * add 添加任务作废 * update 调整任务办理操作 * update 调整加签,减签校验 * update 调整加签 * add 添加获取当前任务的办理人接口 * add 添加任务查询会签,票签比例 * update 调整任务,实例查询 * update 调整任务委托,转办,优化部分代码等 * update 调整流程定义视图 * add 添加任务,流程实例常用查询接口 * Merge branch 'dev' into warm-flow-future * update 优化工作流常量使用 * update 优化流程记录运行时长获取 * update 优化任务管理控制层 * update 回复业务状态枚举 * update 优化业务状态枚举 * update 调整昵称翻译 * update 调整修改办理人接口 * update 调整流程全局监听,调整任务办理人批量修改,优化代码 * update 优化查询可驳回节点 * update 优化添加抄送人 * update 优化增加人员类型枚举,删除无用常量 * update 优化请假天数工具类,删除缓存,加锁处理,可以采用外部传参的形式处理redis部分 * update 优化请假天数计算 * update 优化任务完成时间处理 * update 优化任务办理人获取 * update 优化任务操作,委派、转办、加签、减签、修改办理人等 * add 新增warm-flow-all.sql * del 删除多余SQL * del 删除无用vo * del 删除表单管理信息 * del 删除节点配置信息 * update 优化节点类型常量获取 * update 优化权限办理人获取 * update 优化权限办理人获取判断 * update 提交等待新版本待优化的开始监听信息 * update 新增获取部门负责人 * add 新增分派办理人监听器 * update 优化或者字符串用户ID * update 用户前缀去掉 * update 调整流程实例状态查询 * add 添加流程撤销 * add 添加流程抄送 * add 新增办理人权限处理器 * update 升级warm-flow1.3.4 * Merge branch 'dev' into warm-flow-future * update 调整流程定义复制 * update 调整流程启动设置启动人变量 * update 调整流程定义删除 * update 调整流程定义导入 * update 调整工作流任务,流程定义等查询 * update 调整工作流人员翻译查询 * update 调整转办,加签等参数 * update 调整流程办理设置办理人 * update 调整流程设计保存 * update 调整流程状态,移除过时方法,调整查询办理人 * update 补充工作流请求增加鉴权 * update 工作流请求增加鉴权 * update 新增流程完成监听器 * update 新增流程启动监听器 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 更新warm-flow版本 * update 优化workflow表sql格式 * update 优化,增加岗位权限判空处理 * update 当前用户所有权限岗位ID改为从token获取 * update 当前用户所有权限增加岗位ID权限 * update 更新通过岗位ID查询用户 * update 优化激活/挂起流程定义判断 * Revert "add 新增异常处理器和工作流封装包" * add 新增异常处理器和工作流封装包 * update 优化待办任务查询以及任务流转 * update 优化工作流工具,避免多次获取请求 * fix 修改无效标识 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 查询部门并返回任务指派的列表根据部门树搜索 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化任务办理人分组 * update 优化任务办理人查询 * update 优化任务办理人查询 * update 优化任务办理人 * update 完善任务办理人 * add 新增角色办理人 * !596 优化工作流代码逻辑 * update 优化工作流工具冗余代码 * update 优化工作流代码逻辑 * update 调整办理 驳回 终止等状态 * update 调整流程定义查询 * 解决冲突提交 warmflow代码 * update 升级warm-flow到1.3.0 调整流程办理 ,驳回,终止等 添加自定义监听 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整流程xml查询 * update 调整驳回 * update 升级warm-flow * update 调整任务办理设置办理人 * 调整转办,委托参数 * update warm-flow 1.2.4 => 1.2.7 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整抄送错误 * 添加已办,未办 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * add 添加我发起的单据接口 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整流程实例,待办查询 * remove 删除无用校验 * add 添加待办人查询 * Merge branch 'dev' into warm-flow-future * update 调整字段错误,流程导入 * add 添加流程激活/挂起接口 升级warm-flow到1.2.4 * add 添加历史流程定义查询 调整流程发布 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化 TenantSpringCacheManager 处理逻辑 * fix 修复 一级缓存key未区分租户问题 * update 优化 角色权限判断 * update 更新 readme * update 优化 增加删除标志位常量优化查询代码 * fix 修复 登出无法正确删除对应的租户数据问题 * update 优化 sse 拦截网络中断io异常 * fix 修复 登录错误锁定不区分租户问题 * update 优化 sse 关闭连接各种异常问题 * update 优化 监控使用独立web依赖 * fix 修复 代码生成 错误匹配表名问题 * update 优化 适配 anyline 新改动 * update anyline 8.7.2-20240728 * update 脱敏策略优化增加密码 * add 新增 更多脱敏策略 * update 优化oss查询代码 * update 优化 sse发送消息 增加token有效期判断 * fix 修复 登出后重新登录 sse推送报错问题 * fix 修复 代码生成 数据源切换问题 * update anyline 8.7.2-20240726 * fix 修复 代码生成 表结构缓存问题 * update snailjob 1.1.0 => 1.1.1 * fix 修复 代码生成 表结构缓存问题 * update 优化 sse 自动装配 * 初始化添加warm-flow

---
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java          |   22 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java                  |  244 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwDefinitionService.java            |   79 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java    |  275 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java                     |  176 +
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/CompleteTaskDTO.java          |   71 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/config/WarmFlowConfig.java                    |   15 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowVariableVo.java                 |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCancelBo.java                   |   31 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/CategoryNameTranslationImpl.java |   31 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCopyBo.java                     |    5 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowCategoryVo.java                 |   69 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskStatusEnum.java              |   32 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTerminationBo.java              |    8 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java                         |   12 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/FlowCategory.java                      |   58 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java                 |   20 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowDefinitionVo.java               |  104 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java       |  194 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/MessageTypeEnum.java             |   20 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java          |  101 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTaskBo.java                     |   55 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInvalidBo.java                  |   31 
 ruoyi-admin/src/main/resources/application.yml                                                                |   31 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java                      |  363 -
 script/bpmn/leave1.xml                                                                                        |   17 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwCategoryService.java              |  102 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/StartProcessBo.java                 |    8 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessDeleteEvent.java     |   34 
 script/sql/oracle/oracle_ry_workflow.sql                                                                      |  603 ++-
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwCategoryMapper.java                 |   60 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java          |  669 +++
 ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwInstanceMapper.xml                         |   36 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java          |  115 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java             |  199 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java      |  267 +
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml                                 |   11 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java            |  109 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskOperationBo.java                |   48 
 ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwCategoryMapper.xml                         |   11 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaskAssigneeServiceImpl.java      |  168 +
 script/bpmn/leave5.xml                                                                                        |   27 
 script/sql/ry_workflow.sql                                                                                    |  403 +
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java           |   13 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java       |   56 
 pom.xml                                                                                                       |   16 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java        |   71 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java              |    1 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java              |  159 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java             |   76 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowCopyDTO.java              |    5 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java        |   58 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java                    |    1 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwTaskMapper.java                     |   57 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java                  |  190 +
 ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml                             |  115 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java  |  158 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java         |  132 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java         |  155 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwCategoryController.java         |  130 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCategoryBo.java                 |   47 
 script/bpmn/leave2.xml                                                                                        |   24 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java       |   18 
 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java            |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java            |   12 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java      |  455 ++
 script/sql/sqlserver/sqlserver_ry_workflow.sql                                                                | 1764 +++++++--
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java          |   77 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java                  |   28 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java             |    1 
 script/sql/postgres/postgres_ry_workflow.sql                                                                  |  658 ++-
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java             |  113 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeType.java            |   49 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInstanceBo.java                 |   55 
 script/sql/sqlserver/sqlserver_ry_vue_5.X.sql                                                                 |    6 
 script/bpmn/leave3.xml                                                                                        |   27 
 /dev/null                                                                                                     |    0 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/ITestLeaveService.java                |    3 
 ruoyi-modules/ruoyi-workflow/pom.xml                                                                          |   57 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java            |   79 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/TaskAssigneeService.java         |   45 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwInstanceMapper.java                 |   27 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java              |    1 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java          |   45 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowInstanceVo.java                 |  137 
 script/bpmn/leave4.xml                                                                                        |   20 
 86 files changed, 8,387 insertions(+), 1,692 deletions(-)

diff --git a/pom.xml b/pom.xml
index 63b9d02..2993af4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
         <!-- 闈㈠悜杩愯鏃剁殑D-ORM渚濊禆 -->
         <anyline.version>8.7.2-20241022</anyline.version>
         <!--宸ヤ綔娴侀厤缃�-->
-        <flowable.version>7.0.1</flowable.version>
+        <warm-flow.version>1.3.7</warm-flow.version>
 
         <!-- 鎻掍欢鐗堟湰 -->
         <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
@@ -118,12 +118,16 @@
                 <scope>import</scope>
             </dependency>
 
+            <!-- Warm-Flow鍥戒骇宸ヤ綔娴佸紩鎿�, 鍦ㄧ嚎鏂囨。锛歨ttp://warm-flow.cn/ -->
             <dependency>
-                <groupId>org.flowable</groupId>
-                <artifactId>flowable-bom</artifactId>
-                <version>${flowable.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
+                <groupId>org.dromara.warm</groupId>
+                <artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
+                <version>${warm-flow.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.dromara.warm</groupId>
+                <artifactId>warm-flow-plugin-ui-sb-web</artifactId>
+                <version>${warm-flow.version}</version>
             </dependency>
 
             <!-- JustAuth 鐨勪緷璧栭厤缃�-->
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index c42bb7f..dbe1688 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -119,6 +119,7 @@
     - /error
     - /*/api-docs
     - /*/api-docs/**
+    - /warm-flow-ui/token-name
 
 # 澶氱鎴烽厤缃�
 tenant:
@@ -227,8 +228,7 @@
   # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
   excludeUrls:
     - /system/notice
-    - /workflow/model/save
-    - /workflow/model/editModelXml
+    - /warm-flow/save-xml
 
 # 鍏ㄥ眬绾跨▼姹犵浉鍏抽厤缃�
 # 濡備娇鐢↗DK21璇风洿鎺ヤ娇鐢ㄨ櫄鎷熺嚎绋� 涓嶈寮�鍚閰嶇疆
@@ -273,24 +273,11 @@
   # 璁剧疆璁块棶婧愬湴鍧�
   allowedOrigins: '*'
 
---- #flowable閰嶇疆
-flowable:
-  # 寮�鍏� 鐢ㄤ簬鍚姩/鍋滅敤宸ヤ綔娴�
+--- # warm-flow宸ヤ綔娴侀厤缃�
+warm-flow:
+  # 鏄惁寮�鍚伐浣滄祦锛岄粯璁rue
   enabled: true
-  process.enabled: ${flowable.enabled}
-  eventregistry.enabled: ${flowable.enabled}
-  async-executor-activate: false #鍏抽棴瀹氭椂浠诲姟JOB
-  #  灏哾atabaseSchemaUpdate璁剧疆涓簍rue銆傚綋Flowable鍙戠幇搴撲笌鏁版嵁搴撹〃缁撴瀯涓嶄竴鑷存椂锛屼細鑷姩灏嗘暟鎹簱琛ㄧ粨鏋勫崌绾ц嚦鏂扮増鏈��
-  database-schema-update: true
-  activity-font-name: 瀹嬩綋
-  label-font-name: 瀹嬩綋
-  annotation-font-name: 瀹嬩綋
-  # 鍏抽棴鍚勪釜妯″潡鐢熸垚琛紝鐩墠鍙娇鐢ㄥ伐浣滄祦鍩虹琛�
-  idm:
-    enabled: false
-  cmmn:
-    enabled: false
-  dmn:
-    enabled: false
-  app:
-    enabled: false
+  # 鏄惁寮�鍚璁″櫒ui
+  ui: true
+  # 榛樿Authorization锛屽鏋滄湁澶氫釜token锛岀敤閫楀彿鍒嗛殧
+  token-name: ${sa-token.token-name},clientid
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/CompleteTaskDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/CompleteTaskDTO.java
new file mode 100644
index 0000000..2e63f8a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/CompleteTaskDTO.java
@@ -0,0 +1,71 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 鍔炵悊浠诲姟璇锋眰瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class CompleteTaskDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 浠诲姟id
+     */
+    private Long taskId;
+
+    /**
+     * 闄勪欢id
+     */
+    private String fileId;
+
+    /**
+     * 鎶勯�佷汉鍛�
+     */
+    private List<FlowCopyDTO> flowCopyList;
+
+    /**
+     * 娑堟伅绫诲瀷
+     */
+    private List<String> messageType;
+
+    /**
+     * 鍔炵悊鎰忚
+     */
+    private String message;
+
+    /**
+     * 娑堟伅閫氱煡
+     */
+    private String notice;
+
+    /**
+     * 娴佺▼鍙橀噺
+     */
+    private Map<String, Object> variables;
+
+    /**
+     * 鎵╁睍鍙橀噺(姝ゅ涓洪�楀彿鍒嗛殧鐨刼ssId)
+     */
+    private String ext;
+
+    public Map<String, Object> getVariables() {
+        if (variables == null) {
+            return new HashMap<>(16);
+        }
+        variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
+        return variables;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowCopyDTO.java
similarity index 75%
copy from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java
copy to ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowCopyDTO.java
index 88a5a21..2f20b21 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/FlowCopyDTO.java
@@ -1,9 +1,10 @@
-package org.dromara.workflow.domain.vo;
+package org.dromara.common.core.domain.dto;
 
 import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+
 
 /**
  * 鎶勯��
@@ -11,7 +12,7 @@
  * @author may
  */
 @Data
-public class WfCopy implements Serializable {
+public class FlowCopyDTO implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java
new file mode 100644
index 0000000..3934ada
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/StartProcessDTO.java
@@ -0,0 +1,45 @@
+package org.dromara.common.core.domain.dto;
+
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 鍚姩娴佺▼瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class StartProcessDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 涓氬姟鍞竴鍊糹d
+     */
+    private String businessId;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 娴佺▼鍙橀噺锛屽墠绔細鎻愪氦涓�涓厓绱爗'entity': {涓氬姟璇︽儏鏁版嵁瀵硅薄}}
+     */
+    private Map<String, Object> variables;
+
+    public Map<String, Object> getVariables() {
+        if (variables == null) {
+            return new HashMap<>(16);
+        }
+        variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
+        return variables;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java
new file mode 100644
index 0000000..85893e1
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/TaskAssigneeDTO.java
@@ -0,0 +1,101 @@
+package org.dromara.common.core.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 浠诲姟鍙楄浜�
+ *
+ * @author AprilWind
+ */
+@Data
+@NoArgsConstructor
+public class TaskAssigneeDTO implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎬诲ぇ灏�
+     */
+    private Long total = 0L;
+
+    /**
+     *
+     */
+    private List<TaskHandler> list;
+
+    public TaskAssigneeDTO(Long total, List<TaskHandler> list) {
+        this.total = total;
+        this.list = list;
+    }
+
+    /**
+     * 灏嗘簮鍒楄〃杞崲涓� TaskHandler 鍒楄〃
+     *
+     * @param <T>              閫氱敤绫诲瀷
+     * @param sourceList       寰呰浆鎹㈢殑婧愬垪琛�
+     * @param storageId        鎻愬彇 storageId 鐨勫嚱鏁�
+     * @param handlerCode      鎻愬彇 handlerCode 鐨勫嚱鏁�
+     * @param handlerName      鎻愬彇 handlerName 鐨勫嚱鏁�
+     * @param groupName        鎻愬彇 groupName 鐨勫嚱鏁�
+     * @param createTimeMapper 鎻愬彇 createTime 鐨勫嚱鏁�
+     * @return 杞崲鍚庣殑 TaskHandler 鍒楄〃
+     */
+    public static <T> List<TaskHandler> convertToHandlerList(
+        List<T> sourceList,
+        Function<T, Long> storageId,
+        Function<T, String> handlerCode,
+        Function<T, String> handlerName,
+        Function<T, Long> groupName,
+        Function<T, Date> createTimeMapper) {
+        return sourceList.stream()
+            .map(item -> new TaskHandler(
+                String.valueOf(storageId.apply(item)),
+                handlerCode.apply(item),
+                handlerName.apply(item),
+                groupName != null ? String.valueOf(groupName.apply(item)) : null,
+                createTimeMapper.apply(item)
+            )).collect(Collectors.toList());
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class TaskHandler {
+
+        /**
+         * 涓婚敭
+         */
+        private String storageId;
+
+        /**
+         * 鏉冮檺缂栫爜
+         */
+        private String handlerCode;
+
+        /**
+         * 鏉冮檺鍚嶇О
+         */
+        private String handlerName;
+
+        /**
+         * 鏉冮檺鍒嗙粍
+         */
+        private String groupName;
+
+        /**
+         * 鍒涘缓鏃堕棿
+         */
+        private Date createTime;
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessDeleteEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessDeleteEvent.java
new file mode 100644
index 0000000..d570c31
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessDeleteEvent.java
@@ -0,0 +1,34 @@
+package org.dromara.common.core.domain.event;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鍒犻櫎娴佺▼鐩戝惉
+ *
+ * @author AprilWind
+ */
+@Data
+public class ProcessDeleteEvent implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessId;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java
index 61c7efc..21bfbef 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java
@@ -10,7 +10,6 @@
  *
  * @author may
  */
-
 @Data
 public class ProcessEvent implements Serializable {
 
@@ -18,14 +17,19 @@
     private static final long serialVersionUID = 1L;
 
     /**
-     * 娴佺▼瀹氫箟key
+     * 绉熸埛ID
      */
-    private String key;
+    private String tenantId;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
 
     /**
      * 涓氬姟id
      */
-    private String businessKey;
+    private String businessId;
 
     /**
      * 鐘舵��
@@ -36,6 +40,5 @@
      * 褰撲负true鏃朵负鐢宠浜鸿妭鐐瑰姙鐞�
      */
     private boolean submit;
-
 
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java
index 019ca82..33bc6e5 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java
@@ -10,7 +10,6 @@
  *
  * @author may
  */
-
 @Data
 public class ProcessTaskEvent implements Serializable {
 
@@ -18,23 +17,28 @@
     private static final long serialVersionUID = 1L;
 
     /**
-     * 娴佺▼瀹氫箟key
+     * 绉熸埛ID
      */
-    private String key;
+    private String tenantId;
 
     /**
-     * 瀹℃壒鑺傜偣key
+     * 娴佺▼瀹氫箟缂栫爜
      */
-    private String taskDefinitionKey;
+    private String flowCode;
+
+    /**
+     * 瀹℃壒鑺傜偣缂栫爜
+     */
+    private String nodeCode;
 
     /**
      * 浠诲姟id
      */
-    private String taskId;
+    private Long taskId;
 
     /**
      * 涓氬姟id
      */
-    private String businessKey;
+    private String businessId;
 
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java
new file mode 100644
index 0000000..0cbed2f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/TaskAssigneeBody.java
@@ -0,0 +1,56 @@
+package org.dromara.common.core.domain.model;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 浠诲姟鍙楄浜�
+ *
+ * @author AprilWind
+ */
+@Data
+@NoArgsConstructor
+public class TaskAssigneeBody implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鏉冮檺缂栫爜
+     */
+    private String handlerCode;
+
+    /**
+     * 鏉冮檺鍚嶇О
+     */
+    private String handlerName;
+
+    /**
+     * 鏉冮檺鍒嗙粍
+     */
+    private String groupId;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    private String beginTime;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    private String endTime;
+
+    /**
+     * 褰撳墠椤�
+     */
+    private Integer pageNum = 1;
+
+    /**
+     * 姣忛〉鏄剧ず鏉℃暟
+     */
+    private Integer pageSize = 10;
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
index 0af943a..c1660ee 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
@@ -7,6 +7,10 @@
 import org.dromara.common.core.utils.StringUtils;
 
 import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 涓氬姟鐘舵�佹灇涓�
@@ -16,30 +20,37 @@
 @Getter
 @AllArgsConstructor
 public enum BusinessStatusEnum {
+
     /**
      * 宸叉挙閿�
      */
     CANCEL("cancel", "宸叉挙閿�"),
+
     /**
      * 鑽夌
      */
     DRAFT("draft", "鑽夌"),
+
     /**
      * 寰呭鏍�
      */
     WAITING("waiting", "寰呭鏍�"),
+
     /**
      * 宸插畬鎴�
      */
     FINISH("finish", "宸插畬鎴�"),
+
     /**
      * 宸蹭綔搴�
      */
     INVALID("invalid", "宸蹭綔搴�"),
+
     /**
      * 宸查��鍥�
      */
     BACK("back", "宸查��鍥�"),
+
     /**
      * 宸茬粓姝�
      */
@@ -55,20 +66,72 @@
      */
     private final String desc;
 
+    private static final Map<String, BusinessStatusEnum> STATUS_MAP = Arrays.stream(BusinessStatusEnum.values())
+        .collect(Collectors.toConcurrentMap(BusinessStatusEnum::getStatus, Function.identity()));
+
     /**
-     * 鑾峰彇涓氬姟鐘舵��
+     * 鏍规嵁鐘舵�佽幏鍙栧搴旂殑 BusinessStatusEnum 鏋氫妇
      *
-     * @param status 鐘舵��
+     * @param status 涓氬姟鐘舵�佺爜
+     * @return 瀵瑰簲鐨� BusinessStatusEnum 鏋氫妇锛屽鏋滄壘涓嶅埌鍒欒繑鍥� null
+     */
+    public static BusinessStatusEnum getByStatus(String status) {
+        // 浣跨敤 STATUS_MAP 鑾峰彇瀵瑰簲鐨勬灇涓撅紝鑻ユ壘涓嶅埌鍒欒繑鍥� null
+        return STATUS_MAP.get(status);
+    }
+
+    /**
+     * 鏍规嵁鐘舵�佽幏鍙栧搴旂殑涓氬姟鐘舵�佹弿杩颁俊鎭�
+     *
+     * @param status 涓氬姟鐘舵�佺爜
+     * @return 杩斿洖涓氬姟鐘舵�佹弿杩帮紝鑻ョ姸鎬佺爜涓虹┖鎴栨湭鎵惧埌瀵瑰簲鐨勬灇涓撅紝杩斿洖绌哄瓧绗︿覆
      */
     public static String findByStatus(String status) {
         if (StringUtils.isBlank(status)) {
             return StrUtil.EMPTY;
         }
-        return Arrays.stream(BusinessStatusEnum.values())
-            .filter(statusEnum -> statusEnum.getStatus().equals(status))
-            .findFirst()
-            .map(BusinessStatusEnum::getDesc)
-            .orElse(StrUtil.EMPTY);
+        BusinessStatusEnum statusEnum = STATUS_MAP.get(status);
+        return (statusEnum != null) ? statusEnum.getDesc() : StrUtil.EMPTY;
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁涓烘寚瀹氱殑鐘舵�佷箣涓�锛氳崏绋裤�佸凡鎾ら攢鎴栧凡閫�鍥�
+     *
+     * @param status 瑕佹鏌ョ殑鐘舵��
+     * @return 濡傛灉鐘舵�佷负鑽夌銆佸凡鎾ら攢鎴栧凡閫�鍥炰箣涓�锛屽垯杩斿洖 true锛涘惁鍒欒繑鍥� false
+     */
+    public static boolean isDraftOrCancelOrBack(String status) {
+        return DRAFT.status.equals(status) || CANCEL.status.equals(status) || BACK.status.equals(status);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁涓烘挙閿�锛岄��鍥烇紝浣滃簾锛岀粓姝�
+     *
+     * @param status status
+     * @return 缁撴灉
+     */
+    public static boolean initialState(String status) {
+        return CANCEL.status.equals(status) || BACK.status.equals(status) || INVALID.status.equals(status) || TERMINATION.status.equals(status);
+    }
+
+    /**
+     * 鑾峰彇杩愯涓殑瀹炰緥鐘舵�佸垪琛�
+     *
+     * @return 鍖呭惈杩愯涓疄渚嬬姸鎬佺殑涓嶅彲鍙樺垪琛�
+     * 锛堝寘鍚� DRAFT銆乄AITING銆丅ACK 鍜� CANCEL 鐘舵�侊級
+     */
+    public static List<String> runningStatus() {
+        return Arrays.asList(DRAFT.status, WAITING.status, BACK.status, CANCEL.status);
+    }
+
+    /**
+     * 鑾峰彇缁撴潫瀹炰緥鐨勭姸鎬佸垪琛�
+     *
+     * @return 鍖呭惈缁撴潫瀹炰緥鐘舵�佺殑涓嶅彲鍙樺垪琛�
+     * 锛堝寘鍚� FINISH銆両NVALID 鍜� TERMINATION 鐘舵�侊級
+     */
+    public static List<String> finishStatus() {
+        return Arrays.asList(FINISH.status, INVALID.status, TERMINATION.status);
     }
 
     /**
@@ -148,5 +211,5 @@
             throw new ServiceException("娴佺▼鐘舵�佷负绌猴紒");
         }
     }
-}
 
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/TaskAssigneeService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/TaskAssigneeService.java
new file mode 100644
index 0000000..9af6691
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/TaskAssigneeService.java
@@ -0,0 +1,45 @@
+package org.dromara.common.core.service;
+
+import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
+import org.dromara.common.core.domain.model.TaskAssigneeBody;
+
+/**
+ * 宸ヤ綔娴佽璁″櫒鑾峰彇浠诲姟鎵ц浜�
+ *
+ * @author Lion Li
+ */
+public interface TaskAssigneeService {
+
+    /**
+     * 鏌ヨ瑙掕壊骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    TaskAssigneeDTO selectRolesByTaskAssigneeList(TaskAssigneeBody taskQuery);
+
+    /**
+     * 鏌ヨ宀椾綅骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    TaskAssigneeDTO selectPostsByTaskAssigneeList(TaskAssigneeBody taskQuery);
+
+    /**
+     * 鏌ヨ閮ㄩ棬骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    TaskAssigneeDTO selectDeptsByTaskAssigneeList(TaskAssigneeBody taskQuery);
+
+    /**
+     * 鏌ヨ鐢ㄦ埛骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    TaskAssigneeDTO selectUsersByTaskAssigneeList(TaskAssigneeBody taskQuery);
+
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java
index 4e556c9..565362e 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java
@@ -1,5 +1,8 @@
 package org.dromara.common.core.service;
 
+import org.dromara.common.core.domain.dto.CompleteTaskDTO;
+import org.dromara.common.core.domain.dto.StartProcessDTO;
+
 import java.util.List;
 import java.util.Map;
 
@@ -13,64 +16,63 @@
     /**
      * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param businessKeys 涓氬姟id
+     * @param businessIds 涓氬姟id
      * @return 缁撴灉
      */
-    boolean deleteRunAndHisInstance(List<String> businessKeys);
+    boolean deleteInstance(List<Long> businessIds);
 
     /**
      * 鑾峰彇褰撳墠娴佺▼鐘舵��
      *
      * @param taskId 浠诲姟id
+     * @return 鐘舵��
      */
-    String getBusinessStatusByTaskId(String taskId);
+    String getBusinessStatusByTaskId(Long taskId);
 
     /**
      * 鑾峰彇褰撳墠娴佺▼鐘舵��
      *
-     * @param businessKey 涓氬姟id
+     * @param businessId 涓氬姟id
+     * @return 鐘舵��
      */
-    String getBusinessStatus(String businessKey);
+    String getBusinessStatus(String businessId);
 
     /**
-     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
+     * 璁剧疆娴佺▼鍙橀噺
      *
-     * @param taskId       浠诲姟id
-     * @param variableName 鍙橀噺鍚嶇О
-     * @param value        鍙橀噺鍊�
+     * @param instanceId 娴佺▼瀹炰緥id
+     * @param variable   娴佺▼鍙橀噺
      */
-    void setVariable(String taskId, String variableName, Object value);
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
-     *
-     * @param taskId    浠诲姟id
-     * @param variables 娴佺▼鍙橀噺
-     */
-    void setVariables(String taskId, Map<String, Object> variables);
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
-     *
-     * @param taskId       浠诲姟id
-     * @param variableName 鍙橀噺鍚嶇О
-     * @param value        鍙橀噺鍊�
-     */
-    void setVariableLocal(String taskId, String variableName, Object value);
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
-     *
-     * @param taskId    浠诲姟id
-     * @param variables 娴佺▼鍙橀噺
-     */
-    void setVariablesLocal(String taskId, Map<String, Object> variables);
+    void setVariable(Long instanceId, Map<String, Object> variable);
 
     /**
      * 鎸夌収涓氬姟id鏌ヨ娴佺▼瀹炰緥id
      *
-     * @param businessKey 涓氬姟id
+     * @param businessId 涓氬姟id
      * @return 缁撴灉
      */
-    String getInstanceIdByBusinessKey(String businessKey);
+    Long getInstanceIdByBusinessId(String businessId);
+
+    /**
+     * 鏂板绉熸埛娴佺▼瀹氫箟
+     *
+     * @param tenantId 绉熸埛id
+     */
+    void syncDef(String tenantId);
+
+    /**
+     * 鍚姩娴佺▼
+     *
+     * @param startProcess 鍙傛暟
+     * @return 缁撴灉
+     */
+    Map<String, Object> startWorkFlow(StartProcessDTO startProcess);
+
+    /**
+     * 鍔炵悊浠诲姟
+     *
+     * @param completeTask 鍙傛暟
+     * @return 缁撴灉
+     */
+    boolean completeTask(CompleteTaskDTO completeTask);
 }
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
index 19557e1..e2c9236 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -15,6 +15,7 @@
 
 import java.util.Set;
 
+
 /**
  * 鐧诲綍閴存潈鍔╂墜
  * <p>
diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java
index 3729980..6b9e606 100644
--- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java
+++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java
@@ -63,7 +63,7 @@
     private final GenTableColumnMapper genTableColumnMapper;
     private final IdentifierGenerator identifierGenerator;
 
-    private static final String[] TABLE_IGNORE = new String[]{"sj_", "act_", "flw_", "gen_"};
+    private static final String[] TABLE_IGNORE = new String[]{"sj_", "flow_", "gen_"};
 
     /**
      * 鏌ヨ涓氬姟瀛楁鍒楄〃
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
index 0f2c906..b69624c 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.annotation.DataColumn;
 import org.dromara.common.mybatis.annotation.DataPermission;
@@ -32,6 +33,17 @@
     List<SysDeptVo> selectDeptList(@Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
 
     /**
+     * 鍒嗛〉鏌ヨ閮ㄩ棬绠$悊鏁版嵁
+     *
+     * @param queryWrapper 鏌ヨ鏉′欢
+     * @return 閮ㄩ棬淇℃伅闆嗗悎
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "dept_id"),
+    })
+    Page<SysDeptVo> selectPageDeptList(@Param("page") Page<SysDeptVo> page, @Param(Constants.WRAPPER) Wrapper<SysDept> queryWrapper);
+
+    /**
      * 缁熻鎸囧畾閮ㄩ棬ID鐨勯儴闂ㄦ暟閲�
      *
      * @param deptId 閮ㄩ棬ID
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
index 72f1a5e..5888985 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java
@@ -245,4 +245,5 @@
         SysPost post = MapstructUtils.convert(bo, SysPost.class);
         return baseMapper.updateById(post);
     }
+
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
index 4c00735..0a2e485 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
@@ -548,4 +548,5 @@
             }
         });
     }
+
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaskAssigneeServiceImpl.java
new file mode 100644
index 0000000..23dd052
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaskAssigneeServiceImpl.java
@@ -0,0 +1,168 @@
+package org.dromara.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
+import org.dromara.common.core.domain.model.TaskAssigneeBody;
+import org.dromara.common.core.service.TaskAssigneeService;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.system.domain.SysDept;
+import org.dromara.system.domain.SysPost;
+import org.dromara.system.domain.SysRole;
+import org.dromara.system.domain.SysUser;
+import org.dromara.system.domain.vo.SysDeptVo;
+import org.dromara.system.domain.vo.SysPostVo;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.dromara.system.domain.vo.SysUserVo;
+import org.dromara.system.mapper.SysDeptMapper;
+import org.dromara.system.mapper.SysPostMapper;
+import org.dromara.system.mapper.SysRoleMapper;
+import org.dromara.system.mapper.SysUserMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 宸ヤ綔娴佽璁″櫒鑾峰彇浠诲姟鎵ц浜�
+ *
+ * @author Lion Li
+ */
+@RequiredArgsConstructor
+@Service
+public class SysTaskAssigneeServiceImpl implements TaskAssigneeService {
+
+    private final SysPostMapper postMapper;
+    private final SysDeptMapper deptMapper;
+    private final SysUserMapper userMapper;
+    private final SysRoleMapper roleMapper;
+
+    /**
+     * 鏌ヨ瑙掕壊骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    @Override
+    public TaskAssigneeDTO selectRolesByTaskAssigneeList(TaskAssigneeBody taskQuery) {
+        PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
+        QueryWrapper<SysRole> wrapper = Wrappers.query();
+        wrapper.eq("r.del_flag", SystemConstants.NORMAL)
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "r.role_name", taskQuery.getHandlerCode())
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "r.role_key", taskQuery.getHandlerName())
+            .between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
+                "r.create_time", taskQuery.getBeginTime(), taskQuery.getEndTime())
+            .orderByAsc("r.role_sort").orderByAsc("r.create_time");
+        Page<SysRoleVo> page = roleMapper.selectPageRoleList(pageQuery.build(), wrapper);
+        // 浣跨敤灏佽鐨勫瓧娈垫槧灏勬柟娉曡繘琛岃浆鎹�
+        List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRecords(),
+            SysRoleVo::getRoleId, SysRoleVo::getRoleKey, SysRoleVo::getRoleName, null, SysRoleVo::getCreateTime);
+        return new TaskAssigneeDTO(page.getTotal(), handlers);
+    }
+
+    /**
+     * 鏌ヨ宀椾綅骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    @Override
+    public TaskAssigneeDTO selectPostsByTaskAssigneeList(TaskAssigneeBody taskQuery) {
+        PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
+        LambdaQueryWrapper<SysPost> wrapper = Wrappers.<SysPost>lambdaQuery()
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysPost::getPostCategory, taskQuery.getHandlerCode())
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysPost::getPostName, taskQuery.getHandlerName())
+            .between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
+                SysPost::getCreateTime, taskQuery.getBeginTime(), taskQuery.getEndTime());
+        if (StringUtils.isNotBlank(taskQuery.getGroupId())) {
+            Long belongDeptId = Long.valueOf(taskQuery.getGroupId());
+            wrapper.and(x -> {
+                List<SysDept> deptList = deptMapper.selectListByParentId(belongDeptId);
+                List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
+                deptIds.add(belongDeptId);
+                x.in(SysPost::getDeptId, deptIds);
+            });
+        }
+        Page<SysPostVo> page = postMapper.selectPagePostList(pageQuery.build(), wrapper);
+        // 浣跨敤灏佽鐨勫瓧娈垫槧灏勬柟娉曡繘琛岃浆鎹�
+        List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRecords(),
+            SysPostVo::getPostId, SysPostVo::getPostCategory, SysPostVo::getPostName, SysPostVo::getDeptId, SysPostVo::getCreateTime);
+        return new TaskAssigneeDTO(page.getTotal(), handlers);
+    }
+
+    /**
+     * 鏌ヨ閮ㄩ棬骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    @Override
+    public TaskAssigneeDTO selectDeptsByTaskAssigneeList(TaskAssigneeBody taskQuery) {
+        PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
+        LambdaQueryWrapper<SysDept> wrapper = Wrappers.<SysDept>lambdaQuery()
+            .eq(SysDept::getDelFlag, SystemConstants.NORMAL)
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), SysDept::getDeptCategory, taskQuery.getHandlerCode())
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerName()), SysDept::getDeptName, taskQuery.getHandlerName())
+            .between(StringUtils.isNotBlank(taskQuery.getBeginTime()) && StringUtils.isNotBlank(taskQuery.getEndTime()),
+                SysDept::getCreateTime, taskQuery.getBeginTime(), taskQuery.getEndTime())
+            .orderByAsc(SysDept::getAncestors)
+            .orderByAsc(SysDept::getParentId)
+            .orderByAsc(SysDept::getOrderNum)
+            .orderByAsc(SysDept::getDeptId);
+        if (StringUtils.isNotBlank(taskQuery.getGroupId())) {
+            //閮ㄩ棬鏍戞悳绱�
+            wrapper.and(x -> {
+                Long parentId = Long.valueOf(taskQuery.getGroupId());
+                List<SysDept> deptList = deptMapper.selectListByParentId(parentId);
+                List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
+                deptIds.add(parentId);
+                x.in(SysDept::getDeptId, deptIds);
+            });
+        }
+        Page<SysDeptVo> page = deptMapper.selectPageDeptList(pageQuery.build(), wrapper);
+        // 浣跨敤灏佽鐨勫瓧娈垫槧灏勬柟娉曡繘琛岃浆鎹�
+        List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRecords(),
+            SysDeptVo::getDeptId, SysDeptVo::getDeptCategory, SysDeptVo::getDeptName, SysDeptVo::getParentId, SysDeptVo::getCreateTime);
+        return new TaskAssigneeDTO(page.getTotal(), handlers);
+    }
+
+
+    /**
+     * 鏌ヨ鐢ㄦ埛骞惰繑鍥炰换鍔℃寚娲剧殑鍒楄〃锛屾敮鎸佸垎椤�
+     *
+     * @param taskQuery 鏌ヨ鏉′欢
+     * @return 鍔炵悊浜�
+     */
+    @Override
+    public TaskAssigneeDTO selectUsersByTaskAssigneeList(TaskAssigneeBody taskQuery) {
+        PageQuery pageQuery = new PageQuery(taskQuery.getPageSize(), taskQuery.getPageNum());
+        QueryWrapper<SysUser> wrapper = Wrappers.query();
+        wrapper.eq("u.del_flag", SystemConstants.NORMAL)
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerCode()), "u.user_name", taskQuery.getHandlerCode())
+            .like(StringUtils.isNotBlank(taskQuery.getHandlerName()), "u.nick_name", taskQuery.getHandlerName())
+            .between(taskQuery.getBeginTime() != null && taskQuery.getEndTime() != null,
+                "u.create_time", taskQuery.getBeginTime(), taskQuery.getEndTime())
+            .orderByAsc("u.user_id");
+        if (StringUtils.isNotBlank(taskQuery.getGroupId())) {
+            //閮ㄩ棬鏍戞悳绱�
+            wrapper.and(x -> {
+                Long parentId = Long.valueOf(taskQuery.getGroupId());
+                List<SysDept> deptList = deptMapper.selectListByParentId(parentId);
+                List<Long> deptIds = StreamUtils.toList(deptList, SysDept::getDeptId);
+                deptIds.add(parentId);
+                x.in("u.dept_id", deptIds);
+            });
+        }
+        Page<SysUserVo> page = userMapper.selectPageUserList(pageQuery.build(), wrapper);
+        // 浣跨敤灏佽鐨勫瓧娈垫槧灏勬柟娉曡繘琛岃浆鎹�
+        List<TaskAssigneeDTO.TaskHandler> handlers = TaskAssigneeDTO.convertToHandlerList(page.getRecords(),
+            SysUserVo::getUserId, SysUserVo::getUserName, SysUserVo::getNickName, SysUserVo::getDeptId, SysUserVo::getCreateTime);
+        return new TaskAssigneeDTO(page.getTotal(), handlers);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
index 7bfe989..856dabb 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
@@ -15,6 +15,7 @@
 import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.core.constant.TenantConstants;
 import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.WorkflowService;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StreamUtils;
@@ -56,6 +57,7 @@
     private final SysDictTypeMapper dictTypeMapper;
     private final SysDictDataMapper dictDataMapper;
     private final SysConfigMapper configMapper;
+    private final WorkflowService workflowService;
 
     /**
      * 鏌ヨ绉熸埛
@@ -121,7 +123,9 @@
 
         // 鑾峰彇鎵�鏈夌鎴风紪鍙�
         List<String> tenantIds = baseMapper.selectObjs(
-            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), x -> {return Convert.toStr(x);});
+            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), x -> {
+                return Convert.toStr(x);
+            });
         String tenantId = generateTenantId(tenantIds);
         add.setTenantId(tenantId);
         boolean flag = baseMapper.insert(add) > 0;
@@ -191,6 +195,8 @@
             config.setTenantId(tenantId);
         }
         configMapper.insertBatch(sysConfigList);
+        //鏂板绉熸埛娴佺▼瀹氫箟
+        workflowService.syncDef(tenantId);
         return true;
     }
 
@@ -399,7 +405,9 @@
         // 鑾峰彇鎵�鏈夌鎴风紪鍙�
         List<String> tenantIds = baseMapper.selectObjs(
             new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId)
-                .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> {return Convert.toStr(x);});
+                .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> {
+                return Convert.toStr(x);
+            });
         List<SysDictType> saveTypeList = new ArrayList<>();
         List<SysDictData> saveDataList = new ArrayList<>();
         Set<String> set = new HashSet<>();
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
index 6ad866f..9057a0e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -18,6 +18,17 @@
         from sys_dept ${ew.getCustomSqlSegment}
     </select>
 
+    <select id="selectPageDeptList" resultMap="SysDeptResult">
+        select
+        <if test="ew.getSqlSelect != null">
+            ${ew.getSqlSelect}
+        </if>
+        <if test="ew.getSqlSelect == null">
+            *
+        </if>
+        from sys_dept ${ew.getCustomSqlSegment}
+    </select>
+
     <select id="countDeptById" resultType="Long">
         select count(*) from sys_dept where del_flag = '0' and dept_id = #{deptId}
     </select>
diff --git a/ruoyi-modules/ruoyi-workflow/pom.xml b/ruoyi-modules/ruoyi-workflow/pom.xml
index e55839e..d195faf 100644
--- a/ruoyi-modules/ruoyi-workflow/pom.xml
+++ b/ruoyi-modules/ruoyi-workflow/pom.xml
@@ -18,57 +18,14 @@
 
     <dependencies>
 
-        <!--寮曞叆flowable渚濊禆-->
         <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-spring-boot-autoconfigure</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.flowable</groupId>
-                    <artifactId>flowable-spring-security</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-spring-configurator</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-spring-boot-starter-actuator</artifactId>
-        </dependency>
-
-        <!-- 缁樺埗flowable娴佺▼鍥� -->
-        <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-image-generator</artifactId>
-        </dependency>
-
-        <!-- flowable json 杞崲 -->
-        <dependency>
-            <groupId>org.flowable</groupId>
-            <artifactId>flowable-json-converter</artifactId>
-            <version>6.8.0</version>
-        </dependency>
-
-        <!-- svg杞琾ng鍥剧墖宸ュ叿-->
-        <dependency>
-            <groupId>org.apache.xmlgraphics</groupId>
-            <artifactId>batik-all</artifactId>
-            <version>1.17</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>xalan</groupId>
-                    <artifactId>xalan</artifactId>
-                </exclusion>
-            </exclusions>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-sse</artifactId>
         </dependency>
 
         <dependency>
             <groupId>org.dromara</groupId>
-            <artifactId>ruoyi-common-websocket</artifactId>
+            <artifactId>ruoyi-common-doc</artifactId>
         </dependency>
 
         <dependency>
@@ -113,6 +70,14 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-security</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.dromara.warm</groupId>
+            <artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara.warm</groupId>
+            <artifactId>warm-flow-plugin-ui-sb-web</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java
index c3fcafa..1b10eb8 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java
@@ -8,83 +8,6 @@
  */
 public interface FlowConstant {
 
-    String MESSAGE_CURRENT_TASK_IS_NULL = "褰撳墠浠诲姟涓嶅瓨鍦ㄦ垨浣犱笉鏄换鍔″姙鐞嗕汉锛�";
-
-    String MESSAGE_SUSPENDED = "褰撳墠浠诲姟宸叉寕璧蜂笉鍙鎵癸紒";
-
-    /**
-     * 杩炵嚎
-     */
-    String SEQUENCE_FLOW = "sequenceFlow";
-
-    /**
-     * 骞惰缃戝叧
-     */
-    String PARALLEL_GATEWAY = "parallelGateway";
-
-    /**
-     * 鎺掑畠缃戝叧
-     */
-    String EXCLUSIVE_GATEWAY = "exclusiveGateway";
-
-    /**
-     * 鍖呭惈缃戝叧
-     */
-    String INCLUSIVE_GATEWAY = "inclusiveGateway";
-
-    /**
-     * 缁撴潫鑺傜偣
-     */
-    String END_EVENT = "endEvent";
-
-
-    /**
-     * 娴佺▼濮旀淳鏍囪瘑
-     */
-    String PENDING = "PENDING";
-
-    /**
-     * 鍊欓�変汉鏍囪瘑
-     */
-    String CANDIDATE = "candidate";
-
-    /**
-     * 浼氱浠诲姟鎬绘暟
-     */
-    String NUMBER_OF_INSTANCES = "nrOfInstances";
-
-    /**
-     * 姝e湪鎵ц鐨勪細绛炬�绘暟
-     */
-    String NUMBER_OF_ACTIVE_INSTANCES = "nrOfActiveInstances";
-
-    /**
-     * 宸插畬鎴愮殑浼氱浠诲姟鎬绘暟
-     */
-    String NUMBER_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";
-
-    /**
-     * 寰幆鐨勭储寮曞�硷紝鍙互浣跨敤elementIndexVariable灞炴�т慨鏀筶oopCounter鐨勫彉閲忓悕
-     */
-    String LOOP_COUNTER = "loopCounter";
-
-    String ZIP = "ZIP";
-
-    /**
-     * 涓氬姟涓庢祦绋嬪疄渚嬪叧鑱斿璞�
-     */
-    String BUSINESS_INSTANCE_DTO = "businessInstanceDTO";
-
-    /**
-     * 娴佺▼瀹氫箟閰嶇疆
-     */
-    String WF_DEFINITION_CONFIG_VO = "wfDefinitionConfigVo";
-
-    /**
-     * 鑺傜偣閰嶇疆
-     */
-    String WF_NODE_CONFIG_VO = "wfNodeConfigVo";
-
     /**
      * 娴佺▼鍙戣捣浜�
      */
@@ -98,40 +21,46 @@
     /**
      * 涓氬姟id
      */
-    String BUSINESS_KEY = "businessKey";
+    String BUSINESS_ID = "businessId";
 
     /**
-     * 娴佺▼瀹氫箟id
+     * 浠诲姟id
      */
-    String PROCESS_DEFINITION_ID = "processDefinitionId";
+    String TASK_ID = "taskId";
 
     /**
-     * 寮�鍚烦杩囪〃杈惧紡鍙橀噺
+     * 濮旀墭
      */
-    String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
+    String DELEGATE_TASK = "delegateTask";
 
     /**
-     * 妯″瀷鏍囪瘑key鍛藉悕瑙勮寖姝e垯琛ㄨ揪寮�
+     * 杞姙
      */
-    String MODEL_KEY_PATTERN = "^[a-zA-Z][a-zA-Z0-9_]{0,254}$";
+    String TRANSFER_TASK = "transferTask";
 
     /**
-     * 鐢ㄦ埛浠诲姟
+     * 鍔犵
      */
-    String USER_TASK = "userTask";
+    String ADD_SIGNATURE = "addSignature";
 
     /**
-     * 浼氱
+     * 鍑忕
      */
-    String MULTI_INSTANCE = "multiInstance";
+    String REDUCTION_SIGNATURE = "reductionSignature";
 
     /**
-     * 鏄�
+     * 娴佺▼鍒嗙被Id杞悕绉�
      */
-    String TRUE = "0";
+    String CATEGORY_ID_TO_NAME = "category_id_to_name";
 
     /**
-     * 鍚�
+     * 娴佺▼鍒嗙被鍚嶇О
      */
-    String FALSE = "1";
+    String FLOW_CATEGORY_NAME = "flow_category_name#30d";
+
+    /**
+     * 榛樿绉熸埛OA鐢宠鍒嗙被id
+     */
+    Long FLOW_CATEGORY_ID = 100L;
+
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/FormTypeEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/FormTypeEnum.java
deleted file mode 100644
index 083ab7b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/FormTypeEnum.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.dromara.workflow.common.enums;
-
-import cn.hutool.core.util.StrUtil;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.apache.commons.lang3.StringUtils;
-
-import java.util.Arrays;
-
-/**
- * 浠诲姟鐘舵�佹灇涓�
- *
- * @author may
- */
-@Getter
-@AllArgsConstructor
-public enum FormTypeEnum {
-    /**
-     * 鑷畾涔夎〃鍗�
-     */
-    STATIC("static", "鑷畾涔夎〃鍗�"),
-    /**
-     * 鍔ㄦ�佽〃鍗�
-     */
-    DYNAMIC("dynamic", "鍔ㄦ�佽〃鍗�");
-
-    /**
-     * 绫诲瀷
-     */
-    private final String type;
-
-    /**
-     * 鎻忚堪
-     */
-    private final String desc;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     *
-     * @param formType 琛ㄥ崟绫诲瀷
-     */
-    public static String findByType(String formType) {
-        if (StringUtils.isBlank(formType)) {
-            return StrUtil.EMPTY;
-        }
-
-        return Arrays.stream(FormTypeEnum.values())
-            .filter(statusEnum -> statusEnum.getType().equals(formType))
-            .findFirst()
-            .map(FormTypeEnum::getDesc)
-            .orElse(StrUtil.EMPTY);
-    }
-}
-
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/MessageTypeEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/MessageTypeEnum.java
index a282958..0fe5cfe 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/MessageTypeEnum.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/MessageTypeEnum.java
@@ -3,8 +3,10 @@
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Arrays;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 娑堟伅绫诲瀷鏋氫妇
@@ -14,14 +16,17 @@
 @Getter
 @AllArgsConstructor
 public enum MessageTypeEnum {
+
     /**
      * 绔欏唴淇�
      */
     SYSTEM_MESSAGE("1", "绔欏唴淇�"),
+
     /**
      * 閭
      */
     EMAIL_MESSAGE("2", "閭"),
+
     /**
      * 鐭俊
      */
@@ -31,21 +36,18 @@
 
     private final String desc;
 
-    private final static Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = new ConcurrentHashMap<>(MessageTypeEnum.values().length);
-
-    static {
-        for (MessageTypeEnum messageType : MessageTypeEnum.values()) {
-            MESSAGE_TYPE_ENUM_MAP.put(messageType.code, messageType);
-        }
-    }
+    private static final Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = Arrays.stream(values())
+        .collect(Collectors.toConcurrentMap(MessageTypeEnum::getCode, Function.identity()));
 
     /**
      * 鏍规嵁娑堟伅绫诲瀷 code 鑾峰彇 MessageTypeEnum
+     *
      * @param code 娑堟伅绫诲瀷code
      * @return MessageTypeEnum
      */
     public static MessageTypeEnum getByCode(String code) {
-        return MESSAGE_TYPE_ENUM_MAP.get(code);
+        return MESSAGE_TYPE_ENUM_MAP.getOrDefault(code, null);
     }
+
 }
 
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java
new file mode 100644
index 0000000..60be92f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeEnum.java
@@ -0,0 +1,109 @@
+package org.dromara.workflow.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.dromara.common.core.exception.ServiceException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 浠诲姟鍒嗛厤浜烘灇涓�
+ *
+ * @author AprilWind
+ */
+@Getter
+@AllArgsConstructor
+public enum TaskAssigneeEnum {
+
+    /**
+     * 鐢ㄦ埛
+     */
+    USER("鐢ㄦ埛", ""),
+
+    /**
+     * 瑙掕壊
+     */
+    ROLE("瑙掕壊", "role:"),
+
+    /**
+     * 閮ㄩ棬
+     */
+    DEPT("閮ㄩ棬", "dept:"),
+
+    /**
+     * 宀椾綅
+     */
+    POST("宀椾綅", "post:");
+
+    private final String desc;
+    private final String code;
+
+    /**
+     * 鏍规嵁鎻忚堪鑾峰彇瀵瑰簲鐨勬灇涓剧被鍨�
+     * <p>
+     * 閫氳繃浼犲叆鎻忚堪锛屾煡鎵惧苟杩斿洖鍖归厤鐨勬灇涓鹃」銆傚鏋滄湭鎵惧埌鍖归厤椤癸紝浼氭姏鍑� {@link ServiceException}銆�
+     * </p>
+     *
+     * @param desc 鎻忚堪锛岀敤浜庡尮閰嶅搴旂殑鏋氫妇椤�
+     * @return TaskAssigneeEnum 杩斿洖瀵瑰簲鐨勬灇涓剧被鍨�
+     * @throws ServiceException 濡傛灉鏈壘鍒板尮閰嶇殑鏋氫妇椤�
+     */
+    public static TaskAssigneeEnum fromDesc(String desc) {
+        for (TaskAssigneeEnum type : values()) {
+            if (type.getDesc().equals(desc)) {
+                return type;
+            }
+        }
+        throw new ServiceException("鏈煡鐨勫姙鐞嗕汉绫诲瀷: " + desc);
+    }
+
+    /**
+     * 鏍规嵁浠g爜鑾峰彇瀵瑰簲鐨勬灇涓剧被鍨�
+     * <p>
+     * 閫氳繃浼犲叆浠g爜锛屾煡鎵惧苟杩斿洖鍖归厤鐨勬灇涓鹃」銆傚鏋滄湭鎵惧埌鍖归厤椤癸紝浼氭姏鍑� {@link ServiceException}銆�
+     * </p>
+     *
+     * @param code 浠g爜锛岀敤浜庡尮閰嶅搴旂殑鏋氫妇椤�
+     * @return TaskAssigneeEnum 杩斿洖瀵瑰簲鐨勬灇涓剧被鍨�
+     * @throws IllegalArgumentException 濡傛灉鏈壘鍒板尮閰嶇殑鏋氫妇椤�
+     */
+    public static TaskAssigneeEnum fromCode(String code) {
+        for (TaskAssigneeEnum type : values()) {
+            if (type.getCode().equals(code)) {
+                return type;
+            }
+        }
+        throw new ServiceException("鏈煡鐨勫姙鐞嗕汉绫诲瀷浠g爜: " + code);
+    }
+
+    /**
+     * 鑾峰彇鎵�鏈夊姙鐞嗕汉绫诲瀷鐨勬弿杩板垪琛�
+     * <p>
+     * 鑾峰彇褰撳墠鏋氫妇绫绘墍鏈夐」鐨勬弿杩板瓧娈靛垪琛紝閫氬父鐢ㄤ簬灞曠ず閫夋嫨椤广��
+     * </p>
+     *
+     * @return List<String> 杩斿洖鎵�鏈夊姙鐞嗕汉绫诲瀷鐨勬弿杩板垪琛�
+     */
+    public static List<String> getAssigneeTypeList() {
+        return Arrays.stream(values())
+            .map(TaskAssigneeEnum::getDesc)
+            .collect(Collectors.toList());
+    }
+
+    /**
+     * 鑾峰彇鎵�鏈夊姙鐞嗕汉绫诲瀷鐨勪唬鐮佸垪琛�
+     * <p>
+     * 鑾峰彇褰撳墠鏋氫妇绫绘墍鏈夐」鐨勪唬鐮佸瓧娈靛垪琛紝閫氬父鐢ㄤ簬绋嬪簭鍐呴儴閫昏緫鐨勫垽鏂��
+     * </p>
+     *
+     * @return List<String> 杩斿洖鎵�鏈夊姙鐞嗕汉绫诲瀷鐨勪唬鐮佸垪琛�
+     */
+    public static List<String> getAssigneeCodeList() {
+        return Arrays.stream(values())
+            .map(TaskAssigneeEnum::getCode)
+            .collect(Collectors.toList());
+    }
+}
+
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeType.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeType.java
new file mode 100644
index 0000000..eed1b91
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskAssigneeType.java
@@ -0,0 +1,49 @@
+package org.dromara.workflow.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 浜哄憳绫诲瀷
+ *
+ * @author AprilWind
+ */
+@Getter
+@AllArgsConstructor
+public enum TaskAssigneeType {
+
+    /**
+     * 寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺
+     * <p>璇ユ潈闄愯〃绀虹敤鎴锋槸寰呭姙浠诲姟鐨勫鎵逛汉锛岃礋璐e鏍镐换鍔$殑鎵ц鎯呭喌銆�</p>
+     */
+    APPROVER("1", "寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺"),
+
+    /**
+     * 寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺
+     * <p>璇ユ潈闄愯〃绀虹敤鎴锋槸寰呭姙浠诲姟鐨勮浆鍔炰汉锛岃礋璐e皢浠诲姟鍒嗛厤缁欏叾浠栦汉鍛樸��</p>
+     */
+    TRANSFER("2", "寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺"),
+
+    /**
+     * 寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺
+     * <p>璇ユ潈闄愯〃绀虹敤鎴锋槸寰呭姙浠诲姟鐨勫鎵樹汉锛岃兘澶熷鎵樺叾浠栦汉浠d负澶勭悊浠诲姟銆�</p>
+     */
+    DELEGATE("3", "寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺"),
+
+    /**
+     * 寰呭姙浠诲姟鐨勬妱閫佷汉鏉冮檺
+     * <p>璇ユ潈闄愯〃绀虹敤鎴锋槸寰呭姙浠诲姟鐨勬妱閫佷汉锛屼粎鎺ユ敹浠诲姟淇℃伅鐨勯�氱煡锛屼笉鍙備笌浠诲姟鐨勫鎵规垨澶勭悊銆�</p>
+     */
+    COPY("4", "寰呭姙浠诲姟鐨勬妱閫佷汉鏉冮檺");
+
+    /**
+     * 绫诲瀷
+     */
+    private final String code;
+
+    /**
+     * 鎻忚堪
+     */
+    private final String description;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskStatusEnum.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskStatusEnum.java
index 7b2f55c..d18ebb0 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskStatusEnum.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/TaskStatusEnum.java
@@ -3,9 +3,10 @@
 import cn.hutool.core.util.StrUtil;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
-import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 浠诲姟鐘舵�佹灇涓�
@@ -15,50 +16,62 @@
 @Getter
 @AllArgsConstructor
 public enum TaskStatusEnum {
+
     /**
      * 鎾ら攢
      */
     CANCEL("cancel", "鎾ら攢"),
+
     /**
      * 閫氳繃
      */
     PASS("pass", "閫氳繃"),
+
     /**
      * 寰呭鏍�
      */
     WAITING("waiting", "寰呭鏍�"),
+
     /**
      * 浣滃簾
      */
     INVALID("invalid", "浣滃簾"),
+
     /**
      * 閫�鍥�
      */
     BACK("back", "閫�鍥�"),
+
     /**
      * 缁堟
      */
     TERMINATION("termination", "缁堟"),
+
     /**
      * 杞姙
      */
     TRANSFER("transfer", "杞姙"),
+
     /**
      * 濮旀墭
      */
-    PENDING("pending", "濮旀墭"),
+    DEPUTE("depute", "濮旀墭"),
+
     /**
      * 鎶勯��
      */
     COPY("copy", "鎶勯��"),
+
     /**
      * 鍔犵
      */
     SIGN("sign", "鍔犵"),
+
     /**
      * 鍑忕
      */
     SIGN_OFF("sign_off", "鍑忕"),
+
     /**
      * 瓒呮椂
      */
@@ -74,21 +87,18 @@
      */
     private final String desc;
 
+    private static final Map<String, String> STATUS_DESC_MAP = Arrays.stream(values())
+        .collect(Collectors.toConcurrentMap(TaskStatusEnum::getStatus, TaskStatusEnum::getDesc));
+
     /**
      * 浠诲姟涓氬姟鐘舵��
      *
      * @param status 鐘舵��
      */
     public static String findByStatus(String status) {
-        if (StringUtils.isBlank(status)) {
-            return StrUtil.EMPTY;
-        }
-
-        return Arrays.stream(TaskStatusEnum.values())
-            .filter(statusEnum -> statusEnum.getStatus().equals(status))
-            .findFirst()
-            .map(TaskStatusEnum::getDesc)
-            .orElse(StrUtil.EMPTY);
+        // 浠庣紦瀛樹腑鐩存帴鑾峰彇鎻忚堪
+        return STATUS_DESC_MAP.getOrDefault(status, StrUtil.EMPTY);
     }
+
 }
 
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/config/WarmFlowConfig.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/config/WarmFlowConfig.java
new file mode 100644
index 0000000..a38c83e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/config/WarmFlowConfig.java
@@ -0,0 +1,15 @@
+package org.dromara.workflow.config;
+
+
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * warmFlow閰嶇疆
+ *
+ * @author may
+ */
+@Configuration
+public class WarmFlowConfig {
+
+}
+
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java
deleted file mode 100644
index 842d3d6..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package org.dromara.workflow.controller;
-
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotEmpty;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.workflow.domain.bo.ModelBo;
-import org.dromara.workflow.domain.vo.ModelVo;
-import org.dromara.workflow.service.IActModelService;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.repository.Model;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 妯″瀷绠$悊 鎺у埗灞�
- *
- * @author may
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/model")
-public class ActModelController extends BaseController {
-
-    @Autowired(required = false)
-    private RepositoryService repositoryService;
-    private final IActModelService actModelService;
-
-
-    /**
-     * 鍒嗛〉鏌ヨ妯″瀷
-     *
-     * @param modelBo 妯″瀷鍙傛暟
-     */
-    @GetMapping("/list")
-    public TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery) {
-        return actModelService.page(modelBo, pageQuery);
-    }
-
-    /**
-     * 鏂板妯″瀷
-     *
-     * @param modelBo 妯″瀷璇锋眰瀵硅薄
-     */
-    @Log(title = "妯″瀷绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/save")
-    public R<Void> saveNewModel(@Validated(AddGroup.class) @RequestBody ModelBo modelBo) {
-        return toAjax(actModelService.saveNewModel(modelBo));
-    }
-
-    /**
-     * 鏌ヨ妯″瀷
-     *
-     * @param id 妯″瀷id
-     */
-    @GetMapping("/getInfo/{id}")
-    public R<ModelVo> getInfo(@NotBlank(message = "妯″瀷id涓嶈兘涓虹┖") @PathVariable String id) {
-        return R.ok(actModelService.getInfo(id));
-    }
-
-    /**
-     * 淇敼妯″瀷淇℃伅
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     */
-    @Log(title = "妯″瀷绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping(value = "/update")
-    public R<Void> update(@RequestBody ModelBo modelBo) {
-        return toAjax(actModelService.update(modelBo));
-    }
-
-    /**
-     * 缂栬緫XMl妯″瀷
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     */
-    @Log(title = "妯″瀷绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping(value = "/editModelXml")
-    public R<Void> editModel(@Validated(EditGroup.class) @RequestBody ModelBo modelBo) {
-        return toAjax(actModelService.editModelXml(modelBo));
-    }
-
-    /**
-     * 鍒犻櫎娴佺▼妯″瀷
-     *
-     * @param ids 妯″瀷id
-     */
-    @Log(title = "妯″瀷绠$悊", businessType = BusinessType.DELETE)
-    @RepeatSubmit()
-    @DeleteMapping("/{ids}")
-    @Transactional(rollbackFor = Exception.class)
-    public R<Void> delete(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖") @PathVariable String[] ids) {
-        Arrays.stream(ids).parallel().forEachOrdered(repositoryService::deleteModel);
-        return R.ok();
-    }
-
-    /**
-     * 妯″瀷閮ㄧ讲
-     *
-     * @param id 妯″瀷id
-     */
-    @Log(title = "妯″瀷绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/modelDeploy/{id}")
-    public R<Void> deploy(@NotBlank(message = "妯″瀷id涓嶈兘涓虹┖") @PathVariable("id") String id) {
-        return toAjax(actModelService.modelDeploy(id));
-    }
-
-    /**
-     * 瀵煎嚭妯″瀷zip鍘嬬缉鍖�
-     *
-     * @param modelIds 妯″瀷id
-     * @param response 鐩稿簲
-     */
-    @GetMapping("/export/zip/{modelIds}")
-    public void exportZip(@NotEmpty(message = "妯″瀷id涓嶈兘涓虹┖") @PathVariable List<String> modelIds,
-                          HttpServletResponse response) {
-        actModelService.exportZip(modelIds, response);
-    }
-
-    /**
-     * 澶嶅埗妯″瀷
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     */
-    @PostMapping("/copyModel")
-    public R<Void> copyModel(@RequestBody ModelBo modelBo) {
-        return toAjax(actModelService.copyModel(modelBo));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java
deleted file mode 100644
index 5198bd1..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessDefinitionController.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.dromara.workflow.controller;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.workflow.domain.bo.ProcessDefinitionBo;
-import org.dromara.workflow.domain.vo.ProcessDefinitionVo;
-import org.dromara.workflow.service.IActProcessDefinitionService;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * 娴佺▼瀹氫箟绠$悊 鎺у埗灞�
- *
- * @author may
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/processDefinition")
-public class ActProcessDefinitionController extends BaseController {
-
-    private final IActProcessDefinitionService actProcessDefinitionService;
-
-    /**
-     * 鍒嗛〉鏌ヨ
-     *
-     * @param bo 鍙傛暟
-     */
-    @GetMapping("/list")
-    public TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo bo, PageQuery pageQuery) {
-        return actProcessDefinitionService.page(bo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ鍘嗗彶娴佺▼瀹氫箟鍒楄〃
-     *
-     * @param key 娴佺▼瀹氫箟key
-     */
-    @GetMapping("/getListByKey/{key}")
-    public R<List<ProcessDefinitionVo>> getListByKey(@NotEmpty(message = "娴佺▼瀹氫箟key涓嶈兘涓虹┖") @PathVariable String key) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessDefinitionService.getListByKey(key));
-    }
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟鍥剧墖
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @GetMapping("/definitionImage/{processDefinitionId}")
-    public R<String> definitionImage(@PathVariable String processDefinitionId) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessDefinitionService.definitionImage(processDefinitionId));
-    }
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟xml鏂囦欢
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @GetMapping("/definitionXml/{processDefinitionId}")
-    public R<Map<String, Object>> definitionXml(@NotBlank(message = "娴佺▼瀹氫箟id涓嶈兘涓虹┖") @PathVariable String processDefinitionId) {
-        Map<String, Object> map = new HashMap<>();
-        String xmlStr = actProcessDefinitionService.definitionXml(processDefinitionId);
-        map.put("xml", Arrays.asList(xmlStr.split("\n")));
-        map.put("xmlStr", xmlStr);
-        return R.ok(map);
-    }
-
-    /**
-     * 鍒犻櫎娴佺▼瀹氫箟
-     *
-     * @param deploymentIds        閮ㄧ讲id
-     * @param processDefinitionIds 娴佺▼瀹氫箟id
-     */
-    @Log(title = "娴佺▼瀹氫箟绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{deploymentIds}/{processDefinitionIds}")
-    public R<Void> deleteDeployment(@NotNull(message = "娴佺▼閮ㄧ讲id涓嶈兘涓虹┖") @PathVariable List<String> deploymentIds,
-                                    @NotNull(message = "娴佺▼瀹氫箟id涓嶈兘涓虹┖") @PathVariable List<String> processDefinitionIds) {
-        return toAjax(actProcessDefinitionService.deleteDeployment(deploymentIds, processDefinitionIds));
-    }
-
-    /**
-     * 婵�娲绘垨鑰呮寕璧锋祦绋嬪畾涔�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @Log(title = "娴佺▼瀹氫箟绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping("/updateDefinitionState/{processDefinitionId}")
-    public R<Void> updateDefinitionState(@NotBlank(message = "娴佺▼瀹氫箟id涓嶈兘涓虹┖") @PathVariable String processDefinitionId) {
-        return toAjax(actProcessDefinitionService.updateDefinitionState(processDefinitionId));
-    }
-
-    /**
-     * 杩佺Щ娴佺▼瀹氫箟
-     *
-     * @param currentProcessDefinitionId 褰撳墠娴佺▼瀹氫箟id
-     * @param fromProcessDefinitionId    闇�瑕佽縼绉诲埌鐨勬祦绋嬪畾涔塱d
-     */
-    @Log(title = "娴佺▼瀹氫箟绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping("/migrationDefinition/{currentProcessDefinitionId}/{fromProcessDefinitionId}")
-    public R<Void> migrationDefinition(@NotBlank(message = "褰撳墠娴佺▼瀹氫箟id") @PathVariable String currentProcessDefinitionId,
-                                       @NotBlank(message = "闇�瑕佽縼绉诲埌鐨勬祦绋嬪畾涔塱d") @PathVariable String fromProcessDefinitionId) {
-        return toAjax(actProcessDefinitionService.migrationDefinition(currentProcessDefinitionId, fromProcessDefinitionId));
-    }
-
-    /**
-     * 娴佺▼瀹氫箟杞崲涓烘ā鍨�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @Log(title = "娴佺▼瀹氫箟绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping("/convertToModel/{processDefinitionId}")
-    public R<Void> convertToModel(@NotEmpty(message = "娴佺▼瀹氫箟id涓嶈兘涓虹┖") @PathVariable String processDefinitionId) {
-        return toAjax(actProcessDefinitionService.convertToModel(processDefinitionId));
-    }
-
-    /**
-     * 閫氳繃zip鎴杧ml閮ㄧ讲娴佺▼瀹氫箟
-     *
-     * @param file         鏂囦欢
-     * @param categoryCode 鍒嗙被
-     */
-    @Log(title = "娴佺▼瀹氫箟绠$悊", businessType = BusinessType.INSERT)
-    @PostMapping("/deployByFile")
-    public void deployByFile(@RequestParam("file") MultipartFile file, @RequestParam("categoryCode") String categoryCode) {
-        actProcessDefinitionService.deployByFile(file, categoryCode);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java
deleted file mode 100644
index 931b9f5..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package org.dromara.workflow.controller;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.workflow.domain.bo.ProcessInstanceBo;
-import org.dromara.workflow.domain.bo.ProcessInvalidBo;
-import org.dromara.workflow.domain.bo.TaskUrgingBo;
-import org.dromara.workflow.domain.vo.ActHistoryInfoVo;
-import org.dromara.workflow.domain.vo.ProcessInstanceVo;
-import org.dromara.workflow.service.IActProcessInstanceService;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 娴佺▼瀹炰緥绠$悊 鎺у埗灞�
- *
- * @author may
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/processInstance")
-public class ActProcessInstanceController extends BaseController {
-
-    private final IActProcessInstanceService actProcessInstanceService;
-
-    /**
-     * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
-     *
-     * @param bo 鍙傛暟
-     */
-    @GetMapping("/getPageByRunning")
-    public TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo bo, PageQuery pageQuery) {
-        return actProcessInstanceService.getPageByRunning(bo, pageQuery);
-    }
-
-    /**
-     * 鍒嗛〉鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥
-     *
-     * @param bo 鍙傛暟
-     */
-    @GetMapping("/getPageByFinish")
-    public TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo bo, PageQuery pageQuery) {
-        return actProcessInstanceService.getPageByFinish(bo, pageQuery);
-    }
-
-    /**
-     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥�
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @GetMapping("/getHistoryImage/{businessKey}")
-    public R<String> getHistoryImage(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryImage(businessKey));
-    }
-
-    /**
-     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @GetMapping("/getHistoryList/{businessKey}")
-    public R<Map<String, Object>> getHistoryList(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryList(businessKey));
-    }
-
-    /**
-     * 鑾峰彇瀹℃壒璁板綍
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @GetMapping("/getHistoryRecord/{businessKey}")
-    public R<List<ActHistoryInfoVo>> getHistoryRecord(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
-        return R.ok(actProcessInstanceService.getHistoryRecord(businessKey));
-    }
-
-    /**
-     * 浣滃簾娴佺▼瀹炰緥锛屼笉浼氬垹闄ゅ巻鍙茶褰�(鍒犻櫎杩愯涓殑瀹炰緥)
-     *
-     * @param processInvalidBo 鍙傛暟
-     */
-    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.DELETE)
-    @RepeatSubmit()
-    @PostMapping("/deleteRunInstance")
-    public R<Void> deleteRunInstance(@Validated(AddGroup.class) @RequestBody ProcessInvalidBo processInvalidBo) {
-        return toAjax(actProcessInstanceService.deleteRunInstance(processInvalidBo));
-    }
-
-    /**
-     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     */
-    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.DELETE)
-    @RepeatSubmit()
-    @DeleteMapping("/deleteRunAndHisInstance/{businessKeys}")
-    public R<Void> deleteRunAndHisInstance(@NotNull(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String[] businessKeys) {
-        return toAjax(actProcessInstanceService.deleteRunAndHisInstance(Arrays.asList(businessKeys)));
-    }
-
-    /**
-     * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     */
-    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.DELETE)
-    @RepeatSubmit()
-    @DeleteMapping("/deleteFinishAndHisInstance/{businessKeys}")
-    public R<Void> deleteFinishAndHisInstance(@NotNull(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String[] businessKeys) {
-        return toAjax(actProcessInstanceService.deleteFinishAndHisInstance(Arrays.asList(businessKeys)));
-    }
-
-    /**
-     * 鎾ら攢娴佺▼鐢宠
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/cancelProcessApply/{businessKey}")
-    public R<Void> cancelProcessApply(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
-        return toAjax(actProcessInstanceService.cancelProcessApply(businessKey));
-    }
-
-    /**
-     * 鍒嗛〉鏌ヨ褰撳墠鐧诲綍浜哄崟鎹�
-     *
-     * @param bo 鍙傛暟
-     */
-    @GetMapping("/getPageByCurrent")
-    public TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo bo, PageQuery pageQuery) {
-        return actProcessInstanceService.getPageByCurrent(bo, pageQuery);
-    }
-
-    /**
-     * 浠诲姟鍌姙(缁欏綋鍓嶄换鍔″姙鐞嗕汉鍙戦�佺珯鍐呬俊锛岄偖浠讹紝鐭俊绛�)
-     *
-     * @param taskUrgingBo 浠诲姟鍌姙
-     */
-    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/taskUrging")
-    public R<Void> taskUrging(@RequestBody TaskUrgingBo taskUrgingBo) {
-        return toAjax(actProcessInstanceService.taskUrging(taskUrgingBo));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java
deleted file mode 100644
index 25724b6..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java
+++ /dev/null
@@ -1,295 +0,0 @@
-package org.dromara.workflow.controller;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import jakarta.validation.constraints.NotBlank;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.workflow.domain.WfTaskBackNode;
-import org.dromara.workflow.domain.bo.*;
-import org.dromara.workflow.domain.vo.TaskVo;
-import org.dromara.workflow.domain.vo.VariableVo;
-import org.dromara.workflow.service.IActTaskService;
-import org.dromara.workflow.service.IWfTaskBackNodeService;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.engine.TaskService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 浠诲姟绠$悊 鎺у埗灞�
- *
- * @author may
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/task")
-public class ActTaskController extends BaseController {
-
-    @Autowired(required = false)
-    private TaskService taskService;
-    private final IActTaskService actTaskService;
-    private final IWfTaskBackNodeService wfTaskBackNodeService;
-
-
-    /**
-     * 鍚姩浠诲姟
-     *
-     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/startWorkFlow")
-    public R<Map<String, Object>> startWorkFlow(@Validated(AddGroup.class) @RequestBody StartProcessBo startProcessBo) {
-        Map<String, Object> map = actTaskService.startWorkFlow(startProcessBo);
-        return R.ok("鎻愪氦鎴愬姛", map);
-    }
-
-    /**
-     * 鍔炵悊浠诲姟
-     *
-     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/completeTask")
-    public R<Void> completeTask(@Validated(AddGroup.class) @RequestBody CompleteTaskBo completeTaskBo) {
-        return toAjax(actTaskService.completeTask(completeTaskBo));
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @GetMapping("/getPageByTaskWait")
-    public TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery) {
-        return actTaskService.getPageByTaskWait(taskBo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊緟鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @GetMapping("/getPageByAllTaskWait")
-    public TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery) {
-        return actTaskService.getPageByAllTaskWait(taskBo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫凡鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @GetMapping("/getPageByTaskFinish")
-    public TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery) {
-        return actTaskService.getPageByTaskFinish(taskBo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @GetMapping("/getPageByTaskCopy")
-    public TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery) {
-        return actTaskService.getPageByTaskCopy(taskBo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊凡鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @GetMapping("/getPageByAllTaskFinish")
-    public TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery) {
-        return actTaskService.getPageByAllTaskFinish(taskBo, pageQuery);
-    }
-
-    /**
-     * 绛炬敹锛堟嬀鍙栵級浠诲姟
-     *
-     * @param taskId 浠诲姟id
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/claim/{taskId}")
-    public R<Void> claimTask(@NotBlank(message = "浠诲姟id涓嶈兘涓虹┖") @PathVariable String taskId) {
-        try {
-            taskService.claim(taskId, Convert.toStr(LoginHelper.getUserId()));
-            return R.ok();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.fail("绛炬敹浠诲姟澶辫触锛�" + e.getMessage());
-        }
-    }
-
-    /**
-     * 褰掕繕锛堟嬀鍙栫殑锛変换鍔�
-     *
-     * @param taskId 浠诲姟id
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/returnTask/{taskId}")
-    public R<Void> returnTask(@NotBlank(message = "浠诲姟id涓嶈兘涓虹┖") @PathVariable String taskId) {
-        try {
-            taskService.setAssignee(taskId, null);
-            return R.ok();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return R.fail("褰掕繕浠诲姟澶辫触锛�" + e.getMessage());
-        }
-    }
-
-    /**
-     * 濮旀淳浠诲姟
-     *
-     * @param delegateBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/delegateTask")
-    public R<Void> delegateTask(@Validated({AddGroup.class}) @RequestBody DelegateBo delegateBo) {
-        return toAjax(actTaskService.delegateTask(delegateBo));
-    }
-
-    /**
-     * 缁堟浠诲姟
-     *
-     * @param terminationBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.DELETE)
-    @RepeatSubmit()
-    @PostMapping("/terminationTask")
-    public R<Void> terminationTask(@RequestBody TerminationBo terminationBo) {
-        return toAjax(actTaskService.terminationTask(terminationBo));
-    }
-
-    /**
-     * 杞姙浠诲姟
-     *
-     * @param transmitBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/transferTask")
-    public R<Void> transferTask(@Validated({AddGroup.class}) @RequestBody TransmitBo transmitBo) {
-        return toAjax(actTaskService.transferTask(transmitBo));
-    }
-
-    /**
-     * 浼氱浠诲姟鍔犵
-     *
-     * @param addMultiBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/addMultiInstanceExecution")
-    public R<Void> addMultiInstanceExecution(@Validated({AddGroup.class}) @RequestBody AddMultiBo addMultiBo) {
-        return toAjax(actTaskService.addMultiInstanceExecution(addMultiBo));
-    }
-
-    /**
-     * 浼氱浠诲姟鍑忕
-     *
-     * @param deleteMultiBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/deleteMultiInstanceExecution")
-    public R<Void> deleteMultiInstanceExecution(@Validated({AddGroup.class}) @RequestBody DeleteMultiBo deleteMultiBo) {
-        return toAjax(actTaskService.deleteMultiInstanceExecution(deleteMultiBo));
-    }
-
-    /**
-     * 椹冲洖瀹℃壒
-     *
-     * @param backProcessBo 鍙傛暟
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/backProcess")
-    public R<String> backProcess(@Validated({AddGroup.class}) @RequestBody BackProcessBo backProcessBo) {
-        return R.ok("鎿嶄綔鎴愬姛", actTaskService.backProcess(backProcessBo));
-    }
-
-    /**
-     * 鑾峰彇褰撳墠浠诲姟
-     *
-     * @param taskId 浠诲姟id
-     */
-    @GetMapping("/getTaskById/{taskId}")
-    public R<TaskVo> getTaskById(@PathVariable String taskId) {
-        return R.ok(QueryUtils.getTask(taskId));
-    }
-
-
-    /**
-     * 淇敼浠诲姟鍔炵悊浜�
-     *
-     * @param taskIds 浠诲姟id
-     * @param userId  鍔炵悊浜篿d
-     */
-    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping("/updateAssignee/{taskIds}/{userId}")
-    public R<Void> updateAssignee(@PathVariable String[] taskIds, @PathVariable String userId) {
-        return toAjax(actTaskService.updateAssignee(taskIds, userId));
-    }
-
-    /**
-     * 鏌ヨ娴佺▼鍙橀噺
-     *
-     * @param taskId 浠诲姟id
-     */
-    @GetMapping("/getInstanceVariable/{taskId}")
-    public R<List<VariableVo>> getProcessInstVariable(@PathVariable String taskId) {
-        return R.ok(actTaskService.getInstanceVariable(taskId));
-    }
-
-    /**
-     * 鑾峰彇鍙┏鍥炲緱浠诲姟鑺傜偣
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     */
-    @GetMapping("/getTaskNodeList/{processInstanceId}")
-    public R<List<WfTaskBackNode>> getNodeList(@PathVariable String processInstanceId) {
-        return R.ok(CollUtil.reverse(wfTaskBackNodeService.getListByInstanceId(processInstanceId)));
-    }
-
-    /**
-     * 鏌ヨ宸ヤ綔娴佷换鍔$敤鎴烽�夋嫨鍔犵浜哄憳
-     *
-     * @param taskId 浠诲姟id
-     */
-    @GetMapping("/getTaskUserIdsByAddMultiInstance/{taskId}")
-    public R<String> getTaskUserIdsByAddMultiInstance(@PathVariable String taskId) {
-        return R.ok("鎿嶄綔鎴愬姛", actTaskService.getTaskUserIdsByAddMultiInstance(taskId));
-    }
-
-    /**
-     * 鏌ヨ宸ヤ綔娴侀�夋嫨鍑忕浜哄憳
-     *
-     * @param taskId 浠诲姟id
-     */
-    @GetMapping("/getListByDeleteMultiInstance/{taskId}")
-    public R<List<TaskVo>> getListByDeleteMultiInstance(@PathVariable String taskId) {
-        return R.ok(actTaskService.getListByDeleteMultiInstance(taskId));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwCategoryController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwCategoryController.java
new file mode 100644
index 0000000..99fa064
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwCategoryController.java
@@ -0,0 +1,130 @@
+package org.dromara.workflow.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.lang.tree.Tree;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.workflow.domain.bo.FlowCategoryBo;
+import org.dromara.workflow.domain.vo.FlowCategoryVo;
+import org.dromara.workflow.service.IFlwCategoryService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 娴佺▼鍒嗙被
+ *
+ * @author may
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/workflow/category")
+public class FlwCategoryController extends BaseController {
+
+    private final IFlwCategoryService flwCategoryService;
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鍒楄〃
+     */
+    @SaCheckPermission("workflow:category:list")
+    @GetMapping("/list")
+    public R<List<FlowCategoryVo>> list(FlowCategoryBo bo) {
+        List<FlowCategoryVo> list = flwCategoryService.queryList(bo);
+        return R.ok(list);
+    }
+
+    /**
+     * 瀵煎嚭娴佺▼鍒嗙被鍒楄〃
+     */
+    @SaCheckPermission("workflow:category:export")
+    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(FlowCategoryBo bo, HttpServletResponse response) {
+        List<FlowCategoryVo> list = flwCategoryService.queryList(bo);
+        ExcelUtil.exportExcel(list, "娴佺▼鍒嗙被", FlowCategoryVo.class, response);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍒嗙被璇︾粏淇℃伅
+     *
+     * @param categoryId 涓婚敭
+     */
+    @SaCheckPermission("workflow:category:query")
+    @GetMapping("/{categoryId}")
+    public R<FlowCategoryVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖") @PathVariable Long categoryId) {
+        flwCategoryService.checkCategoryDataScope(categoryId);
+        return R.ok(flwCategoryService.queryById(categoryId));
+    }
+
+    /**
+     * 鏂板娴佺▼鍒嗙被
+     */
+    @SaCheckPermission("workflow:category:add")
+    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody FlowCategoryBo category) {
+        if (!flwCategoryService.checkCategoryNameUnique(category)) {
+            return R.fail("鏂板娴佺▼鍒嗙被'" + category.getCategoryName() + "'澶辫触锛屾祦绋嬪垎绫诲悕绉板凡瀛樺湪");
+        }
+        return toAjax(flwCategoryService.insertByBo(category));
+    }
+
+    /**
+     * 淇敼娴佺▼鍒嗙被
+     */
+    @SaCheckPermission("workflow:category:edit")
+    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody FlowCategoryBo category) {
+        Long categoryId = category.getCategoryId();
+        flwCategoryService.checkCategoryDataScope(categoryId);
+        if (!flwCategoryService.checkCategoryNameUnique(category)) {
+            return R.fail("淇敼娴佺▼鍒嗙被'" + category.getCategoryName() + "'澶辫触锛屾祦绋嬪垎绫诲悕绉板凡瀛樺湪");
+        } else if (category.getParentId().equals(categoryId)) {
+            return R.fail("淇敼娴佺▼鍒嗙被'" + category.getCategoryName() + "'澶辫触锛屼笂绾ф祦绋嬪垎绫讳笉鑳芥槸鑷繁");
+        }
+        return toAjax(flwCategoryService.updateByBo(category));
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼鍒嗙被
+     *
+     * @param categoryId 涓婚敭
+     */
+    @SaCheckPermission("workflow:category:remove")
+    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{categoryId}")
+    public R<Void> remove(@PathVariable Long categoryId) {
+        if (flwCategoryService.hasChildByCategoryId(categoryId)) {
+            return R.warn("瀛樺湪涓嬬骇娴佺▼鍒嗙被,涓嶅厑璁稿垹闄�");
+        }
+        if (flwCategoryService.checkCategoryExistDefinition(categoryId)) {
+            return R.warn("娴佺▼鍒嗙被瀛樺湪娴佺▼瀹氫箟,涓嶅厑璁稿垹闄�");
+        }
+        return toAjax(flwCategoryService.deleteWithValidById(categoryId));
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍒嗙被鏍戝垪琛�
+     *
+     * @param categoryBo 娴佺▼鍒嗙被
+     */
+    @GetMapping("/categoryTree")
+    public R<List<Tree<Long>>> categoryTree(FlowCategoryBo categoryBo) {
+        return R.ok(flwCategoryService.selectCategoryTreeList(categoryBo));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java
new file mode 100644
index 0000000..b125f0f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwDefinitionController.java
@@ -0,0 +1,194 @@
+package org.dromara.workflow.controller;
+
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.warm.flow.core.entity.Definition;
+import org.dromara.warm.flow.core.service.DefService;
+import org.dromara.warm.flow.orm.entity.FlowDefinition;
+import org.dromara.workflow.domain.vo.FlowDefinitionVo;
+import org.dromara.workflow.service.IFlwDefinitionService;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 娴佺▼瀹氫箟绠$悊 鎺у埗灞�
+ *
+ * @author may
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/workflow/definition")
+public class FlwDefinitionController extends BaseController {
+
+    private final IFlwDefinitionService flwDefinitionService;
+    private final DefService defService;
+
+    /**
+     * 鏌ヨ娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 鍙傛暟
+     * @param pageQuery      鍒嗛〉
+     */
+    @GetMapping("/list")
+    public TableDataInfo<FlowDefinitionVo> list(FlowDefinition flowDefinition, PageQuery pageQuery) {
+        return flwDefinitionService.queryList(flowDefinition, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ鏈彂甯冪殑娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 鍙傛暟
+     * @param pageQuery      鍒嗛〉
+     */
+    @GetMapping("/unPublishList")
+    public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery) {
+        return flwDefinitionService.unPublishList(flowDefinition, pageQuery);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼瀹氫箟璇︾粏淇℃伅
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @GetMapping(value = "/{id}")
+    public R<Definition> getInfo(@PathVariable Long id) {
+        return R.ok(defService.getById(id));
+    }
+
+    /**
+     * 鏂板娴佺▼瀹氫箟
+     *
+     * @param flowDefinition 鍙傛暟
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.INSERT)
+    @PostMapping
+    @RepeatSubmit()
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> add(@RequestBody FlowDefinition flowDefinition) {
+        return R.ok(defService.checkAndSave(flowDefinition));
+    }
+
+    /**
+     * 淇敼娴佺▼瀹氫箟
+     *
+     * @param flowDefinition 鍙傛暟
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @RepeatSubmit()
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> edit(@RequestBody FlowDefinition flowDefinition) {
+        return R.ok(defService.updateById(flowDefinition));
+    }
+
+    /**
+     * 鍙戝竷娴佺▼瀹氫箟
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.INSERT)
+    @PutMapping("/publish/{id}")
+    @RepeatSubmit()
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> publish(@PathVariable Long id) {
+        return R.ok(flwDefinitionService.publish(id));
+    }
+
+    /**
+     * 鍙栨秷鍙戝竷娴佺▼瀹氫箟
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.INSERT)
+    @PutMapping("/unPublish/{id}")
+    @RepeatSubmit()
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> unPublish(@PathVariable Long id) {
+        return R.ok(defService.unPublish(id));
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼瀹氫箟
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @Transactional(rollbackFor = Exception.class)
+    public R<Void> remove(@PathVariable List<Long> ids) {
+        return toAjax(flwDefinitionService.removeDef(ids));
+    }
+
+    /**
+     * 澶嶅埗娴佺▼瀹氫箟
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.INSERT)
+    @PostMapping("/copy/{id}")
+    @RepeatSubmit()
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> copy(@PathVariable Long id) {
+        return R.ok(defService.copyDef(id));
+    }
+
+    /**
+     * 瀵煎叆娴佺▼瀹氫箟
+     *
+     * @param file     鏂囦欢
+     * @param category 鍒嗙被
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.IMPORT)
+    @PostMapping("/importDef")
+    @Transactional(rollbackFor = Exception.class)
+    public R<Boolean> importDef(MultipartFile file, String category) {
+        return R.ok(flwDefinitionService.importXml(file, category));
+    }
+
+    /**
+     * 瀵煎嚭娴佺▼瀹氫箟
+     *
+     * @param id       娴佺▼瀹氫箟id
+     * @param response 鍝嶅簲
+     * @throws IOException 寮傚父
+     */
+    @Log(title = "娴佺▼瀹氫箟", businessType = BusinessType.EXPORT)
+    @PostMapping("/exportDef/{id}")
+    public void exportDef(@PathVariable Long id, HttpServletResponse response) throws IOException {
+        flwDefinitionService.exportDef(id, response);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼瀹氫箟xml瀛楃涓�
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @GetMapping("/xmlString/{id}")
+    public R<String> xmlString(@PathVariable Long id) {
+        return R.ok("鎿嶄綔鎴愬姛", defService.xmlString(id));
+    }
+
+    /**
+     * 婵�娲�/鎸傝捣娴佺▼瀹氫箟
+     *
+     * @param id     娴佺▼瀹氫箟id
+     * @param active 婵�娲�/鎸傝捣
+     */
+    @RepeatSubmit()
+    @PutMapping("/active/{id}")
+    public R<Boolean> active(@PathVariable Long id, @RequestParam boolean active) {
+        return R.ok(active ? defService.active(id) : defService.unActive(id));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java
new file mode 100644
index 0000000..cb65f21
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwInstanceController.java
@@ -0,0 +1,155 @@
+package org.dromara.workflow.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.warm.flow.core.service.InsService;
+import org.dromara.workflow.domain.bo.FlowCancelBo;
+import org.dromara.workflow.domain.bo.FlowInstanceBo;
+import org.dromara.workflow.domain.bo.FlowInvalidBo;
+import org.dromara.workflow.domain.vo.FlowInstanceVo;
+import org.dromara.workflow.service.IFlwInstanceService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼瀹炰緥绠$悊 鎺у埗灞�
+ *
+ * @author may
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/workflow/instance")
+public class FlwInstanceController extends BaseController {
+
+    private final IFlwInstanceService flwInstanceService;
+    private final InsService insService;
+
+    /**
+     * 鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚嬪垪琛�
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     */
+    @GetMapping("/pageByRunning")
+    public TableDataInfo<FlowInstanceVo> selectRunningInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery) {
+        return flwInstanceService.selectRunningInstanceList(flowInstanceBo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥鍒楄〃
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     */
+    @GetMapping("/pageByFinish")
+    public TableDataInfo<FlowInstanceVo> selectFinishInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery) {
+        return flwInstanceService.selectFinishInstanceList(flowInstanceBo, pageQuery);
+    }
+
+    /**
+     * 鏍规嵁涓氬姟id鏌ヨ娴佺▼瀹炰緥璇︾粏淇℃伅
+     *
+     * @param businessId 涓氬姟id
+     */
+    @GetMapping("/getInfo/{businessId}")
+    public R<FlowInstanceVo> getInfo(@PathVariable Long businessId) {
+        return R.ok(flwInstanceService.queryByBusinessId(businessId));
+    }
+
+    /**
+     * 鎸夌収涓氬姟id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param businessIds 涓氬姟id
+     */
+    @DeleteMapping("/deleteByBusinessIds/{businessIds}")
+    public R<Void> deleteByBusinessIds(@PathVariable List<Long> businessIds) {
+        return toAjax(flwInstanceService.deleteByBusinessIds(businessIds));
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param instanceIds 瀹炰緥id
+     */
+    @DeleteMapping("/deleteByInstanceIds/{instanceIds}")
+    public R<Void> deleteByInstanceIds(@PathVariable List<Long> instanceIds) {
+        return toAjax(flwInstanceService.deleteByInstanceIds(instanceIds));
+    }
+
+    /**
+     * 鎾ら攢娴佺▼
+     *
+     * @param bo 鍙傛暟
+     */
+    @RepeatSubmit()
+    @PutMapping("/cancelProcessApply")
+    public R<Void> cancelProcessApply(@RequestBody FlowCancelBo bo) {
+        return toAjax(flwInstanceService.cancelProcessApply(bo));
+    }
+
+    /**
+     * 婵�娲�/鎸傝捣娴佺▼瀹炰緥
+     *
+     * @param id     娴佺▼瀹炰緥id
+     * @param active 婵�娲�/鎸傝捣
+     */
+    @RepeatSubmit()
+    @PutMapping("/active/{id}")
+    public R<Boolean> active(@PathVariable Long id, @RequestParam boolean active) {
+        return R.ok(active ? insService.active(id) : insService.unActive(id));
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐧婚檰浜哄彂璧风殑娴佺▼瀹炰緥
+     *
+     * @param flowInstanceBo 鍙傛暟
+     * @param pageQuery      鍒嗛〉
+     */
+    @GetMapping("/pageByCurrent")
+    public TableDataInfo<FlowInstanceVo> selectCurrentInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery) {
+        return flwInstanceService.selectCurrentInstanceList(flowInstanceBo, pageQuery);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍥撅紝娴佺▼璁板綍
+     *
+     * @param businessId 涓氬姟id
+     */
+    @GetMapping("/flowImage/{businessId}")
+    public R<Map<String, Object>> flowImage(@PathVariable String businessId) {
+        return R.ok(flwInstanceService.flowImage(businessId));
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍙橀噺
+     *
+     * @param instanceId 娴佺▼瀹炰緥id
+     */
+    @GetMapping("/instanceVariable/{instanceId}")
+    public R<Map<String, Object>> instanceVariable(@PathVariable String instanceId) {
+        return R.ok(flwInstanceService.instanceVariable(instanceId));
+    }
+
+    /**
+     * 浣滃簾娴佺▼
+     *
+     * @param bo 鍙傛暟
+     */
+    @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/invalid")
+    public R<Boolean> invalid(@Validated @RequestBody FlowInvalidBo bo) {
+        return R.ok(flwInstanceService.processInvalid(bo));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java
new file mode 100644
index 0000000..7736b7b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java
@@ -0,0 +1,199 @@
+package org.dromara.workflow.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.dto.UserDTO;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.warm.flow.core.entity.Node;
+import org.dromara.workflow.domain.bo.*;
+import org.dromara.workflow.domain.vo.FlowHisTaskVo;
+import org.dromara.workflow.domain.vo.FlowTaskVo;
+import org.dromara.workflow.service.IFlwTaskService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 浠诲姟绠$悊 鎺у埗灞�
+ *
+ * @author may
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/workflow/task")
+public class FlwTaskController extends BaseController {
+
+    private final IFlwTaskService flwTaskService;
+
+    /**
+     * 鍚姩浠诲姟
+     *
+     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/startWorkFlow")
+    public R<Map<String, Object>> startWorkFlow(@Validated(AddGroup.class) @RequestBody StartProcessBo startProcessBo) {
+        Map<String, Object> map = flwTaskService.startWorkFlow(startProcessBo);
+        return R.ok("鎻愪氦鎴愬姛", map);
+    }
+
+    /**
+     * 鍔炵悊浠诲姟
+     *
+     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/completeTask")
+    public R<Void> completeTask(@Validated(AddGroup.class) @RequestBody CompleteTaskBo completeTaskBo) {
+        return toAjax(flwTaskService.completeTask(completeTaskBo));
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @GetMapping("/pageByTaskWait")
+    public TableDataInfo<FlowTaskVo> pageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        return flwTaskService.pageByTaskWait(flowTaskBo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫凡鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+
+    @GetMapping("/pageByTaskFinish")
+    public TableDataInfo<FlowHisTaskVo> pageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        return flwTaskService.pageByTaskFinish(flowTaskBo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ寰呭姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @GetMapping("/pageByAllTaskWait")
+    public TableDataInfo<FlowTaskVo> pageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        return flwTaskService.pageByAllTaskWait(flowTaskBo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ宸插姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @GetMapping("/pageByAllTaskFinish")
+    public TableDataInfo<FlowHisTaskVo> pageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        return flwTaskService.pageByAllTaskFinish(flowTaskBo, pageQuery);
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @GetMapping("/pageByTaskCopy")
+    public TableDataInfo<FlowTaskVo> pageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        return flwTaskService.pageByTaskCopy(flowTaskBo, pageQuery);
+    }
+
+    /**
+     * 鏍规嵁taskId鏌ヨ浠h〃浠诲姟
+     *
+     * @param taskId 浠诲姟id
+     */
+    @GetMapping("/getTask/{taskId}")
+    public R<FlowTaskVo> getTask(@PathVariable Long taskId) {
+        return R.ok(flwTaskService.selectById(taskId));
+    }
+
+    /**
+     * 缁堟浠诲姟
+     *
+     * @param bo 鍙傛暟
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/terminationTask")
+    public R<Boolean> terminationTask(@RequestBody FlowTerminationBo bo) {
+        return R.ok(flwTaskService.terminationTask(bo));
+    }
+
+    /**
+     * 浠诲姟鎿嶄綔
+     *
+     * @param bo            鍙傛暟
+     * @param taskOperation 鎿嶄綔绫诲瀷锛屽娲� delegateTask銆佽浆鍔� transferTask銆佸姞绛� addSignature銆佸噺绛� reductionSignature
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.UPDATE)
+    @RepeatSubmit
+    @PostMapping("/taskOperation/{taskOperation}")
+    public R<Void> taskOperation(@Validated @RequestBody TaskOperationBo bo, @PathVariable String taskOperation) {
+        return toAjax(flwTaskService.taskOperation(bo, taskOperation));
+    }
+
+    /**
+     * 淇敼浠诲姟鍔炵悊浜�
+     *
+     * @param taskIdList 浠诲姟id
+     * @param userId     鍔炵悊浜篿d
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/updateAssignee/{userId}")
+    public R<Void> updateAssignee(@RequestBody List<Long> taskIdList, @PathVariable String userId) {
+        return toAjax(flwTaskService.updateAssignee(taskIdList, userId));
+    }
+
+    /**
+     * 椹冲洖瀹℃壒
+     *
+     * @param bo 鍙傛暟
+     */
+    @Log(title = "浠诲姟绠$悊", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/backProcess")
+    public R<Void> backProcess(@Validated({AddGroup.class}) @RequestBody BackProcessBo bo) {
+        return toAjax(flwTaskService.backProcess(bo));
+    }
+
+    /**
+     * 鑾峰彇鍙┏鍥炵殑鍓嶇疆鑺傜偣
+     *
+     * @param definitionId 娴佺▼瀹氫箟id
+     * @param nowNodeCode  褰撳墠鑺傜偣
+     */
+    @GetMapping("/getBackTaskNode/{definitionId}/{nowNodeCode}")
+    public R<List<Node>> getBackTaskNode(@PathVariable Long definitionId, @PathVariable String nowNodeCode) {
+        return R.ok(flwTaskService.getBackTaskNode(definitionId, nowNodeCode));
+    }
+
+    /**
+     * 鑾峰彇褰撳墠浠诲姟鐨勬墍鏈夊姙鐞嗕汉
+     *
+     * @param taskId 浠诲姟id
+     */
+    @GetMapping("/currentTaskAllUser/{taskId}")
+    public R<List<UserDTO>> currentTaskAllUser(@PathVariable Long taskId) {
+        return R.ok(flwTaskService.currentTaskAllUser(taskId));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfCategoryController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfCategoryController.java
deleted file mode 100644
index 8dced89..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfCategoryController.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.dromara.workflow.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.common.excel.utils.ExcelUtil;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.workflow.domain.bo.WfCategoryBo;
-import org.dromara.workflow.domain.vo.WfCategoryVo;
-import org.dromara.workflow.service.IWfCategoryService;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 娴佺▼鍒嗙被
- *
- * @author may
- * @date 2023-06-28
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/category")
-public class WfCategoryController extends BaseController {
-
-    private final IWfCategoryService wfCategoryService;
-
-    /**
-     * 鏌ヨ娴佺▼鍒嗙被鍒楄〃
-     */
-    @SaCheckPermission("workflow:category:list")
-    @GetMapping("/list")
-    public R<List<WfCategoryVo>> list(WfCategoryBo bo) {
-        List<WfCategoryVo> list = wfCategoryService.queryList(bo);
-        return R.ok(list);
-
-    }
-
-    /**
-     * 瀵煎嚭娴佺▼鍒嗙被鍒楄〃
-     */
-    @SaCheckPermission("workflow:category:export")
-    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(WfCategoryBo bo, HttpServletResponse response) {
-        List<WfCategoryVo> list = wfCategoryService.queryList(bo);
-        ExcelUtil.exportExcel(list, "娴佺▼鍒嗙被", WfCategoryVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇娴佺▼鍒嗙被璇︾粏淇℃伅
-     *
-     * @param id 涓婚敭
-     */
-    @SaCheckPermission("workflow:category:query")
-    @GetMapping("/{id}")
-    public R<WfCategoryVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                   @PathVariable Long id) {
-        return R.ok(wfCategoryService.queryById(id));
-    }
-
-    /**
-     * 鏂板娴佺▼鍒嗙被
-     */
-    @SaCheckPermission("workflow:category:add")
-    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody WfCategoryBo bo) {
-        return toAjax(wfCategoryService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼娴佺▼鍒嗙被
-     */
-    @SaCheckPermission("workflow:category:edit")
-    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfCategoryBo bo) {
-        return toAjax(wfCategoryService.updateByBo(bo));
-    }
-
-    /**
-     * 鍒犻櫎娴佺▼鍒嗙被
-     *
-     * @param ids 涓婚敭涓�
-     */
-    @SaCheckPermission("workflow:category:remove")
-    @Log(title = "娴佺▼鍒嗙被", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(wfCategoryService.deleteWithValidByIds(List.of(ids), true));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfDefinitionConfigController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfDefinitionConfigController.java
deleted file mode 100644
index 176aba2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfDefinitionConfigController.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.dromara.workflow.controller;
-
-import java.util.List;
-
-import lombok.RequiredArgsConstructor;
-import jakarta.validation.constraints.*;
-import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.validation.annotation.Validated;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.workflow.service.IWfDefinitionConfigService;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆
- *
- * @author may
- * @date 2024-03-18
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/definitionConfig")
-public class WfDefinitionConfigController extends BaseController {
-
-    private final IWfDefinitionConfigService wfDefinitionConfigService;
-
-
-    /**
-     * 鑾峰彇娴佺▼瀹氫箟閰嶇疆璇︾粏淇℃伅
-     *
-     * @param definitionId 涓婚敭
-     */
-    @GetMapping("/getByDefId/{definitionId}")
-    public R<WfDefinitionConfigVo> getByDefId(@NotBlank(message = "娴佺▼瀹氫箟ID涓嶈兘涓虹┖")
-                                              @PathVariable String definitionId) {
-        return R.ok(wfDefinitionConfigService.getByDefId(definitionId));
-    }
-
-    /**
-     * 鏂板娴佺▼瀹氫箟閰嶇疆
-     */
-    @Log(title = "娴佺▼瀹氫箟閰嶇疆", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping("/saveOrUpdate")
-    public R<Void> saveOrUpdate(@Validated(AddGroup.class) @RequestBody WfDefinitionConfigBo bo) {
-        return toAjax(wfDefinitionConfigService.saveOrUpdate(bo));
-    }
-
-    /**
-     * 鍒犻櫎娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param ids 涓婚敭涓�
-     */
-    @Log(title = "娴佺▼瀹氫箟閰嶇疆", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(wfDefinitionConfigService.deleteByIds(List.of(ids)));
-    }
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆鎺掗櫎褰撳墠鏌ヨ鐨勬祦绋嬪畾涔�
-     *
-     * @param tableName    琛ㄥ悕
-     * @param definitionId 娴佺▼瀹氫箟id
-     */
-    @GetMapping("/getByTableNameNotDefId/{tableName}/{definitionId}")
-    public R<List<WfDefinitionConfigVo>> getByTableNameNotDefId(@NotBlank(message = "琛ㄥ悕涓嶈兘涓虹┖") @PathVariable String tableName,
-                                                                @NotBlank(message = "娴佺▼瀹氫箟ID涓嶈兘涓虹┖") @PathVariable String definitionId) {
-        return R.ok(wfDefinitionConfigService.getByTableNameNotDefId(tableName, definitionId));
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfFormManageController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfFormManageController.java
deleted file mode 100644
index 198e233..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/WfFormManageController.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.dromara.workflow.controller;
-
-import java.util.List;
-
-import lombok.RequiredArgsConstructor;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.*;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.validation.annotation.Validated;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.log.annotation.Log;
-import org.dromara.common.web.core.BaseController;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.common.log.enums.BusinessType;
-import org.dromara.common.excel.utils.ExcelUtil;
-import org.dromara.workflow.domain.vo.WfFormManageVo;
-import org.dromara.workflow.domain.bo.WfFormManageBo;
-import org.dromara.workflow.service.IWfFormManageService;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-
-/**
- * 琛ㄥ崟绠$悊
- *
- * @author may
- * @date 2024-03-29
- */
-@Validated
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/workflow/formManage")
-public class WfFormManageController extends BaseController {
-
-    private final IWfFormManageService wfFormManageService;
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     */
-    @SaCheckPermission("workflow:formManage:list")
-    @GetMapping("/list")
-    public TableDataInfo<WfFormManageVo> list(WfFormManageBo bo, PageQuery pageQuery) {
-        return wfFormManageService.queryPageList(bo, pageQuery);
-    }
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     */
-    @SaCheckPermission("workflow:formManage:list")
-    @GetMapping("/list/selectList")
-    public R<List<WfFormManageVo>> selectList() {
-        return R.ok(wfFormManageService.selectList());
-    }
-
-    /**
-     * 瀵煎嚭琛ㄥ崟绠$悊鍒楄〃
-     */
-    @SaCheckPermission("workflow:formManage:export")
-    @Log(title = "琛ㄥ崟绠$悊", businessType = BusinessType.EXPORT)
-    @PostMapping("/export")
-    public void export(WfFormManageBo bo, HttpServletResponse response) {
-        List<WfFormManageVo> list = wfFormManageService.queryList(bo);
-        ExcelUtil.exportExcel(list, "琛ㄥ崟绠$悊", WfFormManageVo.class, response);
-    }
-
-    /**
-     * 鑾峰彇琛ㄥ崟绠$悊璇︾粏淇℃伅
-     *
-     * @param id 涓婚敭
-     */
-    @SaCheckPermission("workflow:formManage:query")
-    @GetMapping("/{id}")
-    public R<WfFormManageVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                     @PathVariable Long id) {
-        return R.ok(wfFormManageService.queryById(id));
-    }
-
-    /**
-     * 鏂板琛ㄥ崟绠$悊
-     */
-    @SaCheckPermission("workflow:formManage:add")
-    @Log(title = "琛ㄥ崟绠$悊", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
-    @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody WfFormManageBo bo) {
-        return toAjax(wfFormManageService.insertByBo(bo));
-    }
-
-    /**
-     * 淇敼琛ㄥ崟绠$悊
-     */
-    @SaCheckPermission("workflow:formManage:edit")
-    @Log(title = "琛ㄥ崟绠$悊", businessType = BusinessType.UPDATE)
-    @RepeatSubmit()
-    @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody WfFormManageBo bo) {
-        return toAjax(wfFormManageService.updateByBo(bo));
-    }
-
-    /**
-     * 鍒犻櫎琛ㄥ崟绠$悊
-     *
-     * @param ids 涓婚敭涓�
-     */
-    @SaCheckPermission("workflow:formManage:remove")
-    @Log(title = "琛ㄥ崟绠$悊", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{ids}")
-    public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                          @PathVariable Long[] ids) {
-        return toAjax(wfFormManageService.deleteByIds(List.of(ids)));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiProcinst.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiProcinst.java
deleted file mode 100644
index e87fb92..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiProcinst.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package org.dromara.workflow.domain;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 娴佺▼瀹炰緥瀵硅薄 act_hi_procinst
- *
- * @author may
- * @date 2023-07-22
- */
-@Data
-@TableName("act_hi_procinst")
-public class ActHiProcinst implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     *
-     */
-    @TableId(value = "ID_")
-    private String id;
-
-    /**
-     *
-     */
-    @TableField(value = "REV_")
-    private Long rev;
-
-    /**
-     *
-     */
-    @TableField(value = "PROC_INST_ID_")
-    private String procInstId;
-
-    /**
-     *
-     */
-    @TableField(value = "BUSINESS_KEY_")
-    private String businessKey;
-
-    /**
-     *
-     */
-    @TableField(value = "PROC_DEF_ID_")
-    private String procDefId;
-
-    /**
-     *
-     */
-    @TableField(value = "START_TIME_")
-    private Date startTime;
-
-    /**
-     *
-     */
-    @TableField(value = "END_TIME_")
-    private Date endTime;
-
-    /**
-     *
-     */
-    @TableField(value = "DURATION_")
-    private Long duration;
-
-    /**
-     *
-     */
-    @TableField(value = "START_USER_ID_")
-    private String startUserId;
-
-    /**
-     *
-     */
-    @TableField(value = "START_ACT_ID_")
-    private String startActId;
-
-    /**
-     *
-     */
-    @TableField(value = "END_ACT_ID_")
-    private String endActId;
-
-    /**
-     *
-     */
-    @TableField(value = "SUPER_PROCESS_INSTANCE_ID_")
-    private String superProcessInstanceId;
-
-    /**
-     *
-     */
-    @TableField(value = "DELETE_REASON_")
-    private String deleteReason;
-
-    /**
-     *
-     */
-    @TableField(value = "TENANT_ID_")
-    private String tenantId;
-
-    /**
-     *
-     */
-    @TableField(value = "NAME_")
-    private String name;
-
-    /**
-     *
-     */
-    @TableField(value = "CALLBACK_ID_")
-    private String callbackId;
-
-    /**
-     *
-     */
-    @TableField(value = "CALLBACK_TYPE_")
-    private String callbackType;
-
-    /**
-     *
-     */
-    @TableField(value = "REFERENCE_ID_")
-    private String referenceId;
-
-    /**
-     *
-     */
-    @TableField(value = "REFERENCE_TYPE_")
-    private String referenceType;
-
-    /**
-     *
-     */
-    @TableField(value = "PROPAGATED_STAGE_INST_ID_")
-    private String propagatedStageInstId;
-
-    /**
-     *
-     */
-    @TableField(value = "BUSINESS_STATUS_")
-    private String businessStatus;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiTaskinst.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiTaskinst.java
deleted file mode 100644
index abc17b5..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/ActHiTaskinst.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package org.dromara.workflow.domain;
-
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.Date;
-
-import java.io.Serial;
-
-/**
- * 娴佺▼鍘嗗彶浠诲姟瀵硅薄 act_hi_taskinst
- *
- * @author may
- * @date 2024-03-02
- */
-@Data
-@TableName("act_hi_taskinst")
-public class ActHiTaskinst implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     *
-     */
-    @TableId(value = "ID_")
-    private String id;
-
-    /**
-     * 鐗堟湰
-     */
-    @TableField(value = "REV_")
-    private Long rev;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    @TableField(value = "PROC_DEF_ID_")
-    private String procDefId;
-
-    /**
-     *
-     */
-    @TableField(value = "TASK_DEF_ID_")
-    private String taskDefId;
-
-    /**
-     * 浠诲姟鑺傜偣id
-     */
-    @TableField(value = "TASK_DEF_KEY_")
-    private String taskDefKey;
-
-    /**
-     * 娴佺▼瀹炰緥id
-     */
-    @TableField(value = "PROC_INST_ID_")
-    private String procInstId;
-
-    /**
-     * 娴佺▼鎵цid
-     */
-    @TableField(value = "EXECUTION_ID")
-    private String executionId;
-
-    /**
-     *
-     */
-    @TableField(value = "SCOPE_ID_")
-    private String scopeId;
-
-    /**
-     *
-     */
-    @TableField(value = "SUB_SCOPE_ID_")
-    private String subScopeId;
-
-    /**
-     * 鍏堢敤褰撳墠瀛楁鏍囪瘑鎶勯�佺被鍨�
-     */
-    @TableField(value = "SCOPE_TYPE_")
-    private String scopeType;
-
-    /**
-     *
-     */
-    @TableField(value = "SCOPE_DEFINITION_ID_")
-    private String scopeDefinitionId;
-
-    /**
-     *
-     */
-    @TableField(value = "PROPAGATED_STAGE_INST_ID_")
-    private String propagatedStageInstId;
-
-    /**
-     * 浠诲姟鍚嶇О
-     */
-    @TableField(value = "NAME_")
-    private String name;
-
-    /**
-     * 鐖剁骇id
-     */
-    @TableField(value = "PARENT_TASK_ID_")
-    private String parentTaskId;
-
-    /**
-     * 鎻忚堪
-     */
-    @TableField(value = "DESCRIPTION_")
-    private String description;
-
-    /**
-     * 鍔炵悊浜�
-     */
-    @TableField(value = "OWNER_")
-    private String owner;
-
-    /**
-     * 鍔炵悊浜�
-     */
-    @TableField(value = "ASSIGNEE_")
-    private String assignee;
-
-    /**
-     * 寮�濮嬩簨浠�
-     */
-    @TableField(value = "START_TIME_")
-    private Date startTime;
-
-    /**
-     * 璁ら鏃堕棿
-     */
-    @TableField(value = "CLAIM_TIME_")
-    private Date claimTime;
-
-    /**
-     * 缁撴潫鏃堕棿
-     */
-    @TableField(value = "END_TIME_")
-    private Date endTime;
-
-    /**
-     * 鎸佺画鏃堕棿
-     */
-    @TableField(value = "DURATION_")
-    private Long duration;
-
-    /**
-     * 鍒犻櫎鍘熷洜
-     */
-    @TableField(value = "DELETE_REASON_")
-    private String deleteReason;
-
-    /**
-     * 浼樺厛绾�
-     */
-    @TableField(value = "PRIORITY_")
-    private Long priority;
-
-    /**
-     * 鍒版湡鏃堕棿
-     */
-    @TableField(value = "DUE_DATE_")
-    private Date dueDate;
-
-    /**
-     *
-     */
-    @TableField(value = "FORM_KEY_")
-    private String formKey;
-
-    /**
-     * 鍒嗙被
-     */
-    @TableField(value = "CATEGORY_")
-    private String category;
-
-    /**
-     * 鏈�鍚庝慨鏀规椂闂�
-     */
-    @TableField(value = "LAST_UPDATED_TIME_")
-    private Date lastUpdatedTime;
-
-    /**
-     * 绉熸埛id
-     */
-    @TableField(value = "TENANT_ID_")
-    private String tenantId;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/FlowCategory.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/FlowCategory.java
new file mode 100644
index 0000000..2ec297c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/FlowCategory.java
@@ -0,0 +1,58 @@
+package org.dromara.workflow.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.tenant.core.TenantEntity;
+
+import java.io.Serial;
+
+/**
+ * 娴佺▼鍒嗙被瀵硅薄 wf_category
+ *
+ * @author may
+ * @date 2023-06-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("flow_category")
+public class FlowCategory extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼鍒嗙被ID
+     */
+    @TableId(value = "category_id")
+    private Long categoryId;
+
+    /**
+     * 鐖舵祦绋嬪垎绫籭d
+     */
+    private Long parentId;
+
+    /**
+     * 绁栫骇鍒楄〃
+     */
+    private String ancestors;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    private String categoryName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Long orderNum;
+
+    /**
+     * 鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�
+     */
+    @TableLogic
+    private String delFlag;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfCategory.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfCategory.java
deleted file mode 100644
index 94a7cf5..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfCategory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.dromara.workflow.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.dromara.common.tenant.core.TenantEntity;
-
-import java.io.Serial;
-
-/**
- * 娴佺▼鍒嗙被瀵硅薄 wf_category
- *
- * @author may
- * @date 2023-06-27
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("wf_category")
-public class WfCategory extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 鍒嗙被鍚嶇О
-     */
-    private String categoryName;
-
-    /**
-     * 鍒嗙被缂栫爜
-     */
-    private String categoryCode;
-
-    /**
-     * 鐖剁骇id
-     */
-    private Long parentId;
-
-    /**
-     * 鎺掑簭
-     */
-    private Long sortNum;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfDefinitionConfig.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfDefinitionConfig.java
deleted file mode 100644
index 11dcaa0..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfDefinitionConfig.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.dromara.workflow.domain;
-
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆瀵硅薄 wf_definition_config
- *
- * @author may
- * @date 2024-03-18
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("wf_definition_config")
-public class WfDefinitionConfig extends BaseEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 琛ㄥ悕
-     */
-    private String tableName;
-
-    /**
-     * 娴佺▼瀹氫箟ID
-     */
-    private String definitionId;
-
-    /**
-     * 娴佺▼KEY
-     */
-    private String processKey;
-
-    /**
-     * 娴佺▼鐗堟湰
-     */
-    private Integer version;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfFormManage.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfFormManage.java
deleted file mode 100644
index 47f0d7a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfFormManage.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.dromara.workflow.domain;
-
-import org.dromara.common.tenant.core.TenantEntity;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 琛ㄥ崟绠$悊瀵硅薄 wf_form_manage
- *
- * @author may
- * @date 2024-03-29
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("wf_form_manage")
-public class WfFormManage extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 琛ㄥ崟鍚嶇О
-     */
-    private String formName;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    private String formType;
-
-    /**
-     * 璺敱鍦板潃/琛ㄥ崟ID
-     */
-    private String router;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfNodeConfig.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfNodeConfig.java
deleted file mode 100644
index 999425f..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfNodeConfig.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.dromara.workflow.domain;
-
-import org.dromara.common.tenant.core.TenantEntity;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.io.Serial;
-
-/**
- * 鑺傜偣閰嶇疆瀵硅薄 wf_node_config
- *
- * @author may
- * @date 2024-03-30
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("wf_node_config")
-public class WfNodeConfig extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 琛ㄥ崟id
-     */
-    private Long formId;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    private String formType;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    private String nodeName;
-
-    /**
-     * 鑺傜偣id
-     */
-    private String nodeId;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    private String definitionId;
-
-    /**
-     * 鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級
-     */
-    private String applyUserTask;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfTaskBackNode.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfTaskBackNode.java
deleted file mode 100644
index 6f59727..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/WfTaskBackNode.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.dromara.workflow.domain;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.dromara.common.tenant.core.TenantEntity;
-
-import java.io.Serial;
-
-/**
- * 鑺傜偣椹冲洖璁板綍 wf_task_back_node
- *
- * @author may
- * @date 2024-03-13
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@TableName("wf_task_back_node")
-public class WfTaskBackNode extends TenantEntity {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 瀹炰緥id
-     */
-    private String instanceId;
-
-    /**
-     * 鑺傜偣id
-     */
-    private String nodeId;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    private String nodeName;
-
-    /**
-     * 鎺掑簭
-     */
-    private Integer orderNo;
-
-    /**
-     * 鑺傜偣绫诲瀷
-     */
-    private String taskType;
-
-    /**
-     * 鍔炵悊浜�
-     */
-    private String assignee;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/AddMultiBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/AddMultiBo.java
deleted file mode 100644
index 320ec64..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/AddMultiBo.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotEmpty;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 鍔犵鍙傛暟璇锋眰
- *
- * @author may
- */
-@Data
-public class AddMultiBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟ID
-     */
-    @NotBlank(message = "浠诲姟ID涓嶈兘涓虹┖", groups = AddGroup.class)
-    private String taskId;
-
-    /**
-     * 鍔犵浜哄憳id
-     */
-    @NotEmpty(message = "鍔犵浜哄憳涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<Long> assignees;
-
-    /**
-     * 鍔犵浜哄憳鍚嶇О
-     */
-    @NotEmpty(message = "鍔犵浜哄憳涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<String> assigneeNames;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java
index d0f4369..80b9691 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java
@@ -1,12 +1,16 @@
 package org.dromara.workflow.domain.bo;
 
 import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import org.dromara.common.core.validate.AddGroup;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 
 /**
@@ -23,8 +27,8 @@
     /**
      * 浠诲姟ID
      */
-    @NotBlank(message = "浠诲姟ID涓嶈兘涓虹┖", groups = AddGroup.class)
-    private String taskId;
+    @NotNull(message = "浠诲姟ID涓嶈兘涓虹┖", groups = AddGroup.class)
+    private Long taskId;
 
     /**
      * 娑堟伅绫诲瀷
@@ -35,10 +39,28 @@
      * 椹冲洖鐨勮妭鐐筰d(鐩墠鏈娇鐢紝鐩存帴椹冲洖鍒扮敵璇蜂汉)
      */
     @NotBlank(message = "椹冲洖鐨勮妭鐐逛笉鑳戒负绌�", groups = AddGroup.class)
-    private String targetActivityId;
+    private String nodeCode;
 
     /**
      * 鍔炵悊鎰忚
      */
     private String message;
+
+    /**
+     * 閫氱煡
+     */
+    private String notice;
+
+    /**
+     * 娴佺▼鍙橀噺
+     */
+    private Map<String, Object> variables;
+
+    public Map<String, Object> getVariables() {
+        if (variables == null) {
+            return new HashMap<>(16);
+        }
+        variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
+        return variables;
+    }
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java
index 0623905..9fdf484 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java
@@ -1,9 +1,8 @@
 package org.dromara.workflow.domain.bo;
 
-import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import org.dromara.common.core.validate.AddGroup;
-import org.dromara.workflow.domain.vo.WfCopy;
 
 import java.io.Serial;
 import java.io.Serializable;
@@ -26,8 +25,8 @@
     /**
      * 浠诲姟id
      */
-    @NotBlank(message = "浠诲姟id涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String taskId;
+    @NotNull(message = "浠诲姟id涓嶈兘涓虹┖", groups = {AddGroup.class})
+    private Long taskId;
 
     /**
      * 闄勪欢id
@@ -37,7 +36,7 @@
     /**
      * 鎶勯�佷汉鍛�
      */
-    private List<WfCopy> wfCopyList;
+    private List<FlowCopyBo> flowCopyList;
 
     /**
      * 娑堟伅绫诲瀷
@@ -50,10 +49,21 @@
     private String message;
 
     /**
+     * 娑堟伅閫氱煡
+     */
+    private String notice;
+
+    /**
      * 娴佺▼鍙橀噺
      */
     private Map<String, Object> variables;
 
+    /**
+     * 鎵╁睍鍙橀噺(姝ゅ涓洪�楀彿鍒嗛殧鐨刼ssId)
+     * @return
+     */
+    private String ext;
+
     public Map<String, Object> getVariables() {
         if (variables == null) {
             return new HashMap<>(16);
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DelegateBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DelegateBo.java
deleted file mode 100644
index a6846a6..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DelegateBo.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 濮旀淳浠诲姟璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class DelegateBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 濮旀淳浜篿d
-     */
-    @NotBlank(message = "濮旀淳浜篿d涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String userId;
-
-    /**
-     * 濮旀淳浜哄悕绉�
-     */
-    @NotBlank(message = "濮旀淳浜哄悕绉颁笉鑳戒负绌�", groups = {AddGroup.class})
-    private String nickName;
-
-    /**
-     * 浠诲姟id
-     */
-    @NotBlank(message = "浠诲姟id涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String taskId;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DeleteMultiBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DeleteMultiBo.java
deleted file mode 100644
index e533167..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/DeleteMultiBo.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotEmpty;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 鍑忕鍙傛暟璇锋眰
- *
- * @author may
- */
-@Data
-public class DeleteMultiBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟ID
-     */
-    @NotBlank(message = "浠诲姟ID涓嶈兘涓虹┖", groups = AddGroup.class)
-    private String taskId;
-
-    /**
-     * 鍑忕浜哄憳
-     */
-    @NotEmpty(message = "鍑忕浜哄憳涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<String> taskIds;
-
-    /**
-     * 鎵цid
-     */
-    @NotEmpty(message = "鎵цid涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<String> executionIds;
-
-    /**
-     * 浜哄憳id
-     */
-    @NotEmpty(message = "鍑忕浜哄憳id涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<Long> assigneeIds;
-
-    /**
-     * 浜哄憳鍚嶇О
-     */
-    @NotEmpty(message = "鍑忕浜哄憳涓嶈兘涓虹┖", groups = AddGroup.class)
-    private List<String> assigneeNames;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCancelBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCancelBo.java
new file mode 100644
index 0000000..31742ea
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCancelBo.java
@@ -0,0 +1,31 @@
+package org.dromara.workflow.domain.bo;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import org.dromara.common.core.validate.AddGroup;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鎾ら攢浠诲姟璇锋眰瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class FlowCancelBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 浠诲姟ID
+     */
+    @NotBlank(message = "涓氬姟ID涓嶈兘涓虹┖", groups = AddGroup.class)
+    private String businessId;
+
+    /**
+     * 鍔炵悊鎰忚
+     */
+    private String message;
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCategoryBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCategoryBo.java
new file mode 100644
index 0000000..fd626eb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCategoryBo.java
@@ -0,0 +1,47 @@
+package org.dromara.workflow.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.workflow.domain.FlowCategory;
+
+/**
+ * 娴佺▼鍒嗙被涓氬姟瀵硅薄 wf_category
+ *
+ * @author may
+ * @date 2023-06-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = FlowCategory.class, reverseConvertGenerate = false)
+public class FlowCategoryBo extends BaseEntity {
+
+    /**
+     * 娴佺▼鍒嗙被ID
+     */
+    @NotNull(message = "娴佺▼鍒嗙被ID涓嶈兘涓虹┖", groups = { EditGroup.class })
+    private Long categoryId;
+
+    /**
+     * 鐖舵祦绋嬪垎绫籭d
+     */
+    @NotNull(message = "鐖舵祦绋嬪垎绫籭d涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private Long parentId;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @NotBlank(message = "娴佺▼鍒嗙被鍚嶇О涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
+    private String categoryName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    private Long orderNum;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCopyBo.java
similarity index 76%
rename from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java
rename to ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCopyBo.java
index 88a5a21..a45e521 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCopy.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowCopyBo.java
@@ -1,9 +1,10 @@
-package org.dromara.workflow.domain.vo;
+package org.dromara.workflow.domain.bo;
 
 import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+
 
 /**
  * 鎶勯��
@@ -11,7 +12,7 @@
  * @author may
  */
 @Data
-public class WfCopy implements Serializable {
+public class FlowCopyBo implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInstanceBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInstanceBo.java
new file mode 100644
index 0000000..fb1fe61
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInstanceBo.java
@@ -0,0 +1,55 @@
+package org.dromara.workflow.domain.bo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 娴佺▼瀹炰緥璇锋眰瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class FlowInstanceBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 浠诲姟鍙戣捣浜�
+     */
+    private String startUserId;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessId;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 浠诲姟鍚嶇О
+     */
+    private String nodeName;
+
+    /**
+     * 鐢宠浜篒ds
+     */
+    private List<Long> createByIds;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInvalidBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInvalidBo.java
new file mode 100644
index 0000000..297bd00
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowInvalidBo.java
@@ -0,0 +1,31 @@
+package org.dromara.workflow.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.dromara.common.core.validate.AddGroup;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 浣滃簾璇锋眰瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class FlowInvalidBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼瀹炰緥id
+     */
+    @NotNull(message = "娴佺▼瀹炰緥id涓虹┖", groups = AddGroup.class)
+    private Long id;
+
+    /**
+     * 瀹℃壒鎰忚
+     */
+    private String comment;
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTaskBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTaskBo.java
new file mode 100644
index 0000000..64dd082
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTaskBo.java
@@ -0,0 +1,55 @@
+package org.dromara.workflow.domain.bo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 浠诲姟璇锋眰瀵硅薄
+ *
+ * @author may
+ */
+@Data
+public class FlowTaskBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 浠诲姟鍚嶇О
+     */
+    private String nodeName;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 娴佺▼瀹炰緥id
+     */
+    private Long instanceId;
+
+    /**
+     * 鏉冮檺鍒楄〃
+     */
+    private List<String> permissionList;
+
+    /**
+     * 鐢宠浜篒ds
+     */
+    private List<Long> createByIds;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TerminationBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTerminationBo.java
similarity index 66%
rename from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TerminationBo.java
rename to ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTerminationBo.java
index 8f2206e..897fc21 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TerminationBo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTerminationBo.java
@@ -1,6 +1,6 @@
 package org.dromara.workflow.domain.bo;
 
-import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import org.dromara.common.core.validate.AddGroup;
 
@@ -13,7 +13,7 @@
  * @author may
  */
 @Data
-public class TerminationBo implements Serializable {
+public class FlowTerminationBo implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
@@ -21,8 +21,8 @@
     /**
      * 浠诲姟id
      */
-    @NotBlank(message = "浠诲姟id涓虹┖", groups = AddGroup.class)
-    private String taskId;
+    @NotNull(message = "浠诲姟id涓虹┖", groups = AddGroup.class)
+    private Long taskId;
 
     /**
      * 瀹℃壒鎰忚
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ModelBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ModelBo.java
deleted file mode 100644
index efe9acd..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ModelBo.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.Pattern;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.workflow.common.constant.FlowConstant;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 妯″瀷璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class ModelBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 妯″瀷id
-     */
-    @NotBlank(message = "妯″瀷ID涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private String id;
-
-    /**
-     * 妯″瀷鍚嶇О
-     */
-    @NotBlank(message = "妯″瀷鍚嶇О涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String name;
-
-    /**
-     * 妯″瀷鏍囪瘑key
-     */
-    @NotBlank(message = "妯″瀷鏍囪瘑key涓嶈兘涓虹┖", groups = {AddGroup.class})
-    @Pattern(regexp = FlowConstant.MODEL_KEY_PATTERN, message = "妯″瀷鏍囪瘑key鍙兘瀛楃鎴栬�呬笅鍒掔嚎寮�澶�", groups = {AddGroup.class})
-    private String key;
-
-    /**
-     * 妯″瀷鍒嗙被
-     */
-    @NotBlank(message = "妯″瀷鍒嗙被涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String categoryCode;
-
-    /**
-     * 妯″瀷XML
-     */
-    @NotBlank(message = "妯″瀷XML涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String xml;
-
-    /**
-     * 妯″瀷SVG鍥剧墖
-     */
-    @NotBlank(message = "妯″瀷SVG涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private String svg;
-
-    /**
-     * 澶囨敞
-     */
-    private String description;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessDefinitionBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessDefinitionBo.java
deleted file mode 100644
index 2025932..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessDefinitionBo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 娴佺▼瀹氫箟璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class ProcessDefinitionBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇Оkey
-     */
-    private String key;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 妯″瀷鍒嗙被
-     */
-    private String categoryCode;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInstanceBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInstanceBo.java
deleted file mode 100644
index 2833b3e..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInstanceBo.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 娴佺▼瀹炰緥璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class ProcessInstanceBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 娴佺▼鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 娴佺▼key
-     */
-    private String key;
-
-    /**
-     * 浠诲姟鍙戣捣浜�
-     */
-    private String startUserId;
-
-    /**
-     * 涓氬姟id
-     */
-    private String businessKey;
-
-    /**
-     * 妯″瀷鍒嗙被
-     */
-    private String categoryCode;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInvalidBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInvalidBo.java
deleted file mode 100644
index 41e51c2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInvalidBo.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 娴佺▼瀹炰緥浣滃簾璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class ProcessInvalidBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓氬姟id
-     */
-    @NotBlank(message = "涓氬姟id涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String businessKey;
-
-    /**
-     * 浣滃簾鍘熷洜
-     */
-    private String deleteReason;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/StartProcessBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/StartProcessBo.java
index 7af7935..ea21a81 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/StartProcessBo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/StartProcessBo.java
@@ -26,13 +26,13 @@
      * 涓氬姟鍞竴鍊糹d
      */
     @NotBlank(message = "涓氬姟ID涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String businessKey;
+    private String businessId;
 
     /**
-     * 琛ㄥ悕
+     * 娴佺▼瀹氫箟缂栫爜
      */
-    @NotBlank(message = "琛ㄥ悕涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String tableName;
+    @NotBlank(message = "娴佺▼瀹氫箟缂栫爜涓嶈兘涓虹┖", groups = {AddGroup.class})
+    private String flowCode;
 
     /**
      * 娴佺▼鍙橀噺锛屽墠绔細鎻愪氦涓�涓厓绱爗'entity': {涓氬姟璇︽儏鏁版嵁瀵硅薄}}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/SysUserMultiBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/SysUserMultiBo.java
deleted file mode 100644
index e4d99e4..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/SysUserMultiBo.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 鐢ㄦ埛鍔犵鏌ヨ
- *
- * @author may
- */
-@Data
-public class SysUserMultiBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浜哄憳鍚嶇О
-     */
-    private String userName;
-
-    /**
-     * 浜哄憳鍚嶇О
-     */
-    private String nickName;
-
-    /**
-     * 閮ㄩ棬id
-     */
-    private String deptId;
-
-    /**
-     * 浠诲姟id
-     */
-    private String taskId;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java
deleted file mode 100644
index 3037479..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskBo.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 浠诲姟璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class TaskBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇О
-     */
-    private String processDefinitionName;
-
-    /**
-     * 娴佺▼瀹氫箟key
-     */
-    private String processDefinitionKey;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskOperationBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskOperationBo.java
new file mode 100644
index 0000000..4348e31
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskOperationBo.java
@@ -0,0 +1,48 @@
+package org.dromara.workflow.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * 浠诲姟鎿嶄綔涓氬姟瀵硅薄锛岀敤浜庢弿杩颁换鍔″娲俱�佽浆鍔炪�佸姞绛剧瓑鎿嶄綔鐨勫繀瑕佸弬鏁�
+ * 鍖呭惈浜嗙敤鎴稩D銆佷换鍔D銆佷换鍔$浉鍏崇殑娑堟伅銆佷互鍙婂姞绛�/鍑忕鐨勭敤鎴稩D
+ *
+ * @author AprilWind
+ */
+@Data
+public class TaskOperationBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 濮旀淳/杞姙浜虹殑鐢ㄦ埛ID锛堝繀濉紝鍑嗗濮旀淳/杞姙浜烘搷浣滐級
+     */
+    @NotNull(message = "濮旀淳/杞姙浜篿d涓嶈兘涓虹┖", groups = {AddGroup.class})
+    private String userId;
+
+    /**
+     * 鍔犵/鍑忕浜虹殑鐢ㄦ埛ID鍒楄〃锛堝繀濉紝閽堝鍔犵/鍑忕鎿嶄綔锛�
+     */
+    @NotNull(message = "鍔犵/鍑忕id涓嶈兘涓虹┖", groups = {EditGroup.class})
+    private List<String> userIds;
+
+    /**
+     * 浠诲姟ID锛堝繀濉級
+     */
+    @NotNull(message = "浠诲姟id涓嶈兘涓虹┖")
+    private Long taskId;
+
+    /**
+     * 鎰忚鎴栧娉ㄤ俊鎭紙鍙�夛級
+     */
+    private String message;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskUrgingBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskUrgingBo.java
deleted file mode 100644
index 20856ef..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TaskUrgingBo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 浠诲姟鍌姙
- *
- * @author may
- */
-@Data
-public class TaskUrgingBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 娴佺▼瀹炰緥id
-     */
-    private String processInstanceId;
-
-    /**
-     * 娑堟伅绫诲瀷
-     */
-    private List<String> messageType;
-
-    /**
-     * 鍌姙鍐呭锛堜负绌洪粯璁ょ郴缁熷唴缃俊鎭級
-     */
-    private String message;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java
index 877e981..a1a4b59 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java
@@ -53,7 +53,6 @@
     /**
      * 璇峰亣澶╂暟
      */
-    @NotNull(message = "璇峰亣澶╂暟涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
     private Integer leaveDays;
 
     /**
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TransmitBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TransmitBo.java
deleted file mode 100644
index 3eb6609..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TransmitBo.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 缁堣浆鍔炲姟璇锋眰瀵硅薄
- *
- * @author may
- */
-@Data
-public class TransmitBo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟id
-     */
-    @NotBlank(message = "浠诲姟id涓虹┖", groups = AddGroup.class)
-    private String taskId;
-
-    /**
-     * 杞姙浜篿d
-     */
-    @NotBlank(message = "杞姙浜轰笉鑳戒负绌�", groups = AddGroup.class)
-    private String userId;
-
-    /**
-     * 瀹℃壒鎰忚
-     */
-    private String comment;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfCategoryBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfCategoryBo.java
deleted file mode 100644
index 69608fd..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfCategoryBo.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.workflow.domain.WfCategory;
-
-/**
- * 娴佺▼鍒嗙被涓氬姟瀵硅薄 wf_category
- *
- * @author may
- * @date 2023-06-27
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = WfCategory.class, reverseConvertGenerate = false)
-public class WfCategoryBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long id;
-
-    /**
-     * 鍒嗙被鍚嶇О
-     */
-    @NotBlank(message = "鍒嗙被鍚嶇О涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String categoryName;
-
-    /**
-     * 鍒嗙被缂栫爜
-     */
-    @NotBlank(message = "鍒嗙被缂栫爜涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String categoryCode;
-
-    /**
-     * 鐖剁骇id
-     */
-    @NotNull(message = "鐖剁骇id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private Long parentId;
-
-    /**
-     * 鎺掑簭
-     */
-    private Long sortNum;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfDefinitionConfigBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfDefinitionConfigBo.java
deleted file mode 100644
index fac1770..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfDefinitionConfigBo.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import org.dromara.workflow.domain.WfDefinitionConfig;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆涓氬姟瀵硅薄 wf_form_definition
- *
- * @author may
- * @date 2024-03-18
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = WfDefinitionConfig.class, reverseConvertGenerate = false)
-public class WfDefinitionConfigBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long id;
-
-    /**
-     * 琛ㄥ悕
-     */
-    @NotBlank(message = "琛ㄥ悕涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String tableName;
-
-    /**
-     * 娴佺▼瀹氫箟ID
-     */
-    @NotBlank(message = "娴佺▼瀹氫箟ID涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String definitionId;
-
-    /**
-     * 娴佺▼KEY
-     */
-    @NotBlank(message = "娴佺▼KEY涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String processKey;
-
-    /**
-     * 娴佺▼鐗堟湰
-     */
-    @NotNull(message = "娴佺▼鐗堟湰涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private Integer version;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfFormManageBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfFormManageBo.java
deleted file mode 100644
index 8afc286..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfFormManageBo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import org.dromara.workflow.domain.WfFormManage;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-/**
- * 琛ㄥ崟绠$悊涓氬姟瀵硅薄 wf_form_manage
- *
- * @author may
- * @date 2024-03-29
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = WfFormManage.class, reverseConvertGenerate = false)
-public class WfFormManageBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = { EditGroup.class })
-    private Long id;
-
-    /**
-     * 琛ㄥ崟鍚嶇О
-     */
-    @NotBlank(message = "琛ㄥ崟鍚嶇О涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String formName;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    @NotBlank(message = "琛ㄥ崟绫诲瀷涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String formType;
-    /**
-     * 璺敱鍦板潃/琛ㄥ崟ID
-     */
-    @NotBlank(message = "璺敱鍦板潃/琛ㄥ崟ID涓嶈兘涓虹┖", groups = { AddGroup.class, EditGroup.class })
-    private String router;
-
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfNodeConfigBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfNodeConfigBo.java
deleted file mode 100644
index de518d3..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/WfNodeConfigBo.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.dromara.workflow.domain.bo;
-
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
-
-/**
- * 鑺傜偣閰嶇疆涓氬姟瀵硅薄 wf_node_config
- *
- * @author may
- * @date 2024-03-30
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = WfNodeConfig.class, reverseConvertGenerate = false)
-public class WfNodeConfigBo extends BaseEntity {
-
-    /**
-     * 涓婚敭
-     */
-    @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {EditGroup.class})
-    private Long id;
-
-    /**
-     * 琛ㄥ崟id
-     */
-    private Long formId;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    private String formType;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    @NotBlank(message = "鑺傜偣鍚嶇О涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String nodeName;
-
-    /**
-     * 鑺傜偣id
-     */
-    @NotBlank(message = "鑺傜偣id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String nodeId;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    @NotBlank(message = "娴佺▼瀹氫箟id涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String definitionId;
-
-    /**
-     * 鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級
-     */
-    @NotBlank(message = "鏄惁涓虹敵璇蜂汉鑺傜偣涓嶈兘涓虹┖", groups = {AddGroup.class, EditGroup.class})
-    private String applyUserTask;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java
deleted file mode 100644
index e4c1142..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-import org.dromara.common.translation.annotation.Translation;
-import org.dromara.common.translation.constant.TransConstant;
-import org.flowable.engine.task.Attachment;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-
-/**
- * 娴佺▼瀹℃壒璁板綍瑙嗗浘
- *
- * @author may
- */
-@Data
-public class ActHistoryInfoVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-    /**
-     * 浠诲姟id
-     */
-    private String id;
-    /**
-     * 鑺傜偣id
-     */
-    private String taskDefinitionKey;
-    /**
-     * 浠诲姟鍚嶇О
-     */
-    private String name;
-    /**
-     * 娴佺▼瀹炰緥id
-     */
-    private String processInstanceId;
-    /**
-     * 鐗堟湰
-     */
-    private Integer version;
-    /**
-     * 寮�濮嬫椂闂�
-     */
-    private Date startTime;
-    /**
-     * 缁撴潫鏃堕棿
-     */
-    private Date endTime;
-    /**
-     * 杩愯鏃堕暱
-     */
-    private String runDuration;
-    /**
-     * 鐘舵��
-     */
-    private String status;
-    /**
-     * 鐘舵��
-     */
-    private String statusName;
-    /**
-     * 鍔炵悊浜篿d
-     */
-    private String assignee;
-
-    /**
-     * 鍔炵悊浜哄悕绉�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "assignee")
-    private String nickName;
-
-    /**
-     * 鍔炵悊浜篿d
-     */
-    private String owner;
-
-    /**
-     * 瀹℃壒淇℃伅id
-     */
-    private String commentId;
-
-    /**
-     * 瀹℃壒淇℃伅
-     */
-    private String comment;
-
-    /**
-     * 瀹℃壒闄勪欢
-     */
-    private List<Attachment> attachmentList;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowCategoryVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowCategoryVo.java
new file mode 100644
index 0000000..2c72143
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowCategoryVo.java
@@ -0,0 +1,69 @@
+package org.dromara.workflow.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.workflow.domain.FlowCategory;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 娴佺▼鍒嗙被瑙嗗浘瀵硅薄 wf_category
+ *
+ * @author may
+ * @date 2023-06-27
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = FlowCategory.class)
+public class FlowCategoryVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼鍒嗙被ID
+     */
+    @ExcelProperty(value = "娴佺▼鍒嗙被ID")
+    private Long categoryId;
+
+    /**
+     * 鐖剁骇id
+     */
+    private Long parentId;
+
+    /**
+     * 鐖剁被鍒悕绉�
+     */
+    private String parentName;
+
+    /**
+     * 绁栫骇鍒楄〃
+     */
+    private String ancestors;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @ExcelProperty(value = "娴佺▼鍒嗙被鍚嶇О")
+    private String categoryName;
+
+    /**
+     * 鏄剧ず椤哄簭
+     */
+    @ExcelProperty(value = "鏄剧ず椤哄簭")
+    private Long orderNum;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @ExcelProperty(value = "鍒涘缓鏃堕棿")
+    private Date createTime;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowDefinitionVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowDefinitionVo.java
new file mode 100644
index 0000000..aef7573
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowDefinitionVo.java
@@ -0,0 +1,104 @@
+package org.dromara.workflow.domain.vo;
+
+import lombok.Data;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.workflow.common.constant.FlowConstant;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 娴佺▼瀹氫箟瑙嗗浘
+ *
+ * @author may
+ */
+@Data
+public class FlowDefinitionVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    private Date updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鍒犻櫎鏍囪
+     */
+    private String delFlag;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Translation(type = FlowConstant.CATEGORY_ID_TO_NAME, mapper = "category")
+    private String categoryName;
+
+    /**
+     * 娴佺▼鐗堟湰
+     */
+    private String version;
+
+    /**
+     * 鏄惁鍙戝竷锛�0鏈彂甯� 1宸插彂甯� 9澶辨晥锛�
+     */
+    private Integer isPublish;
+
+    /**
+     * 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+     */
+    private String formCustom;
+
+    /**
+     * 瀹℃壒琛ㄥ崟璺緞
+     */
+    private String formPath;
+
+    /**
+     * 娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級
+     */
+    private Integer activityStatus;
+
+    /**
+     * 鐩戝惉鍣ㄧ被鍨�
+     */
+    private String listenerType;
+
+    /**
+     * 鐩戝惉鍣ㄨ矾寰�
+     */
+    private String listenerPath;
+
+    /**
+     * 鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤
+     */
+    private String ext;
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java
new file mode 100644
index 0000000..8776a76
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java
@@ -0,0 +1,244 @@
+package org.dromara.workflow.domain.vo;
+
+import lombok.Data;
+import org.dromara.common.core.utils.DateUtils;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.warm.flow.core.enums.CooperateType;
+import org.dromara.workflow.common.constant.FlowConstant;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鍘嗗彶浠诲姟瑙嗗浘
+ *
+ * @author may
+ */
+@Data
+public class FlowHisTaskVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    private Date updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鍒犻櫎鏍囪
+     */
+    private String delFlag;
+
+    /**
+     * 瀵瑰簲flow_definition琛ㄧ殑id
+     */
+    private Long definitionId;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 娴佺▼瀹炰緥琛╥d
+     */
+    private Long instanceId;
+
+    /**
+     * 浠诲姟琛╥d
+     */
+    private Long taskId;
+
+    /**
+     * 鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)
+     */
+    private Integer cooperateType;
+
+    /**
+     * 鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)
+     */
+    private String cooperateTypeName;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessId;
+
+    /**
+     * 寮�濮嬭妭鐐圭紪鐮�
+     */
+    private String nodeCode;
+
+    /**
+     * 寮�濮嬭妭鐐瑰悕绉�
+     */
+    private String nodeName;
+
+    /**
+     * 寮�濮嬭妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+     */
+    private Integer nodeType;
+
+    /**
+     * 鐩爣鑺傜偣缂栫爜
+     */
+    private String targetNodeCode;
+
+    /**
+     * 缁撴潫鑺傜偣鍚嶇О
+     */
+    private String targetNodeName;
+
+    /**
+     * 瀹℃壒鑰�
+     */
+    private String approver;
+
+    /**
+     * 瀹℃壒鑰�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "approver")
+    private String approveName;
+
+    /**
+     * 鍗忎綔浜�(鍙湁杞姙銆佷細绛俱�佺エ绛俱�佸娲�)
+     */
+    private String collaborator;
+
+    /**
+     * 鏉冮檺鏍囪瘑 permissionFlag鐨刲ist褰㈠紡
+     */
+    private List<String> permissionList;
+
+    /**
+     * 璺宠浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級
+     */
+    private String skipType;
+
+    /**
+     * 娴佺▼鐘舵��
+     */
+    private String flowStatus;
+
+    /**
+     * 浠诲姟鐘舵��
+     */
+    private String flowTaskStatus;
+
+    /**
+     * 娴佺▼鐘舵��
+     */
+    private String flowStatusName;
+
+    /**
+     * 瀹℃壒鎰忚
+     */
+    private String message;
+
+    /**
+     * 涓氬姟璇︽儏 瀛樹笟鍔$被鐨刯son
+     */
+    private String ext;
+
+    /**
+     * 鍒涘缓鑰�
+     */
+    private String createBy;
+
+    /**
+     * 鐢宠浜�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private String createByName;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Translation(type = FlowConstant.CATEGORY_ID_TO_NAME, mapper = "category")
+    private String categoryName;
+
+    /**
+     * 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+     */
+    private String formCustom;
+
+    /**
+     * 瀹℃壒琛ㄥ崟璺緞
+     */
+    private String formPath;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 娴佺▼鐗堟湰鍙�
+     */
+    private String version;
+
+    /**
+     * 杩愯鏃堕暱
+     */
+    private String runDuration;
+
+    /**
+     * 璁剧疆鍒涘缓鏃堕棿骞惰绠椾换鍔¤繍琛屾椂闀�
+     *
+     * @param createTime 鍒涘缓鏃堕棿
+     */
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+        updateRunDuration();
+    }
+
+    /**
+     * 璁剧疆鏇存柊鏃堕棿骞惰绠椾换鍔¤繍琛屾椂闀�
+     *
+     * @param updateTime 鏇存柊鏃堕棿
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+        updateRunDuration();
+    }
+
+    /**
+     * 鏇存柊杩愯鏃堕暱
+     */
+    private void updateRunDuration() {
+        // 濡傛灉鍒涘缓鏃堕棿鍜屾洿鏂版椂闂村潎涓嶄负绌猴紝璁$畻瀹冧滑涔嬮棿鐨勬椂闀�
+        if (this.updateTime != null && this.createTime != null) {
+            this.runDuration = DateUtils.getTimeDifference(this.updateTime, this.createTime);
+        }
+    }
+
+    /**
+     * 璁剧疆鍗忎綔鏂瑰紡锛屽苟閫氳繃鍗忎綔鏂瑰紡鑾峰彇鍚嶇О
+     */
+    public void setCooperateType(Integer cooperateType) {
+        this.cooperateType = cooperateType;
+        this.cooperateTypeName = CooperateType.getValueByKey(cooperateType);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowInstanceVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowInstanceVo.java
new file mode 100644
index 0000000..75543f4
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowInstanceVo.java
@@ -0,0 +1,137 @@
+package org.dromara.workflow.domain.vo;
+
+import lombok.Data;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.workflow.common.constant.FlowConstant;
+
+import java.util.Date;
+
+/**
+ * 娴佺▼瀹炰緥瑙嗗浘
+ *
+ * @author may
+ */
+@Data
+public class FlowInstanceVo {
+
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    private Date updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鍒犻櫎鏍囪
+     */
+    private String delFlag;
+
+    /**
+     * 瀵瑰簲flow_definition琛ㄧ殑id
+     */
+    private Long definitionId;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessId;
+
+    /**
+     * 鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+     */
+    private Integer nodeType;
+
+    /**
+     * 娴佺▼鑺傜偣缂栫爜   姣忎釜娴佺▼鐨刵odeCode鏄敮涓�鐨�,鍗砫efinitionId+nodeCode鍞竴,鍦ㄦ暟鎹簱灞傞潰鍋氫簡鎺у埗
+     */
+    private String nodeCode;
+
+    /**
+     * 娴佺▼鑺傜偣鍚嶇О
+     */
+    private String nodeName;
+
+    /**
+     * 娴佺▼鍙橀噺
+     */
+    private String variable;
+
+    /**
+     * 娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 3鑷姩閫氳繃 8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�
+     */
+    private String flowStatus;
+
+    /**
+     * 娴佺▼鐘舵��
+     */
+    private String flowStatusName;
+
+    /**
+     * 娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級
+     */
+    private Integer activityStatus;
+
+    /**
+     * 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+     */
+    private String formCustom;
+
+    /**
+     * 瀹℃壒琛ㄥ崟璺緞
+     */
+    private String formPath;
+
+    /**
+     * 鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤
+     */
+    private String ext;
+
+    /**
+     * 娴佺▼瀹氫箟鐗堟湰
+     */
+    private String version;
+
+    /**
+     * 鍒涘缓鑰�
+     */
+    private String createBy;
+
+    /**
+     * 鐢宠浜�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private String createByName;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Translation(type = FlowConstant.CATEGORY_ID_TO_NAME, mapper = "category")
+    private String categoryName;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java
new file mode 100644
index 0000000..3fb08d9
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowTaskVo.java
@@ -0,0 +1,176 @@
+package org.dromara.workflow.domain.vo;
+
+import lombok.Data;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.warm.flow.core.entity.User;
+import org.dromara.workflow.common.constant.FlowConstant;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 浠诲姟瑙嗗浘
+ *
+ * @author may
+ */
+@Data
+public class FlowTaskVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     */
+    private Date updateTime;
+
+    /**
+     * 绉熸埛ID
+     */
+    private String tenantId;
+
+    /**
+     * 鍒犻櫎鏍囪
+     */
+    private String delFlag;
+
+    /**
+     * 瀵瑰簲flow_definition琛ㄧ殑id
+     */
+    private Long definitionId;
+
+    /**
+     * 娴佺▼瀹炰緥琛╥d
+     */
+    private Long instanceId;
+
+    /**
+     * 娴佺▼瀹氫箟鍚嶇О
+     */
+    private String flowName;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessId;
+
+    /**
+     * 鑺傜偣缂栫爜
+     */
+    private String nodeCode;
+
+    /**
+     * 鑺傜偣鍚嶇О
+     */
+    private String nodeName;
+
+    /**
+     * 鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+     */
+    private Integer nodeType;
+
+    /**
+     * 鏉冮檺鏍囪瘑 permissionFlag鐨刲ist褰㈠紡
+     */
+    private List<String> permissionList;
+
+    /**
+     * 娴佺▼鐢ㄦ埛鍒楄〃
+     */
+    private List<User> userList;
+
+    /**
+     * 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+     */
+    private String formCustom;
+
+    /**
+     * 瀹℃壒琛ㄥ崟
+     */
+    private String formPath;
+
+    /**
+     * 娴佺▼瀹氫箟缂栫爜
+     */
+    private String flowCode;
+
+    /**
+     * 娴佺▼鐗堟湰鍙�
+     */
+    private String version;
+
+    /**
+     * 娴佺▼鐘舵��
+     */
+    private String flowStatus;
+
+    /**
+     * 娴佺▼鍒嗙被id
+     */
+    private String category;
+
+    /**
+     * 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Translation(type = FlowConstant.CATEGORY_ID_TO_NAME, mapper = "category")
+    private String categoryName;
+
+    /**
+     * 娴佺▼鐘舵��
+     */
+    @Translation(type = TransConstant.DICT_TYPE_TO_LABEL, mapper = "flowStatus", other = "wf_business_status")
+    private String flowStatusName;
+
+    /**
+     * 鍔炵悊浜虹被鍨�
+     */
+    private String type;
+
+    /**
+     * 鍔炵悊浜篿ds
+     */
+    private String assigneeIds;
+
+    /**
+     * 鍔炵悊浜哄悕绉�
+     */
+    private String assigneeNames;
+
+    /**
+     * 鎶勯�佷汉id
+     */
+    private String processedBy;
+
+    /**
+     * 鎶勯�佷汉鍚嶇О
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "processedBy")
+    private String processedByName;
+
+    /**
+     * 娴佺▼绛剧讲姣斾緥鍊� 澶т簬0涓虹エ绛撅紝浼氱
+     */
+    private BigDecimal nodeRatio;
+
+    /**
+     * 鐢宠浜篿d
+     */
+    private String createBy;
+
+    /**
+     * 鐢宠浜哄悕绉�
+     */
+    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "createBy")
+    private String createByName;
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/VariableVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowVariableVo.java
similarity index 86%
rename from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/VariableVo.java
rename to ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowVariableVo.java
index 6a26c82..b4de76e 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/VariableVo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowVariableVo.java
@@ -11,7 +11,7 @@
  * @author may
  */
 @Data
-public class VariableVo implements Serializable {
+public class FlowVariableVo implements Serializable {
 
     @Serial
     private static final long serialVersionUID = 1L;
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/GraphicInfoVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/GraphicInfoVo.java
deleted file mode 100644
index 7636131..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/GraphicInfoVo.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 鑺傜偣鍥惧舰淇℃伅
- *
- * @author may
- */
-@Data
-public class GraphicInfoVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-    /**
-     * x鍧愭爣
-     */
-    private double x;
-
-    /**
-     * y鍧愭爣
-     */
-    private double y;
-
-    /**
-     * 鑺傜偣楂樺害
-     */
-    private double height;
-
-    /**
-     * 鑺傜偣瀹藉害
-     */
-    private double width;
-
-    /**
-     * 鑺傜偣id
-     */
-    private String nodeId;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    private String nodeName;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ModelVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ModelVo.java
deleted file mode 100644
index b2ce811..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ModelVo.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 妯″瀷瑙嗗浘瀵硅薄
- *
- * @author may
- */
-@Data
-public class ModelVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 妯″瀷id
-     */
-    private String id;
-
-    /**
-     * 妯″瀷鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 妯″瀷鏍囪瘑key
-     */
-    private String key;
-
-    /**
-     * 妯″瀷鍒嗙被
-     */
-    private String categoryCode;
-
-    /**
-     * 妯″瀷XML
-     */
-    private String xml;
-
-    /**
-     * 澶囨敞
-     */
-    private String description;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/MultiInstanceVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/MultiInstanceVo.java
deleted file mode 100644
index b998396..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/MultiInstanceVo.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-/**
- * 澶氬疄渚嬩俊鎭�
- *
- * @author may
- */
-@Data
-public class MultiInstanceVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浼氱绫诲瀷锛堜覆琛岋紝骞惰锛�
-     */
-    private Object type;
-
-    /**
-     * 浼氱浜哄憳KEY
-     */
-    private String assignee;
-
-    /**
-     * 浼氱浜哄憳闆嗗悎KEY
-     */
-    private String assigneeList;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ParticipantVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ParticipantVo.java
deleted file mode 100644
index c5876f6..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ParticipantVo.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 鍙備笌鑰�
- *
- * @author may
- */
-@Data
-public class ParticipantVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 缁刬d锛堣鑹瞚d锛�
-     */
-    private List<Long> groupIds;
-
-    /**
-     * 鍊欓�変汉id锛堢敤鎴穒d锛� 褰撶粍id涓嶄负绌烘椂锛屽皢缁勫唴浜哄憳鏌ュ嚭鏀惧叆candidate
-     */
-    private List<Long> candidate;
-
-    /**
-     * 鍊欓�変汉鍚嶇О锛堢敤鎴峰悕绉帮級 褰撶粍id涓嶄负绌烘椂锛屽皢缁勫唴浜哄憳鏌ュ嚭鏀惧叆candidateName
-     */
-    private List<String> candidateName;
-
-    /**
-     * 鏄惁璁ら鏍囪瘑
-     * 褰撲负绌烘椂榛樿褰撳墠浠诲姟涓嶉渶瑕佽棰�
-     * 褰撲负true鏃跺綋鍓嶄换鍔¤鏄庝负鍊欓�夋ā寮忓苟涓旀湁浜哄凡缁忚棰嗕簡浠诲姟鍙互褰掕繕锛�
-     * 褰撲负false鏃跺綋鍓嶄换鍔¤鏄庝负鍊欓�夋ā寮忚浠诲姟鏈棰嗭紝
-     */
-    private Boolean claim;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessDefinitionVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessDefinitionVo.java
deleted file mode 100644
index 034adbb..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessDefinitionVo.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 娴佺▼瀹氫箟瑙嗗浘
- *
- * @author may
- */
-@Data
-public class ProcessDefinitionVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    private String id;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 娴佺▼瀹氫箟鏍囪瘑key
-     */
-    private String key;
-
-    /**
-     * 娴佺▼瀹氫箟鐗堟湰
-     */
-    private int version;
-
-    /**
-     * 娴佺▼瀹氫箟鎸傝捣鎴栨縺娲� 1婵�娲� 2鎸傝捣
-     */
-    private int suspensionState;
-
-    /**
-     * 娴佺▼xml鍚嶇О
-     */
-    private String resourceName;
-
-    /**
-     * 娴佺▼鍥剧墖鍚嶇О
-     */
-    private String diagramResourceName;
-
-    /**
-     * 娴佺▼閮ㄧ讲id
-     */
-    private String deploymentId;
-
-    /**
-     * 娴佺▼閮ㄧ讲鏃堕棿
-     */
-    private Date deploymentTime;
-
-    /**
-     * 娴佺▼瀹氫箟閰嶇疆
-     */
-    private WfDefinitionConfigVo wfDefinitionConfigVo;
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessInstanceVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessInstanceVo.java
deleted file mode 100644
index ab3e7a1..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ProcessInstanceVo.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.List;
-
-/**
- * 娴佺▼瀹炰緥瑙嗗浘
- *
- * @author may
- */
-@Data
-public class ProcessInstanceVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 娴佺▼瀹炰緥id
-     */
-    private String id;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    private String processDefinitionId;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇О
-     */
-    private String processDefinitionName;
-
-    /**
-     * 娴佺▼瀹氫箟key
-     */
-    private String processDefinitionKey;
-
-    /**
-     * 娴佺▼瀹氫箟鐗堟湰
-     */
-    private Integer processDefinitionVersion;
-
-    /**
-     * 閮ㄧ讲id
-     */
-    private String deploymentId;
-
-    /**
-     * 涓氬姟id
-     */
-    private String businessKey;
-
-    /**
-     * 鏄惁鎸傝捣
-     */
-    private Boolean isSuspended;
-
-    /**
-     * 绉熸埛id
-     */
-    private String tenantId;
-
-    /**
-     * 鍚姩鏃堕棿
-     */
-    private Date startTime;
-
-    /**
-     * 缁撴潫鏃堕棿
-     */
-    private Date endTime;
-
-    /**
-     * 鍚姩浜篿d
-     */
-    private String startUserId;
-
-    /**
-     * 娴佺▼鐘舵��
-     */
-    private String businessStatus;
-
-    /**
-     * 娴佺▼鐘舵��
-     */
-    private String businessStatusName;
-
-    /**
-     * 寰呭姙浠诲姟闆嗗悎
-     */
-    private List<TaskVo> taskVoList;
-
-    /**
-     * 鑺傜偣閰嶇疆
-     */
-    private WfNodeConfigVo wfNodeConfigVo;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java
deleted file mode 100644
index 466e776..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TaskVo.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import lombok.Data;
-import org.dromara.common.translation.annotation.Translation;
-import org.dromara.common.translation.constant.TransConstant;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * 浠诲姟瑙嗗浘
- *
- * @author may
- */
-@Data
-public class TaskVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟id
-     */
-    private String id;
-
-    /**
-     * 浠诲姟鍚嶇О
-     */
-    private String name;
-
-    /**
-     * 鎻忚堪
-     */
-    private String description;
-
-    /**
-     * 浼樺厛绾�
-     */
-    private Integer priority;
-
-    /**
-     * 璐熻矗姝や换鍔$殑浜哄憳鐨勭敤鎴穒d
-     */
-    private String owner;
-
-    /**
-     * 鍔炵悊浜篿d
-     */
-    private Long assignee;
-
-    /**
-     * 鍔炵悊浜�
-     */
-    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "assignee")
-    private String assigneeName;
-
-
-    /**
-     * 娴佺▼瀹炰緥id
-     */
-    private String processInstanceId;
-
-    /**
-     * 鎵цid
-     */
-    private String executionId;
-
-    /**
-     * 鏃犵敤
-     */
-    private String taskDefinitionId;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    private String processDefinitionId;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    private Date createTime;
-
-    /**
-     * 宸插姙浠诲姟-鍒涘缓鏃堕棿
-     */
-    private Date startTime;
-
-    /**
-     * 缁撴潫鏃堕棿
-     */
-    private Date endTime;
-
-    /**
-     * 鑺傜偣id
-     */
-    private String taskDefinitionKey;
-
-    /**
-     * 浠诲姟鎴鏃ユ湡
-     */
-    private Date dueDate;
-
-    /**
-     * 娴佺▼绫诲埆
-     */
-    private String category;
-
-    /**
-     * 鐖剁骇浠诲姟id
-     */
-    private String parentTaskId;
-
-    /**
-     * 绉熸埛id
-     */
-    private String tenantId;
-
-    /**
-     * 璁ら鏃堕棿
-     */
-    private Date claimTime;
-
-    /**
-     * 娴佺▼鐘舵��
-     */
-    private String businessStatus;
-
-    /**
-     * 娴佺▼鐘舵��
-     */
-    private String businessStatusName;
-
-    /**
-     * 娴佺▼瀹氫箟鍚嶇О
-     */
-    private String processDefinitionName;
-
-    /**
-     * 娴佺▼瀹氫箟key
-     */
-    private String processDefinitionKey;
-
-    /**
-     * 娴佺▼瀹氫箟鐗堟湰
-     */
-    private Integer processDefinitionVersion;
-
-    /**
-     * 鍙備笌鑰�
-     */
-    private ParticipantVo participantVo;
-
-    /**
-     * 鏄惁浼氱
-     */
-    private Boolean multiInstance;
-
-    /**
-     * 涓氬姟id
-     */
-    private String businessKey;
-
-    /**
-     * 娴佺▼瀹氫箟閰嶇疆
-     */
-    private WfDefinitionConfigVo wfDefinitionConfigVo;
-
-    /**
-     * 鑺傜偣閰嶇疆
-     */
-    private WfNodeConfigVo wfNodeConfigVo;
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCategoryVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCategoryVo.java
deleted file mode 100644
index 362f646..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfCategoryVo.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-import org.dromara.workflow.domain.WfCategory;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 娴佺▼鍒嗙被瑙嗗浘瀵硅薄 wf_category
- *
- * @author may
- * @date 2023-06-27
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = WfCategory.class)
-public class WfCategoryVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @ExcelProperty(value = "涓婚敭")
-    private Long id;
-
-    /**
-     * 鍒嗙被鍚嶇О
-     */
-    @ExcelProperty(value = "鍒嗙被鍚嶇О")
-    private String categoryName;
-
-    /**
-     * 鍒嗙被缂栫爜
-     */
-    @ExcelProperty(value = "鍒嗙被缂栫爜")
-    private String categoryCode;
-
-    /**
-     * 鐖剁骇id
-     */
-    @ExcelProperty(value = "鐖剁骇id")
-    private Long parentId;
-
-    /**
-     * 鎺掑簭
-     */
-    @ExcelProperty(value = "鎺掑簭")
-    private Long sortNum;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfDefinitionConfigVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfDefinitionConfigVo.java
deleted file mode 100644
index 9c7b0d7..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfDefinitionConfigVo.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import org.dromara.workflow.domain.WfDefinitionConfig;
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆瑙嗗浘瀵硅薄 wf_definition_config
- *
- * @author may
- * @date 2024-03-18
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = WfDefinitionConfig.class)
-public class WfDefinitionConfigVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @ExcelProperty(value = "涓婚敭")
-    private Long id;
-
-    /**
-     * 琛ㄥ悕
-     */
-    @ExcelProperty(value = "琛ㄥ悕")
-    private String tableName;
-
-    /**
-     * 娴佺▼瀹氫箟ID
-     */
-    @ExcelProperty(value = "娴佺▼瀹氫箟ID")
-    private String definitionId;
-
-    /**
-     * 娴佺▼KEY
-     */
-    @ExcelProperty(value = "娴佺▼KEY")
-    private String processKey;
-
-
-    /**
-     * 娴佺▼鐗堟湰
-     */
-    @ExcelProperty(value = "娴佺▼鐗堟湰")
-    private Integer version;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-    /**
-     * 琛ㄥ崟绠$悊
-     */
-    private WfFormManageVo wfFormManageVo;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfFormManageVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfFormManageVo.java
deleted file mode 100644
index 302df23..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfFormManageVo.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import org.dromara.workflow.domain.WfFormManage;
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 琛ㄥ崟绠$悊瑙嗗浘瀵硅薄 wf_form_manage
- *
- * @author may
- * @date 2024-03-29
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = WfFormManage.class)
-public class WfFormManageVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @ExcelProperty(value = "涓婚敭")
-    private Long id;
-
-    /**
-     * 琛ㄥ崟鍚嶇О
-     */
-    @ExcelProperty(value = "琛ㄥ崟鍚嶇О")
-    private String formName;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    @ExcelProperty(value = "琛ㄥ崟绫诲瀷")
-    private String formType;
-
-    /**
-     * 琛ㄥ崟绫诲瀷鍚嶇О
-     */
-    private String formTypeName;
-
-    /**
-     * 璺敱鍦板潃/琛ㄥ崟ID
-     */
-    @ExcelProperty(value = "璺敱鍦板潃/琛ㄥ崟ID")
-    private String router;
-
-    /**
-     * 澶囨敞
-     */
-    @ExcelProperty(value = "澶囨敞")
-    private String remark;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfNodeConfigVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfNodeConfigVo.java
deleted file mode 100644
index 89e9d9b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/WfNodeConfigVo.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.dromara.workflow.domain.vo;
-
-import org.dromara.workflow.domain.WfNodeConfig;
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import io.github.linpeilie.annotations.AutoMapper;
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-
-
-/**
- * 鑺傜偣閰嶇疆瑙嗗浘瀵硅薄 wf_node_config
- *
- * @author may
- * @date 2024-03-30
- */
-@Data
-@ExcelIgnoreUnannotated
-@AutoMapper(target = WfNodeConfig.class)
-public class WfNodeConfigVo implements Serializable {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 涓婚敭
-     */
-    @ExcelProperty(value = "涓婚敭")
-    private Long id;
-
-    /**
-     * 琛ㄥ崟id
-     */
-    @ExcelProperty(value = "琛ㄥ崟id")
-    private Long formId;
-
-    /**
-     * 琛ㄥ崟绫诲瀷
-     */
-    @ExcelProperty(value = "琛ㄥ崟绫诲瀷")
-    private String formType;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    @ExcelProperty(value = "鑺傜偣鍚嶇О")
-    private String nodeName;
-
-    /**
-     * 鑺傜偣id
-     */
-    @ExcelProperty(value = "鑺傜偣id")
-    private String nodeId;
-
-    /**
-     * 娴佺▼瀹氫箟id
-     */
-    @ExcelProperty(value = "娴佺▼瀹氫箟id")
-    private String definitionId;
-
-    /**
-     * 鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級
-     */
-    @ExcelProperty(value = "鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級")
-    private String applyUserTask;
-
-    /**
-     * 琛ㄥ崟绠$悊
-     */
-    private WfFormManageVo wfFormManageVo;
-
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramCanvas.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramCanvas.java
deleted file mode 100644
index 39fd9d3..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramCanvas.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.dromara.workflow.flowable;
-
-import org.flowable.bpmn.model.AssociationDirection;
-import org.flowable.image.impl.DefaultProcessDiagramCanvas;
-
-import java.awt.*;
-import java.awt.geom.Line2D;
-import java.awt.geom.RoundRectangle2D;
-
-public class CustomDefaultProcessDiagramCanvas extends DefaultProcessDiagramCanvas {
-    //璁剧疆楂樹寒绾跨殑棰滆壊  杩欓噷鎴戣缃垚缁胯壊
-    protected static Color HIGHLIGHT_SEQUENCEFLOW_COLOR = Color.GREEN;
-
-    public CustomDefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
-        super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
-    }
-
-    /**
-     * 鐢荤嚎棰滆壊璁剧疆
-     */
-    public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType,
-                               AssociationDirection associationDirection, boolean highLighted, double scaleFactor) {
-
-        Paint originalPaint = g.getPaint();
-        Stroke originalStroke = g.getStroke();
-
-        g.setPaint(CONNECTION_COLOR);
-        if (connectionType.equals("association")) {
-            g.setStroke(ASSOCIATION_STROKE);
-        } else if (highLighted) {
-            //璁剧疆绾跨殑棰滆壊
-            g.setPaint(HIGHLIGHT_SEQUENCEFLOW_COLOR);
-            g.setStroke(HIGHLIGHT_FLOW_STROKE);
-        }
-
-        for (int i = 1; i < xPoints.length; i++) {
-            Integer sourceX = xPoints[i - 1];
-            Integer sourceY = yPoints[i - 1];
-            Integer targetX = xPoints[i];
-            Integer targetY = yPoints[i];
-            Line2D.Double line = new Line2D.Double(sourceX, sourceY, targetX, targetY);
-            g.draw(line);
-        }
-
-        if (isDefault) {
-            Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
-            drawDefaultSequenceFlowIndicator(line, scaleFactor);
-        }
-
-        if (conditional) {
-            Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
-            drawConditionalSequenceFlowIndicator(line, scaleFactor);
-        }
-
-        if (associationDirection == AssociationDirection.ONE || associationDirection == AssociationDirection.BOTH) {
-            Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2], yPoints[xPoints.length - 2], xPoints[xPoints.length - 1], yPoints[xPoints.length - 1]);
-            drawArrowHead(line, scaleFactor);
-        }
-        if (associationDirection == AssociationDirection.BOTH) {
-            Line2D.Double line = new Line2D.Double(xPoints[1], yPoints[1], xPoints[0], yPoints[0]);
-            drawArrowHead(line, scaleFactor);
-        }
-        g.setPaint(originalPaint);
-        g.setStroke(originalStroke);
-    }
-
-    /**
-     * 楂樹寒鑺傜偣璁剧疆
-     */
-    public void drawHighLight(int x, int y, int width, int height) {
-        Paint originalPaint = g.getPaint();
-        Stroke originalStroke = g.getStroke();
-        //璁剧疆楂樹寒鑺傜偣鐨勯鑹�
-        g.setPaint(HIGHLIGHT_COLOR);
-        g.setStroke(THICK_TASK_BORDER_STROKE);
-
-        RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
-        g.draw(rect);
-
-        g.setPaint(originalPaint);
-        g.setStroke(originalStroke);
-    }
-
-    /**
-     * @description: 楂樹寒鑺傜偣绾㈣壊
-     * @param: x
-     * @param: y
-     * @param: width
-     * @param: height
-     * @return: void
-     * @author: gssong
-     * @date: 2022/4/12
-     */
-    public void drawHighLightRed(int x, int y, int width, int height) {
-        Paint originalPaint = g.getPaint();
-        Stroke originalStroke = g.getStroke();
-        //璁剧疆楂樹寒鑺傜偣鐨勯鑹�
-        g.setPaint(Color.green);
-        g.setStroke(THICK_TASK_BORDER_STROKE);
-
-        RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
-        g.draw(rect);
-
-        g.setPaint(originalPaint);
-        g.setStroke(originalStroke);
-    }
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramGenerator.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramGenerator.java
deleted file mode 100644
index e4793a2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/CustomDefaultProcessDiagramGenerator.java
+++ /dev/null
@@ -1,1120 +0,0 @@
-/* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.dromara.workflow.flowable;
-
-import org.flowable.bpmn.model.Event;
-import org.flowable.bpmn.model.Process;
-import org.flowable.bpmn.model.*;
-import org.flowable.image.ProcessDiagramGenerator;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.InputStream;
-import java.util.List;
-import java.util.*;
-
-/**
- * Class to generate an image based the diagram interchange information in a BPMN 2.0 process.
- *
- * @author Joram Barrez
- * @author Tijs Rademakers
- * @author Zheng Ji
- */
-public class CustomDefaultProcessDiagramGenerator implements ProcessDiagramGenerator {
-
-    protected Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions = new HashMap<>();
-    protected Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap<>();
-
-    public CustomDefaultProcessDiagramGenerator() {
-        this(1.0);
-    }
-
-    // The instructions on how to draw a certain construct is
-    // created statically and stored in a map for performance.
-    public CustomDefaultProcessDiagramGenerator(final double scaleFactor) {
-        // start event
-        activityDrawInstructions.put(StartEvent.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                StartEvent startEvent = (StartEvent) flowNode;
-                if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) {
-                    EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
-                    if (eventDefinition instanceof TimerEventDefinition) {
-                        processDiagramCanvas.drawTimerStartEvent(graphicInfo, scaleFactor);
-                    } else if (eventDefinition instanceof ErrorEventDefinition) {
-                        processDiagramCanvas.drawErrorStartEvent(graphicInfo, scaleFactor);
-                    } else if (eventDefinition instanceof EscalationEventDefinition) {
-                        processDiagramCanvas.drawEscalationStartEvent(graphicInfo, scaleFactor);
-                    } else if (eventDefinition instanceof ConditionalEventDefinition) {
-                        processDiagramCanvas.drawConditionalStartEvent(graphicInfo, scaleFactor);
-                    } else if (eventDefinition instanceof SignalEventDefinition) {
-                        processDiagramCanvas.drawSignalStartEvent(graphicInfo, scaleFactor);
-                    } else if (eventDefinition instanceof MessageEventDefinition) {
-                        processDiagramCanvas.drawMessageStartEvent(graphicInfo, scaleFactor);
-                    } else {
-                        processDiagramCanvas.drawNoneStartEvent(graphicInfo);
-                    }
-                } else {
-                    List<ExtensionElement> eventTypeElements = startEvent.getExtensionElements().get("eventType");
-                    if (eventTypeElements != null && eventTypeElements.size() > 0) {
-                        processDiagramCanvas.drawEventRegistryStartEvent(graphicInfo, scaleFactor);
-
-                    } else {
-                        processDiagramCanvas.drawNoneStartEvent(graphicInfo);
-                    }
-                }
-            }
-        });
-
-        // signal catch
-        activityDrawInstructions.put(IntermediateCatchEvent.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode;
-                if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent.getEventDefinitions().isEmpty()) {
-
-                    if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
-                        processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, true, scaleFactor);
-                    } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
-                        processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, true, scaleFactor);
-                    } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
-                        processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, true, scaleFactor);
-                    } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof ConditionalEventDefinition) {
-                        processDiagramCanvas.drawCatchingConditionalEvent(flowNode.getName(), graphicInfo, true, scaleFactor);
-                    }
-                }
-            }
-        });
-
-        // signal throw
-        activityDrawInstructions.put(ThrowEvent.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                ThrowEvent throwEvent = (ThrowEvent) flowNode;
-                if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) {
-                    if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
-                        processDiagramCanvas.drawThrowingSignalEvent(graphicInfo, scaleFactor);
-                    } else if (throwEvent.getEventDefinitions().get(0) instanceof EscalationEventDefinition) {
-                        processDiagramCanvas.drawThrowingEscalationEvent(graphicInfo, scaleFactor);
-                    } else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
-                        processDiagramCanvas.drawThrowingCompensateEvent(graphicInfo, scaleFactor);
-                    } else {
-                        processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor);
-                    }
-                } else {
-                    processDiagramCanvas.drawThrowingNoneEvent(graphicInfo, scaleFactor);
-                }
-            }
-        });
-
-        // end event
-        activityDrawInstructions.put(EndEvent.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                EndEvent endEvent = (EndEvent) flowNode;
-                if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) {
-                    if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
-                        processDiagramCanvas.drawErrorEndEvent(flowNode.getName(), graphicInfo, scaleFactor);
-                    } else if (endEvent.getEventDefinitions().get(0) instanceof EscalationEventDefinition) {
-                        processDiagramCanvas.drawEscalationEndEvent(flowNode.getName(), graphicInfo, scaleFactor);
-                    } else {
-                        processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor);
-                    }
-                } else {
-                    processDiagramCanvas.drawNoneEndEvent(graphicInfo, scaleFactor);
-                }
-            }
-        });
-
-        // task
-        activityDrawInstructions.put(Task.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // user task
-        activityDrawInstructions.put(UserTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawUserTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // script task
-        activityDrawInstructions.put(ScriptTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawScriptTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // service task
-        activityDrawInstructions.put(ServiceTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                ServiceTask serviceTask = (ServiceTask) flowNode;
-                if ("camel".equalsIgnoreCase(serviceTask.getType())) {
-                    processDiagramCanvas.drawCamelTask(serviceTask.getName(), graphicInfo, scaleFactor);
-                }else if (ServiceTask.HTTP_TASK.equalsIgnoreCase(serviceTask.getType())) {
-                    processDiagramCanvas.drawHttpTask(serviceTask.getName(), graphicInfo, scaleFactor);
-                } else if (ServiceTask.DMN_TASK.equalsIgnoreCase(serviceTask.getType())) {
-                    processDiagramCanvas.drawDMNTask(serviceTask.getName(), graphicInfo, scaleFactor);
-                } else if (ServiceTask.SHELL_TASK.equalsIgnoreCase(serviceTask.getType())) {
-                    processDiagramCanvas.drawShellTask(serviceTask.getName(), graphicInfo, scaleFactor);
-                } else {
-                    processDiagramCanvas.drawServiceTask(serviceTask.getName(), graphicInfo, scaleFactor);
-                }
-            }
-        });
-
-        // http service task
-        activityDrawInstructions.put(HttpServiceTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawHttpTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // receive task
-        activityDrawInstructions.put(ReceiveTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawReceiveTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // send task
-        activityDrawInstructions.put(SendTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawSendTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // manual task
-        activityDrawInstructions.put(ManualTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawManualTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // send event service task
-        activityDrawInstructions.put(SendEventServiceTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawSendEventServiceTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // external worker service task
-        activityDrawInstructions.put(ExternalWorkerServiceTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                ServiceTask serviceTask = (ServiceTask) flowNode;
-                processDiagramCanvas.drawServiceTask(serviceTask.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // case service task
-        activityDrawInstructions.put(CaseServiceTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawCaseServiceTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // businessRuleTask task
-        activityDrawInstructions.put(BusinessRuleTask.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawBusinessRuleTask(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // exclusive gateway
-        activityDrawInstructions.put(ExclusiveGateway.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawExclusiveGateway(graphicInfo, scaleFactor);
-            }
-        });
-
-        // inclusive gateway
-        activityDrawInstructions.put(InclusiveGateway.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawInclusiveGateway(graphicInfo, scaleFactor);
-            }
-        });
-
-        // parallel gateway
-        activityDrawInstructions.put(ParallelGateway.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawParallelGateway(graphicInfo, scaleFactor);
-            }
-        });
-
-        // event based gateway
-        activityDrawInstructions.put(EventGateway.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawEventBasedGateway(graphicInfo, scaleFactor);
-            }
-        });
-
-        // Boundary timer
-        activityDrawInstructions.put(BoundaryEvent.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode;
-                if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) {
-                    EventDefinition eventDefinition = boundaryEvent.getEventDefinitions().get(0);
-                    if (eventDefinition instanceof TimerEventDefinition) {
-                        processDiagramCanvas.drawCatchingTimerEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof ConditionalEventDefinition) {
-                        processDiagramCanvas.drawCatchingConditionalEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof ErrorEventDefinition) {
-                        processDiagramCanvas.drawCatchingErrorEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof EscalationEventDefinition) {
-                        processDiagramCanvas.drawCatchingEscalationEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof SignalEventDefinition) {
-                        processDiagramCanvas.drawCatchingSignalEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof MessageEventDefinition) {
-                        processDiagramCanvas.drawCatchingMessageEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-
-                    } else if (eventDefinition instanceof CompensateEventDefinition) {
-                        processDiagramCanvas.drawCatchingCompensateEvent(graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-                    }
-
-                } else {
-                    List<ExtensionElement> eventTypeElements = boundaryEvent.getExtensionElements().get("eventType");
-                    if (eventTypeElements != null && eventTypeElements.size() > 0) {
-                        processDiagramCanvas.drawCatchingEventRegistryEvent(flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity(), scaleFactor);
-                    }
-                }
-            }
-        });
-
-        // subprocess
-        activityDrawInstructions.put(SubProcess.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                    processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor);
-                } else {
-                    processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor);
-                }
-            }
-        });
-
-        // transaction
-        activityDrawInstructions.put(Transaction.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                    processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor);
-                } else {
-                    processDiagramCanvas.drawExpandedTransaction(flowNode.getName(), graphicInfo, scaleFactor);
-                }
-            }
-        });
-
-        // Event subprocess
-        activityDrawInstructions.put(EventSubProcess.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                    processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, true, scaleFactor);
-                } else {
-                    processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, true, scaleFactor);
-                }
-            }
-        });
-
-        // Adhoc subprocess
-        activityDrawInstructions.put(AdhocSubProcess.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                    processDiagramCanvas.drawCollapsedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor);
-                } else {
-                    processDiagramCanvas.drawExpandedSubProcess(flowNode.getName(), graphicInfo, false, scaleFactor);
-                }
-            }
-        });
-
-        // call activity
-        activityDrawInstructions.put(CallActivity.class, new ActivityDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-                processDiagramCanvas.drawCollapsedCallActivity(flowNode.getName(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // text annotation
-        artifactDrawInstructions.put(TextAnnotation.class, new ArtifactDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
-                TextAnnotation textAnnotation = (TextAnnotation) artifact;
-                processDiagramCanvas.drawTextAnnotation(textAnnotation.getText(), graphicInfo, scaleFactor);
-            }
-        });
-
-        // association
-        artifactDrawInstructions.put(Association.class, new ArtifactDrawInstruction() {
-
-            @Override
-            public void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
-                Association association = (Association) artifact;
-                String sourceRef = association.getSourceRef();
-                String targetRef = association.getTargetRef();
-
-                // source and target can be instance of FlowElement or Artifact
-                BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef);
-                BaseElement targetElement = bpmnModel.getFlowElement(targetRef);
-                if (sourceElement == null) {
-                    sourceElement = bpmnModel.getArtifact(sourceRef);
-                }
-                if (targetElement == null) {
-                    targetElement = bpmnModel.getArtifact(targetRef);
-                }
-                List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
-                graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
-                int[] xPoints = new int[graphicInfoList.size()];
-                int[] yPoints = new int[graphicInfoList.size()];
-                for (int i = 1; i < graphicInfoList.size(); i++) {
-                    GraphicInfo graphicInfo = graphicInfoList.get(i);
-                    GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
-                    if (i == 1) {
-                        xPoints[0] = (int) previousGraphicInfo.getX();
-                        yPoints[0] = (int) previousGraphicInfo.getY();
-                    }
-                    xPoints[i] = (int) graphicInfo.getX();
-                    yPoints[i] = (int) graphicInfo.getY();
-                }
-
-                AssociationDirection associationDirection = association.getAssociationDirection();
-                processDiagramCanvas.drawAssociation(xPoints, yPoints, associationDirection, false, scaleFactor);
-            }
-        });
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows,
-                                       String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows,
-            activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI).generateImage(imageType);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, 1.0, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType,
-                                       List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, imageType, highLightedActivities, Collections.emptyList(), scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName,
-                                       String labelFontName, String annotationFontName, ClassLoader customClassLoader, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(),
-            activityFontName, labelFontName, annotationFontName, customClassLoader, 1.0, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName,
-                                       String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(),
-            activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generatePngDiagram(BpmnModel bpmnModel, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generatePngDiagram(bpmnModel, 1.0, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generatePngDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public InputStream generateJpgDiagram(BpmnModel bpmnModel) {
-        return generateJpgDiagram(bpmnModel, 1.0, false);
-    }
-
-    @Override
-    public InputStream generateJpgDiagram(BpmnModel bpmnModel, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-        return generateDiagram(bpmnModel, "jpg", Collections.emptyList(), Collections.emptyList(), drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    public BufferedImage generateImage(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows,
-                                       String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        return generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows,
-            activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, drawSequenceFlowNameWithNoLabelDI).generateBufferedImage(imageType);
-    }
-
-    public BufferedImage generateImage(BpmnModel bpmnModel, String imageType,
-                                       List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        return generateImage(bpmnModel, imageType, highLightedActivities, highLightedFlows, null, null, null, null, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-    }
-
-    @Override
-    public BufferedImage generatePngImage(BpmnModel bpmnModel, double scaleFactor) {
-        return generateImage(bpmnModel, "png", Collections.emptyList(), Collections.emptyList(), scaleFactor, false);
-    }
-
-    protected CustomDefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType,
-                                                                       List<String> highLightedActivities, List<String> highLightedFlows,
-                                                                       String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        prepareBpmnModel(bpmnModel);
-
-        CustomDefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
-
-        // Draw pool shape, if process is participant in collaboration
-        for (Pool pool : bpmnModel.getPools()) {
-            GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
-            processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo, scaleFactor);
-        }
-
-        // Draw lanes
-        for (Process process : bpmnModel.getProcesses()) {
-            for (Lane lane : process.getLanes()) {
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
-                processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo, scaleFactor);
-            }
-        }
-
-        // Draw activities and their sequence-flows
-        for (Process process : bpmnModel.getProcesses()) {
-            for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) {
-                if (!isPartOfCollapsedSubProcess(flowNode, bpmnModel)) {
-                    drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-                }
-            }
-        }
-
-        // Draw artifacts
-        for (Process process : bpmnModel.getProcesses()) {
-
-            for (Artifact artifact : process.getArtifacts()) {
-                drawArtifact(processDiagramCanvas, bpmnModel, artifact);
-            }
-
-            List<SubProcess> subProcesses = process.findFlowElementsOfType(SubProcess.class, true);
-            if (subProcesses != null) {
-                for (SubProcess subProcess : subProcesses) {
-
-                    GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(subProcess.getId());
-                    if (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                        continue;
-                    }
-
-                    if (!isPartOfCollapsedSubProcess(subProcess, bpmnModel)) {
-                        for (Artifact subProcessArtifact : subProcess.getArtifacts()) {
-                            drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);
-                        }
-                    }
-                }
-            }
-        }
-
-        return processDiagramCanvas;
-    }
-
-    protected void prepareBpmnModel(BpmnModel bpmnModel) {
-
-        // Need to make sure all elements have positive x and y.
-        // Check all graphicInfo and update the elements accordingly
-
-        List<GraphicInfo> allGraphicInfos = new ArrayList<>();
-        if (bpmnModel.getLocationMap() != null) {
-            allGraphicInfos.addAll(bpmnModel.getLocationMap().values());
-        }
-        if (bpmnModel.getLabelLocationMap() != null) {
-            allGraphicInfos.addAll(bpmnModel.getLabelLocationMap().values());
-        }
-        if (bpmnModel.getFlowLocationMap() != null) {
-            for (List<GraphicInfo> flowGraphicInfos : bpmnModel.getFlowLocationMap().values()) {
-                allGraphicInfos.addAll(flowGraphicInfos);
-            }
-        }
-
-        if (allGraphicInfos.size() > 0) {
-
-            boolean needsTranslationX = false;
-            boolean needsTranslationY = false;
-
-            double lowestX = 0.0;
-            double lowestY = 0.0;
-
-            // Collect lowest x and y
-            for (GraphicInfo graphicInfo : allGraphicInfos) {
-
-                double x = graphicInfo.getX();
-                double y = graphicInfo.getY();
-
-                if (x < lowestX) {
-                    needsTranslationX = true;
-                    lowestX = x;
-                }
-                if (y < lowestY) {
-                    needsTranslationY = true;
-                    lowestY = y;
-                }
-
-            }
-
-            // Update all graphicInfo objects
-            if (needsTranslationX || needsTranslationY) {
-
-                double translationX = Math.abs(lowestX);
-                double translationY = Math.abs(lowestY);
-
-                for (GraphicInfo graphicInfo : allGraphicInfos) {
-                    if (needsTranslationX) {
-                        graphicInfo.setX(graphicInfo.getX() + translationX);
-                    }
-                    if (needsTranslationY) {
-                        graphicInfo.setY(graphicInfo.getY() + translationY);
-                    }
-                }
-            }
-
-        }
-
-    }
-
-    protected void drawActivity(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,
-                                FlowNode flowNode, List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, Boolean drawSequenceFlowNameWithNoLabelDI) {
-
-        ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
-        if (drawInstruction != null) {
-
-            drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
-
-            // Gather info on the multi instance marker
-            boolean multiInstanceSequential = false;
-            boolean multiInstanceParallel = false;
-            boolean collapsed = false;
-            if (flowNode instanceof Activity) {
-                Activity activity = (Activity) flowNode;
-                MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
-                if (multiInstanceLoopCharacteristics != null) {
-                    multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
-                    multiInstanceParallel = !multiInstanceSequential;
-                }
-            }
-
-            // Gather info on the collapsed marker
-            GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-            if (flowNode instanceof SubProcess) {
-                collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
-            } else if (flowNode instanceof CallActivity) {
-                collapsed = true;
-            }
-
-            if (scaleFactor == 1.0) {
-                // Actually draw the markers
-                processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
-                    multiInstanceSequential, multiInstanceParallel, collapsed);
-            }
-
-            // Draw highlighted activities
-            if (highLightedActivities.contains(flowNode.getId())) {
-                drawHighLightRed(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
-            } else if (highLightedActivities.contains(Color.RED.toString() + flowNode.getId())) {
-                drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
-            }
-
-        } else if (flowNode instanceof Task) {
-            activityDrawInstructions.get(Task.class).draw(processDiagramCanvas, bpmnModel, flowNode);
-
-            if (highLightedActivities.contains(flowNode.getId())) {
-                drawHighLightRed(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
-            } else if (highLightedActivities.contains(Color.RED.toString() + flowNode.getId())) {
-                drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
-            }
-        }
-
-        // Outgoing transitions of activity
-        for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
-            boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
-            String defaultFlow = null;
-            if (flowNode instanceof Activity) {
-                defaultFlow = ((Activity) flowNode).getDefaultFlow();
-            } else if (flowNode instanceof Gateway) {
-                defaultFlow = ((Gateway) flowNode).getDefaultFlow();
-            }
-
-            boolean isDefault = false;
-            if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
-                isDefault = true;
-            }
-            boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && sequenceFlow.getConditionExpression().trim().length() > 0 && !(flowNode instanceof Gateway);
-
-            String sourceRef = sequenceFlow.getSourceRef();
-            String targetRef = sequenceFlow.getTargetRef();
-            FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
-            FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
-            List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
-            if (graphicInfoList != null && graphicInfoList.size() > 0) {
-                graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
-                int[] xPoints = new int[graphicInfoList.size()];
-                int[] yPoints = new int[graphicInfoList.size()];
-
-                for (int i = 1; i < graphicInfoList.size(); i++) {
-                    GraphicInfo graphicInfo = graphicInfoList.get(i);
-                    GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
-                    if (i == 1) {
-                        xPoints[0] = (int) previousGraphicInfo.getX();
-                        yPoints[0] = (int) previousGraphicInfo.getY();
-                    }
-                    xPoints[i] = (int) graphicInfo.getX();
-                    yPoints[i] = (int) graphicInfo.getY();
-
-                }
-
-                processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor);
-
-                // Draw sequenceflow label
-                GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
-                if (labelGraphicInfo != null) {
-                    processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
-                } else {
-                    if (drawSequenceFlowNameWithNoLabelDI) {
-                        GraphicInfo lineCenter = getLineCenter(graphicInfoList);
-                        processDiagramCanvas.drawLabel(sequenceFlow.getName(), lineCenter, false);
-                    }
-
-                }
-            }
-        }
-
-        // Nested elements
-        if (flowNode instanceof FlowElementsContainer) {
-            for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
-                if (nestedFlowElement instanceof FlowNode && !isPartOfCollapsedSubProcess(nestedFlowElement, bpmnModel)) {
-                    drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement,
-                        highLightedActivities, highLightedFlows, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
-                }
-            }
-        }
-    }
-
-    /**
-     * This method makes coordinates of connection flow better.
-     *
-     * @param processDiagramCanvas
-     * @param bpmnModel
-     * @param sourceElement
-     * @param targetElement
-     * @param graphicInfoList
-     * @return
-     */
-    protected static List<GraphicInfo> connectionPerfectionizer(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, BaseElement sourceElement, BaseElement targetElement, List<GraphicInfo> graphicInfoList) {
-        GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId());
-        GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId());
-
-        CustomDefaultProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement);
-        CustomDefaultProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement);
-
-        return processDiagramCanvas.connectionPerfectionizer(sourceShapeType, targetShapeType, sourceGraphicInfo, targetGraphicInfo, graphicInfoList);
-    }
-
-    /**
-     * This method returns shape type of base element.<br>
-     * Each element can be presented as rectangle, rhombus, or ellipse.
-     *
-     * @param baseElement
-     * @return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE
-     */
-    protected static CustomDefaultProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) {
-        if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) {
-            return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Rectangle;
-        } else if (baseElement instanceof Gateway) {
-            return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Rhombus;
-        } else if (baseElement instanceof Event) {
-            return CustomDefaultProcessDiagramCanvas.SHAPE_TYPE.Ellipse;
-        } else {
-            // unknown source element, just do not correct coordinates
-        }
-        return null;
-    }
-
-    protected static GraphicInfo getLineCenter(List<GraphicInfo> graphicInfoList) {
-        GraphicInfo gi = new GraphicInfo();
-
-        int[] xPoints = new int[graphicInfoList.size()];
-        int[] yPoints = new int[graphicInfoList.size()];
-
-        double length = 0;
-        double[] lengths = new double[graphicInfoList.size()];
-        lengths[0] = 0;
-        double m;
-        for (int i = 1; i < graphicInfoList.size(); i++) {
-            GraphicInfo graphicInfo = graphicInfoList.get(i);
-            GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
-            if (i == 1) {
-                xPoints[0] = (int) previousGraphicInfo.getX();
-                yPoints[0] = (int) previousGraphicInfo.getY();
-            }
-            xPoints[i] = (int) graphicInfo.getX();
-            yPoints[i] = (int) graphicInfo.getY();
-
-            length += Math.sqrt(
-                Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(), 2) +
-                    Math.pow((int) graphicInfo.getY() - (int) previousGraphicInfo.getY(), 2));
-            lengths[i] = length;
-        }
-        m = length / 2;
-        int p1 = 0;
-        int p2 = 1;
-        for (int i = 1; i < lengths.length; i++) {
-            double len = lengths[i];
-            p1 = i - 1;
-            p2 = i;
-            if (len > m) {
-                break;
-            }
-        }
-
-        GraphicInfo graphicInfo1 = graphicInfoList.get(p1);
-        GraphicInfo graphicInfo2 = graphicInfoList.get(p2);
-
-        double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX();
-        double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY();
-        double OB = lengths[p2] - lengths[p1];
-        double ob = m - lengths[p1];
-        double ab = AB * ob / OB;
-        double oa = OA * ob / OB;
-
-        double mx = graphicInfo1.getX() + ab;
-        double my = graphicInfo1.getY() + oa;
-
-        gi.setX(mx);
-        gi.setY(my);
-        return gi;
-    }
-
-    protected void drawArtifact(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
-
-        ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass());
-        if (drawInstruction != null) {
-            drawInstruction.draw(processDiagramCanvas, bpmnModel, artifact);
-        }
-    }
-
-    private static void drawHighLight(CustomDefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
-        processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());
-
-    }
-
-    private static void drawHighLightRed(CustomDefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
-        processDiagramCanvas.drawHighLightRed((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());
-
-    }
-
-    protected static CustomDefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType,
-                                                                                String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
-
-        // We need to calculate maximum values to know how big the image will be in its entirety
-        double minX = Double.MAX_VALUE;
-        double maxX = 0;
-        double minY = Double.MAX_VALUE;
-        double maxY = 0;
-
-        for (Pool pool : bpmnModel.getPools()) {
-            GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
-            minX = graphicInfo.getX();
-            maxX = graphicInfo.getX() + graphicInfo.getWidth();
-            minY = graphicInfo.getY();
-            maxY = graphicInfo.getY() + graphicInfo.getHeight();
-        }
-
-        List<FlowNode> flowNodes = gatherAllFlowNodes(bpmnModel);
-        for (FlowNode flowNode : flowNodes) {
-
-            GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-
-            // width
-            if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {
-                maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth();
-            }
-            if (flowNodeGraphicInfo.getX() < minX) {
-                minX = flowNodeGraphicInfo.getX();
-            }
-            // height
-            if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {
-                maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight();
-            }
-            if (flowNodeGraphicInfo.getY() < minY) {
-                minY = flowNodeGraphicInfo.getY();
-            }
-
-            for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
-                List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
-                if (graphicInfoList != null) {
-                    for (GraphicInfo graphicInfo : graphicInfoList) {
-                        // width
-                        if (graphicInfo.getX() > maxX) {
-                            maxX = graphicInfo.getX();
-                        }
-                        if (graphicInfo.getX() < minX) {
-                            minX = graphicInfo.getX();
-                        }
-                        // height
-                        if (graphicInfo.getY() > maxY) {
-                            maxY = graphicInfo.getY();
-                        }
-                        if (graphicInfo.getY() < minY) {
-                            minY = graphicInfo.getY();
-                        }
-                    }
-                }
-            }
-        }
-
-        List<Artifact> artifacts = gatherAllArtifacts(bpmnModel);
-        for (Artifact artifact : artifacts) {
-
-            GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
-
-            if (artifactGraphicInfo != null) {
-                // width
-                if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {
-                    maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();
-                }
-                if (artifactGraphicInfo.getX() < minX) {
-                    minX = artifactGraphicInfo.getX();
-                }
-                // height
-                if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {
-                    maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();
-                }
-                if (artifactGraphicInfo.getY() < minY) {
-                    minY = artifactGraphicInfo.getY();
-                }
-            }
-
-            List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
-            if (graphicInfoList != null) {
-                for (GraphicInfo graphicInfo : graphicInfoList) {
-                    // width
-                    if (graphicInfo.getX() > maxX) {
-                        maxX = graphicInfo.getX();
-                    }
-                    if (graphicInfo.getX() < minX) {
-                        minX = graphicInfo.getX();
-                    }
-                    // height
-                    if (graphicInfo.getY() > maxY) {
-                        maxY = graphicInfo.getY();
-                    }
-                    if (graphicInfo.getY() < minY) {
-                        minY = graphicInfo.getY();
-                    }
-                }
-            }
-        }
-
-        int nrOfLanes = 0;
-        for (Process process : bpmnModel.getProcesses()) {
-            for (Lane l : process.getLanes()) {
-
-                nrOfLanes++;
-
-                GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(l.getId());
-                // // width
-                if (graphicInfo.getX() + graphicInfo.getWidth() > maxX) {
-                    maxX = graphicInfo.getX() + graphicInfo.getWidth();
-                }
-                if (graphicInfo.getX() < minX) {
-                    minX = graphicInfo.getX();
-                }
-                // height
-                if (graphicInfo.getY() + graphicInfo.getHeight() > maxY) {
-                    maxY = graphicInfo.getY() + graphicInfo.getHeight();
-                }
-                if (graphicInfo.getY() < minY) {
-                    minY = graphicInfo.getY();
-                }
-            }
-        }
-
-        // Special case, see https://activiti.atlassian.net/browse/ACT-1431
-        if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
-            // Nothing to show
-            minX = 0;
-            minY = 0;
-        }
-
-        return new CustomDefaultProcessDiagramCanvas((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY,
-            imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
-    }
-
-    protected static List<Artifact> gatherAllArtifacts(BpmnModel bpmnModel) {
-        List<Artifact> artifacts = new ArrayList<>();
-        for (Process process : bpmnModel.getProcesses()) {
-            artifacts.addAll(process.getArtifacts());
-        }
-        return artifacts;
-    }
-
-    protected static List<FlowNode> gatherAllFlowNodes(BpmnModel bpmnModel) {
-        List<FlowNode> flowNodes = new ArrayList<>();
-        for (Process process : bpmnModel.getProcesses()) {
-            flowNodes.addAll(gatherAllFlowNodes(process));
-        }
-        return flowNodes;
-    }
-
-    protected static List<FlowNode> gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) {
-        List<FlowNode> flowNodes = new ArrayList<>();
-        for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
-            if (flowElement instanceof FlowNode) {
-                flowNodes.add((FlowNode) flowElement);
-            }
-            if (flowElement instanceof FlowElementsContainer) {
-                flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement));
-            }
-        }
-        return flowNodes;
-    }
-
-    protected boolean isPartOfCollapsedSubProcess(FlowElement flowElement, BpmnModel model) {
-        SubProcess subProcess = flowElement.getSubProcess();
-        if (subProcess != null) {
-            GraphicInfo graphicInfo = model.getGraphicInfo(subProcess.getId());
-            if (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
-                return true;
-            }
-
-            return isPartOfCollapsedSubProcess(subProcess, model);
-        }
-
-        return false;
-    }
-
-    public Map<Class<? extends BaseElement>, ActivityDrawInstruction> getActivityDrawInstructions() {
-        return activityDrawInstructions;
-    }
-
-    public void setActivityDrawInstructions(
-        Map<Class<? extends BaseElement>, ActivityDrawInstruction> activityDrawInstructions) {
-        this.activityDrawInstructions = activityDrawInstructions;
-    }
-
-    public Map<Class<? extends BaseElement>, ArtifactDrawInstruction> getArtifactDrawInstructions() {
-        return artifactDrawInstructions;
-    }
-
-    public void setArtifactDrawInstructions(
-        Map<Class<? extends BaseElement>, ArtifactDrawInstruction> artifactDrawInstructions) {
-        this.artifactDrawInstructions = artifactDrawInstructions;
-    }
-
-    protected interface ActivityDrawInstruction {
-        void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode);
-    }
-
-    protected interface ArtifactDrawInstruction {
-        void draw(CustomDefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AddSequenceMultiInstanceCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AddSequenceMultiInstanceCmd.java
deleted file mode 100644
index 3cdfcf4..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AddSequenceMultiInstanceCmd.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import cn.hutool.core.collection.CollUtil;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.dromara.workflow.common.constant.FlowConstant.NUMBER_OF_INSTANCES;
-
-/**
- * 涓茶鍔犵
- *
- * @author may
- */
-public class AddSequenceMultiInstanceCmd implements Command<Void> {
-
-    /**
-     * 鎵цid
-     */
-    private final String executionId;
-
-    /**
-     * 浼氱浜哄憳闆嗗悎KEY
-     */
-    private final String assigneeList;
-
-    /**
-     * 鍔犵浜哄憳
-     */
-    private final List<Long> assignees;
-
-    public AddSequenceMultiInstanceCmd(String executionId, String assigneeList, List<Long> assignees) {
-        this.executionId = executionId;
-        this.assigneeList = assigneeList;
-        this.assignees = assignees;
-    }
-
-    @Override
-    public Void execute(CommandContext commandContext) {
-        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
-        ExecutionEntity entity = executionEntityManager.findById(executionId);
-        // 澶氬疄渚嬩换鍔℃�绘暟鍔� assignees.size()
-        if (entity.getVariable(NUMBER_OF_INSTANCES) instanceof Integer nrOfInstances) {
-            entity.setVariable(NUMBER_OF_INSTANCES, nrOfInstances + assignees.size());
-        }
-        // 璁剧疆娴佺▼鍙橀噺
-        if (entity.getVariable(assigneeList) instanceof List<?> userIds) {
-            CollUtil.addAll(userIds, assignees);
-            Map<String, Object> variables = new HashMap<>(16);
-            variables.put(assigneeList, userIds);
-            entity.setVariables(variables);
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AttachmentCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AttachmentCmd.java
deleted file mode 100644
index 20a0a5f..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/AttachmentCmd.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import cn.hutool.core.collection.CollUtil;
-import org.dromara.common.core.domain.dto.OssDTO;
-import org.dromara.common.core.service.OssService;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.AttachmentEntity;
-import org.flowable.engine.impl.persistence.entity.AttachmentEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * 闄勪欢涓婁紶
- *
- * @author may
- */
-public class AttachmentCmd implements Command<Boolean> {
-
-    private final String fileId;
-
-    private final String taskId;
-
-    private final String processInstanceId;
-
-    private final OssService ossService;
-
-    public AttachmentCmd(String fileId, String taskId, String processInstanceId, OssService ossService) {
-        this.fileId = fileId;
-        this.taskId = taskId;
-        this.processInstanceId = processInstanceId;
-        this.ossService = ossService;
-    }
-
-    @Override
-    public Boolean execute(CommandContext commandContext) {
-        try {
-            if (StringUtils.isNotBlank(fileId)) {
-                List<OssDTO> ossList = ossService.selectByIds(fileId);
-                if (CollUtil.isNotEmpty(ossList)) {
-                    for (OssDTO oss : ossList) {
-                        AttachmentEntityManager attachmentEntityManager = CommandContextUtil.getAttachmentEntityManager();
-                        AttachmentEntity attachmentEntity = attachmentEntityManager.create();
-                        attachmentEntity.setRevision(1);
-                        attachmentEntity.setUserId(LoginHelper.getUserId().toString());
-                        attachmentEntity.setName(oss.getOriginalName());
-                        attachmentEntity.setDescription(oss.getOriginalName());
-                        attachmentEntity.setType(oss.getFileSuffix());
-                        attachmentEntity.setTaskId(taskId);
-                        attachmentEntity.setProcessInstanceId(processInstanceId);
-                        attachmentEntity.setContentId(oss.getOssId().toString());
-                        attachmentEntity.setTime(new Date());
-                        attachmentEntityManager.insert(attachmentEntity);
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        return true;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteExecutionCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteExecutionCmd.java
deleted file mode 100644
index 215d310..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteExecutionCmd.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-import java.io.Serializable;
-
-/**
- * 鍒犻櫎鎵ц鏁版嵁
- *
- * @author may
- */
-public class DeleteExecutionCmd implements Command<Void>, Serializable {
-
-    /**
-     * 鎵цid
-     */
-    private final String executionId;
-
-    public DeleteExecutionCmd(String executionId) {
-        this.executionId = executionId;
-    }
-
-    @Override
-    public Void execute(CommandContext commandContext) {
-        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
-        ExecutionEntity entity = executionEntityManager.findById(executionId);
-        if (entity != null) {
-            executionEntityManager.deleteExecutionAndRelatedData(entity, "", false, false);
-        }
-        return null;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteSequenceMultiInstanceCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteSequenceMultiInstanceCmd.java
deleted file mode 100644
index a61daeb..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/DeleteSequenceMultiInstanceCmd.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import cn.hutool.core.util.ObjectUtil;
-import lombok.AllArgsConstructor;
-import org.dromara.common.core.utils.StreamUtils;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.dromara.workflow.common.constant.FlowConstant.LOOP_COUNTER;
-import static org.dromara.workflow.common.constant.FlowConstant.NUMBER_OF_INSTANCES;
-
-
-/**
- * 涓茶鍑忕
- *
- * @author may
- */
-@AllArgsConstructor
-public class DeleteSequenceMultiInstanceCmd implements Command<Void> {
-
-    /**
-     * 褰撳墠鑺傜偣瀹℃壒浜哄憳id
-     */
-    private final String currentUserId;
-
-    /**
-     * 鎵цid
-     */
-    private final String executionId;
-
-    /**
-     * 浼氱浜哄憳闆嗗悎KEY
-     */
-    private final String assigneeList;
-
-    /**
-     * 鍑忕浜哄憳
-     */
-    private final List<Long> assignees;
-
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public Void execute(CommandContext commandContext) {
-        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
-        ExecutionEntity entity = executionEntityManager.findById(executionId);
-        // 璁剧疆娴佺▼鍙橀噺
-        List<Long> userIds = new ArrayList<>();
-        List<Object> variable = (List<Object>) entity.getVariable(assigneeList);
-        for (Object o : variable) {
-            userIds.add(Long.valueOf(o.toString()));
-        }
-        List<Long> userIdList = new ArrayList<>();
-        userIds.forEach(e -> {
-            Long userId = StreamUtils.findFirst(assignees, id -> ObjectUtil.equals(id, e));
-            if (userId == null) {
-                userIdList.add(e);
-            }
-        });
-        // 褰撳墠浠诲姟鎵ц浣嶇疆
-        int loopCounterIndex = -1;
-        for (int i = 0; i < userIdList.size(); i++) {
-            Long userId = userIdList.get(i);
-            if (currentUserId.equals(userId.toString())) {
-                loopCounterIndex = i;
-            }
-        }
-        Map<String, Object> variables = new HashMap<>(16);
-        variables.put(NUMBER_OF_INSTANCES, userIdList.size());
-        variables.put(assigneeList, userIdList);
-        variables.put(LOOP_COUNTER, loopCounterIndex);
-        entity.setVariables(variables);
-        return null;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/ExecutionChildByExecutionIdCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/ExecutionChildByExecutionIdCmd.java
deleted file mode 100644
index 1f3088b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/ExecutionChildByExecutionIdCmd.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import org.dromara.common.core.utils.StreamUtils;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 鑾峰彇骞惰缃戝叧鎵ц鍚庝繚鐣欑殑鎵ц瀹炰緥鏁版嵁
- *
- * @author may
- */
-public class ExecutionChildByExecutionIdCmd implements Command<List<ExecutionEntity>>, Serializable {
-
-    /**
-     * 褰撳墠浠诲姟鎵ц瀹炰緥id
-     */
-    private final String executionId;
-
-    public ExecutionChildByExecutionIdCmd(String executionId) {
-        this.executionId = executionId;
-    }
-
-    @Override
-    public List<ExecutionEntity> execute(CommandContext commandContext) {
-        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager();
-        // 鑾峰彇褰撳墠鎵ц鏁版嵁
-        ExecutionEntity executionEntity = executionEntityManager.findById(executionId);
-        // 閫氳繃褰撳墠鎵ц鏁版嵁鐨勭埗鎵ц锛屾煡璇㈡墍鏈夊瓙鎵ц鏁版嵁
-        List<ExecutionEntity> allChildrenExecution =
-            executionEntityManager.collectChildren(executionEntity.getParent());
-        return StreamUtils.filter(allChildrenExecution, e -> !e.isActive());
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateBusinessStatusCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateBusinessStatusCmd.java
deleted file mode 100644
index 3ba120a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateBusinessStatusCmd.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import org.dromara.common.core.exception.ServiceException;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
-import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntityManager;
-import org.flowable.engine.impl.util.CommandContextUtil;
-
-/**
- * 淇敼娴佺▼鐘舵��
- *
- * @author may
- */
-public class UpdateBusinessStatusCmd implements Command<Boolean> {
-
-    private final String processInstanceId;
-    private final String status;
-
-    public UpdateBusinessStatusCmd(String processInstanceId, String status) {
-        this.processInstanceId = processInstanceId;
-        this.status = status;
-    }
-
-    @Override
-    public Boolean execute(CommandContext commandContext) {
-        try {
-            HistoricProcessInstanceEntityManager manager = CommandContextUtil.getHistoricProcessInstanceEntityManager();
-            HistoricProcessInstanceEntity processInstance = manager.findById(processInstanceId);
-            processInstance.setBusinessStatus(status);
-            manager.update(processInstance);
-            return true;
-        } catch (Exception e) {
-            throw new ServiceException(e.getMessage());
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateHiTaskInstCmd.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateHiTaskInstCmd.java
deleted file mode 100644
index 42f6d1c..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/cmd/UpdateHiTaskInstCmd.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.dromara.workflow.flowable.cmd;
-
-import org.dromara.common.core.exception.ServiceException;
-import org.flowable.common.engine.impl.interceptor.Command;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.impl.util.CommandContextUtil;
-import org.flowable.task.service.HistoricTaskService;
-import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
-
-import java.util.Date;
-import java.util.List;
-
-
-/**
- * 淇敼娴佺▼鍘嗗彶
- *
- * @author may
- */
-public class UpdateHiTaskInstCmd implements Command<Boolean> {
-
-    private final List<String> taskIds;
-
-    private final String processDefinitionId;
-
-    private final String processInstanceId;
-
-    public UpdateHiTaskInstCmd(List<String> taskIds, String processDefinitionId, String processInstanceId) {
-        this.taskIds = taskIds;
-        this.processDefinitionId = processDefinitionId;
-        this.processInstanceId = processInstanceId;
-    }
-
-    @Override
-    public Boolean execute(CommandContext commandContext) {
-        try {
-            HistoricTaskService historicTaskService = CommandContextUtil.getHistoricTaskService();
-            for (String taskId : taskIds) {
-                HistoricTaskInstanceEntity historicTask = historicTaskService.getHistoricTask(taskId);
-                if (historicTask != null) {
-                    historicTask.setProcessDefinitionId(processDefinitionId);
-                    historicTask.setProcessInstanceId(processInstanceId);
-                    historicTask.setCreateTime(new Date());
-                    CommandContextUtil.getHistoricTaskService().updateHistoricTask(historicTask, true);
-                }
-            }
-            return true;
-        } catch (Exception e) {
-            throw new ServiceException(e.getMessage());
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/FlowableConfig.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/FlowableConfig.java
deleted file mode 100644
index 1494bf3..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/FlowableConfig.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.dromara.workflow.flowable.config;
-
-import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
-import org.dromara.workflow.flowable.handler.TaskTimeoutJobHandler;
-import org.flowable.spring.SpringProcessEngineConfiguration;
-import org.flowable.spring.boot.EngineConfigurationConfigurer;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.Collections;
-
-
-/**
- * flowable閰嶇疆
- *
- * @author may
- */
-@Configuration
-public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
-
-    @Autowired
-    private GlobalFlowableListener globalFlowableListener;
-    @Autowired
-    private IdentifierGenerator identifierGenerator;
-
-    @Override
-    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
-        processEngineConfiguration.setIdGenerator(() -> identifierGenerator.nextId(null).toString());
-        processEngineConfiguration.setEventListeners(Collections.singletonList(globalFlowableListener));
-        processEngineConfiguration.addCustomJobHandler(new TaskTimeoutJobHandler());
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/GlobalFlowableListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/GlobalFlowableListener.java
deleted file mode 100644
index 9bb971a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/config/GlobalFlowableListener.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.dromara.workflow.flowable.config;
-
-import cn.hutool.core.collection.CollUtil;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.flowable.handler.TaskTimeoutJobHandler;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.bpmn.model.BoundaryEvent;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.FlowElement;
-import org.flowable.common.engine.api.delegate.event.*;
-import org.flowable.common.engine.impl.cfg.TransactionState;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.RuntimeService;
-import org.flowable.engine.TaskService;
-import org.flowable.engine.impl.util.CommandContextUtil;
-import org.flowable.engine.runtime.Execution;
-import org.flowable.engine.task.Comment;
-import org.flowable.job.service.TimerJobService;
-import org.flowable.job.service.impl.persistence.entity.JobEntity;
-import org.flowable.job.service.impl.persistence.entity.TimerJobEntity;
-import org.flowable.task.api.Task;
-import org.flowable.task.service.impl.persistence.entity.TaskEntity;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-import java.util.List;
-
-
-/**
- * 寮曟搸璋冨害鐩戝惉
- *
- * @author may
- */
-@Component
-public class GlobalFlowableListener implements FlowableEventListener {
-
-    @Autowired
-    @Lazy
-    private TaskService taskService;
-
-    @Autowired
-    @Lazy
-    private RuntimeService runtimeService;
-
-    @Autowired
-    @Lazy
-    private RepositoryService repositoryService;
-
-    @Value("${flowable.async-executor-activate}")
-    private boolean asyncExecutorActivate;
-
-    @Override
-    public void onEvent(FlowableEvent flowableEvent) {
-        if (flowableEvent instanceof FlowableEngineEvent flowableEngineEvent) {
-            FlowableEngineEventType engineEventType = (FlowableEngineEventType) flowableEvent.getType();
-            switch (engineEventType) {
-                case JOB_EXECUTION_SUCCESS -> jobExecutionSuccess((FlowableEngineEntityEvent) flowableEngineEvent);
-                case TASK_DUEDATE_CHANGED, TASK_CREATED -> {
-                    FlowableEntityEvent flowableEntityEvent = (FlowableEntityEvent) flowableEngineEvent;
-                    Object entityObject = flowableEntityEvent.getEntity();
-                    TaskEntity task = (TaskEntity) entityObject;
-                    if (asyncExecutorActivate && task.getDueDate() != null && task.getDueDate().after(new Date())) {
-                        //鍒犻櫎涔嬪墠宸茬粡瀛樺湪鐨勫畾鏃朵换鍔�
-                        TimerJobService timerJobService = CommandContextUtil.getTimerJobService();
-                        List<TimerJobEntity> timerJobEntityList = timerJobService.findTimerJobsByProcessInstanceId(task.getProcessInstanceId());
-                        if (!CollUtil.isEmpty(timerJobEntityList)) {
-                            for (TimerJobEntity timerJobEntity : timerJobEntityList) {
-                                String taskId = timerJobEntity.getJobHandlerConfiguration();
-                                if (task.getId().equals(taskId)) {
-                                    timerJobService.deleteTimerJob(timerJobEntity);
-                                }
-                            }
-                        }
-                        //鍒涘缓job瀵硅薄
-                        TimerJobEntity timer = timerJobService.createTimerJob();
-                        timer.setTenantId(TenantHelper.getTenantId());
-                        //璁剧疆job绫诲瀷
-                        timer.setJobType(JobEntity.JOB_TYPE_TIMER);
-                        timer.setJobHandlerType(TaskTimeoutJobHandler.TYPE);
-                        timer.setDuedate(task.getDueDate());
-                        timer.setProcessInstanceId(task.getProcessInstanceId());
-                        //璁剧疆浠诲姟id
-                        timer.setJobHandlerConfiguration(task.getId());
-                        //淇濆瓨骞惰Е鍙戜簨浠�
-                        timerJobService.scheduleTimerJob(timer);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean isFailOnException() {
-        return true;
-    }
-
-    @Override
-    public boolean isFireOnTransactionLifecycleEvent() {
-        return false;
-    }
-
-    @Override
-    public String getOnTransaction() {
-        return TransactionState.COMMITTED.name();
-    }
-
-    /**
-     * 澶勭悊杈圭晫瀹氭椂浜嬩欢鑷姩瀹℃壒璁板綍
-     *
-     * @param event 浜嬩欢
-     */
-    protected void jobExecutionSuccess(FlowableEngineEntityEvent event) {
-        if (event != null && StringUtils.isNotBlank(event.getExecutionId())) {
-            Execution execution = runtimeService.createExecutionQuery().executionId(event.getExecutionId()).singleResult();
-            if (execution != null) {
-                BpmnModel bpmnModel = repositoryService.getBpmnModel(event.getProcessDefinitionId());
-                FlowElement flowElement = bpmnModel.getFlowElement(execution.getActivityId());
-                if (flowElement instanceof BoundaryEvent) {
-                    String attachedToRefId = ((BoundaryEvent) flowElement).getAttachedToRefId();
-                    List<Execution> list = runtimeService.createExecutionQuery().activityId(attachedToRefId).list();
-                    for (Execution ex : list) {
-                        Task task = QueryUtils.taskQuery().executionId(ex.getId()).singleResult();
-                        if (task != null) {
-                            List<Comment> taskComments = taskService.getTaskComments(task.getId());
-                            if (CollUtil.isEmpty(taskComments)) {
-                                taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), "瓒呮椂鑷姩瀹℃壒!");
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/FlowProcessEventHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/FlowProcessEventHandler.java
deleted file mode 100644
index 69ae70a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/FlowProcessEventHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.dromara.workflow.flowable.handler;
-
-import org.dromara.common.core.domain.event.ProcessEvent;
-import org.dromara.common.core.domain.event.ProcessTaskEvent;
-import org.dromara.common.core.utils.SpringUtils;
-import org.springframework.stereotype.Component;
-
-/**
- * 娴佺▼鐩戝惉鏈嶅姟
- *
- * @author may
- * @date 2024-06-02
- */
-@Component
-public class FlowProcessEventHandler {
-
-    /**
-     * 鎬讳綋娴佺▼鐩戝惉(渚嬪: 鎻愪氦 閫�鍥� 鎾ら攢 缁堟 浣滃簾绛�)
-     *
-     * @param key         娴佺▼key
-     * @param businessKey 涓氬姟id
-     * @param status      鐘舵��
-     * @param submit      褰撲负true鏃朵负鐢宠浜鸿妭鐐瑰姙鐞�
-     */
-    public void processHandler(String key, String businessKey, String status, boolean submit) {
-        ProcessEvent processEvent = new ProcessEvent();
-        processEvent.setKey(key);
-        processEvent.setBusinessKey(businessKey);
-        processEvent.setStatus(status);
-        processEvent.setSubmit(submit);
-        SpringUtils.context().publishEvent(processEvent);
-    }
-
-    /**
-     * 鎵ц鍔炵悊浠诲姟鐩戝惉
-     *
-     * @param key               娴佺▼key
-     * @param taskDefinitionKey 瀹℃壒鑺傜偣key
-     * @param taskId            浠诲姟id
-     * @param businessKey       涓氬姟id
-     */
-    public void processTaskHandler(String key, String taskDefinitionKey, String taskId, String businessKey) {
-        ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
-        processTaskEvent.setKey(key);
-        processTaskEvent.setTaskDefinitionKey(taskDefinitionKey);
-        processTaskEvent.setTaskId(taskId);
-        processTaskEvent.setBusinessKey(businessKey);
-        SpringUtils.context().publishEvent(processTaskEvent);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/TaskTimeoutJobHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/TaskTimeoutJobHandler.java
deleted file mode 100644
index 61c9388..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/TaskTimeoutJobHandler.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.dromara.workflow.flowable.handler;
-
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.flowable.common.engine.impl.interceptor.CommandContext;
-import org.flowable.engine.TaskService;
-import org.flowable.engine.impl.jobexecutor.TimerEventHandler;
-import org.flowable.engine.impl.util.CommandContextUtil;
-import org.flowable.job.service.JobHandler;
-import org.flowable.job.service.impl.persistence.entity.JobEntity;
-import org.flowable.task.api.Task;
-import org.flowable.variable.api.delegate.VariableScope;
-
-/**
- * 鍔炵悊瓒呮椂(杩囨湡)浠诲姟
- *
- * @author may
- */
-public class TaskTimeoutJobHandler extends TimerEventHandler implements JobHandler {
-
-    public static final String TYPE = "taskTimeout";
-
-    @Override
-    public String getType() {
-        return TYPE;
-    }
-
-    @Override
-    public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
-        TaskService taskService = CommandContextUtil.getProcessEngineConfiguration(commandContext)
-            .getTaskService();
-        Task task = taskService.createTaskQuery().taskId(configuration).singleResult();
-        if (task != null) {
-            taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.TIMEOUT.getStatus(), "瓒呮椂鑷姩瀹℃壒!");
-            taskService.complete(configuration);
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java
new file mode 100644
index 0000000..9bac6bc
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/FlowProcessEventHandler.java
@@ -0,0 +1,77 @@
+package org.dromara.workflow.handler;
+
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.event.ProcessDeleteEvent;
+import org.dromara.common.core.domain.event.ProcessEvent;
+import org.dromara.common.core.domain.event.ProcessTaskEvent;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.springframework.stereotype.Component;
+
+/**
+ * 娴佺▼鐩戝惉鏈嶅姟
+ *
+ * @author may
+ * @date 2024-06-02
+ */
+@Slf4j
+@Component
+public class FlowProcessEventHandler {
+
+    /**
+     * 鎬讳綋娴佺▼鐩戝惉(渚嬪: 鑽夌锛屾挙閿�锛岄��鍥烇紝浣滃簾锛岀粓姝紝宸插畬鎴愮瓑)
+     *
+     * @param flowCode   娴佺▼瀹氫箟缂栫爜
+     * @param businessId 涓氬姟id
+     * @param status     鐘舵��
+     * @param submit     褰撲负true鏃朵负鐢宠浜鸿妭鐐瑰姙鐞�
+     */
+    public void processHandler(String flowCode, String businessId, String status, boolean submit) {
+        String tenantId = TenantHelper.getTenantId();
+        log.info("鍙戝竷娴佺▼浜嬩欢锛岀鎴稩D: {}, 娴佺▼鐘舵��: {}, 娴佺▼缂栫爜: {}, 涓氬姟ID: {}, 鏄惁鐢宠浜鸿妭鐐瑰姙鐞�: {}", tenantId, status, flowCode, businessId, submit);
+        ProcessEvent processEvent = new ProcessEvent();
+        processEvent.setTenantId(tenantId);
+        processEvent.setFlowCode(flowCode);
+        processEvent.setBusinessId(businessId);
+        processEvent.setStatus(status);
+        processEvent.setSubmit(submit);
+        SpringUtils.context().publishEvent(processEvent);
+    }
+
+    /**
+     * 鎵ц鍔炵悊浠诲姟鐩戝惉
+     *
+     * @param flowCode   娴佺▼瀹氫箟缂栫爜
+     * @param nodeCode   瀹℃壒鑺傜偣缂栫爜
+     * @param taskId     浠诲姟id
+     * @param businessId 涓氬姟id
+     */
+    public void processTaskHandler(String flowCode, String nodeCode, Long taskId, String businessId) {
+        String tenantId = TenantHelper.getTenantId();
+        log.info("鍙戝竷娴佺▼浠诲姟浜嬩欢, 绉熸埛ID: {}, 娴佺▼缂栫爜: {}, 鑺傜偣缂栫爜: {}, 浠诲姟ID: {}, 涓氬姟ID: {}", tenantId, flowCode, nodeCode, taskId, businessId);
+        ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
+        processTaskEvent.setTenantId(tenantId);
+        processTaskEvent.setFlowCode(flowCode);
+        processTaskEvent.setNodeCode(nodeCode);
+        processTaskEvent.setTaskId(taskId);
+        processTaskEvent.setBusinessId(businessId);
+        SpringUtils.context().publishEvent(processTaskEvent);
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼鐩戝惉
+     *
+     * @param flowCode    娴佺▼瀹氫箟缂栫爜
+     * @param businessId  涓氬姟ID
+     */
+    public void processDeleteHandler(String flowCode, String businessId) {
+        String tenantId = TenantHelper.getTenantId();
+        log.info("鍙戝竷鍒犻櫎娴佺▼浜嬩欢, 绉熸埛ID: {}, 娴佺▼缂栫爜: {}, 涓氬姟ID: {}", tenantId, flowCode, businessId);
+        ProcessDeleteEvent processDeleteEvent = new ProcessDeleteEvent();
+        processDeleteEvent.setTenantId(tenantId);
+        processDeleteEvent.setFlowCode(flowCode);
+        processDeleteEvent.setBusinessId(businessId);
+        SpringUtils.context().publishEvent(processDeleteEvent);
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java
new file mode 100644
index 0000000..a58709a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/handler/WorkflowPermissionHandler.java
@@ -0,0 +1,71 @@
+package org.dromara.workflow.handler;
+
+import cn.hutool.core.util.ObjectUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.workflow.common.enums.TaskAssigneeEnum;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.warm.flow.core.dto.FlowParams;
+import org.dromara.warm.flow.core.handler.PermissionHandler;
+import org.dromara.warm.flow.core.service.impl.TaskServiceImpl;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 鍔炵悊浜烘潈闄愬鐞嗗櫒
+ *
+ * @author AprilWind
+ */
+@RequiredArgsConstructor
+@Component
+@Slf4j
+public class WorkflowPermissionHandler implements PermissionHandler {
+
+    /**
+     * 瀹℃壒鍓嶈幏鍙栧綋鍓嶅姙鐞嗕汉锛屽姙鐞嗘椂浼氭牎楠岀殑璇ユ潈闄愰泦鍚�
+     * 鍚庣画鍦▄@link TaskServiceImpl#checkAuth(Task, FlowParams)} 涓皟鐢�
+     * 杩斿洖褰撳墠鐢ㄦ埛鏉冮檺闆嗗悎
+     */
+    @Override
+    public List<String> permissions() {
+        LoginUser loginUser = LoginHelper.getLoginUser();
+        if (ObjectUtil.isNull(loginUser)) {
+            return new ArrayList<>();
+        }
+        // 浣跨敤涓�涓祦鏉ユ瀯寤烘潈闄愬垪琛�
+        return Stream.of(
+                // 瑙掕壊鏉冮檺鍓嶇紑
+                loginUser.getRoles().stream()
+                    .map(role -> TaskAssigneeEnum.ROLE.getCode() + role.getRoleId()),
+
+                // 宀椾綅鏉冮檺鍓嶇紑
+                Stream.ofNullable(loginUser.getPosts())
+                    .flatMap(Collection::stream)
+                    .map(post -> TaskAssigneeEnum.POST.getCode() + post.getPostId()),
+
+                // 鐢ㄦ埛鍜岄儴闂ㄦ潈闄�
+                Stream.of(String.valueOf(loginUser.getUserId()),
+                    TaskAssigneeEnum.DEPT.getCode() + loginUser.getDeptId()
+                )
+            )
+            .flatMap(stream -> stream)
+            .collect(Collectors.toList());
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鍔炵悊浜�
+     *
+     * @return 褰撳墠鍔炵悊浜�
+     */
+    @Override
+    public String getHandler() {
+        return LoginHelper.getUserIdStr();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java
new file mode 100644
index 0000000..29b8b72
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java
@@ -0,0 +1,115 @@
+package org.dromara.workflow.listener;
+
+import cn.hutool.core.collection.CollUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.enums.BusinessStatusEnum;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.warm.flow.core.entity.Definition;
+import org.dromara.warm.flow.core.entity.Instance;
+import org.dromara.warm.flow.core.entity.Task;
+import org.dromara.warm.flow.core.listener.GlobalListener;
+import org.dromara.warm.flow.core.listener.ListenerVariable;
+import org.dromara.warm.flow.orm.entity.FlowTask;
+import org.dromara.workflow.handler.FlowProcessEventHandler;
+import org.dromara.workflow.service.IFlwInstanceService;
+import org.dromara.workflow.service.IFlwTaskService;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 鍏ㄥ眬浠诲姟鍔炵悊鐩戝惉
+ *
+ * @author may
+ */
+@Component
+@Slf4j
+@RequiredArgsConstructor
+public class WorkflowGlobalListener implements GlobalListener {
+
+    private final IFlwTaskService taskService;
+    private final IFlwInstanceService instanceService;
+    private final FlowProcessEventHandler flowProcessEventHandler;
+
+    /**
+     * 鍒涘缓鐩戝惉鍣紝浠诲姟鍒涘缓鏃舵墽琛�
+     *
+     * @param listenerVariable 鐩戝惉鍣ㄥ彉閲�
+     */
+    @Override
+    public void create(ListenerVariable listenerVariable) {
+        Instance instance = listenerVariable.getInstance();
+        Definition definition = listenerVariable.getDefinition();
+        String businessId = instance.getBusinessId();
+        String flowStatus = instance.getFlowStatus();
+        Task task = listenerVariable.getTask();
+        if (task != null && BusinessStatusEnum.WAITING.getStatus().equals(flowStatus)) {
+            // 鍒ゆ柇娴佺▼鐘舵�侊紙鍙戝竷瀹℃壒涓簨浠讹級
+            flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), task.getNodeCode(), task.getId(), businessId);
+        }
+    }
+
+    /**
+     * 寮�濮嬬洃鍚櫒锛屼换鍔″紑濮嬪姙鐞嗘椂鎵ц
+     *
+     * @param listenerVariable 鐩戝惉鍣ㄥ彉閲�
+     */
+    @Override
+    public void start(ListenerVariable listenerVariable) {
+    }
+
+    /**
+     * 鍒嗘淳鐩戝惉鍣紝鍔ㄦ�佷慨鏀逛唬鍔炰换鍔′俊鎭�
+     *
+     * @param listenerVariable 鐩戝惉鍣ㄥ彉閲�
+     */
+    @Override
+    public void assignment(ListenerVariable listenerVariable) {
+    }
+
+    /**
+     * 瀹屾垚鐩戝惉鍣紝褰撳墠浠诲姟瀹屾垚鍚庢墽琛�
+     *
+     * @param listenerVariable 鐩戝惉鍣ㄥ彉閲�
+     */
+    @Override
+    public void finish(ListenerVariable listenerVariable) {
+        Instance instance = listenerVariable.getInstance();
+        Definition definition = listenerVariable.getDefinition();
+        String businessId = instance.getBusinessId();
+        String flowStatus = instance.getFlowStatus();
+        // 鍒ゆ柇娴佺▼鐘舵�侊紙鍙戝竷锛氭挙閿�锛岄��鍥烇紝浣滃簾锛岀粓姝紝宸插畬鎴愪簨浠讹級
+        String status = determineFlowStatus(instance, flowStatus);
+        if (StringUtils.isNotBlank(status)) {
+            flowProcessEventHandler.processHandler(definition.getFlowCode(), businessId, status, false);
+        }
+    }
+
+    /**
+     * 鏍规嵁娴佺▼瀹炰緥鍜屽綋鍓嶆祦绋嬬姸鎬佺‘瀹氭渶缁堢姸鎬�
+     *
+     * @param instance   娴佺▼瀹炰緥
+     * @param flowStatus 娴佺▼瀹炰緥褰撳墠鐘舵��
+     * @return 娴佺▼鏈�缁堢姸鎬�
+     */
+    private String determineFlowStatus(Instance instance, String flowStatus) {
+        if (StringUtils.isNotBlank(flowStatus) && BusinessStatusEnum.initialState(flowStatus)) {
+            log.info("娴佺▼瀹炰緥褰撳墠鐘舵��: {}", flowStatus);
+            return flowStatus;
+        } else {
+            Long instanceId = instance.getId();
+            List<FlowTask> flowTasks = taskService.selectByInstId(instanceId);
+            if (CollUtil.isEmpty(flowTasks)) {
+                String status = BusinessStatusEnum.FINISH.getStatus();
+                // 鏇存柊娴佺▼鐘舵�佷负宸插畬鎴�
+                instanceService.updateStatus(instanceId, status);
+                log.info("娴佺▼宸茬粨鏉燂紝鐘舵�佹洿鏂颁负: {}", status);
+                return status;
+            }
+            log.warn("娴佺▼鏈粨鏉燂紝瀹炰緥ID: {}", instanceId);
+            return null;
+        }
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiProcinstMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiProcinstMapper.java
deleted file mode 100644
index a3a41c9..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiProcinstMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-import org.dromara.workflow.domain.ActHiProcinst;
-
-/**
- * 娴佺▼瀹炰緥Mapper鎺ュ彛
- *
- * @author may
- * @date 2023-07-22
- */
-@InterceptorIgnore(tenantLine = "true")
-public interface ActHiProcinstMapper extends BaseMapperPlus<ActHiProcinst, ActHiProcinst> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiTaskinstMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiTaskinstMapper.java
deleted file mode 100644
index 63b394b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActHiTaskinstMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import org.dromara.workflow.domain.ActHiTaskinst;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 娴佺▼鍘嗗彶浠诲姟Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-02
- */
-@InterceptorIgnore(tenantLine = "true")
-public interface ActHiTaskinstMapper extends BaseMapperPlus<ActHiTaskinst, ActHiTaskinst> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActTaskMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActTaskMapper.java
deleted file mode 100644
index 63c5ecb..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/ActTaskMapper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Constants;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import org.apache.ibatis.annotations.Param;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-import org.dromara.workflow.domain.vo.TaskVo;
-
-
-/**
- * 浠诲姟淇℃伅Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-02
- */
-@InterceptorIgnore(tenantLine = "true")
-public interface ActTaskMapper extends BaseMapperPlus<TaskVo, TaskVo> {
-    /**
-     * 鑾峰彇寰呭姙淇℃伅
-     *
-     * @param page         鍒嗛〉
-     * @param queryWrapper 鏉′欢
-     * @return 缁撴灉
-     */
-    Page<TaskVo> getTaskWaitByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) Wrapper<TaskVo> queryWrapper);
-
-    /**
-     * 鑾峰彇宸插姙
-     *
-     * @param page         鍒嗛〉
-     * @param queryWrapper 鏉′欢
-     * @return 缁撴灉
-     */
-    Page<TaskVo> getTaskFinishByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) Wrapper<TaskVo> queryWrapper);
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
-     *
-     * @param page         鍒嗛〉
-     * @param queryWrapper 鏉′欢
-     * @return 缁撴灉
-     */
-    Page<TaskVo> getTaskCopyByPage(@Param("page") Page<TaskVo> page, @Param(Constants.WRAPPER) QueryWrapper<TaskVo> queryWrapper);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwCategoryMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwCategoryMapper.java
new file mode 100644
index 0000000..d2c0b3a
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwCategoryMapper.java
@@ -0,0 +1,60 @@
+package org.dromara.workflow.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.dromara.common.mybatis.annotation.DataColumn;
+import org.dromara.common.mybatis.annotation.DataPermission;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.workflow.domain.FlowCategory;
+import org.dromara.workflow.domain.vo.FlowCategoryVo;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 娴佺▼鍒嗙被Mapper鎺ュ彛
+ *
+ * @author may
+ * @date 2023-06-27
+ */
+public interface FlwCategoryMapper extends BaseMapperPlus<FlowCategory, FlowCategoryVo> {
+
+    /**
+     * 缁熻鎸囧畾娴佺▼鍒嗙被ID鐨勫垎绫绘暟閲�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 璇ユ祦绋嬪垎绫籌D鐨勫垎绫绘暟閲�
+     */
+    @DataPermission({
+        @DataColumn(key = "deptName", value = "createDept")
+    })
+    long countCategoryById(Long categoryId);
+
+    /**
+     * 鏍规嵁鐖舵祦绋嬪垎绫籌D鏌ヨ鍏舵墍鏈夊瓙娴佺▼鍒嗙被鐨勫垪琛�
+     *
+     * @param parentId 鐖舵祦绋嬪垎绫籌D
+     * @return 鍖呭惈瀛愭祦绋嬪垎绫荤殑鍒楄〃
+     */
+    default List<FlowCategory> selectListByParentId(Long parentId) {
+        return this.selectList(new LambdaQueryWrapper<FlowCategory>()
+            .select(FlowCategory::getCategoryId)
+            .apply(DataBaseHelper.findInSet(parentId, "ancestors")));
+    }
+
+    /**
+     * 鏍规嵁鐖舵祦绋嬪垎绫籌D鏌ヨ鍖呮嫭鐖禝D鍙婂叾鎵�鏈夊瓙娴佺▼鍒嗙被ID鐨勫垪琛�
+     *
+     * @param parentId 鐖舵祦绋嬪垎绫籌D
+     * @return 鍖呭惈鐖禝D鍜屽瓙娴佺▼鍒嗙被ID鐨勫垪琛�
+     */
+    default List<Long> selectCategoryIdsByParentId(Long parentId) {
+        return Stream.concat(
+            this.selectListByParentId(parentId).stream()
+                .map(FlowCategory::getCategoryId),
+            Stream.of(parentId)
+        ).collect(Collectors.toList());
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwInstanceMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwInstanceMapper.java
new file mode 100644
index 0000000..92809c8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwInstanceMapper.java
@@ -0,0 +1,27 @@
+package org.dromara.workflow.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.workflow.domain.bo.FlowInstanceBo;
+import org.dromara.workflow.domain.vo.FlowInstanceVo;
+
+/**
+ * 瀹炰緥淇℃伅Mapper鎺ュ彛
+ *
+ * @author may
+ * @date 2024-03-02
+ */
+public interface FlwInstanceMapper {
+
+    /**
+     * 娴佺▼瀹炰緥淇℃伅
+     *
+     * @param page         鍒嗛〉
+     * @param queryWrapper 鏉′欢
+     * @return 缁撴灉
+     */
+    Page<FlowInstanceVo> selectInstanceList(@Param("page") Page<FlowInstanceVo> page, @Param(Constants.WRAPPER) Wrapper<FlowInstanceBo> queryWrapper);
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwTaskMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwTaskMapper.java
new file mode 100644
index 0000000..fd86c82
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwTaskMapper.java
@@ -0,0 +1,57 @@
+package org.dromara.workflow.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.workflow.domain.bo.FlowTaskBo;
+import org.dromara.workflow.domain.vo.FlowHisTaskVo;
+import org.dromara.workflow.domain.vo.FlowTaskVo;
+
+import java.util.List;
+
+
+/**
+ * 浠诲姟淇℃伅Mapper鎺ュ彛
+ *
+ * @author may
+ * @date 2024-03-02
+ */
+public interface FlwTaskMapper {
+
+    /**
+     * 鑾峰彇寰呭姙淇℃伅
+     *
+     * @param page         鍒嗛〉
+     * @param queryWrapper 鏉′欢
+     * @return 缁撴灉
+     */
+    Page<FlowTaskVo> getListRunTask(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
+
+    /**
+     * 鑾峰彇寰呭姙淇℃伅
+     *
+     * @param queryWrapper 鏉′欢
+     * @return 缁撴灉
+     */
+    List<FlowTaskVo> getListRunTask(@Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
+
+    /**
+     * 鑾峰彇宸插姙
+     *
+     * @param page         鍒嗛〉
+     * @param queryWrapper 鏉′欢
+     * @return 缁撴灉
+     */
+    Page<FlowHisTaskVo> getListFinishTask(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
+     *
+     * @param page         鍒嗛〉
+     * @param queryWrapper 鏉′欢
+     * @return 缁撴灉
+     */
+    Page<FlowTaskVo> getTaskCopyByPage(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) QueryWrapper<FlowTaskBo> queryWrapper);
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfCategoryMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfCategoryMapper.java
deleted file mode 100644
index 98aea02..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfCategoryMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-import org.dromara.workflow.domain.WfCategory;
-import org.dromara.workflow.domain.vo.WfCategoryVo;
-
-/**
- * 娴佺▼鍒嗙被Mapper鎺ュ彛
- *
- * @author may
- * @date 2023-06-27
- */
-public interface WfCategoryMapper extends BaseMapperPlus<WfCategory, WfCategoryVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfDefinitionConfigMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfDefinitionConfigMapper.java
deleted file mode 100644
index ee20882..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfDefinitionConfigMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import org.dromara.workflow.domain.WfDefinitionConfig;
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-18
- */
-public interface WfDefinitionConfigMapper extends BaseMapperPlus<WfDefinitionConfig, WfDefinitionConfigVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfFormManageMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfFormManageMapper.java
deleted file mode 100644
index acf8111..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfFormManageMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import org.dromara.workflow.domain.WfFormManage;
-import org.dromara.workflow.domain.vo.WfFormManageVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 琛ㄥ崟绠$悊Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-29
- */
-public interface WfFormManageMapper extends BaseMapperPlus<WfFormManage, WfFormManageVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfNodeConfigMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfNodeConfigMapper.java
deleted file mode 100644
index d2aecac..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfNodeConfigMapper.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.workflow.domain.vo.WfNodeConfigVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-
-/**
- * 鑺傜偣閰嶇疆Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-30
- */
-public interface WfNodeConfigMapper extends BaseMapperPlus<WfNodeConfig, WfNodeConfigVo> {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfTaskBackNodeMapper.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfTaskBackNodeMapper.java
deleted file mode 100644
index 9b291fe..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/WfTaskBackNodeMapper.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.dromara.workflow.mapper;
-
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
-import org.dromara.workflow.domain.WfTaskBackNode;
-
-/**
- * 鑺傜偣椹冲洖璁板綍Mapper鎺ュ彛
- *
- * @author may
- * @date 2024-03-13
- */
-public interface WfTaskBackNodeMapper extends BaseMapperPlus<WfTaskBackNode, WfTaskBackNode> {
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiProcinstService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiProcinstService.java
deleted file mode 100644
index e802c69..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiProcinstService.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.dromara.workflow.service;
-
-
-import org.dromara.workflow.domain.ActHiProcinst;
-
-import java.util.List;
-
-/**
- * 娴佺▼瀹炰緥Service鎺ュ彛
- *
- * @author may
- * @date 2023-07-22
- */
-public interface IActHiProcinstService {
-
-    /**
-     * 鎸夌収涓氬姟id鏌ヨ
-     *
-     * @param businessKeys 涓氬姟id
-     * @return 缁撴灉
-     */
-    List<ActHiProcinst> selectByBusinessKeyIn(List<String> businessKeys);
-
-    /**
-     * 鎸夌収涓氬姟id鏌ヨ
-     *
-     * @param businessKey 涓氬姟id
-     * @return 缁撴灉
-     */
-    ActHiProcinst selectByBusinessKey(String businessKey);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiTaskinstService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiTaskinstService.java
deleted file mode 100644
index ad286e2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActHiTaskinstService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.dromara.workflow.service;
-
-
-/**
- * 娴佺▼鍘嗗彶浠诲姟Service鎺ュ彛
- *
- * @author may
- * @date 2024-03-02
- */
-public interface IActHiTaskinstService {
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActModelService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActModelService.java
deleted file mode 100644
index 4a6d170..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActModelService.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.dromara.workflow.service;
-
-import jakarta.servlet.http.HttpServletResponse;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.workflow.domain.bo.ModelBo;
-import org.dromara.workflow.domain.vo.ModelVo;
-import org.flowable.engine.repository.Model;
-
-import java.util.List;
-
-
-/**
- * 妯″瀷绠$悊 鏈嶅姟灞�
- *
- * @author may
- */
-public interface IActModelService {
-    /**
-     * 鍒嗛〉鏌ヨ妯″瀷
-     *
-     * @param modelBo   妯″瀷鍙傛暟
-     * @param pageQuery 鍙傛暟
-     * @return 杩斿洖鍒嗛〉鍒楄〃
-     */
-    TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery);
-
-    /**
-     * 鏂板妯″瀷
-     *
-     * @param modelBo 妯″瀷璇锋眰瀵硅薄
-     * @return 缁撴灉
-     */
-    boolean saveNewModel(ModelBo modelBo);
-
-    /**
-     * 鏌ヨ妯″瀷
-     *
-     * @param modelId 妯″瀷id
-     * @return 妯″瀷鏁版嵁
-     */
-    ModelVo getInfo(String modelId);
-
-    /**
-     * 淇敼妯″瀷淇℃伅
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    boolean update(ModelBo modelBo);
-
-    /**
-     * 缂栬緫妯″瀷XML
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    boolean editModelXml(ModelBo modelBo);
-
-    /**
-     * 妯″瀷閮ㄧ讲
-     *
-     * @param id 妯″瀷id
-     * @return 缁撴灉
-     */
-    boolean modelDeploy(String id);
-
-    /**
-     * 瀵煎嚭妯″瀷zip鍘嬬缉鍖�
-     *
-     * @param modelIds 妯″瀷id
-     * @param response 鍝嶅簲
-     */
-    void exportZip(List<String> modelIds, HttpServletResponse response);
-
-    /**
-     * 澶嶅埗妯″瀷
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    boolean copyModel(ModelBo modelBo);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessDefinitionService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessDefinitionService.java
deleted file mode 100644
index 5d00e41..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessDefinitionService.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.workflow.domain.bo.ProcessDefinitionBo;
-import org.dromara.workflow.domain.vo.ProcessDefinitionVo;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.util.List;
-
-/**
- * 娴佺▼瀹氫箟 鏈嶅姟灞�
- *
- * @author may
- */
-public interface IActProcessDefinitionService {
-    /**
-     * 鍒嗛〉鏌ヨ
-     *
-     * @param processDefinitionBo 鍙傛暟
-     * @param pageQuery           鍒嗛〉
-     * @return 杩斿洖鍒嗛〉鍒楄〃
-     */
-    TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo processDefinitionBo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ鍘嗗彶娴佺▼瀹氫箟鍒楄〃
-     *
-     * @param key 娴佺▼瀹氫箟key
-     * @return 缁撴灉
-     */
-    List<ProcessDefinitionVo> getListByKey(String key);
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟鍥剧墖
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    String definitionImage(String processDefinitionId);
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟xml鏂囦欢
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    String definitionXml(String processDefinitionId);
-
-    /**
-     * 鍒犻櫎娴佺▼瀹氫箟
-     *
-     * @param deploymentIds        閮ㄧ讲id
-     * @param processDefinitionIds 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    boolean deleteDeployment(List<String> deploymentIds, List<String> processDefinitionIds);
-
-    /**
-     * 婵�娲绘垨鑰呮寕璧锋祦绋嬪畾涔�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    boolean updateDefinitionState(String processDefinitionId);
-
-    /**
-     * 杩佺Щ娴佺▼瀹氫箟
-     *
-     * @param currentProcessDefinitionId 褰撳墠娴佺▼瀹氫箟id
-     * @param fromProcessDefinitionId    闇�瑕佽縼绉诲埌鐨勬祦绋嬪畾涔塱d
-     * @return 缁撴灉
-     */
-    boolean migrationDefinition(String currentProcessDefinitionId, String fromProcessDefinitionId);
-
-    /**
-     * 娴佺▼瀹氫箟杞崲涓烘ā鍨�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    boolean convertToModel(String processDefinitionId);
-
-    /**
-     * 閫氳繃zip鎴杧ml閮ㄧ讲娴佺▼瀹氫箟
-     *
-     * @param file         鏂囦欢
-     * @param categoryCode 鍒嗙被
-     */
-    void deployByFile(MultipartFile file, String categoryCode);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java
deleted file mode 100644
index ca3b6fb..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.workflow.domain.bo.ProcessInstanceBo;
-import org.dromara.workflow.domain.bo.ProcessInvalidBo;
-import org.dromara.workflow.domain.bo.TaskUrgingBo;
-import org.dromara.workflow.domain.vo.ActHistoryInfoVo;
-import org.dromara.workflow.domain.vo.ProcessInstanceVo;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 娴佺▼瀹炰緥 鏈嶅姟灞�
- *
- * @author may
- */
-public interface IActProcessInstanceService {
-    /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥�
-     *
-     * @param businessKey 娴佺▼瀹炰緥id
-     * @return 缁撴灉
-     */
-    String getHistoryImage(String businessKey);
-
-    /**
-     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
-     *
-     * @param businessKey 涓氬姟id
-     * @return 缁撴灉
-     */
-    Map<String, Object> getHistoryList(String businessKey);
-
-    /**
-     * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
-     *
-     * @param processInstanceBo 鍙傛暟
-     * @param pageQuery         鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo processInstanceBo, PageQuery pageQuery);
-
-    /**
-     * 鍒嗛〉鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥
-     *
-     * @param processInstanceBo 鍙傛暟
-     * @param pageQuery         鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo processInstanceBo, PageQuery pageQuery);
-
-    /**
-     * 鑾峰彇瀹℃壒璁板綍
-     *
-     * @param businessKey 涓氬姟id
-     * @return 缁撴灉
-     */
-    List<ActHistoryInfoVo> getHistoryRecord(String businessKey);
-
-    /**
-     * 浣滃簾娴佺▼瀹炰緥锛屼笉浼氬垹闄ゅ巻鍙茶褰�(鍒犻櫎杩愯涓殑瀹炰緥)
-     *
-     * @param processInvalidBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean deleteRunInstance(ProcessInvalidBo processInvalidBo);
-
-    /**
-     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     * @return 缁撴灉
-     */
-    boolean deleteRunAndHisInstance(List<String> businessKeys);
-
-    /**
-     * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     * @return 缁撴灉
-     */
-    boolean deleteFinishAndHisInstance(List<String> businessKeys);
-
-    /**
-     * 鎾ら攢娴佺▼鐢宠
-     *
-     * @param businessKey 涓氬姟id
-     * @return 缁撴灉
-     */
-    boolean cancelProcessApply(String businessKey);
-
-    /**
-     * 鍒嗛〉鏌ヨ褰撳墠鐧诲綍浜哄崟鎹�
-     *
-     * @param processInstanceBo 鍙傛暟
-     * @param pageQuery         鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo processInstanceBo, PageQuery pageQuery);
-
-    /**
-     * 浠诲姟鍌姙(缁欏綋鍓嶄换鍔″姙鐞嗕汉鍙戦�佺珯鍐呬俊锛岄偖浠讹紝鐭俊绛�)
-     *
-     * @param taskUrgingBo 浠诲姟鍌姙
-     * @return 缁撴灉
-     */
-    boolean taskUrging(TaskUrgingBo taskUrgingBo);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java
deleted file mode 100644
index 8e9f763..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActTaskService.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.workflow.domain.bo.*;
-import org.dromara.workflow.domain.vo.TaskVo;
-import org.dromara.workflow.domain.vo.VariableVo;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 浠诲姟 鏈嶅姟灞�
- *
- * @author may
- */
-public interface IActTaskService {
-    /**
-     * 鍚姩浠诲姟
-     *
-     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
-     * @return 缁撴灉
-     */
-    Map<String, Object> startWorkFlow(StartProcessBo startProcessBo);
-
-
-    /**
-     * 鍔炵悊浠诲姟
-     *
-     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean completeTask(CompleteTaskBo completeTaskBo);
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
-     *
-     * @param taskBo    鍙傛暟
-     * @param pageQuery 鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊緟鍔炰换鍔�
-     *
-     * @param taskBo    鍙傛暟
-     * @param pageQuery 鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery);
-
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫凡鍔炰换鍔�
-     *
-     * @param taskBo    鍙傛暟
-     * @param pageQuery 鍙傛暟
-     * @return 缁撴灉
-     */
-    TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
-     *
-     * @param taskBo    鍙傛暟
-     * @param pageQuery 鍙傛暟
-     * @return 缁撴灉
-     */
-    TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊凡鍔炰换鍔�
-     *
-     * @param taskBo    鍙傛暟
-     * @param pageQuery 鍙傛暟
-     * @return 缁撴灉
-     */
-    TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery);
-
-    /**
-     * 濮旀淳浠诲姟
-     *
-     * @param delegateBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean delegateTask(DelegateBo delegateBo);
-
-    /**
-     * 缁堟浠诲姟
-     *
-     * @param terminationBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean terminationTask(TerminationBo terminationBo);
-
-    /**
-     * 杞姙浠诲姟
-     *
-     * @param transmitBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean transferTask(TransmitBo transmitBo);
-
-    /**
-     * 浼氱浠诲姟鍔犵
-     *
-     * @param addMultiBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean addMultiInstanceExecution(AddMultiBo addMultiBo);
-
-    /**
-     * 浼氱浠诲姟鍑忕
-     *
-     * @param deleteMultiBo 鍙傛暟
-     * @return 缁撴灉
-     */
-    boolean deleteMultiInstanceExecution(DeleteMultiBo deleteMultiBo);
-
-    /**
-     * 椹冲洖瀹℃壒
-     *
-     * @param backProcessBo 鍙傛暟
-     * @return 娴佺▼瀹炰緥id
-     */
-    String backProcess(BackProcessBo backProcessBo);
-
-    /**
-     * 淇敼浠诲姟鍔炵悊浜�
-     *
-     * @param taskIds 浠诲姟id
-     * @param userId  鍔炵悊浜篿d
-     * @return 缁撴灉
-     */
-    boolean updateAssignee(String[] taskIds, String userId);
-
-    /**
-     * 鏌ヨ娴佺▼鍙橀噺
-     *
-     * @param taskId 浠诲姟id
-     * @return 缁撴灉
-     */
-    List<VariableVo> getInstanceVariable(String taskId);
-
-    /**
-     * 鏌ヨ宸ヤ綔娴佷换鍔$敤鎴烽�夋嫨鍔犵浜哄憳
-     *
-     * @param taskId 浠诲姟id
-     * @return 缁撴灉
-     */
-    String getTaskUserIdsByAddMultiInstance(String taskId);
-
-    /**
-     * 鏌ヨ宸ヤ綔娴侀�夋嫨鍑忕浜哄憳
-     *
-     * @param taskId 浠诲姟id
-     * @return 缁撴灉
-     */
-    List<TaskVo> getListByDeleteMultiInstance(String taskId);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwCategoryService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwCategoryService.java
new file mode 100644
index 0000000..43bc175
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwCategoryService.java
@@ -0,0 +1,102 @@
+package org.dromara.workflow.service;
+
+import cn.hutool.core.lang.tree.Tree;
+import org.dromara.workflow.domain.bo.FlowCategoryBo;
+import org.dromara.workflow.domain.vo.FlowCategoryVo;
+
+import java.util.List;
+
+/**
+ * 娴佺▼鍒嗙被Service鎺ュ彛
+ *
+ * @author may
+ */
+public interface IFlwCategoryService {
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被
+     *
+     * @param categoryId 涓婚敭
+     * @return 娴佺▼鍒嗙被
+     */
+    FlowCategoryVo queryById(Long categoryId);
+
+    /**
+     * 鏍规嵁娴佺▼鍒嗙被ID鏌ヨ娴佺▼鍒嗙被鍚嶇О
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 娴佺▼鍒嗙被鍚嶇О
+     */
+    String selectCategoryNameById(String categoryId);
+
+    /**
+     * 鏌ヨ绗﹀悎鏉′欢鐨勬祦绋嬪垎绫诲垪琛�
+     *
+     * @param bo 鏌ヨ鏉′欢
+     * @return 娴佺▼鍒嗙被鍒楄〃
+     */
+    List<FlowCategoryVo> queryList(FlowCategoryBo bo);
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏍戠粨鏋勪俊鎭�
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 娴佺▼鍒嗙被鏍戜俊鎭泦鍚�
+     */
+    List<Tree<Long>> selectCategoryTreeList(FlowCategoryBo category);
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     */
+    void checkCategoryDataScope(Long categoryId);
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鍚嶇О鏄惁鍞竴
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 缁撴灉
+     */
+    boolean checkCategoryNameUnique(FlowCategoryBo category);
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏄惁瀛樺湪娴佺▼瀹氫箟
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    boolean checkCategoryExistDefinition(Long categoryId);
+
+    /**
+     * 鏄惁瀛樺湪娴佺▼鍒嗙被瀛愯妭鐐�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉
+     */
+    boolean hasChildByCategoryId(Long categoryId);
+
+    /**
+     * 鏂板娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁鏂板鎴愬姛
+     */
+    int insertByBo(FlowCategoryBo bo);
+
+    /**
+     * 淇敼娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁淇敼鎴愬姛
+     */
+    int updateByBo(FlowCategoryBo bo);
+
+    /**
+     * 鍒犻櫎娴佺▼鍒嗙被淇℃伅
+     *
+     * @param categoryId 涓婚敭
+     * @return 鏄惁鍒犻櫎鎴愬姛
+     */
+    int deleteWithValidById(Long categoryId);
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwDefinitionService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwDefinitionService.java
new file mode 100644
index 0000000..6b5ca59
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwDefinitionService.java
@@ -0,0 +1,79 @@
+package org.dromara.workflow.service;
+
+import jakarta.servlet.http.HttpServletResponse;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.warm.flow.orm.entity.FlowDefinition;
+import org.dromara.workflow.domain.vo.FlowDefinitionVo;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 娴佺▼瀹氫箟 鏈嶅姟灞�
+ *
+ * @author may
+ */
+public interface IFlwDefinitionService {
+
+    /**
+     * 鏌ヨ娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 鍙傛暟
+     * @param pageQuery      鍒嗛〉
+     * @return 杩斿洖鍒嗛〉鍒楄〃
+     */
+    TableDataInfo<FlowDefinitionVo> queryList(FlowDefinition flowDefinition, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ鏈彂甯冪殑娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 鍙傛暟
+     * @param pageQuery      鍒嗛〉
+     * @return 杩斿洖鍒嗛〉鍒楄〃
+     */
+    TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery);
+
+
+    /**
+     * 鍙戝竷娴佺▼瀹氫箟
+     *
+     * @param id 娴佺▼瀹氫箟id
+     * @return 缁撴灉
+     */
+    boolean publish(Long id);
+
+    /**
+     * 瀵煎嚭娴佺▼瀹氫箟
+     *
+     * @param id       娴佺▼瀹氫箟id
+     * @param response 鍝嶅簲
+     * @throws IOException 寮傚父
+     */
+    void exportDef(Long id, HttpServletResponse response) throws IOException;
+
+    /**
+     * 瀵煎叆娴佺▼瀹氫箟
+     *
+     * @param file     鏂囦欢
+     * @param category 鍒嗙被
+     * @return 缁撴灉
+     */
+    boolean importXml(MultipartFile file, String category);
+
+    /**
+     * 鍒犻櫎娴佺▼瀹氫箟
+     *
+     * @param ids 娴佺▼瀹氫箟id
+     * @return 缁撴灉
+     */
+    boolean removeDef(List<Long> ids);
+
+    /**
+     * 鏂板绉熸埛娴佺▼瀹氫箟
+     *
+     * @param tenantId 绉熸埛id
+     */
+    void syncDef(String tenantId);
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java
new file mode 100644
index 0000000..97d84a2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwInstanceService.java
@@ -0,0 +1,159 @@
+package org.dromara.workflow.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.warm.flow.orm.entity.FlowInstance;
+import org.dromara.workflow.domain.bo.FlowCancelBo;
+import org.dromara.workflow.domain.bo.FlowInstanceBo;
+import org.dromara.workflow.domain.bo.FlowInvalidBo;
+import org.dromara.workflow.domain.vo.FlowInstanceVo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼瀹炰緥 鏈嶅姟灞�
+ *
+ * @author may
+ */
+public interface IFlwInstanceService {
+
+    /**
+     * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowInstanceVo> selectRunningInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery);
+
+    /**
+     * 鍒嗛〉鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowInstanceVo> selectFinishInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery);
+
+    /**
+     * 鏍规嵁涓氬姟id鏌ヨ娴佺▼瀹炰緥璇︾粏淇℃伅
+     *
+     * @param businessId 涓氬姟id
+     * @return 缁撴灉
+     */
+    FlowInstanceVo queryByBusinessId(Long businessId);
+
+    /**
+     * 鎸夌収涓氬姟id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param businessId 涓氬姟id
+     * @return 缁撴灉
+     */
+    FlowInstance selectInstByBusinessId(String businessId);
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param instanceId 瀹炰緥id
+     * @return 缁撴灉
+     */
+    FlowInstance selectInstById(Long instanceId);
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param instanceIds 瀹炰緥id
+     * @return 缁撴灉
+     */
+    List<FlowInstance> selectInstListByIdList(List<Long> instanceIds);
+
+    /**
+     * 鎸夌収涓氬姟id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param businessIds 涓氬姟id
+     * @return 缁撴灉
+     */
+    boolean deleteByBusinessIds(List<Long> businessIds);
+
+    /**
+     * 鎸夌収瀹炰緥id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param instanceIds 瀹炰緥id
+     * @return 缁撴灉
+     */
+    boolean deleteByInstanceIds(List<Long> instanceIds);
+
+    /**
+     * 鎾ら攢娴佺▼
+     *
+     * @param bo 鍙傛暟
+     * @return 缁撴灉
+     */
+    boolean cancelProcessApply(FlowCancelBo bo);
+
+    /**
+     * 鑾峰彇褰撳墠鐧婚檰浜哄彂璧风殑娴佺▼瀹炰緥
+     *
+     * @param instanceBo 娴佺▼瀹炰緥
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowInstanceVo> selectCurrentInstanceList(FlowInstanceBo instanceBo, PageQuery pageQuery);
+
+    /**
+     * 鑾峰彇娴佺▼鍥�,娴佺▼璁板綍
+     *
+     * @param businessId 涓氬姟id
+     * @return 缁撴灉
+     */
+    Map<String, Object> flowImage(String businessId);
+
+    /**
+     * 鎸夌収瀹炰緥id鏇存柊鐘舵��
+     *
+     * @param instanceId 瀹炰緥id
+     * @param status     鐘舵��
+     */
+    void updateStatus(Long instanceId, String status);
+
+    /**
+     * 鑾峰彇娴佺▼鍙橀噺
+     *
+     * @param instanceId 瀹炰緥id
+     * @return 缁撴灉
+     */
+    Map<String, Object> instanceVariable(String instanceId);
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺
+     *
+     * @param instanceId 瀹炰緥id
+     * @param variable   娴佺▼鍙橀噺
+     */
+    void setVariable(Long instanceId, Map<String, Object> variable);
+
+    /**
+     * 鎸変换鍔d鏌ヨ瀹炰緥
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    FlowInstance selectByTaskId(Long taskId);
+
+    /**
+     * 鎸変换鍔d鏌ヨ瀹炰緥
+     *
+     * @param taskIdList 浠诲姟id
+     * @return 缁撴灉
+     */
+    List<FlowInstance> selectByTaskIdList(List<Long> taskIdList);
+
+    /**
+     * 浣滃簾娴佺▼
+     *
+     * @param bo 娴佺▼瀹炰緥
+     * @return 缁撴灉
+     */
+    boolean processInvalid(FlowInvalidBo bo);
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java
new file mode 100644
index 0000000..116cb74
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskAssigneeService.java
@@ -0,0 +1,22 @@
+package org.dromara.workflow.service;
+
+import org.dromara.common.core.domain.dto.UserDTO;
+
+import java.util.List;
+
+/**
+ * 娴佺▼璁捐鍣�-鑾峰彇鍔炵悊浜�
+ *
+ * @author AprilWind
+ */
+public interface IFlwTaskAssigneeService {
+
+    /**
+     * 鏍规嵁瀛樺偍鏍囪瘑绗︼紙storageId锛夎В鏋愬垎閰嶇被鍨嬪拰ID锛屽苟鑾峰彇瀵瑰簲鐨勭敤鎴峰垪琛�
+     *
+     * @param storageId 鍖呭惈鍒嗛厤绫诲瀷鍜孖D鐨勫瓧绗︿覆锛堜緥濡� "user:123" 鎴� "role:456"锛�
+     * @return 涓庡垎閰嶇被鍨嬪拰ID鍖归厤鐨勭敤鎴峰垪琛紝濡傛灉鏍煎紡鏃犳晥鍒欒繑鍥炵┖鍒楄〃
+     */
+    List<UserDTO> fetchUsersByStorageId(String storageId);
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java
new file mode 100644
index 0000000..80bfa94
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java
@@ -0,0 +1,190 @@
+package org.dromara.workflow.service;
+
+import org.dromara.common.core.domain.dto.UserDTO;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.warm.flow.core.entity.Node;
+import org.dromara.warm.flow.orm.entity.FlowHisTask;
+import org.dromara.warm.flow.orm.entity.FlowTask;
+import org.dromara.workflow.domain.bo.*;
+import org.dromara.workflow.domain.vo.FlowHisTaskVo;
+import org.dromara.workflow.domain.vo.FlowTaskVo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 浠诲姟 鏈嶅姟灞�
+ *
+ * @author may
+ */
+public interface IFlwTaskService {
+
+    /**
+     * 鍚姩浠诲姟
+     *
+     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
+     * @return 缁撴灉
+     */
+    Map<String, Object> startWorkFlow(StartProcessBo startProcessBo);
+
+    /**
+     * 鍔炵悊浠诲姟
+     *
+     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
+     * @return 缁撴灉
+     */
+    boolean completeTask(CompleteTaskBo completeTaskBo);
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowTaskVo> pageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊緟鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowHisTaskVo> pageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ寰呭姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowTaskVo> pageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ宸插姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowHisTaskVo> pageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery);
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     * @return 缁撴灉
+     */
+    TableDataInfo<FlowTaskVo> pageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery);
+
+    /**
+     * 淇敼浠诲姟鍔炵悊浜�
+     *
+     * @param taskIdList 浠诲姟id
+     * @param userId     鐢ㄦ埛id
+     * @return 缁撴灉
+     */
+    boolean updateAssignee(List<Long> taskIdList, String userId);
+
+    /**
+     * 椹冲洖瀹℃壒
+     *
+     * @param bo 鍙傛暟
+     * @return 缁撴灉
+     */
+    boolean backProcess(BackProcessBo bo);
+
+    /**
+     * 鑾峰彇鍙┏鍥炵殑鍓嶇疆鑺傜偣
+     *
+     * @param definitionId 娴佺▼瀹氫箟id
+     * @param nowNodeCode  褰撳墠鑺傜偣
+     * @return 缁撴灉
+     */
+    List<Node> getBackTaskNode(Long definitionId, String nowNodeCode);
+
+    /**
+     * 缁堟浠诲姟
+     *
+     * @param bo 鍙傛暟
+     * @return 缁撴灉
+     */
+    boolean terminationTask(FlowTerminationBo bo);
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskIdList 浠诲姟id
+     * @return 缁撴灉
+     */
+    List<FlowTask> selectByIdList(List<Long> taskIdList);
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    FlowTaskVo selectById(Long taskId);
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskIdList 浠诲姟id
+     * @return 缁撴灉
+     */
+    List<FlowHisTask> selectHisTaskByIdList(List<Long> taskIdList);
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    FlowHisTask selectHisTaskById(Long taskId);
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ浠诲姟
+     *
+     * @param instanceIdList 娴佺▼瀹炰緥id
+     * @return 缁撴灉
+     */
+    List<FlowTask> selectByInstIdList(List<Long> instanceIdList);
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ浠诲姟
+     *
+     * @param instanceId 娴佺▼瀹炰緥id
+     * @return 缁撴灉
+     */
+    List<FlowTask> selectByInstId(Long instanceId);
+
+    /**
+     * 浠诲姟鎿嶄綔
+     *
+     * @param bo            鍙傛暟
+     * @param taskOperation 鎿嶄綔绫诲瀷锛屽娲� delegateTask銆佽浆鍔� transferTask銆佸姞绛� addSignature銆佸噺绛� reductionSignature
+     * @return 缁撴灉
+     */
+    boolean taskOperation(TaskOperationBo bo, String taskOperation);
+
+    /**
+     * 鑾峰彇浠诲姟鎵�鏈夊姙鐞嗕汉
+     *
+     * @param taskIdList 浠诲姟id
+     * @return 缁撴灉
+     */
+    Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList);
+
+    /**
+     * 鑾峰彇褰撳墠浠诲姟鐨勬墍鏈夊姙鐞嗕汉
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    List<UserDTO> currentTaskAllUser(Long taskId);
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/ITestLeaveService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/ITestLeaveService.java
index 943c919..67b50ba 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/ITestLeaveService.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/ITestLeaveService.java
@@ -5,7 +5,6 @@
 import org.dromara.workflow.domain.bo.TestLeaveBo;
 import org.dromara.workflow.domain.vo.TestLeaveVo;
 
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -44,5 +43,5 @@
     /**
      * 鏍¢獙骞舵壒閲忓垹闄よ鍋囦俊鎭�
      */
-    Boolean deleteWithValidByIds(Collection<Long> ids);
+    Boolean deleteWithValidByIds(List<Long> ids);
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfCategoryService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfCategoryService.java
deleted file mode 100644
index acf0aa2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfCategoryService.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.workflow.domain.WfCategory;
-import org.dromara.workflow.domain.bo.WfCategoryBo;
-import org.dromara.workflow.domain.vo.WfCategoryVo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴佺▼鍒嗙被Service鎺ュ彛
- *
- * @author may
- * @date 2023-06-28
- */
-public interface IWfCategoryService {
-
-    /**
-     * 鏌ヨ娴佺▼鍒嗙被
-     */
-    WfCategoryVo queryById(Long id);
-
-
-    /**
-     * 鏌ヨ娴佺▼鍒嗙被鍒楄〃
-     */
-    List<WfCategoryVo> queryList(WfCategoryBo bo);
-
-    /**
-     * 鏂板娴佺▼鍒嗙被
-     */
-    Boolean insertByBo(WfCategoryBo bo);
-
-    /**
-     * 淇敼娴佺▼鍒嗙被
-     */
-    Boolean updateByBo(WfCategoryBo bo);
-
-    /**
-     * 鏍¢獙骞舵壒閲忓垹闄ゆ祦绋嬪垎绫讳俊鎭�
-     */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
-
-    /**
-     * 鎸夌収绫诲埆缂栫爜鏌ヨ
-     *
-     * @param categoryCode 鍒嗙被姣斿悧
-     * @return 缁撴灉
-     */
-    WfCategory queryByCategoryCode(String categoryCode);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfDefinitionConfigService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfDefinitionConfigService.java
deleted file mode 100644
index fe5cf7a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfDefinitionConfigService.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆Service鎺ュ彛
- *
- * @author may
- * @date 2024-03-18
- */
-public interface IWfDefinitionConfigService {
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param definitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    WfDefinitionConfigVo getByDefId(String definitionId);
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param tableName 琛ㄥ悕
-     * @return 缁撴灉
-     */
-    WfDefinitionConfigVo getByTableNameLastVersion(String tableName);
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param definitionId 娴佺▼瀹氫箟id
-     * @param tableName    琛ㄥ悕
-     * @return 缁撴灉
-     */
-    WfDefinitionConfigVo getByDefIdAndTableName(String definitionId, String tableName);
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆鎺掗櫎褰撳墠鏌ヨ鐨勬祦绋嬪畾涔�
-     *
-     * @param definitionId 娴佺▼瀹氫箟id
-     * @param tableName    琛ㄥ悕
-     * @return 缁撴灉
-     */
-    List<WfDefinitionConfigVo> getByTableNameNotDefId(String tableName, String definitionId);
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆鍒楄〃
-     *
-     * @param definitionIds 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    List<WfDefinitionConfigVo> queryList(List<String> definitionIds);
-
-
-    /**
-     * 鏂板娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param bo 鍙傛暟
-     * @return 缁撴灉
-     */
-    Boolean saveOrUpdate(WfDefinitionConfigBo bo);
-
-    /**
-     * 鍒犻櫎
-     *
-     * @param ids id
-     * @return 缁撴灉
-     */
-    Boolean deleteByIds(Collection<Long> ids);
-
-    /**
-     * 鎸夌収娴佺▼瀹氫箟id鍒犻櫎
-     *
-     * @param ids 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    Boolean deleteByDefIds(Collection<String> ids);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfFormManageService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfFormManageService.java
deleted file mode 100644
index 2ca2264..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfFormManageService.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.workflow.domain.vo.WfFormManageVo;
-import org.dromara.workflow.domain.bo.WfFormManageBo;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 琛ㄥ崟绠$悊Service鎺ュ彛
- *
- * @author may
- * @date 2024-03-29
- */
-public interface IWfFormManageService {
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊
-     *
-     * @param id 涓婚敭
-     * @return 缁撴灉
-     */
-    WfFormManageVo queryById(Long id);
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊
-     *
-     * @param ids 涓婚敭
-     * @return 缁撴灉
-     */
-    List<WfFormManageVo> queryByIds(List<Long> ids);
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     *
-     * @param bo        鍙傛暟
-     * @param pageQuery 鍒嗛〉
-     * @return 缁撴灉
-     */
-    TableDataInfo<WfFormManageVo> queryPageList(WfFormManageBo bo, PageQuery pageQuery);
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     *
-     * @return 缁撴灉
-     */
-    List<WfFormManageVo> selectList();
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     *
-     * @param bo 鍙傛暟
-     * @return 缁撴灉
-     */
-    List<WfFormManageVo> queryList(WfFormManageBo bo);
-
-    /**
-     * 鏂板琛ㄥ崟绠$悊
-     *
-     * @param bo 鍙傛暟
-     * @return 缁撴灉
-     */
-    Boolean insertByBo(WfFormManageBo bo);
-
-    /**
-     * 淇敼琛ㄥ崟绠$悊
-     *
-     * @param bo 鍙傛暟
-     * @return 缁撴灉
-     */
-    Boolean updateByBo(WfFormManageBo bo);
-
-    /**
-     * 鎵归噺鍒犻櫎琛ㄥ崟绠$悊淇℃伅
-     *
-     * @param ids 涓婚敭
-     * @return 缁撴灉
-     */
-    Boolean deleteByIds(Collection<Long> ids);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfNodeConfigService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfNodeConfigService.java
deleted file mode 100644
index 5e64d64..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfNodeConfigService.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.dromara.workflow.service;
-
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.workflow.domain.vo.WfNodeConfigVo;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 鑺傜偣閰嶇疆Service鎺ュ彛
- *
- * @author may
- * @date 2024-03-30
- */
-public interface IWfNodeConfigService {
-
-    /**
-     * 鏌ヨ鑺傜偣閰嶇疆
-     *
-     * @param id 涓婚敭
-     * @return 缁撴灉
-     */
-    WfNodeConfigVo queryById(Long id);
-
-    /**
-     * 淇濆瓨鑺傜偣閰嶇疆
-     *
-     * @param list 鍙傛暟
-     * @return 缁撴灉
-     */
-    Boolean saveOrUpdate(List<WfNodeConfig> list);
-
-    /**
-     * 鎵归噺鍒犻櫎鑺傜偣閰嶇疆淇℃伅
-     *
-     * @param ids 涓婚敭
-     * @return 缁撴灉
-     */
-    Boolean deleteByIds(Collection<Long> ids);
-
-    /**
-     * 鎸夌収娴佺▼瀹氫箟id鍒犻櫎
-     *
-     * @param ids 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    Boolean deleteByDefIds(Collection<String> ids);
-
-    /**
-     * 鎸夌収娴佺▼瀹氫箟id鏌ヨ
-     *
-     * @param ids 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    List<WfNodeConfigVo> selectByDefIds(Collection<String> ids);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfTaskBackNodeService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfTaskBackNodeService.java
deleted file mode 100644
index 97f9406..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IWfTaskBackNodeService.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.dromara.workflow.service;
-
-
-import org.dromara.workflow.domain.WfTaskBackNode;
-import org.flowable.task.api.Task;
-
-import java.util.List;
-
-/**
- * 鑺傜偣椹冲洖璁板綍Service鎺ュ彛
- *
- * @author may
- * @date 2024-03-13
- */
-public interface IWfTaskBackNodeService {
-
-    /**
-     * 璁板綍瀹℃壒鑺傜偣
-     *
-     * @param task 浠诲姟
-     */
-    void recordExecuteNode(Task task);
-
-    /**
-     * 鎸夋祦绋嬪疄渚媔d鏌ヨ
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     * @return 缁撴灉
-     */
-    List<WfTaskBackNode> getListByInstanceId(String processInstanceId);
-
-    /**
-     * 鎸夌収娴佺▼瀹炰緥id锛岃妭鐐筰d鏌ヨ
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     * @param nodeId            鑺傜偣id
-     * @return 缁撴灉
-     */
-    WfTaskBackNode getListByInstanceIdAndNodeId(String processInstanceId, String nodeId);
-
-    /**
-     * 鍒犻櫎椹冲洖鍚庣殑鑺傜偣
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     * @param targetActivityId  鑺傜偣id
-     * @return 缁撴灉
-     */
-    boolean deleteBackTaskNode(String processInstanceId, String targetActivityId);
-
-    /**
-     * 鎸夋祦绋嬪疄渚媔d鍒犻櫎
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     * @return 缁撴灉
-     */
-    boolean deleteByInstanceId(String processInstanceId);
-
-    /**
-     * 鎸夋祦绋嬪疄渚媔d鍒犻櫎
-     *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
-     * @return 缁撴灉
-     */
-    boolean deleteByInstanceIds(List<String> processInstanceIds);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiProcinstServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiProcinstServiceImpl.java
deleted file mode 100644
index 06d607b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiProcinstServiceImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.domain.ActHiProcinst;
-import org.dromara.workflow.mapper.ActHiProcinstMapper;
-import org.dromara.workflow.service.IActHiProcinstService;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-
-/**
- * 娴佺▼瀹炰緥Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2023-07-22
- */
-@RequiredArgsConstructor
-@Service
-public class ActHiProcinstServiceImpl implements IActHiProcinstService {
-
-    private final ActHiProcinstMapper baseMapper;
-
-    /**
-     * 鎸夌収涓氬姟id鏌ヨ
-     *
-     * @param businessKeys 涓氬姟id
-     */
-    @Override
-    public List<ActHiProcinst> selectByBusinessKeyIn(List<String> businessKeys) {
-        return baseMapper.selectList(new LambdaQueryWrapper<ActHiProcinst>()
-            .in(ActHiProcinst::getBusinessKey, businessKeys)
-            .eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId()));
-    }
-
-    /**
-     * 鎸夌収涓氬姟id鏌ヨ
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @Override
-    public ActHiProcinst selectByBusinessKey(String businessKey) {
-        return baseMapper.selectOne(new LambdaQueryWrapper<ActHiProcinst>()
-            .eq(ActHiProcinst::getBusinessKey, businessKey)
-            .eq(TenantHelper.isEnable(), ActHiProcinst::getTenantId, TenantHelper.getTenantId()));
-
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiTaskinstServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiTaskinstServiceImpl.java
deleted file mode 100644
index 5548f22..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActHiTaskinstServiceImpl.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.dromara.workflow.service.IActHiTaskinstService;
-
-
-/**
- * 娴佺▼鍘嗗彶浠诲姟Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2024-03-02
- */
-@RequiredArgsConstructor
-@Service
-public class ActHiTaskinstServiceImpl implements IActHiTaskinstService {
-
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java
deleted file mode 100644
index 217538e..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java
+++ /dev/null
@@ -1,431 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.core.util.ZipUtil;
-import cn.hutool.json.JSONUtil;
-import com.alibaba.excel.util.StringUtils;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.batik.transcoder.TranscoderInput;
-import org.apache.batik.transcoder.TranscoderOutput;
-import org.apache.batik.transcoder.image.PNGTranscoder;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.workflow.domain.bo.ModelBo;
-import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
-import org.dromara.workflow.domain.vo.ModelVo;
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.workflow.service.IActModelService;
-import org.dromara.workflow.service.IWfDefinitionConfigService;
-import org.dromara.workflow.service.IWfNodeConfigService;
-import org.dromara.workflow.utils.ModelUtils;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.bpmn.converter.BpmnXMLConverter;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.Process;
-import org.flowable.bpmn.model.UserTask;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.repository.Deployment;
-import org.flowable.engine.repository.Model;
-import org.flowable.engine.repository.ModelQuery;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.flowable.validation.ValidationError;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-/**
- * 妯″瀷绠$悊 鏈嶅姟灞傚疄鐜�
- *
- * @author may
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class ActModelServiceImpl implements IActModelService {
-
-    @Autowired(required = false)
-    private RepositoryService repositoryService;
-    private final IWfNodeConfigService wfNodeConfigService;
-    private final IWfDefinitionConfigService wfDefinitionConfigService;
-
-    /**
-     * 鍒嗛〉鏌ヨ妯″瀷
-     *
-     * @param modelBo 妯″瀷鍙傛暟
-     * @return 杩斿洖鍒嗛〉鍒楄〃
-     */
-    @Override
-    public TableDataInfo<Model> page(ModelBo modelBo, PageQuery pageQuery) {
-        ModelQuery query = QueryUtils.modelQuery();
-        if (StringUtils.isNotBlank(modelBo.getName())) {
-            query.modelNameLike("%" + modelBo.getName() + "%");
-        }
-        if (StringUtils.isNotBlank(modelBo.getKey())) {
-            query.modelKey(modelBo.getKey());
-        }
-        if (StringUtils.isNotBlank(modelBo.getCategoryCode())) {
-            query.modelCategory(modelBo.getCategoryCode());
-        }
-        query.orderByLastUpdateTime().desc();
-        // 鍒涘缓鏃堕棿闄嶅簭鎺掑垪
-        query.orderByCreateTime().desc();
-        // 鍒嗛〉鏌ヨ
-        List<Model> modelList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        // 鎬昏褰曟暟
-        long total = query.count();
-        TableDataInfo<Model> build = TableDataInfo.build();
-        build.setRows(modelList);
-        build.setTotal(total);
-        return build;
-    }
-
-    /**
-     * 鏂板妯″瀷
-     *
-     * @param modelBo 妯″瀷璇锋眰瀵硅薄
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean saveNewModel(ModelBo modelBo) {
-        try {
-            int version = 0;
-            String key = modelBo.getKey();
-            String name = modelBo.getName();
-            String description = modelBo.getDescription();
-            String categoryCode = modelBo.getCategoryCode();
-            String xml = modelBo.getXml();
-            Model checkModel = QueryUtils.modelQuery().modelKey(key).singleResult();
-            if (ObjectUtil.isNotNull(checkModel)) {
-                throw new ServiceException("妯″瀷key宸插瓨鍦紒");
-            }
-            //鍒濆绌虹殑妯″瀷
-            Model model = repositoryService.newModel();
-            model.setKey(key);
-            model.setName(name);
-            model.setVersion(version);
-            model.setCategory(categoryCode);
-            model.setMetaInfo(description);
-            model.setTenantId(TenantHelper.getTenantId());
-            //淇濆瓨鍒濆鍖栫殑妯″瀷鍩烘湰淇℃伅鏁版嵁
-            repositoryService.saveModel(model);
-            repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(xml));
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 鏌ヨ妯″瀷
-     *
-     * @param id 妯″瀷id
-     * @return 妯″瀷鏁版嵁
-     */
-    @Override
-    public ModelVo getInfo(String id) {
-        ModelVo modelVo = new ModelVo();
-        Model model = repositoryService.getModel(id);
-        if (model != null) {
-            try {
-                byte[] modelEditorSource = repositoryService.getModelEditorSource(model.getId());
-                modelVo.setXml(StrUtil.utf8Str(modelEditorSource));
-                modelVo.setId(model.getId());
-                modelVo.setKey(model.getKey());
-                modelVo.setName(model.getName());
-                modelVo.setCategoryCode(model.getCategory());
-                modelVo.setDescription(model.getMetaInfo());
-                return modelVo;
-            } catch (Exception e) {
-                log.error(e.getMessage(), e);
-                throw new ServiceException(e.getMessage());
-            }
-        }
-        return modelVo;
-    }
-
-    /**
-     * 淇敼妯″瀷淇℃伅
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean update(ModelBo modelBo) {
-        try {
-            Model model = repositoryService.getModel(modelBo.getId());
-            List<Model> list = QueryUtils.modelQuery().modelKey(modelBo.getKey()).list();
-            list.stream().filter(e -> !e.getId().equals(model.getId())).findFirst().ifPresent(e -> {
-                throw new ServiceException("妯″瀷KEY宸插瓨鍦紒");
-            });
-            model.setCategory(modelBo.getCategoryCode());
-            model.setMetaInfo(modelBo.getDescription());
-            repositoryService.saveModel(model);
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-        return true;
-    }
-
-    /**
-     * 缂栬緫妯″瀷XML
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean editModelXml(ModelBo modelBo) {
-        try {
-            String xml = modelBo.getXml();
-            String svg = modelBo.getSvg();
-            String modelId = modelBo.getId();
-            String key = modelBo.getKey();
-            String name = modelBo.getName();
-            BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xml);
-            ModelUtils.checkBpmnModel(bpmnModel);
-            Model model = repositoryService.getModel(modelId);
-            List<Model> list = QueryUtils.modelQuery().modelKey(key).list();
-            list.stream().filter(e -> !e.getId().equals(model.getId())).findFirst().ifPresent(e -> {
-                throw new ServiceException("妯″瀷KEY宸插瓨鍦紒");
-            });
-            // 鏍¢獙key鍛藉悕瑙勮寖
-            if (!Validator.isMatchRegex(FlowConstant.MODEL_KEY_PATTERN, key)) {
-                throw new ServiceException("妯″瀷鏍囪瘑KEY鍙兘瀛楃鎴栬�呬笅鍒掔嚎寮�澶达紒");
-            }
-            model.setKey(key);
-            model.setName(name);
-            model.setVersion(model.getVersion() + 1);
-            repositoryService.saveModel(model);
-            repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(xml));
-            // 杞崲鍥剧墖
-            InputStream svgStream = new ByteArrayInputStream(StrUtil.utf8Bytes(svg));
-            TranscoderInput input = new TranscoderInput(svgStream);
-
-            PNGTranscoder transcoder = new PNGTranscoder();
-            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
-            TranscoderOutput output = new TranscoderOutput(outStream);
-
-            transcoder.transcode(input, output);
-            final byte[] result = outStream.toByteArray();
-            repositoryService.addModelEditorSourceExtra(model.getId(), result);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 妯″瀷閮ㄧ讲
-     *
-     * @param id 妯″瀷id
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean modelDeploy(String id) {
-        try {
-            // 鏌ヨ娴佺▼瀹氫箟妯″瀷xml
-            byte[] xmlBytes = repositoryService.getModelEditorSource(id);
-            if (ArrayUtil.isEmpty(xmlBytes)) {
-                throw new ServiceException("妯″瀷鏁版嵁涓虹┖锛岃鍏堣璁℃祦绋嬪畾涔夋ā鍨嬶紝鍐嶈繘琛岄儴缃诧紒");
-            }
-            if (JSONUtil.isTypeJSON(new String(xmlBytes, StandardCharsets.UTF_8))) {
-                byte[] bytes = ModelUtils.bpmnJsonToXmlBytes(xmlBytes);
-                if (ArrayUtil.isEmpty(bytes)) {
-                    throw new ServiceException("妯″瀷涓嶈兘涓虹┖锛岃鑷冲皯璁捐涓�鏉′富绾挎祦绋嬶紒");
-                }
-            }
-            BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xmlBytes);
-            // 鏍¢獙妯″瀷
-            ModelUtils.checkBpmnModel(bpmnModel);
-            List<ValidationError> validationErrors = repositoryService.validateProcess(bpmnModel);
-            if (CollUtil.isNotEmpty(validationErrors)) {
-                String errorMsg = validationErrors.stream().map(ValidationError::getProblem).distinct().collect(Collectors.joining(","));
-                throw new ServiceException(errorMsg);
-            }
-            // 鏌ヨ妯″瀷鐨勫熀鏈俊鎭�
-            Model model = repositoryService.getModel(id);
-            ProcessDefinition processDefinition = QueryUtils.definitionQuery().processDefinitionKey(model.getKey()).latestVersion().singleResult();
-            // xml璧勬簮鐨勫悕绉� 锛屽搴攁ct_ge_bytearray琛ㄤ腑鐨刵ame_瀛楁
-            String processName = model.getName() + ".bpmn20.xml";
-            // 璋冪敤閮ㄧ讲鐩稿叧鐨刟pi鏂规硶杩涜閮ㄧ讲娴佺▼瀹氫箟
-            Deployment deployment = repositoryService.createDeployment()
-                // 閮ㄧ讲鍚嶇О
-                .name(model.getName())
-                // 閮ㄧ讲鏍囪瘑key
-                .key(model.getKey())
-                // 閮ㄧ讲娴佺▼鍒嗙被
-                .category(model.getCategory())
-                // bpmn20.xml璧勬簮
-                .addBytes(processName, xmlBytes)
-                // 绉熸埛id
-                .tenantId(TenantHelper.getTenantId())
-                .deploy();
-
-            // 鏇存柊 閮ㄧ讲id 鍒版祦绋嬪畾涔夋ā鍨嬫暟鎹〃涓�
-            model.setDeploymentId(deployment.getId());
-            repositoryService.saveModel(model);
-            // 鏇存柊鍒嗙被
-            ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
-            repositoryService.setProcessDefinitionCategory(definition.getId(), model.getCategory());
-            //鏇存柊娴佺▼瀹氫箟閰嶇疆
-            if (processDefinition != null) {
-                WfDefinitionConfigVo definitionVo = wfDefinitionConfigService.getByDefId(processDefinition.getId());
-                if (definitionVo != null) {
-                    wfDefinitionConfigService.deleteByDefIds(Collections.singletonList(processDefinition.getId()));
-                    WfDefinitionConfigBo wfFormDefinition = new WfDefinitionConfigBo();
-                    wfFormDefinition.setDefinitionId(definition.getId());
-                    wfFormDefinition.setProcessKey(definition.getKey());
-                    wfFormDefinition.setTableName(definitionVo.getTableName());
-                    wfFormDefinition.setVersion(definition.getVersion());
-                    wfFormDefinition.setRemark(definitionVo.getRemark());
-                    wfDefinitionConfigService.saveOrUpdate(wfFormDefinition);
-                }
-            }
-            //鏇存柊娴佺▼鑺傜偣閰嶇疆琛ㄥ崟
-            List<UserTask> userTasks = ModelUtils.getUserTaskFlowElements(definition.getId());
-            UserTask applyUserTask = ModelUtils.getApplyUserTask(definition.getId());
-            List<WfNodeConfig> wfNodeConfigList = new ArrayList<>();
-            for (UserTask userTask : userTasks) {
-                if (StringUtils.isNotBlank(userTask.getFormKey()) && userTask.getFormKey().contains(StrUtil.COLON)) {
-                    WfNodeConfig wfNodeConfig = new WfNodeConfig();
-                    wfNodeConfig.setNodeId(userTask.getId());
-                    wfNodeConfig.setNodeName(userTask.getName());
-                    wfNodeConfig.setDefinitionId(definition.getId());
-                    String[] split = userTask.getFormKey().split(StrUtil.COLON);
-                    wfNodeConfig.setFormType(split[0]);
-                    wfNodeConfig.setFormId(Long.valueOf(split[1]));
-                    wfNodeConfig.setApplyUserTask(applyUserTask.getId().equals(userTask.getId()) ? FlowConstant.TRUE : FlowConstant.FALSE);
-                    wfNodeConfigList.add(wfNodeConfig);
-                }
-            }
-            if (CollUtil.isNotEmpty(wfNodeConfigList)) {
-                wfNodeConfigService.saveOrUpdate(wfNodeConfigList);
-            }
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 瀵煎嚭妯″瀷zip鍘嬬缉鍖�
-     *
-     * @param modelIds 妯″瀷id
-     * @param response 鐩稿簲
-     */
-    @Override
-    public void exportZip(List<String> modelIds, HttpServletResponse response) {
-        try (ZipOutputStream zos = ZipUtil.getZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8)) {
-            // 鍘嬬缉鍖呮枃浠跺悕
-            String zipName = "妯″瀷涓嶅瓨鍦�";
-            // 鏌ヨ妯″瀷鍩烘湰淇℃伅
-            for (String modelId : modelIds) {
-                Model model = repositoryService.getModel(modelId);
-                byte[] xmlBytes = repositoryService.getModelEditorSource(modelId);
-                if (ObjectUtil.isNotNull(model)) {
-                    if (JSONUtil.isTypeJSON(new String(xmlBytes, StandardCharsets.UTF_8)) && ArrayUtil.isEmpty(ModelUtils.bpmnJsonToXmlBytes(xmlBytes))) {
-                        zipName = "妯″瀷涓嶈兘涓虹┖锛岃鑷冲皯璁捐涓�鏉′富绾挎祦绋嬶紒";
-                        zos.putNextEntry(new ZipEntry(zipName + ".txt"));
-                        zos.write(zipName.getBytes(StandardCharsets.UTF_8));
-                    } else if (ArrayUtil.isEmpty(xmlBytes)) {
-                        zipName = "妯″瀷鏁版嵁涓虹┖锛岃鍏堣璁℃祦绋嬪畾涔夋ā鍨嬶紝鍐嶈繘琛岄儴缃诧紒";
-                        zos.putNextEntry(new ZipEntry(zipName + ".txt"));
-                        zos.write(zipName.getBytes(StandardCharsets.UTF_8));
-                    } else {
-                        String fileName = model.getName() + "-" + model.getKey();
-                        // 鍘嬬缉鍖呮枃浠跺悕
-                        zipName = fileName + ".zip";
-                        // 灏唜ml娣诲姞鍒板帇缂╁寘涓�(鎸囧畾xml鏂囦欢鍚嶏細璇峰亣娴佺▼.bpmn20.xml
-                        zos.putNextEntry(new ZipEntry(fileName + ".bpmn20.xml"));
-                        zos.write(xmlBytes);
-                    }
-                }
-            }
-            response.setHeader("Content-Disposition",
-                "attachment; filename=" + URLEncoder.encode(zipName, StandardCharsets.UTF_8) + ".zip");
-            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
-            // 鍒峰嚭鍝嶅簲娴�
-            response.flushBuffer();
-        } catch (IOException e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 澶嶅埗妯″瀷
-     *
-     * @param modelBo 妯″瀷鏁版嵁
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean copyModel(ModelBo modelBo) {
-        try {
-            String key = modelBo.getKey();
-            if (StringUtils.isNotBlank(key)) {
-                // 鏌ヨ妯″瀷
-                Model model = repositoryService.createModelQuery().modelId(modelBo.getId()).singleResult();
-                if (ObjectUtil.isNotNull(model)) {
-                    byte[] modelEditorSource = repositoryService.getModelEditorSource(model.getId());
-                    List<Model> list = QueryUtils.modelQuery().modelKey(key).list();
-                    if (CollUtil.isNotEmpty(list)) {
-                        throw new ServiceException("妯″瀷KEY宸插瓨鍦紒");
-                    }
-                    // 鏍¢獙key鍛藉悕瑙勮寖
-                    if (!Validator.isMatchRegex(FlowConstant.MODEL_KEY_PATTERN, key)) {
-                        throw new ServiceException("妯″瀷鏍囪瘑KEY鍙兘瀛楃鎴栬�呬笅鍒掔嚎寮�澶达紒");
-                    }
-                    // 澶嶅埗妯″瀷鏁版嵁
-                    Model newModel = repositoryService.newModel();
-                    newModel.setKey(modelBo.getKey());
-                    newModel.setName(modelBo.getName());
-                    newModel.setCategory(modelBo.getCategoryCode());
-                    newModel.setVersion(1);
-                    newModel.setMetaInfo(modelBo.getDescription());
-                    newModel.setTenantId(TenantHelper.getTenantId());
-                    String xml = StrUtil.utf8Str(modelEditorSource);
-                    BpmnModel bpmnModel = ModelUtils.xmlToBpmnModel(xml);
-                    Process mainProcess = bpmnModel.getMainProcess();
-                    mainProcess.setId(modelBo.getKey());
-                    mainProcess.setName(modelBo.getName());
-                    byte[] xmlBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
-                    repositoryService.saveModel(newModel);
-                    repositoryService.addModelEditorSource(newModel.getId(), xmlBytes);
-                }
-            }
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-        return true;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java
deleted file mode 100644
index 77fb257..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java
+++ /dev/null
@@ -1,444 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.workflow.domain.WfCategory;
-import org.dromara.workflow.domain.WfDefinitionConfig;
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.workflow.domain.bo.ProcessDefinitionBo;
-import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
-import org.dromara.workflow.domain.vo.ProcessDefinitionVo;
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.workflow.mapper.WfDefinitionConfigMapper;
-import org.dromara.workflow.service.IActProcessDefinitionService;
-import org.dromara.workflow.service.IWfCategoryService;
-import org.dromara.workflow.service.IWfDefinitionConfigService;
-import org.dromara.workflow.service.IWfNodeConfigService;
-import org.dromara.workflow.utils.ModelUtils;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.bpmn.model.UserTask;
-import org.flowable.engine.ProcessMigrationService;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.impl.bpmn.deployer.ResourceNameUtil;
-import org.flowable.engine.repository.*;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * 娴佺▼瀹氫箟 鏈嶅姟灞傚疄鐜�
- *
- * @author may
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionService {
-
-    @Autowired(required = false)
-    private RepositoryService repositoryService;
-    @Autowired(required = false)
-    private ProcessMigrationService processMigrationService;
-    private final IWfCategoryService wfCategoryService;
-    private final IWfDefinitionConfigService wfDefinitionConfigService;
-    private final WfDefinitionConfigMapper wfDefinitionConfigMapper;
-    private final IWfNodeConfigService wfNodeConfigService;
-
-    /**
-     * 鍒嗛〉鏌ヨ
-     *
-     * @param bo 鍙傛暟
-     * @return 杩斿洖鍒嗛〉鍒楄〃
-     */
-    @Override
-    public TableDataInfo<ProcessDefinitionVo> page(ProcessDefinitionBo bo, PageQuery pageQuery) {
-        ProcessDefinitionQuery query = QueryUtils.definitionQuery();
-        if (StringUtils.isNotEmpty(bo.getKey())) {
-            query.processDefinitionKey(bo.getKey());
-        }
-        if (StringUtils.isNotEmpty(bo.getCategoryCode())) {
-            query.processDefinitionCategory(bo.getCategoryCode());
-        }
-        if (StringUtils.isNotEmpty(bo.getName())) {
-            query.processDefinitionNameLike("%" + bo.getName() + "%");
-        }
-        query.orderByDeploymentId().desc();
-        // 鍒嗛〉鏌ヨ
-        List<ProcessDefinitionVo> processDefinitionVoList = new ArrayList<>();
-        List<ProcessDefinition> definitionList = query.latestVersion().listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        List<Deployment> deploymentList = null;
-        if (CollUtil.isNotEmpty(definitionList)) {
-            List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId);
-            deploymentList = QueryUtils.deploymentQuery(deploymentIds).list();
-        }
-        if (CollUtil.isNotEmpty(definitionList)) {
-            List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId);
-            List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids);
-            for (ProcessDefinition processDefinition : definitionList) {
-                ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
-                if (CollUtil.isNotEmpty(deploymentList)) {
-                    // 閮ㄧ讲鏃堕棿
-                    deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
-                        processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
-                    });
-                }
-                if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) {
-                    wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo);
-                }
-                processDefinitionVoList.add(processDefinitionVo);
-            }
-        }
-        // 鎬昏褰曟暟
-        long total = query.count();
-        TableDataInfo<ProcessDefinitionVo> build = TableDataInfo.build();
-        build.setRows(processDefinitionVoList);
-        build.setTotal(total);
-        return build;
-    }
-
-    /**
-     * 鏌ヨ鍘嗗彶娴佺▼瀹氫箟鍒楄〃
-     *
-     * @param key 娴佺▼瀹氫箟key
-     */
-    @Override
-    public List<ProcessDefinitionVo> getListByKey(String key) {
-        List<ProcessDefinitionVo> processDefinitionVoList = new ArrayList<>();
-        ProcessDefinitionQuery query = QueryUtils.definitionQuery();
-        List<ProcessDefinition> definitionList = query.processDefinitionKey(key).list();
-        List<Deployment> deploymentList = null;
-        if (CollUtil.isNotEmpty(definitionList)) {
-            List<String> deploymentIds = StreamUtils.toList(definitionList, ProcessDefinition::getDeploymentId);
-            deploymentList = QueryUtils.deploymentQuery(deploymentIds).list();
-        }
-        if (CollUtil.isNotEmpty(definitionList)) {
-            List<String> ids = StreamUtils.toList(definitionList, ProcessDefinition::getId);
-            List<WfDefinitionConfigVo> wfDefinitionConfigVos = wfDefinitionConfigService.queryList(ids);
-            for (ProcessDefinition processDefinition : definitionList) {
-                ProcessDefinitionVo processDefinitionVo = BeanUtil.toBean(processDefinition, ProcessDefinitionVo.class);
-                if (CollUtil.isNotEmpty(deploymentList)) {
-                    // 閮ㄧ讲鏃堕棿
-                    deploymentList.stream().filter(e -> e.getId().equals(processDefinition.getDeploymentId())).findFirst().ifPresent(e -> {
-                        processDefinitionVo.setDeploymentTime(e.getDeploymentTime());
-                    });
-                    if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) {
-                        wfDefinitionConfigVos.stream().filter(e -> e.getDefinitionId().equals(processDefinition.getId())).findFirst().ifPresent(processDefinitionVo::setWfDefinitionConfigVo);
-                    }
-                }
-                processDefinitionVoList.add(processDefinitionVo);
-            }
-        }
-        return CollUtil.reverse(processDefinitionVoList);
-    }
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟鍥剧墖
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @SneakyThrows
-    @Override
-    public String definitionImage(String processDefinitionId) {
-        InputStream inputStream = repositoryService.getProcessDiagram(processDefinitionId);
-        return Base64.encode(IoUtil.readBytes(inputStream));
-    }
-
-    /**
-     * 鏌ョ湅娴佺▼瀹氫箟xml鏂囦欢
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @Override
-    public String definitionXml(String processDefinitionId) {
-        StringBuilder xml = new StringBuilder();
-        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
-        InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
-        xml.append(IoUtil.read(inputStream, StandardCharsets.UTF_8));
-        return xml.toString();
-    }
-
-    /**
-     * 鍒犻櫎娴佺▼瀹氫箟
-     *
-     * @param deploymentIds        閮ㄧ讲id
-     * @param processDefinitionIds 娴佺▼瀹氫箟id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteDeployment(List<String> deploymentIds, List<String> processDefinitionIds) {
-        try {
-            List<HistoricProcessInstance> historicProcessInstances = QueryUtils.hisInstanceQuery().deploymentIdIn(deploymentIds).list();
-            if (CollUtil.isNotEmpty(historicProcessInstances)) {
-                Set<String> defIds = StreamUtils.toSet(historicProcessInstances, HistoricProcessInstance::getProcessDefinitionId);
-                List<ProcessDefinition> processDefinitions = QueryUtils.definitionQuery().processDefinitionIds(defIds).list();
-                if (CollUtil.isNotEmpty(processDefinitions)) {
-                    Set<String> keys = StreamUtils.toSet(processDefinitions, ProcessDefinition::getKey);
-                    throw new ServiceException("褰撳墠銆�" + String.join(",", keys) + "銆戞祦绋嬪畾涔夊凡琚娇鐢ㄤ笉鍙垹闄わ紒");
-                }
-            }
-            //鍒犻櫎娴佺▼瀹氫箟
-            for (String deploymentId : deploymentIds) {
-                repositoryService.deleteDeployment(deploymentId);
-            }
-            //鍒犻櫎娴佺▼瀹氫箟閰嶇疆
-            wfDefinitionConfigService.deleteByDefIds(processDefinitionIds);
-            //鍒犻櫎鑺傜偣閰嶇疆
-            wfNodeConfigService.deleteByDefIds(processDefinitionIds);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 婵�娲绘垨鑰呮寕璧锋祦绋嬪畾涔�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @Override
-    public boolean updateDefinitionState(String processDefinitionId) {
-        try {
-            ProcessDefinition processDefinition = QueryUtils.definitionQuery()
-                .processDefinitionId(processDefinitionId).singleResult();
-            //灏嗗綋鍓嶄负鎸傝捣鐘舵�佹洿鏂颁负婵�娲荤姸鎬�
-            //鍙傛暟璇存槑锛氬弬鏁�1锛氭祦绋嬪畾涔塱d,鍙傛暟2锛氭槸鍚︽縺娲伙紙true鏄惁绾ц仈瀵瑰簲娴佺▼瀹炰緥锛屾縺娲讳簡鍒欏搴旀祦绋嬪疄渚嬮兘鍙互瀹℃壒锛夛紝
-            //鍙傛暟3锛氫粈涔堟椂鍊欐縺娲伙紝濡傛灉涓簄ull鍒欑珛鍗虫縺娲伙紝濡傛灉涓哄叿浣撴椂闂村垯鍒拌揪姝ゆ椂闂村悗婵�娲�
-            if (processDefinition.isSuspended()) {
-                repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
-            } else {
-                repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
-            }
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException("鎿嶄綔澶辫触:" + e.getMessage());
-        }
-    }
-
-    /**
-     * 杩佺Щ娴佺▼瀹氫箟
-     *
-     * @param currentProcessDefinitionId 褰撳墠娴佺▼瀹氫箟id
-     * @param fromProcessDefinitionId    闇�瑕佽縼绉诲埌鐨勬祦绋嬪畾涔塱d
-     */
-
-    @Override
-    public boolean migrationDefinition(String currentProcessDefinitionId, String fromProcessDefinitionId) {
-        try {
-            // 杩佺Щ楠岃瘉
-            boolean migrationValid = processMigrationService.createProcessInstanceMigrationBuilder()
-                .migrateToProcessDefinition(currentProcessDefinitionId)
-                .validateMigrationOfProcessInstances(fromProcessDefinitionId)
-                .isMigrationValid();
-            if (!migrationValid) {
-                throw new ServiceException("娴佺▼瀹氫箟宸紓杩囧ぇ鏃犳硶杩佺Щ锛岃淇敼娴佺▼鍥�");
-            }
-            // 宸茬粨鏉熺殑娴佺▼瀹炰緥涓嶄細杩佺Щ
-            processMigrationService.createProcessInstanceMigrationBuilder()
-                .migrateToProcessDefinition(currentProcessDefinitionId)
-                .migrateProcessInstances(fromProcessDefinitionId);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 娴佺▼瀹氫箟杞崲涓烘ā鍨�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    @Override
-    public boolean convertToModel(String processDefinitionId) {
-        ProcessDefinition pd = QueryUtils.definitionQuery()
-            .processDefinitionId(processDefinitionId).singleResult();
-        InputStream inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getResourceName());
-        ModelQuery query = QueryUtils.modelQuery();
-        Model model = query.modelKey(pd.getKey()).singleResult();
-        try {
-            if (ObjectUtil.isNotNull(model)) {
-                repositoryService.addModelEditorSource(model.getId(), IoUtil.readBytes(inputStream));
-            } else {
-                Model modelData = repositoryService.newModel();
-                modelData.setKey(pd.getKey());
-                modelData.setName(pd.getName());
-                modelData.setCategory(pd.getCategory());
-                modelData.setTenantId(pd.getTenantId());
-                repositoryService.saveModel(modelData);
-                repositoryService.addModelEditorSource(modelData.getId(), IoUtil.readBytes(inputStream));
-            }
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 閫氳繃zip鎴杧ml閮ㄧ讲娴佺▼瀹氫箟
-     *
-     * @param file         鏂囦欢
-     * @param categoryCode 鍒嗙被
-     */
-    @SneakyThrows
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void deployByFile(MultipartFile file, String categoryCode) {
-
-        WfCategory wfCategory = wfCategoryService.queryByCategoryCode(categoryCode);
-        if (wfCategory == null) {
-            throw new ServiceException("娴佺▼鍒嗙被涓嶅瓨鍦�");
-        }
-        // 鏂囦欢鍚庣紑鍚�
-        String suffix = FileUtil.extName(file.getOriginalFilename());
-        InputStream inputStream = file.getInputStream();
-        if (FlowConstant.ZIP.equalsIgnoreCase(suffix)) {
-            ZipInputStream zipInputStream = null;
-            try {
-                zipInputStream = new ZipInputStream(inputStream);
-                ZipEntry zipEntry;
-                while ((zipEntry = zipInputStream.getNextEntry()) != null) {
-                    String filename = zipEntry.getName();
-                    String[] splitFilename = filename.substring(0, filename.lastIndexOf(".")).split("-");
-                    //娴佺▼鍚嶇О
-                    String processName = splitFilename[0];
-                    //娴佺▼key
-                    String processKey = splitFilename[1];
-                    ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
-                    DeploymentBuilder builder = repositoryService.createDeployment();
-                    Deployment deployment = builder.addInputStream(filename, zipInputStream)
-                        .tenantId(TenantHelper.getTenantId())
-                        .name(processName).key(processKey).category(categoryCode).deploy();
-                    ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
-                    repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
-                    setWfConfig(oldProcessDefinition, definition);
-                    zipInputStream.closeEntry();
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            } finally {
-                if (zipInputStream != null) {
-                    zipInputStream.close();
-                }
-            }
-            //鍒濆鍖栭厤缃暟鎹紙demo浣跨敤锛屼笉鐢ㄥ彲鍒犻櫎锛�
-            initWfDefConfig();
-        } else {
-            String originalFilename = file.getOriginalFilename();
-            if (StringUtils.containsAny(originalFilename, ResourceNameUtil.BPMN_RESOURCE_SUFFIXES)) {
-                // 鏂囦欢鍚� = 娴佺▼鍚嶇О-娴佺▼key
-                String[] splitFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")).split("-");
-                if (splitFilename.length < 2) {
-                    throw new ServiceException("鏂囦欢鍚� = 娴佺▼鍚嶇О-娴佺▼KEY");
-                }
-                //娴佺▼鍚嶇О
-                String processName = splitFilename[0];
-                //娴佺▼key
-                String processKey = splitFilename[1];
-                ProcessDefinition oldProcessDefinition = QueryUtils.definitionQuery().processDefinitionKey(processKey).latestVersion().singleResult();
-                DeploymentBuilder builder = repositoryService.createDeployment();
-                Deployment deployment = builder.addInputStream(originalFilename, inputStream)
-                    .tenantId(TenantHelper.getTenantId())
-                    .name(processName).key(processKey).category(categoryCode).deploy();
-                // 鏇存柊鍒嗙被
-                ProcessDefinition definition = QueryUtils.definitionQuery().deploymentId(deployment.getId()).singleResult();
-                repositoryService.setProcessDefinitionCategory(definition.getId(), categoryCode);
-                setWfConfig(oldProcessDefinition, definition);
-            } else {
-                throw new ServiceException("鏂囦欢绫诲瀷涓婁紶閿欒锛�");
-            }
-        }
-
-    }
-
-    /**
-     * 鍒濆鍖栭厤缃暟鎹紙demo浣跨敤锛屼笉鐢ㄥ彲鍒犻櫎锛�
-     */
-    private void initWfDefConfig() {
-        List<WfDefinitionConfig> wfDefinitionConfigs = wfDefinitionConfigMapper.selectList();
-        if (CollUtil.isEmpty(wfDefinitionConfigs)) {
-            ProcessDefinition processDefinition = QueryUtils.definitionQuery().processDefinitionKey("leave1").latestVersion().singleResult();
-            if (processDefinition != null) {
-                WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo();
-                wfDefinitionConfigBo.setDefinitionId(processDefinition.getId());
-                wfDefinitionConfigBo.setProcessKey(processDefinition.getKey());
-                wfDefinitionConfigBo.setTableName("test_leave");
-                wfDefinitionConfigBo.setVersion(processDefinition.getVersion());
-                wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo);
-            }
-        }
-
-    }
-
-    /**
-     * 璁剧疆琛ㄥ崟鍐呭
-     *
-     * @param oldProcessDefinition 閮ㄧ讲鍓嶆渶鏂版祦绋嬪畾涔�
-     * @param definition           閮ㄧ讲鍚庢渶鏂版祦绋嬪畾涔�
-     */
-    private void setWfConfig(ProcessDefinition oldProcessDefinition, ProcessDefinition definition) {
-        //鏇存柊娴佺▼瀹氫箟琛ㄥ崟
-        if (oldProcessDefinition != null) {
-            WfDefinitionConfigVo definitionVo = wfDefinitionConfigService.getByDefId(oldProcessDefinition.getId());
-            if (definitionVo != null) {
-                wfDefinitionConfigService.deleteByDefIds(Collections.singletonList(oldProcessDefinition.getId()));
-                WfDefinitionConfigBo wfDefinitionConfigBo = new WfDefinitionConfigBo();
-                wfDefinitionConfigBo.setDefinitionId(definition.getId());
-                wfDefinitionConfigBo.setProcessKey(definition.getKey());
-                wfDefinitionConfigBo.setTableName(definitionVo.getTableName());
-                wfDefinitionConfigBo.setVersion(definition.getVersion());
-                wfDefinitionConfigBo.setRemark(definitionVo.getRemark());
-                wfDefinitionConfigService.saveOrUpdate(wfDefinitionConfigBo);
-            }
-        }
-        //鏇存柊娴佺▼鑺傜偣閰嶇疆琛ㄥ崟
-        List<UserTask> userTasks = ModelUtils.getUserTaskFlowElements(definition.getId());
-        UserTask applyUserTask = ModelUtils.getApplyUserTask(definition.getId());
-        List<WfNodeConfig> wfNodeConfigList = new ArrayList<>();
-        for (UserTask userTask : userTasks) {
-            if (StringUtils.isNotBlank(userTask.getFormKey()) && userTask.getFormKey().contains(StrUtil.COLON)) {
-                WfNodeConfig wfNodeConfig = new WfNodeConfig();
-                wfNodeConfig.setNodeId(userTask.getId());
-                wfNodeConfig.setNodeName(userTask.getName());
-                wfNodeConfig.setDefinitionId(definition.getId());
-                String[] split = userTask.getFormKey().split(StrUtil.COLON);
-                wfNodeConfig.setFormType(split[0]);
-                wfNodeConfig.setFormId(Long.valueOf(split[1]));
-                wfNodeConfig.setApplyUserTask(applyUserTask.getId().equals(userTask.getId()) ? FlowConstant.TRUE : FlowConstant.FALSE);
-                wfNodeConfigList.add(wfNodeConfig);
-            }
-        }
-        if (CollUtil.isNotEmpty(wfNodeConfigList)) {
-            wfNodeConfigService.saveOrUpdate(wfNodeConfigList);
-        }
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java
deleted file mode 100644
index 8b9b113..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java
+++ /dev/null
@@ -1,691 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.ObjectUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.enums.BusinessStatusEnum;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.service.UserService;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.domain.ActHiProcinst;
-import org.dromara.workflow.domain.bo.ProcessInstanceBo;
-import org.dromara.workflow.domain.bo.ProcessInvalidBo;
-import org.dromara.workflow.domain.bo.TaskUrgingBo;
-import org.dromara.workflow.domain.vo.*;
-import org.dromara.workflow.flowable.CustomDefaultProcessDiagramGenerator;
-import org.dromara.workflow.flowable.cmd.DeleteExecutionCmd;
-import org.dromara.workflow.flowable.cmd.ExecutionChildByExecutionIdCmd;
-import org.dromara.workflow.flowable.handler.FlowProcessEventHandler;
-import org.dromara.workflow.service.IActHiProcinstService;
-import org.dromara.workflow.service.IActProcessInstanceService;
-import org.dromara.workflow.service.IWfNodeConfigService;
-import org.dromara.workflow.service.IWfTaskBackNodeService;
-import org.dromara.workflow.utils.QueryUtils;
-import org.dromara.workflow.utils.WorkflowUtils;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.engine.*;
-import org.flowable.engine.history.HistoricActivityInstance;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.history.HistoricProcessInstanceQuery;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.flowable.engine.runtime.ProcessInstance;
-import org.flowable.engine.runtime.ProcessInstanceQuery;
-import org.flowable.engine.task.Attachment;
-import org.flowable.engine.task.Comment;
-import org.flowable.task.api.Task;
-import org.flowable.task.api.history.HistoricTaskInstance;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.awt.*;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-import java.util.*;
-
-/**
- * 娴佺▼瀹炰緥 鏈嶅姟灞傚疄鐜�
- *
- * @author may
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class ActProcessInstanceServiceImpl implements IActProcessInstanceService {
-
-    @Autowired(required = false)
-    private RepositoryService repositoryService;
-    @Autowired(required = false)
-    private RuntimeService runtimeService;
-    @Autowired(required = false)
-    private HistoryService historyService;
-    @Autowired(required = false)
-    private TaskService taskService;
-    @Autowired(required = false)
-    private ManagementService managementService;
-    private final IActHiProcinstService actHiProcinstService;
-    private final IWfTaskBackNodeService wfTaskBackNodeService;
-    private final IWfNodeConfigService wfNodeConfigService;
-    private final FlowProcessEventHandler flowProcessEventHandler;
-    private final UserService userService;
-
-    @Value("${flowable.activity-font-name}")
-    private String activityFontName;
-
-    @Value("${flowable.label-font-name}")
-    private String labelFontName;
-
-    @Value("${flowable.annotation-font-name}")
-    private String annotationFontName;
-
-    /**
-     * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
-     *
-     * @param bo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<ProcessInstanceVo> getPageByRunning(ProcessInstanceBo bo, PageQuery pageQuery) {
-        List<ProcessInstanceVo> list = new ArrayList<>();
-        ProcessInstanceQuery query = QueryUtils.instanceQuery();
-        if (StringUtils.isNotBlank(bo.getName())) {
-            query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%");
-        }
-        if (StringUtils.isNotBlank(bo.getKey())) {
-            query.processDefinitionKey(bo.getKey());
-        }
-        if (StringUtils.isNotBlank(bo.getStartUserId())) {
-            query.startedBy(bo.getStartUserId());
-        }
-        if (StringUtils.isNotBlank(bo.getBusinessKey())) {
-            query.processInstanceBusinessKey(bo.getBusinessKey());
-        }
-        if (StringUtils.isNotBlank(bo.getCategoryCode())) {
-            query.processDefinitionCategory(bo.getCategoryCode());
-        }
-        query.orderByStartTime().desc();
-        List<ProcessInstance> processInstances = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        for (ProcessInstance processInstance : processInstances) {
-            ProcessInstanceVo processInstanceVo = BeanUtil.toBean(processInstance, ProcessInstanceVo.class);
-            processInstanceVo.setIsSuspended(processInstance.isSuspended());
-            processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstance.getBusinessStatus()));
-            list.add(processInstanceVo);
-        }
-        if (CollUtil.isNotEmpty(list)) {
-            List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (ProcessInstanceVo processInstanceVo : list) {
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo);
-                }
-            }
-        }
-        long count = query.count();
-        TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build();
-        build.setRows(list);
-        build.setTotal(count);
-        return build;
-    }
-
-    /**
-     * 鍒嗛〉鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥
-     *
-     * @param bo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<ProcessInstanceVo> getPageByFinish(ProcessInstanceBo bo, PageQuery pageQuery) {
-        List<ProcessInstanceVo> list = new ArrayList<>();
-        HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery()
-            .finished().orderByProcessInstanceEndTime().desc();
-        if (StringUtils.isNotEmpty(bo.getName())) {
-            query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%");
-        }
-        if (StringUtils.isNotBlank(bo.getKey())) {
-            query.processDefinitionKey(bo.getKey());
-        }
-        if (StringUtils.isNotEmpty(bo.getStartUserId())) {
-            query.startedBy(bo.getStartUserId());
-        }
-        if (StringUtils.isNotBlank(bo.getBusinessKey())) {
-            query.processInstanceBusinessKey(bo.getBusinessKey());
-        }
-        if (StringUtils.isNotBlank(bo.getCategoryCode())) {
-            query.processDefinitionCategory(bo.getCategoryCode());
-        }
-        List<HistoricProcessInstance> historicProcessInstances = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
-            ProcessInstanceVo processInstanceVo = BeanUtil.toBean(historicProcessInstance, ProcessInstanceVo.class);
-            processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(historicProcessInstance.getBusinessStatus()));
-            list.add(processInstanceVo);
-        }
-        if (CollUtil.isNotEmpty(list)) {
-            List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (ProcessInstanceVo processInstanceVo : list) {
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo);
-                }
-            }
-        }
-        long count = query.count();
-        TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build();
-        build.setRows(list);
-        build.setTotal(count);
-        return build;
-    }
-
-    /**
-     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥�
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @SneakyThrows
-    @Override
-    public String getHistoryImage(String businessKey) {
-        String processDefinitionId;
-        // 鑾峰彇褰撳墠鐨勬祦绋嬪疄渚�
-        ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey).singleResult();
-        // 濡傛灉娴佺▼宸茬粡缁撴潫锛屽垯寰楀埌缁撴潫鑺傜偣
-        if (Objects.isNull(processInstance)) {
-            HistoricProcessInstance pi = QueryUtils.hisInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();
-            processDefinitionId = pi.getProcessDefinitionId();
-        } else {
-            // 鏍规嵁娴佺▼瀹炰緥ID鑾峰緱褰撳墠澶勪簬娲诲姩鐘舵�佺殑ActivityId鍚堥泦
-            ProcessInstance pi = QueryUtils.instanceQuery(processInstance.getProcessInstanceId()).singleResult();
-            processDefinitionId = pi.getProcessDefinitionId();
-        }
-
-        // 鑾峰緱娲诲姩鐨勮妭鐐�
-        List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstance.getProcessInstanceId()).orderByHistoricActivityInstanceStartTime().asc().list();
-
-        List<String> highLightedFlows = new ArrayList<>();
-        List<String> highLightedNodes = new ArrayList<>();
-        //楂樹寒
-        for (HistoricActivityInstance tempActivity : highLightedFlowList) {
-            if (FlowConstant.SEQUENCE_FLOW.equals(tempActivity.getActivityType())) {
-                //楂樹寒绾�
-                highLightedFlows.add(tempActivity.getActivityId());
-            } else {
-                //楂樹寒鑺傜偣
-                if (tempActivity.getEndTime() == null) {
-                    highLightedNodes.add(Color.RED.toString() + tempActivity.getActivityId());
-                } else {
-                    highLightedNodes.add(tempActivity.getActivityId());
-                }
-            }
-        }
-        List<String> highLightedNodeList = new ArrayList<>();
-        //杩愯涓殑鑺傜偣
-        List<String> redNodeCollect = StreamUtils.filter(highLightedNodes, e -> e.contains(Color.RED.toString()));
-        //鎺掗櫎涓庤繍琛屼腑鐩稿悓鐨勮妭鐐�
-        for (String nodeId : highLightedNodes) {
-            if (!nodeId.contains(Color.RED.toString()) && !redNodeCollect.contains(Color.RED + nodeId)) {
-                highLightedNodeList.add(nodeId);
-            }
-        }
-        highLightedNodeList.addAll(redNodeCollect);
-        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
-        CustomDefaultProcessDiagramGenerator diagramGenerator = new CustomDefaultProcessDiagramGenerator();
-        InputStream inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedNodeList, highLightedFlows, activityFontName, labelFontName, annotationFontName, null, 1.0, true);
-        return Base64.encode(IoUtil.readBytes(inputStream));
-    }
-
-    /**
-     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @Override
-    public Map<String, Object> getHistoryList(String businessKey) {
-        Map<String, Object> map = new HashMap<>();
-        List<Map<String, Object>> taskList = new ArrayList<>();
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
-        String processInstanceId = historicProcessInstance.getId();
-        StringBuilder xml = new StringBuilder();
-        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
-        // 鑾峰彇鑺傜偣
-        List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
-        for (HistoricActivityInstance tempActivity : highLightedFlowList) {
-            Map<String, Object> task = new HashMap<>();
-            switch (tempActivity.getActivityType()) {
-                case FlowConstant.SEQUENCE_FLOW, FlowConstant.PARALLEL_GATEWAY,
-                     FlowConstant.EXCLUSIVE_GATEWAY, FlowConstant.INCLUSIVE_GATEWAY -> {}
-                default -> {
-                    task.put("key", tempActivity.getActivityId());
-                    task.put("completed", tempActivity.getEndTime() != null);
-                    task.put("activityType", tempActivity.getActivityType());
-                    taskList.add(task);
-                }
-            }
-        }
-        ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId).singleResult();
-        if (processInstance != null) {
-            taskList = StreamUtils.filter(taskList, e -> !e.get("activityType").equals(FlowConstant.END_EVENT));
-        }
-        //鏌ヨ鍑鸿繍琛屼腑鑺傜偣
-        List<Map<String, Object>> runtimeNodeList = StreamUtils.filter(taskList, e -> !(Boolean) e.get("completed"));
-        if (CollUtil.isNotEmpty(runtimeNodeList)) {
-            Iterator<Map<String, Object>> iterator = taskList.iterator();
-            while (iterator.hasNext()) {
-                Map<String, Object> next = iterator.next();
-                runtimeNodeList.stream().filter(t -> t.get("key").equals(next.get("key")) && (Boolean) next.get("completed")).findFirst().ifPresent(t -> iterator.remove());
-            }
-        }
-        map.put("taskList", taskList);
-        List<ActHistoryInfoVo> historyTaskList = getHistoryTaskList(processInstanceId, processDefinition.getVersion());
-        map.put("historyList", historyTaskList);
-        InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
-        xml.append(IoUtil.read(inputStream, StandardCharsets.UTF_8));
-        map.put("xml", xml.toString());
-        return map;
-    }
-
-    /**
-     * 鑾峰彇鍘嗗彶浠诲姟鑺傜偣淇℃伅
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     * @param version           鐗堟湰
-     */
-    private List<ActHistoryInfoVo> getHistoryTaskList(String processInstanceId, Integer version) {
-        //鏌ヨ浠诲姟鍔炵悊璁板綍
-        List<HistoricTaskInstance> list = QueryUtils.hisTaskInstanceQuery(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list();
-        list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo)).reversed());
-        List<ActHistoryInfoVo> actHistoryInfoVoList = new ArrayList<>();
-        for (HistoricTaskInstance historicTaskInstance : list) {
-            ActHistoryInfoVo actHistoryInfoVo = new ActHistoryInfoVo();
-            BeanUtils.copyProperties(historicTaskInstance, actHistoryInfoVo);
-            actHistoryInfoVo.setStatus(actHistoryInfoVo.getEndTime() == null ? "寰呭鐞�" : "宸插鐞�");
-            if (ObjectUtil.isNotEmpty(historicTaskInstance.getDurationInMillis())) {
-                actHistoryInfoVo.setRunDuration(getDuration(historicTaskInstance.getDurationInMillis()));
-            }
-            actHistoryInfoVo.setVersion(version);
-            actHistoryInfoVoList.add(actHistoryInfoVo);
-        }
-        List<ActHistoryInfoVo> historyInfoVoList = new ArrayList<>();
-        Map<String, List<ActHistoryInfoVo>> groupByKey = StreamUtils.groupByKey(actHistoryInfoVoList, ActHistoryInfoVo::getTaskDefinitionKey);
-        for (Map.Entry<String, List<ActHistoryInfoVo>> entry : groupByKey.entrySet()) {
-            ActHistoryInfoVo historyInfoVo = new ActHistoryInfoVo();
-            if (entry.getValue().size() > 1) {
-                List<ActHistoryInfoVo> historyInfoVos = StreamUtils.filter(entry.getValue(), e -> StringUtils.isNotBlank(e.getAssignee()));
-                if (CollUtil.isNotEmpty(historyInfoVos)) {
-                    ActHistoryInfoVo infoVo = historyInfoVos.get(0);
-                    BeanUtils.copyProperties(infoVo, historyInfoVo);
-                    historyInfoVo.setStatus(infoVo.getEndTime() == null ? "寰呭鐞�" : "宸插鐞�");
-                    historyInfoVo.setStartTime(infoVo.getStartTime());
-                    historyInfoVo.setEndTime(infoVo.getEndTime() == null ? null : infoVo.getEndTime());
-                    historyInfoVo.setRunDuration(infoVo.getEndTime() == null ? null : infoVo.getRunDuration());
-                    if (ObjectUtil.isEmpty(infoVo.getAssignee())) {
-                        ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(infoVo.getId(), userService);
-                        if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) {
-                            historyInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr));
-                        }
-                    }
-                }
-            } else {
-                actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey())).findFirst()
-                    .ifPresent(e -> {
-                        BeanUtils.copyProperties(e, historyInfoVo);
-                        historyInfoVo.setStatus(e.getEndTime() == null ? "寰呭鐞�" : "宸插鐞�");
-                        historyInfoVo.setStartTime(e.getStartTime());
-                        historyInfoVo.setEndTime(e.getEndTime() == null ? null : e.getEndTime());
-                        historyInfoVo.setRunDuration(e.getEndTime() == null ? null : e.getRunDuration());
-                        if (ObjectUtil.isEmpty(e.getAssignee())) {
-                            ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(e.getId(), userService);
-                            if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) {
-                                historyInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr));
-                            }
-                        }
-                    });
-
-            }
-            historyInfoVoList.add(historyInfoVo);
-
-        }
-        return historyInfoVoList;
-    }
-
-    /**
-     * 鑾峰彇瀹℃壒璁板綍
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @Override
-    public List<ActHistoryInfoVo> getHistoryRecord(String businessKey) {
-        // 鏌ヨ浠诲姟鍔炵悊璁板綍
-        List<HistoricTaskInstance> list = QueryUtils.hisTaskBusinessKeyQuery(businessKey).orderByHistoricTaskInstanceEndTime().desc().list();
-        list = StreamUtils.sorted(list, Comparator.comparing(HistoricTaskInstance::getEndTime, Comparator.nullsFirst(Date::compareTo)).reversed());
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
-        String processInstanceId = historicProcessInstance.getId();
-        List<ActHistoryInfoVo> actHistoryInfoVoList = new ArrayList<>();
-        List<Comment> processInstanceComments = taskService.getProcessInstanceComments(processInstanceId);
-        //闄勪欢
-        List<Attachment> attachmentList = taskService.getProcessInstanceAttachments(processInstanceId);
-        for (HistoricTaskInstance historicTaskInstance : list) {
-            ActHistoryInfoVo actHistoryInfoVo = new ActHistoryInfoVo();
-            BeanUtils.copyProperties(historicTaskInstance, actHistoryInfoVo);
-            if (actHistoryInfoVo.getEndTime() == null) {
-                actHistoryInfoVo.setStatus(TaskStatusEnum.WAITING.getStatus());
-                actHistoryInfoVo.setStatusName(TaskStatusEnum.WAITING.getDesc());
-            }
-            if (CollUtil.isNotEmpty(processInstanceComments)) {
-                processInstanceComments.stream().filter(e -> e.getTaskId().equals(historicTaskInstance.getId())).findFirst().ifPresent(e -> {
-                    actHistoryInfoVo.setComment(e.getFullMessage());
-                    actHistoryInfoVo.setStatus(e.getType());
-                    actHistoryInfoVo.setStatusName(TaskStatusEnum.findByStatus(e.getType()));
-                });
-            }
-            if (ObjectUtil.isNotEmpty(historicTaskInstance.getDurationInMillis())) {
-                actHistoryInfoVo.setRunDuration(getDuration(historicTaskInstance.getDurationInMillis()));
-            }
-            //闄勪欢
-            if (CollUtil.isNotEmpty(attachmentList)) {
-                List<Attachment> attachments = StreamUtils.filter(attachmentList, e -> e.getTaskId().equals(historicTaskInstance.getId()));
-                if (CollUtil.isNotEmpty(attachments)) {
-                    actHistoryInfoVo.setAttachmentList(attachments);
-                }
-            }
-            //璁剧疆浜哄憳id
-            if (ObjectUtil.isEmpty(historicTaskInstance.getAssignee())) {
-                ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(historicTaskInstance.getId(), userService);
-                if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) {
-                    actHistoryInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr));
-                }
-            }
-            actHistoryInfoVoList.add(actHistoryInfoVo);
-        }
-        // 瀹℃壒璁板綍
-        Map<String, List<ActHistoryInfoVo>> groupByKey = StreamUtils.groupByKey(actHistoryInfoVoList, ActHistoryInfoVo::getTaskDefinitionKey);
-        for (Map.Entry<String, List<ActHistoryInfoVo>> entry : groupByKey.entrySet()) {
-            ActHistoryInfoVo actHistoryInfoVo = BeanUtil.toBean(entry.getValue().get(0), ActHistoryInfoVo.class);
-            actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() != null).findFirst()
-                .ifPresent(e -> {
-                    actHistoryInfoVo.setStatus("宸插鐞�");
-                    actHistoryInfoVo.setStartTime(e.getStartTime());
-                });
-            actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() == null).findFirst()
-                .ifPresent(e -> {
-                    actHistoryInfoVo.setStatus("寰呭鐞�");
-                    actHistoryInfoVo.setStartTime(e.getStartTime());
-                    actHistoryInfoVo.setEndTime(null);
-                    actHistoryInfoVo.setRunDuration(null);
-                });
-        }
-        List<ActHistoryInfoVo> recordList = new ArrayList<>();
-        // 寰呭姙鐞�
-        recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() == null));
-        // 宸插姙鐞�
-        recordList.addAll(StreamUtils.filter(actHistoryInfoVoList, e -> e.getEndTime() != null));
-
-        return recordList;
-    }
-
-    /**
-     * 浠诲姟瀹屾垚鏃堕棿澶勭悊
-     *
-     * @param time 鏃堕棿
-     */
-    private String getDuration(long time) {
-
-        long day = time / (24 * 60 * 60 * 1000);
-        long hour = (time / (60 * 60 * 1000) - day * 24);
-        long minute = ((time / (60 * 1000)) - day * 24 * 60 - hour * 60);
-        long second = (time / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
-
-        if (day > 0) {
-            return day + "澶�" + hour + "灏忔椂" + minute + "鍒嗛挓";
-        }
-        if (hour > 0) {
-            return hour + "灏忔椂" + minute + "鍒嗛挓";
-        }
-        if (minute > 0) {
-            return minute + "鍒嗛挓";
-        }
-        if (second > 0) {
-            return second + "绉�";
-        } else {
-            return 0 + "绉�";
-        }
-    }
-
-    /**
-     * 浣滃簾娴佺▼瀹炰緥锛屼笉浼氬垹闄ゅ巻鍙茶褰�(鍒犻櫎杩愯涓殑瀹炰緥)
-     *
-     * @param processInvalidBo 鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteRunInstance(ProcessInvalidBo processInvalidBo) {
-        try {
-            List<Task> list = QueryUtils.taskQuery().processInstanceBusinessKey(processInvalidBo.getBusinessKey()).list();
-            String processInstanceId = list.get(0).getProcessInstanceId();
-            List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId()));
-            if (CollUtil.isNotEmpty(subTasks)) {
-                subTasks.forEach(e -> taskService.deleteTask(e.getId()));
-            }
-            String deleteReason = LoginHelper.getLoginUser().getNickname() + "浣滃簾浜嗗綋鍓嶇敵璇凤紒";
-            if (StringUtils.isNotBlank(processInvalidBo.getDeleteReason())) {
-                deleteReason = LoginHelper.getLoginUser().getNickname() + "浣滃簾鐞嗙敱:" + processInvalidBo.getDeleteReason();
-            }
-            for (Task task : StreamUtils.filter(list, e -> StringUtils.isBlank(e.getParentTaskId()))) {
-                taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.INVALID.getStatus(), deleteReason);
-            }
-            HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult();
-            BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus());
-            runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.INVALID.getStatus());
-            runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
-            //娴佺▼浣滃簾鐩戝惉
-            flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(),
-                historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteRunAndHisInstance(List<String> businessKeys) {
-        try {
-            // 1.鍒犻櫎杩愯涓祦绋嬪疄渚�
-            List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys);
-            if (CollUtil.isEmpty(actHiProcinsts)) {
-                log.warn("褰撳墠涓氬姟ID:{}鏌ヨ鍒版祦绋嬪疄渚嬩负绌猴紒", businessKeys);
-                return false;
-            }
-            List<String> processInstanceIds = StreamUtils.toList(actHiProcinsts, ActHiProcinst::getId);
-            List<Task> list = QueryUtils.taskQuery(processInstanceIds).list();
-            List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId()));
-            if (CollUtil.isNotEmpty(subTasks)) {
-                subTasks.forEach(e -> taskService.deleteTask(e.getId()));
-            }
-            runtimeService.bulkDeleteProcessInstances(processInstanceIds, LoginHelper.getUserId() + "鍒犻櫎浜嗗綋鍓嶆祦绋嬬敵璇�");
-            // 2.鍒犻櫎鍘嗗彶璁板綍
-            List<HistoricProcessInstance> historicProcessInstanceList = QueryUtils.hisInstanceQuery(new HashSet<>(processInstanceIds)).list();
-            if (ObjectUtil.isNotEmpty(historicProcessInstanceList)) {
-                historyService.bulkDeleteHistoricProcessInstances(processInstanceIds);
-            }
-            wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
-     * @param businessKeys 涓氬姟id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteFinishAndHisInstance(List<String> businessKeys) {
-        try {
-            List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys);
-            if (CollUtil.isEmpty(actHiProcinsts)) {
-                log.warn("褰撳墠涓氬姟ID:{}鏌ヨ鍒版祦绋嬪疄渚嬩负绌猴紒", businessKeys);
-                return false;
-            }
-            List<String> processInstanceIds = StreamUtils.toList(actHiProcinsts, ActHiProcinst::getId);
-            historyService.bulkDeleteHistoricProcessInstances(processInstanceIds);
-            wfTaskBackNodeService.deleteByInstanceIds(processInstanceIds);
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 鎾ら攢娴佺▼鐢宠
-     *
-     * @param businessKey 涓氬姟id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean cancelProcessApply(String businessKey) {
-        try {
-            ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey)
-                .startedBy(String.valueOf(LoginHelper.getUserId())).singleResult();
-            if (ObjectUtil.isNull(processInstance)) {
-                throw new ServiceException("鎮ㄤ笉鏄祦绋嬪彂璧蜂汉,鎾ら攢澶辫触!");
-            }
-            if (processInstance.isSuspended()) {
-                throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-            }
-            String processInstanceId = processInstance.getId();
-            BusinessStatusEnum.checkCancelStatus(processInstance.getBusinessStatus());
-            List<Task> taskList = QueryUtils.taskQuery(processInstanceId).list();
-            for (Task task : taskList) {
-                taskService.setAssignee(task.getId(), null);
-                taskService.addComment(task.getId(), processInstanceId, TaskStatusEnum.CANCEL.getStatus(), LoginHelper.getLoginUser().getNickname() + "锛氭挙閿�鐢宠");
-            }
-            HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0);
-            List<String> nodeIds = StreamUtils.toList(taskList, Task::getTaskDefinitionKey);
-            runtimeService.createChangeActivityStateBuilder()
-                .processInstanceId(processInstanceId)
-                .moveActivityIdsToSingleActivityId(nodeIds, historicTaskInstance.getTaskDefinitionKey()).changeState();
-            Task task = QueryUtils.taskQuery(processInstanceId).list().get(0);
-            taskService.setAssignee(task.getId(), historicTaskInstance.getAssignee());
-            //鑾峰彇骞惰缃戝叧鎵ц鍚庝繚鐣欑殑鎵ц瀹炰緥鏁版嵁
-            ExecutionChildByExecutionIdCmd childByExecutionIdCmd = new ExecutionChildByExecutionIdCmd(task.getExecutionId());
-            List<ExecutionEntity> executionEntities = managementService.executeCommand(childByExecutionIdCmd);
-            //鍒犻櫎娴佺▼瀹炰緥鍨冨溇鏁版嵁
-            for (ExecutionEntity executionEntity : executionEntities) {
-                DeleteExecutionCmd deleteExecutionCmd = new DeleteExecutionCmd(executionEntity.getId());
-                managementService.executeCommand(deleteExecutionCmd);
-            }
-            runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.CANCEL.getStatus());
-            //娴佺▼浣滃簾鐩戝惉
-            flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
-                processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false);
-            return true;
-        } catch (Exception e) {
-            log.error("鎾ら攢澶辫触:" + e.getMessage(), e);
-            throw new ServiceException("鎾ら攢澶辫触:" + e.getMessage());
-        }
-    }
-
-    /**
-     * 鍒嗛〉鏌ヨ褰撳墠鐧诲綍浜哄崟鎹�
-     *
-     * @param bo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<ProcessInstanceVo> getPageByCurrent(ProcessInstanceBo bo, PageQuery pageQuery) {
-        List<ProcessInstanceVo> list = new ArrayList<>();
-        HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery();
-        query.startedBy(String.valueOf(LoginHelper.getUserId()));
-        if (StringUtils.isNotBlank(bo.getName())) {
-            query.processInstanceNameLikeIgnoreCase("%" + bo.getName() + "%");
-        }
-        if (StringUtils.isNotBlank(bo.getKey())) {
-            query.processDefinitionKey(bo.getKey());
-        }
-        if (StringUtils.isNotBlank(bo.getBusinessKey())) {
-            query.processInstanceBusinessKey(bo.getBusinessKey());
-        }
-        if (StringUtils.isNotBlank(bo.getCategoryCode())) {
-            query.processDefinitionCategory(bo.getCategoryCode());
-        }
-        query.orderByProcessInstanceStartTime().desc();
-        List<HistoricProcessInstance> historicProcessInstanceList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        List<TaskVo> taskVoList = new ArrayList<>();
-        if (CollUtil.isNotEmpty(historicProcessInstanceList)) {
-            List<String> processInstanceIds = StreamUtils.toList(historicProcessInstanceList, HistoricProcessInstance::getId);
-            List<Task> taskList = QueryUtils.taskQuery(processInstanceIds).list();
-            for (Task task : taskList) {
-                taskVoList.add(BeanUtil.toBean(task, TaskVo.class));
-            }
-        }
-        for (HistoricProcessInstance processInstance : historicProcessInstanceList) {
-            ProcessInstanceVo processInstanceVo = BeanUtil.toBean(processInstance, ProcessInstanceVo.class);
-            processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstance.getBusinessStatus()));
-            if (CollUtil.isNotEmpty(taskVoList)) {
-                List<TaskVo> collect = StreamUtils.filter(taskVoList, e -> e.getProcessInstanceId().equals(processInstance.getId()));
-                processInstanceVo.setTaskVoList(CollUtil.isNotEmpty(collect) ? collect : Collections.emptyList());
-            }
-            list.add(processInstanceVo);
-        }
-        if (CollUtil.isNotEmpty(list)) {
-            List<String> processDefinitionIds = StreamUtils.toList(list, ProcessInstanceVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (ProcessInstanceVo processInstanceVo : list) {
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(processInstanceVo.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(processInstanceVo::setWfNodeConfigVo);
-                }
-            }
-        }
-        long count = query.count();
-        TableDataInfo<ProcessInstanceVo> build = TableDataInfo.build();
-        build.setRows(list);
-        build.setTotal(count);
-        return build;
-    }
-
-    /**
-     * 浠诲姟鍌姙(缁欏綋鍓嶄换鍔″姙鐞嗕汉鍙戦�佺珯鍐呬俊锛岄偖浠讹紝鐭俊绛�)
-     *
-     * @param taskUrgingBo 浠诲姟鍌姙
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean taskUrging(TaskUrgingBo taskUrgingBo) {
-        try {
-            ProcessInstance processInstance = QueryUtils.instanceQuery(taskUrgingBo.getProcessInstanceId()).singleResult();
-            if (processInstance == null) {
-                throw new ServiceException("浠诲姟宸茬粨鏉燂紒");
-            }
-            String message = taskUrgingBo.getMessage();
-            if (StringUtils.isBlank(message)) {
-                message = "鎮ㄧ殑銆�" + processInstance.getName() + "銆戝崟鎹繕鏈鎵癸紝璇锋偍鍙婃椂澶勭悊銆�";
-            }
-            List<Task> list = QueryUtils.taskQuery(taskUrgingBo.getProcessInstanceId()).list();
-            WorkflowUtils.sendMessage(list, processInstance.getName(), taskUrgingBo.getMessageType(), message, userService);
-        } catch (ServiceException e) {
-            throw new ServiceException(e.getMessage());
-        }
-        return true;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java
deleted file mode 100644
index d9a674a..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java
+++ /dev/null
@@ -1,861 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.domain.dto.RoleDTO;
-import org.dromara.common.core.domain.dto.UserDTO;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.service.OssService;
-import org.dromara.common.core.service.UserService;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.common.core.enums.BusinessStatusEnum;
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.domain.ActHiTaskinst;
-import org.dromara.workflow.domain.WfTaskBackNode;
-import org.dromara.workflow.domain.bo.*;
-import org.dromara.workflow.domain.vo.*;
-import org.dromara.workflow.flowable.cmd.*;
-import org.dromara.workflow.flowable.handler.FlowProcessEventHandler;
-import org.dromara.workflow.mapper.ActHiTaskinstMapper;
-import org.dromara.workflow.mapper.ActTaskMapper;
-import org.dromara.workflow.service.IActTaskService;
-import org.dromara.workflow.service.IWfDefinitionConfigService;
-import org.dromara.workflow.service.IWfNodeConfigService;
-import org.dromara.workflow.service.IWfTaskBackNodeService;
-import org.dromara.workflow.utils.ModelUtils;
-import org.dromara.workflow.utils.QueryUtils;
-import org.dromara.workflow.utils.WorkflowUtils;
-import org.flowable.common.engine.api.FlowableObjectNotFoundException;
-import org.flowable.common.engine.impl.identity.Authentication;
-import org.flowable.engine.*;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.history.HistoricProcessInstanceQuery;
-import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
-import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
-import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
-import org.flowable.engine.runtime.ProcessInstance;
-import org.flowable.identitylink.api.history.HistoricIdentityLink;
-import org.flowable.task.api.Task;
-import org.flowable.task.api.TaskQuery;
-import org.flowable.task.api.history.HistoricTaskInstance;
-import org.flowable.task.service.impl.persistence.entity.TaskEntity;
-import org.flowable.variable.api.persistence.entity.VariableInstance;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static org.dromara.workflow.common.constant.FlowConstant.*;
-
-/**
- * 浠诲姟 鏈嶅姟灞傚疄鐜�
- *
- * @author may
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class ActTaskServiceImpl implements IActTaskService {
-
-    @Autowired(required = false)
-    private RuntimeService runtimeService;
-    @Autowired(required = false)
-    private TaskService taskService;
-    @Autowired(required = false)
-    private HistoryService historyService;
-    @Autowired(required = false)
-    private IdentityService identityService;
-    @Autowired(required = false)
-    private ManagementService managementService;
-    private final ActTaskMapper actTaskMapper;
-    private final IWfTaskBackNodeService wfTaskBackNodeService;
-    private final ActHiTaskinstMapper actHiTaskinstMapper;
-    private final IWfNodeConfigService wfNodeConfigService;
-    private final IWfDefinitionConfigService wfDefinitionConfigService;
-    private final FlowProcessEventHandler flowProcessEventHandler;
-    private final UserService userService;
-    private final OssService ossService;
-
-    /**
-     * 鍚姩浠诲姟
-     *
-     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Map<String, Object> startWorkFlow(StartProcessBo startProcessBo) {
-        Map<String, Object> map = new HashMap<>();
-        if (StringUtils.isBlank(startProcessBo.getBusinessKey())) {
-            throw new ServiceException("鍚姩宸ヤ綔娴佹椂蹇呴』鍖呭惈涓氬姟ID");
-        }
-        // 鍒ゆ柇褰撳墠涓氬姟鏄惁鍚姩杩囨祦绋�
-        HistoricProcessInstanceQuery query = QueryUtils.hisInstanceQuery();
-        HistoricProcessInstance historicProcessInstance = query.processInstanceBusinessKey(startProcessBo.getBusinessKey()).singleResult();
-        if (ObjectUtil.isNotEmpty(historicProcessInstance)) {
-            BusinessStatusEnum.checkStartStatus(historicProcessInstance.getBusinessStatus());
-        }
-        List<Task> taskResult = QueryUtils.taskQuery().processInstanceBusinessKey(startProcessBo.getBusinessKey()).list();
-        if (CollUtil.isNotEmpty(taskResult)) {
-            if (CollUtil.isNotEmpty(startProcessBo.getVariables())) {
-                taskService.setVariables(taskResult.get(0).getId(), startProcessBo.getVariables());
-            }
-            map.put(PROCESS_INSTANCE_ID, taskResult.get(0).getProcessInstanceId());
-            map.put("taskId", taskResult.get(0).getId());
-            return map;
-        }
-        WfDefinitionConfigVo wfDefinitionConfigVo = wfDefinitionConfigService.getByTableNameLastVersion(startProcessBo.getTableName());
-        if (wfDefinitionConfigVo == null) {
-            throw new ServiceException("璇峰埌娴佺▼瀹氫箟缁戝畾涓氬姟琛ㄥ悕涓庢祦绋婯EY锛�");
-        }
-        // 璁剧疆鍚姩浜�
-        identityService.setAuthenticatedUserId(String.valueOf(LoginHelper.getUserId()));
-        Authentication.setAuthenticatedUserId(String.valueOf(LoginHelper.getUserId()));
-        // 鍚姩娴佺▼瀹炰緥锛堟彁浜ょ敵璇凤級
-        Map<String, Object> variables = startProcessBo.getVariables();
-        // 鍚姩璺宠繃琛ㄨ揪寮�
-        variables.put(FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
-        // 娴佺▼鍙戣捣浜�
-        variables.put(INITIATOR, (String.valueOf(LoginHelper.getUserId())));
-        ProcessInstance pi;
-        try {
-            if (TenantHelper.isEnable()) {
-                pi = runtimeService.startProcessInstanceByKeyAndTenantId(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables, TenantHelper.getTenantId());
-            } else {
-                pi = runtimeService.startProcessInstanceByKey(wfDefinitionConfigVo.getProcessKey(), startProcessBo.getBusinessKey(), variables);
-            }
-        } catch (FlowableObjectNotFoundException e) {
-            throw new ServiceException("鎵句笉鍒板綋鍓嶃��" + wfDefinitionConfigVo.getProcessKey() + "銆戞祦绋嬪畾涔夛紒");
-        }
-        // 灏嗘祦绋嬪畾涔夊悕绉� 浣滀负 娴佺▼瀹炰緥鍚嶇О
-        runtimeService.setProcessInstanceName(pi.getProcessInstanceId(), pi.getProcessDefinitionName());
-        // 鐢宠浜烘墽琛屾祦绋�
-        List<Task> taskList = QueryUtils.taskQuery(pi.getId()).list();
-        if (taskList.size() > 1) {
-            throw new ServiceException("璇锋鏌ユ祦绋嬬涓�涓幆鑺傛槸鍚︿负鐢宠浜猴紒");
-        }
-
-        runtimeService.updateBusinessStatus(pi.getProcessInstanceId(), BusinessStatusEnum.DRAFT.getStatus());
-        taskService.setAssignee(taskList.get(0).getId(), LoginHelper.getUserId().toString());
-        taskService.setVariable(taskList.get(0).getId(), PROCESS_INSTANCE_ID, pi.getProcessInstanceId());
-        taskService.setVariable(taskList.get(0).getId(), BUSINESS_KEY, pi.getBusinessKey());
-        map.put("processInstanceId", pi.getProcessInstanceId());
-        map.put("taskId", taskList.get(0).getId());
-        return map;
-    }
-
-    /**
-     * 鍔炵悊浠诲姟
-     *
-     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean completeTask(CompleteTaskBo completeTaskBo) {
-        try {
-            String userId = String.valueOf(LoginHelper.getUserId());
-            Task task = WorkflowUtils.getTaskByCurrentUser(completeTaskBo.getTaskId());
-            if (task == null) {
-                throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-            }
-            if (task.isSuspended()) {
-                throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-            }
-            ProcessInstance processInstance = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult();
-            //鍔炵悊濮旀墭浠诲姟
-            if (ObjectUtil.isNotEmpty(task.getDelegationState()) && FlowConstant.PENDING.equals(task.getDelegationState().name())) {
-                taskService.resolveTask(completeTaskBo.getTaskId());
-                TaskEntity newTask = WorkflowUtils.createNewTask(task);
-                taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isNotBlank(completeTaskBo.getMessage()) ? completeTaskBo.getMessage() : StrUtil.EMPTY);
-                taskService.complete(newTask.getId());
-                return true;
-            }
-            //闄勪欢涓婁紶
-            AttachmentCmd attachmentCmd = new AttachmentCmd(completeTaskBo.getFileId(), task.getId(), task.getProcessInstanceId(), ossService);
-            managementService.executeCommand(attachmentCmd);
-            String businessStatus = WorkflowUtils.getBusinessStatus(processInstance.getBusinessKey());
-            //娴佺▼鎻愪氦鐩戝惉
-            if (BusinessStatusEnum.DRAFT.getStatus().equals(businessStatus) || BusinessStatusEnum.BACK.getStatus().equals(businessStatus) || BusinessStatusEnum.CANCEL.getStatus().equals(businessStatus)) {
-                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(), businessStatus, true);
-            }
-            runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.WAITING.getStatus());
-            //鍔炵悊鐩戝惉
-            flowProcessEventHandler.processTaskHandler(processInstance.getProcessDefinitionKey(), task.getTaskDefinitionKey(),
-                task.getId(), processInstance.getBusinessKey());
-            //鍔炵悊鎰忚
-            taskService.addComment(completeTaskBo.getTaskId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isBlank(completeTaskBo.getMessage()) ? "鍚屾剰" : completeTaskBo.getMessage());
-            //鍔炵悊浠诲姟
-            taskService.setAssignee(task.getId(), userId);
-            if (CollUtil.isNotEmpty(completeTaskBo.getVariables())) {
-                taskService.complete(completeTaskBo.getTaskId(), completeTaskBo.getVariables());
-            } else {
-                taskService.complete(completeTaskBo.getTaskId());
-            }
-            //璁板綍鎵ц杩囩殑娴佺▼浠诲姟鑺傜偣
-            wfTaskBackNodeService.recordExecuteNode(task);
-            ProcessInstance pi = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult();
-            if (pi == null) {
-                UpdateBusinessStatusCmd updateBusinessStatusCmd = new UpdateBusinessStatusCmd(task.getProcessInstanceId(), BusinessStatusEnum.FINISH.getStatus());
-                managementService.executeCommand(updateBusinessStatusCmd);
-                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(),
-                    BusinessStatusEnum.FINISH.getStatus(), false);
-            } else {
-                List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
-                for (Task t : list) {
-                    if (ModelUtils.isUserTask(t.getProcessDefinitionId(), t.getTaskDefinitionKey())) {
-                        List<HistoricIdentityLink> links = historyService.getHistoricIdentityLinksForTask(t.getId());
-                        if (CollUtil.isEmpty(links) && StringUtils.isBlank(t.getAssignee())) {
-                            throw new ServiceException("涓嬩竴鑺傜偣銆�" + t.getName() + "銆戞病鏈夊姙鐞嗕汉!");
-                        }
-                    }
-                }
-
-                if (CollUtil.isNotEmpty(list) && CollUtil.isNotEmpty(completeTaskBo.getWfCopyList())) {
-                    TaskEntity newTask = WorkflowUtils.createNewTask(task);
-                    taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.COPY.getStatus(), LoginHelper.getLoginUser().getNickname() + "銆愭妱閫併�戠粰" + String.join(",", StreamUtils.toList(completeTaskBo.getWfCopyList(), WfCopy::getUserName)));
-                    taskService.complete(newTask.getId());
-                    List<Task> taskList = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
-                    WorkflowUtils.createCopyTask(taskList, StreamUtils.toList(completeTaskBo.getWfCopyList(), WfCopy::getUserId));
-                }
-                sendMessage(list, processInstance.getName(), completeTaskBo.getMessageType(), null);
-            }
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 鍙戦�佹秷鎭�
-     *
-     * @param list        浠诲姟
-     * @param name        娴佺▼鍚嶇О
-     * @param messageType 娑堟伅绫诲瀷
-     * @param message     娑堟伅鍐呭锛屼负绌哄垯鍙戦�侀粯璁ら厤缃殑娑堟伅鍐呭
-     */
-    @Async
-    public void sendMessage(List<Task> list, String name, List<String> messageType, String message) {
-        WorkflowUtils.sendMessage(list, name, messageType, message, userService);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<TaskVo> getPageByTaskWait(TaskBo taskBo, PageQuery pageQuery) {
-        QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>();
-        List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
-        List<String> roleIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId()));
-        String userId = String.valueOf(LoginHelper.getUserId());
-        queryWrapper.eq("t.business_status_", BusinessStatusEnum.WAITING.getStatus());
-        queryWrapper.eq(TenantHelper.isEnable(), "t.tenant_id_", TenantHelper.getTenantId());
-        String ids = StreamUtils.join(roleIds, x -> "'" + x + "'");
-        queryWrapper.and(w1 -> w1.eq("t.assignee_", userId).or(w2 -> w2.isNull("t.assignee_").apply("exists ( select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = t.ID_ and LINK.TYPE_ = 'candidate' and (LINK.USER_ID_ = {0} or ( LINK.GROUP_ID_ IN (" + ids + ") ) ))", userId)));
-        if (StringUtils.isNotBlank(taskBo.getName())) {
-            queryWrapper.like("t.name_", taskBo.getName());
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) {
-            queryWrapper.like("t.processDefinitionName", taskBo.getProcessDefinitionName());
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) {
-            queryWrapper.eq("t.processDefinitionKey", taskBo.getProcessDefinitionKey());
-        }
-        queryWrapper.orderByDesc("t.CREATE_TIME_");
-        Page<TaskVo> page = actTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper);
-
-        List<TaskVo> taskList = page.getRecords();
-        if (CollUtil.isNotEmpty(taskList)) {
-            List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (TaskVo task : taskList) {
-                task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus()));
-                task.setParticipantVo(WorkflowUtils.getCurrentTaskParticipant(task.getId(), userService));
-                task.setMultiInstance(WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()) != null);
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                }
-            }
-        }
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊緟鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<TaskVo> getPageByAllTaskWait(TaskBo taskBo, PageQuery pageQuery) {
-        TaskQuery query = QueryUtils.taskQuery();
-        if (StringUtils.isNotBlank(taskBo.getName())) {
-            query.taskNameLike("%" + taskBo.getName() + "%");
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) {
-            query.processDefinitionNameLike("%" + taskBo.getProcessDefinitionName() + "%");
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) {
-            query.processDefinitionKey(taskBo.getProcessDefinitionKey());
-        }
-        query.orderByTaskCreateTime().desc();
-        List<Task> taskList = query.listPage(pageQuery.getFirstNum(), pageQuery.getPageSize());
-        List<ProcessInstance> processInstanceList = null;
-        if (CollUtil.isNotEmpty(taskList)) {
-            Set<String> processInstanceIds = StreamUtils.toSet(taskList, Task::getProcessInstanceId);
-            processInstanceList = QueryUtils.instanceQuery(processInstanceIds).list();
-        }
-        List<TaskVo> list = new ArrayList<>();
-        if (CollUtil.isNotEmpty(taskList)) {
-            List<String> processDefinitionIds = StreamUtils.toList(taskList, Task::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (Task task : taskList) {
-                TaskVo taskVo = BeanUtil.toBean(task, TaskVo.class);
-                if (CollUtil.isNotEmpty(processInstanceList)) {
-                    processInstanceList.stream().filter(e -> e.getId().equals(task.getProcessInstanceId())).findFirst().ifPresent(e -> {
-                        taskVo.setBusinessStatus(e.getBusinessStatus());
-                        taskVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(taskVo.getBusinessStatus()));
-                        taskVo.setProcessDefinitionKey(e.getProcessDefinitionKey());
-                        taskVo.setProcessDefinitionName(e.getProcessDefinitionName());
-                        taskVo.setProcessDefinitionVersion(e.getProcessDefinitionVersion());
-                        taskVo.setBusinessKey(e.getBusinessKey());
-                    });
-                }
-                taskVo.setAssignee(StringUtils.isNotBlank(task.getAssignee()) ? Long.valueOf(task.getAssignee()) : null);
-                taskVo.setParticipantVo(WorkflowUtils.getCurrentTaskParticipant(task.getId(), userService));
-                taskVo.setMultiInstance(WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()) != null);
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(taskVo::setWfNodeConfigVo);
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(taskVo::setWfNodeConfigVo);
-                }
-                list.add(taskVo);
-            }
-        }
-        long count = query.count();
-        TableDataInfo<TaskVo> build = TableDataInfo.build();
-        build.setRows(list);
-        build.setTotal(count);
-        return build;
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫凡鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<TaskVo> getPageByTaskFinish(TaskBo taskBo, PageQuery pageQuery) {
-        String userId = String.valueOf(LoginHelper.getUserId());
-        QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>();
-        queryWrapper.like(StringUtils.isNotBlank(taskBo.getName()), "t.name_", taskBo.getName());
-        queryWrapper.like(StringUtils.isNotBlank(taskBo.getProcessDefinitionName()), "t.processDefinitionName", taskBo.getProcessDefinitionName());
-        queryWrapper.eq(StringUtils.isNotBlank(taskBo.getProcessDefinitionKey()), "t.processDefinitionKey", taskBo.getProcessDefinitionKey());
-        queryWrapper.eq("t.assignee_", userId);
-        queryWrapper.orderByDesc("t.START_TIME_");
-        Page<TaskVo> page = actTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper);
-
-        List<TaskVo> taskList = page.getRecords();
-        if (CollUtil.isNotEmpty(taskList)) {
-            List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (TaskVo task : taskList) {
-                task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus()));
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                }
-            }
-        }
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<TaskVo> getPageByTaskCopy(TaskBo taskBo, PageQuery pageQuery) {
-        QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>();
-        String userId = String.valueOf(LoginHelper.getUserId());
-        if (StringUtils.isNotBlank(taskBo.getName())) {
-            queryWrapper.like("t.name_", taskBo.getName());
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionName())) {
-            queryWrapper.like("t.processDefinitionName", taskBo.getProcessDefinitionName());
-        }
-        if (StringUtils.isNotBlank(taskBo.getProcessDefinitionKey())) {
-            queryWrapper.eq("t.processDefinitionKey", taskBo.getProcessDefinitionKey());
-        }
-        queryWrapper.eq("t.assignee_", userId);
-        queryWrapper.orderByDesc("t.START_TIME_");
-        Page<TaskVo> page = actTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper);
-
-        List<TaskVo> taskList = page.getRecords();
-        if (CollUtil.isNotEmpty(taskList)) {
-            List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (TaskVo task : taskList) {
-                task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus()));
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                }
-            }
-        }
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 鏌ヨ褰撳墠绉熸埛鎵�鏈夊凡鍔炰换鍔�
-     *
-     * @param taskBo 鍙傛暟
-     */
-    @Override
-    public TableDataInfo<TaskVo> getPageByAllTaskFinish(TaskBo taskBo, PageQuery pageQuery) {
-        QueryWrapper<TaskVo> queryWrapper = new QueryWrapper<>();
-        queryWrapper.like(StringUtils.isNotBlank(taskBo.getName()), "t.name_", taskBo.getName());
-        queryWrapper.like(StringUtils.isNotBlank(taskBo.getProcessDefinitionName()), "t.processDefinitionName", taskBo.getProcessDefinitionName());
-        queryWrapper.eq(StringUtils.isNotBlank(taskBo.getProcessDefinitionKey()), "t.processDefinitionKey", taskBo.getProcessDefinitionKey());
-        Page<TaskVo> page = actTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper);
-
-        List<TaskVo> taskList = page.getRecords();
-        if (CollUtil.isNotEmpty(taskList)) {
-            List<String> processDefinitionIds = StreamUtils.toList(taskList, TaskVo::getProcessDefinitionId);
-            List<WfNodeConfigVo> wfNodeConfigVoList = wfNodeConfigService.selectByDefIds(processDefinitionIds);
-            for (TaskVo task : taskList) {
-                task.setBusinessStatusName(BusinessStatusEnum.findByStatus(task.getBusinessStatus()));
-                if (CollUtil.isNotEmpty(wfNodeConfigVoList)) {
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && FlowConstant.TRUE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                    wfNodeConfigVoList.stream().filter(e -> e.getDefinitionId().equals(task.getProcessDefinitionId()) && e.getNodeId().equals(task.getTaskDefinitionKey()) && FlowConstant.FALSE.equals(e.getApplyUserTask())).findFirst().ifPresent(task::setWfNodeConfigVo);
-                }
-            }
-        }
-        return TableDataInfo.build(page);
-    }
-
-    /**
-     * 濮旀淳浠诲姟
-     *
-     * @param delegateBo 鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean delegateTask(DelegateBo delegateBo) {
-        Task task = WorkflowUtils.getTaskByCurrentUser(delegateBo.getTaskId());
-
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        try {
-            TaskEntity newTask = WorkflowUtils.createNewTask(task);
-            taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.PENDING.getStatus(), "銆�" + LoginHelper.getLoginUser().getNickname() + "銆戝娲剧粰銆�" + delegateBo.getNickName() + "銆�");
-            //濮旀墭浠诲姟
-            taskService.delegateTask(delegateBo.getTaskId(), delegateBo.getUserId());
-            //鍔炵悊鐢熸垚鐨勪换鍔¤褰�
-            taskService.complete(newTask.getId());
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 缁堟浠诲姟
-     *
-     * @param terminationBo 鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean terminationTask(TerminationBo terminationBo) {
-        TaskQuery query = QueryUtils.taskQuery();
-        Task task = query.taskId(terminationBo.getTaskId()).singleResult();
-
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
-        BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus());
-        try {
-            if (StringUtils.isBlank(terminationBo.getComment())) {
-                terminationBo.setComment(LoginHelper.getLoginUser().getNickname() + "缁堟浜嗙敵璇�");
-            } else {
-                terminationBo.setComment(LoginHelper.getLoginUser().getNickname() + "缁堟浜嗙敵璇凤細" + terminationBo.getComment());
-            }
-            taskService.addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.TERMINATION.getStatus(), terminationBo.getComment());
-            List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
-            if (CollUtil.isNotEmpty(list)) {
-                List<Task> subTasks = StreamUtils.filter(list, e -> StringUtils.isNotBlank(e.getParentTaskId()));
-                if (CollUtil.isNotEmpty(subTasks)) {
-                    subTasks.forEach(e -> taskService.deleteTask(e.getId()));
-                }
-                runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.TERMINATION.getStatus());
-                runtimeService.deleteProcessInstance(task.getProcessInstanceId(), StrUtil.EMPTY);
-            }
-            //娴佺▼缁堟鐩戝惉
-            flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(),
-                historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false);
-            return true;
-        } catch (Exception e) {
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 杞姙浠诲姟
-     *
-     * @param transmitBo 鍙傛暟
-     */
-    @Override
-    public boolean transferTask(TransmitBo transmitBo) {
-        Task task = WorkflowUtils.getTaskByCurrentUser(transmitBo.getTaskId());
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        try {
-            TaskEntity newTask = WorkflowUtils.createNewTask(task);
-            taskService.addComment(newTask.getId(), task.getProcessInstanceId(), TaskStatusEnum.TRANSFER.getStatus(), StringUtils.isNotBlank(transmitBo.getComment()) ? transmitBo.getComment() : LoginHelper.getUsername() + "杞姙浜嗕换鍔�");
-            taskService.complete(newTask.getId());
-            taskService.setAssignee(task.getId(), transmitBo.getUserId());
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 浼氱浠诲姟鍔犵
-     *
-     * @param addMultiBo 鍙傛暟
-     */
-    @Override
-    public boolean addMultiInstanceExecution(AddMultiBo addMultiBo) {
-        TaskQuery taskQuery = QueryUtils.taskQuery();
-        taskQuery.taskId(addMultiBo.getTaskId());
-        if (!LoginHelper.isSuperAdmin() && !LoginHelper.isTenantAdmin()) {
-            taskQuery.taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId()));
-        }
-        Task task = taskQuery.singleResult();
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        String taskDefinitionKey = task.getTaskDefinitionKey();
-        String processInstanceId = task.getProcessInstanceId();
-        String processDefinitionId = task.getProcessDefinitionId();
-
-        try {
-            MultiInstanceVo multiInstanceVo = WorkflowUtils.isMultiInstance(processDefinitionId, taskDefinitionKey);
-            if (multiInstanceVo == null) {
-                throw new ServiceException("褰撳墠鐜妭涓嶆槸浼氱鑺傜偣");
-            }
-            if (multiInstanceVo.getType() instanceof ParallelMultiInstanceBehavior) {
-                for (Long assignee : addMultiBo.getAssignees()) {
-                    runtimeService.addMultiInstanceExecution(taskDefinitionKey, processInstanceId, Collections.singletonMap(multiInstanceVo.getAssignee(), assignee));
-                }
-            } else if (multiInstanceVo.getType() instanceof SequentialMultiInstanceBehavior) {
-                AddSequenceMultiInstanceCmd addSequenceMultiInstanceCmd = new AddSequenceMultiInstanceCmd(task.getExecutionId(), multiInstanceVo.getAssigneeList(), addMultiBo.getAssignees());
-                managementService.executeCommand(addSequenceMultiInstanceCmd);
-            }
-            List<String> assigneeNames = addMultiBo.getAssigneeNames();
-            String username = LoginHelper.getUsername();
-            TaskEntity newTask = WorkflowUtils.createNewTask(task);
-            taskService.addComment(newTask.getId(), processInstanceId, TaskStatusEnum.SIGN.getStatus(), username + "鍔犵銆�" + String.join(StringUtils.SEPARATOR, assigneeNames) + "銆�");
-            taskService.complete(newTask.getId());
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 浼氱浠诲姟鍑忕
-     *
-     * @param deleteMultiBo 鍙傛暟
-     */
-    @Override
-    public boolean deleteMultiInstanceExecution(DeleteMultiBo deleteMultiBo) {
-        TaskQuery taskQuery = QueryUtils.taskQuery();
-        taskQuery.taskId(deleteMultiBo.getTaskId());
-        if (!LoginHelper.isSuperAdmin() && !LoginHelper.isTenantAdmin()) {
-            taskQuery.taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId()));
-        }
-        Task task = taskQuery.singleResult();
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        String taskDefinitionKey = task.getTaskDefinitionKey();
-        String processInstanceId = task.getProcessInstanceId();
-        String processDefinitionId = task.getProcessDefinitionId();
-        try {
-            MultiInstanceVo multiInstanceVo = WorkflowUtils.isMultiInstance(processDefinitionId, taskDefinitionKey);
-            if (multiInstanceVo == null) {
-                throw new ServiceException("褰撳墠鐜妭涓嶆槸浼氱鑺傜偣");
-            }
-            if (multiInstanceVo.getType() instanceof ParallelMultiInstanceBehavior) {
-                for (String executionId : deleteMultiBo.getExecutionIds()) {
-                    runtimeService.deleteMultiInstanceExecution(executionId, false);
-                }
-                for (String taskId : deleteMultiBo.getTaskIds()) {
-                    historyService.deleteHistoricTaskInstance(taskId);
-                }
-            } else if (multiInstanceVo.getType() instanceof SequentialMultiInstanceBehavior) {
-                DeleteSequenceMultiInstanceCmd deleteSequenceMultiInstanceCmd = new DeleteSequenceMultiInstanceCmd(task.getAssignee(), task.getExecutionId(), multiInstanceVo.getAssigneeList(), deleteMultiBo.getAssigneeIds());
-                managementService.executeCommand(deleteSequenceMultiInstanceCmd);
-            }
-            List<String> assigneeNames = deleteMultiBo.getAssigneeNames();
-            String username = LoginHelper.getUsername();
-            TaskEntity newTask = WorkflowUtils.createNewTask(task);
-            taskService.addComment(newTask.getId(), processInstanceId, TaskStatusEnum.SIGN_OFF.getStatus(), username + "鍑忕銆�" + String.join(StringUtils.SEPARATOR, assigneeNames) + "銆�");
-            taskService.complete(newTask.getId());
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 椹冲洖瀹℃壒
-     *
-     * @param backProcessBo 鍙傛暟
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public String backProcess(BackProcessBo backProcessBo) {
-        String userId = String.valueOf(LoginHelper.getUserId());
-        Task task = WorkflowUtils.getTaskByCurrentUser(backProcessBo.getTaskId());
-
-        if (ObjectUtil.isEmpty(task)) {
-            throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
-        }
-        if (task.isSuspended()) {
-            throw new ServiceException(FlowConstant.MESSAGE_SUSPENDED);
-        }
-        try {
-            String processInstanceId = task.getProcessInstanceId();
-            ProcessInstance processInstance = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult();
-            //鑾峰彇骞惰缃戝叧鎵ц鍚庝繚鐣欑殑鎵ц瀹炰緥鏁版嵁
-            ExecutionChildByExecutionIdCmd childByExecutionIdCmd = new ExecutionChildByExecutionIdCmd(task.getExecutionId());
-            List<ExecutionEntity> executionEntities = managementService.executeCommand(childByExecutionIdCmd);
-            //鏍¢獙鍗曟嵁
-            BusinessStatusEnum.checkBackStatus(processInstance.getBusinessStatus());
-            //鍒ゆ柇鏄惁鏈夊涓换鍔�
-            List<Task> taskList = QueryUtils.taskQuery(processInstanceId).list();
-            String backTaskDefinitionKey = backProcessBo.getTargetActivityId();
-            taskService.addComment(task.getId(), processInstanceId, TaskStatusEnum.BACK.getStatus(), StringUtils.isNotBlank(backProcessBo.getMessage()) ? backProcessBo.getMessage() : "閫�鍥�");
-            if (taskList.size() > 1) {
-                //褰撳墠澶氫釜浠诲姟椹冲洖鍒板崟涓妭鐐�
-                runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveActivityIdsToSingleActivityId(taskList.stream().map(Task::getTaskDefinitionKey).distinct().collect(Collectors.toList()), backTaskDefinitionKey).changeState();
-                ActHiTaskinst actHiTaskinst = new ActHiTaskinst();
-                actHiTaskinst.setAssignee(userId);
-                actHiTaskinst.setId(task.getId());
-                actHiTaskinstMapper.updateById(actHiTaskinst);
-            } else {
-                //褰撳墠鍗曚釜鑺傜偣椹冲洖鍗曚釜鑺傜偣
-                runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveActivityIdTo(task.getTaskDefinitionKey(), backTaskDefinitionKey).changeState();
-            }
-            //鍒犻櫎骞惰鐜妭鏈姙鐞嗚褰�
-            MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
-            if (multiInstance == null && taskList.size() > 1) {
-                List<Task> tasks = StreamUtils.filter(taskList, e -> !e.getTaskDefinitionKey().equals(task.getTaskDefinitionKey()));
-                if (CollUtil.isNotEmpty(tasks)) {
-                    actHiTaskinstMapper.deleteByIds(StreamUtils.toList(tasks, Task::getId));
-                }
-            }
-
-
-            List<HistoricTaskInstance> instanceList = QueryUtils.hisTaskInstanceQuery(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().desc().list();
-            List<Task> list = QueryUtils.taskQuery(processInstanceId).list();
-            for (Task t : list) {
-                instanceList.stream().filter(e -> e.getTaskDefinitionKey().equals(t.getTaskDefinitionKey())).findFirst().ifPresent(e -> {
-                    taskService.setAssignee(t.getId(), e.getAssignee());
-                });
-            }
-            //鍙戦�佹秷鎭�
-            String message = "鎮ㄧ殑銆�" + processInstance.getName() + "銆戝崟鎹凡缁忚椹冲洖锛岃鎮ㄦ敞鎰忔煡鏀躲��";
-            sendMessage(list, processInstance.getName(), backProcessBo.getMessageType(), message);
-            //鍒犻櫎娴佺▼瀹炰緥鍨冨溇鏁版嵁
-            for (ExecutionEntity executionEntity : executionEntities) {
-                DeleteExecutionCmd deleteExecutionCmd = new DeleteExecutionCmd(executionEntity.getId());
-                managementService.executeCommand(deleteExecutionCmd);
-            }
-
-            WfTaskBackNode wfTaskBackNode = wfTaskBackNodeService.getListByInstanceIdAndNodeId(task.getProcessInstanceId(), backProcessBo.getTargetActivityId());
-            if (ObjectUtil.isNotNull(wfTaskBackNode) && wfTaskBackNode.getOrderNo() == 0) {
-                runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.BACK.getStatus());
-                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
-                    processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false);
-            }
-            //鍒犻櫎椹冲洖鍚庣殑娴佺▼鑺傜偣
-            wfTaskBackNodeService.deleteBackTaskNode(processInstanceId, backProcessBo.getTargetActivityId());
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException(e.getMessage());
-        }
-        return task.getProcessInstanceId();
-    }
-
-    /**
-     * 淇敼浠诲姟鍔炵悊浜�
-     *
-     * @param taskIds 浠诲姟id
-     * @param userId  鍔炵悊浜篿d
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean updateAssignee(String[] taskIds, String userId) {
-        try {
-            List<Task> list = QueryUtils.taskQuery().taskIds(Arrays.asList(taskIds)).list();
-            for (Task task : list) {
-                taskService.setAssignee(task.getId(), userId);
-            }
-        } catch (Exception e) {
-            log.error("淇敼澶辫触锛�" + e.getMessage(), e);
-            throw new ServiceException("淇敼澶辫触锛�" + e.getMessage());
-        }
-        return true;
-    }
-
-    /**
-     * 鏌ヨ娴佺▼鍙橀噺
-     *
-     * @param taskId 浠诲姟id
-     */
-    @Override
-    public List<VariableVo> getInstanceVariable(String taskId) {
-        List<VariableVo> variableVoList = new ArrayList<>();
-        Map<String, VariableInstance> variableInstances = taskService.getVariableInstances(taskId);
-        if (CollUtil.isNotEmpty(variableInstances)) {
-            for (Map.Entry<String, VariableInstance> entry : variableInstances.entrySet()) {
-                VariableVo variableVo = new VariableVo();
-                variableVo.setKey(entry.getKey());
-                variableVo.setValue(entry.getValue().getValue().toString());
-                variableVoList.add(variableVo);
-            }
-        }
-        return variableVoList;
-    }
-
-    /**
-     * 鏌ヨ宸ヤ綔娴佷换鍔$敤鎴烽�夋嫨鍔犵浜哄憳
-     *
-     * @param taskId 浠诲姟id
-     * @return
-     */
-    @Override
-    @SuppressWarnings("unchecked")
-    public String getTaskUserIdsByAddMultiInstance(String taskId) {
-        Task task = QueryUtils.taskQuery().taskId(taskId).singleResult();
-        if (task == null) {
-            throw new ServiceException("浠诲姟涓嶅瓨鍦�");
-        }
-        MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
-        if (multiInstance == null) {
-            return "";
-        }
-        List<Long> userIds;
-        if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) {
-            userIds = (List<Long>) runtimeService.getVariable(task.getExecutionId(), multiInstance.getAssigneeList());
-        } else {
-            List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
-            userIds = StreamUtils.toList(list, e -> Long.valueOf(e.getAssignee()));
-        }
-        return StringUtils.join(userIds, StringUtils.SEPARATOR);
-    }
-
-    /**
-     * 鏌ヨ宸ヤ綔娴侀�夋嫨鍑忕浜哄憳
-     *
-     * @param taskId 浠诲姟id 浠诲姟id
-     */
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<TaskVo> getListByDeleteMultiInstance(String taskId) {
-        Task task = QueryUtils.taskQuery().taskId(taskId).singleResult();
-        List<Task> taskList = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
-        MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
-        List<TaskVo> taskListVo = new ArrayList<>();
-        if (multiInstance == null) {
-            return List.of();
-        }
-        List<Long> assigneeList = new ArrayList<>();
-        if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) {
-            List<Object> variable = (List<Object>) runtimeService.getVariable(task.getExecutionId(), multiInstance.getAssigneeList());
-            for (Object o : variable) {
-                assigneeList.add(Long.valueOf(o.toString()));
-            }
-        }
-
-        if (multiInstance.getType() instanceof SequentialMultiInstanceBehavior) {
-            List<Long> userIds = StreamUtils.filter(assigneeList, e -> !String.valueOf(e).equals(task.getAssignee()));
-            List<UserDTO> userList = userService.selectListByIds(userIds);
-            for (Long userId : userIds) {
-                TaskVo taskVo = new TaskVo();
-                taskVo.setId("涓茶浼氱");
-                taskVo.setExecutionId("涓茶浼氱");
-                taskVo.setProcessInstanceId(task.getProcessInstanceId());
-                taskVo.setName(task.getName());
-                taskVo.setAssignee(userId);
-                if (CollUtil.isNotEmpty(userList)) {
-                    userList.stream().filter(u -> u.getUserId().toString().equals(userId.toString())).findFirst().ifPresent(u -> taskVo.setAssigneeName(u.getNickName()));
-                }
-                taskListVo.add(taskVo);
-            }
-            return taskListVo;
-        } else if (multiInstance.getType() instanceof ParallelMultiInstanceBehavior) {
-            List<Task> tasks = StreamUtils.filter(taskList, e -> StringUtils.isBlank(e.getParentTaskId()) && !e.getExecutionId().equals(task.getExecutionId()) && e.getTaskDefinitionKey().equals(task.getTaskDefinitionKey()));
-            if (CollUtil.isNotEmpty(tasks)) {
-                List<Long> userIds = StreamUtils.toList(tasks, e -> Long.valueOf(e.getAssignee()));
-                List<UserDTO> userList = userService.selectListByIds(userIds);
-                for (Task t : tasks) {
-                    TaskVo taskVo = new TaskVo();
-                    taskVo.setId(t.getId());
-                    taskVo.setExecutionId(t.getExecutionId());
-                    taskVo.setProcessInstanceId(t.getProcessInstanceId());
-                    taskVo.setName(t.getName());
-                    taskVo.setAssignee(Long.valueOf(t.getAssignee()));
-                    if (CollUtil.isNotEmpty(userList)) {
-                        userList.stream().filter(u -> u.getUserId().toString().equals(t.getAssignee())).findFirst().ifPresent(e -> taskVo.setAssigneeName(e.getNickName()));
-                    }
-                    taskListVo.add(taskVo);
-                }
-                return taskListVo;
-            }
-        }
-        return List.of();
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/CategoryNameTranslationImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/CategoryNameTranslationImpl.java
new file mode 100644
index 0000000..4adbada
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/CategoryNameTranslationImpl.java
@@ -0,0 +1,31 @@
+package org.dromara.workflow.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.core.TranslationInterface;
+import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.workflow.service.IFlwCategoryService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 娴佺▼鍒嗙被鍚嶇О缈昏瘧瀹炵幇
+ *
+ * @author AprilWind
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+@TranslationType(type = FlowConstant.CATEGORY_ID_TO_NAME)
+public class CategoryNameTranslationImpl implements TranslationInterface<String> {
+
+    private final IFlwCategoryService flwCategoryService;
+
+    @Override
+    public String translation(Object key, String other) {
+        if (key instanceof String categoryId) {
+            return flwCategoryService.selectCategoryNameById(categoryId);
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java
new file mode 100644
index 0000000..0a5c0bb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCategoryServiceImpl.java
@@ -0,0 +1,267 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.*;
+import org.dromara.common.mybatis.helper.DataBaseHelper;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.warm.flow.core.service.DefService;
+import org.dromara.warm.flow.orm.entity.FlowDefinition;
+import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.workflow.domain.FlowCategory;
+import org.dromara.workflow.domain.bo.FlowCategoryBo;
+import org.dromara.workflow.domain.vo.FlowCategoryVo;
+import org.dromara.workflow.mapper.FlwCategoryMapper;
+import org.dromara.workflow.service.IFlwCategoryService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 娴佺▼鍒嗙被Service涓氬姟灞傚鐞�
+ *
+ * @author may
+ */
+@RequiredArgsConstructor
+@Service
+public class FlwCategoryServiceImpl implements IFlwCategoryService {
+
+    private final FlwCategoryMapper baseMapper;
+    private final DefService defService;
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被
+     *
+     * @param categoryId 涓婚敭
+     * @return 娴佺▼鍒嗙被
+     */
+    @Override
+    public FlowCategoryVo queryById(Long categoryId) {
+        FlowCategoryVo category = baseMapper.selectVoById(categoryId);
+        if (ObjectUtil.isNull(category)) {
+            return null;
+        }
+        FlowCategoryVo parentCategory = baseMapper.selectVoOne(new LambdaQueryWrapper<FlowCategory>()
+            .select(FlowCategory::getCategoryName).eq(FlowCategory::getCategoryId, category.getParentId()));
+        category.setParentName(ObjectUtils.notNullGetter(parentCategory, FlowCategoryVo::getCategoryName));
+        return category;
+    }
+
+    /**
+     * 鏍规嵁娴佺▼鍒嗙被ID鏌ヨ娴佺▼鍒嗙被鍚嶇О
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 娴佺▼鍒嗙被鍚嶇О
+     */
+    @Cacheable(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#categoryId")
+    @Override
+    public String selectCategoryNameById(String categoryId) {
+        if (StringUtils.isBlank(categoryId)) {
+            return null;
+        }
+        FlowCategory category = baseMapper.selectOne(new LambdaQueryWrapper<FlowCategory>()
+            .select(FlowCategory::getCategoryName).eq(FlowCategory::getCategoryId, categoryId));
+        return ObjectUtils.notNullGetter(category, FlowCategory::getCategoryName);
+    }
+
+    /**
+     * 鏌ヨ绗﹀悎鏉′欢鐨勬祦绋嬪垎绫诲垪琛�
+     *
+     * @param bo 鏌ヨ鏉′欢
+     * @return 娴佺▼鍒嗙被鍒楄〃
+     */
+    @Override
+    public List<FlowCategoryVo> queryList(FlowCategoryBo bo) {
+        LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏍戠粨鏋勪俊鎭�
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 娴佺▼鍒嗙被鏍戜俊鎭泦鍚�
+     */
+    @Override
+    public List<Tree<Long>> selectCategoryTreeList(FlowCategoryBo category) {
+        LambdaQueryWrapper<FlowCategory> lqw = buildQueryWrapper(category);
+        List<FlowCategoryVo> categorys = baseMapper.selectVoList(lqw);
+        if (CollUtil.isEmpty(categorys)) {
+            return CollUtil.newArrayList();
+        }
+        // 鑾峰彇褰撳墠鍒楄〃涓瘡涓�涓妭鐐圭殑parentId锛岀劧鍚庡湪鍒楄〃涓煡鎵炬槸鍚︽湁id涓庡叾parentId瀵瑰簲锛岃嫢鏃犲搴旓紝鍒欒〃鏄庢鏃惰妭鐐瑰垪琛ㄤ腑锛岃鑺傜偣鍦ㄥ綋鍓嶅垪琛ㄤ腑灞炰簬椤剁骇鑺傜偣
+        List<Tree<Long>> treeList = CollUtil.newArrayList();
+        for (FlowCategoryVo d : categorys) {
+            Long parentId = d.getParentId();
+            FlowCategoryVo categoryVo = StreamUtils.findFirst(categorys, it -> it.getCategoryId().longValue() == parentId);
+            if (ObjectUtil.isNull(categoryVo)) {
+                List<Tree<Long>> trees = TreeBuildUtils.build(categorys, parentId, (dept, tree) ->
+                    tree.setId(dept.getCategoryId())
+                        .setParentId(dept.getParentId())
+                        .setName(dept.getCategoryName())
+                        .setWeight(dept.getOrderNum()));
+                Tree<Long> tree = StreamUtils.findFirst(trees, it -> it.getId().longValue() == d.getCategoryId());
+                treeList.add(tree);
+            }
+        }
+        return treeList;
+    }
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鏄惁鏈夋暟鎹潈闄�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     */
+    @Override
+    public void checkCategoryDataScope(Long categoryId) {
+        if (ObjectUtil.isNull(categoryId)) {
+            return;
+        }
+        if (LoginHelper.isSuperAdmin()) {
+            return;
+        }
+        if (baseMapper.countCategoryById(categoryId) == 0) {
+            throw new ServiceException("娌℃湁鏉冮檺璁块棶娴佺▼鍒嗙被鏁版嵁锛�");
+        }
+    }
+
+    /**
+     * 鏍¢獙娴佺▼鍒嗙被鍚嶇О鏄惁鍞竴
+     *
+     * @param category 娴佺▼鍒嗙被淇℃伅
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkCategoryNameUnique(FlowCategoryBo category) {
+        boolean exist = baseMapper.exists(new LambdaQueryWrapper<FlowCategory>()
+            .eq(FlowCategory::getCategoryName, category.getCategoryName())
+            .eq(FlowCategory::getParentId, category.getParentId())
+            .ne(ObjectUtil.isNotNull(category.getCategoryId()), FlowCategory::getCategoryId, category.getCategoryId()));
+        return !exist;
+    }
+
+    /**
+     * 鏌ヨ娴佺▼鍒嗙被鏄惁瀛樺湪娴佺▼瀹氫箟
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉 true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    @Override
+    public boolean checkCategoryExistDefinition(Long categoryId) {
+        FlowDefinition definition = new FlowDefinition();
+        definition.setCategory(categoryId.toString());
+        return defService.exists(definition);
+    }
+
+    /**
+     * 鏄惁瀛樺湪娴佺▼鍒嗙被瀛愯妭鐐�
+     *
+     * @param categoryId 娴佺▼鍒嗙被ID
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean hasChildByCategoryId(Long categoryId) {
+        return baseMapper.exists(new LambdaQueryWrapper<FlowCategory>()
+            .eq(FlowCategory::getParentId, categoryId));
+    }
+
+    private LambdaQueryWrapper<FlowCategory> buildQueryWrapper(FlowCategoryBo bo) {
+        LambdaQueryWrapper<FlowCategory> lqw = Wrappers.lambdaQuery();
+        lqw.eq(FlowCategory::getDelFlag, SystemConstants.NORMAL);
+        lqw.eq(ObjectUtil.isNotNull(bo.getCategoryId()), FlowCategory::getCategoryId, bo.getCategoryId());
+        lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), FlowCategory::getParentId, bo.getParentId());
+        lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), FlowCategory::getCategoryName, bo.getCategoryName());
+        lqw.orderByAsc(FlowCategory::getAncestors);
+        lqw.orderByAsc(FlowCategory::getParentId);
+        lqw.orderByAsc(FlowCategory::getOrderNum);
+        lqw.orderByAsc(FlowCategory::getCategoryId);
+        return lqw;
+    }
+
+    /**
+     * 鏂板娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁鏂板鎴愬姛
+     */
+    @Override
+    public int insertByBo(FlowCategoryBo bo) {
+        FlowCategory info = baseMapper.selectById(bo.getParentId());
+        FlowCategory category = MapstructUtils.convert(bo, FlowCategory.class);
+        category.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + category.getParentId());
+        return baseMapper.insert(category);
+    }
+
+    /**
+     * 淇敼娴佺▼鍒嗙被
+     *
+     * @param bo 娴佺▼鍒嗙被
+     * @return 鏄惁淇敼鎴愬姛
+     */
+    @CacheEvict(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#bo.categoryId")
+    @Override
+    public int updateByBo(FlowCategoryBo bo) {
+        FlowCategory category = MapstructUtils.convert(bo, FlowCategory.class);
+        FlowCategory oldCategory = baseMapper.selectById(category.getCategoryId());
+        if (ObjectUtil.isNull(oldCategory)) {
+            throw new ServiceException("娴佺▼鍒嗙被涓嶅瓨鍦紝鏃犳硶淇敼");
+        }
+        if (!oldCategory.getParentId().equals(category.getParentId())) {
+            // 濡傛灉鏄柊鐖舵祦绋嬪垎绫� 鍒欐牎楠屾槸鍚﹀叿鏈夋柊鐖舵祦绋嬪垎绫绘潈闄� 閬垮厤瓒婃潈
+            this.checkCategoryDataScope(category.getParentId());
+            FlowCategory newParentCategory = baseMapper.selectById(category.getParentId());
+            if (ObjectUtil.isNotNull(newParentCategory)) {
+                String newAncestors = newParentCategory.getAncestors() + StringUtils.SEPARATOR + newParentCategory.getCategoryId();
+                String oldAncestors = oldCategory.getAncestors();
+                category.setAncestors(newAncestors);
+                updateCategoryChildren(category.getCategoryId(), newAncestors, oldAncestors);
+            }
+        } else {
+            category.setAncestors(oldCategory.getAncestors());
+        }
+        return baseMapper.updateById(category);
+    }
+
+    /**
+     * 淇敼瀛愬厓绱犲叧绯�
+     *
+     * @param categoryId   琚慨鏀圭殑娴佺▼鍒嗙被ID
+     * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
+     * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
+     */
+    private void updateCategoryChildren(Long categoryId, String newAncestors, String oldAncestors) {
+        List<FlowCategory> children = baseMapper.selectList(new LambdaQueryWrapper<FlowCategory>()
+            .apply(DataBaseHelper.findInSet(categoryId, "ancestors")));
+        List<FlowCategory> list = new ArrayList<>();
+        for (FlowCategory child : children) {
+            FlowCategory category = new FlowCategory();
+            category.setCategoryId(child.getCategoryId());
+            category.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
+            list.add(category);
+        }
+        if (CollUtil.isNotEmpty(list)) {
+            baseMapper.updateBatchById(list);
+        }
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼鍒嗙被淇℃伅
+     *
+     * @param categoryId 涓婚敭
+     * @return 鏄惁鍒犻櫎鎴愬姛
+     */
+    @CacheEvict(cacheNames = FlowConstant.FLOW_CATEGORY_NAME, key = "#categoryId")
+    @Override
+    public int deleteWithValidById(Long categoryId) {
+        return baseMapper.deleteById(categoryId);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java
new file mode 100644
index 0000000..baec223
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwDefinitionServiceImpl.java
@@ -0,0 +1,275 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.Document;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.warm.flow.core.dto.FlowCombine;
+import org.dromara.warm.flow.core.entity.Definition;
+import org.dromara.warm.flow.core.enums.NodeType;
+import org.dromara.warm.flow.core.enums.PublishStatus;
+import org.dromara.warm.flow.core.service.DefService;
+import org.dromara.warm.flow.orm.entity.FlowDefinition;
+import org.dromara.warm.flow.orm.entity.FlowHisTask;
+import org.dromara.warm.flow.orm.entity.FlowNode;
+import org.dromara.warm.flow.orm.entity.FlowSkip;
+import org.dromara.warm.flow.orm.mapper.FlowDefinitionMapper;
+import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
+import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
+import org.dromara.warm.flow.orm.mapper.FlowSkipMapper;
+import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.workflow.domain.FlowCategory;
+import org.dromara.workflow.domain.vo.FlowDefinitionVo;
+import org.dromara.workflow.mapper.FlwCategoryMapper;
+import org.dromara.workflow.service.IFlwDefinitionService;
+import org.dromara.workflow.utils.WorkflowUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.dromara.common.core.constant.TenantConstants.DEFAULT_TENANT_ID;
+
+/**
+ * 娴佺▼瀹氫箟 鏈嶅姟灞傚疄鐜�
+ *
+ * @author may
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
+
+    private final DefService defService;
+    private final FlowDefinitionMapper flowDefinitionMapper;
+    private final FlowHisTaskMapper flowHisTaskMapper;
+    private final FlwCategoryMapper flwCategoryMapper;
+    private final FlowNodeMapper flowNodeMapper;
+    private final FlowSkipMapper flowSkipMapper;
+
+    /**
+     * 鏌ヨ娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 娴佺▼瀹氫箟淇℃伅
+     * @param pageQuery      鍒嗛〉
+     * @return 杩斿洖鍒嗛〉鍒楄〃
+     */
+    @Override
+    public TableDataInfo<FlowDefinitionVo> queryList(FlowDefinition flowDefinition, PageQuery pageQuery) {
+        LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition);
+        wrapper.eq(FlowDefinition::getIsPublish, PublishStatus.PUBLISHED.getKey());
+        Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
+        TableDataInfo<FlowDefinitionVo> build = TableDataInfo.build();
+        build.setRows(BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class));
+        build.setTotal(page.getTotal());
+        return build;
+    }
+
+    /**
+     * 鏌ヨ鏈彂甯冪殑娴佺▼瀹氫箟鍒楄〃
+     *
+     * @param flowDefinition 娴佺▼瀹氫箟淇℃伅
+     * @param pageQuery      鍒嗛〉
+     * @return 杩斿洖鍒嗛〉鍒楄〃
+     */
+    @Override
+    public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery) {
+        LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition);
+        wrapper.in(FlowDefinition::getIsPublish, Arrays.asList(PublishStatus.UNPUBLISHED.getKey(), PublishStatus.EXPIRED.getKey()));
+        Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
+        TableDataInfo<FlowDefinitionVo> build = TableDataInfo.build();
+        build.setRows(BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class));
+        build.setTotal(page.getTotal());
+        return build;
+    }
+
+    private LambdaQueryWrapper<FlowDefinition> buildQueryWrapper(FlowDefinition flowDefinition) {
+        LambdaQueryWrapper<FlowDefinition> wrapper = Wrappers.lambdaQuery();
+        wrapper.like(StringUtils.isNotBlank(flowDefinition.getFlowCode()), FlowDefinition::getFlowCode, flowDefinition.getFlowCode());
+        wrapper.like(StringUtils.isNotBlank(flowDefinition.getFlowName()), FlowDefinition::getFlowName, flowDefinition.getFlowName());
+        if (StringUtils.isNotBlank(flowDefinition.getCategory())) {
+            List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowDefinition.getCategory()));
+            wrapper.in(FlowDefinition::getCategory, categoryIds);
+        }
+        wrapper.orderByDesc(FlowDefinition::getCreateTime);
+        return wrapper;
+    }
+
+    /**
+     * 鍙戝竷娴佺▼瀹氫箟
+     *
+     * @param id 娴佺▼瀹氫箟id
+     */
+    @Override
+    public boolean publish(Long id) {
+        List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, id));
+        List<String> errorMsg = new ArrayList<>();
+        if (CollUtil.isNotEmpty(flowNodes)) {
+            for (FlowNode flowNode : flowNodes) {
+                String applyNodeCode = WorkflowUtils.applyNodeCode(id);
+                if (StringUtils.isBlank(flowNode.getPermissionFlag()) && !applyNodeCode.equals(flowNode.getNodeCode()) && NodeType.BETWEEN.getKey().equals(flowNode.getNodeType())) {
+                    errorMsg.add(flowNode.getNodeName());
+                }
+            }
+            if (CollUtil.isNotEmpty(errorMsg)) {
+                throw new ServiceException("鑺傜偣銆�" + StringUtils.join(errorMsg, ",") + "銆戞湭閰嶇疆鍔炵悊浜�!");
+            }
+        }
+        return defService.publish(id);
+    }
+
+    /**
+     * 瀵煎叆娴佺▼瀹氫箟
+     *
+     * @param file 鏂囦欢
+     */
+    @Override
+    public boolean importXml(MultipartFile file, String category) {
+        try {
+            FlowCombine combine = defService.readXml(file.getInputStream());
+            // 娴佺▼瀹氫箟
+            Definition definition = combine.getDefinition();
+            definition.setCategory(category);
+            defService.importFlow(combine);
+        } catch (Exception e) {
+            log.error("瀵煎叆娴佺▼瀹氫箟閿欒: {}", e.getMessage(), e);
+            throw new RuntimeException(e);
+        }
+        return true;
+    }
+
+    /**
+     * 瀵煎嚭娴佺▼瀹氫箟
+     *
+     * @param id       娴佺▼瀹氫箟id
+     * @param response 鍝嶅簲
+     * @throws IOException 寮傚父
+     */
+    @Override
+    public void exportDef(Long id, HttpServletResponse response) throws IOException {
+        Document document = defService.exportXml(id);
+        // 璁剧疆鐢熸垚xml鐨勬牸寮�
+        OutputFormat of = OutputFormat.createPrettyPrint();
+        // 璁剧疆缂栫爜鏍煎紡
+        of.setEncoding("UTF-8");
+        of.setIndent(true);
+        of.setIndent("    ");
+        of.setNewlines(true);
+
+        // 鍒涘缓涓�涓獂ml鏂囨。缂栬緫鍣�
+        XMLWriter writer = new XMLWriter(response.getOutputStream(), of);
+        writer.setEscapeText(false);
+        response.reset();
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/x-msdownload");
+        response.setHeader("Content-Disposition", "attachment;");
+        writer.write(document);
+        writer.close();
+    }
+
+    /**
+     * 鍒犻櫎娴佺▼瀹氫箟
+     *
+     * @param ids 娴佺▼瀹氫箟id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean removeDef(List<Long> ids) {
+        LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
+        wrapper.in(FlowHisTask::getDefinitionId, ids);
+        List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
+        if (CollUtil.isNotEmpty(flowHisTasks)) {
+            List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectByIds(StreamUtils.toList(flowHisTasks, FlowHisTask::getDefinitionId));
+            if (CollUtil.isNotEmpty(flowDefinitions)) {
+                String join = StreamUtils.join(flowDefinitions, FlowDefinition::getFlowCode);
+                log.error("娴佺▼瀹氫箟銆恵}銆戝凡琚娇鐢ㄤ笉鍙鍒犻櫎锛�", join);
+                throw new ServiceException("娴佺▼瀹氫箟銆�" + join + "銆戝凡琚娇鐢ㄤ笉鍙鍒犻櫎锛�");
+            }
+        }
+        try {
+            defService.removeDef(ids);
+        } catch (Exception e) {
+            log.error("Error removing flow definitions: {}", e.getMessage(), e);
+            throw new RuntimeException("Failed to remove flow definitions", e);
+        }
+        return true;
+    }
+
+    /**
+     * 鏂板绉熸埛娴佺▼瀹氫箟
+     *
+     * @param tenantId 绉熸埛id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void syncDef(String tenantId) {
+        List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectList(new LambdaQueryWrapper<FlowDefinition>().eq(FlowDefinition::getTenantId, DEFAULT_TENANT_ID));
+        if (CollUtil.isEmpty(flowDefinitions)) {
+            return;
+        }
+        FlowCategory flowCategory = flwCategoryMapper.selectOne(new LambdaQueryWrapper<FlowCategory>()
+            .eq(FlowCategory::getTenantId, DEFAULT_TENANT_ID).eq(FlowCategory::getCategoryId, FlowConstant.FLOW_CATEGORY_ID));
+        flowCategory.setCategoryId(null);
+        flowCategory.setTenantId(tenantId);
+        flwCategoryMapper.insert(flowCategory);
+        List<Long> defIds = StreamUtils.toList(flowDefinitions, FlowDefinition::getId);
+        List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().in(FlowNode::getDefinitionId, defIds));
+        List<FlowSkip> flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<FlowSkip>().in(FlowSkip::getDefinitionId, defIds));
+        for (FlowDefinition definition : flowDefinitions) {
+            FlowDefinition flowDefinition = BeanUtil.toBean(definition, FlowDefinition.class);
+            flowDefinition.setId(null);
+            flowDefinition.setTenantId(tenantId);
+            flowDefinition.setIsPublish(0);
+            flowDefinition.setCategory(String.valueOf(flowCategory.getCategoryId()));
+            int insert = flowDefinitionMapper.insert(flowDefinition);
+            if (insert <= 0) {
+                log.info("鍚屾娴佺▼瀹氫箟銆恵}銆戝け璐ワ紒", definition.getFlowCode());
+                continue;
+            }
+            log.info("鍚屾娴佺▼瀹氫箟銆恵}銆戞垚鍔燂紒", definition.getFlowCode());
+            Long definitionId = flowDefinition.getId();
+            if (CollUtil.isNotEmpty(flowNodes)) {
+                List<FlowNode> nodes = StreamUtils.filter(flowNodes, node -> node.getDefinitionId().equals(definition.getId()));
+                if (CollUtil.isNotEmpty(nodes)) {
+                    List<FlowNode> flowNodeList = BeanUtil.copyToList(nodes, FlowNode.class);
+                    flowNodeList.forEach(e -> {
+                        e.setId(null);
+                        e.setDefinitionId(definitionId);
+                        e.setTenantId(tenantId);
+                        e.setPermissionFlag(null);
+                    });
+                    flowNodeMapper.insertOrUpdate(flowNodeList);
+                }
+            }
+            if (CollUtil.isNotEmpty(flowSkips)) {
+                List<FlowSkip> skips = StreamUtils.filter(flowSkips, skip -> skip.getDefinitionId().equals(definition.getId()));
+                if (CollUtil.isNotEmpty(skips)) {
+                    List<FlowSkip> flowSkipList = BeanUtil.copyToList(skips, FlowSkip.class);
+                    flowSkipList.forEach(e -> {
+                        e.setId(null);
+                        e.setDefinitionId(definitionId);
+                        e.setTenantId(tenantId);
+                    });
+                    flowSkipMapper.insertOrUpdate(flowSkipList);
+                }
+            }
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java
new file mode 100644
index 0000000..c053e6d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java
@@ -0,0 +1,455 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.dto.UserDTO;
+import org.dromara.common.core.enums.BusinessStatusEnum;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.warm.flow.core.FlowFactory;
+import org.dromara.warm.flow.core.constant.ExceptionCons;
+import org.dromara.warm.flow.core.dto.FlowParams;
+import org.dromara.warm.flow.core.entity.Definition;
+import org.dromara.warm.flow.core.entity.Instance;
+import org.dromara.warm.flow.core.entity.Task;
+import org.dromara.warm.flow.core.enums.NodeType;
+import org.dromara.warm.flow.core.service.DefService;
+import org.dromara.warm.flow.core.service.InsService;
+import org.dromara.warm.flow.core.service.TaskService;
+import org.dromara.warm.flow.orm.entity.FlowHisTask;
+import org.dromara.warm.flow.orm.entity.FlowInstance;
+import org.dromara.warm.flow.orm.entity.FlowTask;
+import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
+import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
+import org.dromara.workflow.common.enums.TaskStatusEnum;
+import org.dromara.workflow.domain.bo.FlowCancelBo;
+import org.dromara.workflow.domain.bo.FlowInstanceBo;
+import org.dromara.workflow.domain.bo.FlowInvalidBo;
+import org.dromara.workflow.domain.vo.FlowHisTaskVo;
+import org.dromara.workflow.domain.vo.FlowInstanceVo;
+import org.dromara.workflow.domain.vo.FlowVariableVo;
+import org.dromara.workflow.handler.FlowProcessEventHandler;
+import org.dromara.workflow.mapper.FlwCategoryMapper;
+import org.dromara.workflow.mapper.FlwInstanceMapper;
+import org.dromara.workflow.service.IFlwInstanceService;
+import org.dromara.workflow.service.IFlwTaskService;
+import org.dromara.workflow.utils.WorkflowUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 娴佺▼瀹炰緥 鏈嶅姟灞傚疄鐜�
+ *
+ * @author may
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlwInstanceServiceImpl implements IFlwInstanceService {
+
+    private final InsService insService;
+    private final DefService defService;
+    private final FlowHisTaskMapper flowHisTaskMapper;
+    private final FlowInstanceMapper flowInstanceMapper;
+    private final FlwInstanceMapper flwInstanceMapper;
+    private final TaskService taskService;
+    private final IFlwTaskService flwTaskService;
+    private final FlowProcessEventHandler flowProcessEventHandler;
+    private final FlwCategoryMapper flwCategoryMapper;
+
+    /**
+     * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowInstanceVo> selectRunningInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery) {
+        QueryWrapper<FlowInstanceBo> queryWrapper = buildQueryWrapper(flowInstanceBo);
+        queryWrapper.in("fi.flow_status", BusinessStatusEnum.runningStatus());
+        Page<FlowInstanceVo> page = flwInstanceMapper.selectInstanceList(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鍒嗛〉鏌ヨ宸茬粨鏉熺殑娴佺▼瀹炰緥
+     *
+     * @param flowInstanceBo 娴佺▼瀹炰緥
+     * @param pageQuery      鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowInstanceVo> selectFinishInstanceList(FlowInstanceBo flowInstanceBo, PageQuery pageQuery) {
+        QueryWrapper<FlowInstanceBo> queryWrapper = buildQueryWrapper(flowInstanceBo);
+        queryWrapper.in("fi.flow_status", BusinessStatusEnum.finishStatus());
+        Page<FlowInstanceVo> page = flwInstanceMapper.selectInstanceList(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏍规嵁涓氬姟id鏌ヨ娴佺▼瀹炰緥璇︾粏淇℃伅
+     *
+     * @param businessId 涓氬姟id
+     * @return 缁撴灉
+     */
+    @Override
+    public FlowInstanceVo queryByBusinessId(Long businessId) {
+        FlowInstance instance = this.selectInstByBusinessId(String.valueOf(businessId));
+        FlowInstanceVo instanceVo = BeanUtil.toBean(instance, FlowInstanceVo.class);
+        Definition definition = defService.getById(instanceVo.getDefinitionId());
+        instanceVo.setFlowName(definition.getFlowName());
+        instanceVo.setFlowCode(definition.getFlowCode());
+        instanceVo.setVersion(definition.getVersion());
+        instanceVo.setFormCustom(definition.getFormCustom());
+        instanceVo.setFormPath(definition.getFormPath());
+        instanceVo.setCategory(definition.getCategory());
+        return instanceVo;
+    }
+
+    /**
+     * 閫氱敤鏌ヨ鏉′欢
+     *
+     * @param flowInstanceBo 鏌ヨ鏉′欢
+     * @return 鏌ヨ鏉′欢鏋勯�犳柟娉�
+     */
+    private QueryWrapper<FlowInstanceBo> buildQueryWrapper(FlowInstanceBo flowInstanceBo) {
+        QueryWrapper<FlowInstanceBo> queryWrapper = Wrappers.query();
+        queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getNodeName()), "fi.node_name", flowInstanceBo.getNodeName());
+        queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowName()), "fd.flow_name", flowInstanceBo.getFlowName());
+        queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowCode()), "fd.flow_code", flowInstanceBo.getFlowCode());
+        if (StringUtils.isNotBlank(flowInstanceBo.getCategory())) {
+            List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowInstanceBo.getCategory()));
+            queryWrapper.in("fd.category", categoryIds);
+        }
+        queryWrapper.eq(StringUtils.isNotBlank(flowInstanceBo.getBusinessId()), "fi.business_id", flowInstanceBo.getBusinessId());
+        queryWrapper.in(CollUtil.isNotEmpty(flowInstanceBo.getCreateByIds()), "fi.create_by", flowInstanceBo.getCreateByIds());
+        queryWrapper.eq("fi.del_flag", "0");
+        queryWrapper.orderByDesc("fi.create_time");
+        return queryWrapper;
+    }
+
+    /**
+     * 鏍规嵁涓氬姟id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param businessId 涓氬姟id
+     */
+    @Override
+    public FlowInstance selectInstByBusinessId(String businessId) {
+        return flowInstanceMapper.selectOne(new LambdaQueryWrapper<FlowInstance>().eq(FlowInstance::getBusinessId, businessId));
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param instanceId 瀹炰緥id
+     */
+    @Override
+    public FlowInstance selectInstById(Long instanceId) {
+        return flowInstanceMapper.selectById(instanceId);
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ娴佺▼瀹炰緥
+     *
+     * @param instanceIds 瀹炰緥id
+     */
+    @Override
+    public List<FlowInstance> selectInstListByIdList(List<Long> instanceIds) {
+        return flowInstanceMapper.selectByIds(instanceIds);
+    }
+
+    /**
+     * 鎸夌収涓氬姟id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param businessIds 涓氬姟id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByBusinessIds(List<Long> businessIds) {
+        List<FlowInstance> flowInstances = flowInstanceMapper.selectList(new LambdaQueryWrapper<FlowInstance>().in(FlowInstance::getBusinessId, businessIds));
+        if (CollUtil.isEmpty(flowInstances)) {
+            log.warn("鏈壘鍒板搴旂殑娴佺▼瀹炰緥淇℃伅锛屾棤娉曟墽琛屽垹闄ゆ搷浣溿��");
+            return false;
+        }
+        return insService.remove(StreamUtils.toList(flowInstances, FlowInstance::getId));
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鍒犻櫎娴佺▼瀹炰緥
+     *
+     * @param instanceIds 瀹炰緥id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean deleteByInstanceIds(List<Long> instanceIds) {
+        // 鑾峰彇瀹炰緥淇℃伅
+        List<Instance> instances = insService.getByIds(instanceIds);
+        if (CollUtil.isEmpty(instances)) {
+            log.warn("鏈壘鍒板搴旂殑娴佺▼瀹炰緥淇℃伅锛屾棤娉曟墽琛屽垹闄ゆ搷浣溿��");
+            return false;
+        }
+        // 鑾峰彇瀹氫箟淇℃伅
+        Map<Long, Definition> definitionMap = defService.getByIds(
+            StreamUtils.toList(instances, Instance::getDefinitionId)
+        ).stream().collect(Collectors.toMap(Definition::getId, definition -> definition));
+
+        // 閫愪竴瑙﹀彂鍒犻櫎浜嬩欢
+        instances.forEach(instance -> {
+            Definition definition = definitionMap.get(instance.getDefinitionId());
+            if (ObjectUtil.isNull(definition)) {
+                log.warn("瀹炰緥 ID: {} 瀵瑰簲鐨勬祦绋嬪畾涔変俊鎭湭鎵惧埌锛岃烦杩囧垹闄や簨浠惰Е鍙戙��", instance.getId());
+                return;
+            }
+            flowProcessEventHandler.processDeleteHandler(definition.getFlowCode(), instance.getBusinessId());
+        });
+
+        // 鍒犻櫎瀹炰緥
+        return insService.remove(instanceIds);
+    }
+
+    /**
+     * 鎾ら攢娴佺▼
+     *
+     * @param bo 鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean cancelProcessApply(FlowCancelBo bo) {
+        try {
+            Instance instance = selectInstByBusinessId(bo.getBusinessId());
+            if (instance == null) {
+                throw new ServiceException(ExceptionCons.NOT_FOUNT_INSTANCE);
+            }
+            Definition definition = defService.getById(instance.getDefinitionId());
+            if (definition == null) {
+                throw new ServiceException(ExceptionCons.NOT_FOUNT_DEF);
+            }
+            String message = bo.getMessage();
+            BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
+            String applyNodeCode = WorkflowUtils.applyNodeCode(definition.getId());
+            //鎾ら攢
+            WorkflowUtils.backTask(message, instance.getId(), applyNodeCode, BusinessStatusEnum.CANCEL.getStatus(), BusinessStatusEnum.CANCEL.getStatus());
+            //鍒ゆ柇鎴栫鑺傜偣鏄惁鏈夊涓紝鍙繚鐣欎竴涓�
+            List<Task> currentTaskList = taskService.list(FlowFactory.newTask().setInstanceId(instance.getId()));
+            if (CollUtil.isNotEmpty(currentTaskList)) {
+                if (currentTaskList.size() > 1) {
+                    currentTaskList.remove(0);
+                    WorkflowUtils.deleteRunTask(StreamUtils.toList(currentTaskList, Task::getId));
+                }
+            }
+
+        } catch (Exception e) {
+            log.error("鎾ら攢澶辫触: {}", e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐧婚檰浜哄彂璧风殑娴佺▼瀹炰緥
+     *
+     * @param instanceBo 娴佺▼瀹炰緥
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowInstanceVo> selectCurrentInstanceList(FlowInstanceBo instanceBo, PageQuery pageQuery) {
+        QueryWrapper<FlowInstanceBo> queryWrapper = buildQueryWrapper(instanceBo);
+        queryWrapper.eq("fi.create_by", LoginHelper.getUserIdStr());
+        Page<FlowInstanceVo> page = flwInstanceMapper.selectInstanceList(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍥�,娴佺▼璁板綍
+     *
+     * @param businessId 涓氬姟id
+     */
+    @Override
+    public Map<String, Object> flowImage(String businessId) {
+        Map<String, Object> map = new HashMap<>(16);
+        FlowInstance flowInstance = this.selectInstByBusinessId(businessId);
+        if (flowInstance == null) {
+            throw new ServiceException(ExceptionCons.NOT_FOUNT_INSTANCE);
+        }
+        //杩愯涓殑浠诲姟
+        List<FlowHisTaskVo> list = new ArrayList<>();
+        List<FlowTask> flowTaskList = flwTaskService.selectByInstId(flowInstance.getId());
+        if (CollUtil.isNotEmpty(flowTaskList)) {
+            List<FlowHisTaskVo> flowHisTaskVos = BeanUtil.copyToList(flowTaskList, FlowHisTaskVo.class);
+            for (FlowHisTaskVo flowHisTaskVo : flowHisTaskVos) {
+                flowHisTaskVo.setFlowStatus(TaskStatusEnum.WAITING.getStatus());
+                flowHisTaskVo.setUpdateTime(null);
+                flowHisTaskVo.setRunDuration(null);
+                List<UserDTO> allUser = flwTaskService.currentTaskAllUser(flowHisTaskVo.getId());
+                if (CollUtil.isNotEmpty(allUser)) {
+                    String join = StreamUtils.join(allUser, e -> String.valueOf(e.getUserId()));
+                    flowHisTaskVo.setApprover(join);
+                }
+                if (BusinessStatusEnum.isDraftOrCancelOrBack(flowInstance.getFlowStatus())) {
+                    flowHisTaskVo.setApprover(LoginHelper.getUserIdStr());
+                    flowHisTaskVo.setApproveName(LoginHelper.getLoginUser().getNickname());
+                }
+            }
+            list.addAll(flowHisTaskVos);
+        }
+        //鍘嗗彶浠诲姟
+        LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(FlowHisTask::getInstanceId, flowInstance.getId());
+        wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey());
+        wrapper.orderByDesc(FlowHisTask::getCreateTime).orderByDesc(FlowHisTask::getUpdateTime);
+        List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
+        if (CollUtil.isNotEmpty(flowHisTasks)) {
+            list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class));
+        }
+
+        map.put("list", list);
+        try {
+            String flowChart = defService.flowChart(flowInstance.getId());
+            map.put("image", flowChart);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return map;
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鏇存柊鐘舵��
+     *
+     * @param instanceId 瀹炰緥id
+     * @param status     鐘舵��
+     */
+    @Override
+    public void updateStatus(Long instanceId, String status) {
+        LambdaUpdateWrapper<FlowInstance> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(FlowInstance::getFlowStatus, status);
+        wrapper.eq(FlowInstance::getId, instanceId);
+        flowInstanceMapper.update(wrapper);
+    }
+
+    /**
+     * 鑾峰彇娴佺▼鍙橀噺
+     *
+     * @param instanceId 瀹炰緥id
+     */
+    @Override
+    public Map<String, Object> instanceVariable(String instanceId) {
+        Map<String, Object> map = new HashMap<>();
+        FlowInstance flowInstance = flowInstanceMapper.selectById(instanceId);
+        Map<String, Object> variableMap = flowInstance.getVariableMap();
+        List<FlowVariableVo> list = new ArrayList<>();
+        if (CollUtil.isNotEmpty(variableMap)) {
+            for (Map.Entry<String, Object> entry : variableMap.entrySet()) {
+                FlowVariableVo flowVariableVo = new FlowVariableVo();
+                flowVariableVo.setKey(entry.getKey());
+                flowVariableVo.setValue(entry.getValue().toString());
+                list.add(flowVariableVo);
+            }
+        }
+        map.put("variableList", list);
+        map.put("variable", flowInstance.getVariable());
+        return map;
+    }
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺
+     *
+     * @param instanceId 瀹炰緥id
+     * @param variable   娴佺▼鍙橀噺
+     */
+    @Override
+    public void setVariable(Long instanceId, Map<String, Object> variable) {
+        Instance instance = insService.getById(instanceId);
+        if (instance != null) {
+            taskService.mergeVariable(instance, variable);
+        }
+    }
+
+    /**
+     * 鎸変换鍔d鏌ヨ瀹炰緥
+     *
+     * @param taskId 浠诲姟id
+     */
+    @Override
+    public FlowInstance selectByTaskId(Long taskId) {
+        Task task = taskService.getById(taskId);
+        if (task == null) {
+            FlowHisTask flowHisTask = flwTaskService.selectHisTaskById(taskId);
+            if (flowHisTask != null) {
+                return this.selectInstById(flowHisTask.getInstanceId());
+            }
+        } else {
+            return this.selectInstById(task.getInstanceId());
+        }
+        return null;
+    }
+
+    /**
+     * 鎸変换鍔d鏌ヨ瀹炰緥
+     *
+     * @param taskIdList 浠诲姟id
+     */
+    @Override
+    public List<FlowInstance> selectByTaskIdList(List<Long> taskIdList) {
+        if (CollUtil.isEmpty(taskIdList)) {
+            return Collections.emptyList();
+        }
+        Set<Long> instanceIds = new HashSet<>();
+        List<FlowTask> flowTaskList = flwTaskService.selectByIdList(taskIdList);
+        for (FlowTask flowTask : flowTaskList) {
+            instanceIds.add(flowTask.getInstanceId());
+        }
+        List<FlowHisTask> flowHisTaskList = flwTaskService.selectHisTaskByIdList(taskIdList);
+        for (FlowHisTask flowHisTask : flowHisTaskList) {
+            instanceIds.add(flowHisTask.getInstanceId());
+        }
+        if (!instanceIds.isEmpty()) {
+            return this.selectInstListByIdList(new ArrayList<>(instanceIds));
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * 浣滃簾娴佺▼
+     *
+     * @param bo 鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean processInvalid(FlowInvalidBo bo) {
+        try {
+            Instance instance = insService.getById(bo.getId());
+            if (instance != null) {
+                BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus());
+            }
+            List<FlowTask> flowTaskList = flwTaskService.selectByInstId(bo.getId());
+            for (FlowTask flowTask : flowTaskList) {
+                FlowParams flowParams = new FlowParams();
+                flowParams.message(bo.getComment());
+                flowParams.flowStatus(BusinessStatusEnum.INVALID.getStatus())
+                    .hisStatus(TaskStatusEnum.INVALID.getStatus());
+                flowParams.ignore(true);
+                taskService.termination(flowTask.getId(), flowParams);
+            }
+            return true;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java
new file mode 100644
index 0000000..28c1e8b
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskAssigneeServiceImpl.java
@@ -0,0 +1,158 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.dto.DeptDTO;
+import org.dromara.common.core.domain.dto.TaskAssigneeDTO;
+import org.dromara.common.core.domain.dto.UserDTO;
+import org.dromara.common.core.domain.model.TaskAssigneeBody;
+import org.dromara.common.core.enums.FormatsType;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.DeptService;
+import org.dromara.common.core.service.TaskAssigneeService;
+import org.dromara.common.core.service.UserService;
+import org.dromara.common.core.utils.DateUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.warm.flow.ui.dto.HandlerFunDto;
+import org.dromara.warm.flow.ui.dto.HandlerQuery;
+import org.dromara.warm.flow.ui.dto.TreeFunDto;
+import org.dromara.warm.flow.ui.service.HandlerSelectService;
+import org.dromara.warm.flow.ui.vo.HandlerSelectVo;
+import org.dromara.workflow.common.enums.TaskAssigneeEnum;
+import org.dromara.workflow.service.IFlwTaskAssigneeService;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 娴佺▼璁捐鍣�-鑾峰彇鍔炵悊浜烘潈闄愯缃垪琛�
+ *
+ * @author AprilWind
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, HandlerSelectService {
+
+    private static final String DEFAULT_GROUP_NAME = "榛樿鍒嗙粍";
+    private final TaskAssigneeService taskAssigneeService;
+    private final UserService userService;
+    private final DeptService deptService;
+
+    /**
+     * 鑾峰彇鍔炵悊浜烘潈闄愯缃垪琛╰abs椤电
+     *
+     * @return tabs椤电
+     */
+    @Override
+    public List<String> getHandlerType() {
+        return TaskAssigneeEnum.getAssigneeTypeList();
+    }
+
+    /**
+     * 鑾峰彇鍔炵悊鍒楄〃, 鍚屾椂鏋勫缓宸︿晶閮ㄩ棬鏍戠姸缁撴瀯
+     *
+     * @param query 鏌ヨ鏉′欢
+     * @return HandlerSelectVo
+     */
+    @Override
+    public HandlerSelectVo getHandlerSelect(HandlerQuery query) {
+        // 鑾峰彇浠诲姟鍔炵悊绫诲瀷
+        TaskAssigneeEnum type = TaskAssigneeEnum.fromDesc(query.getHandlerType());
+        // 杞崲鏌ヨ鏉′欢涓� TaskAssigneeBody
+        TaskAssigneeBody taskQuery = BeanUtil.toBean(query, TaskAssigneeBody.class);
+
+        // 缁熶竴鏌ヨ骞舵瀯寤轰笟鍔℃暟鎹�
+        TaskAssigneeDTO dto = fetchTaskAssigneeData(type, taskQuery);
+        List<DeptDTO> depts = fetchDeptData(type);
+
+        return getHandlerSelectVo(buildHandlerData(dto, type), buildDeptTree(depts));
+    }
+
+    /**
+     * 鏍规嵁浠诲姟鍔炵悊绫诲瀷鏌ヨ瀵瑰簲鐨勬暟鎹�
+     */
+    private TaskAssigneeDTO fetchTaskAssigneeData(TaskAssigneeEnum type, TaskAssigneeBody taskQuery) {
+        return switch (type) {
+            case USER -> taskAssigneeService.selectUsersByTaskAssigneeList(taskQuery);
+            case ROLE -> taskAssigneeService.selectRolesByTaskAssigneeList(taskQuery);
+            case DEPT -> taskAssigneeService.selectDeptsByTaskAssigneeList(taskQuery);
+            case POST -> taskAssigneeService.selectPostsByTaskAssigneeList(taskQuery);
+            default -> throw new ServiceException("Unsupported handler type");
+        };
+    }
+
+    /**
+     * 鏍规嵁浠诲姟鍔炵悊绫诲瀷鑾峰彇閮ㄩ棬鏁版嵁
+     */
+    private List<DeptDTO> fetchDeptData(TaskAssigneeEnum type) {
+        if (type == TaskAssigneeEnum.USER || type == TaskAssigneeEnum.DEPT || type == TaskAssigneeEnum.POST) {
+            return deptService.selectDeptsByList();
+        }
+        return new ArrayList<>();
+    }
+
+    /**
+     * 鏋勫缓閮ㄩ棬鏍戠姸缁撴瀯
+     */
+    private TreeFunDto<DeptDTO> buildDeptTree(List<DeptDTO> depts) {
+        return new TreeFunDto<>(depts)
+            .setId(dept -> String.valueOf(dept.getDeptId()))
+            .setName(DeptDTO::getDeptName)
+            .setParentId(dept -> String.valueOf(dept.getParentId()));
+    }
+
+    /**
+     * 鏋勫缓浠诲姟鍔炵悊浜烘暟鎹�
+     */
+    private HandlerFunDto<TaskAssigneeDTO.TaskHandler> buildHandlerData(TaskAssigneeDTO dto, TaskAssigneeEnum type) {
+        return new HandlerFunDto<>(dto.getList(), dto.getTotal())
+            .setStorageId(assignee -> type.getCode() + assignee.getStorageId())
+            .setHandlerCode(assignee -> StringUtils.blankToDefault(assignee.getHandlerCode(), "鏃�"))
+            .setHandlerName(assignee -> StringUtils.blankToDefault(assignee.getHandlerName(), "鏃�"))
+            .setGroupName(assignee -> StringUtils.defaultIfBlank(
+                Optional.ofNullable(assignee.getGroupName())
+                    .map(deptService::selectDeptNameByIds)
+                    .orElse(DEFAULT_GROUP_NAME), DEFAULT_GROUP_NAME))
+            .setCreateTime(assignee -> DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, assignee.getCreateTime()));
+    }
+
+    /**
+     * 鏍规嵁瀛樺偍鏍囪瘑绗︼紙storageId锛夎В鏋愬垎閰嶇被鍨嬪拰ID锛屽苟鑾峰彇瀵瑰簲鐨勭敤鎴峰垪琛�
+     *
+     * @param storageId 鍖呭惈鍒嗛厤绫诲瀷鍜孖D鐨勫瓧绗︿覆锛堜緥濡� "user:123" 鎴� "role:456"锛�
+     * @return 涓庡垎閰嶇被鍨嬪拰ID鍖归厤鐨勭敤鎴峰垪琛紝濡傛灉鏍煎紡鏃犳晥鍒欒繑鍥炵┖鍒楄〃
+     */
+    @Override
+    public List<UserDTO> fetchUsersByStorageId(String storageId) {
+        String[] parts = storageId.split(StrUtil.COLON, 2);
+        if (parts.length < 2) {
+            return getUsersByType(TaskAssigneeEnum.USER, List.of(Long.valueOf(parts[0])));
+        }
+        return getUsersByType(TaskAssigneeEnum.fromCode(parts[0] + StrUtil.COLON), List.of(Long.valueOf(parts[1])));
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鐨勪换鍔″垎閰嶇被鍨嬶紙TaskAssigneeEnum锛夊拰 ID 鍒楄〃锛岃幏鍙栧搴旂殑鐢ㄦ埛淇℃伅鍒楄〃
+     *
+     * @param type 浠诲姟鍒嗛厤绫诲瀷锛岃〃绀虹敤鎴枫�佽鑹层�侀儴闂ㄦ垨鍏朵粬锛圱askAssigneeEnum 鏋氫妇鍊硷級
+     * @param ids  涓庢寚瀹氬垎閰嶇被鍨嬪叧鑱旂殑 ID 鍒楄〃锛堜緥濡傜敤鎴稩D銆佽鑹睮D銆侀儴闂↖D绛夛級
+     * @return 杩斿洖鍖呭惈鐢ㄦ埛淇℃伅鐨勫垪琛ㄣ�傚鏋滅被鍨嬩负鐢ㄦ埛锛圲SER锛夛紝鍒欓�氳繃鐢ㄦ埛ID鍒楄〃鏌ヨ锛�
+     * 濡傛灉绫诲瀷涓鸿鑹诧紙ROLE锛夛紝鍒欓�氳繃瑙掕壊ID鍒楄〃鏌ヨ锛�
+     * 濡傛灉绫诲瀷涓洪儴闂紙DEPT锛夛紝鍒欓�氳繃閮ㄩ棬ID鍒楄〃鏌ヨ锛�
+     * 濡傛灉绫诲瀷涓哄矖浣嶏紙POST锛夋垨鏃犳硶璇嗗埆鐨勭被鍨嬶紝鍒欒繑鍥炵┖鍒楄〃
+     */
+    private List<UserDTO> getUsersByType(TaskAssigneeEnum type, List<Long> ids) {
+        return switch (type) {
+            case USER -> userService.selectListByIds(ids);
+            case ROLE -> userService.selectUsersByRoleIds(ids);
+            case DEPT -> userService.selectUsersByDeptIds(ids);
+            case POST -> userService.selectUsersByPostIds(ids);
+        };
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java
new file mode 100644
index 0000000..fca38fb
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java
@@ -0,0 +1,669 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.dto.UserDTO;
+import org.dromara.common.core.enums.BusinessStatusEnum;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.service.UserService;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.warm.flow.core.dto.FlowParams;
+import org.dromara.warm.flow.core.entity.*;
+import org.dromara.warm.flow.core.enums.NodeType;
+import org.dromara.warm.flow.core.enums.SkipType;
+import org.dromara.warm.flow.core.service.*;
+import org.dromara.warm.flow.orm.entity.*;
+import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
+import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
+import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
+import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
+import org.dromara.workflow.common.enums.TaskAssigneeType;
+import org.dromara.workflow.common.enums.TaskStatusEnum;
+import org.dromara.workflow.domain.bo.*;
+import org.dromara.workflow.domain.vo.FlowHisTaskVo;
+import org.dromara.workflow.domain.vo.FlowTaskVo;
+import org.dromara.workflow.handler.FlowProcessEventHandler;
+import org.dromara.workflow.handler.WorkflowPermissionHandler;
+import org.dromara.workflow.mapper.FlwCategoryMapper;
+import org.dromara.workflow.mapper.FlwTaskMapper;
+import org.dromara.workflow.service.IFlwTaskService;
+import org.dromara.workflow.utils.WorkflowUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.dromara.workflow.common.constant.FlowConstant.*;
+
+/**
+ * 浠诲姟 鏈嶅姟灞傚疄鐜�
+ *
+ * @author may
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlwTaskServiceImpl implements IFlwTaskService {
+
+    private final TaskService taskService;
+    private final InsService insService;
+    private final FlowInstanceMapper flowInstanceMapper;
+    private final FlwTaskMapper flwTaskMapper;
+    private final UserService userService;
+    private final FlowTaskMapper flowTaskMapper;
+    private final FlowHisTaskMapper flowHisTaskMapper;
+    private final FlowProcessEventHandler flowProcessEventHandler;
+    private final DefService defService;
+    private final HisTaskService hisTaskService;
+    private final IdentifierGenerator identifierGenerator;
+    private final NodeService nodeService;
+    private final FlowNodeMapper flowNodeMapper;
+    private final FlwCategoryMapper flwCategoryMapper;
+
+    /**
+     * 鍚姩浠诲姟
+     *
+     * @param startProcessBo 鍚姩娴佺▼鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> startWorkFlow(StartProcessBo startProcessBo) {
+        String businessId = startProcessBo.getBusinessId();
+        if (StringUtils.isBlank(businessId)) {
+            throw new ServiceException("鍚姩宸ヤ綔娴佹椂蹇呴』鍖呭惈涓氬姟ID");
+        }
+        // 鍚姩娴佺▼瀹炰緥锛堟彁浜ょ敵璇凤級
+        Map<String, Object> variables = startProcessBo.getVariables();
+        // 娴佺▼鍙戣捣浜�
+        variables.put(INITIATOR, LoginHelper.getUserIdStr());
+        // 涓氬姟id
+        variables.put(BUSINESS_ID, businessId);
+        FlowInstance flowInstance = flowInstanceMapper.selectOne(new LambdaQueryWrapper<>(FlowInstance.class)
+            .eq(FlowInstance::getBusinessId, businessId));
+        if (ObjectUtil.isNotNull(flowInstance)) {
+            BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
+            List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
+            return Map.of(PROCESS_INSTANCE_ID, taskList.get(0).getInstanceId(), TASK_ID, taskList.get(0).getId());
+        }
+        FlowParams flowParams = new FlowParams();
+        flowParams.flowCode(startProcessBo.getFlowCode());
+        flowParams.variable(startProcessBo.getVariables());
+        flowParams.flowStatus(BusinessStatusEnum.DRAFT.getStatus());
+        Instance instance;
+        try {
+            instance = insService.start(businessId, flowParams);
+        } catch (Exception e) {
+            throw new ServiceException(e.getMessage());
+        }
+        // 鐢宠浜烘墽琛屾祦绋�
+        List<Task> taskList = taskService.list(new FlowTask().setInstanceId(instance.getId()));
+        if (taskList.size() > 1) {
+            throw new ServiceException("璇锋鏌ユ祦绋嬬涓�涓幆鑺傛槸鍚︿负鐢宠浜猴紒");
+        }
+        return Map.of(PROCESS_INSTANCE_ID, instance.getId(), TASK_ID, taskList.get(0).getId());
+    }
+
+    /**
+     * 鍔炵悊浠诲姟
+     *
+     * @param completeTaskBo 鍔炵悊浠诲姟鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean completeTask(CompleteTaskBo completeTaskBo) {
+        try {
+            // 鑾峰彇浠诲姟ID骞舵煡璇㈠搴旂殑娴佺▼浠诲姟鍜屽疄渚嬩俊鎭�
+            Long taskId = completeTaskBo.getTaskId();
+            List<String> messageType = completeTaskBo.getMessageType();
+            String notice = completeTaskBo.getNotice();
+            // 鑾峰彇鎶勯�佷汉
+            List<FlowCopyBo> flowCopyList = completeTaskBo.getFlowCopyList();
+            FlowTask flowTask = flowTaskMapper.selectById(taskId);
+            Instance ins = insService.getById(flowTask.getInstanceId());
+            // 鑾峰彇娴佺▼瀹氫箟淇℃伅
+            Definition definition = defService.getById(flowTask.getDefinitionId());
+            // 妫�鏌ユ祦绋嬬姸鎬佹槸鍚︿负鑽夌銆佸凡鎾ら攢鎴栧凡閫�鍥炵姸鎬侊紝鑻ユ槸鍒欐墽琛屾祦绋嬫彁浜ょ洃鍚�
+            if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) {
+                flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), true);
+            }
+            // 鏋勫缓娴佺▼鍙傛暟锛屽寘鎷彉閲忋�佽烦杞被鍨嬨�佹秷鎭�佸鐞嗕汉銆佹潈闄愮瓑淇℃伅
+            FlowParams flowParams = new FlowParams();
+            flowParams.variable(completeTaskBo.getVariables());
+            flowParams.skipType(SkipType.PASS.getKey());
+            flowParams.message(completeTaskBo.getMessage());
+            flowParams.flowStatus(BusinessStatusEnum.WAITING.getStatus()).hisStatus(TaskStatusEnum.PASS.getStatus());
+
+            flowParams.hisTaskExt(completeTaskBo.getFileId());
+            // 鎵ц浠诲姟璺宠浆锛屽苟鏍规嵁杩斿洖鐨勫鐞嗕汉璁剧疆涓嬩竴姝ュ鐞嗕汉
+            Instance instance = taskService.skip(taskId, flowParams);
+            this.setHandler(instance, flowTask, flowCopyList);
+            // 娑堟伅閫氱煡
+            WorkflowUtils.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
+            return true;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
+    /**
+     * 璁剧疆鍔炵悊浜�
+     *
+     * @param instance     瀹炰緥
+     * @param task         (褰撳墠浠诲姟)鏈姙鐞嗙殑浠诲姟
+     * @param flowCopyList 鎶勯�佷汉
+     */
+    private void setHandler(Instance instance, FlowTask task, List<FlowCopyBo> flowCopyList) {
+        if (ObjectUtil.isNull(instance)) {
+            return;
+        }
+        // 娣诲姞鎶勯�佷汉
+        this.setCopy(task, flowCopyList);
+        // 鏍规嵁娴佺▼瀹炰緥ID鏌ヨ鎵�鏈夊叧鑱旂殑浠诲姟
+        List<FlowTask> flowTasks = this.selectByInstId(instance.getId());
+        List<User> userList = new ArrayList<>();
+        // 閬嶅巻浠诲姟鍒楄〃锛屽鐞嗘瘡涓换鍔$殑鍔炵悊浜�
+        for (FlowTask flowTask : flowTasks) {
+            // 鑾峰彇涓庡綋鍓嶄换鍔″叧鑱旂殑鐢ㄦ埛鍒楄〃
+            List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(Collections.singletonList(flowTask.getId()));
+            if (CollUtil.isNotEmpty(associatedUsers)) {
+                userList.addAll(WorkflowUtils.buildUser(associatedUsers, flowTask.getId()));
+            }
+        }
+        // 鎵归噺鍒犻櫎鐜版湁浠诲姟鐨勫姙鐞嗕汉璁板綍
+        if (CollUtil.isNotEmpty(flowTasks)) {
+            WorkflowUtils.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
+        }
+        // 纭繚瑕佷繚瀛樼殑 userList 涓嶄负绌�
+        if (CollUtil.isNotEmpty(userList)) {
+            WorkflowUtils.getFlowUserService().saveBatch(userList);
+        }
+    }
+
+    /**
+     * 娣诲姞鎶勯�佷汉
+     *
+     * @param task         浠诲姟淇℃伅
+     * @param flowCopyList 鎶勯�佷汉
+     */
+    public void setCopy(FlowTask task, List<FlowCopyBo> flowCopyList) {
+        if (CollUtil.isEmpty(flowCopyList)) {
+            return;
+        }
+        // 娣诲姞鎶勯�佷汉璁板綍
+        FlowHisTask flowHisTask = flowHisTaskMapper.selectList(new LambdaQueryWrapper<>(FlowHisTask.class).eq(FlowHisTask::getTaskId, task.getId())).get(0);
+        FlowNode flowNode = new FlowNode();
+        flowNode.setNodeCode(flowHisTask.getTargetNodeCode());
+        flowNode.setNodeName(flowHisTask.getTargetNodeName());
+        //鐢熸垚鏂扮殑浠诲姟id
+        long taskId = identifierGenerator.nextId(null).longValue();
+        task.setId(taskId);
+        task.setNodeName("銆愭妱閫併��" + task.getNodeName());
+        Date updateTime = new Date(flowHisTask.getUpdateTime().getTime() - 1000);
+        FlowParams flowParams = FlowParams.build();
+        flowParams.skipType(SkipType.NONE.getKey());
+        flowParams.hisStatus(TaskStatusEnum.COPY.getStatus());
+        flowParams.message("銆愭妱閫佺粰銆�" + StreamUtils.join(flowCopyList, FlowCopyBo::getUserName));
+        HisTask hisTask = hisTaskService.setSkipHisTask(task, flowNode, flowParams);
+        hisTask.setCreateTime(updateTime);
+        hisTask.setUpdateTime(updateTime);
+        hisTaskService.save(hisTask);
+        List<User> userList = flowCopyList.stream()
+            .map(flowCopy -> {
+                FlowUser flowUser = new FlowUser();
+                flowUser.setType(TaskAssigneeType.COPY.getCode());
+                flowUser.setProcessedBy(String.valueOf(flowCopy.getUserId()));
+                flowUser.setAssociated(taskId);
+                return flowUser;
+            }).collect(Collectors.toList());
+        // 鎵归噺淇濆瓨鎶勯�佷汉鍛�
+        WorkflowUtils.getFlowUserService().saveBatch(userList);
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫緟鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowTaskVo> pageByTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
+        queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
+        queryWrapper.in("t.processed_by", SpringUtils.getBean(WorkflowPermissionHandler.class).permissions());
+        queryWrapper.in("t.flow_status", BusinessStatusEnum.WAITING.getStatus());
+        Page<FlowTaskVo> page = this.getFlowTaskVoPage(pageQuery, queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勫凡鍔炰换鍔�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowHisTaskVo> pageByTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
+        queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
+        queryWrapper.in("t.approver", LoginHelper.getUserIdStr());
+        queryWrapper.orderByDesc("t.create_time").orderByDesc("t.update_time");
+        Page<FlowHisTaskVo> page = flwTaskMapper.getListFinishTask(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ寰呭姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowTaskVo> pageByAllTaskWait(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
+        queryWrapper.eq("t.node_type", NodeType.BETWEEN.getKey());
+        Page<FlowTaskVo> page = getFlowTaskVoPage(pageQuery, queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    private Page<FlowTaskVo> getFlowTaskVoPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper) {
+        Page<FlowTaskVo> page = flwTaskMapper.getListRunTask(pageQuery.build(), queryWrapper);
+        List<FlowTaskVo> records = page.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            List<Long> taskIds = StreamUtils.toList(records, FlowTaskVo::getId);
+            Map<Long, List<UserDTO>> listMap = currentTaskAllUser(taskIds);
+            records.forEach(t -> {
+                List<UserDTO> userList = listMap.getOrDefault(t.getId(), Collections.emptyList());
+                if (CollUtil.isNotEmpty(userList)) {
+                    t.setAssigneeIds(StreamUtils.join(userList, e -> String.valueOf(e.getUserId())));
+                    t.setAssigneeNames(StreamUtils.join(userList, UserDTO::getNickName));
+                }
+            });
+        }
+        return page;
+    }
+
+    /**
+     * 鏌ヨ宸插姙浠诲姟
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowHisTaskVo> pageByAllTaskFinish(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
+        Page<FlowHisTaskVo> page = flwTaskMapper.getListFinishTask(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    /**
+     * 鏌ヨ褰撳墠鐢ㄦ埛鐨勬妱閫�
+     *
+     * @param flowTaskBo 鍙傛暟
+     * @param pageQuery  鍒嗛〉
+     */
+    @Override
+    public TableDataInfo<FlowTaskVo> pageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery) {
+        QueryWrapper<FlowTaskBo> queryWrapper = buildQueryWrapper(flowTaskBo);
+        queryWrapper.in("t.processed_by", LoginHelper.getUserIdStr());
+        Page<FlowTaskVo> page = flwTaskMapper.getTaskCopyByPage(pageQuery.build(), queryWrapper);
+        return TableDataInfo.build(page);
+    }
+
+    private QueryWrapper<FlowTaskBo> buildQueryWrapper(FlowTaskBo flowTaskBo) {
+        QueryWrapper<FlowTaskBo> wrapper = Wrappers.query();
+        wrapper.like(StringUtils.isNotBlank(flowTaskBo.getNodeName()), "t.node_name", flowTaskBo.getNodeName());
+        wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName());
+        wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode());
+        wrapper.in(CollUtil.isNotEmpty(flowTaskBo.getCreateByIds()), "t.create_by", flowTaskBo.getCreateByIds());
+        if (StringUtils.isNotBlank(flowTaskBo.getCategory())) {
+            List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowTaskBo.getCategory()));
+            wrapper.in("t.category", categoryIds);
+        }
+        wrapper.orderByDesc("t.create_time");
+        return wrapper;
+    }
+
+    /**
+     * 椹冲洖浠诲姟
+     *
+     * @param bo 鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean backProcess(BackProcessBo bo) {
+        try {
+            Long taskId = bo.getTaskId();
+            String notice = bo.getNotice();
+            List<String> messageType = bo.getMessageType();
+            String message = bo.getMessage();
+            FlowTask task = flowTaskMapper.selectById(taskId);
+            if (ObjectUtil.isNull(task)) {
+                throw new ServiceException("浠诲姟涓嶅瓨鍦紒");
+            }
+            Instance inst = insService.getById(task.getInstanceId());
+            BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
+            Long definitionId = task.getDefinitionId();
+            Definition definition = defService.getById(definitionId);
+            String applyNodeCode = WorkflowUtils.applyNodeCode(definitionId);
+            FlowParams flowParams = FlowParams.build();
+            flowParams.nodeCode(bo.getNodeCode());
+            flowParams.message(message);
+            flowParams.skipType(SkipType.REJECT.getKey());
+            flowParams.flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus())
+                .hisStatus(TaskStatusEnum.BACK.getStatus());
+            taskService.skip(task.getId(), flowParams);
+
+            Instance instance = insService.getById(inst.getId());
+            this.setHandler(instance, task, null);
+            // 娑堟伅閫氱煡
+            WorkflowUtils.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
+            return true;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰彇鍙┏鍥炵殑鍓嶇疆鑺傜偣
+     *
+     * @param definitionId 娴佺▼瀹氫箟id
+     * @param nowNodeCode  褰撳墠鑺傜偣
+     */
+    @Override
+    public List<Node> getBackTaskNode(Long definitionId, String nowNodeCode) {
+        List<Node> nodeCodes = nodeService.getByNodeCodes(Collections.singletonList(nowNodeCode), definitionId);
+        if (!CollUtil.isNotEmpty(nodeCodes)) {
+            return nodeCodes;
+        }
+        //鍒ゆ柇鏄惁閰嶇疆浜嗗浐瀹氶┏鍥炶妭鐐�
+        Node node = nodeCodes.get(0);
+        if (StringUtils.isNotBlank(node.getAnyNodeSkip())) {
+            return nodeService.getByNodeCodes(Collections.singletonList(node.getAnyNodeSkip()), definitionId);
+        }
+        //鑾峰彇鍙┏鍥炵殑鍓嶇疆鑺傜偣
+        List<Node> nodes = nodeService.previousNodeList(definitionId, nowNodeCode);
+        if (CollUtil.isNotEmpty(nodes)) {
+            return StreamUtils.filter(nodes, e -> NodeType.BETWEEN.getKey().equals(e.getNodeType()));
+        }
+        return nodes;
+    }
+
+    /**
+     * 缁堟浠诲姟
+     *
+     * @param bo 鍙傛暟
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean terminationTask(FlowTerminationBo bo) {
+        try {
+            Long taskId = bo.getTaskId();
+            Task task = taskService.getById(taskId);
+            if (task == null) {
+                throw new ServiceException("浠诲姟涓嶅瓨鍦紒");
+            }
+            Instance instance = insService.getById(task.getInstanceId());
+            if (ObjectUtil.isNotNull(instance)) {
+                BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus());
+            }
+            FlowParams flowParams = new FlowParams();
+            flowParams.message(bo.getComment());
+            flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus())
+                .hisStatus(TaskStatusEnum.TERMINATION.getStatus());
+            taskService.termination(taskId, flowParams);
+            return true;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+    }
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskIdList 浠诲姟id
+     */
+    @Override
+    public List<FlowTask> selectByIdList(List<Long> taskIdList) {
+        return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
+            .in(FlowTask::getId, taskIdList));
+    }
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskId 浠诲姟id
+     */
+    @Override
+    public FlowTaskVo selectById(Long taskId) {
+        Task task = taskService.getById(taskId);
+        if (ObjectUtil.isNull(task)) {
+            return null;
+        }
+        FlowTaskVo flowTaskVo = BeanUtil.toBean(task, FlowTaskVo.class);
+        Instance instance = insService.getById(task.getInstanceId());
+        Definition definition = defService.getById(task.getDefinitionId());
+        flowTaskVo.setFlowStatus(instance.getFlowStatus());
+        flowTaskVo.setVersion(definition.getVersion());
+        flowTaskVo.setFlowCode(definition.getFlowCode());
+        flowTaskVo.setFlowName(definition.getFlowName());
+        flowTaskVo.setBusinessId(instance.getBusinessId());
+        List<Node> nodeList = nodeService.getByNodeCodes(Collections.singletonList(flowTaskVo.getNodeCode()), instance.getDefinitionId());
+        if (CollUtil.isNotEmpty(nodeList)) {
+            Node node = nodeList.get(0);
+            flowTaskVo.setNodeRatio(node.getNodeRatio());
+        }
+        return flowTaskVo;
+    }
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskIdList 浠诲姟id
+     * @return 缁撴灉
+     */
+    @Override
+    public List<FlowHisTask> selectHisTaskByIdList(List<Long> taskIdList) {
+        return flowHisTaskMapper.selectList(new LambdaQueryWrapper<>(FlowHisTask.class)
+            .in(FlowHisTask::getId, taskIdList));
+    }
+
+    /**
+     * 鎸夌収浠诲姟id鏌ヨ浠诲姟
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    @Override
+    public FlowHisTask selectHisTaskById(Long taskId) {
+        return flowHisTaskMapper.selectOne(new LambdaQueryWrapper<>(FlowHisTask.class)
+            .eq(FlowHisTask::getId, taskId));
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ浠诲姟
+     *
+     * @param instanceIdList 娴佺▼瀹炰緥id
+     */
+    @Override
+    public List<FlowTask> selectByInstIdList(List<Long> instanceIdList) {
+        return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
+            .in(FlowTask::getInstanceId, instanceIdList));
+    }
+
+    /**
+     * 鎸夌収瀹炰緥id鏌ヨ浠诲姟
+     *
+     * @param instanceId 娴佺▼瀹炰緥id
+     */
+    @Override
+    public List<FlowTask> selectByInstId(Long instanceId) {
+        return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
+            .eq(FlowTask::getInstanceId, instanceId));
+    }
+
+    /**
+     * 浠诲姟鎿嶄綔
+     *
+     * @param bo            鍙傛暟
+     * @param taskOperation 鎿嶄綔绫诲瀷锛屽娲� delegateTask銆佽浆鍔� transferTask銆佸姞绛� addSignature銆佸噺绛� reductionSignature
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean taskOperation(TaskOperationBo bo, String taskOperation) {
+        FlowParams flowParams = new FlowParams();
+        flowParams.message(bo.getMessage());
+        if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
+            flowParams.ignore(true);
+        }
+
+        // 鏍规嵁鎿嶄綔绫诲瀷鏋勫缓 FlowParams
+        switch (taskOperation) {
+            case DELEGATE_TASK, TRANSFER_TASK -> {
+                ValidatorUtils.validate(bo, AddGroup.class);
+                flowParams.addHandlers(Collections.singletonList(bo.getUserId()));
+            }
+            case ADD_SIGNATURE -> {
+                ValidatorUtils.validate(bo, EditGroup.class);
+                flowParams.addHandlers(bo.getUserIds());
+            }
+            case REDUCTION_SIGNATURE -> {
+                ValidatorUtils.validate(bo, EditGroup.class);
+                flowParams.reductionHandlers(bo.getUserIds());
+            }
+            default -> {
+                log.error("Invalid operation type:{} ", taskOperation);
+                throw new ServiceException("Invalid operation type " + taskOperation);
+            }
+        }
+
+        Long taskId = bo.getTaskId();
+        FlowTaskVo flowTaskVo = selectById(taskId);
+        if ("addSignature".equals(taskOperation) || "reductionSignature".equals(taskOperation)) {
+            if (flowTaskVo.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) {
+                throw new ServiceException(flowTaskVo.getNodeName() + "涓嶆槸浼氱鑺傜偣锛�");
+            }
+        }
+        // 璁剧疆浠诲姟鐘舵�佸苟鎵ц瀵瑰簲鐨勪换鍔℃搷浣�
+        switch (taskOperation) {
+            //濮旀淳浠诲姟
+            case DELEGATE_TASK -> {
+                flowParams.hisStatus(TaskStatusEnum.DEPUTE.getStatus());
+                return taskService.depute(taskId, flowParams);
+            }
+            //杞姙浠诲姟
+            case TRANSFER_TASK -> {
+                flowParams.hisStatus(TaskStatusEnum.TRANSFER.getStatus());
+                return taskService.transfer(taskId, flowParams);
+            }
+            //鍔犵锛屽鍔犲姙鐞嗕汉
+            case ADD_SIGNATURE -> {
+                flowParams.hisStatus(TaskStatusEnum.SIGN.getStatus());
+                return taskService.addSignature(taskId, flowParams);
+            }
+            //鍑忕锛屽噺灏戝姙鐞嗕汉
+            case REDUCTION_SIGNATURE -> {
+                flowParams.hisStatus(TaskStatusEnum.SIGN_OFF.getStatus());
+                return taskService.reductionSignature(taskId, flowParams);
+            }
+            default -> {
+                log.error("Invalid operation type:{} ", taskOperation);
+                throw new ServiceException("Invalid operation type " + taskOperation);
+            }
+        }
+    }
+
+    /**
+     * 淇敼浠诲姟鍔炵悊浜猴紙姝ゆ柟娉曞皢浼氭壒閲忎慨鏀规墍鏈変换鍔$殑鍔炵悊浜猴級
+     *
+     * @param taskIdList 浠诲姟id
+     * @param userId     鐢ㄦ埛id
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateAssignee(List<Long> taskIdList, String userId) {
+        if (CollUtil.isEmpty(taskIdList)) {
+            return false;
+        }
+        try {
+            List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
+            // 鎵归噺鍒犻櫎鐜版湁浠诲姟鐨勫姙鐞嗕汉璁板綍
+            if (CollUtil.isNotEmpty(flowTasks)) {
+                WorkflowUtils.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
+                List<User> userList = flowTasks.stream()
+                    .map(flowTask -> {
+                        FlowUser flowUser = new FlowUser();
+                        flowUser.setType(TaskAssigneeType.APPROVER.getCode());
+                        flowUser.setProcessedBy(userId);
+                        flowUser.setAssociated(flowTask.getId());
+                        return flowUser;
+                    })
+                    .collect(Collectors.toList());
+                if (CollUtil.isNotEmpty(userList)) {
+                    WorkflowUtils.getFlowUserService().saveBatch(userList);
+                }
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new ServiceException(e.getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * 鑾峰彇浠诲姟鎵�鏈夊姙鐞嗕汉
+     *
+     * @param taskIdList 浠诲姟id
+     */
+    @Override
+    public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
+        Map<Long, List<UserDTO>> map = new HashMap<>();
+        // 鑾峰彇涓庡綋鍓嶄换鍔″叧鑱旂殑鐢ㄦ埛鍒楄〃
+        List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList);
+        Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
+        for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
+            List<User> value = entry.getValue();
+            if (CollUtil.isNotEmpty(value)) {
+                List<UserDTO> userDTOS = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
+                map.put(entry.getKey(), userDTOS);
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠浠诲姟鐨勬墍鏈夊姙鐞嗕汉
+     *
+     * @param taskId 浠诲姟id
+     */
+    @Override
+    public List<UserDTO> currentTaskAllUser(Long taskId) {
+        // 鑾峰彇涓庡綋鍓嶄换鍔″叧鑱旂殑鐢ㄦ埛鍒楄〃
+        List<User> userList = WorkflowUtils.getFlowUserService().getByAssociateds(Collections.singletonList(taskId));
+        if (CollUtil.isEmpty(userList)) {
+            return Collections.emptyList();
+        }
+        return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java
index f81c85f..499d64b 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java
@@ -1,16 +1,18 @@
 package org.dromara.workflow.service.impl;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.event.ProcessDeleteEvent;
 import org.dromara.common.core.domain.event.ProcessEvent;
 import org.dromara.common.core.domain.event.ProcessTaskEvent;
 import org.dromara.common.core.enums.BusinessStatusEnum;
 import org.dromara.common.core.service.WorkflowService;
 import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -24,7 +26,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -82,6 +83,9 @@
      */
     @Override
     public TestLeaveVo insertByBo(TestLeaveBo bo) {
+        long day = DateUtil.betweenDay(bo.getStartDate(), bo.getEndDate(), true);
+        // 鎴鏃ユ湡涔熺畻涓�澶�
+        bo.setLeaveDays((int) day + 1);
         TestLeave add = MapstructUtils.convert(bo, TestLeave.class);
         if (StringUtils.isBlank(add.getStatus())) {
             add.setStatus(BusinessStatusEnum.DRAFT.getStatus());
@@ -108,23 +112,22 @@
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean deleteWithValidByIds(Collection<Long> ids) {
-        List<String> idList = StreamUtils.toList(ids, String::valueOf);
-        workflowService.deleteRunAndHisInstance(idList);
+    public Boolean deleteWithValidByIds(List<Long> ids) {
+        workflowService.deleteInstance(ids);
         return baseMapper.deleteByIds(ids) > 0;
     }
 
     /**
-     * 鎬讳綋娴佺▼鐩戝惉(渚嬪: 鎻愪氦 閫�鍥� 鎾ら攢 缁堟 浣滃簾绛�)
-     * 姝e父浣跨敤鍙渶#processEvent.key=='leave1'
+     * 鎬讳綋娴佺▼鐩戝惉(渚嬪: 鑽夌锛屾挙閿�锛岄��鍥烇紝浣滃簾锛岀粓姝紝宸插畬鎴愮瓑)
+     * 姝e父浣跨敤鍙渶#processEvent.flowCode=='leave1'
      * 绀轰緥涓轰簡鏂逛究鍒欎娇鐢╯tartsWith鍖归厤浜嗗叏閮ㄧず渚媖ey
      *
      * @param processEvent 鍙傛暟
      */
-    @EventListener(condition = "#processEvent.key.startsWith('leave')")
+    @EventListener(condition = "#processEvent.flowCode.startsWith('leave')")
     public void processHandler(ProcessEvent processEvent) {
         log.info("褰撳墠浠诲姟鎵ц浜唟}", processEvent.toString());
-        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessKey()));
+        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessId()));
         testLeave.setStatus(processEvent.getStatus());
         if (processEvent.isSubmit()) {
             testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
@@ -134,24 +137,37 @@
 
     /**
      * 鎵ц鍔炵悊浠诲姟鐩戝惉
-     * 绀轰緥锛氫篃鍙�氳繃  @EventListener(condition = "#processTaskEvent.key=='leave1'")杩涜鍒ゆ柇
+     * 绀轰緥锛氫篃鍙�氳繃  @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")杩涜鍒ゆ柇
      * 鍦ㄦ柟娉曚腑鍒ゆ柇娴佺▼鑺傜偣key
-     * if ("xxx".equals(processTaskEvent.getTaskDefinitionKey())) {
+     * if ("xxx".equals(processTaskEvent.getNodeCode())) {
      * //鎵ц涓氬姟閫昏緫
      * }
      *
      * @param processTaskEvent 鍙傛暟
      */
-    @EventListener(condition = "#processTaskEvent.key.startsWith('leave')")
+    @EventListener(condition = "#processTaskEvent.flowCode.startsWith('leave')")
     public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
-        // 鎵�鏈塪emo妗堜緥鐨勭敵璇蜂汉鑺傜偣id
-        String[] ids = {"Activity_14633hx", "Activity_19b1i4j", "Activity_0uscrk3",
-            "Activity_0uscrk3", "Activity_0x6b71j", "Activity_0zy3g6j", "Activity_06a55t0"};
-        if (StringUtils.equalsAny(processTaskEvent.getTaskDefinitionKey(), ids)) {
-            log.info("褰撳墠浠诲姟鎵ц浜唟}", processTaskEvent.toString());
-            TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessKey()));
-            testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
-            baseMapper.updateById(testLeave);
-        }
+        log.info("褰撳墠浠诲姟鎵ц浜唟}", processTaskEvent.toString());
+        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessId()));
+        testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
+        baseMapper.updateById(testLeave);
     }
+
+    /**
+     * 鐩戝惉鍒犻櫎娴佺▼浜嬩欢
+     * 姝e父浣跨敤鍙渶#processDeleteEvent.flowCode=='leave1'
+     * 绀轰緥涓轰簡鏂逛究鍒欎娇鐢╯tartsWith鍖归厤浜嗗叏閮ㄧず渚媖ey
+     *
+     * @param processDeleteEvent 鍙傛暟
+     */
+    @EventListener(condition = "#processDeleteEvent.flowCode.startsWith('leave')")
+    public void processDeleteHandler(ProcessDeleteEvent processDeleteEvent) {
+        log.info("鐩戝惉鍒犻櫎娴佺▼浜嬩欢锛屽綋鍓嶄换鍔℃墽琛屼簡{}", processDeleteEvent.toString());
+        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processDeleteEvent.getBusinessId()));
+        if (ObjectUtil.isNull(testLeave)) {
+            return;
+        }
+        baseMapper.deleteById(testLeave.getId());
+    }
+
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java
deleted file mode 100644
index e562823..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.workflow.domain.WfCategory;
-import org.dromara.workflow.domain.bo.WfCategoryBo;
-import org.dromara.workflow.domain.vo.WfCategoryVo;
-import org.dromara.workflow.mapper.WfCategoryMapper;
-import org.dromara.workflow.service.IWfCategoryService;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.engine.RepositoryService;
-import org.flowable.engine.repository.Deployment;
-import org.flowable.engine.repository.Model;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 娴佺▼鍒嗙被Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2023-06-28
- */
-@RequiredArgsConstructor
-@Service
-public class WfCategoryServiceImpl implements IWfCategoryService {
-
-    private final WfCategoryMapper baseMapper;
-    @Autowired(required = false)
-    private RepositoryService repositoryService;
-
-    /**
-     * 鏌ヨ娴佺▼鍒嗙被
-     */
-    @Override
-    public WfCategoryVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-
-    /**
-     * 鏌ヨ娴佺▼鍒嗙被鍒楄〃
-     */
-    @Override
-    public List<WfCategoryVo> queryList(WfCategoryBo bo) {
-        LambdaQueryWrapper<WfCategory> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<WfCategory> buildQueryWrapper(WfCategoryBo bo) {
-        LambdaQueryWrapper<WfCategory> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), WfCategory::getCategoryName, bo.getCategoryName());
-        lqw.eq(StringUtils.isNotBlank(bo.getCategoryCode()), WfCategory::getCategoryCode, bo.getCategoryCode());
-        return lqw;
-    }
-
-    /**
-     * 鏂板娴佺▼鍒嗙被
-     */
-    @Override
-    public Boolean insertByBo(WfCategoryBo bo) {
-        WfCategory add = MapstructUtils.convert(bo, WfCategory.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    /**
-     * 淇敼娴佺▼鍒嗙被
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean updateByBo(WfCategoryBo bo) {
-        WfCategory update = MapstructUtils.convert(bo, WfCategory.class);
-        validEntityBeforeSave(update);
-        WfCategoryVo wfCategoryVo = baseMapper.selectVoById(bo.getId());
-        List<ProcessDefinition> processDefinitionList = QueryUtils.definitionQuery().processDefinitionCategory(wfCategoryVo.getCategoryCode()).list();
-        for (ProcessDefinition processDefinition : processDefinitionList) {
-            repositoryService.setProcessDefinitionCategory(processDefinition.getId(), bo.getCategoryCode());
-        }
-        List<Deployment> deploymentList = QueryUtils.deploymentQuery().deploymentCategory(wfCategoryVo.getCategoryCode()).list();
-        for (Deployment deployment : deploymentList) {
-            repositoryService.setDeploymentCategory(deployment.getId(), bo.getCategoryCode());
-        }
-        List<Model> modelList = QueryUtils.modelQuery().modelCategory(wfCategoryVo.getCategoryCode()).list();
-        for (Model model : modelList) {
-            model.setCategory(bo.getCategoryCode());
-            repositoryService.saveModel(model);
-        }
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
-     */
-    private void validEntityBeforeSave(WfCategory entity) {
-        //TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎娴佺▼鍒嗙被
-     */
-    @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
-        }
-        return baseMapper.deleteByIds(ids) > 0;
-    }
-
-    /**
-     * 鎸夌収绫诲埆缂栫爜鏌ヨ
-     *
-     * @param categoryCode 鍒嗙被姣斿悧
-     */
-    @Override
-    public WfCategory queryByCategoryCode(String categoryCode) {
-        return baseMapper.selectOne(new LambdaQueryWrapper<WfCategory>().eq(WfCategory::getCategoryCode, categoryCode));
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfDefinitionConfigServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfDefinitionConfigServiceImpl.java
deleted file mode 100644
index b2ffb9e..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfDefinitionConfigServiceImpl.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import org.dromara.common.core.utils.MapstructUtils;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
-import org.dromara.workflow.domain.WfDefinitionConfig;
-import org.dromara.workflow.domain.bo.WfDefinitionConfigBo;
-import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
-import org.dromara.workflow.service.IWfDefinitionConfigService;
-import org.springframework.stereotype.Service;
-import org.dromara.workflow.mapper.WfDefinitionConfigMapper;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.Collection;
-
-/**
- * 娴佺▼瀹氫箟閰嶇疆Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2024-03-18
- */
-@RequiredArgsConstructor
-@Service
-public class WfDefinitionConfigServiceImpl implements IWfDefinitionConfigService {
-
-    private final WfDefinitionConfigMapper baseMapper;
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     */
-    @Override
-    public WfDefinitionConfigVo getByDefId(String definitionId) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getDefinitionId, definitionId));
-    }
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param tableName 琛ㄥ悕
-     * @return 缁撴灉
-     */
-    @Override
-    public WfDefinitionConfigVo getByTableNameLastVersion(String tableName) {
-        List<WfDefinitionConfigVo> wfDefinitionConfigVos = baseMapper.selectVoList(
-            new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getTableName, tableName).orderByDesc(WfDefinitionConfig::getVersion));
-        if (CollUtil.isNotEmpty(wfDefinitionConfigVos)) {
-            return wfDefinitionConfigVos.get(0);
-        }
-        return null;
-    }
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆
-     *
-     * @param definitionId 娴佺▼瀹氫箟id
-     * @param tableName    琛ㄥ悕
-     * @return 缁撴灉
-     */
-    @Override
-    public WfDefinitionConfigVo getByDefIdAndTableName(String definitionId, String tableName) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<WfDefinitionConfig>()
-            .eq(WfDefinitionConfig::getDefinitionId, definitionId)
-            .eq(WfDefinitionConfig::getTableName, tableName));
-    }
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆鎺掗櫎褰撳墠鏌ヨ鐨勬祦绋嬪畾涔�
-     *
-     * @param tableName    琛ㄥ悕
-     * @param definitionId 娴佺▼瀹氫箟id
-     */
-    @Override
-    public List<WfDefinitionConfigVo> getByTableNameNotDefId(String tableName, String definitionId) {
-        return baseMapper.selectVoList(new LambdaQueryWrapper<WfDefinitionConfig>()
-            .eq(WfDefinitionConfig::getTableName, tableName)
-            .ne(WfDefinitionConfig::getDefinitionId, definitionId));
-    }
-
-    /**
-     * 鏌ヨ娴佺▼瀹氫箟閰嶇疆鍒楄〃
-     */
-    @Override
-    public List<WfDefinitionConfigVo> queryList(List<String> definitionIds) {
-        return baseMapper.selectVoList(new LambdaQueryWrapper<WfDefinitionConfig>().in(WfDefinitionConfig::getDefinitionId, definitionIds));
-    }
-
-    /**
-     * 鏂板娴佺▼瀹氫箟閰嶇疆
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Boolean saveOrUpdate(WfDefinitionConfigBo bo) {
-        WfDefinitionConfig add = MapstructUtils.convert(bo, WfDefinitionConfig.class);
-        baseMapper.delete(new LambdaQueryWrapper<WfDefinitionConfig>().eq(WfDefinitionConfig::getTableName, bo.getTableName()));
-        add.setTableName(add.getTableName().toLowerCase());
-        boolean flag = baseMapper.insertOrUpdate(add);
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎娴佺▼瀹氫箟閰嶇疆
-     */
-    @Override
-    public Boolean deleteByIds(Collection<Long> ids) {
-        return baseMapper.deleteByIds(ids) > 0;
-    }
-
-    @Override
-    public Boolean deleteByDefIds(Collection<String> ids) {
-        return baseMapper.delete(new LambdaQueryWrapper<WfDefinitionConfig>().in(WfDefinitionConfig::getDefinitionId, ids)) > 0;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfFormManageServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfFormManageServiceImpl.java
deleted file mode 100644
index 55e4911..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfFormManageServiceImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import lombok.RequiredArgsConstructor;
-import org.dromara.workflow.common.enums.FormTypeEnum;
-import org.springframework.stereotype.Service;
-import org.dromara.workflow.domain.bo.WfFormManageBo;
-import org.dromara.workflow.domain.vo.WfFormManageVo;
-import org.dromara.workflow.domain.WfFormManage;
-import org.dromara.workflow.mapper.WfFormManageMapper;
-import org.dromara.workflow.service.IWfFormManageService;
-
-import java.util.List;
-import java.util.Collection;
-
-/**
- * 琛ㄥ崟绠$悊Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2024-03-29
- */
-@RequiredArgsConstructor
-@Service
-public class WfFormManageServiceImpl implements IWfFormManageService {
-
-    private final WfFormManageMapper baseMapper;
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊
-     */
-    @Override
-    public WfFormManageVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-    @Override
-    public List<WfFormManageVo> queryByIds(List<Long> ids) {
-        return baseMapper.selectVoByIds(ids);
-    }
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     */
-    @Override
-    public TableDataInfo<WfFormManageVo> queryPageList(WfFormManageBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<WfFormManage> lqw = buildQueryWrapper(bo);
-        Page<WfFormManageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
-    }
-
-    @Override
-    public List<WfFormManageVo> selectList() {
-        List<WfFormManageVo> wfFormManageVos = baseMapper.selectVoList(new LambdaQueryWrapper<WfFormManage>().orderByDesc(WfFormManage::getUpdateTime));
-        for (WfFormManageVo wfFormManageVo : wfFormManageVos) {
-            wfFormManageVo.setFormTypeName(FormTypeEnum.findByType(wfFormManageVo.getFormType()));
-        }
-        return wfFormManageVos;
-    }
-
-    /**
-     * 鏌ヨ琛ㄥ崟绠$悊鍒楄〃
-     */
-    @Override
-    public List<WfFormManageVo> queryList(WfFormManageBo bo) {
-        LambdaQueryWrapper<WfFormManage> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
-    }
-
-    private LambdaQueryWrapper<WfFormManage> buildQueryWrapper(WfFormManageBo bo) {
-        LambdaQueryWrapper<WfFormManage> lqw = Wrappers.lambdaQuery();
-        lqw.like(StringUtils.isNotBlank(bo.getFormName()), WfFormManage::getFormName, bo.getFormName());
-        lqw.eq(StringUtils.isNotBlank(bo.getFormType()), WfFormManage::getFormType, bo.getFormType());
-        return lqw;
-    }
-
-    /**
-     * 鏂板琛ㄥ崟绠$悊
-     */
-    @Override
-    public Boolean insertByBo(WfFormManageBo bo) {
-        WfFormManage add = MapstructUtils.convert(bo, WfFormManage.class);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
-        }
-        return flag;
-    }
-
-    /**
-     * 淇敼琛ㄥ崟绠$悊
-     */
-    @Override
-    public Boolean updateByBo(WfFormManageBo bo) {
-        WfFormManage update = MapstructUtils.convert(bo, WfFormManage.class);
-        return baseMapper.updateById(update) > 0;
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎琛ㄥ崟绠$悊
-     */
-    @Override
-    public Boolean deleteByIds(Collection<Long> ids) {
-        return baseMapper.deleteByIds(ids) > 0;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfNodeConfigServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfNodeConfigServiceImpl.java
deleted file mode 100644
index 2f71482..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfNodeConfigServiceImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.workflow.domain.vo.WfFormManageVo;
-import org.dromara.workflow.service.IWfFormManageService;
-import org.springframework.stereotype.Service;
-import org.dromara.workflow.domain.vo.WfNodeConfigVo;
-import org.dromara.workflow.domain.WfNodeConfig;
-import org.dromara.workflow.mapper.WfNodeConfigMapper;
-import org.dromara.workflow.service.IWfNodeConfigService;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * 鑺傜偣閰嶇疆Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2024-03-30
- */
-@RequiredArgsConstructor
-@Service
-public class WfNodeConfigServiceImpl implements IWfNodeConfigService {
-
-    private final WfNodeConfigMapper baseMapper;
-    private final IWfFormManageService wfFormManageService;
-
-    /**
-     * 鏌ヨ鑺傜偣閰嶇疆
-     */
-    @Override
-    public WfNodeConfigVo queryById(Long id) {
-        return baseMapper.selectVoById(id);
-    }
-
-    /**
-     * 淇濆瓨鑺傜偣閰嶇疆
-     */
-    @Override
-    public Boolean saveOrUpdate(List<WfNodeConfig> list) {
-        return baseMapper.insertOrUpdateBatch(list);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎鑺傜偣閰嶇疆
-     */
-    @Override
-    public Boolean deleteByIds(Collection<Long> ids) {
-        return baseMapper.deleteByIds(ids) > 0;
-    }
-
-
-
-    @Override
-    public Boolean deleteByDefIds(Collection<String> ids) {
-        return baseMapper.delete(new LambdaQueryWrapper<WfNodeConfig>().in(WfNodeConfig::getDefinitionId, ids)) > 0;
-    }
-
-    @Override
-    public List<WfNodeConfigVo> selectByDefIds(Collection<String> ids) {
-        List<WfNodeConfigVo> wfNodeConfigVos = baseMapper.selectVoList(new LambdaQueryWrapper<WfNodeConfig>().in(WfNodeConfig::getDefinitionId, ids));
-        if (CollUtil.isNotEmpty(wfNodeConfigVos)) {
-            List<Long> formIds = StreamUtils.toList(wfNodeConfigVos, WfNodeConfigVo::getFormId);
-            List<WfFormManageVo> wfFormManageVos = wfFormManageService.queryByIds(formIds);
-            for (WfNodeConfigVo wfNodeConfigVo : wfNodeConfigVos) {
-                wfFormManageVos.stream().filter(e -> ObjectUtil.equals(e.getId(), wfNodeConfigVo.getFormId())).findFirst().ifPresent(wfNodeConfigVo::setWfFormManageVo);
-            }
-        }
-        return wfNodeConfigVos;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskBackNodeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskBackNodeServiceImpl.java
deleted file mode 100644
index 6c255d3..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskBackNodeServiceImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.dromara.workflow.service.impl;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.workflow.domain.WfTaskBackNode;
-import org.dromara.workflow.domain.vo.MultiInstanceVo;
-import org.dromara.workflow.mapper.WfTaskBackNodeMapper;
-import org.dromara.workflow.service.IWfTaskBackNodeService;
-import org.dromara.workflow.utils.WorkflowUtils;
-import org.flowable.task.api.Task;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.dromara.workflow.common.constant.FlowConstant.MULTI_INSTANCE;
-import static org.dromara.workflow.common.constant.FlowConstant.USER_TASK;
-
-
-/**
- * 鑺傜偣椹冲洖璁板綍Service涓氬姟灞傚鐞�
- *
- * @author may
- * @date 2024-03-13
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service
-public class WfTaskBackNodeServiceImpl implements IWfTaskBackNodeService {
-
-    private final WfTaskBackNodeMapper wfTaskBackNodeMapper;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void recordExecuteNode(Task task) {
-        List<WfTaskBackNode> list = getListByInstanceId(task.getProcessInstanceId());
-        WfTaskBackNode wfTaskBackNode = new WfTaskBackNode();
-        wfTaskBackNode.setNodeId(task.getTaskDefinitionKey());
-        wfTaskBackNode.setNodeName(task.getName());
-        wfTaskBackNode.setInstanceId(task.getProcessInstanceId());
-        wfTaskBackNode.setAssignee(String.valueOf(LoginHelper.getUserId()));
-        MultiInstanceVo multiInstance = WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
-        if (ObjectUtil.isNotEmpty(multiInstance)) {
-            wfTaskBackNode.setTaskType(MULTI_INSTANCE);
-        } else {
-            wfTaskBackNode.setTaskType(USER_TASK);
-        }
-        if (CollUtil.isEmpty(list)) {
-            wfTaskBackNode.setOrderNo(0);
-            wfTaskBackNodeMapper.insert(wfTaskBackNode);
-        } else {
-            WfTaskBackNode taskNode = StreamUtils.findFirst(list, e -> e.getNodeId().equals(wfTaskBackNode.getNodeId()) && e.getOrderNo() == 0);
-            if (ObjectUtil.isEmpty(taskNode)) {
-                wfTaskBackNode.setOrderNo(list.get(0).getOrderNo() + 1);
-                WfTaskBackNode node = getListByInstanceIdAndNodeId(wfTaskBackNode.getInstanceId(), wfTaskBackNode.getNodeId());
-                if (ObjectUtil.isNotEmpty(node)) {
-                    node.setAssignee(node.getAssignee() + StringUtils.SEPARATOR + LoginHelper.getUserId());
-                    wfTaskBackNodeMapper.updateById(node);
-                } else {
-                    wfTaskBackNodeMapper.insert(wfTaskBackNode);
-                }
-            }
-        }
-    }
-
-    @Override
-    public List<WfTaskBackNode> getListByInstanceId(String processInstanceId) {
-        LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId);
-        wrapper.orderByDesc(WfTaskBackNode::getOrderNo);
-        return wfTaskBackNodeMapper.selectList(wrapper);
-    }
-
-    @Override
-    public WfTaskBackNode getListByInstanceIdAndNodeId(String processInstanceId, String nodeId) {
-        LambdaQueryWrapper<WfTaskBackNode> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId);
-        queryWrapper.eq(WfTaskBackNode::getNodeId, nodeId);
-        return wfTaskBackNodeMapper.selectOne(queryWrapper);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteBackTaskNode(String processInstanceId, String targetActivityId) {
-        try {
-            LambdaQueryWrapper<WfTaskBackNode> queryWrapper = new LambdaQueryWrapper<>();
-            queryWrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId);
-            queryWrapper.eq(WfTaskBackNode::getNodeId, targetActivityId);
-            WfTaskBackNode actTaskNode = wfTaskBackNodeMapper.selectOne(queryWrapper);
-            if (ObjectUtil.isNotNull(actTaskNode)) {
-                Integer orderNo = actTaskNode.getOrderNo();
-                List<WfTaskBackNode> taskNodeList = getListByInstanceId(processInstanceId);
-                List<Long> ids = new ArrayList<>();
-                if (CollUtil.isNotEmpty(taskNodeList)) {
-                    for (WfTaskBackNode taskNode : taskNodeList) {
-                        if (taskNode.getOrderNo() >= orderNo) {
-                            ids.add(taskNode.getId());
-                        }
-                    }
-                }
-                if (CollUtil.isNotEmpty(ids)) {
-                    wfTaskBackNodeMapper.deleteByIds(ids);
-                }
-            }
-            return true;
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw new ServiceException("鍒犻櫎澶辫触");
-        }
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteByInstanceId(String processInstanceId) {
-        LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(WfTaskBackNode::getInstanceId, processInstanceId);
-        List<WfTaskBackNode> list = wfTaskBackNodeMapper.selectList(wrapper);
-        int delete = wfTaskBackNodeMapper.delete(wrapper);
-        if (list.size() != delete) {
-            throw new ServiceException("鍒犻櫎澶辫触");
-        }
-        return true;
-    }
-
-    @Override
-    public boolean deleteByInstanceIds(List<String> processInstanceIds) {
-        LambdaQueryWrapper<WfTaskBackNode> wrapper = new LambdaQueryWrapper<>();
-        wrapper.in(WfTaskBackNode::getInstanceId, processInstanceIds);
-        List<WfTaskBackNode> list = wfTaskBackNodeMapper.selectList(wrapper);
-        int delete = wfTaskBackNodeMapper.delete(wrapper);
-        if (list.size() != delete) {
-            throw new ServiceException("鍒犻櫎澶辫触");
-        }
-        return true;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java
index b036584..d00c907 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java
@@ -1,14 +1,18 @@
 package org.dromara.workflow.service.impl;
 
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.dto.CompleteTaskDTO;
+import org.dromara.common.core.domain.dto.StartProcessDTO;
 import org.dromara.common.core.service.WorkflowService;
-import org.dromara.workflow.domain.ActHiProcinst;
-import org.dromara.workflow.service.IActHiProcinstService;
-import org.dromara.workflow.service.IActProcessInstanceService;
-import org.dromara.workflow.utils.WorkflowUtils;
-import org.flowable.engine.TaskService;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.warm.flow.orm.entity.FlowInstance;
+import org.dromara.workflow.domain.bo.CompleteTaskBo;
+import org.dromara.workflow.domain.bo.StartProcessBo;
+import org.dromara.workflow.service.IFlwDefinitionService;
+import org.dromara.workflow.service.IFlwInstanceService;
+import org.dromara.workflow.service.IFlwTaskService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -23,19 +27,19 @@
 @Service
 public class WorkflowServiceImpl implements WorkflowService {
 
-    @Autowired(required = false)
-    private TaskService taskService;
-    private final IActProcessInstanceService actProcessInstanceService;
-    private final IActHiProcinstService actHiProcinstService;
+    private final IFlwInstanceService flwInstanceService;
+    private final IFlwDefinitionService flwDefinitionService;
+    private final IFlwTaskService flwTaskService;
+
     /**
-     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
+     * 鍒犻櫎娴佺▼瀹炰緥
      *
-     * @param businessKeys 涓氬姟id
+     * @param businessIds 涓氬姟id
      * @return 缁撴灉
      */
     @Override
-    public boolean deleteRunAndHisInstance(List<String> businessKeys) {
-        return actProcessInstanceService.deleteRunAndHisInstance(businessKeys);
+    public boolean deleteInstance(List<Long> businessIds) {
+        return flwInstanceService.deleteByBusinessIds(businessIds);
     }
 
     /**
@@ -44,78 +48,72 @@
      * @param taskId 浠诲姟id
      */
     @Override
-    public String getBusinessStatusByTaskId(String taskId) {
-        return WorkflowUtils.getBusinessStatusByTaskId(taskId);
+    public String getBusinessStatusByTaskId(Long taskId) {
+        FlowInstance flowInstance = flwInstanceService.selectByTaskId(taskId);
+        return ObjectUtil.isNotNull(flowInstance) ? flowInstance.getFlowStatus() : StringUtils.EMPTY;
     }
 
     /**
      * 鑾峰彇褰撳墠娴佺▼鐘舵��
      *
-     * @param businessKey 涓氬姟id
+     * @param businessId 涓氬姟id
      */
     @Override
-    public String getBusinessStatus(String businessKey) {
-        return WorkflowUtils.getBusinessStatus(businessKey);
+    public String getBusinessStatus(String businessId) {
+        FlowInstance flowInstance = flwInstanceService.selectInstByBusinessId(businessId);
+        return ObjectUtil.isNotNull(flowInstance) ? flowInstance.getFlowStatus() : StringUtils.EMPTY;
     }
 
     /**
-     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
+     * 璁剧疆娴佺▼鍙橀噺
      *
-     * @param taskId       浠诲姟id
-     * @param variableName 鍙橀噺鍚嶇О
-     * @param value        鍙橀噺鍊�
+     * @param instanceId 娴佺▼瀹炰緥id
+     * @param variables  娴佺▼鍙橀噺
      */
     @Override
-    public void setVariable(String taskId, String variableName, Object value) {
-        taskService.setVariable(taskId, variableName, value);
-    }
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
-     *
-     * @param taskId    浠诲姟id
-     * @param variables 娴佺▼鍙橀噺
-     */
-    @Override
-    public void setVariables(String taskId, Map<String, Object> variables) {
-        taskService.setVariables(taskId, variables);
-    }
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
-     *
-     * @param taskId       浠诲姟id
-     * @param variableName 鍙橀噺鍚嶇О
-     * @param value        鍙橀噺鍊�
-     */
-    @Override
-    public void setVariableLocal(String taskId, String variableName, Object value) {
-        taskService.setVariableLocal(taskId, variableName, value);
-    }
-
-    /**
-     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
-     *
-     * @param taskId    浠诲姟id
-     * @param variables 娴佺▼鍙橀噺
-     */
-    @Override
-    public void setVariablesLocal(String taskId, Map<String, Object> variables) {
-        taskService.setVariablesLocal(taskId, variables);
+    public void setVariable(Long instanceId, Map<String, Object> variables) {
+        flwInstanceService.setVariable(instanceId, variables);
     }
 
     /**
      * 鎸夌収涓氬姟id鏌ヨ娴佺▼瀹炰緥id
      *
-     * @param businessKey 涓氬姟id
+     * @param businessId 涓氬姟id
      * @return 缁撴灉
      */
     @Override
-    public String getInstanceIdByBusinessKey(String businessKey) {
-        ActHiProcinst actHiProcinst = actHiProcinstService.selectByBusinessKey(businessKey);
-        if (actHiProcinst == null) {
-            return StrUtil.EMPTY;
-        }
-        return actHiProcinst.getId();
+    public Long getInstanceIdByBusinessId(String businessId) {
+        FlowInstance flowInstance = flwInstanceService.selectInstByBusinessId(businessId);
+        return ObjectUtil.isNotNull(flowInstance) ? flowInstance.getId() : null;
+    }
+
+    /**
+     * 鏂板绉熸埛娴佺▼瀹氫箟
+     *
+     * @param tenantId 绉熸埛id
+     */
+    @Override
+    public void syncDef(String tenantId) {
+        flwDefinitionService.syncDef(tenantId);
+    }
+
+    /**
+     * 鍚姩娴佺▼
+     *
+     * @param startProcess 鍙傛暟
+     */
+    @Override
+    public Map<String, Object> startWorkFlow(StartProcessDTO startProcess) {
+        return flwTaskService.startWorkFlow(BeanUtil.toBean(startProcess, StartProcessBo.class));
+    }
+
+    /**
+     * 鍔炵悊浠诲姟
+     *
+     * @param completeTask 鍙傛暟
+     */
+    @Override
+    public boolean completeTask(CompleteTaskDTO completeTask) {
+        return flwTaskService.completeTask(BeanUtil.toBean(completeTask, CompleteTaskBo.class));
     }
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/ModelUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/ModelUtils.java
deleted file mode 100644
index 7c5377e..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/ModelUtils.java
+++ /dev/null
@@ -1,289 +0,0 @@
-package org.dromara.workflow.utils;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.json.utils.JsonUtils;
-import org.dromara.workflow.domain.vo.MultiInstanceVo;
-import org.flowable.bpmn.converter.BpmnXMLConverter;
-import org.flowable.bpmn.model.*;
-import org.flowable.bpmn.model.Process;
-import org.flowable.editor.language.json.converter.BpmnJsonConverter;
-import org.flowable.engine.ProcessEngine;
-
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.ServerException;
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * 妯″瀷宸ュ叿
- *
- * @author may
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class ModelUtils {
-
-    private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class);
-
-    public static BpmnModel xmlToBpmnModel(String xml) throws IOException {
-        if (xml == null) {
-            throw new ServerException("xml涓嶈兘涓虹┖");
-        }
-        try {
-            InputStream inputStream = new ByteArrayInputStream(StrUtil.utf8Bytes(xml));
-            XMLInputFactory factory = XMLInputFactory.newInstance();
-            XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
-            return new BpmnXMLConverter().convertToBpmnModel(reader);
-        } catch (XMLStreamException e) {
-            throw new ServerException(e.getMessage());
-        }
-    }
-
-    /**
-     * bpmnModel杞负xml
-     *
-     * @param jsonBytes json
-     */
-    public static byte[] bpmnJsonToXmlBytes(byte[] jsonBytes) throws IOException {
-        if (jsonBytes == null) {
-            return new byte[0];
-        }
-        // 1. json瀛楄妭鐮佽浆鎴� BpmnModel 瀵硅薄
-        ObjectMapper objectMapper = JsonUtils.getObjectMapper();
-        JsonNode jsonNode = objectMapper.readTree(jsonBytes);
-        BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode);
-
-        if (bpmnModel.getProcesses().isEmpty()) {
-            return new byte[0];
-        }
-        // 2.灏哹pmnModel杞负xml
-        return new BpmnXMLConverter().convertToXML(bpmnModel);
-    }
-
-    /**
-     * xml杞负bpmnModel
-     *
-     * @param xmlBytes xml
-     */
-    public static BpmnModel xmlToBpmnModel(byte[] xmlBytes) throws XMLStreamException {
-        ByteArrayInputStream byteArrayInputStream = IoUtil.toStream(xmlBytes);
-        XMLInputFactory xif = XMLInputFactory.newInstance();
-        XMLStreamReader xtr = xif.createXMLStreamReader(byteArrayInputStream);
-        return new BpmnXMLConverter().convertToBpmnModel(xtr);
-    }
-
-    /**
-     * 鏍¢獙妯″瀷
-     *
-     * @param bpmnModel bpmn妯″瀷
-     */
-    public static void checkBpmnModel(BpmnModel bpmnModel) throws ServerException {
-        Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();
-
-        checkBpmnNode(flowElements, false);
-
-        List<SubProcess> subProcessList = flowElements.stream().filter(SubProcess.class::isInstance).map(SubProcess.class::cast).collect(Collectors.toList());
-        if (!CollUtil.isEmpty(subProcessList)) {
-            for (SubProcess subProcess : subProcessList) {
-                Collection<FlowElement> subProcessFlowElements = subProcess.getFlowElements();
-                checkBpmnNode(subProcessFlowElements, true);
-            }
-        }
-        List<MultiInstanceVo> multiInstanceVoList = new ArrayList<>();
-        for (FlowElement flowElement : flowElements) {
-            if (flowElement instanceof UserTask && ObjectUtil.isNotEmpty(((UserTask) flowElement).getLoopCharacteristics()) && StringUtils.isNotBlank(((UserTask) flowElement).getLoopCharacteristics().getInputDataItem())) {
-                MultiInstanceVo multiInstanceVo = new MultiInstanceVo();
-                multiInstanceVo.setAssigneeList(((UserTask) flowElement).getLoopCharacteristics().getInputDataItem());
-                multiInstanceVoList.add(multiInstanceVo);
-            }
-        }
-
-        if (CollectionUtil.isNotEmpty(multiInstanceVoList) && multiInstanceVoList.size() > 1) {
-            Map<String, List<MultiInstanceVo>> assigneeListGroup = StreamUtils.groupByKey(multiInstanceVoList, MultiInstanceVo::getAssigneeList);
-            for (Map.Entry<String, List<MultiInstanceVo>> entry : assigneeListGroup.entrySet()) {
-                List<MultiInstanceVo> value = entry.getValue();
-                if (CollectionUtil.isNotEmpty(value) && value.size() > 1) {
-                    String key = entry.getKey();
-                    throw new ServerException("浼氱浜哄憳闆嗗悎銆�" + key + "銆戦噸澶�,璇烽噸鏂拌缃泦鍚圞EY");
-                }
-            }
-        }
-    }
-
-    /**
-     * 鏍¢獙bpmn鑺傜偣鏄惁鍚堟硶
-     *
-     * @param flowElements 鑺傜偣闆嗗悎
-     * @param subtask      鏄惁瀛愭祦绋�
-     */
-    private static void checkBpmnNode(Collection<FlowElement> flowElements, boolean subtask) throws ServerException {
-
-        if (CollUtil.isEmpty(flowElements)) {
-            throw new ServerException(subtask ? "瀛愭祦绋嬪繀椤诲瓨鍦ㄨ妭鐐�" : "蹇呴』瀛樺湪鑺傜偣锛�");
-        }
-
-        List<StartEvent> startEventList = flowElements.stream().filter(StartEvent.class::isInstance).map(StartEvent.class::cast).collect(Collectors.toList());
-        if (CollUtil.isEmpty(startEventList)) {
-            throw new ServerException(subtask ? "瀛愭祦绋嬪繀椤诲瓨鍦ㄥ紑濮嬭妭鐐�" : "蹇呴』瀛樺湪寮�濮嬭妭鐐癸紒");
-        }
-
-        if (startEventList.size() > 1) {
-            throw new ServerException(subtask ? "瀛愭祦绋嬪彧鑳藉瓨鍦ㄤ竴涓紑濮嬭妭鐐�" : "鍙兘瀛樺湪涓�涓紑濮嬭妭鐐癸紒");
-        }
-
-        StartEvent startEvent = startEventList.get(0);
-        List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows();
-        if (CollUtil.isEmpty(outgoingFlows)) {
-            throw new ServerException(subtask ? "瀛愭祦绋嬫祦绋嬭妭鐐逛负绌猴紝璇疯嚦灏戣璁′竴鏉′富绾挎祦绋嬶紒" : "娴佺▼鑺傜偣涓虹┖锛岃鑷冲皯璁捐涓�鏉′富绾挎祦绋嬶紒");
-        }
-
-        FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();
-        if (!(targetFlowElement instanceof UserTask) && !subtask) {
-            throw new ServerException("寮�濮嬭妭鐐瑰悗绗竴涓妭鐐瑰繀椤绘槸鐢ㄦ埛浠诲姟锛�");
-        }
-        //寮�濮嬭妭鐐瑰悗绗竴涓妭鐐圭敵璇蜂汉鑺傜偣
-        if ((targetFlowElement instanceof UserTask) && !subtask) {
-            UserTask userTask = (UserTask) targetFlowElement;
-            if (StringUtils.isBlank(userTask.getFormKey())) {
-                throw new ServerException("鐢宠浜鸿妭鐐瑰繀椤婚�夋嫨琛ㄥ崟锛�");
-            }
-        }
-        List<EndEvent> endEventList = flowElements.stream().filter(EndEvent.class::isInstance).map(EndEvent.class::cast).collect(Collectors.toList());
-        if (CollUtil.isEmpty(endEventList)) {
-            throw new ServerException(subtask ? "瀛愭祦绋嬪繀椤诲瓨鍦ㄧ粨鏉熻妭鐐癸紒" : "蹇呴』瀛樺湪缁撴潫鑺傜偣锛�");
-        }
-    }
-
-    /**
-     * 鑾峰彇娴佺▼鍏ㄩ儴鐢ㄦ埛鑺傜偣
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    public static List<UserTask> getUserTaskFlowElements(String processDefinitionId) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        List<UserTask> list = new ArrayList<>();
-        List<Process> processes = bpmnModel.getProcesses();
-        Collection<FlowElement> flowElements = processes.get(0).getFlowElements();
-        buildUserTaskFlowElements(flowElements, list);
-        return list;
-    }
-
-    /**
-     * 閫掑綊鑾峰彇鎵�鏈夎妭鐐�
-     *
-     * @param flowElements 鑺傜偣淇℃伅
-     * @param list         闆嗗悎
-     */
-    private static void buildUserTaskFlowElements(Collection<FlowElement> flowElements, List<UserTask> list) {
-        for (FlowElement flowElement : flowElements) {
-            if (flowElement instanceof SubProcess) {
-                Collection<FlowElement> subFlowElements = ((SubProcess) flowElement).getFlowElements();
-                buildUserTaskFlowElements(subFlowElements, list);
-            } else if (flowElement instanceof UserTask) {
-                list.add((UserTask) flowElement);
-            }
-        }
-    }
-
-    /**
-     * 鑾峰彇娴佺▼鍏ㄩ儴鑺傜偣
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    public static List<FlowElement> getFlowElements(String processDefinitionId) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        List<FlowElement> list = new ArrayList<>();
-        List<Process> processes = bpmnModel.getProcesses();
-        Collection<FlowElement> flowElements = processes.get(0).getFlowElements();
-        buildFlowElements(flowElements, list);
-        return list;
-    }
-
-    /**
-     * 閫掑綊鑾峰彇鎵�鏈夎妭鐐�
-     *
-     * @param flowElements 鑺傜偣淇℃伅
-     * @param list         闆嗗悎
-     */
-    private static void buildFlowElements(Collection<FlowElement> flowElements, List<FlowElement> list) {
-        for (FlowElement flowElement : flowElements) {
-            list.add(flowElement);
-            if (flowElement instanceof SubProcess) {
-                Collection<FlowElement> subFlowElements = ((SubProcess) flowElement).getFlowElements();
-                buildFlowElements(subFlowElements, list);
-            }
-        }
-    }
-
-    /**
-     * 鑾峰彇鍏ㄩ儴鎵╁睍淇℃伅
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     */
-    public static Map<String, List<ExtensionElement>> getExtensionElements(String processDefinitionId) {
-        Map<String, List<ExtensionElement>> map = new HashMap<>();
-        List<FlowElement> flowElements = getFlowElements(processDefinitionId);
-        for (FlowElement flowElement : flowElements) {
-            if (flowElement instanceof UserTask && CollUtil.isNotEmpty(flowElement.getExtensionElements())) {
-                map.putAll(flowElement.getExtensionElements());
-            }
-        }
-        return map;
-    }
-
-    /**
-     * 鑾峰彇鏌愪釜鑺傜偣鐨勬墿灞曚俊鎭�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @param flowElementId       鑺傜偣id
-     */
-    public static Map<String, List<ExtensionElement>> getExtensionElement(String processDefinitionId, String flowElementId) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        Process process = bpmnModel.getMainProcess();
-        FlowElement flowElement = process.getFlowElement(flowElementId);
-        return flowElement.getExtensionElements();
-    }
-
-    /**
-     * 鍒ゆ柇褰撳墠鑺傜偣鏄惁涓虹敤鎴蜂换鍔�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @param taskDefinitionKey   娴佺▼瀹氫箟id
-     */
-    public static boolean isUserTask(String processDefinitionId, String taskDefinitionKey) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey);
-        return flowNode instanceof UserTask;
-    }
-
-    /**
-     * 鑾峰彇鐢宠浜鸿妭鐐�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @return 缁撴灉
-     */
-    public static UserTask getApplyUserTask(String processDefinitionId) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();
-        List<StartEvent> startEventList = flowElements.stream().filter(StartEvent.class::isInstance).map(StartEvent.class::cast).collect(Collectors.toList());
-        StartEvent startEvent = startEventList.get(0);
-        List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows();
-        FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();
-        return (UserTask) targetFlowElement;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/QueryUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/QueryUtils.java
deleted file mode 100644
index df928dc..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/QueryUtils.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.dromara.workflow.utils;
-
-import cn.hutool.core.bean.BeanUtil;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.workflow.domain.vo.TaskVo;
-import org.flowable.engine.ProcessEngine;
-import org.flowable.engine.history.HistoricActivityInstanceQuery;
-import org.flowable.engine.history.HistoricProcessInstanceQuery;
-import org.flowable.engine.repository.DeploymentQuery;
-import org.flowable.engine.repository.ModelQuery;
-import org.flowable.engine.repository.ProcessDefinitionQuery;
-import org.flowable.engine.runtime.ProcessInstance;
-import org.flowable.engine.runtime.ProcessInstanceQuery;
-import org.flowable.task.api.Task;
-import org.flowable.task.api.TaskQuery;
-import org.flowable.task.api.history.HistoricTaskInstanceQuery;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- * 鏌ヨ宸ュ叿
- *
- * @author Lion Li
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class QueryUtils {
-
-    private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class);
-
-    public static ModelQuery modelQuery() {
-        ModelQuery query = PROCESS_ENGINE.getRepositoryService().createModelQuery();
-        if (TenantHelper.isEnable()) {
-            query.modelTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static ProcessDefinitionQuery definitionQuery() {
-        ProcessDefinitionQuery query = PROCESS_ENGINE.getRepositoryService().createProcessDefinitionQuery();
-        if (TenantHelper.isEnable()) {
-            query.processDefinitionTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static DeploymentQuery deploymentQuery() {
-        DeploymentQuery query = PROCESS_ENGINE.getRepositoryService().createDeploymentQuery();
-        if (TenantHelper.isEnable()) {
-            query.deploymentTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static DeploymentQuery deploymentQuery(String deploymentId) {
-        return deploymentQuery().deploymentId(deploymentId);
-    }
-
-    public static DeploymentQuery deploymentQuery(List<String> deploymentIds) {
-        return deploymentQuery().deploymentIds(deploymentIds);
-    }
-
-    public static HistoricTaskInstanceQuery hisTaskInstanceQuery() {
-        HistoricTaskInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricTaskInstanceQuery();
-        if (TenantHelper.isEnable()) {
-            query.taskTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static HistoricTaskInstanceQuery hisTaskInstanceQuery(String processInstanceId) {
-        return hisTaskInstanceQuery().processInstanceId(processInstanceId);
-    }
-
-    public static HistoricTaskInstanceQuery hisTaskBusinessKeyQuery(String businessKey) {
-        return hisTaskInstanceQuery().processInstanceBusinessKey(businessKey);
-    }
-
-    public static ProcessInstanceQuery instanceQuery() {
-        ProcessInstanceQuery query = PROCESS_ENGINE.getRuntimeService().createProcessInstanceQuery();
-        if (TenantHelper.isEnable()) {
-            query.processInstanceTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static ProcessInstanceQuery instanceQuery(String processInstanceId) {
-        return instanceQuery().processInstanceId(processInstanceId);
-    }
-
-    public static ProcessInstanceQuery businessKeyQuery(String businessKey) {
-        return instanceQuery().processInstanceBusinessKey(businessKey);
-    }
-
-    public static ProcessInstanceQuery instanceQuery(Set<String> processInstanceIds) {
-        return instanceQuery().processInstanceIds(processInstanceIds);
-    }
-
-    public static HistoricProcessInstanceQuery hisInstanceQuery() {
-        HistoricProcessInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricProcessInstanceQuery();
-        if (TenantHelper.isEnable()) {
-            query.processInstanceTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static HistoricProcessInstanceQuery hisInstanceQuery(String processInstanceId) {
-        return hisInstanceQuery().processInstanceId(processInstanceId);
-    }
-
-    public static HistoricProcessInstanceQuery hisBusinessKeyQuery(String businessKey) {
-        return hisInstanceQuery().processInstanceBusinessKey(businessKey);
-    }
-
-    public static HistoricProcessInstanceQuery hisInstanceQuery(Set<String> processInstanceIds) {
-        return hisInstanceQuery().processInstanceIds(processInstanceIds);
-    }
-
-    public static HistoricActivityInstanceQuery hisActivityInstanceQuery() {
-        HistoricActivityInstanceQuery query = PROCESS_ENGINE.getHistoryService().createHistoricActivityInstanceQuery();
-        if (TenantHelper.isEnable()) {
-            query.activityTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static HistoricActivityInstanceQuery hisActivityInstanceQuery(String processInstanceId) {
-        return hisActivityInstanceQuery().processInstanceId(processInstanceId);
-    }
-
-    public static TaskQuery taskQuery() {
-        TaskQuery query = PROCESS_ENGINE.getTaskService().createTaskQuery();
-        if (TenantHelper.isEnable()) {
-            query.taskTenantId(TenantHelper.getTenantId());
-        }
-        return query;
-    }
-
-    public static TaskQuery taskQuery(String processInstanceId) {
-        return taskQuery().processInstanceId(processInstanceId);
-    }
-
-    public static TaskQuery taskQuery(Collection<String> processInstanceIds) {
-        return taskQuery().processInstanceIdIn(processInstanceIds);
-    }
-
-    /**
-     * 鎸夌収浠诲姟id鏌ヨ褰撳墠浠诲姟
-     *
-     * @param taskId 浠诲姟id
-     */
-    public static TaskVo getTask(String taskId) {
-        Task task = PROCESS_ENGINE.getTaskService().createTaskQuery().taskId(taskId).singleResult();
-        if (task == null) {
-            return null;
-        }
-        ProcessInstance processInstance = QueryUtils.instanceQuery(task.getProcessInstanceId()).singleResult();
-        TaskVo taskVo = BeanUtil.toBean(task, TaskVo.class);
-        taskVo.setBusinessKey(processInstance.getBusinessKey());
-        taskVo.setMultiInstance(WorkflowUtils.isMultiInstance(task.getProcessDefinitionId(), task.getTaskDefinitionKey()) != null);
-        String businessStatus = WorkflowUtils.getBusinessStatus(taskVo.getBusinessKey());
-        taskVo.setBusinessStatus(businessStatus);
-        return taskVo;
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
index d7c4472..0bf8f42 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
@@ -2,43 +2,42 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.dromara.common.core.domain.dto.RoleDTO;
 import org.dromara.common.core.domain.dto.UserDTO;
-import org.dromara.common.core.service.UserService;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mail.utils.MailUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.common.websocket.dto.WebSocketMessageDto;
-import org.dromara.common.websocket.utils.WebSocketUtils;
-import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.common.sse.dto.SseMessageDto;
+import org.dromara.common.sse.utils.SseMessageUtils;
+import org.dromara.warm.flow.core.constant.ExceptionCons;
+import org.dromara.warm.flow.core.dto.FlowParams;
+import org.dromara.warm.flow.core.entity.Node;
+import org.dromara.warm.flow.core.entity.Task;
+import org.dromara.warm.flow.core.entity.User;
+import org.dromara.warm.flow.core.enums.NodeType;
+import org.dromara.warm.flow.core.enums.SkipType;
+import org.dromara.warm.flow.core.service.NodeService;
+import org.dromara.warm.flow.core.service.TaskService;
+import org.dromara.warm.flow.core.service.UserService;
+import org.dromara.warm.flow.core.utils.AssertUtil;
+import org.dromara.warm.flow.orm.entity.FlowNode;
+import org.dromara.warm.flow.orm.entity.FlowTask;
+import org.dromara.warm.flow.orm.entity.FlowUser;
+import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
+import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
 import org.dromara.workflow.common.enums.MessageTypeEnum;
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.domain.ActHiTaskinst;
-import org.dromara.workflow.domain.vo.MultiInstanceVo;
-import org.dromara.workflow.domain.vo.ParticipantVo;
-import org.dromara.workflow.flowable.cmd.UpdateHiTaskInstCmd;
-import org.dromara.workflow.mapper.ActHiTaskinstMapper;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.FlowNode;
-import org.flowable.common.engine.api.delegate.Expression;
-import org.flowable.engine.ProcessEngine;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
-import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
-import org.flowable.identitylink.api.history.HistoricIdentityLink;
-import org.flowable.task.api.Task;
-import org.flowable.task.api.TaskQuery;
-import org.flowable.task.api.history.HistoricTaskInstance;
-import org.flowable.task.service.impl.persistence.entity.TaskEntity;
+import org.dromara.workflow.service.IFlwTaskAssigneeService;
+import org.dromara.workflow.service.IFlwTaskService;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 
 /**
  * 宸ヤ綔娴佸伐鍏�
@@ -48,220 +47,84 @@
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class WorkflowUtils {
 
-    private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class);
-    private static final ActHiTaskinstMapper ACT_HI_TASKINST_MAPPER = SpringUtils.getBean(ActHiTaskinstMapper.class);
+    private static final IFlwTaskAssigneeService TASK_ASSIGNEE_SERVICE = SpringUtils.getBean(IFlwTaskAssigneeService.class);
+    private static final IFlwTaskService FLW_TASK_SERVICE = SpringUtils.getBean(IFlwTaskService.class);
+    private static final FlowNodeMapper FLOW_NODE_MAPPER = SpringUtils.getBean(FlowNodeMapper.class);
+    private static final FlowTaskMapper FLOW_TASK_MAPPER = SpringUtils.getBean(FlowTaskMapper.class);
+    private static final UserService USER_SERVICE = SpringUtils.getBean(UserService.class);
+    private static final TaskService TASK_SERVICE = SpringUtils.getBean(TaskService.class);
+    private static final NodeService NODE_SERVICE = SpringUtils.getBean(NodeService.class);
 
     /**
-     * 鍒涘缓涓�涓柊浠诲姟
-     *
-     * @param currentTask 鍙傛暟
+     * 鑾峰彇宸ヤ綔娴佺敤鎴穝ervice
      */
-    public static TaskEntity createNewTask(Task currentTask) {
-        TaskEntity task = null;
-        if (ObjectUtil.isNotEmpty(currentTask)) {
-            task = (TaskEntity) PROCESS_ENGINE.getTaskService().newTask();
-            task.setCategory(currentTask.getCategory());
-            task.setDescription(currentTask.getDescription());
-            task.setAssignee(currentTask.getAssignee());
-            task.setName(currentTask.getName());
-            task.setProcessDefinitionId(currentTask.getProcessDefinitionId());
-            task.setProcessInstanceId(currentTask.getProcessInstanceId());
-            task.setTaskDefinitionKey(currentTask.getTaskDefinitionKey());
-            task.setPriority(currentTask.getPriority());
-            task.setCreateTime(new Date());
-            task.setTenantId(TenantHelper.getTenantId());
-            PROCESS_ENGINE.getTaskService().saveTask(task);
-        }
-        if (ObjectUtil.isNotNull(task)) {
-            UpdateHiTaskInstCmd updateHiTaskInstCmd = new UpdateHiTaskInstCmd(Collections.singletonList(task.getId()), task.getProcessDefinitionId(), task.getProcessInstanceId());
-            PROCESS_ENGINE.getManagementService().executeCommand(updateHiTaskInstCmd);
-        }
-        return task;
+    public static UserService getFlowUserService() {
+        return USER_SERVICE;
     }
 
     /**
-     * 鎶勯�佷换鍔�
+     * 鏋勫缓宸ヤ綔娴佺敤鎴�
      *
-     * @param parentTaskList 鐖剁骇浠诲姟
-     * @param userIds        浜哄憳id
+     * @param userList 鍔炵悊鐢ㄦ埛
+     * @param taskId   浠诲姟ID
+     * @return 鐢ㄦ埛
      */
-    public static void createCopyTask(List<Task> parentTaskList, List<Long> userIds) {
-        List<Task> list = new ArrayList<>();
-        String tenantId = TenantHelper.getTenantId();
-        for (Task parentTask : parentTaskList) {
-            for (Long userId : userIds) {
-                TaskEntity newTask = (TaskEntity) PROCESS_ENGINE.getTaskService().newTask();
-                newTask.setParentTaskId(parentTask.getId());
-                newTask.setAssignee(userId.toString());
-                newTask.setName("銆愭妱閫併��-" + parentTask.getName());
-                newTask.setProcessDefinitionId(parentTask.getProcessDefinitionId());
-                newTask.setProcessInstanceId(parentTask.getProcessInstanceId());
-                newTask.setTaskDefinitionKey(parentTask.getTaskDefinitionKey());
-                newTask.setTenantId(tenantId);
-                list.add(newTask);
+    public static Set<User> buildUser(List<User> userList, Long taskId) {
+        if (CollUtil.isEmpty(userList)) {
+            return Set.of();
+        }
+        Set<User> list = new HashSet<>();
+        Set<String> processedBySet = new HashSet<>();
+        for (User user : userList) {
+            // 鏍规嵁 processedBy 鍓嶇紑鍒ゆ柇澶勭悊浜虹被鍨嬶紝鍒嗗埆鑾峰彇鐢ㄦ埛鍒楄〃
+            List<UserDTO> users = TASK_ASSIGNEE_SERVICE.fetchUsersByStorageId(user.getProcessedBy());
+            // 杞崲涓� FlowUser 骞舵坊鍔犲埌缁撴灉闆嗗悎
+            if (CollUtil.isNotEmpty(users)) {
+                users.forEach(dto -> {
+                    String processedBy = String.valueOf(dto.getUserId());
+                    if (!processedBySet.contains(processedBy)) {
+                        FlowUser flowUser = new FlowUser();
+                        flowUser.setType(user.getType());
+                        flowUser.setProcessedBy(processedBy);
+                        flowUser.setAssociated(taskId);
+                        list.add(flowUser);
+                        processedBySet.add(processedBy);
+                    }
+                });
             }
         }
-        PROCESS_ENGINE.getTaskService().bulkSaveTasks(list);
-        if (CollUtil.isNotEmpty(list) && CollUtil.isNotEmpty(parentTaskList)) {
-            String processInstanceId = parentTaskList.get(0).getProcessInstanceId();
-            String processDefinitionId = parentTaskList.get(0).getProcessDefinitionId();
-            List<String> taskIds = StreamUtils.toList(list, Task::getId);
-            ActHiTaskinst actHiTaskinst = new ActHiTaskinst();
-            actHiTaskinst.setProcDefId(processDefinitionId);
-            actHiTaskinst.setProcInstId(processInstanceId);
-            actHiTaskinst.setScopeType(TaskStatusEnum.COPY.getStatus());
-            actHiTaskinst.setTenantId(tenantId);
-            LambdaUpdateWrapper<ActHiTaskinst> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.in(ActHiTaskinst::getId, taskIds);
-            ACT_HI_TASKINST_MAPPER.update(actHiTaskinst, updateWrapper);
-            for (Task task : list) {
-                PROCESS_ENGINE.getTaskService().addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.COPY.getStatus(), StrUtil.EMPTY);
-            }
-        }
-    }
-
-    /**
-     * 鑾峰彇褰撳墠浠诲姟鍙備笌鑰�
-     *
-     * @param taskId 浠诲姟id
-     */
-    public static ParticipantVo getCurrentTaskParticipant(String taskId, UserService userService) {
-        ParticipantVo participantVo = new ParticipantVo();
-        List<HistoricIdentityLink> linksForTask = PROCESS_ENGINE.getHistoryService().getHistoricIdentityLinksForTask(taskId);
-        Task task = QueryUtils.taskQuery().taskId(taskId).singleResult();
-        if (task != null && CollUtil.isNotEmpty(linksForTask)) {
-            List<HistoricIdentityLink> groupList = StreamUtils.filter(linksForTask, e -> StringUtils.isNotBlank(e.getGroupId()));
-            if (CollUtil.isNotEmpty(groupList)) {
-                List<Long> groupIds = StreamUtils.toList(groupList, e -> Long.valueOf(e.getGroupId()));
-                List<Long> userIds = userService.selectUserIdsByRoleIds(groupIds);
-                if (CollUtil.isNotEmpty(userIds)) {
-                    participantVo.setGroupIds(groupIds);
-                    List<UserDTO> userList = userService.selectListByIds(userIds);
-                    if (CollUtil.isNotEmpty(userList)) {
-                        List<Long> userIdList = StreamUtils.toList(userList, UserDTO::getUserId);
-                        List<String> nickNames = StreamUtils.toList(userList, UserDTO::getNickName);
-                        participantVo.setCandidate(userIdList);
-                        participantVo.setCandidateName(nickNames);
-                        participantVo.setClaim(!StringUtils.isBlank(task.getAssignee()));
-                    }
-                }
-            } else {
-                List<HistoricIdentityLink> candidateList = StreamUtils.filter(linksForTask, e -> FlowConstant.CANDIDATE.equals(e.getType()));
-                List<Long> userIdList = new ArrayList<>();
-                for (HistoricIdentityLink historicIdentityLink : linksForTask) {
-                    try {
-                        userIdList.add(Long.valueOf(historicIdentityLink.getUserId()));
-                    } catch (NumberFormatException ignored) {
-
-                    }
-                }
-                List<UserDTO> userList = userService.selectListByIds(userIdList);
-                if (CollUtil.isNotEmpty(userList)) {
-                    List<Long> userIds = StreamUtils.toList(userList, UserDTO::getUserId);
-                    List<String> nickNames = StreamUtils.toList(userList, UserDTO::getNickName);
-                    participantVo.setCandidate(userIds);
-                    participantVo.setCandidateName(nickNames);
-                    // 鍒ゆ柇褰撳墠浠诲姟鏄惁鍏锋湁澶氫釜鍔炵悊浜�
-                    if (CollUtil.isNotEmpty(candidateList) && candidateList.size() > 1) {
-                        // 濡傛灉 assignee 瀛樺湪锛屽垯璁剧疆褰撳墠浠诲姟宸茬粡琚棰�
-                        participantVo.setClaim(StringUtils.isNotBlank(task.getAssignee()));
-                    }
-                }
-            }
-        }
-        return participantVo;
-    }
-
-    /**
-     * 鍒ゆ柇褰撳墠鑺傜偣鏄惁涓轰細绛捐妭鐐�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @param taskDefinitionKey   娴佺▼瀹氫箟id
-     */
-    public static MultiInstanceVo isMultiInstance(String processDefinitionId, String taskDefinitionKey) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey);
-        MultiInstanceVo multiInstanceVo = new MultiInstanceVo();
-        //鍒ゆ柇鏄惁涓哄苟琛屼細绛捐妭鐐�
-        if (flowNode.getBehavior() instanceof ParallelMultiInstanceBehavior behavior && behavior.getCollectionExpression() != null) {
-            Expression collectionExpression = behavior.getCollectionExpression();
-            String assigneeList = collectionExpression.getExpressionText();
-            String assignee = behavior.getCollectionElementVariable();
-            multiInstanceVo.setType(behavior);
-            multiInstanceVo.setAssignee(assignee);
-            multiInstanceVo.setAssigneeList(assigneeList);
-            return multiInstanceVo;
-            //鍒ゆ柇鏄惁涓轰覆琛屼細绛捐妭鐐�
-        } else if (flowNode.getBehavior() instanceof SequentialMultiInstanceBehavior behavior && behavior.getCollectionExpression() != null) {
-            Expression collectionExpression = behavior.getCollectionExpression();
-            String assigneeList = collectionExpression.getExpressionText();
-            String assignee = behavior.getCollectionElementVariable();
-            multiInstanceVo.setType(behavior);
-            multiInstanceVo.setAssignee(assignee);
-            multiInstanceVo.setAssigneeList(assigneeList);
-            return multiInstanceVo;
-        }
-        return null;
-    }
-
-    /**
-     * 鑾峰彇褰撳墠娴佺▼鐘舵��
-     *
-     * @param taskId 浠诲姟id
-     */
-    public static String getBusinessStatusByTaskId(String taskId) {
-        HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery().taskId(taskId).singleResult();
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(historicTaskInstance.getProcessInstanceId()).singleResult();
-        return historicProcessInstance.getBusinessStatus();
-    }
-
-    /**
-     * 鑾峰彇褰撳墠娴佺▼鐘舵��
-     *
-     * @param businessKey 涓氬姟id
-     */
-    public static String getBusinessStatus(String businessKey) {
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
-        return historicProcessInstance.getBusinessStatus();
+        return list;
     }
 
     /**
      * 鍙戦�佹秷鎭�
      *
-     * @param list        浠诲姟
-     * @param name        娴佺▼鍚嶇О
+     * @param flowName    娴佺▼瀹氫箟鍚嶇О
      * @param messageType 娑堟伅绫诲瀷
      * @param message     娑堟伅鍐呭锛屼负绌哄垯鍙戦�侀粯璁ら厤缃殑娑堟伅鍐呭
      */
-    public static void sendMessage(List<Task> list, String name, List<String> messageType, String message, UserService userService) {
-        Set<Long> userIds = new HashSet<>();
+    public static void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
+        List<UserDTO> userList = new ArrayList<>();
+        List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instId);
         if (StringUtils.isBlank(message)) {
-            message = "鏈夋柊鐨勩��" + name + "銆戝崟鎹凡缁忔彁浜よ嚦鎮ㄧ殑寰呭姙锛岃鎮ㄥ強鏃跺鐞嗐��";
+            message = "鏈夋柊鐨勩��" + flowName + "銆戝崟鎹凡缁忔彁浜よ嚦鎮紝璇锋偍鍙婃椂澶勭悊銆�";
         }
-        for (Task t : list) {
-            ParticipantVo taskParticipant = WorkflowUtils.getCurrentTaskParticipant(t.getId(), userService);
-            if (CollUtil.isNotEmpty(taskParticipant.getGroupIds())) {
-                List<Long> userIdList = userService.selectUserIdsByRoleIds(taskParticipant.getGroupIds());
-                if (CollUtil.isNotEmpty(userIdList)) {
-                    userIds.addAll(userIdList);
-                }
-            }
-            List<Long> candidate = taskParticipant.getCandidate();
-            if (CollUtil.isNotEmpty(candidate)) {
-                userIds.addAll(candidate);
+        for (Task task : list) {
+            List<UserDTO> users = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
+            if (CollUtil.isNotEmpty(users)) {
+                userList.addAll(users);
             }
         }
-        if (CollUtil.isNotEmpty(userIds)) {
-            List<UserDTO> userList = userService.selectListByIds(new ArrayList<>(userIds));
+        if (CollUtil.isNotEmpty(userList)) {
             for (String code : messageType) {
                 MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code);
                 if (ObjectUtil.isNotEmpty(messageTypeEnum)) {
                     switch (messageTypeEnum) {
                         case SYSTEM_MESSAGE:
-                            WebSocketMessageDto dto = new WebSocketMessageDto();
-                            dto.setSessionKeys(new ArrayList<>(userIds));
+                            SseMessageDto dto = new SseMessageDto();
+                            dto.setUserIds(StreamUtils.toList(userList, UserDTO::getUserId).stream().distinct().collect(Collectors.toList()));
                             dto.setMessage(message);
-                            WebSocketUtils.publishMessage(dto);
+                            SseMessageUtils.publishMessage(dto);
                             break;
                         case EMAIL_MESSAGE:
                             MailUtils.sendText(StreamUtils.join(userList, UserDTO::getEmail), "鍗曟嵁瀹℃壒鎻愰啋", message);
@@ -269,6 +132,8 @@
                         case SMS_MESSAGE:
                             //todo 鐭俊鍙戦��
                             break;
+                        default:
+                            throw new IllegalStateException("Unexpected value: " + messageTypeEnum);
                     }
                 }
             }
@@ -276,20 +141,66 @@
     }
 
     /**
-     * 鏍规嵁浠诲姟id鏌ヨ 褰撳墠鐢ㄦ埛鐨勪换鍔★紝妫�鏌� 褰撳墠浜哄憳 鏄惁鏄 taskId 鐨勫姙鐞嗕汉
+     * 椹冲洖
      *
-     * @param taskId 浠诲姟id
-     * @return 缁撴灉
+     * @param message        瀹℃壒鎰忚
+     * @param instanceId     娴佺▼瀹炰緥id
+     * @param targetNodeCode 鐩爣鑺傜偣
+     * @param flowStatus     娴佺▼鐘舵��
+     * @param flowHisStatus  鑺傜偣鎿嶄綔鐘舵��
      */
-    public static Task getTaskByCurrentUser(String taskId) {
-        TaskQuery taskQuery = QueryUtils.taskQuery();
-        taskQuery.taskId(taskId).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId()));
-
-        List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
-        if (CollUtil.isNotEmpty(roles)) {
-            List<String> groupIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId()));
-            taskQuery.taskCandidateGroupIn(groupIds);
+    public static void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
+        List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instanceId);
+        if (CollUtil.isNotEmpty(list)) {
+            List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
+            if (list.size() == tasks.size()) {
+                return;
+            }
         }
-        return taskQuery.singleResult();
+        for (FlowTask task : list) {
+            List<UserDTO> userList = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
+            FlowParams flowParams = FlowParams.build();
+            flowParams.nodeCode(targetNodeCode);
+            flowParams.message(message);
+            flowParams.skipType(SkipType.PASS.getKey());
+            flowParams.flowStatus(flowStatus).hisStatus(flowHisStatus);
+            flowParams.ignore(true);
+            //瑙e喅浼氱娌℃潈闄愰棶棰�
+            if (CollUtil.isNotEmpty(userList)) {
+                flowParams.handler(userList.get(0).getUserId().toString());
+            }
+            TASK_SERVICE.skip(task.getId(), flowParams);
+        }
+        //瑙e喅浼氱澶氫汉瀹℃壒闂
+        backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
+    }
+
+    /**
+     * 鐢宠浜鸿妭鐐圭紪鐮�
+     *
+     * @param definitionId 娴佺▼瀹氫箟id
+     * @return 鐢宠浜鸿妭鐐圭紪鐮�
+     */
+    public static String applyNodeCode(Long definitionId) {
+        //鑾峰彇宸插彂甯冪殑娴佺▼鑺傜偣
+        List<FlowNode> flowNodes = FLOW_NODE_MAPPER.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
+        AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
+        Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
+        AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
+        Node nextNode = NODE_SERVICE.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.NONE.getKey());
+        return nextNode.getNodeCode();
+    }
+
+    /**
+     * 鍒犻櫎杩愯涓殑浠诲姟
+     *
+     * @param taskIds 浠诲姟id
+     */
+    public static void deleteRunTask(List<Long> taskIds) {
+        if (CollUtil.isEmpty(taskIds)) {
+            return;
+        }
+        USER_SERVICE.deleteByTaskIds(taskIds);
+        FLOW_TASK_MAPPER.deleteByIds(taskIds);
     }
 }
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiProcinstMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiProcinstMapper.xml
deleted file mode 100644
index dd05785..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiProcinstMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.ActHiProcinstMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiTaskinstMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiTaskinstMapper.xml
deleted file mode 100644
index 7e73b60..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActHiTaskinstMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.ActHiTaskinstMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActTaskMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActTaskMapper.xml
deleted file mode 100644
index 3641900..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/ActTaskMapper.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.ActTaskMapper">
-    <resultMap type="org.dromara.workflow.domain.vo.TaskVo" id="TaskVoResult">
-        <result property="id" column="ID_"/>
-        <result property="name" column="NAME_"/>
-        <result property="description" column="DESCRIPTION_"/>
-        <result property="priority" column="PRIORITY_"/>
-        <result property="owner" column="OWNER_"/>
-        <result property="assignee" column="ASSIGNEE_"/>
-        <result property="processInstanceId" column="PROC_INST_ID_"/>
-        <result property="executionId" column="EXECUTION_ID_"/>
-        <result property="taskDefinitionId" column="TASK_DEF_ID_"/>
-        <result property="processDefinitionId" column="PROC_DEF_ID_"/>
-        <result property="createTime" column="CREATE_TIME_"/>
-        <result property="startTime" column="START_TIME_"/>
-        <result property="endTime" column="END_TIME_"/>
-        <result property="taskDefinitionKey" column="TASK_DEF_KEY_"/>
-        <result property="dueDate" column="DUE_DATE_"/>
-        <result property="category" column="CATEGORY_"/>
-        <result property="parentTaskId" column="PARENT_TASK_ID_"/>
-        <result property="tenantId" column="TENANT_ID_"/>
-        <result property="claimTime" column="CLAIM_TIME"/>
-        <result property="businessStatus" column="BUSINESS_STATUS_"/>
-        <result property="processDefinitionName" column="processDefinitionName"/>
-        <result property="processDefinitionKey" column="processDefinitionKey"/>
-        <result property="processDefinitionVersion" column="processDefinitionVersion"/>
-        <result property="businessKey" column="BUSINESS_KEY_"/>
-
-    </resultMap>
-    <select id="getTaskWaitByPage" resultMap="TaskVoResult">
-        select *
-        from (SELECT RES.*,
-                     AHP.BUSINESS_STATUS_,
-                     AHP.BUSINESS_KEY_,
-                     ARP.NAME_ AS processDefinitionName,
-                     ARP.KEY_  AS processDefinitionKey,
-                     ARP.VERSION_  AS processDefinitionVersion
-              FROM ACT_RU_TASK RES
-                       INNER JOIN ACT_HI_PROCINST AHP ON RES.PROC_INST_ID_ = AHP.PROC_INST_ID_
-                       INNER JOIN ACT_RE_PROCDEF ARP ON ARP.ID_ = RES.PROC_DEF_ID_
-              WHERE RES.PARENT_TASK_ID_ IS NULL) t ${ew.getCustomSqlSegment}
-    </select>
-
-    <select id="getTaskFinishByPage" resultMap="TaskVoResult">
-        select *
-        from (SELECT HTI.*,
-                     AHP.BUSINESS_STATUS_,
-                     AHP.BUSINESS_KEY_,
-                     ARP.NAME_ AS processDefinitionName,
-                     ARP.KEY_  AS processDefinitionKey,
-                     ARP.VERSION_  AS processDefinitionVersion
-              FROM ACT_HI_TASKINST HTI
-                       INNER JOIN ACT_HI_PROCINST AHP ON HTI.PROC_INST_ID_ = AHP.PROC_INST_ID_
-                       INNER JOIN ACT_RE_PROCDEF ARP ON ARP.ID_ = HTI.PROC_DEF_ID_
-              WHERE HTI.PARENT_TASK_ID_ IS NULL AND HTI.END_TIME_ IS NOT NULL
-             ) t ${ew.getCustomSqlSegment}
-    </select>
-
-    <select id="getTaskCopyByPage" resultMap="TaskVoResult">
-        select *
-        from (SELECT AHT.*,
-                     AHP.BUSINESS_STATUS_,
-                     AHP.BUSINESS_KEY_,
-                     ARP.NAME_ as processDefinitionName,
-                     ARP.KEY_  as processDefinitionKey,
-                     ARP.VERSION_  AS processDefinitionVersion
-              FROM ACT_HI_TASKINST AHT
-                       INNER JOIN ACT_HI_PROCINST AHP ON AHT.PROC_INST_ID_ = AHP.PROC_INST_ID_
-                       INNER JOIN ACT_RE_PROCDEF ARP ON ARP.ID_ = AHT.PROC_DEF_ID_
-              WHERE AHT.PARENT_TASK_ID_ IS NOT NULL
-                and AHT.scope_type_ = 'copy'
-             ) t ${ew.getCustomSqlSegment}
-    </select>
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwCategoryMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwCategoryMapper.xml
new file mode 100644
index 0000000..e9918f1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwCategoryMapper.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.workflow.mapper.FlwCategoryMapper">
+
+    <select id="countCategoryById" resultType="Long">
+        select count(*) from flow_category where del_flag = '0' and category_id = #{categoryId}
+    </select>
+
+</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwInstanceMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwInstanceMapper.xml
new file mode 100644
index 0000000..30e2267
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwInstanceMapper.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.workflow.mapper.FlwInstanceMapper">
+    <resultMap type="org.dromara.workflow.domain.vo.FlowInstanceVo" id="FlowInstanceResult">
+    </resultMap>
+
+    <select id="selectInstanceList" resultMap="FlowInstanceResult">
+        select fi.id,
+               fi.create_time,
+               fi.update_time,
+               fi.tenant_id,
+               fi.del_flag,
+               fi.definition_id,
+               fi.business_id,
+               fi.node_type,
+               fi.node_code,
+               fi.node_name,
+               fi.variable,
+               fi.flow_status,
+               fi.activity_status,
+               fi.create_by,
+               fi.ext,
+               fd.flow_name,
+               fd.flow_code,
+               fd.version,
+               fd.form_custom,
+               fd.form_path,
+               fd.category
+        from flow_instance fi
+                 left join flow_definition fd on fi.definition_id = fd.id
+                ${ew.getCustomSqlSegment}
+    </select>
+
+</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml
new file mode 100644
index 0000000..73e4ec7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.workflow.mapper.FlwTaskMapper">
+    <resultMap type="org.dromara.workflow.domain.vo.FlowTaskVo" id="FlowTaskResult">
+    </resultMap>
+    <resultMap type="org.dromara.workflow.domain.vo.FlowHisTaskVo" id="FlowHisTaskResult">
+    </resultMap>
+
+    <select id="getListRunTask" resultMap="FlowTaskResult">
+        select * from (
+            select distinct
+                t.id,
+                t.node_code,
+                t.node_name,
+                t.node_type,
+                t.definition_id,
+                t.instance_id,
+                t.create_time,
+                t.update_time,
+                t.tenant_id,
+                i.business_id,
+                i.flow_status,
+                i.create_by,
+                d.flow_name,
+                d.flow_code,
+                d.form_custom,
+                d.category,
+                COALESCE(t.form_path, d.form_path) as form_path,
+                d.version,
+                uu.processed_by,
+                uu.type
+            from flow_task as t
+                    left join flow_user uu on uu.associated = t.id
+                    left join flow_definition d on t.definition_id = d.id
+                    left join flow_instance i on t.instance_id = i.id
+            where t.node_type = 1
+              and t.del_flag = '0'
+              and uu.del_flag = '0'
+              and uu.type in ('1','2','3')
+         ) t
+         ${ew.getCustomSqlSegment}
+    </select>
+
+    <select id="getListFinishTask" resultMap="FlowHisTaskResult">
+        select * from (
+            select
+                a.id,
+                a.node_code,
+                a.node_name,
+                a.cooperate_type,
+                a.approver,
+                a.collaborator,
+                a.node_type,
+                a.target_node_code,
+                a.target_node_name,
+                a.definition_id,
+                a.instance_id,
+                a.flow_status flow_task_status,
+                a.message,
+                a.ext,
+                a.create_time,
+                a.update_time,
+                a.tenant_id,
+                a.form_custom,
+                a.form_path,
+                b.flow_status,
+                b.business_id,
+                b.create_by,
+                c.flow_name,
+                c.flow_code,
+                c.category,
+                c.version
+            from flow_his_task a
+                    left join flow_instance b on a.instance_id = b.id
+                    left join flow_definition c on a.definition_id = c.id
+            where a.del_flag ='0'
+              and b.del_flag = '0'
+              and c.del_flag = '0'
+              and a.node_type in ('1','3','4')
+        ) t
+        ${ew.getCustomSqlSegment}
+    </select>
+
+    <select id="getTaskCopyByPage" resultMap="FlowTaskResult">
+       select * from (
+            select
+                b.id,
+                b.update_time,
+                c.business_id,
+                c.flow_status,
+                c.create_by,
+                a.processed_by,
+                a.create_time,
+                b.form_custom,
+                b.form_path,
+                b.node_name,
+                b.node_code,
+                d.flow_name,
+                d.flow_code,
+                d.category,
+                d.version
+            from flow_user a
+                left join flow_his_task b on a.associated = b.task_id
+                left join flow_instance c on b.instance_id = c.id
+                left join flow_definition d on c.definition_id=d.id
+            where a.type = '4'
+               and a.del_flag = '0'
+               and b.del_flag = '0'
+               and d.del_flag = '0'
+            ) t
+        ${ew.getCustomSqlSegment}
+    </select>
+</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfCategoryMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfCategoryMapper.xml
deleted file mode 100644
index 4375cb2..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfCategoryMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.WfCategoryMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfDefinitionConfigMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfDefinitionConfigMapper.xml
deleted file mode 100644
index 8d579f7..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfDefinitionConfigMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.WfDefinitionConfigMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfFormManageMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfFormManageMapper.xml
deleted file mode 100644
index 59221f8..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfFormManageMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.WfFormManageMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfNodeConfigMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfNodeConfigMapper.xml
deleted file mode 100644
index b65194f..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfNodeConfigMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.WfNodeConfigMapper">
-
-</mapper>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfTaskBackNodeMapper.xml b/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfTaskBackNodeMapper.xml
deleted file mode 100644
index 4a9179b..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/WfTaskBackNodeMapper.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.workflow.mapper.WfTaskBackNodeMapper">
-
-</mapper>
diff --git a/script/bpmn/leave1.xml b/script/bpmn/leave1.xml
new file mode 100644
index 0000000..1013eb2
--- /dev/null
+++ b/script/bpmn/leave1.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definition flowCode="leave1" flowName="璇峰亣鐢宠-鏅��" version="1" category="1" formCustom="N" formPath="/workflow/leaveEdit/index">
+    <node nodeType="start" nodeCode="d5ee3ddf-3968-4379-a86f-9ceabde5faac" nodeName="寮�濮�" nodeRatio="0.000" coordinate="200,200|200,200" skipAnyNode="N" formCustom="N">
+        <skip coordinate="220,200;310,200" skipType="PASS">dd515cdd-59f6-446f-94ca-25ca062afb42</skip>
+    </node>
+    <node nodeType="between" nodeCode="dd515cdd-59f6-446f-94ca-25ca062afb42" nodeName="鐢宠浜�" nodeRatio="0.000" coordinate="360,200|360,200" skipAnyNode="N" formCustom="N">
+        <skip coordinate="410,200;490,200" skipType="PASS">78fa8e5b-e809-44ed-978a-41092409ebcf</skip>
+    </node>
+    <node nodeType="between" nodeCode="78fa8e5b-e809-44ed-978a-41092409ebcf" nodeName="缁勯暱" permissionFlag="role:1" nodeRatio="0.000" coordinate="540,200|540,200" skipAnyNode="N" formCustom="N">
+        <skip coordinate="590,200;670,200" skipType="PASS">a8abf15f-b83e-428a-86cc-033555ea9bbe</skip>
+    </node>
+    <node nodeType="between" nodeCode="a8abf15f-b83e-428a-86cc-033555ea9bbe" nodeName="閮ㄩ棬涓荤" permissionFlag="role:3,role:4" nodeRatio="0.000" coordinate="720,200|720,200" skipAnyNode="N" formCustom="N">
+        <skip coordinate="770,200;880,200" skipType="PASS">8b82b7d7-8660-455e-b880-d6d22ea3eb6d</skip>
+    </node>
+    <node nodeType="end" nodeCode="8b82b7d7-8660-455e-b880-d6d22ea3eb6d" nodeName="缁撴潫" nodeRatio="0.000" coordinate="900,200|900,200" skipAnyNode="N" formCustom="N"/>
+</definition>
diff --git a/script/bpmn/leave2.xml b/script/bpmn/leave2.xml
new file mode 100644
index 0000000..38ec0a9
--- /dev/null
+++ b/script/bpmn/leave2.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definition flowCode="leave2" flowName="璇峰亣鐢宠-鎺掍粬缃戝叧" version="2" category="1" formCustom="N" formPath="/workflow/leaveEdit/index">
+    <node nodeType="start" nodeCode="cef3895c-f7d8-4598-8bf3-8ec2ef6ce84a" nodeName="寮�濮�" nodeRatio="0.000" coordinate="300,240|300,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="320,240;390,240" skipType="PASS">fdcae93b-b69c-498a-b231-09255e74bcbd</skip>
+    </node>
+    <node nodeType="between" nodeCode="fdcae93b-b69c-498a-b231-09255e74bcbd" nodeName="鐢宠浜�" nodeRatio="0.000" coordinate="440,240|440,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="490,240;535,240" skipType="PASS">7b8c7ead-7dc8-4951-a7f3-f0c41995909e</skip>
+    </node>
+    <node nodeType="serial" nodeCode="7b8c7ead-7dc8-4951-a7f3-f0c41995909e" nodeRatio="0.000" coordinate="560,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="560,265;560,320;670,320" skipType="PASS" skipCondition="@@le@@|leaveDays@@le@@2">b3528155-dcb7-4445-bbdf-3d00e3499e86</skip>
+        <skip coordinate="560,215;560,160;670,160|560,187" skipType="PASS" skipName="澶т簬涓ゅぉ" skipCondition="@@gt@@|leaveDays@@gt@@2">5ed2362b-fc0c-4d52-831f-95208b830605</skip>
+    </node>
+    <node nodeType="between" nodeCode="b3528155-dcb7-4445-bbdf-3d00e3499e86" nodeName="缁勯暱" permissionFlag="3,4" nodeRatio="0.000" coordinate="720,320|720,320" skipAnyNode="N" formCustom="N">
+        <skip coordinate="770,320;860,320;860,280" skipType="PASS">c9fa6d7d-2a74-4e78-b947-0cad8a6af869</skip>
+    </node>
+    <node nodeType="between" nodeCode="c9fa6d7d-2a74-4e78-b947-0cad8a6af869" nodeName="鎬荤粡鐞�" permissionFlag="role:1" nodeRatio="0.000" coordinate="860,240|860,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="910,240;980,240" skipType="PASS">40aa65fd-0712-4d23-b6f7-d0432b920fd1</skip>
+    </node>
+    <node nodeType="end" nodeCode="40aa65fd-0712-4d23-b6f7-d0432b920fd1" nodeName="缁撴潫" nodeRatio="0.000" coordinate="1000,240|1000,240" skipAnyNode="N" formCustom="N"/>
+    <node nodeType="between" nodeCode="5ed2362b-fc0c-4d52-831f-95208b830605" nodeName="閮ㄩ棬棰嗗" permissionFlag="role:1" nodeRatio="0.000" coordinate="720,160|720,160" skipAnyNode="N" formCustom="N">
+        <skip coordinate="770,160;860,160;860,200" skipType="PASS">c9fa6d7d-2a74-4e78-b947-0cad8a6af869</skip>
+    </node>
+</definition>
diff --git a/script/bpmn/leave3.xml b/script/bpmn/leave3.xml
new file mode 100644
index 0000000..ffb8d95
--- /dev/null
+++ b/script/bpmn/leave3.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definition flowCode="leave3" flowName="璇峰亣鐢宠-骞惰缃戝叧" version="1" category="1" formCustom="N" formPath="/workflow/leaveEdit/index">
+    <node nodeType="start" nodeCode="a80ecf9f-f465-4ae5-a429-e30ec5d0f957" nodeName="寮�濮�" nodeRatio="0.000" coordinate="380,220|380,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="400,220;470,220" skipType="PASS">b7bbb571-06de-455c-8083-f83c07bf0b99</skip>
+    </node>
+    <node nodeType="between" nodeCode="b7bbb571-06de-455c-8083-f83c07bf0b99" nodeName="鐢宠浜�" nodeRatio="0.000" coordinate="520,220|520,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="570,220;655,220" skipType="PASS">84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a</skip>
+    </node>
+    <node nodeType="parallel" nodeCode="84d7ed24-bb44-4ba1-bf1f-e6f5092d3f0a" nodeRatio="0.000" coordinate="680,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="680,195;680,140;750,140" skipType="PASS">4b7743cd-940c-431b-926f-e7b614fbf1fe</skip>
+        <skip coordinate="680,245;680,300;750,300" skipType="PASS">762cb975-37d8-4276-b6db-79a4c3606394</skip>
+    </node>
+    <node nodeType="between" nodeCode="4b7743cd-940c-431b-926f-e7b614fbf1fe" nodeName="甯傚満閮�" permissionFlag="role:1" nodeRatio="0.000" coordinate="800,140|800,140" skipAnyNode="N" formCustom="N">
+        <skip coordinate="850,140;920,140;920,195" skipType="PASS">b66b6563-f9fe-41cc-a782-f7837bb6f3d2</skip>
+    </node>
+    <node nodeType="parallel" nodeCode="b66b6563-f9fe-41cc-a782-f7837bb6f3d2" nodeRatio="0.000" coordinate="920,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="945,220;975,220;975,220;960,220;960,220;990,220" skipType="PASS">23e7429e-2b47-4431-b93e-40db7c431ce6</skip>
+    </node>
+    <node nodeType="between" nodeCode="23e7429e-2b47-4431-b93e-40db7c431ce6" nodeName="CEO" permissionFlag="1" nodeRatio="0.000" coordinate="1040,220|1040,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="1090,220;1140,220" skipType="PASS">f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1</skip>
+    </node>
+    <node nodeType="end" nodeCode="f5ace37f-5a5e-4e64-a6f6-913ab9a71cd1" nodeName="缁撴潫" nodeRatio="0.000" coordinate="1160,220|1160,220" skipAnyNode="N" formCustom="N"/>
+    <node nodeType="between" nodeCode="762cb975-37d8-4276-b6db-79a4c3606394" nodeName="缁煎悎閮�" permissionFlag="role:3,role:4" nodeRatio="0.000" coordinate="800,300|800,300" skipAnyNode="N" formCustom="N">
+        <skip coordinate="850,300;920,300;920,245" skipType="PASS">b66b6563-f9fe-41cc-a782-f7837bb6f3d2</skip>
+    </node>
+</definition>
diff --git a/script/bpmn/leave4.xml b/script/bpmn/leave4.xml
new file mode 100644
index 0000000..2061d17
--- /dev/null
+++ b/script/bpmn/leave4.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definition flowCode="leave4" flowName="璇峰亣鐢宠-浼氱" version="1" category="103" formCustom="N" formPath="/workflow/leaveEdit/index">
+    <node nodeType="start" nodeCode="9ce8bf00-f25b-4fc6-91b8-827082fc4876" nodeName="寮�濮�" nodeRatio="0.000" coordinate="320,240|320,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="340,240;410,240" skipType="PASS">e90b98ef-35b4-410c-a663-bae8b7624b9f</skip>
+    </node>
+    <node nodeType="between" nodeCode="e90b98ef-35b4-410c-a663-bae8b7624b9f" nodeName="鐢宠浜�" nodeRatio="0.000" coordinate="460,240|460,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="510,240;590,240" skipType="PASS">768b5b1a-6726-4d67-8853-4cc70d5b1045</skip>
+    </node>
+    <node nodeType="between" nodeCode="768b5b1a-6726-4d67-8853-4cc70d5b1045" nodeName="鐧惧垎涔�60閫氳繃" permissionFlag="${userList}" nodeRatio="60.000" coordinate="640,240|640,240" skipAnyNode="N" anyNodeSkip="e90b98ef-35b4-410c-a663-bae8b7624b9f" formCustom="N">
+        <skip coordinate="690,240;770,240" skipType="PASS">2f9f2e21-9bcf-42a3-a07c-13037aad22d1</skip>
+    </node>
+    <node nodeType="between" nodeCode="2f9f2e21-9bcf-42a3-a07c-13037aad22d1" nodeName="鍏ㄩ儴瀹℃壒閫氳繃" permissionFlag="role:1,role:3" nodeRatio="100.000" coordinate="820,240|820,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="870,240;950,240" skipType="PASS">27461e01-3d9f-4530-8fe3-bd5ec7f9571f</skip>
+    </node>
+    <node nodeType="between" nodeCode="27461e01-3d9f-4530-8fe3-bd5ec7f9571f" nodeName="CEO" permissionFlag="1" nodeRatio="0.000" coordinate="1000,240|1000,240" skipAnyNode="N" formCustom="N">
+        <skip coordinate="1050,240;1080,240;1080,240;1070,240;1070,240;1100,240" skipType="PASS">b62b88c3-8d8d-4969-911e-2aaea219e7fc</skip>
+    </node>
+    <node nodeType="end" nodeCode="b62b88c3-8d8d-4969-911e-2aaea219e7fc" nodeName="缁撴潫" nodeRatio="0.000" coordinate="1120,240|1120,240" skipAnyNode="N" formCustom="N"/>
+</definition>
diff --git a/script/bpmn/leave5.xml b/script/bpmn/leave5.xml
new file mode 100644
index 0000000..d6c0117
--- /dev/null
+++ b/script/bpmn/leave5.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<definition flowCode="leave5" flowName="璇峰亣鐢宠-骞惰浼氱缃戝叧" version="1" category="103" formCustom="N" formPath="/workflow/leaveEdit/index">
+    <node nodeType="start" nodeCode="ebebaf26-9cb6-497e-8119-4c9fed4c597c" nodeName="寮�濮�" nodeRatio="0.000" coordinate="300,220|300,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="320,220;350,220;350,220;340,220;340,220;370,220" skipType="PASS">e1b04e96-dc81-4858-a309-2fe945d2f374</skip>
+    </node>
+    <node nodeType="between" nodeCode="e1b04e96-dc81-4858-a309-2fe945d2f374" nodeName="鐢宠浜�" nodeRatio="0.000" coordinate="420,220|420,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="470,220;535,220" skipType="PASS">3e743f4f-51ca-41d4-8e94-21f5dd9b59c9</skip>
+    </node>
+    <node nodeType="parallel" nodeCode="3e743f4f-51ca-41d4-8e94-21f5dd9b59c9" nodeRatio="0.000" coordinate="560,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="560,245;560,320;650,320" skipType="PASS">c80f273e-1f17-4bd8-9ad1-04a4a94ea862</skip>
+        <skip coordinate="560,195;560,120;650,120" skipType="PASS">1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4</skip>
+    </node>
+    <node nodeType="between" nodeCode="c80f273e-1f17-4bd8-9ad1-04a4a94ea862" nodeName="浼氱" permissionFlag="role:1,role:3" nodeRatio="100.000" coordinate="700,320|700,320" skipAnyNode="N" formCustom="N">
+        <skip coordinate="750,320;860,320;860,245" skipType="PASS">1a20169e-3d82-4926-a151-e2daad28de1b</skip>
+    </node>
+    <node nodeType="parallel" nodeCode="1a20169e-3d82-4926-a151-e2daad28de1b" nodeRatio="0.000" coordinate="860,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="885,220;950,220" skipType="PASS">7a8f0473-e409-442e-a843-5c2b813d00e9</skip>
+    </node>
+    <node nodeType="between" nodeCode="7a8f0473-e409-442e-a843-5c2b813d00e9" nodeName="CEO" permissionFlag="1" nodeRatio="0.000" coordinate="1000,220|1000,220" skipAnyNode="N" formCustom="N">
+        <skip coordinate="1050,220;1120,220" skipType="PASS">03c4d2bc-58b5-4408-a2e4-65afb046f169</skip>
+    </node>
+    <node nodeType="end" nodeCode="03c4d2bc-58b5-4408-a2e4-65afb046f169" nodeName="缁撴潫" nodeRatio="0.000" coordinate="1140,220|1140,220" skipAnyNode="N" formCustom="N"/>
+    <node nodeType="between" nodeCode="1e3e8d3b-18ae-4d6c-a814-ce0d724adfa4" nodeName="鐧惧垎涔�60绁ㄧ" permissionFlag="${userList}" nodeRatio="60.000" coordinate="700,120|700,120" skipAnyNode="N" anyNodeSkip="e1b04e96-dc81-4858-a309-2fe945d2f374" formCustom="N">
+        <skip coordinate="750,120;860,120;860,195" skipType="PASS">1a20169e-3d82-4926-a151-e2daad28de1b</skip>
+    </node>
+</definition>
diff --git "a/script/bpmn/\346\250\241\345\236\213.zip" "b/script/bpmn/\346\250\241\345\236\213.zip"
deleted file mode 100644
index 6f30952..0000000
--- "a/script/bpmn/\346\250\241\345\236\213.zip"
+++ /dev/null
Binary files differ
diff --git a/script/sql/oracle/oracle_ry_workflow.sql b/script/sql/oracle/oracle_ry_workflow.sql
index 65474f4..6a7c5c5 100644
--- a/script/sql/oracle/oracle_ry_workflow.sql
+++ b/script/sql/oracle/oracle_ry_workflow.sql
@@ -1,261 +1,410 @@
-insert into sys_menu values('11616', '宸ヤ綔娴�'  , '0',    '6', 'workflow',          '',                                 '', '1', '0', 'M', '0', '0', '',                       'workflow', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11617', '妯″瀷绠$悊', '11616', '2', 'model',             'workflow/model/index',             '', '1', '1', 'C', '0', '0', 'workflow:model:list',    'model', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11618', '鎴戠殑浠诲姟', '0', '7', 'task',              '',                                 '', '1', '0', 'M', '0', '0', '',                       'my-task', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting',       'workflow/task/taskWaiting',              '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish',       'workflow/task/taskFinish',              '', '1', '1', 'C', '0', '0', '',                       'finish', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList',       'workflow/task/taskCopyList',              '', '1', '1', 'C', '0', '0', '',                       'my-copy', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '',                       'process-definition', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance',   'workflow/processInstance/index',   '', '1', '1', 'C', '0', '0', '',                       'tree-table', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11622', '娴佺▼鍒嗙被', '11616', '1', 'category',          'workflow/category/index',          '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument',        'workflow/task/myDocument',         '', '1', '1', 'C', '0', '0', '',                       'guide', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor',           '',                                 '', '1', '0', 'M', '0', '0', '',                       'monitor', 103, 1, sysdate, NULL, NULL, '');
-insert into sys_menu values('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting',    'workflow/task/allTaskWaiting',     '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, sysdate, NULL, NULL, '');
 
-
--- 娴佺▼鍒嗙被绠$悊鐩稿叧鎸夐挳
-insert into sys_menu values ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add',   '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:edit',  '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:remove','#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:export','#', 103, 1, sysdate, null, null, '');
-
--- 璇峰亣鍗曚俊鎭�
-create table TEST_LEAVE
+create table FLOW_DEFINITION
 (
-    ID          NUMBER(20) not null
-        constraint PK_TEST_LEAVE
-        primary key,
-    LEAVE_TYPE  VARCHAR2(255),
-    START_DATE  DATE,
-    END_DATE    DATE,
-    LEAVE_DAYS  NUMBER(10),
-    REMARK      VARCHAR2(255),
-    STATUS      VARCHAR2(255),
-    CREATE_DEPT NUMBER(20),
-    CREATE_BY   NUMBER(20),
+    ID NUMBER (20) not null,
+    FLOW_CODE VARCHAR2 (40) not null,
+    FLOW_NAME VARCHAR2 (100) not null,
+    CATEGORY VARCHAR2 (100),
+    VERSION VARCHAR2 (20) not null,
+    IS_PUBLISH NUMBER (1) default 0 not null,
+    FORM_CUSTOM VARCHAR2 (1) default 'N',
+    FORM_PATH VARCHAR2 (100),
+    ACTIVITY_STATUS NUMBER (1) default 1,
+    LISTENER_TYPE VARCHAR2 (100),
+    LISTENER_PATH VARCHAR2 (500),
+    EXT VARCHAR2 (500),
     CREATE_TIME DATE,
-    UPDATE_BY   NUMBER(20),
     UPDATE_TIME DATE,
-    TENANT_ID   VARCHAR2(20)
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
 );
 
-comment on table TEST_LEAVE is '璇峰亣鐢宠琛�';
-comment on column TEST_LEAVE.ID is '涓婚敭';
-comment on column TEST_LEAVE.LEAVE_TYPE is '璇峰亣绫诲瀷';
-comment on column TEST_LEAVE.START_DATE is '寮�濮嬫椂闂�';
-comment on column TEST_LEAVE.END_DATE is '缁撴潫鏃堕棿';
-comment on column TEST_LEAVE.LEAVE_DAYS is '璇峰亣澶╂暟';
-comment on column TEST_LEAVE.REMARK is '璇峰亣鍘熷洜';
-comment on column TEST_LEAVE.STATUS is '鐘舵��';
-comment on column TEST_LEAVE.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column TEST_LEAVE.CREATE_BY is '鍒涘缓鑰�';
-comment on column TEST_LEAVE.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column TEST_LEAVE.UPDATE_BY is '鏇存柊鑰�';
-comment on column TEST_LEAVE.UPDATE_TIME is '鏇存柊鏃堕棿';
-comment on column TEST_LEAVE.TENANT_ID is '绉熸埛缂栧彿';
+alter table FLOW_DEFINITION add constraint PK_FLOW_DEFINITION primary key (ID);
 
--- 娴佺▼鍒嗙被淇℃伅琛�
-create table WF_CATEGORY
+comment on table FLOW_DEFINITION is '娴佺▼瀹氫箟琛�';
+comment on column FLOW_DEFINITION.ID is '涓婚敭id';
+comment on column FLOW_DEFINITION.FLOW_CODE is '娴佺▼缂栫爜';
+comment on column FLOW_DEFINITION.FLOW_NAME is '娴佺▼鍚嶇О';
+comment on column FLOW_DEFINITION.CATEGORY is '娴佺▼绫诲埆';
+comment on column FLOW_DEFINITION.VERSION is '娴佺▼鐗堟湰';
+comment on column FLOW_DEFINITION.IS_PUBLISH is '鏄惁鍙戝竷 (0鏈彂甯� 1宸插彂甯� 9澶辨晥)';
+comment on column FLOW_DEFINITION.FORM_CUSTOM is '瀹℃壒琛ㄥ崟鏄惁鑷畾涔� (Y鏄� N鍚�)';
+comment on column FLOW_DEFINITION.FORM_PATH is '瀹℃壒琛ㄥ崟璺緞';
+comment on column FLOW_DEFINITION.ACTIVITY_STATUS is '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級';
+comment on column FLOW_DEFINITION.LISTENER_TYPE is '鐩戝惉鍣ㄧ被鍨�';
+comment on column FLOW_DEFINITION.LISTENER_PATH is '鐩戝惉鍣ㄨ矾寰�';
+comment on column FLOW_DEFINITION.EXT is '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+comment on column FLOW_DEFINITION.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_DEFINITION.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_DEFINITION.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_DEFINITION.TENANT_ID is '绉熸埛id';
+
+create table FLOW_NODE
 (
-    ID            NUMBER(20) not null
-        constraint PK_WF_CATEGORY
-        primary key,
-    CATEGORY_NAME VARCHAR2(255),
-    CATEGORY_CODE VARCHAR2(255)
-        constraint UNI_CATEGORY_CODE
-        unique,
-    PARENT_ID     NUMBER(20),
-    SORT_NUM      NUMBER(10),
-    TENANT_ID     VARCHAR2(20),
-    CREATE_DEPT   NUMBER(20),
-    CREATE_BY     NUMBER(20),
-    CREATE_TIME   DATE,
-    UPDATE_BY     NUMBER(20),
-    UPDATE_TIME   DATE
+    ID NUMBER (20) not null,
+    NODE_TYPE NUMBER (1) not null,
+    DEFINITION_ID NUMBER (20) not null,
+    NODE_CODE VARCHAR2 (100) not null,
+    NODE_NAME VARCHAR2 (100),
+    NODE_RATIO NUMBER (6,3),
+    COORDINATE VARCHAR2 (100),
+    SKIP_ANY_NODE VARCHAR2 (100) default 'N',
+    ANY_NODE_SKIP VARCHAR2 (100),
+    LISTENER_TYPE VARCHAR2 (100),
+    LISTENER_PATH VARCHAR2 (500),
+    HANDLER_TYPE VARCHAR2 (100),
+    HANDLER_PATH VARCHAR2 (400),
+    FORM_CUSTOM VARCHAR2 (1) default 'N',
+    FORM_PATH VARCHAR2 (100),
+    VERSION VARCHAR2 (20),
+    CREATE_TIME DATE,
+    UPDATE_TIME DATE,
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40),
+    PERMISSION_FLAG VARCHAR2 (200)
 );
 
-comment on table WF_CATEGORY is '娴佺▼鍒嗙被';
-comment on column WF_CATEGORY.ID is '涓婚敭';
-comment on column WF_CATEGORY.CATEGORY_NAME is '鍒嗙被鍚嶇О';
-comment on column WF_CATEGORY.CATEGORY_CODE is '鍒嗙被缂栫爜';
-comment on column WF_CATEGORY.PARENT_ID is '鐖剁骇id';
-comment on column WF_CATEGORY.SORT_NUM is '鎺掑簭';
-comment on column WF_CATEGORY.TENANT_ID is '绉熸埛缂栧彿';
-comment on column WF_CATEGORY.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column WF_CATEGORY.CREATE_BY is '鍒涘缓鑰�';
-comment on column WF_CATEGORY.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column WF_CATEGORY.UPDATE_BY is '鏇存柊鑰�';
-comment on column WF_CATEGORY.UPDATE_TIME is '鏇存柊鏃堕棿';
-INSERT INTO wf_category values (1, 'OA', 'OA', 0, 0, '000000', 103, 1, sysdate, 1, sysdate);
+alter table FLOW_NODE add constraint PK_FLOW_NODE primary key (ID);
 
-create table WF_TASK_BACK_NODE
+comment on table FLOW_NODE is '娴佺▼鑺傜偣琛�';
+comment on column FLOW_NODE.ID is '涓婚敭id';
+comment on column FLOW_NODE.NODE_TYPE is '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+comment on column FLOW_NODE.DEFINITION_ID is '瀵瑰簲flow_definition琛ㄧ殑id';
+comment on column FLOW_NODE.NODE_CODE is '娴佺▼鑺傜偣缂栫爜';
+comment on column FLOW_NODE.NODE_NAME is '娴佺▼鑺傜偣鍚嶇О';
+comment on column FLOW_NODE.NODE_RATIO is '娴佺▼绛剧讲姣斾緥鍊�';
+comment on column FLOW_NODE.COORDINATE is '鍧愭爣';
+comment on column FLOW_NODE.SKIP_ANY_NODE is '鏄惁鍙互閫�鍥炰换鎰忚妭鐐癸紙Y鏄� N鍚︼級鍗冲皢鍒犻櫎';
+comment on column FLOW_NODE.ANY_NODE_SKIP is '浠绘剰缁撶偣璺宠浆';
+comment on column FLOW_NODE.LISTENER_TYPE is '鐩戝惉鍣ㄧ被鍨�';
+comment on column FLOW_NODE.LISTENER_PATH is '鐩戝惉鍣ㄨ矾寰�';
+comment on column FLOW_NODE.HANDLER_TYPE is '澶勭悊鍣ㄧ被鍨�';
+comment on column FLOW_NODE.HANDLER_PATH is '澶勭悊鍣ㄨ矾寰�';
+comment on column FLOW_NODE.FORM_CUSTOM is '瀹℃壒琛ㄥ崟鏄惁鑷畾涔� (Y鏄� N鍚�)';
+comment on column FLOW_NODE.FORM_PATH is '瀹℃壒琛ㄥ崟璺緞';
+comment on column FLOW_NODE.VERSION is '鐗堟湰';
+comment on column FLOW_NODE.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_NODE.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_NODE.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_NODE.TENANT_ID is '绉熸埛id';
+comment on column FLOW_NODE.PERMISSION_FLAG is '鏉冮檺鏍囪瘑锛堟潈闄愮被鍨�:鏉冮檺鏍囪瘑锛屽彲浠ュ涓紝鐢ㄩ�楀彿闅斿紑)';
+
+create table FLOW_SKIP
 (
-    ID            NUMBER(20) not null
-        constraint PK_WF_TASK_BACK_NODE
-        primary key,
-    NODE_ID       VARCHAR2(255) not null,
-    NODE_NAME     VARCHAR2(255) not null,
-    ORDER_NO      NUMBER(20) not null,
-    INSTANCE_ID   VARCHAR2(255) not null,
-    TASK_TYPE     VARCHAR2(255) not null,
-    ASSIGNEE      VARCHAR2(2000) not null,
-    TENANT_ID     VARCHAR2(20),
-    CREATE_DEPT   NUMBER(20),
-    CREATE_BY     NUMBER(20),
-    CREATE_TIME   DATE,
-    UPDATE_BY     NUMBER(20),
-    UPDATE_TIME   DATE
+    ID NUMBER (20) not null,
+    DEFINITION_ID NUMBER (20) not null,
+    NOW_NODE_CODE VARCHAR2 (100) not null,
+    NOW_NODE_TYPE NUMBER (1),
+    NEXT_NODE_CODE VARCHAR2 (100) not null,
+    NEXT_NODE_TYPE NUMBER (1),
+    SKIP_NAME VARCHAR2 (100),
+    SKIP_TYPE VARCHAR2 (40),
+    SKIP_CONDITION VARCHAR2 (200),
+    COORDINATE VARCHAR2 (100),
+    CREATE_TIME DATE,
+    UPDATE_TIME DATE,
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
 );
-comment on table WF_TASK_BACK_NODE is '鑺傜偣瀹℃壒璁板綍';
-comment on column WF_TASK_BACK_NODE.ID is '涓婚敭';
-comment on column WF_TASK_BACK_NODE.NODE_ID is '鑺傜偣id';
-comment on column WF_TASK_BACK_NODE.NODE_NAME is '鑺傜偣鍚嶇О';
-comment on column WF_TASK_BACK_NODE.ORDER_NO is '鎺掑簭';
-comment on column WF_TASK_BACK_NODE.INSTANCE_ID is '娴佺▼瀹炰緥id';
-comment on column WF_TASK_BACK_NODE.TASK_TYPE is '鑺傜偣绫诲瀷';
-comment on column WF_TASK_BACK_NODE.ASSIGNEE is '瀹℃壒浜�';
-comment on column WF_TASK_BACK_NODE.TENANT_ID is '绉熸埛缂栧彿';
-comment on column WF_TASK_BACK_NODE.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column WF_TASK_BACK_NODE.CREATE_BY is '鍒涘缓鑰�';
-comment on column WF_TASK_BACK_NODE.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column WF_TASK_BACK_NODE.UPDATE_BY is '鏇存柊鑰�';
-comment on column WF_TASK_BACK_NODE.UPDATE_TIME is '鏇存柊鏃堕棿';
 
-create table WF_DEFINITION_CONFIG
+alter table FLOW_SKIP add constraint PK_FLOW_SKIP primary key (ID);
+
+comment on table FLOW_SKIP is '鑺傜偣璺宠浆鍏宠仈琛�';
+comment on column FLOW_SKIP.ID is '涓婚敭id';
+comment on column FLOW_SKIP.DEFINITION_ID is '娴佺▼瀹氫箟id';
+comment on column FLOW_SKIP.NOW_NODE_CODE is '褰撳墠娴佺▼鑺傜偣绫诲瀷 (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_SKIP.NOW_NODE_TYPE is '涓嬩竴涓祦绋嬭妭鐐圭被鍨� (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_SKIP.NEXT_NODE_CODE is '涓嬩竴涓祦绋嬭妭鐐圭紪鐮�';
+comment on column FLOW_SKIP.NEXT_NODE_TYPE is '涓嬩竴涓祦绋嬭妭鐐圭被鍨� (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_SKIP.SKIP_NAME is '璺宠浆鍚嶇О';
+comment on column FLOW_SKIP.SKIP_TYPE is '璺宠浆绫诲瀷 (PASS瀹℃壒閫氳繃 REJECT閫�鍥�)';
+comment on column FLOW_SKIP.SKIP_CONDITION is '璺宠浆鏉′欢';
+comment on column FLOW_SKIP.COORDINATE is '鍧愭爣';
+comment on column FLOW_SKIP.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_SKIP.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_SKIP.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_SKIP.TENANT_ID is '绉熸埛id';
+
+create table FLOW_INSTANCE
 (
-    ID            NUMBER(20) NOT NULL
-        CONSTRAINT PK_WF_DEFINITION_CONFIG
-        PRIMARY KEY,
-    TABLE_NAME    VARCHAR2(255) NOT NULL,
-    DEFINITION_ID VARCHAR2(255) NOT NULL,
-    PROCESS_KEY   VARCHAR2(255) NOT NULL,
-    VERSION       NUMBER(10)    NOT NULL,
-    REMARK        VARCHAR2(500),
-    TENANT_ID     VARCHAR2(20),
-    CREATE_DEPT   NUMBER(20),
-    CREATE_BY     NUMBER(20),
-    CREATE_TIME   DATE,
-    UPDATE_BY     NUMBER(20),
-    UPDATE_TIME   DATE,
-    constraint uni_definition_id
-        unique (definition_id)
+    ID NUMBER not null,
+    DEFINITION_ID NUMBER not null,
+    BUSINESS_ID VARCHAR2 (40) not null,
+    NODE_TYPE NUMBER (1),
+    NODE_CODE VARCHAR2 (100),
+    NODE_NAME VARCHAR2 (100),
+    VARIABLE CLOB,
+    FLOW_STATUS VARCHAR2 (20),
+    ACTIVITY_STATUS NUMBER (1) default 1,
+    CREATE_BY VARCHAR2 (64) default '',
+    CREATE_TIME DATE,
+    UPDATE_TIME DATE,
+    EXT VARCHAR2 (500),
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
 );
-comment on table WF_DEFINITION_CONFIG is '娴佺▼瀹氫箟閰嶇疆';
-comment on column WF_DEFINITION_CONFIG.ID is '涓婚敭';
-comment on column WF_DEFINITION_CONFIG.TABLE_NAME is '琛ㄥ悕';
-comment on column WF_DEFINITION_CONFIG.DEFINITION_ID is '娴佺▼瀹氫箟ID';
-comment on column WF_DEFINITION_CONFIG.PROCESS_KEY is '娴佺▼KEY';
-comment on column WF_DEFINITION_CONFIG.VERSION is '娴佺▼鐗堟湰';
-comment on column WF_DEFINITION_CONFIG.TENANT_ID is '绉熸埛缂栧彿';
-comment on column WF_DEFINITION_CONFIG.REMARK is '澶囨敞';
-comment on column WF_DEFINITION_CONFIG.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column WF_DEFINITION_CONFIG.CREATE_BY is '鍒涘缓鑰�';
-comment on column WF_DEFINITION_CONFIG.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column WF_DEFINITION_CONFIG.UPDATE_BY is '鏇存柊鑰�';
-comment on column WF_DEFINITION_CONFIG.UPDATE_TIME is '鏇存柊鏃堕棿';
 
-create table WF_FORM_MANAGE
+alter table FLOW_INSTANCE add constraint PK_FLOW_INSTANCE primary key (ID);
+
+comment on table FLOW_INSTANCE is '娴佺▼瀹炰緥琛�';
+comment on column FLOW_INSTANCE.ID is '涓婚敭id';
+comment on column FLOW_INSTANCE.DEFINITION_ID is '瀵瑰簲flow_definition琛ㄧ殑id';
+comment on column FLOW_INSTANCE.BUSINESS_ID is '涓氬姟id';
+comment on column FLOW_INSTANCE.NODE_TYPE is '寮�濮嬭妭鐐圭被鍨� (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_INSTANCE.NODE_CODE is '寮�濮嬭妭鐐圭紪鐮�';
+comment on column FLOW_INSTANCE.NODE_NAME is '寮�濮嬭妭鐐瑰悕绉�';
+comment on column FLOW_INSTANCE.VARIABLE is '浠诲姟鍙橀噺';
+comment on column FLOW_INSTANCE.FLOW_STATUS is '娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 3鑷姩閫氳繃 4缁堟 5浣滃簾 6鎾ら攢 7鍙栧洖  8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�';
+comment on column FLOW_INSTANCE.ACTIVITY_STATUS is '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級';
+comment on column FLOW_INSTANCE.CREATE_BY is '鍒涘缓鑰�';
+comment on column FLOW_INSTANCE.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_INSTANCE.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_INSTANCE.EXT is '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+comment on column FLOW_INSTANCE.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_INSTANCE.TENANT_ID is '绉熸埛id';
+
+create table FLOW_TASK
 (
-    ID            NUMBER(20) NOT NULL
-        CONSTRAINT PK_WF_FORM_MANAGE
-        PRIMARY KEY,
-    FORM_NAME     VARCHAR2(255) NOT NULL,
-    FORM_TYPE     VARCHAR2(255) NOT NULL,
-    ROUTER        VARCHAR2(255) NOT NULL,
-    REMARK        VARCHAR2(500),
-    TENANT_ID     VARCHAR2(20),
-    CREATE_DEPT   NUMBER(20),
-    CREATE_BY     NUMBER(20),
-    CREATE_TIME   DATE,
-    UPDATE_BY     NUMBER(20),
-    UPDATE_TIME   DATE
+    ID NUMBER (20) not null,
+    DEFINITION_ID NUMBER (20) not null,
+    INSTANCE_ID NUMBER (20) not null,
+    NODE_CODE VARCHAR2 (100),
+    NODE_NAME VARCHAR2 (100),
+    NODE_TYPE NUMBER (1),
+    FORM_CUSTOM VARCHAR2 (1) default 'N',
+    FORM_PATH VARCHAR2 (100),
+    CREATE_TIME DATE,
+    UPDATE_TIME DATE,
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
 );
 
-comment on table WF_FORM_MANAGE is '琛ㄥ崟绠$悊';
-comment on column WF_FORM_MANAGE.ID is '涓婚敭';
-comment on column WF_FORM_MANAGE.FORM_NAME is '琛ㄥ崟鍚嶇О';
-comment on column WF_FORM_MANAGE.FORM_TYPE is '琛ㄥ崟绫诲瀷';
-comment on column WF_FORM_MANAGE.ROUTER is '璺敱鍦板潃/琛ㄥ崟ID';
-comment on column WF_FORM_MANAGE.REMARK is '澶囨敞';
-comment on column WF_FORM_MANAGE.TENANT_ID is '绉熸埛缂栧彿';
-comment on column WF_FORM_MANAGE.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column WF_FORM_MANAGE.CREATE_BY is '鍒涘缓鑰�';
-comment on column WF_FORM_MANAGE.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column WF_FORM_MANAGE.UPDATE_BY is '鏇存柊鑰�';
-comment on column WF_FORM_MANAGE.UPDATE_TIME is '鏇存柊鏃堕棿';
+alter table FLOW_TASK add constraint PK_FLOW_TASK primary key (ID);
 
-insert into wf_form_manage(id, form_name, form_type, router, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time) VALUES (1, '璇峰亣鐢宠', 'static', '/workflow/leaveEdit/index', NULL, '000000', 103, 1, sysdate, 1, sysdate);
+comment on table FLOW_TASK is '寰呭姙浠诲姟琛�';
+comment on column FLOW_TASK.ID is '涓婚敭id';
+comment on column FLOW_TASK.DEFINITION_ID is '瀵瑰簲flow_definition琛ㄧ殑id';
+comment on column FLOW_TASK.INSTANCE_ID is '瀵瑰簲flow_instance琛ㄧ殑id';
+comment on column FLOW_TASK.NODE_CODE is '鑺傜偣缂栫爜';
+comment on column FLOW_TASK.NODE_NAME is '鑺傜偣鍚嶇О';
+comment on column FLOW_TASK.NODE_TYPE is '鑺傜偣绫诲瀷 (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_TASK.FORM_CUSTOM is '瀹℃壒琛ㄥ崟鏄惁鑷畾涔� (Y鏄� N鍚�)';
+comment on column FLOW_TASK.FORM_PATH is '瀹℃壒琛ㄥ崟璺緞';
+comment on column FLOW_TASK.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_TASK.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_TASK.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_TASK.TENANT_ID is '绉熸埛id';
 
-create table WF_NODE_CONFIG
+create table FLOW_HIS_TASK
 (
-    ID               NUMBER(20) NOT NULL
-        CONSTRAINT PK_WF_NODE_CONFIG
-        PRIMARY KEY,
-    FORM_ID          NUMBER(20),
-    FORM_TYPE        VARCHAR2(255),
-    NODE_NAME        VARCHAR2(255) NOT NULL,
-    NODE_ID          VARCHAR2(255) NOT NULL,
-    DEFINITION_ID    VARCHAR2(255) NOT NULL,
-    APPLY_USER_TASK  CHAR(1) DEFAULT '0',
-    TENANT_ID        VARCHAR2(20),
-    CREATE_DEPT      NUMBER(20),
-    CREATE_BY        NUMBER(20),
-    CREATE_TIME      DATE,
-    UPDATE_BY        NUMBER(20),
-    UPDATE_TIME      DATE
+    ID NUMBER (20) not null,
+    DEFINITION_ID NUMBER (20) not null,
+    INSTANCE_ID NUMBER (20) not null,
+    TASK_ID NUMBER (20) not null,
+    NODE_CODE VARCHAR2 (100),
+    NODE_NAME VARCHAR2 (100),
+    NODE_TYPE NUMBER (1),
+    TARGET_NODE_CODE VARCHAR2 (100),
+    TARGET_NODE_NAME VARCHAR2 (100),
+    APPROVER VARCHAR2 (40),
+    COOPERATE_TYPE NUMBER (1) default 0,
+    COLLABORATOR VARCHAR2 (40),
+    SKIP_TYPE VARCHAR2 (10),
+    FLOW_STATUS VARCHAR2 (20),
+    FORM_CUSTOM VARCHAR2 (1) default 'N',
+    FORM_PATH VARCHAR2 (100),
+    MESSAGE VARCHAR2 (500),
+    EXT VARCHAR2 (500),
+    CREATE_TIME DATE,
+    UPDATE_TIME DATE,
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
 );
 
-comment on table WF_NODE_CONFIG is '鑺傜偣閰嶇疆';
-comment on column WF_NODE_CONFIG.ID is '涓婚敭';
-comment on column WF_NODE_CONFIG.FORM_ID is '琛ㄥ崟id';
-comment on column WF_NODE_CONFIG.FORM_TYPE is '琛ㄥ崟绫诲瀷';
-comment on column WF_NODE_CONFIG.NODE_ID is '鑺傜偣id';
-comment on column WF_NODE_CONFIG.NODE_NAME is '鑺傜偣鍚嶇О';
-comment on column WF_NODE_CONFIG.DEFINITION_ID is '娴佺▼瀹氫箟id';
-comment on column WF_NODE_CONFIG.APPLY_USER_TASK is '鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級';
-comment on column WF_NODE_CONFIG.TENANT_ID is '绉熸埛缂栧彿';
-comment on column WF_NODE_CONFIG.CREATE_DEPT is '鍒涘缓閮ㄩ棬';
-comment on column WF_NODE_CONFIG.CREATE_BY is '鍒涘缓鑰�';
-comment on column WF_NODE_CONFIG.CREATE_TIME is '鍒涘缓鏃堕棿';
-comment on column WF_NODE_CONFIG.UPDATE_BY is '鏇存柊鑰�';
-comment on column WF_NODE_CONFIG.UPDATE_TIME is '鏇存柊鏃堕棿';
+alter table FLOW_HIS_TASK add constraint PK_FLOW_HIS_TASK primary key (ID);
 
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11638, '璇峰亣鐢宠', 5, 1, 'leave', 'workflow/leave/index', 1, 0, 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, sysdate, NULL, NULL, '璇峰亣鐢宠鑿滃崟');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11639, '璇峰亣鐢宠鏌ヨ', 11638, 1, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, sysdate, NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11640, '璇峰亣鐢宠鏂板', 11638, 2, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, sysdate, NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11641, '璇峰亣鐢宠淇敼', 11638, 3, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, sysdate, NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11642, '璇峰亣鐢宠鍒犻櫎', 11638, 4, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, sysdate, NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11643, '璇峰亣鐢宠瀵煎嚭', 11638, 5, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, sysdate, NULL, NULL, '');
+comment on table FLOW_HIS_TASK is '鍘嗗彶浠诲姟璁板綍琛�';
+comment on column FLOW_HIS_TASK.ID is '涓婚敭id';
+comment on column FLOW_HIS_TASK.DEFINITION_ID is '瀵瑰簲flow_definition琛ㄧ殑id';
+comment on column FLOW_HIS_TASK.INSTANCE_ID is '瀵瑰簲flow_instance琛ㄧ殑id';
+comment on column FLOW_HIS_TASK.TASK_ID is '瀵瑰簲flow_task琛ㄧ殑id';
+comment on column FLOW_HIS_TASK.NODE_CODE is '寮�濮嬭妭鐐圭紪鐮�';
+comment on column FLOW_HIS_TASK.NODE_NAME is '寮�濮嬭妭鐐瑰悕绉�';
+comment on column FLOW_HIS_TASK.NODE_TYPE is '寮�濮嬭妭鐐圭被鍨� (0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧)';
+comment on column FLOW_HIS_TASK.TARGET_NODE_CODE is '鐩爣鑺傜偣缂栫爜';
+comment on column FLOW_HIS_TASK.TARGET_NODE_NAME is '鐩爣鑺傜偣鍚嶇О';
+comment on column FLOW_HIS_TASK.SKIP_TYPE is '娴佽浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級';
+comment on column FLOW_HIS_TASK.FLOW_STATUS is '娴佺▼鐘舵�侊紙1瀹℃壒涓� 2 瀹℃壒閫氳繃 9宸查��鍥� 10澶辨晥锛�';
+comment on column FLOW_HIS_TASK.FORM_CUSTOM is '瀹℃壒琛ㄥ崟鏄惁鑷畾涔� (Y鏄� N鍚�)';
+comment on column FLOW_HIS_TASK.FORM_PATH is '瀹℃壒琛ㄥ崟璺緞';
+comment on column FLOW_HIS_TASK.MESSAGE is '瀹℃壒鎰忚';
+comment on column FLOW_HIS_TASK.EXT is '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+comment on column FLOW_HIS_TASK.CREATE_TIME is '浠诲姟寮�濮嬫椂闂�';
+comment on column FLOW_HIS_TASK.UPDATE_TIME is '瀹℃壒瀹屾垚鏃堕棿';
+comment on column FLOW_HIS_TASK.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_HIS_TASK.TENANT_ID is '绉熸埛id';
+comment on column FLOW_HIS_TASK.APPROVER is '瀹℃壒鑰�';
+comment on column FLOW_HIS_TASK.COOPERATE_TYPE is '鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)';
+comment on column FLOW_HIS_TASK.COLLABORATOR is '鍗忎綔浜�';
 
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, sysdate, NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, sysdate, NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
+create table FLOW_USER
+(
+    ID NUMBER (20) not null,
+    TYPE VARCHAR2 (1) not null,
+    PROCESSED_BY VARCHAR2 (80),
+    ASSOCIATED NUMBER (20) not null,
+    CREATE_TIME DATE,
+    CREATE_BY VARCHAR2 (80),
+    UPDATE_TIME DATE,
+    DEL_FLAG VARCHAR2 (1) default '0',
+    TENANT_ID VARCHAR2 (40)
+);
 
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate, NULL, NULL, '宸叉挙閿�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, sysdate, NULL, NULL, '鑽夌');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1,sysdate, NULL, NULL, '寰呭鏍�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, sysdate, NULL, NULL, '宸插畬鎴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate, NULL, NULL, '宸蹭綔搴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate, NULL, NULL, '宸查��鍥�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1,sysdate, NULL, NULL, '宸茬粓姝�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, sysdate, NULL, NULL, '鑷畾涔夎〃鍗�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, sysdate, NULL, NULL, '鍔ㄦ�佽〃鍗�');
+alter table FLOW_USER add constraint PK_FLOW_USER primary key (ID);
 
--- 琛ㄥ崟绠$悊 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11628, '琛ㄥ崟绠$悊', '11616', '5', 'formManage', 'workflow/formManage/index', 1, 0, 'C', '0', '0', 'workflow:formManage:list', 'tree-table', 103, 1, sysdate, null, null, '琛ㄥ崟绠$悊鑿滃崟');
+comment on table FLOW_USER is '寰呭姙浠诲姟琛�';
+comment on column FLOW_USER.ID is '涓婚敭id';
+comment on column FLOW_USER.TYPE is '浜哄憳绫诲瀷锛�1寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺 2寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺 3寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺锛�';
+comment on column FLOW_USER.PROCESSED_BY is '鏉冮檺浜�)';
+comment on column FLOW_USER.ASSOCIATED is '浠诲姟琛╥d';
+comment on column FLOW_USER.CREATE_TIME is '鍒涘缓鏃堕棿';
+comment on column FLOW_USER.CREATE_BY is '鑺傜偣鍚嶇О';
+comment on column FLOW_USER.UPDATE_TIME is '鏇存柊鏃堕棿';
+comment on column FLOW_USER.DEL_FLAG is '鍒犻櫎鏍囧織';
+comment on column FLOW_USER.TENANT_ID is '绉熸埛id';
 
--- 琛ㄥ崟绠$悊鎸夐挳 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11644, '琛ㄥ崟绠$悊鏌ヨ', 11628, '1',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:query',        '', 103, 1, sysdate, null, null, '');
+create index USER_PROCESSED_TYPE on FLOW_USER (PROCESSED_BY, TYPE);
 
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11645, '琛ㄥ崟绠$悊鏂板', 11628, '2',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:add',          '', 103, 1, sysdate, null, null, '');
+-- ----------------------------
+-- 娴佺▼鍒嗙被琛�
+-- ----------------------------
+CREATE TABLE flow_category
+(
+    category_id NUMBER (20) NOT NULL,
+    tenant_id VARCHAR2 (20) DEFAULT '000000',
+    parent_id NUMBER (20) DEFAULT 0,
+    ancestors VARCHAR2 (500) DEFAULT '',
+    category_name VARCHAR2 (30) NOT NULL,
+    order_num NUMBER (4) DEFAULT 0,
+    del_flag    CHAR(1) DEFAULT '0',
+    create_dept NUMBER (20),
+    create_by NUMBER (20),
+    create_time DATE,
+    update_by NUMBER (20),
+    update_time DATE
+);
 
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11646, '琛ㄥ崟绠$悊淇敼', 11628, '3',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:edit',         '', 103, 1, sysdate, null, null, '');
+alter table flow_category add constraint pk_flow_category primary key (category_id);
 
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11647, '琛ㄥ崟绠$悊鍒犻櫎', 11628, '4',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:remove',       '', 103, 1, sysdate, null, null, '');
+COMMENT ON TABLE flow_category IS '娴佺▼鍒嗙被';
+COMMENT ON COLUMN flow_category.category_id IS '娴佺▼鍒嗙被ID';
+COMMENT ON COLUMN flow_category.tenant_id IS '绉熸埛缂栧彿';
+COMMENT ON COLUMN flow_category.parent_id IS '鐖舵祦绋嬪垎绫籭d';
+COMMENT ON COLUMN flow_category.ancestors IS '绁栫骇鍒楄〃';
+COMMENT ON COLUMN flow_category.category_name IS '娴佺▼鍒嗙被鍚嶇О';
+COMMENT ON COLUMN flow_category.order_num IS '鏄剧ず椤哄簭';
+COMMENT ON COLUMN flow_category.del_flag IS '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�';
+COMMENT ON COLUMN flow_category.create_dept IS '鍒涘缓閮ㄩ棬';
+COMMENT ON COLUMN flow_category.create_by IS '鍒涘缓鑰�';
+COMMENT ON COLUMN flow_category.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_category.update_by IS '鏇存柊鑰�';
+COMMENT ON COLUMN flow_category.update_time IS '鏇存柊鏃堕棿';
 
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11648, '琛ㄥ崟绠$悊瀵煎嚭', 11628, '5',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:export',       'tree-table', 103, 1, sysdate, null, null, '');
+INSERT INTO flow_category VALUES (100, '000000', 0, '0', 'OA瀹℃壒', 0, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (101, '000000', 100, '0,100', '鍋囧嫟绠$悊', 0, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (102, '000000', 100, '0,100', '浜轰簨绠$悊', 0, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (103, '000000', 101, '0,100,101', '璇峰亣', 0, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (104, '000000', 101, '0,100,101', '鍑哄樊', 1, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (105, '000000', 101, '0,100,101', '鍔犵彮', 2, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (106, '000000', 101, '0,100,101', '鎹㈢彮', 3, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (107, '000000', 101, '0,100,101', '澶栧嚭', 4, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (108, '000000', 102, '0,100,102', '杞', 1, '0', 103, 1, SYSDATE, NULL, NULL);
+INSERT INTO flow_category VALUES (109, '000000', 102, '0,100,102', '绂昏亴', 2, '0', 103, 1, SYSDATE, NULL, NULL);
+
+
+-- ----------------------------
+-- 璇峰亣鍗曚俊鎭�
+-- ----------------------------
+CREATE TABLE test_leave
+(
+    id NUMBER (20) NOT NULL,
+    tenant_id VARCHAR2 (20) DEFAULT '000000',
+    leave_type VARCHAR2 (255) NOT NULL,
+    start_date  DATE NOT NULL,
+    end_date    DATE NOT NULL,
+    leave_days NUMBER (10) NOT NULL,
+    remark VARCHAR2 (255),
+    status VARCHAR2 (255),
+    create_dept NUMBER (20),
+    create_by NUMBER (20),
+    create_time DATE,
+    update_by NUMBER (20),
+    update_time DATE
+);
+
+alter table test_leave add constraint pk_test_leave primary key (id);
+
+COMMENT ON TABLE test_leave IS '璇峰亣鐢宠琛�';
+COMMENT ON COLUMN test_leave.id IS 'ID';
+COMMENT ON COLUMN test_leave.tenant_id IS '绉熸埛缂栧彿';
+COMMENT ON COLUMN test_leave.leave_type IS '璇峰亣绫诲瀷';
+COMMENT ON COLUMN test_leave.start_date IS '寮�濮嬫椂闂�';
+COMMENT ON COLUMN test_leave.end_date IS '缁撴潫鏃堕棿';
+COMMENT ON COLUMN test_leave.leave_days IS '璇峰亣澶╂暟';
+COMMENT ON COLUMN test_leave.remark IS '璇峰亣鍘熷洜';
+COMMENT ON COLUMN test_leave.status IS '鐘舵��';
+COMMENT ON COLUMN test_leave.create_dept IS '鍒涘缓閮ㄩ棬';
+COMMENT ON COLUMN test_leave.create_by IS '鍒涘缓鑰�';
+COMMENT ON COLUMN test_leave.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN test_leave.update_by IS '鏇存柊鑰�';
+COMMENT ON COLUMN test_leave.update_time IS '鏇存柊鏃堕棿';
+
+INSERT INTO sys_menu VALUES ('11616', '宸ヤ綔娴�', '0', '6', 'workflow', '', '', '1', '0', 'M', '0', '0', '', 'workflow', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11618', '鎴戠殑浠诲姟', '0', '7', 'task', '', '', '1', '0', 'M', '0', '0', '', 'my-task', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting', 'workflow/task/taskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish', 'workflow/task/taskFinish', '', '1', '1', 'C', '0', '0', '', 'finish', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList', 'workflow/task/taskCopyList', '', '1', '1', 'C', '0', '0', '', 'my-copy', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '', 'process-definition', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance', 'workflow/processInstance/index', '', '1', '1', 'C', '0', '0', '', 'tree-table', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11622', '娴佺▼鍒嗙被', '11616', '1', 'category', 'workflow/category/index', '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, SYSDATE, NULL, NULL, '');
+
+INSERT INTO sys_menu VALUES ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:query', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:add', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:remove', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:export', '#', 103, 1, SYSDATE, NULL, NULL, '');
+
+INSERT INTO sys_menu VALUES ('11638', '璇峰亣鐢宠', '5', '1', 'leave', 'workflow/leave/index', '', '1', '0', 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, SYSDATE, NULL, NULL, '璇峰亣鐢宠鑿滃崟');
+INSERT INTO sys_menu VALUES ('11639', '璇峰亣鐢宠鏌ヨ', '11638', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11640', '璇峰亣鐢宠鏂板', '11638', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11641', '璇峰亣鐢宠淇敼', '11638', '3', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11642', '璇峰亣鐢宠鍒犻櫎', '11638', '4', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, SYSDATE, NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11643', '璇峰亣鐢宠瀵煎嚭', '11638', '5', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, SYSDATE, NULL, NULL, '');
+
+INSERT INTO sys_dict_type VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, SYSDATE, NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
+INSERT INTO sys_dict_type VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, SYSDATE, NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
+INSERT INTO sys_dict_type VALUES (15, '000000', '浠诲姟鐘舵��', 'wf_task_status', 103, 1, SYSDATE, NULL, NULL, '浠诲姟鐘舵��');
+INSERT INTO sys_dict_data VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '宸叉挙閿�');
+INSERT INTO sys_dict_data VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, SYSDATE, NULL, NULL, '鑽夌');
+INSERT INTO sys_dict_data VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, SYSDATE, NULL, NULL, '宸插畬鎴�');
+INSERT INTO sys_dict_data VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '宸蹭綔搴�');
+INSERT INTO sys_dict_data VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '宸查��鍥�');
+INSERT INTO sys_dict_data VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '宸茬粓姝�');
+INSERT INTO sys_dict_data VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, SYSDATE, NULL, NULL, '鑷畾涔夎〃鍗�');
+INSERT INTO sys_dict_data VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '鍔ㄦ�佽〃鍗�');
+INSERT INTO sys_dict_data VALUES (48, '000000', 1, '鎾ら攢', 'cancel', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '鎾ら攢');
+INSERT INTO sys_dict_data VALUES (49, '000000', 2, '閫氳繃', 'pass', 'wf_task_status', '', 'success', 'N', 103, 1, SYSDATE, NULL, NULL, '閫氳繃');
+INSERT INTO sys_dict_data VALUES (50, '000000', 3, '寰呭鏍�', 'waiting', 'wf_task_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (51, '000000', 4, '浣滃簾', 'invalid', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '浣滃簾');
+INSERT INTO sys_dict_data VALUES (52, '000000', 5, '閫�鍥�', 'back', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '閫�鍥�');
+INSERT INTO sys_dict_data VALUES (53, '000000', 6, '缁堟', 'termination', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '缁堟');
+INSERT INTO sys_dict_data VALUES (54, '000000', 7, '杞姙', 'transfer', 'wf_task_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '杞姙');
+INSERT INTO sys_dict_data VALUES (55, '000000', 8, '濮旀墭', 'depute', 'wf_task_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '濮旀墭');
+INSERT INTO sys_dict_data VALUES (56, '000000', 9, '鎶勯��', 'copy', 'wf_task_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '鎶勯��');
+INSERT INTO sys_dict_data VALUES (57, '000000', 10, '鍔犵', 'sign', 'wf_task_status', '', 'primary', 'N', 103, 1, SYSDATE, NULL, NULL, '鍔犵');
+INSERT INTO sys_dict_data VALUES (58, '000000', 11, '鍑忕', 'sign_off', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '鍑忕');
+INSERT INTO sys_dict_data VALUES (59, '000000', 11, '瓒呮椂', 'timeout', 'wf_task_status', '', 'danger', 'N', 103, 1, SYSDATE, NULL, NULL, '瓒呮椂');
diff --git a/script/sql/postgres/postgres_ry_workflow.sql b/script/sql/postgres/postgres_ry_workflow.sql
index 8a6078d..aacd145 100644
--- a/script/sql/postgres/postgres_ry_workflow.sql
+++ b/script/sql/postgres/postgres_ry_workflow.sql
@@ -1,275 +1,401 @@
-insert into sys_menu values('11616', '宸ヤ綔娴�'  , '0',    '6', 'workflow',          '',                                 '', '1', '0', 'M', '0', '0', '',                       'workflow', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11617', '妯″瀷绠$悊', '11616', '2', 'model',             'workflow/model/index',             '', '1', '1', 'C', '0', '0', 'workflow:model:list',    'model', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11618', '鎴戠殑浠诲姟', '0', '7', 'task',              '',                                 '', '1', '0', 'M', '0', '0', '',                       'my-task', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting',       'workflow/task/taskWaiting',              '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish',       'workflow/task/taskFinish',              '', '1', '1', 'C', '0', '0', '',                       'finish', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList',       'workflow/task/taskCopyList',              '', '1', '1', 'C', '0', '0', '',                       'my-copy', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '',                       'process-definition', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance',   'workflow/processInstance/index',   '', '1', '1', 'C', '0', '0', '',                       'tree-table', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11622', '娴佺▼鍒嗙被', '11616', '1', 'category',          'workflow/category/index',          '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument',        'workflow/task/myDocument',         '', '1', '1', 'C', '0', '0', '',                       'guide', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor',           '',                                 '', '1', '0', 'M', '0', '0', '',                       'monitor', 103, 1, now(), NULL, NULL, '');
-insert into sys_menu values('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting',    'workflow/task/allTaskWaiting',     '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, now(), NULL, NULL, '');
+-- ----------------------------
+-- 0銆亀arm-flow-all.sql锛屽湴鍧�锛歨ttps://gitee.com/dromara/warm-flow/blob/master/sql/postgresql/postgresql-warm-flow-all.sql
+-- ----------------------------
+CREATE TABLE flow_definition
+(
+    id              int8         NOT NULL,                      -- 涓婚敭id
+    flow_code       varchar(40)  NOT NULL,                      -- 娴佺▼缂栫爜
+    flow_name       varchar(100) NOT NULL,                      -- 娴佺▼鍚嶇О
+    category        varchar(100) NULL,                          -- 娴佺▼绫诲埆
+    "version"       varchar(20)  NOT NULL,                      -- 娴佺▼鐗堟湰
+    is_publish      int2         NOT NULL DEFAULT 0,            -- 鏄惁鍙戝竷锛�0鏈彂甯� 1宸插彂甯� 9澶辨晥锛�
+    form_custom     bpchar(1) NULL DEFAULT 'N':: character varying, -- 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+    form_path       varchar(100) NULL,                          -- 瀹℃壒琛ㄥ崟璺緞
+    activity_status int2         NOT NULL DEFAULT 1,            -- 娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級
+    listener_type   varchar(100) NULL,                          -- 鐩戝惉鍣ㄧ被鍨�
+    listener_path   varchar(400) NULL,                          -- 鐩戝惉鍣ㄨ矾寰�
+    ext             varchar(500) NULL,                          -- 鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤
+    create_time     timestamp    NULL,                          -- 鍒涘缓鏃堕棿
+    update_time     timestamp    NULL,                          -- 鏇存柊鏃堕棿
+    del_flag        bpchar(1) NULL DEFAULT '0':: character varying,    -- 鍒犻櫎鏍囧織
+    tenant_id       varchar(40)  NULL,                          -- 绉熸埛id
+    CONSTRAINT flow_definition_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_definition IS '娴佺▼瀹氫箟琛�';
+
+COMMENT ON COLUMN flow_definition.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_definition.flow_code IS '娴佺▼缂栫爜';
+COMMENT ON COLUMN flow_definition.flow_name IS '娴佺▼鍚嶇О';
+COMMENT ON COLUMN flow_definition.category IS '娴佺▼绫诲埆';
+COMMENT ON COLUMN flow_definition."version" IS '娴佺▼鐗堟湰';
+COMMENT ON COLUMN flow_definition.is_publish IS '鏄惁鍙戝竷锛�0鏈彂甯� 1宸插彂甯� 9澶辨晥锛�';
+COMMENT ON COLUMN flow_definition.form_custom IS '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級';
+COMMENT ON COLUMN flow_definition.form_path IS '瀹℃壒琛ㄥ崟璺緞';
+COMMENT ON COLUMN flow_definition.activity_status IS '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級';
+COMMENT ON COLUMN flow_definition.listener_type IS '鐩戝惉鍣ㄧ被鍨�';
+COMMENT ON COLUMN flow_definition.listener_path IS '鐩戝惉鍣ㄨ矾寰�';
+COMMENT ON COLUMN flow_definition.ext IS '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+COMMENT ON COLUMN flow_definition.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_definition.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_definition.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_definition.tenant_id IS '绉熸埛id';
+
+CREATE TABLE flow_node
+(
+    id              int8          NOT NULL,                             -- 涓婚敭id
+    node_type       int2          NOT NULL,                             -- 鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    definition_id   int8          NOT NULL,                             -- 娴佺▼瀹氫箟id
+    node_code       varchar(100)  NOT NULL,                             -- 娴佺▼鑺傜偣缂栫爜
+    node_name       varchar(100)  NULL,                                 -- 娴佺▼鑺傜偣鍚嶇О
+    permission_flag varchar(200)  NULL,                                 -- 鏉冮檺鏍囪瘑锛堟潈闄愮被鍨�:鏉冮檺鏍囪瘑锛屽彲浠ュ涓紝鐢ㄩ�楀彿闅斿紑)
+    node_ratio      numeric(6, 3) NULL,                                 -- 娴佺▼绛剧讲姣斾緥鍊�
+    coordinate      varchar(100)  NULL,                                 -- 鍧愭爣
+    skip_any_node   varchar(100)  NULL DEFAULT 'N':: character varying, -- 鏄惁鍙互閫�鍥炰换鎰忚妭鐐癸紙Y鏄� N鍚︼級鍗冲皢鍒犻櫎
+    any_node_skip   varchar(100)  NULL,                                 -- 浠绘剰缁撶偣璺宠浆
+    listener_type   varchar(100)  NULL,                                 -- 鐩戝惉鍣ㄧ被鍨�
+    listener_path   varchar(400)  NULL,                                 -- 鐩戝惉鍣ㄨ矾寰�
+    handler_type    varchar(100)  NULL,                                 -- 澶勭悊鍣ㄧ被鍨�
+    handler_path    varchar(400)  NULL,                                 -- 澶勭悊鍣ㄨ矾寰�
+    form_custom     bpchar(1) NULL DEFAULT 'N':: character varying,         -- 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+    form_path       varchar(100)  NULL,                                 -- 瀹℃壒琛ㄥ崟璺緞
+    "version"       varchar(20)   NOT NULL,                             -- 鐗堟湰
+    create_time     timestamp     NULL,                                 -- 鍒涘缓鏃堕棿
+    update_time     timestamp     NULL,                                 -- 鏇存柊鏃堕棿
+    del_flag        bpchar(1) NULL DEFAULT '0':: character varying,            -- 鍒犻櫎鏍囧織
+    tenant_id       varchar(40)   NULL,                                 -- 绉熸埛id
+    CONSTRAINT flow_node_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_node IS '娴佺▼鑺傜偣琛�';
+
+COMMENT ON COLUMN flow_node.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_node.node_type IS '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_node.definition_id IS '娴佺▼瀹氫箟id';
+COMMENT ON COLUMN flow_node.node_code IS '娴佺▼鑺傜偣缂栫爜';
+COMMENT ON COLUMN flow_node.node_name IS '娴佺▼鑺傜偣鍚嶇О';
+COMMENT ON COLUMN flow_node.permission_flag IS '鏉冮檺鏍囪瘑锛堟潈闄愮被鍨�:鏉冮檺鏍囪瘑锛屽彲浠ュ涓紝鐢ㄩ�楀彿闅斿紑)';
+COMMENT ON COLUMN flow_node.node_ratio IS '娴佺▼绛剧讲姣斾緥鍊�';
+COMMENT ON COLUMN flow_node.coordinate IS '鍧愭爣';
+COMMENT ON COLUMN flow_node.skip_any_node IS '鏄惁鍙互閫�鍥炰换鎰忚妭鐐癸紙Y鏄� N鍚︼級鍗冲皢鍒犻櫎';
+COMMENT ON COLUMN flow_node.any_node_skip IS '浠绘剰缁撶偣璺宠浆';
+COMMENT ON COLUMN flow_node.listener_type IS '鐩戝惉鍣ㄧ被鍨�';
+COMMENT ON COLUMN flow_node.listener_path IS '鐩戝惉鍣ㄨ矾寰�';
+COMMENT ON COLUMN flow_node.handler_type IS '澶勭悊鍣ㄧ被鍨�';
+COMMENT ON COLUMN flow_node.handler_path IS '澶勭悊鍣ㄨ矾寰�';
+COMMENT ON COLUMN flow_node.form_custom IS '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級';
+COMMENT ON COLUMN flow_node.form_path IS '瀹℃壒琛ㄥ崟璺緞';
+COMMENT ON COLUMN flow_node."version" IS '鐗堟湰';
+COMMENT ON COLUMN flow_node.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_node.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_node.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_node.tenant_id IS '绉熸埛id';
 
 
--- 娴佺▼鍒嗙被绠$悊鐩稿叧鎸夐挳
-insert into sys_menu values ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1, now(), null, null, '');
-insert into sys_menu values ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add',   '#', 103, 1, now(), null, null, '');
-insert into sys_menu values ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:edit',  '#', 103, 1, now(), null, null, '');
-insert into sys_menu values ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:remove','#', 103, 1, now(), null, null, '');
-insert into sys_menu values ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:export','#', 103, 1, now(), null, null, '');
+CREATE TABLE flow_skip
+(
+    id             int8         NOT NULL,                    -- 涓婚敭id
+    definition_id  int8         NOT NULL,                    -- 娴佺▼瀹氫箟id
+    now_node_code  varchar(100) NOT NULL,                    -- 褰撳墠娴佺▼鑺傜偣鐨勭紪鐮�
+    now_node_type  int2         NULL,                        -- 褰撳墠鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    next_node_code varchar(100) NOT NULL,                    -- 涓嬩竴涓祦绋嬭妭鐐圭殑缂栫爜
+    next_node_type int2         NULL,                        -- 涓嬩竴涓妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    skip_name      varchar(100) NULL,                        -- 璺宠浆鍚嶇О
+    skip_type      varchar(40)  NULL,                        -- 璺宠浆绫诲瀷锛圥ASS瀹℃壒閫氳繃 REJECT閫�鍥烇級
+    skip_condition varchar(200) NULL,                        -- 璺宠浆鏉′欢
+    coordinate     varchar(100) NULL,                        -- 鍧愭爣
+    create_time    timestamp    NULL,                        -- 鍒涘缓鏃堕棿
+    update_time    timestamp    NULL,                        -- 鏇存柊鏃堕棿
+    del_flag       bpchar(1) NULL DEFAULT '0':: character varying, -- 鍒犻櫎鏍囧織
+    tenant_id      varchar(40)  NULL,                        -- 绉熸埛id
+    CONSTRAINT flow_skip_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_skip IS '鑺傜偣璺宠浆鍏宠仈琛�';
+
+COMMENT ON COLUMN flow_skip.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_skip.definition_id IS '娴佺▼瀹氫箟id';
+COMMENT ON COLUMN flow_skip.now_node_code IS '褰撳墠娴佺▼鑺傜偣鐨勭紪鐮�';
+COMMENT ON COLUMN flow_skip.now_node_type IS '褰撳墠鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_skip.next_node_code IS '涓嬩竴涓祦绋嬭妭鐐圭殑缂栫爜';
+COMMENT ON COLUMN flow_skip.next_node_type IS '涓嬩竴涓妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_skip.skip_name IS '璺宠浆鍚嶇О';
+COMMENT ON COLUMN flow_skip.skip_type IS '璺宠浆绫诲瀷锛圥ASS瀹℃壒閫氳繃 REJECT閫�鍥烇級';
+COMMENT ON COLUMN flow_skip.skip_condition IS '璺宠浆鏉′欢';
+COMMENT ON COLUMN flow_skip.coordinate IS '鍧愭爣';
+COMMENT ON COLUMN flow_skip.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_skip.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_skip.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_skip.tenant_id IS '绉熸埛id';
+
+CREATE TABLE flow_instance
+(
+    id              int8         NOT NULL,                                -- 涓婚敭id
+    definition_id   int8         NOT NULL,                                -- 瀵瑰簲flow_definition琛ㄧ殑id
+    business_id     varchar(40)  NOT NULL,                                -- 涓氬姟id
+    node_type       int2         NOT NULL,                                -- 鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    node_code       varchar(40)  NOT NULL,                                -- 娴佺▼鑺傜偣缂栫爜
+    node_name       varchar(100) NULL,                                    -- 娴佺▼鑺傜偣鍚嶇О
+    variable        text         NULL,                                    -- 浠诲姟鍙橀噺
+    flow_status     varchar(20)  NOT NULL,                                -- 娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�
+    activity_status int2         NOT NULL DEFAULT 1,                      -- 娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級
+    create_by       varchar(64)  NULL     DEFAULT '':: character varying, -- 鍒涘缓鑰�
+    create_time     timestamp    NULL,                                    -- 鍒涘缓鏃堕棿
+    update_time     timestamp    NULL,                                    -- 鏇存柊鏃堕棿
+    ext             varchar(500) NULL,                                    -- 鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤
+    del_flag        bpchar(1) NULL DEFAULT '0':: character varying,              -- 鍒犻櫎鏍囧織
+    tenant_id       varchar(40)  NULL,                                    -- 绉熸埛id
+    CONSTRAINT flow_instance_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_instance IS '娴佺▼瀹炰緥琛�';
+
+COMMENT ON COLUMN flow_instance.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_instance.definition_id IS '瀵瑰簲flow_definition琛ㄧ殑id';
+COMMENT ON COLUMN flow_instance.business_id IS '涓氬姟id';
+COMMENT ON COLUMN flow_instance.node_type IS '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_instance.node_code IS '娴佺▼鑺傜偣缂栫爜';
+COMMENT ON COLUMN flow_instance.node_name IS '娴佺▼鑺傜偣鍚嶇О';
+COMMENT ON COLUMN flow_instance.variable IS '浠诲姟鍙橀噺';
+COMMENT ON COLUMN flow_instance.flow_status IS '娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 3鑷姩閫氳繃 4缁堟 5浣滃簾 6鎾ら攢 7鍙栧洖  8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�';
+COMMENT ON COLUMN flow_instance.activity_status IS '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級';
+COMMENT ON COLUMN flow_instance.create_by IS '鍒涘缓鑰�';
+COMMENT ON COLUMN flow_instance.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_instance.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_instance.ext IS '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+COMMENT ON COLUMN flow_instance.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_instance.tenant_id IS '绉熸埛id';
+
+CREATE TABLE flow_task
+(
+    id            int8         NOT NULL,                        -- 涓婚敭id
+    definition_id int8         NOT NULL,                        -- 瀵瑰簲flow_definition琛ㄧ殑id
+    instance_id   int8         NOT NULL,                        -- 瀵瑰簲flow_instance琛ㄧ殑id
+    node_code     varchar(100) NOT NULL,                        -- 鑺傜偣缂栫爜
+    node_name     varchar(100) NULL,                            -- 鑺傜偣鍚嶇О
+    node_type     int2         NOT NULL,                        -- 鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    form_custom   bpchar(1) NULL DEFAULT 'N':: character varying, -- 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+    form_path     varchar(100) NULL,                            -- 瀹℃壒琛ㄥ崟璺緞
+    create_time   timestamp    NULL,                            -- 鍒涘缓鏃堕棿
+    update_time   timestamp    NULL,                            -- 鏇存柊鏃堕棿
+    del_flag      bpchar(1) NULL DEFAULT '0':: character varying,    -- 鍒犻櫎鏍囧織
+    tenant_id     varchar(40)  NULL,                            -- 绉熸埛id
+    CONSTRAINT flow_task_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_task IS '寰呭姙浠诲姟琛�';
+
+COMMENT ON COLUMN flow_task.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_task.definition_id IS '瀵瑰簲flow_definition琛ㄧ殑id';
+COMMENT ON COLUMN flow_task.instance_id IS '瀵瑰簲flow_instance琛ㄧ殑id';
+COMMENT ON COLUMN flow_task.node_code IS '鑺傜偣缂栫爜';
+COMMENT ON COLUMN flow_task.node_name IS '鑺傜偣鍚嶇О';
+COMMENT ON COLUMN flow_task.node_type IS '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_task.form_custom IS '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級';
+COMMENT ON COLUMN flow_task.form_path IS '瀹℃壒琛ㄥ崟璺緞';
+COMMENT ON COLUMN flow_task.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_task.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_task.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_task.tenant_id IS '绉熸埛id';
+
+CREATE TABLE flow_his_task
+(
+    id               int8         NOT NULL,                     -- 涓婚敭id
+    definition_id    int8         NOT NULL,                     -- 瀵瑰簲flow_definition琛ㄧ殑id
+    instance_id      int8         NOT NULL,                     -- 瀵瑰簲flow_instance琛ㄧ殑id
+    task_id          int8         NOT NULL,                     -- 瀵瑰簲flow_task琛ㄧ殑id
+    node_code        varchar(100) NULL,                         -- 寮�濮嬭妭鐐圭紪鐮�
+    node_name        varchar(100) NULL,                         -- 寮�濮嬭妭鐐瑰悕绉�
+    node_type        int2         NULL,                         -- 寮�濮嬭妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�
+    target_node_code varchar(100) NULL,                         -- 鐩爣鑺傜偣缂栫爜
+    target_node_name varchar(100) NULL,                         -- 缁撴潫鑺傜偣鍚嶇О
+    approver         varchar(40)  NULL,                         -- 瀹℃壒鑰�
+    cooperate_type   int2         NOT NULL DEFAULT 0,           -- 鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)
+    collaborator     varchar(40)  NULL,                         -- 鍗忎綔浜�(鍙湁杞姙銆佷細绛俱�佺エ绛俱�佸娲�)
+    skip_type        varchar(10)  NULL,                         -- 娴佽浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級
+    flow_status      varchar(20)  NOT NULL,                     -- 娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�
+    form_custom      bpchar(1) NULL DEFAULT 'N':: character varying, -- 瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級
+    form_path        varchar(100) NULL,                         -- 瀹℃壒琛ㄥ崟璺緞
+    ext              varchar(500) NULL,                         -- 鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤
+    message          varchar(500) NULL,                         -- 瀹℃壒鎰忚
+    create_time      timestamp    NULL,                         -- 鍒涘缓鏃堕棿
+    update_time      timestamp    NULL,                         -- 鏇存柊鏃堕棿
+    del_flag         bpchar(1) NULL DEFAULT '0':: character varying,    -- 鍒犻櫎鏍囧織
+    tenant_id        varchar(40)  NULL,                         -- 绉熸埛id
+    CONSTRAINT flow_his_task_pkey PRIMARY KEY (id)
+);
+COMMENT ON TABLE flow_his_task IS '鍘嗗彶浠诲姟璁板綍琛�';
+
+COMMENT ON COLUMN flow_his_task.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_his_task.definition_id IS '瀵瑰簲flow_definition琛ㄧ殑id';
+COMMENT ON COLUMN flow_his_task.instance_id IS '瀵瑰簲flow_instance琛ㄧ殑id';
+COMMENT ON COLUMN flow_his_task.task_id IS '瀵瑰簲flow_task琛ㄧ殑id';
+COMMENT ON COLUMN flow_his_task.node_code IS '寮�濮嬭妭鐐圭紪鐮�';
+COMMENT ON COLUMN flow_his_task.node_name IS '寮�濮嬭妭鐐瑰悕绉�';
+COMMENT ON COLUMN flow_his_task.node_type IS '寮�濮嬭妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�';
+COMMENT ON COLUMN flow_his_task.target_node_code IS '鐩爣鑺傜偣缂栫爜';
+COMMENT ON COLUMN flow_his_task.target_node_name IS '缁撴潫鑺傜偣鍚嶇О';
+COMMENT ON COLUMN flow_his_task.approver IS '瀹℃壒鑰�';
+COMMENT ON COLUMN flow_his_task.cooperate_type IS '鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)';
+COMMENT ON COLUMN flow_his_task.collaborator IS '鍗忎綔浜�';
+COMMENT ON COLUMN flow_his_task.skip_type IS '娴佽浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級';
+COMMENT ON COLUMN flow_his_task.flow_status IS '娴佺▼鐘舵�侊紙1瀹℃壒涓� 2 瀹℃壒閫氳繃 9宸查��鍥� 10澶辨晥锛�';
+COMMENT ON COLUMN flow_his_task.form_custom IS '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級';
+COMMENT ON COLUMN flow_his_task.form_path IS '瀹℃壒琛ㄥ崟璺緞';
+COMMENT ON COLUMN flow_his_task.message IS '瀹℃壒鎰忚';
+COMMENT ON COLUMN flow_his_task.ext IS '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤';
+COMMENT ON COLUMN flow_his_task.create_time IS '浠诲姟寮�濮嬫椂闂�';
+COMMENT ON COLUMN flow_his_task.update_time IS '瀹℃壒瀹屾垚鏃堕棿';
+COMMENT ON COLUMN flow_his_task.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_his_task.tenant_id IS '绉熸埛id';
+
+CREATE TABLE flow_user
+(
+    id           int8        NOT NULL,                       -- 涓婚敭id
+    "type"       bpchar(1) NOT NULL,                         -- 浜哄憳绫诲瀷锛�1寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺 2寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺 3娴佺▼瀹炰緥鐨勬妱閫佷汉鏉冮檺 4寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺锛�
+    processed_by varchar(80) NULL,                           -- 鏉冮檺浜�
+    associated   int8        NOT NULL,                       -- 浠诲姟琛╥d
+    create_time  timestamp   NULL,                           -- 鍒涘缓鏃堕棿
+    create_by    varchar(80) NULL,                           -- 鍒涘缓浜�
+    update_time  timestamp   NULL,                           -- 鏇存柊鏃堕棿
+    del_flag     bpchar(1) NULL DEFAULT '0':: character varying, -- 鍒犻櫎鏍囧織
+    tenant_id    varchar(40) NULL,                           -- 绉熸埛id
+    CONSTRAINT flow_user_pk PRIMARY KEY (id)
+);
+CREATE INDEX user_processed_type ON flow_user USING btree (processed_by, type);
+COMMENT ON TABLE flow_user IS '娴佺▼鐢ㄦ埛琛�';
+
+COMMENT ON COLUMN flow_user.id IS '涓婚敭id';
+COMMENT ON COLUMN flow_user."type" IS '浜哄憳绫诲瀷锛�1寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺 2寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺 3寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺锛�';
+COMMENT ON COLUMN flow_user.processed_by IS '鏉冮檺浜�';
+COMMENT ON COLUMN flow_user.associated IS '浠诲姟琛╥d';
+COMMENT ON COLUMN flow_user.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_user.create_by IS '鍒涘缓浜�';
+COMMENT ON COLUMN flow_user.update_time IS '鏇存柊鏃堕棿';
+COMMENT ON COLUMN flow_user.del_flag IS '鍒犻櫎鏍囧織';
+COMMENT ON COLUMN flow_user.tenant_id IS '绉熸埛id';
+
+-- ----------------------------
+-- 娴佺▼鍒嗙被琛�
+-- ----------------------------
+CREATE TABLE flow_category
+(
+    category_id   int8         NOT NULL,
+    tenant_id     VARCHAR(20)  DEFAULT '000000'::varchar,
+    parent_id     int8         DEFAULT 0,
+    ancestors     VARCHAR(500) DEFAULT ''::varchar,
+    category_name VARCHAR(30)  NOT NULL,
+    order_num     INT          DEFAULT 0,
+    del_flag      CHAR         DEFAULT '0'::bpchar,
+    create_dept   int8,
+    create_by     int8,
+    create_time   TIMESTAMP,
+    update_by     int8,
+    update_time   TIMESTAMP,
+    PRIMARY KEY (category_id)
+);
+
+COMMENT ON TABLE flow_category IS '娴佺▼鍒嗙被';
+COMMENT ON COLUMN flow_category.category_id IS '娴佺▼鍒嗙被ID';
+COMMENT ON COLUMN flow_category.tenant_id IS '绉熸埛缂栧彿';
+COMMENT ON COLUMN flow_category.parent_id IS '鐖舵祦绋嬪垎绫籭d';
+COMMENT ON COLUMN flow_category.ancestors IS '绁栫骇鍒楄〃';
+COMMENT ON COLUMN flow_category.category_name IS '娴佺▼鍒嗙被鍚嶇О';
+COMMENT ON COLUMN flow_category.order_num IS '鏄剧ず椤哄簭';
+COMMENT ON COLUMN flow_category.del_flag IS '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�';
+COMMENT ON COLUMN flow_category.create_dept IS '鍒涘缓閮ㄩ棬';
+COMMENT ON COLUMN flow_category.create_by IS '鍒涘缓鑰�';
+COMMENT ON COLUMN flow_category.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN flow_category.update_by IS '鏇存柊鑰�';
+COMMENT ON COLUMN flow_category.update_time IS '鏇存柊鏃堕棿';
+
+INSERT INTO flow_category VALUES (100, '000000', 0, '0', 'OA瀹℃壒', 0, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (101, '000000', 100, '0,100', '鍋囧嫟绠$悊', 0, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (102, '000000', 100, '0,100', '浜轰簨绠$悊', 0, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (103, '000000', 101, '0,100,101', '璇峰亣', 0, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (104, '000000', 101, '0,100,101', '鍑哄樊', 1, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (105, '000000', 101, '0,100,101', '鍔犵彮', 2, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (106, '000000', 101, '0,100,101', '鎹㈢彮', 3, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (107, '000000', 101, '0,100,101', '澶栧嚭', 4, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (108, '000000', 102, '0,100,102', '杞', 1, '0', 103, 1, now(), NULL, NULL);
+INSERT INTO flow_category VALUES (109, '000000', 102, '0,100,102', '绂昏亴', 2, '0', 103, 1, now(), NULL, NULL);
+
+-- ----------------------------
 -- 璇峰亣鍗曚俊鎭�
-create table test_leave
+-- ----------------------------
+CREATE TABLE test_leave
 (
-    id          bigint not null
-        constraint test_leave_pk
-            primary key,
-    leave_type  varchar(255),
-    start_date  timestamp,
-    end_date    timestamp,
-    leave_days  bigint,
-    remark      varchar(255),
-    status      varchar(255),
-    create_dept bigint,
-    create_by   bigint,
-    create_time timestamp,
-    update_by   bigint,
-    update_time timestamp,
-    tenant_id   varchar(20)
+    id          int8         NOT NULL,
+    tenant_id   VARCHAR(20)  DEFAULT '000000'::varchar,
+    leave_type  VARCHAR(255) NOT NULL,
+    start_date  TIMESTAMP    NOT NULL,
+    end_date    TIMESTAMP    NOT NULL,
+    leave_days  int2          NOT NULL,
+    remark      VARCHAR(255),
+    status      VARCHAR(255),
+    create_dept int8,
+    create_by   int8,
+    create_time TIMESTAMP,
+    update_by   int8,
+    update_time TIMESTAMP,
+    PRIMARY KEY (id)
 );
 
-comment on table test_leave is '璇峰亣鐢宠琛�';
-comment on column test_leave.id is '涓婚敭';
-comment on column test_leave.leave_type is '璇峰亣绫诲瀷';
-comment on column test_leave.start_date is '寮�濮嬫椂闂�';
-comment on column test_leave.end_date is '缁撴潫鏃堕棿';
-comment on column test_leave.remark is '璇峰亣鍘熷洜';
-comment on column test_leave.status is '鐘舵��';
-comment on column test_leave.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column test_leave.create_by is '鍒涘缓鑰�';
-comment on column test_leave.create_time is '鍒涘缓鏃堕棿';
-comment on column test_leave.update_by is '鏇存柊鑰�';
-comment on column test_leave.update_time is '鏇存柊鏃堕棿';
-comment on column test_leave.tenant_id is '绉熸埛缂栫爜';
+COMMENT ON TABLE test_leave IS '璇峰亣鐢宠琛�';
+COMMENT ON COLUMN test_leave.id IS 'id';
+COMMENT ON COLUMN test_leave.tenant_id IS '绉熸埛缂栧彿';
+COMMENT ON COLUMN test_leave.leave_type IS '璇峰亣绫诲瀷';
+COMMENT ON COLUMN test_leave.start_date IS '寮�濮嬫椂闂�';
+COMMENT ON COLUMN test_leave.end_date IS '缁撴潫鏃堕棿';
+COMMENT ON COLUMN test_leave.leave_days IS '璇峰亣澶╂暟';
+COMMENT ON COLUMN test_leave.remark IS '璇峰亣鍘熷洜';
+COMMENT ON COLUMN test_leave.status IS '鐘舵��';
+COMMENT ON COLUMN test_leave.create_dept IS '鍒涘缓閮ㄩ棬';
+COMMENT ON COLUMN test_leave.create_by IS '鍒涘缓鑰�';
+COMMENT ON COLUMN test_leave.create_time IS '鍒涘缓鏃堕棿';
+COMMENT ON COLUMN test_leave.update_by IS '鏇存柊鑰�';
+COMMENT ON COLUMN test_leave.update_time IS '鏇存柊鏃堕棿';
 
-alter table test_leave
-    owner to postgres;
+INSERT INTO sys_menu VALUES ('11616', '宸ヤ綔娴�', '0', '6', 'workflow', '', '', '1', '0', 'M', '0', '0', '', 'workflow', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11618', '鎴戠殑浠诲姟', '0', '7', 'task', '', '', '1', '0', 'M', '0', '0', '', 'my-task', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting', 'workflow/task/taskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish', 'workflow/task/taskFinish', '', '1', '1', 'C', '0', '0', '', 'finish', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList', 'workflow/task/taskCopyList', '', '1', '1', 'C', '0', '0', '', 'my-copy', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '', 'process-definition', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance', 'workflow/processInstance/index', '', '1', '1', 'C', '0', '0', '', 'tree-table', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11622', '娴佺▼鍒嗙被', '11616', '1', 'category', 'workflow/category/index', '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:query', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:add', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:edit', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:remove', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:category:export', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11638', '璇峰亣鐢宠', '5', '1', 'leave', 'workflow/leave/index', '', '1', '0', 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, now(), NULL, NULL, '璇峰亣鐢宠鑿滃崟');
+INSERT INTO sys_menu VALUES ('11639', '璇峰亣鐢宠鏌ヨ', '11638', '1', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11640', '璇峰亣鐢宠鏂板', '11638', '2', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11641', '璇峰亣鐢宠淇敼', '11638', '3', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11642', '璇峰亣鐢宠鍒犻櫎', '11638', '4', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, now(), NULL, NULL, '');
+INSERT INTO sys_menu VALUES ('11643', '璇峰亣鐢宠瀵煎嚭', '11638', '5', '#', '', '', '1', '0', 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, now(), NULL, NULL, '');
 
--- 娴佺▼鍒嗙被淇℃伅琛�
-create table wf_category
-(
-    id            bigint not null
-        constraint wf_category_pk
-            primary key,
-    category_name varchar(255),
-    category_code varchar(255),
-    parent_id     bigint,
-    sort_num      bigint,
-    tenant_id     varchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   timestamp,
-    update_by     bigint,
-    update_time   timestamp
-);
+INSERT INTO sys_dict_type VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, now(), NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
+INSERT INTO sys_dict_type VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, now(), NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
+INSERT INTO sys_dict_type VALUES (15, '000000', '浠诲姟鐘舵��', 'wf_task_status', 103, 1, now(), NULL, NULL, '浠诲姟鐘舵��');
+INSERT INTO sys_dict_data VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸叉挙閿�');
+INSERT INTO sys_dict_data VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, now(), NULL, NULL, '鑽夌');
+INSERT INTO sys_dict_data VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, now(), NULL, NULL, '宸插畬鎴�');
+INSERT INTO sys_dict_data VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸蹭綔搴�');
+INSERT INTO sys_dict_data VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸查��鍥�');
+INSERT INTO sys_dict_data VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸茬粓姝�');
+INSERT INTO sys_dict_data VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, now(), NULL, NULL, '鑷畾涔夎〃鍗�');
+INSERT INTO sys_dict_data VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '鍔ㄦ�佽〃鍗�');
+INSERT INTO sys_dict_data VALUES (48, '000000', 1, '鎾ら攢', 'cancel', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '鎾ら攢');
+INSERT INTO sys_dict_data VALUES (49, '000000', 2, '閫氳繃', 'pass', 'wf_task_status', '', 'success', 'N', 103, 1, now(), NULL, NULL, '閫氳繃');
+INSERT INTO sys_dict_data VALUES (50, '000000', 3, '寰呭鏍�', 'waiting', 'wf_task_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (51, '000000', 4, '浣滃簾', 'invalid', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '浣滃簾');
+INSERT INTO sys_dict_data VALUES (52, '000000', 5, '閫�鍥�', 'back', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '閫�鍥�');
+INSERT INTO sys_dict_data VALUES (53, '000000', 6, '缁堟', 'termination', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '缁堟');
+INSERT INTO sys_dict_data VALUES (54, '000000', 7, '杞姙', 'transfer', 'wf_task_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '杞姙');
+INSERT INTO sys_dict_data VALUES (55, '000000', 8, '濮旀墭', 'depute', 'wf_task_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '濮旀墭');
+INSERT INTO sys_dict_data VALUES (56, '000000', 9, '鎶勯��', 'copy', 'wf_task_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '鎶勯��');
+INSERT INTO sys_dict_data VALUES (57, '000000', 10, '鍔犵', 'sign', 'wf_task_status', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '鍔犵');
+INSERT INTO sys_dict_data VALUES (58, '000000', 11, '鍑忕', 'sign_off', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '鍑忕');
+INSERT INTO sys_dict_data VALUES (59, '000000', 11, '瓒呮椂', 'timeout', 'wf_task_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '瓒呮椂');
 
-comment on table wf_category is '娴佺▼鍒嗙被';
-comment on column wf_category.id is '涓婚敭';
-comment on column wf_category.category_name is '鍒嗙被鍚嶇О';
-comment on column wf_category.category_code is '鍒嗙被缂栫爜';
-comment on column wf_category.parent_id is '鐖剁骇id';
-comment on column wf_category.sort_num is '鎺掑簭';
-comment on column wf_category.tenant_id is '绉熸埛id';
-comment on column wf_category.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column wf_category.create_by is '鍒涘缓鑰�';
-comment on column wf_category.create_time is '鍒涘缓鏃堕棿';
-comment on column wf_category.update_by is '淇敼鑰�';
-comment on column wf_category.update_time is '淇敼鏃堕棿';
-
-alter table wf_category
-    owner to postgres;
-
-create unique index uni_category_code
-    on wf_category (category_code);
-
-INSERT INTO wf_category values (1, 'OA', 'OA', 0, 0, '000000', 103, 1, now(), 1, now());
-
-create table wf_task_back_node
-(
-    id            bigint not null
-        constraint pk_wf_task_back_node
-        primary key,
-    node_id       varchar(255) not null,
-    node_name     varchar(255) not null,
-    order_no      bigint not null,
-    instance_id   varchar(255) not null,
-    task_type     varchar(255) not null,
-    assignee      varchar(2000) not null,
-    tenant_id     varchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   timestamp,
-    update_by     bigint,
-    update_time   timestamp
-);
-
-comment on table wf_task_back_node is '鑺傜偣瀹℃壒璁板綍';
-comment on column wf_task_back_node.id is '涓婚敭';
-comment on column wf_task_back_node.node_id is '鑺傜偣id';
-comment on column wf_task_back_node.node_name is '鑺傜偣鍚嶇О';
-comment on column wf_task_back_node.order_no is '鎺掑簭';
-comment on column wf_task_back_node.instance_id is '娴佺▼瀹炰緥id';
-comment on column wf_task_back_node.task_type is '鑺傜偣绫诲瀷';
-comment on column wf_task_back_node.assignee is '瀹℃壒浜�';
-comment on column wf_task_back_node.tenant_id is '绉熸埛id';
-comment on column wf_task_back_node.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column wf_task_back_node.create_by is '鍒涘缓鑰�';
-comment on column wf_task_back_node.create_time is '鍒涘缓鏃堕棿';
-comment on column wf_task_back_node.update_by is '淇敼鑰�';
-comment on column wf_task_back_node.update_time is '淇敼鏃堕棿';
-
-alter table wf_task_back_node
-    owner to postgres;
-
-create table wf_definition_config
-(
-    id            bigint not null
-        constraint pk_wf_definition_config
-        primary key,
-    table_name    varchar(255) not null,
-    definition_id varchar(255) not null,
-    process_key   varchar(255) not null,
-    version       bigint       not null,
-    tenant_id     varchar(20),
-    remark        varchar(500),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   timestamp,
-    update_by     bigint,
-    update_time   timestamp
-);
-
-comment on table wf_definition_config is '娴佺▼瀹氫箟閰嶇疆';
-comment on column wf_definition_config.id is '涓婚敭';
-comment on column wf_definition_config.table_name is '琛ㄥ悕';
-comment on column wf_definition_config.definition_id is '娴佺▼瀹氫箟ID';
-comment on column wf_definition_config.process_key is '娴佺▼KEY';
-comment on column wf_definition_config.version is '娴佺▼鐗堟湰';
-comment on column wf_definition_config.tenant_id is '绉熸埛id';
-comment on column wf_definition_config.remark is '澶囨敞';
-comment on column wf_definition_config.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column wf_definition_config.create_by is '鍒涘缓鑰�';
-comment on column wf_definition_config.create_time is '鍒涘缓鏃堕棿';
-comment on column wf_definition_config.update_by is '淇敼鑰�';
-comment on column wf_definition_config.update_time is '淇敼鏃堕棿';
-
-alter table wf_definition_config
-    owner to postgres;
-create unique index uni_definition_id
-    on wf_definition_config (definition_id);
-
-create table wf_form_manage
-(
-    id            bigint not null
-        constraint pk_wf_form_manage
-        primary key,
-    form_name     varchar(255) not null,
-    form_type     varchar(255) not null,
-    router        varchar(255) not null,
-    remark        varchar(500),
-    tenant_id     varchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   timestamp,
-    update_by     bigint,
-    update_time   timestamp
-);
-
-comment on table wf_form_manage is '琛ㄥ崟绠$悊';
-comment on column wf_form_manage.id is '涓婚敭';
-comment on column wf_form_manage.form_name is '琛ㄥ崟鍚嶇О';
-comment on column wf_form_manage.form_type is '琛ㄥ崟绫诲瀷';
-comment on column wf_form_manage.router is '璺敱鍦板潃/琛ㄥ崟ID';
-comment on column wf_form_manage.remark is '澶囨敞';
-comment on column wf_form_manage.tenant_id is '绉熸埛id';
-comment on column wf_form_manage.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column wf_form_manage.create_by is '鍒涘缓鑰�';
-comment on column wf_form_manage.create_time is '鍒涘缓鏃堕棿';
-comment on column wf_form_manage.update_by is '淇敼鑰�';
-comment on column wf_form_manage.update_time is '淇敼鏃堕棿';
-
-insert into wf_form_manage(id, form_name, form_type, router, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time) VALUES (1, '璇峰亣鐢宠', 'static', '/workflow/leaveEdit/index', NULL, '000000', 103, 1, now(), 1, now());
-
-create table wf_node_config
-(
-    id               bigint not null
-        constraint pk_wf_node_config
-            primary key,
-    form_id          bigint,
-    form_type        varchar(255),
-    node_name        varchar(255) not null,
-    node_id          varchar(255) not null,
-    definition_id    varchar(255) not null,
-    apply_user_task  char(1) default '0',
-    tenant_id        varchar(20),
-    create_dept      bigint,
-    create_by        bigint,
-    create_time      timestamp,
-    update_by        bigint,
-    update_time      timestamp
-);
-
-comment on table wf_node_config is '鑺傜偣閰嶇疆';
-comment on column wf_node_config.id is '涓婚敭';
-comment on column wf_node_config.form_id is '琛ㄥ崟id';
-comment on column wf_node_config.form_type is '琛ㄥ崟绫诲瀷';
-comment on column wf_node_config.node_id is '鑺傜偣id';
-comment on column wf_node_config.node_name is '鑺傜偣鍚嶇О';
-comment on column wf_node_config.definition_id is '娴佺▼瀹氫箟id';
-comment on column wf_node_config.apply_user_task is '鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級';
-comment on column wf_node_config.tenant_id is '绉熸埛id';
-comment on column wf_node_config.create_dept is '鍒涘缓閮ㄩ棬';
-comment on column wf_node_config.create_by is '鍒涘缓鑰�';
-comment on column wf_node_config.create_time is '鍒涘缓鏃堕棿';
-comment on column wf_node_config.update_by is '淇敼鑰�';
-comment on column wf_node_config.update_time is '淇敼鏃堕棿';
-
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11638, '璇峰亣鐢宠', 5, 1, 'leave', 'workflow/leave/index', 1, 0, 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, now(), NULL, NULL, '璇峰亣鐢宠鑿滃崟');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11639, '璇峰亣鐢宠鏌ヨ', 11638, 1, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, now(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11640, '璇峰亣鐢宠鏂板', 11638, 2, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, now(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11641, '璇峰亣鐢宠淇敼', 11638, 3, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, now(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11642, '璇峰亣鐢宠鍒犻櫎', 11638, 4, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, now(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11643, '璇峰亣鐢宠瀵煎嚭', 11638, 5, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, now(), NULL, NULL, '');
-
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, now(), NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, now(), NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
-
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸叉挙閿�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, now(), NULL, NULL, '鑽夌');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1,now(), NULL, NULL, '寰呭鏍�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, now(), NULL, NULL, '宸插畬鎴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸蹭綔搴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, now(), NULL, NULL, '宸查��鍥�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1,now(), NULL, NULL, '宸茬粓姝�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, now(), NULL, NULL, '鑷畾涔夎〃鍗�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, now(), NULL, NULL, '鍔ㄦ�佽〃鍗�');
-
--- 琛ㄥ崟绠$悊 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11628, '琛ㄥ崟绠$悊', '11616', '5', 'formManage', 'workflow/formManage/index', 1, 0, 'C', '0', '0', 'workflow:formManage:list', 'tree-table', 103, 1, now(), null, null, '琛ㄥ崟绠$悊鑿滃崟');
-
--- 琛ㄥ崟绠$悊鎸夐挳 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11644, '琛ㄥ崟绠$悊鏌ヨ', 11628, '1',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:query',        '', 103, 1, now(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11645, '琛ㄥ崟绠$悊鏂板', 11628, '2',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:add',          '', 103, 1, now(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11646, '琛ㄥ崟绠$悊淇敼', 11628, '3',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:edit',         '', 103, 1, now(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11647, '琛ㄥ崟绠$悊鍒犻櫎', 11628, '4',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:remove',       '', 103, 1, now(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11648, '琛ㄥ崟绠$悊瀵煎嚭', 11628, '5',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:export',       'tree-table', 103, 1, now(), null, null, '');
diff --git a/script/sql/ry_workflow.sql b/script/sql/ry_workflow.sql
index e8dc798..7b82ef6 100644
--- a/script/sql/ry_workflow.sql
+++ b/script/sql/ry_workflow.sql
@@ -1,176 +1,251 @@
-insert into sys_menu values('11616', '宸ヤ綔娴�'  , '0',    '6', 'workflow',          '',                                 '', '1', '0', 'M', '0', '0', '',                       'workflow', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11617', '妯″瀷绠$悊', '11616', '2', 'model',             'workflow/model/index',             '', '1', '1', 'C', '0', '0', 'workflow:model:list',    'model', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11618', '鎴戠殑浠诲姟', '0', '7', 'task',              '',                                 '', '1', '0', 'M', '0', '0', '',                       'my-task', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting',       'workflow/task/taskWaiting',              '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish',       'workflow/task/taskFinish',              '', '1', '1', 'C', '0', '0', '',                       'finish', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList',       'workflow/task/taskCopyList',              '', '1', '1', 'C', '0', '0', '',                       'my-copy', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '',                       'process-definition', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance',   'workflow/processInstance/index',   '', '1', '1', 'C', '0', '0', '',                       'tree-table', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11622', '娴佺▼鍒嗙被', '11616', '1', 'category',          'workflow/category/index',          '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument',        'workflow/task/myDocument',         '', '1', '1', 'C', '0', '0', '',                       'guide', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor',           '',                                 '', '1', '0', 'M', '0', '0', '',                       'monitor', 103, 1, sysdate(), NULL, NULL, '');
-insert into sys_menu values('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting',    'workflow/task/allTaskWaiting',     '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, sysdate(), NULL, NULL, '');
+-- ----------------------------
+-- 0銆亀arm-flow-all.sql锛屽湴鍧�锛歨ttps://gitee.com/dromara/warm-flow/blob/master/sql/mysql/warm-flow-all.sql
+-- ----------------------------
+CREATE TABLE `flow_definition`
+(
+    `id`          bigint unsigned NOT NULL COMMENT '涓婚敭id',
+    `flow_code`   varchar(40)  NOT NULL COMMENT '娴佺▼缂栫爜',
+    `flow_name`   varchar(100) NOT NULL COMMENT '娴佺▼鍚嶇О',
+    `category`   varchar(100) DEFAULT NULL COMMENT '娴佺▼绫诲埆',
+    `version`     varchar(20)  NOT NULL COMMENT '娴佺▼鐗堟湰',
+    `is_publish`  tinyint(1) NOT NULL DEFAULT '0' COMMENT '鏄惁鍙戝竷锛�0鏈彂甯� 1宸插彂甯� 9澶辨晥锛�',
+    `form_custom` char(1)      DEFAULT 'N' COMMENT '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+    `form_path`   varchar(100) DEFAULT NULL COMMENT '瀹℃壒琛ㄥ崟璺緞',
+    `activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級',
+    `listener_type`   varchar(100) DEFAULT NULL COMMENT '鐩戝惉鍣ㄧ被鍨�',
+    `listener_path`   varchar(400) DEFAULT NULL COMMENT '鐩戝惉鍣ㄨ矾寰�',
+    `ext`         varchar(500) DEFAULT NULL COMMENT '涓氬姟璇︽儏 瀛樹笟鍔¤〃瀵硅薄json瀛楃涓�',
+    `create_time` datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_time` datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `del_flag`    char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id` varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB  COMMENT='娴佺▼瀹氫箟琛�';
+
+CREATE TABLE `flow_node`
+(
+    `id`              bigint unsigned NOT NULL COMMENT '涓婚敭id',
+    `node_type`       tinyint(1) NOT NULL COMMENT '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `definition_id`   bigint       NOT NULL COMMENT '娴佺▼瀹氫箟id',
+    `node_code`       varchar(100) NOT NULL COMMENT '娴佺▼鑺傜偣缂栫爜',
+    `node_name`       varchar(100) DEFAULT NULL COMMENT '娴佺▼鑺傜偣鍚嶇О',
+    `permission_flag` varchar(200) DEFAULT NULL COMMENT '鏉冮檺鏍囪瘑锛堟潈闄愮被鍨�:鏉冮檺鏍囪瘑锛屽彲浠ュ涓紝鐢ㄩ�楀彿闅斿紑)',
+    `node_ratio`      DECIMAL(6,3) DEFAULT NULL COMMENT '娴佺▼绛剧讲姣斾緥鍊�',
+    `coordinate`      varchar(100) DEFAULT NULL COMMENT '鍧愭爣',
+    `skip_any_node`   varchar(100) DEFAULT 'N' COMMENT '鏄惁鍙互閫�鍥炰换鎰忚妭鐐癸紙Y鏄� N鍚︼級鍗冲皢鍒犻櫎',
+    `any_node_skip`   varchar(100) DEFAULT NULL COMMENT '浠绘剰缁撶偣璺宠浆',
+    `listener_type`   varchar(100) DEFAULT NULL COMMENT '鐩戝惉鍣ㄧ被鍨�',
+    `listener_path`   varchar(400) DEFAULT NULL COMMENT '鐩戝惉鍣ㄨ矾寰�',
+    `handler_type`    varchar(100)  DEFAULT NULL COMMENT '澶勭悊鍣ㄧ被鍨�',
+    `handler_path`    varchar(400)  DEFAULT NULL COMMENT '澶勭悊鍣ㄨ矾寰�',
+    `form_custom`     char(1)      DEFAULT 'N' COMMENT '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+    `form_path`       varchar(100) DEFAULT NULL COMMENT '瀹℃壒琛ㄥ崟璺緞',
+    `version`         varchar(20)  NOT NULL COMMENT '鐗堟湰',
+    `create_time`     datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_time`     datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `del_flag`        char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`       varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB  COMMENT='娴佺▼鑺傜偣琛�';
+
+CREATE TABLE `flow_skip`
+(
+    `id`             bigint unsigned NOT NULL COMMENT '涓婚敭id',
+    `definition_id`  bigint       NOT NULL COMMENT '娴佺▼瀹氫箟id',
+    `now_node_code`  varchar(100) NOT NULL COMMENT '褰撳墠娴佺▼鑺傜偣鐨勭紪鐮�',
+    `now_node_type`  tinyint(1) DEFAULT NULL COMMENT '褰撳墠鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `next_node_code` varchar(100) NOT NULL COMMENT '涓嬩竴涓祦绋嬭妭鐐圭殑缂栫爜',
+    `next_node_type` tinyint(1) DEFAULT NULL COMMENT '涓嬩竴涓妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `skip_name`      varchar(100) DEFAULT NULL COMMENT '璺宠浆鍚嶇О',
+    `skip_type`      varchar(40)  DEFAULT NULL COMMENT '璺宠浆绫诲瀷锛圥ASS瀹℃壒閫氳繃 REJECT閫�鍥烇級',
+    `skip_condition` varchar(200) DEFAULT NULL COMMENT '璺宠浆鏉′欢',
+    `coordinate`     varchar(100) DEFAULT NULL COMMENT '鍧愭爣',
+    `create_time`    datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_time`    datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `del_flag`    char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`     varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB  COMMENT='鑺傜偣璺宠浆鍏宠仈琛�';
+
+CREATE TABLE `flow_instance`
+(
+    `id`            bigint      NOT NULL COMMENT '涓婚敭id',
+    `definition_id` bigint      NOT NULL COMMENT '瀵瑰簲flow_definition琛ㄧ殑id',
+    `business_id`   varchar(40) NOT NULL COMMENT '涓氬姟id',
+    `node_type`     tinyint(1) NOT NULL COMMENT '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `node_code`     varchar(40) NOT NULL COMMENT '娴佺▼鑺傜偣缂栫爜',
+    `node_name`     varchar(100) DEFAULT NULL COMMENT '娴佺▼鑺傜偣鍚嶇О',
+    `variable`      text COMMENT '浠诲姟鍙橀噺',
+    `flow_status`   varchar(20) NOT NULL COMMENT '娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 3鑷姩閫氳繃 4缁堟 5浣滃簾 6鎾ら攢 7鍙栧洖  8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�',
+    `activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級',
+    `create_by`     varchar(64)  DEFAULT '' COMMENT '鍒涘缓鑰�',
+    `create_time`   datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_time`   datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `ext`           varchar(500) DEFAULT NULL COMMENT '鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤',
+    `del_flag`    char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`     varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB  COMMENT='娴佺▼瀹炰緥琛�';
+
+CREATE TABLE `flow_task`
+(
+    `id`              bigint       NOT NULL COMMENT '涓婚敭id',
+    `definition_id`   bigint       NOT NULL COMMENT '瀵瑰簲flow_definition琛ㄧ殑id',
+    `instance_id`     bigint       NOT NULL COMMENT '瀵瑰簲flow_instance琛ㄧ殑id',
+    `node_code`       varchar(100) NOT NULL COMMENT '鑺傜偣缂栫爜',
+    `node_name`       varchar(100) DEFAULT NULL COMMENT '鑺傜偣鍚嶇О',
+    `node_type`       tinyint(1) NOT NULL COMMENT '鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `form_custom`     char(1)      DEFAULT 'N' COMMENT '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+    `form_path`       varchar(100) DEFAULT NULL COMMENT '瀹℃壒琛ㄥ崟璺緞',
+    `create_time`     datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `update_time`     datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `del_flag`        char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`       varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB  COMMENT='寰呭姙浠诲姟琛�';
+
+CREATE TABLE `flow_his_task`
+(
+    `id`               bigint(20) unsigned NOT NULL COMMENT '涓婚敭id',
+    `definition_id`    bigint(20)          NOT NULL COMMENT '瀵瑰簲flow_definition琛ㄧ殑id',
+    `instance_id`      bigint(20)          NOT NULL COMMENT '瀵瑰簲flow_instance琛ㄧ殑id',
+    `task_id`          bigint(20)          NOT NULL COMMENT '瀵瑰簲flow_task琛ㄧ殑id',
+    `node_code`        varchar(100)                 DEFAULT NULL COMMENT '寮�濮嬭妭鐐圭紪鐮�',
+    `node_name`        varchar(100)                 DEFAULT NULL COMMENT '寮�濮嬭妭鐐瑰悕绉�',
+    `node_type`        tinyint(1)                   DEFAULT NULL COMMENT '寮�濮嬭妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+    `target_node_code` varchar(100)                 DEFAULT NULL COMMENT '鐩爣鑺傜偣缂栫爜',
+    `target_node_name` varchar(100)                 DEFAULT NULL COMMENT '缁撴潫鑺傜偣鍚嶇О',
+    `approver`         varchar(40)                  DEFAULT NULL COMMENT '瀹℃壒鑰�',
+    `cooperate_type`   tinyint(1)          NOT NULL DEFAULT '0' COMMENT '鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)',
+    `collaborator`     varchar(40)                  DEFAULT NULL COMMENT '鍗忎綔浜�',
+    `skip_type`        varchar(10)          NOT NULL COMMENT '娴佽浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級',
+    `flow_status`      varchar(20)          NOT NULL COMMENT '娴佺▼鐘舵�侊紙1瀹℃壒涓� 2 瀹℃壒閫氳繃 9宸查��鍥� 10澶辨晥锛�',
+    `form_custom`      char(1)      DEFAULT 'N' COMMENT '瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+    `form_path`        varchar(100) DEFAULT NULL COMMENT '瀹℃壒琛ㄥ崟璺緞',
+    `message`          varchar(500)                 DEFAULT NULL COMMENT '瀹℃壒鎰忚',
+    `ext`              varchar(500)                 DEFAULT NULL COMMENT '涓氬姟璇︽儏 瀛樹笟鍔¤〃瀵硅薄json瀛楃涓�',
+    `create_time`      datetime                     DEFAULT NULL COMMENT '浠诲姟寮�濮嬫椂闂�',
+    `update_time`      datetime                     DEFAULT NULL COMMENT '瀹℃壒瀹屾垚鏃堕棿',
+    `del_flag`         char(1)                      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`        varchar(40)                  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB  COMMENT ='鍘嗗彶浠诲姟璁板綍琛�';
 
 
--- 娴佺▼鍒嗙被绠$悊鐩稿叧鎸夐挳
-insert into sys_menu values ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add',   '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:edit',  '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:remove','#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:export','#', 103, 1, sysdate(), null, null, '');
+CREATE TABLE `flow_user`
+(
+    `id`              bigint unsigned NOT NULL COMMENT '涓婚敭id',
+    `type`            char(1)  NOT NULL COMMENT '浜哄憳绫诲瀷锛�1寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺 2寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺 3寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺锛�',
+    `processed_by`    varchar(80) DEFAULT NULL COMMENT '鏉冮檺浜�',
+    `associated`      bigint NOT NULL COMMENT '浠诲姟琛╥d',
+    `create_time`     datetime     DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+    `create_by`       varchar(80) DEFAULT NULL COMMENT '鍒涘缓浜�',
+    `update_time`     datetime     DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+    `del_flag`        char(1)      DEFAULT '0' COMMENT '鍒犻櫎鏍囧織',
+    `tenant_id`       varchar(40)  DEFAULT NULL COMMENT '绉熸埛id',
+    PRIMARY KEY (`id`) USING BTREE,
+    KEY `user_processed_type` (`processed_by`,`type`)
+) ENGINE=InnoDB  COMMENT='娴佺▼鐢ㄦ埛琛�';
+
+-- ----------------------------
+-- 娴佺▼鍒嗙被琛�
+-- ----------------------------
+create table flow_category
+(
+    category_id   bigint(20)  not null comment '娴佺▼鍒嗙被ID',
+    tenant_id     varchar(20)  default '000000' comment '绉熸埛缂栧彿',
+    parent_id     bigint(20)   default 0 comment '鐖舵祦绋嬪垎绫籭d',
+    ancestors     varchar(500) default '' comment '绁栫骇鍒楄〃',
+    category_name varchar(30) not null comment '娴佺▼鍒嗙被鍚嶇О',
+    order_num     int(4)       default 0 comment '鏄剧ず椤哄簭',
+    del_flag      char(1)      default '0' comment '鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�',
+    create_dept   bigint(20)  null comment '鍒涘缓閮ㄩ棬',
+    create_by     bigint(20)  null comment '鍒涘缓鑰�',
+    create_time   datetime    null comment '鍒涘缓鏃堕棿',
+    update_by     bigint(20)  null comment '鏇存柊鑰�',
+    update_time   datetime    null comment '鏇存柊鏃堕棿',
+    primary key (category_id)
+) engine = innodb comment = '娴佺▼鍒嗙被';
+
+INSERT INTO flow_category values (100, '000000', 0, '0', 'OA瀹℃壒', 0, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (101, '000000', 100, '0,100', '鍋囧嫟绠$悊', 0, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (102, '000000', 100, '0,100', '浜轰簨绠$悊', 0, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (103, '000000', 101, '0,100,101', '璇峰亣', 0, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (104, '000000', 101, '0,100,101', '鍑哄樊', 1, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (105, '000000', 101, '0,100,101', '鍔犵彮', 2, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (106, '000000', 101, '0,100,101', '鎹㈢彮', 3, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (107, '000000', 101, '0,100,101', '澶栧嚭', 4, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (108, '000000', 102, '0,100,102', '杞', 1, '0', 103, 1, sysdate(), null, null);
+INSERT INTO flow_category values (109, '000000', 102, '0,100,102', '绂昏亴', 2, '0', 103, 1, sysdate(), null, null);
+
+-- ----------------------------
 -- 璇峰亣鍗曚俊鎭�
+-- ----------------------------
 create table test_leave
 (
-    id          bigint                       not null comment '涓婚敭',
-    leave_type  varchar(255)                 not null comment '璇峰亣绫诲瀷',
-    start_date   datetime                     not null comment '寮�濮嬫椂闂�',
-    end_date     datetime                     not null comment '缁撴潫鏃堕棿',
-    leave_days  int(10)                      not null comment '璇峰亣澶╂暟',
-    remark      varchar(255)                 null comment '璇峰亣鍘熷洜',
-    status      varchar(255)                 null comment '鐘舵��',
-    create_dept bigint                       null comment '鍒涘缓閮ㄩ棬',
-    create_by   bigint                       null comment '鍒涘缓鑰�',
-    create_time datetime                     null comment '鍒涘缓鏃堕棿',
-    update_by   bigint                       null comment '鏇存柊鑰�',
-    update_time datetime                     null comment '鏇存柊鏃堕棿',
-    tenant_id   varchar(20)                  null comment '绉熸埛缂栧彿',
-    PRIMARY KEY (id) USING BTREE
-) ENGINE = InnoDB COMMENT = '璇峰亣鐢宠琛�';
-
--- 娴佺▼鍒嗙被淇℃伅琛�
-create table wf_category
-(
-    id            bigint                       not null comment '涓婚敭'
-        primary key,
-    category_name varchar(255)                 null comment '鍒嗙被鍚嶇О',
-    category_code varchar(255)                 null comment '鍒嗙被缂栫爜',
-    parent_id     bigint                       null comment '鐖剁骇id',
-    sort_num      int(19)                      null comment '鎺掑簭',
-    tenant_id     varchar(20)                  null comment '绉熸埛缂栧彿',
-    create_dept   bigint                       null comment '鍒涘缓閮ㄩ棬',
-    create_by     bigint                       null comment '鍒涘缓鑰�',
-    create_time   datetime                     null comment '鍒涘缓鏃堕棿',
-    update_by     bigint                       null comment '鏇存柊鑰�',
-    update_time   datetime                     null comment '鏇存柊鏃堕棿',
-    constraint uni_category_code
-        unique (category_code)
-) engine=innodb comment= '娴佺▼鍒嗙被';
-INSERT INTO wf_category values (1, 'OA', 'OA', 0, 0, '000000', 103, 1, sysdate(), 1, sysdate());
-
-create table wf_task_back_node
-(
-    id          bigint                       not null
-        primary key,
-    node_id     varchar(255)                 not null comment '鑺傜偣id',
-    node_name   varchar(255)                 not null comment '鑺傜偣鍚嶇О',
-    order_no    int                          not null comment '鎺掑簭',
-    instance_id varchar(255)                 null comment '娴佺▼瀹炰緥id',
-    task_type   varchar(255)                 not null comment '鑺傜偣绫诲瀷',
-    assignee    varchar(2000)                not null comment '瀹℃壒浜�',
-    tenant_id   varchar(20)                  null comment '绉熸埛缂栧彿',
-    create_dept bigint                       null comment '鍒涘缓閮ㄩ棬',
-    create_by   bigint                       null comment '鍒涘缓鑰�',
-    create_time datetime                     null comment '鍒涘缓鏃堕棿',
-    update_by   bigint                       null comment '鏇存柊鑰�',
-    update_time datetime                     null comment '鏇存柊鏃堕棿'
-)
-    comment '鑺傜偣瀹℃壒璁板綍';
-
-create table wf_definition_config
-(
-    id            bigint                        not null comment '涓婚敭'
-        primary key,
-    table_name    varchar(255)                  not null comment '琛ㄥ悕',
-    definition_id varchar(255)                  not null comment '娴佺▼瀹氫箟ID',
-    process_key   varchar(255)                  not null comment '娴佺▼KEY',
-    version       int(10)                       not null comment '娴佺▼鐗堟湰',
-    create_dept   bigint                        null comment '鍒涘缓閮ㄩ棬',
-    create_by     bigint                        null comment '鍒涘缓鑰�',
-    create_time   datetime                      null comment '鍒涘缓鏃堕棿',
-    update_by     bigint                        null comment '鏇存柊鑰�',
-    update_time   datetime                      null comment '鏇存柊鏃堕棿',
-    remark        varchar(500) default ''       null comment '澶囨敞',
-    tenant_id     varchar(20)                   null comment '绉熸埛缂栧彿',
-    constraint uni_definition_id
-        unique (definition_id)
-)
-    comment '娴佺▼瀹氫箟閰嶇疆';
-
-create table wf_form_manage
-(
-    id          bigint       not null comment '涓婚敭'
-        primary key,
-    form_name   varchar(255) not null comment '琛ㄥ崟鍚嶇О',
-    form_type   varchar(255) not null comment '琛ㄥ崟绫诲瀷',
-    router      varchar(255) not null comment '璺敱鍦板潃/琛ㄥ崟ID',
-    remark      varchar(500) null comment '澶囨敞',
-    tenant_id   varchar(20)  null comment '绉熸埛缂栧彿',
+    id          bigint(20)   not null comment 'id',
+    tenant_id   varchar(20) default '000000' comment '绉熸埛缂栧彿',
+    leave_type  varchar(255) not null comment '璇峰亣绫诲瀷',
+    start_date  datetime     not null comment '寮�濮嬫椂闂�',
+    end_date    datetime     not null comment '缁撴潫鏃堕棿',
+    leave_days  int(10)      not null comment '璇峰亣澶╂暟',
+    remark      varchar(255) null comment '璇峰亣鍘熷洜',
+    status      varchar(255) null comment '鐘舵��',
     create_dept bigint       null comment '鍒涘缓閮ㄩ棬',
     create_by   bigint       null comment '鍒涘缓鑰�',
     create_time datetime     null comment '鍒涘缓鏃堕棿',
     update_by   bigint       null comment '鏇存柊鑰�',
-    update_time datetime     null comment '鏇存柊鏃堕棿'
-)
-    comment '琛ㄥ崟绠$悊';
+    update_time datetime     null comment '鏇存柊鏃堕棿',
+    PRIMARY KEY (id) USING BTREE
+) ENGINE = InnoDB COMMENT = '璇峰亣鐢宠琛�';
 
-insert into wf_form_manage(id, form_name, form_type, router, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time) VALUES (1, '璇峰亣鐢宠', 'static', '/workflow/leaveEdit/index', NULL, '000000', 103, 1, sysdate(), 1, sysdate());
+insert into sys_menu values ('11616', '宸ヤ綔娴�', '0', '6', 'workflow', '', '', '1', '0', 'M', '0', '0', '', 'workflow', 103, 1, sysdate(),NULL, NULL, '');
+insert into sys_menu values ('11618', '鎴戠殑浠诲姟', '0', '7', 'task', '', '', '1', '0', 'M', '0', '0', '', 'my-task', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting', 'workflow/task/taskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish', 'workflow/task/taskFinish', '', '1', '1', 'C', '0', '0', '', 'finish', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList', 'workflow/task/taskCopyList', '', '1', '1', 'C', '0', '0', '', 'my-copy', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '', 'process-definition', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance', 'workflow/processInstance/index', '', '1', '1', 'C', '0', '0', '', 'tree-table', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11622', '娴佺▼鍒嗙被', '11616', '1', 'category', 'workflow/category/index', '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument', 'workflow/task/myDocument', '', '1', '1', 'C', '0', '0', '', 'guide', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor', '', '', '1', '0', 'M', '0', '0', '', 'monitor', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu values ('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting', 'workflow/task/allTaskWaiting', '', '1', '1', 'C', '0', '0', '', 'waiting', 103, 1, sysdate(), NULL, NULL, '');
+-- 娴佺▼鍒嗙被绠$悊鐩稿叧鎸夐挳
+insert into sys_menu values ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1,sysdate(), null, null, '');
+insert into sys_menu values ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add', '#', 103, 1,sysdate(), null, null, '');
+insert into sys_menu values ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:edit', '#', 103, 1,sysdate(), null, null, '');
+insert into sys_menu values ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:remove', '#', 103,1, sysdate(), null, null, '');
+insert into sys_menu values ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:export', '#', 103,1, sysdate(), null, null, '');
+-- 璇峰亣娴嬭瘯鐩稿叧鎸夐挳
+insert into sys_menu VALUES (11638, '璇峰亣鐢宠',     5,    1, 'leave', 'workflow/leave/index', '', 1, 0, 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, sysdate(), NULL, NULL, '璇峰亣鐢宠鑿滃崟');
+insert into sys_menu VALUES (11639, '璇峰亣鐢宠鏌ヨ', 11638, 1, '#', '', '', 1, 0, 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu VALUES (11640, '璇峰亣鐢宠鏂板', 11638, 2, '#', '', '', 1, 0, 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu VALUES (11641, '璇峰亣鐢宠淇敼', 11638, 3, '#', '', '', 1, 0, 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu VALUES (11642, '璇峰亣鐢宠鍒犻櫎', 11638, 4, '#', '', '', 1, 0, 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, sysdate(), NULL, NULL, '');
+insert into sys_menu VALUES (11643, '璇峰亣鐢宠瀵煎嚭', 11638, 5, '#', '', '', 1, 0, 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, sysdate(), NULL, NULL, '');
 
-create table wf_node_config
-(
-    id               bigint       not null comment '涓婚敭'
-        primary key,
-    form_id          bigint       null comment '琛ㄥ崟id',
-    form_type        varchar(255) null comment '琛ㄥ崟绫诲瀷',
-    node_name        varchar(255) not null comment '鑺傜偣鍚嶇О',
-    node_id          varchar(255) not null comment '鑺傜偣id',
-    definition_id    varchar(255) not null comment '娴佺▼瀹氫箟id',
-    apply_user_task  char(1)      default '0'     comment '鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級',
-    create_dept      bigint       null comment '鍒涘缓閮ㄩ棬',
-    create_by        bigint       null comment '鍒涘缓鑰�',
-    create_time      datetime     null comment '鍒涘缓鏃堕棿',
-    update_by        bigint       null comment '鏇存柊鑰�',
-    update_time      datetime     null comment '鏇存柊鏃堕棿',
-    tenant_id        varchar(20)  null comment '绉熸埛缂栧彿'
-)
-    comment '鑺傜偣閰嶇疆';
+INSERT INTO sys_dict_type VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, sysdate(), NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
+INSERT INTO sys_dict_type VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, sysdate(), NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
+INSERT INTO sys_dict_type VALUES (15, '000000', '浠诲姟鐘舵��', 'wf_task_status', 103, 1, sysdate(), NULL, NULL, '浠诲姟鐘舵��');
+INSERT INTO sys_dict_data VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL,'宸叉挙閿�');
+INSERT INTO sys_dict_data VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, sysdate(), NULL, NULL, '鑽夌');
+INSERT INTO sys_dict_data VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL,'寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, sysdate(), NULL, NULL,'宸插畬鎴�');
+INSERT INTO sys_dict_data VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL,'宸蹭綔搴�');
+INSERT INTO sys_dict_data VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL,'宸查��鍥�');
+INSERT INTO sys_dict_data VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL,NULL, '宸茬粓姝�');
+INSERT INTO sys_dict_data VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, sysdate(), NULL, NULL,'鑷畾涔夎〃鍗�');
+INSERT INTO sys_dict_data VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL,'鍔ㄦ�佽〃鍗�');
+INSERT INTO sys_dict_data VALUES (48, '000000', 1, '鎾ら攢', 'cancel', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '鎾ら攢');
+INSERT INTO sys_dict_data VALUES (49, '000000', 2, '閫氳繃', 'pass', 'wf_task_status', '', 'success', 'N', 103, 1, sysdate(), NULL, NULL, '閫氳繃');
+INSERT INTO sys_dict_data VALUES (50, '000000', 3, '寰呭鏍�', 'waiting', 'wf_task_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '寰呭鏍�');
+INSERT INTO sys_dict_data VALUES (51, '000000', 4, '浣滃簾', 'invalid', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '浣滃簾');
+INSERT INTO sys_dict_data VALUES (52, '000000', 5, '閫�鍥�', 'back', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '閫�鍥�');
+INSERT INTO sys_dict_data VALUES (53, '000000', 6, '缁堟', 'termination', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '缁堟');
+INSERT INTO sys_dict_data VALUES (54, '000000', 7, '杞姙', 'transfer', 'wf_task_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '杞姙');
+INSERT INTO sys_dict_data VALUES (55, '000000', 8, '濮旀墭', 'depute', 'wf_task_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '濮旀墭');
+INSERT INTO sys_dict_data VALUES (56, '000000', 9, '鎶勯��', 'copy', 'wf_task_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '鎶勯��');
+INSERT INTO sys_dict_data VALUES (57, '000000', 10, '鍔犵', 'sign', 'wf_task_status', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '鍔犵');
+INSERT INTO sys_dict_data VALUES (58, '000000', 11, '鍑忕', 'sign_off', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '鍑忕');
+INSERT INTO sys_dict_data VALUES (59, '000000', 11, '瓒呮椂', 'timeout', 'wf_task_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '瓒呮椂');
 
-
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11638, '璇峰亣鐢宠', 5, 1, 'leave', 'workflow/leave/index', 1, 0, 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, sysdate(), NULL, NULL, '璇峰亣鐢宠鑿滃崟');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11639, '璇峰亣鐢宠鏌ヨ', 11638, 1, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, sysdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11640, '璇峰亣鐢宠鏂板', 11638, 2, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, sysdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11641, '璇峰亣鐢宠淇敼', 11638, 3, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, sysdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11642, '璇峰亣鐢宠鍒犻櫎', 11638, 4, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, sysdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11643, '璇峰亣鐢宠瀵煎嚭', 11638, 5, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, sysdate(), NULL, NULL, '');
-
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, sysdate(), NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, sysdate(), NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
-
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '宸叉挙閿�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, sysdate(), NULL, NULL, '鑽夌');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1,sysdate(), NULL, NULL, '寰呭鏍�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, sysdate(), NULL, NULL, '宸插畬鎴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '宸蹭綔搴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, sysdate(), NULL, NULL, '宸查��鍥�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1,sysdate(), NULL, NULL, '宸茬粓姝�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, sysdate(), NULL, NULL, '鑷畾涔夎〃鍗�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, sysdate(), NULL, NULL, '鍔ㄦ�佽〃鍗�');
-
--- 琛ㄥ崟绠$悊 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11628, '琛ㄥ崟绠$悊', '11616', '5', 'formManage', 'workflow/formManage/index', 1, 0, 'C', '0', '0', 'workflow:formManage:list', 'tree-table', 103, 1, sysdate(), null, null, '琛ㄥ崟绠$悊鑿滃崟');
-
--- 琛ㄥ崟绠$悊鎸夐挳 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11644, '琛ㄥ崟绠$悊鏌ヨ', 11628, '1',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:query',        '', 103, 1, sysdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11645, '琛ㄥ崟绠$悊鏂板', 11628, '2',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:add',          '', 103, 1, sysdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11646, '琛ㄥ崟绠$悊淇敼', 11628, '3',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:edit',         '', 103, 1, sysdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11647, '琛ㄥ崟绠$悊鍒犻櫎', 11628, '4',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:remove',       '', 103, 1, sysdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11648, '琛ㄥ崟绠$悊瀵煎嚭', 11628, '5',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:export',       'tree-table', 103, 1, sysdate(), null, null, '');
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
index bf86615..bc0da26 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -210,7 +210,11 @@
     'TABLE', N'sys_social',
     'COLUMN', N'update_time'
 GO
-
+EXEC sp_addextendedproperty
+    'MS_Description', N'绀句細鍖栧叧绯昏〃',
+    'SCHEMA', N'dbo',
+    'TABLE', N'sys_social'
+GO
 
 CREATE TABLE sys_tenant
 (
diff --git a/script/sql/sqlserver/sqlserver_ry_workflow.sql b/script/sql/sqlserver/sqlserver_ry_workflow.sql
index 2397c35..dc5c6b2 100644
--- a/script/sql/sqlserver/sqlserver_ry_workflow.sql
+++ b/script/sql/sqlserver/sqlserver_ry_workflow.sql
@@ -1,456 +1,1320 @@
-insert into sys_menu values('11616', '宸ヤ綔娴�'  , '0',    '6', 'workflow',          '',                                 '', '1', '0', 'M', '0', '0', '',                       'workflow', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11617', '妯″瀷绠$悊', '11616', '2', 'model',             'workflow/model/index',             '', '1', '1', 'C', '0', '0', 'workflow:model:list',    'model', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11618', '鎴戠殑浠诲姟', '0', '7', 'task',              '',                                 '', '1', '0', 'M', '0', '0', '',                       'my-task', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11619', '鎴戠殑寰呭姙', '11618', '2', 'taskWaiting',       'workflow/task/taskWaiting',              '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11632', '鎴戠殑宸插姙', '11618', '3', 'taskFinish',       'workflow/task/taskFinish',              '', '1', '1', 'C', '0', '0', '',                       'finish', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11633', '鎴戠殑鎶勯��', '11618', '4', 'taskCopyList',       'workflow/task/taskCopyList',              '', '1', '1', 'C', '0', '0', '',                       'my-copy', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11620', '娴佺▼瀹氫箟', '11616', '3', 'processDefinition', 'workflow/processDefinition/index', '', '1', '1', 'C', '0', '0', '',                       'process-definition', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11621', '娴佺▼瀹炰緥', '11630', '1', 'processInstance',   'workflow/processInstance/index',   '', '1', '1', 'C', '0', '0', '',                       'tree-table', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11622', '娴佺▼鍒嗙被', '11616', '1', 'category',          'workflow/category/index',          '', '1', '0', 'C', '0', '0', 'workflow:category:list', 'category', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11629', '鎴戝彂璧风殑', '11618', '1', 'myDocument',        'workflow/task/myDocument',         '', '1', '1', 'C', '0', '0', '',                       'guide', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11630', '娴佺▼鐩戞帶', '11616', '4', 'monitor',           '',                                 '', '1', '0', 'M', '0', '0', '',                       'monitor', 103, 1, getdate(), NULL, NULL, '');
-insert into sys_menu values('11631', '寰呭姙浠诲姟', '11630', '2', 'allTaskWaiting',    'workflow/task/allTaskWaiting',     '', '1', '1', 'C', '0', '0', '',                       'waiting', 103, 1, getdate(), NULL, NULL, '');
+CREATE TABLE flow_definition (
+    id bigint NOT NULL,
+    flow_code nvarchar(40) NOT NULL,
+    flow_name nvarchar(100) NOT NULL,
+    category nvarchar(100) NULL,
+    version nvarchar(20) NOT NULL,
+    is_publish tinyint DEFAULT('0') NULL,
+    form_custom nchar(1) DEFAULT('N') NULL,
+    form_path nvarchar(100) NULL,
+    activity_status tinyint DEFAULT('1') NULL,
+    listener_type nvarchar(100) NULL,
+    listener_path nvarchar(400) NULL,
+    ext nvarchar(500) NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_def__3213E83FEE39AE33 PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
 
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'flow_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'flow_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼绫诲埆',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'category'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鐗堟湰',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'version'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏄惁鍙戝竷锛�0鏈彂甯� 1宸插彂甯� 9澶辨晥锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'is_publish'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'form_custom'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟璺緞',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'form_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'activity_status'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐩戝惉鍣ㄧ被鍨�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'listener_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐩戝惉鍣ㄨ矾寰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'listener_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓氬姟璇︽儏 瀛樹笟鍔¤〃瀵硅薄json瀛楃涓�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'ext'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼瀹氫箟琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_definition'
+GO
+
+CREATE TABLE flow_node (
+    id bigint NOT NULL,
+    node_type tinyint NOT NULL,
+    definition_id bigint NOT NULL,
+    node_code nvarchar(100) NOT NULL,
+    node_name nvarchar(100) NULL,
+    permission_flag nvarchar(200) NULL,
+    node_ratio decimal(6,3)  NULL,
+    coordinate nvarchar(100) NULL,
+    skip_any_node nvarchar(100) DEFAULT('N') NULL,
+    any_node_skip nvarchar(100) NULL,
+    listener_type nvarchar(100) NULL,
+    listener_path nvarchar(400) NULL,
+    handler_type nvarchar(100) NULL,
+    handler_path nvarchar(400) NULL,
+    form_custom nchar(1) DEFAULT('N') NULL,
+    form_path nvarchar(100) NULL,
+    version nvarchar(20) NOT NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_nod__3213E83F372470DE PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼瀹氫箟id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'definition_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鑺傜偣缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鑺傜偣鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'node_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏉冮檺鏍囪瘑锛堟潈闄愮被鍨�:鏉冮檺鏍囪瘑锛屽彲浠ュ涓紝鐢ㄩ�楀彿闅斿紑)',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'permission_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼绛剧讲姣斾緥鍊�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'node_ratio'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍧愭爣',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'coordinate'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏄惁鍙互閫�鍥炰换鎰忚妭鐐癸紙Y鏄� N鍚︼級鍗冲皢鍒犻櫎',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'skip_any_node'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'浠绘剰缁撶偣璺宠浆',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'any_node_skip'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐩戝惉鍣ㄧ被鍨�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'listener_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐩戝惉鍣ㄨ矾寰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'listener_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'澶勭悊鍣ㄧ被鍨�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'handler_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'澶勭悊鍣ㄨ矾寰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'handler_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'form_custom'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟璺緞',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'form_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐗堟湰',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'version'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鑺傜偣琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_node'
+GO
+
+CREATE TABLE flow_skip (
+    id bigint NOT NULL,
+    definition_id bigint NOT NULL,
+    now_node_code nvarchar(100) NOT NULL,
+    now_node_type tinyint  NULL,
+    next_node_code nvarchar(100) NOT NULL,
+    next_node_type tinyint  NULL,
+    skip_name nvarchar(100) NULL,
+    skip_type nvarchar(40) NULL,
+    skip_condition nvarchar(200) NULL,
+    coordinate nvarchar(100) NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_ski__3213E83F073FEE6E PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼瀹氫箟id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'definition_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'褰撳墠娴佺▼鑺傜偣鐨勭紪鐮�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'now_node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'褰撳墠鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'now_node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓嬩竴涓祦绋嬭妭鐐圭殑缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'next_node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓嬩竴涓妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'next_node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璺宠浆鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'skip_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璺宠浆绫诲瀷锛圥ASS瀹℃壒閫氳繃 REJECT閫�鍥烇級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'skip_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璺宠浆鏉′欢',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'skip_condition'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍧愭爣',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'coordinate'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣璺宠浆鍏宠仈琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_skip'
+GO
+
+CREATE TABLE flow_instance (
+    id bigint NOT NULL,
+    definition_id bigint NOT NULL,
+    business_id nvarchar(40) NOT NULL,
+    node_type tinyint NOT NULL,
+    node_code nvarchar(40) NOT NULL,
+    node_name nvarchar(100) NULL,
+    variable nvarchar(max) NULL,
+    flow_status nvarchar(20) NOT NULL,
+    activity_status tinyint DEFAULT('1') NULL,
+    create_by nvarchar(64) NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    ext nvarchar(500) NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_ins__3213E83F5190FEE1 PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+TEXTIMAGE_ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_definition琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'definition_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓氬姟id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'business_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鑺傜偣缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鑺傜偣鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'node_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'浠诲姟鍙橀噺',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'variable'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鐘舵�侊紙0寰呮彁浜� 1瀹℃壒涓� 2 瀹℃壒閫氳繃 3鑷姩閫氳繃 4缁堟 5浣滃簾 6鎾ら攢 7鍙栧洖  8宸插畬鎴� 9宸查��鍥� 10澶辨晥锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'flow_status'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼婵�娲荤姸鎬侊紙0鎸傝捣 1婵�娲伙級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'activity_status'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'create_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鎵╁睍瀛楁锛岄鐣欑粰涓氬姟绯荤粺浣跨敤',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'ext'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼瀹炰緥琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_instance'
+GO
+
+CREATE TABLE flow_task (
+    id bigint NOT NULL,
+    definition_id bigint NOT NULL,
+    instance_id bigint NOT NULL,
+    node_code nvarchar(100) NOT NULL,
+    node_name nvarchar(100) NULL,
+    node_type tinyint NOT NULL,
+    form_custom nchar(1) DEFAULT('N') NULL,
+    form_path nvarchar(100) NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_tas__3213E83F5AE1F1BA PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_definition琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'definition_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_instance琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'instance_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'node_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鑺傜偣绫诲瀷锛�0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'form_custom'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟璺緞',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'form_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'寰呭姙浠诲姟琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_task'
+GO
+
+CREATE TABLE flow_his_task (
+    id bigint NOT NULL,
+    definition_id bigint NOT NULL,
+    instance_id bigint NOT NULL,
+    task_id bigint NOT NULL,
+    node_code nvarchar(100) NULL,
+    node_name nvarchar(100) NULL,
+    node_type tinyint  NULL,
+    target_node_code nvarchar(100) NULL,
+    target_node_name nvarchar(100) NULL,
+    approver nvarchar(40) NULL,
+    cooperate_type tinyint DEFAULT('0') NULL,
+    collaborator nvarchar(40) NULL,
+    skip_type nvarchar(10) NOT NULL,
+    flow_status nvarchar(20) NOT NULL,
+    form_custom nchar(1) DEFAULT('N') NULL,
+    form_path nvarchar(100) NULL,
+    message nvarchar(500) NULL,
+    ext nvarchar(500) NULL,
+    create_time datetime2(7)  NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_his__3213E83F67951564 PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_definition琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'definition_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_instance琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'instance_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀵瑰簲flow_task琛ㄧ殑id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'task_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'寮�濮嬭妭鐐圭紪鐮�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'寮�濮嬭妭鐐瑰悕绉�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'node_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'寮�濮嬭妭鐐圭被鍨嬶紙0寮�濮嬭妭鐐� 1涓棿鑺傜偣 2缁撴潫鑺傜偣 3浜掓枼缃戝叧 4骞惰缃戝叧锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'node_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐩爣鑺傜偣缂栫爜',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'target_node_code'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'缁撴潫鑺傜偣鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'target_node_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'approver'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍗忎綔鏂瑰紡(1瀹℃壒 2杞姙 3濮旀淳 4浼氱 5绁ㄧ 6鍔犵 7鍑忕)',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'cooperate_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍗忎綔浜�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'collaborator'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佽浆绫诲瀷锛圥ASS閫氳繃 REJECT閫�鍥� NONE鏃犲姩浣滐級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'skip_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鐘舵�侊紙1瀹℃壒涓� 2 瀹℃壒閫氳繃 9宸查��鍥� 10澶辨晥锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'flow_status'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟鏄惁鑷畾涔夛紙Y鏄� N鍚︼級',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'form_custom'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒琛ㄥ崟璺緞',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'form_path'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒鎰忚',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'message'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓氬姟璇︽儏 瀛樹笟鍔¤〃瀵硅薄json瀛楃涓�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'ext'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'浠诲姟寮�濮嬫椂闂�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'瀹℃壒瀹屾垚鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍘嗗彶浠诲姟璁板綍琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_his_task'
+GO
+
+CREATE TABLE flow_user (
+    id bigint NOT NULL,
+    type nchar(1) NOT NULL,
+    processed_by nvarchar(80) NULL,
+    associated bigint NOT NULL,
+    create_time datetime2(7)  NULL,
+    create_by nvarchar(80) NULL,
+    update_time datetime2(7)  NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    tenant_id nvarchar(40) NULL,
+    CONSTRAINT PK__flow_use__3213E83FFA38CA8B PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+CREATE NONCLUSTERED INDEX user_processed_type ON flow_user (processed_by ASC, type ASC)
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'涓婚敭id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'浜哄憳绫诲瀷锛�1寰呭姙浠诲姟鐨勫鎵逛汉鏉冮檺 2寰呭姙浠诲姟鐨勮浆鍔炰汉鏉冮檺 3寰呭姙浠诲姟鐨勫鎵樹汉鏉冮檺锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏉冮檺浜�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'processed_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'浠诲姟琛╥d',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'associated'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓浜�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'create_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛id',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鐢ㄦ埛琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_user'
+GO
+
+CREATE TABLE flow_category (
+    category_id bigint NOT NULL,
+    tenant_id nvarchar(20) DEFAULT('000000') NULL,
+    parent_id bigint  DEFAULT(0) NULL,
+    ancestors nvarchar(500) DEFAULT('') NULL,
+    category_name nvarchar(30) NOT NULL,
+    order_num int  DEFAULT(0) NULL,
+    del_flag nchar(1) DEFAULT('0') NULL,
+    create_dept bigint  NULL,
+    create_by bigint  NULL,
+    create_time datetime2(7)  NULL,
+    update_by bigint  NULL,
+    update_time datetime2(7)  NULL,
+    CONSTRAINT PK__flow_cat__D54EE9B4AE98B9C1 PRIMARY KEY CLUSTERED (category_id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鍒嗙被ID',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'category_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛缂栧彿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐖舵祦绋嬪垎绫籭d',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'parent_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绁栫骇鍒楄〃',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'ancestors'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鍒嗙被鍚嶇О',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'category_name'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏄剧ず椤哄簭',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'order_num'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒犻櫎鏍囧織锛�0浠h〃瀛樺湪 2浠h〃鍒犻櫎锛�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'del_flag'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓閮ㄩ棬',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'create_dept'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'create_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'update_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'娴佺▼鍒嗙被',
+'SCHEMA', N'dbo',
+'TABLE', N'flow_category'
+GO
+
+INSERT flow_category VALUES (100, N'000000', 0, N'0', N'OA瀹℃壒', 0, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (101, N'000000', 100, N'0,100', N'鍋囧嫟绠$悊', 0, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (102, N'000000', 100, N'0,100', N'浜轰簨绠$悊', 0, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (103, N'000000', 101, N'0,100,101', N'璇峰亣', 0, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (104, N'000000', 101, N'0,100,101', N'鍑哄樊', 1, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (105, N'000000', 101, N'0,100,101', N'鍔犵彮', 2, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (106, N'000000', 101, N'0,100,101', N'鎹㈢彮', 3, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (107, N'000000', 101, N'0,100,101', N'澶栧嚭', 4, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (108, N'000000', 102, N'0,100,102', N'杞', 1, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+INSERT flow_category VALUES (109, N'000000', 102, N'0,100,102', N'绂昏亴', 2, N'0', 103, 1, getdate(), NULL, NULL);
+GO
+
+CREATE TABLE test_leave (
+    id bigint NOT NULL,
+    tenant_id nvarchar(20) DEFAULT('000000') NULL,
+    leave_type nvarchar(255) NOT NULL,
+    start_date datetime2(7) NOT NULL,
+    end_date datetime2(7) NOT NULL,
+    leave_days int NOT NULL,
+    remark nvarchar(255) NULL,
+    status nvarchar(255) NULL,
+    create_dept bigint  NULL,
+    create_by bigint  NULL,
+    create_time datetime2(7)  NULL,
+    update_by bigint  NULL,
+    update_time datetime2(7)  NULL,
+    CONSTRAINT PK__test_lea__3213E83F348788FA PRIMARY KEY CLUSTERED (id)
+    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
+    ON [PRIMARY]
+)
+ON [PRIMARY]
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'id',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'绉熸埛缂栧彿',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'tenant_id'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璇峰亣绫诲瀷',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'leave_type'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'寮�濮嬫椂闂�',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'start_date'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'缁撴潫鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'end_date'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璇峰亣澶╂暟',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'leave_days'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璇峰亣鍘熷洜',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'remark'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鐘舵��',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'status'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓閮ㄩ棬',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'create_dept'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'create_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鍒涘缓鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'create_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鑰�',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'update_by'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'鏇存柊鏃堕棿',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave',
+'COLUMN', N'update_time'
+GO
+
+EXEC sp_addextendedproperty
+'MS_Description', N'璇峰亣鐢宠琛�',
+'SCHEMA', N'dbo',
+'TABLE', N'test_leave'
+GO
+
+INSERT sys_menu VALUES (11616, N'宸ヤ綔娴�', 0, 6, N'workflow', NULL, N'', 1, 0, N'M', N'0', N'0', N'', N'workflow', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11618, N'鎴戠殑浠诲姟', 0, 7, N'task', NULL, N'', 1, 0, N'M', N'0', N'0', N'', N'my-task', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11619, N'鎴戠殑寰呭姙', 11618, 2, N'taskWaiting', N'workflow/task/taskWaiting', N'', 1, 1, N'C', N'0', N'0', N'', N'waiting', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11632, N'鎴戠殑宸插姙', 11618, 3, N'taskFinish', N'workflow/task/taskFinish', N'', 1, 1, N'C', N'0', N'0', N'', N'finish', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11633, N'鎴戠殑鎶勯��', 11618, 4, N'taskCopyList', N'workflow/task/taskCopyList', N'', 1, 1, N'C', N'0', N'0', N'', N'my-copy', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11620, N'娴佺▼瀹氫箟', 11616, 3, N'processDefinition', N'workflow/processDefinition/index', N'', 1, 1, N'C', N'0', N'0', N'', N'process-definition', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11621, N'娴佺▼瀹炰緥', 11630, 1, N'processInstance', N'workflow/processInstance/index', N'', 1, 1, N'C', N'0', N'0', N'', N'tree-table', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11622, N'娴佺▼鍒嗙被', 11616, 1, N'category', N'workflow/category/index', N'', 1, 0, N'C', N'0', N'0', N'workflow:category:list', N'category', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11629, N'鎴戝彂璧风殑', 11618, 1, N'myDocument', N'workflow/task/myDocument', N'', 1, 1, N'C', N'0', N'0', N'', N'guide', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11630, N'娴佺▼鐩戞帶', 11616, 4, N'monitor', NULL, N'', 1, 0, N'M', N'0', N'0', N'', N'monitor', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11631, N'寰呭姙浠诲姟', 11630, 2, N'allTaskWaiting', N'workflow/task/allTaskWaiting', N'', 1, 1, N'C', N'0', N'0', N'', N'waiting', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
 
 -- 娴佺▼鍒嗙被绠$悊鐩稿叧鎸夐挳
-insert into sys_menu values ('11623', '娴佺▼鍒嗙被鏌ヨ', '11622', '1', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:query', '#', 103, 1, getdate(), null, null, '');
-insert into sys_menu values ('11624', '娴佺▼鍒嗙被鏂板', '11622', '2', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:add',   '#', 103, 1, getdate(), null, null, '');
-insert into sys_menu values ('11625', '娴佺▼鍒嗙被淇敼', '11622', '3', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:edit',  '#', 103, 1, getdate(), null, null, '');
-insert into sys_menu values ('11626', '娴佺▼鍒嗙被鍒犻櫎', '11622', '4', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:remove','#', 103, 1, getdate(), null, null, '');
-insert into sys_menu values ('11627', '娴佺▼鍒嗙被瀵煎嚭', '11622', '5', '#', '', '', 1, 0, 'F', '0', '0', 'workflow:category:export','#', 103, 1, getdate(), null, null, '');
--- 璇峰亣鍗曚俊鎭�
-create table test_leave
-(
-    id          bigint        not null
-        primary key,
-    leave_type  nvarchar(255) not null,
-    start_date  datetime2     not null,
-    end_date    datetime2     not null,
-    leave_days  int           not null,
-    remark      nvarchar(255),
-    status      nvarchar(255),
-    create_dept bigint,
-    create_by   bigint,
-    create_time datetime2,
-    update_by   bigint,
-    update_time datetime2,
-    tenant_id   nvarchar(20)
-)
-go
+INSERT sys_menu VALUES (11623, N'娴佺▼鍒嗙被鏌ヨ', 11622, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:query', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11624, N'娴佺▼鍒嗙被鏂板', 11622, 2, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:add', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11625, N'娴佺▼鍒嗙被淇敼', 11622, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11626, N'娴佺▼鍒嗙被鍒犻櫎', 11622, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:remove', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11627, N'娴佺▼鍒嗙被瀵煎嚭', 11622, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:category:export', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
 
-exec sp_addextendedproperty 'MS_Description', N'璇峰亣鐢宠琛�', 'SCHEMA', 'dbo', 'TABLE', 'test_leave'
-go
+-- 璇峰亣娴嬭瘯鐩稿叧鎸夐挳
+INSERT sys_menu VALUES (11638, N'璇峰亣鐢宠', 5, 1, N'leave', N'workflow/leave/index', N'', 1, 0, N'C', N'0', N'0', N'workflow:leave:list', N'#', 103, 1, GETDATE(), NULL, NULL, N'璇峰亣鐢宠鑿滃崟');
+GO
+INSERT sys_menu VALUES (11639, N'璇峰亣鐢宠鏌ヨ', 11638, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:leave:query', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11640, N'璇峰亣鐢宠鏂板', 11638, 2, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:leave:add', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11641, N'璇峰亣鐢宠淇敼', 11638, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:leave:edit', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11642, N'璇峰亣鐢宠鍒犻櫎', 11638, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:leave:remove', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (11643, N'璇峰亣鐢宠瀵煎嚭', 11638, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'workflow:leave:export', N'#', 103, 1, GETDATE(), NULL, NULL, N'');
 
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'id'
-go
+INSERT sys_dict_type VALUES (13, N'000000', N'涓氬姟鐘舵��', N'wf_business_status', 103, 1, GETDATE(), NULL, NULL, N'涓氬姟鐘舵�佸垪琛�');
+GO
+INSERT sys_dict_type VALUES (14, N'000000', N'琛ㄥ崟绫诲瀷', N'wf_form_type', 103, 1, GETDATE(), NULL, NULL, N'琛ㄥ崟绫诲瀷鍒楄〃');
+GO
+INSERT sys_dict_type VALUES (15, N'000000', N'浠诲姟鐘舵��', N'wf_task_status', 103, 1, GETDATE(), NULL, NULL, N'浠诲姟鐘舵��');
+GO
 
-exec sp_addextendedproperty 'MS_Description', N'璇峰亣绫诲瀷', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'leave_type'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'寮�濮嬫椂闂�', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'start_date'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'缁撴潫鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'end_date'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'璇峰亣澶╂暟', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'leave_days'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'璇峰亣鍘熷洜', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'remark'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鐘舵��', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'status'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN',
-     'update_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'test_leave', 'COLUMN', 'tenant_id'
-go
-
--- 娴佺▼鍒嗙被淇℃伅琛�
-create table wf_category
-(
-    id            bigint not null
-        primary key,
-    category_name nvarchar(255),
-    category_code nvarchar(255)
-        constraint uni_category_code
-        unique,
-    parent_id     bigint,
-    sort_num      int,
-    tenant_id     nvarchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   datetime2,
-    update_by     bigint,
-    update_time   datetime2
-)
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼鍒嗙被', 'SCHEMA', 'dbo', 'TABLE', 'wf_category'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN', 'id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒嗙被鍚嶇О', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'category_name'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒嗙被缂栫爜', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'category_code'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鐖剁骇id', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN', 'parent_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鎺掑簭', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN', 'sort_num'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'tenant_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_category', 'COLUMN',
-     'update_time'
-go
-
-INSERT INTO wf_category values (1, 'OA', 'OA', 0, 0, '000000', 103, 1, getdate(), 1, getdate());
-
-create table wf_task_back_node
-(
-    id            bigint not null primary key,
-    node_id       nvarchar(255) not null,
-    node_name     nvarchar(255) not null,
-    order_no      int not null,
-    instance_id   nvarchar(255) not null,
-    task_type     nvarchar(255) not null,
-    assignee      nvarchar(2000) not null,
-    tenant_id     nvarchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   datetime2,
-    update_by     bigint,
-    update_time   datetime2
-)
-
-go
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣瀹℃壒璁板綍', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣id', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'node_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣鍚嶇О', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'node_name'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鎺掑簭', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'order_no'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼瀹炰緥id', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'instance_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣绫诲瀷', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'task_type'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'瀹℃壒浜�', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'assignee'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'tenant_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_task_back_node', 'COLUMN',
-     'update_time'
-go
-
-create table wf_definition_config
-(
-    id            bigint not null primary key,
-    table_name    nvarchar(255)  not null,
-    definition_id nvarchar(255)  not null
-        constraint uni_definition_id
-        unique,
-    process_key   nvarchar(255)  not null,
-    version       bigint         not null,
-    remark        nvarchar(500) DEFAULT ('') null,
-    tenant_id     nvarchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   datetime2,
-    update_by     bigint,
-    update_time   datetime2
-)
-
-go
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼瀹氫箟閰嶇疆', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN', 'id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ悕', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'table_name'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼瀹氫箟ID', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'definition_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼KEY', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'process_key'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼鐗堟湰', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'version'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'澶囨敞', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'remark'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'tenant_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_definition_config', 'COLUMN',
-     'update_time'
-go
-
-create table wf_form_manage
-(
-    id            bigint not null primary key,
-    form_name     nvarchar(255) not null,
-    form_type     nvarchar(255) not null,
-    router        nvarchar(255) not null,
-    remark        nvarchar(500) null,
-    tenant_id     nvarchar(20),
-    create_dept   bigint,
-    create_by     bigint,
-    create_time   datetime2,
-    update_by     bigint,
-    update_time   datetime2
-)
-
-go
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ崟绠$悊', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN', 'id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ崟鍚嶇О', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'form_name'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ崟绫诲瀷', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'form_type'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'璺敱鍦板潃/琛ㄥ崟ID', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'router'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'澶囨敞', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'remark'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'tenant_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_form_manage', 'COLUMN',
-     'update_time'
-go
-
-insert into wf_form_manage(id, form_name, form_type, router, remark, tenant_id, create_dept, create_by, create_time, update_by, update_time) VALUES (1, '璇峰亣鐢宠', 'static', '/workflow/leaveEdit/index', NULL, '000000', 103, 1, getdate(), 1, getdate());
-
-create table wf_node_config
-(
-    id               bigint not null primary key,
-    form_id          bigint,
-    form_type        nvarchar(255) ,
-    node_name        nvarchar(255) not null,
-    node_id          nvarchar(255) not null,
-    definition_id    nvarchar(255) not null,
-    apply_user_task  nchar default ('0')  null,
-    tenant_id        nvarchar(20),
-    create_dept      bigint,
-    create_by        bigint,
-    create_time      datetime2,
-    update_by        bigint,
-    update_time      datetime2
-)
-
-go
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣閰嶇疆', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'涓婚敭', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN', 'id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ崟id', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'form_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'琛ㄥ崟绫诲瀷', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'form_type'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣鍚嶇О', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'node_name'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鑺傜偣id', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'node_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'娴佺▼瀹氫箟id', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'definition_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏄惁涓虹敵璇蜂汉鑺傜偣 锛�0鏄� 1鍚︼級', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'apply_user_task'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'绉熸埛缂栧彿', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'tenant_id'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓閮ㄩ棬', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'create_dept'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN', 'create_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鍒涘缓鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'create_time'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鑰�', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN', 'update_by'
-go
-
-exec sp_addextendedproperty 'MS_Description', N'鏇存柊鏃堕棿', 'SCHEMA', 'dbo', 'TABLE', 'wf_node_config', 'COLUMN',
-     'update_time'
-go
-
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11638, '璇峰亣鐢宠', 5, 1, 'leave', 'workflow/leave/index', 1, 0, 'C', '0', '0', 'workflow:leave:list', '#', 103, 1, getdate(), NULL, NULL, '璇峰亣鐢宠鑿滃崟');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11639, '璇峰亣鐢宠鏌ヨ', 11638, 1, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:query', '#', 103, 1, getdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11640, '璇峰亣鐢宠鏂板', 11638, 2, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:add', '#', 103, 1, getdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11641, '璇峰亣鐢宠淇敼', 11638, 3, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:edit', '#', 103, 1, getdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11642, '璇峰亣鐢宠鍒犻櫎', 11638, 4, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:remove', '#', 103, 1, getdate(), NULL, NULL, '');
-INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (11643, '璇峰亣鐢宠瀵煎嚭', 11638, 5, '#', '', 1, 0, 'F', '0', '0', 'workflow:leave:export', '#', 103, 1, getdate(), NULL, NULL, '');
-
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (13, '000000', '涓氬姟鐘舵��', 'wf_business_status', 103, 1, getdate(), NULL, NULL, '涓氬姟鐘舵�佸垪琛�');
-INSERT INTO sys_dict_type(dict_id, tenant_id, dict_name, dict_type, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (14, '000000', '琛ㄥ崟绫诲瀷', 'wf_form_type', 103, 1, getdate(), NULL, NULL, '琛ㄥ崟绫诲瀷鍒楄〃');
-
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (39, '000000', 1, '宸叉挙閿�', 'cancel', 'wf_business_status', '', 'danger', 'N', 103, 1, getdate(), NULL, NULL, '宸叉挙閿�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (40, '000000', 2, '鑽夌', 'draft', 'wf_business_status', '', 'info', 'N', 103, 1, getdate(), NULL, NULL, '鑽夌');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (41, '000000', 3, '寰呭鏍�', 'waiting', 'wf_business_status', '', 'primary', 'N', 103, 1,getdate(), NULL, NULL, '寰呭鏍�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (42, '000000', 4, '宸插畬鎴�', 'finish', 'wf_business_status', '', 'success', 'N', 103, 1, getdate(), NULL, NULL, '宸插畬鎴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (43, '000000', 5, '宸蹭綔搴�', 'invalid', 'wf_business_status', '', 'danger', 'N', 103, 1, getdate(), NULL, NULL, '宸蹭綔搴�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (44, '000000', 6, '宸查��鍥�', 'back', 'wf_business_status', '', 'danger', 'N', 103, 1, getdate(), NULL, NULL, '宸查��鍥�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (45, '000000', 7, '宸茬粓姝�', 'termination', 'wf_business_status', '', 'danger', 'N', 103, 1,getdate(), NULL, NULL, '宸茬粓姝�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (46, '000000', 1, '鑷畾涔夎〃鍗�', 'static', 'wf_form_type', '', 'success', 'N', 103, 1, getdate(), NULL, NULL, '鑷畾涔夎〃鍗�');
-INSERT INTO sys_dict_data(dict_code, tenant_id, dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, create_dept, create_by, create_time, update_by, update_time, remark) VALUES (47, '000000', 2, '鍔ㄦ�佽〃鍗�', 'dynamic', 'wf_form_type', '', 'primary', 'N', 103, 1, getdate(), NULL, NULL, '鍔ㄦ�佽〃鍗�');
-
--- 琛ㄥ崟绠$悊 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11628, '琛ㄥ崟绠$悊', '11616', '5', 'formManage', 'workflow/formManage/index', 1, 0, 'C', '0', '0', 'workflow:formManage:list', 'tree-table', 103, 1, getdate(), null, null, '琛ㄥ崟绠$悊鑿滃崟');
-
--- 琛ㄥ崟绠$悊鎸夐挳 SQL
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11644, '琛ㄥ崟绠$悊鏌ヨ', 11628, '1',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:query',        '', 103, 1, getdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11645, '琛ㄥ崟绠$悊鏂板', 11628, '2',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:add',          '', 103, 1, getdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11646, '琛ㄥ崟绠$悊淇敼', 11628, '3',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:edit',         '', 103, 1, getdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11647, '琛ㄥ崟绠$悊鍒犻櫎', 11628, '4',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:remove',       '', 103, 1, getdate(), null, null, '');
-
-insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
-values(11648, '琛ㄥ崟绠$悊瀵煎嚭', 11628, '5',  '#', '', 1, 0, 'F', '0', '0', 'workflow:formManage:export',       'tree-table', 103, 1, getdate(), null, null, '');
+INSERT sys_dict_data VALUES (39, N'000000', 1, N'宸叉挙閿�', N'cancel', N'wf_business_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'宸叉挙閿�');
+GO
+INSERT sys_dict_data VALUES (40, N'000000', 2, N'鑽夌', N'draft', N'wf_business_status', N'', N'info', N'N', 103, 1, GETDATE(), NULL, NULL, N'鑽夌');
+GO
+INSERT sys_dict_data VALUES (41, N'000000', 3, N'寰呭鏍�', N'waiting', N'wf_business_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'寰呭鏍�');
+GO
+INSERT sys_dict_data VALUES (42, N'000000', 4, N'宸插畬鎴�', N'finish', N'wf_business_status', N'', N'success', N'N', 103, 1, GETDATE(), NULL, NULL, N'宸插畬鎴�');
+GO
+INSERT sys_dict_data VALUES (43, N'000000', 5, N'宸蹭綔搴�', N'invalid', N'wf_business_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'宸蹭綔搴�');
+GO
+INSERT sys_dict_data VALUES (44, N'000000', 6, N'宸查��鍥�', N'back', N'wf_business_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'宸查��鍥�');
+GO
+INSERT sys_dict_data VALUES (45, N'000000', 7, N'宸茬粓姝�', N'termination', N'wf_business_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'宸茬粓姝�');
+GO
+INSERT sys_dict_data VALUES (46, N'000000', 1, N'鑷畾涔夎〃鍗�', N'static', N'wf_form_type', N'', N'success', N'N', 103, 1, GETDATE(), NULL, NULL, N'鑷畾涔夎〃鍗�');
+GO
+INSERT sys_dict_data VALUES (47, N'000000', 2, N'鍔ㄦ�佽〃鍗�', N'dynamic', N'wf_form_type', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'鍔ㄦ�佽〃鍗�');
+GO
+INSERT sys_dict_data VALUES (48, N'000000', 1, N'鎾ら攢', N'cancel', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'鎾ら攢');
+GO
+INSERT sys_dict_data VALUES (49, N'000000', 2, N'閫氳繃', N'pass', N'wf_task_status', N'', N'success', N'N', 103, 1, GETDATE(), NULL, NULL, N'閫氳繃');
+GO
+INSERT sys_dict_data VALUES (50, N'000000', 3, N'寰呭鏍�', N'waiting', N'wf_task_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'寰呭鏍�');
+GO
+INSERT sys_dict_data VALUES (51, N'000000', 4, N'浣滃簾', N'invalid', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'浣滃簾');
+GO
+INSERT sys_dict_data VALUES (52, N'000000', 5, N'閫�鍥�', N'back', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'閫�鍥�');
+GO
+INSERT sys_dict_data VALUES (53, N'000000', 6, N'缁堟', N'termination', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'缁堟');
+GO
+INSERT sys_dict_data VALUES (54, N'000000', 7, N'杞姙', N'transfer', N'wf_task_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'杞姙');
+GO
+INSERT sys_dict_data VALUES (55, N'000000', 8, N'濮旀墭', N'depute', N'wf_task_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'濮旀墭');
+GO
+INSERT sys_dict_data VALUES (56, N'000000', 9, N'鎶勯��', N'copy', N'wf_task_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'鎶勯��');
+GO
+INSERT sys_dict_data VALUES (57, N'000000', 10, N'鍔犵', N'sign', N'wf_task_status', N'', N'primary', N'N', 103, 1, GETDATE(), NULL, NULL, N'鍔犵');
+GO
+INSERT sys_dict_data VALUES (58, N'000000', 11, N'鍑忕', N'sign_off', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'鍑忕');
+GO
+INSERT sys_dict_data VALUES (59, N'000000', 11, N'瓒呮椂', N'timeout', N'wf_task_status', N'', N'danger', N'N', 103, 1, GETDATE(), NULL, NULL, N'瓒呮椂');
+GO

--
Gitblit v1.9.3