From 456620b6383611bc5982d670fca8dead60571208 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期四, 06 六月 2024 11:13:46 +0800
Subject: [PATCH] !549 ♥️发布 5.2.0-BETA2 公测版本 Merge pull request !549 from 疯狂的狮子Li/dev

---
 ruoyi-modules/ruoyi-workflow/README.md                                                                                   |    3 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TestLeaveVo.java                               |    6 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java                                   |   20 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/RedisExceptionHandler.java                |    2 
 script/sql/sqlserver/flowable.sql                                                                                        |   23 
 script/sql/oracle/oracle_ry_vue_5.X.sql                                                                                  |    1 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java                        |    2 
 script/sql/postgres/flowable.sql                                                                                         |   17 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java                              |   16 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java                        |    4 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java        |   28 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/QueryUtils.java                                    |   17 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java                                 |  108 +---
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java                        |   21 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java         |   47 +
 ruoyi-admin/src/main/resources/application-prod.yml                                                                      |    3 
 script/sql/update/sqlserver/update_5.1.2-5.2.0.sql                                                                       |    4 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java      |    9 
 ruoyi-admin/src/main/resources/application-dev.yml                                                                       |    4 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java                      |    9 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java          |  157 +++---
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java                  |    9 
 ruoyi-common/ruoyi-common-bom/pom.xml                                                                                    |    2 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java                      |   41 +
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActProcessInstanceController.java             |   52 +-
 pom.xml                                                                                                                  |   11 
 script/sql/update/update_5.1.2-5.2.0.sql                                                                                 |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/ActHistoryInfoVo.java                          |    4 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java                        |   76 +++
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/handler/SmsExceptionHandler.java                      |   30 +
 script/sql/update/oracle/update_5.1.2-5.2.0.sql                                                                          |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java                   |   68 ++
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java                 |   35 +
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java                   |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/TestLeaveBo.java                               |    5 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IActProcessInstanceService.java                  |   32 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/ProcessInvalidBo.java                          |    6 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java                    |  119 +++++
 script/bpmn/模型.zip                                                                                                       |    0 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java |   27 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/TaskTimeoutJobHandler.java              |    1 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java                  |   35 +
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java               |    7 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/TestLeaveController.java                      |   14 
 ruoyi-admin/pom.xml                                                                                                      |   15 
 script/sql/ry_vue_5.X.sql                                                                                                |    1 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java                         |    8 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/constant/FlowConstant.java                        |    4 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java                               |    5 
 script/sql/sqlserver/sqlserver_ry_vue_5.X.sql                                                                            |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/TestLeave.java                                    |    5 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java                     |   65 +-
 script/sql/flowable.sql                                                                                                  |   15 
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java          |    1 
 /dev/null                                                                                                                |   21 
 ruoyi-modules/ruoyi-workflow/pom.xml                                                                                     |    5 
 script/sql/oracle/flowable.sql                                                                                           |   16 
 script/sql/update/postgres/update_5.1.2-5.2.0.sql                                                                        |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java                  |   13 
 script/sql/postgres/postgres_ry_vue_5.X.sql                                                                              |    1 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java                       |    2 
 ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/SnailJobConfig.java                            |    2 
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/FlowProcessEventHandler.java            |   48 ++
 63 files changed, 860 insertions(+), 452 deletions(-)

diff --git a/pom.xml b/pom.xml
index 4d04d39..7d89d8a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,8 +13,8 @@
     <description>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</description>
 
     <properties>
-        <revision>5.2.0-BETA</revision>
-        <spring-boot.version>3.2.5</spring-boot.version>
+        <revision>5.2.0-BETA2</revision>
+        <spring-boot.version>3.2.6</spring-boot.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <java.version>17</java.version>
@@ -34,7 +34,7 @@
         <lock4j.version>2.2.7</lock4j.version>
         <dynamic-ds.version>4.3.0</dynamic-ds.version>
         <alibaba-ttl.version>2.14.4</alibaba-ttl.version>
-        <snailjob.version>1.0.0-beta1</snailjob.version>
+        <snailjob.version>1.0.0-beta3</snailjob.version>
         <mapstruct-plus.version>1.3.6</mapstruct-plus.version>
         <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
         <lombok.version>1.18.32</lombok.version>
@@ -50,6 +50,8 @@
         <sms4j.version>3.2.1</sms4j.version>
         <!-- 闄愬埗妗嗘灦涓殑fastjson鐗堟湰 -->
         <fastjson.version>1.2.83</fastjson.version>
+        <!--宸ヤ綔娴侀厤缃�-->
+        <flowable.version>7.0.0</flowable.version>
 
         <!-- 鎻掍欢鐗堟湰 -->
         <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
@@ -57,9 +59,6 @@
         <maven-compiler-plugin.verison>3.11.0</maven-compiler-plugin.verison>
         <maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
         <flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
-
-        <!--宸ヤ綔娴侀厤缃�-->
-        <flowable.version>7.0.0</flowable.version>
     </properties>
 
     <profiles>
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 0ae1850..610e9d7 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -97,21 +97,6 @@
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>me.zhyd.oauth</groupId>
-            <artifactId>JustAuth</artifactId>
-        </dependency>
-
-        <!-- SnailJob client -->
-        <dependency>
-            <groupId>com.aizuda</groupId>
-            <artifactId>snail-job-client-starter</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.aizuda</groupId>
-            <artifactId>snail-job-client-job-core</artifactId>
-        </dependency>
-
         <!-- skywalking 鏁村悎 logback -->
 <!--        <dependency>-->
 <!--            <groupId>org.apache.skywalking</groupId>-->
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index 529a106..5b55973 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -12,7 +12,7 @@
 snail-job:
   enabled: true
   # 闇�瑕佸湪 SnailJob 鍚庡彴缁勭鐞嗗垱寤哄搴斿悕绉扮殑缁�,鐒跺悗鍒涘缓浠诲姟鐨勬椂鍊欓�夋嫨瀵瑰簲鐨勭粍,鎵嶈兘姝g‘鍒嗘淳浠诲姟
-  group-name: "ruoyi_group"
+  group: "ruoyi_group"
   # SnailJob 鎺ュ叆楠岃瘉浠ょ墝 璇﹁ script/sql/snail_job.sql `sj_group_config` 琛�
   token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT"
   server:
@@ -20,7 +20,6 @@
     port: 1788
   # 璇﹁ script/sql/snail_job.sql `sj_namespace` 琛�
   namespace: ${spring.profiles.active}
-
 
 --- # 鏁版嵁婧愰厤缃�
 spring:
@@ -102,6 +101,7 @@
     # 鏄惁寮�鍚痵sl
     ssl.enabled: false
 
+# redisson 閰嶇疆
 redisson:
   # redis key鍓嶇紑
   keyPrefix:
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index 0613bd7..d21644d 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -15,7 +15,7 @@
 snail-job:
   enabled: false
   # 闇�瑕佸湪 SnailJob 鍚庡彴缁勭鐞嗗垱寤哄搴斿悕绉扮殑缁�,鐒跺悗鍒涘缓浠诲姟鐨勬椂鍊欓�夋嫨瀵瑰簲鐨勭粍,鎵嶈兘姝g‘鍒嗘淳浠诲姟
-  group-name: "ruoyi_group"
+  group: "ruoyi_group"
   # SnailJob 鎺ュ叆楠岃瘉浠ょ墝 璇﹁ script/sql/snail_job.sql `sj_group_config` 琛�
   token: "SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT"
   server:
@@ -104,6 +104,7 @@
     # 鏄惁寮�鍚痵sl
     ssl.enabled: false
 
+# redisson 閰嶇疆
 redisson:
   # redis key鍓嶇紑
   keyPrefix:
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index f9af9de..39ef2b3 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -14,7 +14,7 @@
     </description>
 
     <properties>
-        <revision>5.2.0-BETA</revision>
+        <revision>5.2.0-BETA2</revision>
     </properties>
 
     <dependencyManagement>
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
new file mode 100644
index 0000000..61c7efc
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessEvent.java
@@ -0,0 +1,41 @@
+package org.dromara.common.core.domain.event;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 鎬讳綋娴佺▼鐩戝惉
+ *
+ * @author may
+ */
+
+@Data
+public class ProcessEvent implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼瀹氫箟key
+     */
+    private String key;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessKey;
+
+    /**
+     * 鐘舵��
+     */
+    private String status;
+
+    /**
+     * 褰撲负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
new file mode 100644
index 0000000..09c84bd
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/ProcessTaskEvent.java
@@ -0,0 +1,35 @@
+package org.dromara.common.core.domain.event;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 娴佺▼鍔炵悊鐩戝惉
+ *
+ * @author may
+ */
+
+@Data
+public class ProcessTaskEvent implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 娴佺▼瀹氫箟key涓庢祦绋嬭妭鐐规爣璇�(鎷兼帴鏂瑰紡锛氭祦绋嬪畾涔塳ey_娴佺▼鑺傜偣)
+     */
+    private String keyNode;
+
+    /**
+     * 浠诲姟id
+     */
+    private String taskId;
+
+    /**
+     * 涓氬姟id
+     */
+    private String businessKey;
+
+}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/BusinessStatusEnum.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
similarity index 98%
rename from ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/BusinessStatusEnum.java
rename to ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
index 6eb6ffe..0af943a 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/enums/BusinessStatusEnum.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java
@@ -1,4 +1,4 @@
-package org.dromara.workflow.common.enums;
+package org.dromara.common.core.enums;
 
 import cn.hutool.core.util.StrUtil;
 import lombok.AllArgsConstructor;
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
new file mode 100644
index 0000000..4e556c9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/WorkflowService.java
@@ -0,0 +1,76 @@
+package org.dromara.common.core.service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 閫氱敤 宸ヤ綔娴佹湇鍔�
+ *
+ * @author may
+ */
+public interface WorkflowService {
+
+    /**
+     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
+     *
+     * @param businessKeys 涓氬姟id
+     * @return 缁撴灉
+     */
+    boolean deleteRunAndHisInstance(List<String> businessKeys);
+
+    /**
+     * 鑾峰彇褰撳墠娴佺▼鐘舵��
+     *
+     * @param taskId 浠诲姟id
+     */
+    String getBusinessStatusByTaskId(String taskId);
+
+    /**
+     * 鑾峰彇褰撳墠娴佺▼鐘舵��
+     *
+     * @param businessKey 涓氬姟id
+     */
+    String getBusinessStatus(String businessKey);
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
+     *
+     * @param taskId       浠诲姟id
+     * @param variableName 鍙橀噺鍚嶇О
+     * @param value        鍙橀噺鍊�
+     */
+    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);
+
+    /**
+     * 鎸夌収涓氬姟id鏌ヨ娴佺▼瀹炰緥id
+     *
+     * @param businessKey 涓氬姟id
+     * @return 缁撴灉
+     */
+    String getInstanceIdByBusinessKey(String businessKey);
+}
diff --git a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/SnailJobConfig.java b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/SnailJobConfig.java
index d671f0e..cba3753 100644
--- a/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/SnailJobConfig.java
+++ b/ruoyi-common/ruoyi-common-job/src/main/java/org/dromara/common/job/config/SnailJobConfig.java
@@ -21,7 +21,7 @@
 @AutoConfiguration
 @ConditionalOnProperty(prefix = "snail-job", name = "enabled", havingValue = "true")
 @EnableScheduling
-@EnableSnailJob(group = "${snail-job.group-name}")
+@EnableSnailJob
 public class SnailJobConfig {
 
     @EventListener(SnailClientStartingEvent.class)
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
index fcad35b..86668aa 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java
@@ -162,13 +162,14 @@
     /**
      * 涓婁紶鏂囦欢鍒� Amazon S3锛屽苟杩斿洖涓婁紶缁撴灉
      *
-     * @param filePath  鏈湴鏂囦欢璺緞
-     * @param key       鍦� Amazon S3 涓殑瀵硅薄閿�
-     * @param md5Digest 鏈湴鏂囦欢鐨� MD5 鍝堝笇鍊硷紙鍙�夛級
+     * @param filePath    鏈湴鏂囦欢璺緞
+     * @param key         鍦� Amazon S3 涓殑瀵硅薄閿�
+     * @param md5Digest   鏈湴鏂囦欢鐨� MD5 鍝堝笇鍊硷紙鍙�夛級
+     * @param contentType 鏂囦欢鍐呭绫诲瀷
      * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅
      * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父
      */
-    public UploadResult upload(Path filePath, String key, String md5Digest) {
+    public UploadResult upload(Path filePath, String key, String md5Digest, String contentType) {
         try {
             // 鏋勫缓涓婁紶璇锋眰瀵硅薄
             FileUpload fileUpload = transferManager.uploadFile(
@@ -176,6 +177,7 @@
                         y -> y.bucket(properties.getBucketName())
                             .key(key)
                             .contentMD5(StringUtils.isNotEmpty(md5Digest) ? md5Digest : null)
+                            .contentType(contentType)
                             .build())
                     .addTransferListener(LoggingTransferListener.create())
                     .source(filePath).build());
@@ -201,10 +203,11 @@
      * @param inputStream 瑕佷笂浼犵殑杈撳叆娴�
      * @param key         鍦� Amazon S3 涓殑瀵硅薄閿�
      * @param length      杈撳叆娴佺殑闀垮害
+     * @param contentType 鏂囦欢鍐呭绫诲瀷
      * @return UploadResult 鍖呭惈涓婁紶鍚庣殑鏂囦欢淇℃伅
      * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父
      */
-    public UploadResult upload(InputStream inputStream, String key, Long length) {
+    public UploadResult upload(InputStream inputStream, String key, Long length, String contentType) {
         // 濡傛灉杈撳叆娴佷笉鏄� ByteArrayInputStream锛屽垯灏嗗叾璇诲彇涓哄瓧鑺傛暟缁勫啀鍒涘缓 ByteArrayInputStream
         if (!(inputStream instanceof ByteArrayInputStream)) {
             inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
@@ -219,6 +222,7 @@
                     .putObjectRequest(
                         y -> y.bucket(properties.getBucketName())
                             .key(key)
+                            .contentType(contentType)
                             .build())
                     .build());
 
@@ -335,7 +339,7 @@
      * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父
      */
     public UploadResult uploadSuffix(byte[] data, String suffix) {
-        return upload(new ByteArrayInputStream(data), getPath(properties.getPrefix(), suffix), Long.valueOf(data.length));
+        return upload(new ByteArrayInputStream(data), getPath(properties.getPrefix(), suffix), Long.valueOf(data.length), FileUtils.getMimeType(suffix));
     }
 
     /**
@@ -348,7 +352,7 @@
      * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父
      */
     public UploadResult uploadSuffix(InputStream inputStream, String suffix, Long length) {
-        return upload(inputStream, getPath(properties.getPrefix(), suffix), length);
+        return upload(inputStream, getPath(properties.getPrefix(), suffix), length, FileUtils.getMimeType(suffix));
     }
 
     /**
@@ -360,7 +364,7 @@
      * @throws OssException 濡傛灉涓婁紶澶辫触锛屾姏鍑鸿嚜瀹氫箟寮傚父
      */
     public UploadResult uploadSuffix(File file, String suffix) {
-        return upload(file.toPath(), getPath(properties.getPrefix(), suffix), null);
+        return upload(file.toPath(), getPath(properties.getPrefix(), suffix), null, FileUtils.getMimeType(suffix));
     }
 
     /**
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
index d70270a..3da1ba5 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
@@ -48,7 +48,10 @@
         }
         OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);
         // 浣跨敤绉熸埛鏍囪瘑閬垮厤澶氫釜绉熸埛鐩稿悓key瀹炰緥瑕嗙洊
-        String key = properties.getTenantId() + ":" + configKey;
+        String key = configKey;
+        if (StringUtils.isNotBlank(properties.getTenantId())) {
+            key = properties.getTenantId() + ":" + configKey;
+        }
         OssClient client = CLIENT_CACHE.get(key);
         // 瀹㈡埛绔笉瀛樺湪鎴栭厤缃笉鐩稿悓鍒欓噸鏂版瀯寤�
         if (client == null || !client.checkPropertiesSame(properties)) {
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/RedisExceptionHandler.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/RedisExceptionHandler.java
index 5ed12a6..5e904f3 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/RedisExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/RedisExceptionHandler.java
@@ -23,7 +23,7 @@
     @ExceptionHandler(LockFailureException.class)
     public R<Void> handleLockFailureException(LockFailureException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
-        log.error("鑾峰彇閿佸け璐ヤ簡'{}',鍙戠敓Lock4j寮傚父." + requestURI, e.getMessage());
+        log.error("鑾峰彇閿佸け璐ヤ簡'{}',鍙戠敓Lock4j寮傚父.", requestURI, e);
         return R.fail(HttpStatus.HTTP_UNAVAILABLE, "涓氬姟澶勭悊涓紝璇风◢鍚庡啀璇�...");
     }
 
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
index 0664755..38e12c3 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
@@ -2,7 +2,6 @@
 
 import cn.dev33.satoken.dao.SaTokenDao;
 import cn.dev33.satoken.util.SaFoxUtil;
-import cn.hutool.core.lang.Console;
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
 import org.dromara.common.redis.utils.RedisUtils;
@@ -54,7 +53,7 @@
         } else {
             RedisUtils.setCacheObject(key, value, Duration.ofSeconds(timeout));
         }
-        CAFFEINE.put(key, value);
+        CAFFEINE.invalidate(key);
     }
 
     /**
@@ -64,7 +63,7 @@
     public void update(String key, String value) {
         if (RedisUtils.hasKey(key)) {
             RedisUtils.setCacheObject(key, value, true);
-            CAFFEINE.put(key, value);
+            CAFFEINE.invalidate(key);
         }
     }
 
@@ -117,7 +116,7 @@
         } else {
             RedisUtils.setCacheObject(key, object, Duration.ofSeconds(timeout));
         }
-        CAFFEINE.put(key, object);
+        CAFFEINE.invalidate(key);
     }
 
     /**
@@ -127,7 +126,7 @@
     public void updateObject(String key, Object object) {
         if (RedisUtils.hasKey(key)) {
             RedisUtils.setCacheObject(key, object, true);
-            CAFFEINE.put(key, object);
+            CAFFEINE.invalidate(key);
         }
     }
 
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
index 1e88407..3a39cc2 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
@@ -1,6 +1,7 @@
 package org.dromara.common.sms.config;
 
 import org.dromara.common.sms.core.dao.PlusSmsDao;
+import org.dromara.common.sms.handler.SmsExceptionHandler;
 import org.dromara.sms4j.api.dao.SmsDao;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
@@ -21,4 +22,12 @@
         return new PlusSmsDao();
     }
 
+    /**
+     * 寮傚父澶勭悊鍣�
+     */
+    @Bean
+    public SmsExceptionHandler smsExceptionHandler() {
+        return new SmsExceptionHandler();
+    }
+
 }
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/handler/SmsExceptionHandler.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/handler/SmsExceptionHandler.java
new file mode 100644
index 0000000..2c619a3
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/handler/SmsExceptionHandler.java
@@ -0,0 +1,30 @@
+package org.dromara.common.sms.handler;
+
+import cn.hutool.http.HttpStatus;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.R;
+import org.dromara.sms4j.comm.exception.SmsBlendException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * SMS寮傚父澶勭悊鍣�
+ *
+ * @author AprilWind
+ */
+@Slf4j
+@RestControllerAdvice
+public class SmsExceptionHandler {
+
+    /**
+     * sms寮傚父
+     */
+    @ExceptionHandler(SmsBlendException.class)
+    public R<Void> handleSmsBlendException(SmsBlendException e, HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        log.error("璇锋眰鍦板潃'{}',鍙戠敓sms鐭俊寮傚父.", requestURI, e);
+        return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "鐭俊鍙戦�佸け璐ワ紝璇风◢鍚庡啀璇�...");
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
index 3fb99c5..07302bc 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
@@ -35,7 +35,7 @@
 
     @ConditionalOnBean(MybatisPlusConfig.class)
     @AutoConfiguration(after = {MybatisPlusConfig.class})
-    static class MybatisPlusConfigation {
+    static class MybatisPlusConfiguration {
 
         /**
          * 澶氱鎴锋彃浠�
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
index e830c19..9d087e1 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
@@ -1,6 +1,5 @@
 package org.dromara.common.tenant.helper;
 
-import cn.dev33.satoken.context.SaHolder;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.convert.Convert;
 import com.alibaba.ttl.TransmittableThreadLocal;
@@ -79,22 +78,28 @@
         }
     }
 
+    public static void setDynamic(String tenantId) {
+        setDynamic(tenantId, false);
+    }
+
     /**
      * 璁剧疆鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
      * <p>
      * 濡傛灉涓烘湭鐧诲綍鐘舵�佷笅 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
+     *
+     * @param tenantId 绉熸埛id
+     * @param global   鏄惁鍏ㄥ眬鐢熸晥
      */
-    public static void setDynamic(String tenantId) {
+    public static void setDynamic(String tenantId, boolean global) {
         if (!isEnable()) {
             return;
         }
-        if (!isLogin()) {
+        if (!isLogin() || !global) {
             TEMP_DYNAMIC_TENANT.set(tenantId);
             return;
         }
         String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
         RedisUtils.setCacheObject(cacheKey, tenantId);
-        SaHolder.getStorage().set(cacheKey, tenantId);
     }
 
     /**
@@ -109,13 +114,13 @@
         if (!isLogin()) {
             return TEMP_DYNAMIC_TENANT.get();
         }
-        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
-        String tenantId = (String) SaHolder.getStorage().get(cacheKey);
+        // 濡傛灉绾跨▼鍐呮湁鍊� 浼樺厛杩斿洖
+        String tenantId = TEMP_DYNAMIC_TENANT.get();
         if (StringUtils.isNotBlank(tenantId)) {
             return tenantId;
         }
+        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
         tenantId = RedisUtils.getCacheObject(cacheKey);
-        SaHolder.getStorage().set(cacheKey, tenantId);
         return tenantId;
     }
 
@@ -130,9 +135,9 @@
             TEMP_DYNAMIC_TENANT.remove();
             return;
         }
+        TEMP_DYNAMIC_TENANT.remove();
         String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
         RedisUtils.deleteObject(cacheKey);
-        SaHolder.getStorage().delete(cacheKey);
     }
 
     /**
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
index 30d109e..ef5cfc9 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/config/WebSocketConfig.java
@@ -27,17 +27,20 @@
 
     @Bean
     public WebSocketConfigurer webSocketConfigurer(HandshakeInterceptor handshakeInterceptor,
-                                                   WebSocketHandler webSocketHandler,
-                                                   WebSocketProperties webSocketProperties) {
+                                                   WebSocketHandler webSocketHandler, WebSocketProperties webSocketProperties) {
+        // 濡傛灉WebSocket鐨勮矾寰勪负绌猴紝鍒欒缃粯璁よ矾寰勪负 "/websocket"
         if (StrUtil.isBlank(webSocketProperties.getPath())) {
             webSocketProperties.setPath("/websocket");
         }
 
+        // 濡傛灉鍏佽璺ㄥ煙璁块棶鐨勫湴鍧�涓虹┖锛屽垯璁剧疆涓� "*"锛岃〃绀哄厑璁告墍鏈夋潵婧愮殑璺ㄥ煙璇锋眰
         if (StrUtil.isBlank(webSocketProperties.getAllowedOrigins())) {
             webSocketProperties.setAllowedOrigins("*");
         }
 
+        // 杩斿洖涓�涓猈ebSocketConfigurer瀵硅薄锛岀敤浜庨厤缃甒ebSocket
         return registry -> registry
+            // 娣诲姞WebSocket澶勭悊绋嬪簭鍜屾嫤鎴櫒鍒版寚瀹氳矾寰勶紝璁剧疆鍏佽鐨勮法鍩熸潵婧�
             .addHandler(webSocketHandler, webSocketProperties.getPath())
             .addInterceptors(handshakeInterceptor)
             .setAllowedOrigins(webSocketProperties.getAllowedOrigins());
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
index 54eb447..e243279 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/constant/WebSocketConstants.java
@@ -6,6 +6,7 @@
  * @author zendwang
  */
 public interface WebSocketConstants {
+
     /**
      * websocketSession涓殑鍙傛暟鐨刱ey
      */
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
index a53583f..759aece 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/handler/PlusWebSocketHandler.java
@@ -31,33 +31,42 @@
     }
 
     /**
-     * 澶勭悊鍙戦�佹潵鐨勬枃鏈秷鎭�
+     * 澶勭悊鎺ユ敹鍒扮殑鏂囨湰娑堟伅
      *
-     * @param session
-     * @param message
-     * @throws Exception
+     * @param session WebSocket浼氳瘽
+     * @param message 鎺ユ敹鍒扮殑鏂囨湰娑堟伅
+     * @throws Exception 澶勭悊娑堟伅杩囩▼涓彲鑳芥姏鍑虹殑寮傚父
      */
     @Override
     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+        // 浠嶹ebSocket浼氳瘽涓幏鍙栫櫥褰曠敤鎴蜂俊鎭�
         LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
-        List<Long> userIds = List.of(loginUser.getUserId());
+
+        // 鍒涘缓WebSocket娑堟伅DTO瀵硅薄
         WebSocketMessageDto webSocketMessageDto = new WebSocketMessageDto();
-        webSocketMessageDto.setSessionKeys(userIds);
+        webSocketMessageDto.setSessionKeys(List.of(loginUser.getUserId()));
         webSocketMessageDto.setMessage(message.getPayload());
         WebSocketUtils.publishMessage(webSocketMessageDto);
     }
 
+    /**
+     * 澶勭悊鎺ユ敹鍒扮殑浜岃繘鍒舵秷鎭�
+     *
+     * @param session WebSocket浼氳瘽
+     * @param message 鎺ユ敹鍒扮殑浜岃繘鍒舵秷鎭�
+     * @throws Exception 澶勭悊娑堟伅杩囩▼涓彲鑳芥姏鍑虹殑寮傚父
+     */
     @Override
     protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
         super.handleBinaryMessage(session, message);
     }
 
     /**
-     * 蹇冭烦鐩戞祴鐨勫洖澶�
+     * 澶勭悊鎺ユ敹鍒扮殑Pong娑堟伅锛堝績璺崇洃娴嬶級
      *
-     * @param session
-     * @param message
-     * @throws Exception
+     * @param session WebSocket浼氳瘽
+     * @param message 鎺ユ敹鍒扮殑Pong娑堟伅
+     * @throws Exception 澶勭悊娑堟伅杩囩▼涓彲鑳芥姏鍑虹殑寮傚父
      */
     @Override
     protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
@@ -65,11 +74,11 @@
     }
 
     /**
-     * 杩炴帴鍑洪敊鏃�
+     * 澶勭悊WebSocket浼犺緭閿欒
      *
-     * @param session
-     * @param exception
-     * @throws Exception
+     * @param session   WebSocket浼氳瘽
+     * @param exception 鍙戠敓鐨勫紓甯�
+     * @throws Exception 澶勭悊杩囩▼涓彲鑳芥姏鍑虹殑寮傚父
      */
     @Override
     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
@@ -77,10 +86,10 @@
     }
 
     /**
-     * 杩炴帴鍏抽棴鍚�
+     * 鍦╓ebSocket杩炴帴鍏抽棴鍚庢墽琛屾竻鐞嗘搷浣�
      *
-     * @param session
-     * @param status
+     * @param session WebSocket浼氳瘽
+     * @param status  鍏抽棴鐘舵�佷俊鎭�
      */
     @Override
     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
@@ -90,9 +99,9 @@
     }
 
     /**
-     * 鏄惁鏀寔鍒嗙墖娑堟伅
+     * 鎸囩ず澶勭悊绋嬪簭鏄惁鏀寔鎺ユ敹閮ㄥ垎娑堟伅
      *
-     * @return
+     * @return 濡傛灉鏀寔鎺ユ敹閮ㄥ垎娑堟伅锛屽垯杩斿洖true锛涘惁鍒欒繑鍥瀎alse
      */
     @Override
     public boolean supportsPartialMessages() {
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
index de8c5a7..368801c 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/holder/WebSocketSessionHolder.java
@@ -18,24 +18,52 @@
 
     private static final Map<Long, WebSocketSession> USER_SESSION_MAP = new ConcurrentHashMap<>();
 
+    /**
+     * 灏哤ebSocket浼氳瘽娣诲姞鍒扮敤鎴蜂細璇滿ap涓�
+     *
+     * @param sessionKey 浼氳瘽閿紝鐢ㄤ簬妫�绱細璇�
+     * @param session    瑕佹坊鍔犵殑WebSocket浼氳瘽
+     */
     public static void addSession(Long sessionKey, WebSocketSession session) {
         USER_SESSION_MAP.put(sessionKey, session);
     }
 
+    /**
+     * 浠庣敤鎴蜂細璇滿ap涓Щ闄ゆ寚瀹氫細璇濋敭瀵瑰簲鐨刉ebSocket浼氳瘽
+     *
+     * @param sessionKey 瑕佺Щ闄ょ殑浼氳瘽閿�
+     */
     public static void removeSession(Long sessionKey) {
         if (USER_SESSION_MAP.containsKey(sessionKey)) {
             USER_SESSION_MAP.remove(sessionKey);
         }
     }
 
+    /**
+     * 鏍规嵁浼氳瘽閿粠鐢ㄦ埛浼氳瘽Map涓幏鍙朩ebSocket浼氳瘽
+     *
+     * @param sessionKey 瑕佽幏鍙栫殑浼氳瘽閿�
+     * @return 涓庣粰瀹氫細璇濋敭瀵瑰簲鐨刉ebSocket浼氳瘽锛屽鏋滀笉瀛樺湪鍒欒繑鍥瀗ull
+     */
     public static WebSocketSession getSessions(Long sessionKey) {
         return USER_SESSION_MAP.get(sessionKey);
     }
 
+    /**
+     * 鑾峰彇瀛樺偍鍦ㄧ敤鎴蜂細璇滿ap涓墍鏈塛ebSocket浼氳瘽鐨勪細璇濋敭闆嗗悎
+     *
+     * @return 鎵�鏈塛ebSocket浼氳瘽鐨勪細璇濋敭闆嗗悎
+     */
     public static Set<Long> getSessionsAll() {
         return USER_SESSION_MAP.keySet();
     }
 
+    /**
+     * 妫�鏌ョ粰瀹氱殑浼氳瘽閿槸鍚﹀瓨鍦ㄤ簬鐢ㄦ埛浼氳瘽Map涓�
+     *
+     * @param sessionKey 瑕佹鏌ョ殑浼氳瘽閿�
+     * @return 濡傛灉瀛樺湪瀵瑰簲鐨勪細璇濋敭锛屽垯杩斿洖true锛涘惁鍒欒繑鍥瀎alse
+     */
     public static Boolean existSession(Long sessionKey) {
         return USER_SESSION_MAP.containsKey(sessionKey);
     }
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
index 1dc4120..0abbbd3 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/interceptor/PlusWebSocketInterceptor.java
@@ -1,8 +1,8 @@
 package org.dromara.common.websocket.interceptor;
 
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.model.LoginUser;
 import org.dromara.common.satoken.utils.LoginHelper;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.server.ServerHttpRequest;
 import org.springframework.http.server.ServerHttpResponse;
 import org.springframework.web.socket.WebSocketHandler;
@@ -21,13 +21,13 @@
 public class PlusWebSocketInterceptor implements HandshakeInterceptor {
 
     /**
-     * 鎻℃墜鍓�
+     * WebSocket鎻℃墜涔嬪墠鎵ц鐨勫墠缃鐞嗘柟娉�
      *
-     * @param request    request
-     * @param response   response
-     * @param wsHandler  wsHandler
-     * @param attributes attributes
-     * @return 鏄惁鎻℃墜鎴愬姛
+     * @param request    WebSocket鎻℃墜璇锋眰
+     * @param response   WebSocket鎻℃墜鍝嶅簲
+     * @param wsHandler  WebSocket澶勭悊绋嬪簭
+     * @param attributes 涓嶹ebSocket浼氳瘽鍏宠仈鐨勫睘鎬�
+     * @return 濡傛灉鍏佽鎻℃墜缁х画杩涜锛屽垯杩斿洖true锛涘惁鍒欒繑鍥瀎alse
      */
     @Override
     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) {
@@ -37,15 +37,16 @@
     }
 
     /**
-     * 鎻℃墜鍚�
+     * WebSocket鎻℃墜鎴愬姛鍚庢墽琛岀殑鍚庣疆澶勭悊鏂规硶
      *
-     * @param request   request
-     * @param response  response
-     * @param wsHandler wsHandler
-     * @param exception 寮傚父
+     * @param request   WebSocket鎻℃墜璇锋眰
+     * @param response  WebSocket鎻℃墜鍝嶅簲
+     * @param wsHandler WebSocket澶勭悊绋嬪簭
+     * @param exception 鎻℃墜杩囩▼涓彲鑳藉嚭鐜扮殑寮傚父
      */
     @Override
     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
-
+        // 鍦ㄨ繖涓柟娉曚腑鍙互鎵ц涓�浜涙彙鎵嬫垚鍔熷悗鐨勫悗缁鐞嗛�昏緫锛屾瘮濡傝褰曟棩蹇楁垨鑰呭叾浠栨搷浣�
     }
+
 }
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
index 01528d0..0ad39af 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/listener/WebSocketTopicListener.java
@@ -1,9 +1,9 @@
 package org.dromara.common.websocket.listener;
 
 import cn.hutool.core.collection.CollUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.websocket.holder.WebSocketSessionHolder;
 import org.dromara.common.websocket.utils.WebSocketUtils;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.core.Ordered;
@@ -16,8 +16,15 @@
 @Slf4j
 public class WebSocketTopicListener implements ApplicationRunner, Ordered {
 
+    /**
+     * 鍦⊿pring Boot搴旂敤绋嬪簭鍚姩鏃跺垵濮嬪寲WebSocket涓婚璁㈤槄鐩戝惉鍣�
+     *
+     * @param args 搴旂敤绋嬪簭鍙傛暟
+     * @throws Exception 鍒濆鍖栬繃绋嬩腑鍙兘鎶涘嚭鐨勫紓甯�
+     */
     @Override
     public void run(ApplicationArguments args) throws Exception {
+        // 璁㈤槄WebSocket娑堟伅
         WebSocketUtils.subscribeMessage((message) -> {
             log.info("WebSocket涓婚璁㈤槄鏀跺埌娑堟伅session keys={} message={}", message.getSessionKeys(), message.getMessage());
             // 濡傛灉key涓嶄负绌哄氨鎸夌収key鍙戞秷鎭� 濡傛灉涓虹┖灏辩兢鍙�
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
index 086599c..afe76e0 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
@@ -29,10 +29,10 @@
 public class WebSocketUtils {
 
     /**
-     * 鍙戦�佹秷鎭�
+     * 鍚戞寚瀹氱殑WebSocket浼氳瘽鍙戦�佹秷鎭�
      *
-     * @param sessionKey session涓婚敭 涓�鑸负鐢ㄦ埛id
-     * @param message    娑堟伅鏂囨湰
+     * @param sessionKey 瑕佸彂閫佹秷鎭殑鐢ㄦ埛id
+     * @param message    瑕佸彂閫佺殑娑堟伅鍐呭
      */
     public static void sendMessage(Long sessionKey, String message) {
         WebSocketSession session = WebSocketSessionHolder.getSessions(sessionKey);
@@ -40,18 +40,18 @@
     }
 
     /**
-     * 璁㈤槄娑堟伅
+     * 璁㈤槄WebSocket娑堟伅涓婚锛屽苟鎻愪緵涓�涓秷璐硅�呭嚱鏁版潵澶勭悊鎺ユ敹鍒扮殑娑堟伅
      *
-     * @param consumer 鑷畾涔夊鐞�
+     * @param consumer 澶勭悊WebSocket娑堟伅鐨勬秷璐硅�呭嚱鏁�
      */
     public static void subscribeMessage(Consumer<WebSocketMessageDto> consumer) {
         RedisUtils.subscribe(WEB_SOCKET_TOPIC, WebSocketMessageDto.class, consumer);
     }
 
     /**
-     * 鍙戝竷璁㈤槄鐨勬秷鎭�
+     * 鍙戝竷WebSocket璁㈤槄娑堟伅
      *
-     * @param webSocketMessage 娑堟伅瀵硅薄
+     * @param webSocketMessage 瑕佸彂甯冪殑WebSocket娑堟伅瀵硅薄
      */
     public static void publishMessage(WebSocketMessageDto webSocketMessage) {
         List<Long> unsentSessionKeys = new ArrayList<>();
@@ -76,9 +76,9 @@
     }
 
     /**
-     * 鍙戝竷璁㈤槄鐨勬秷鎭�(缇ゅ彂)
+     * 鍚戞墍鏈夌殑WebSocket浼氳瘽鍙戝竷璁㈤槄鐨勬秷鎭�(缇ゅ彂)
      *
-     * @param message 娑堟伅鍐呭
+     * @param message 瑕佸彂甯冪殑娑堟伅鍐呭
      */
     public static void publishAll(String message) {
         WebSocketMessageDto broadcastMessage = new WebSocketMessageDto();
@@ -88,14 +88,31 @@
         });
     }
 
+    /**
+     * 鍚戞寚瀹氱殑WebSocket浼氳瘽鍙戦�丳ong娑堟伅
+     *
+     * @param session 瑕佸彂閫丳ong娑堟伅鐨刉ebSocket浼氳瘽
+     */
     public static void sendPongMessage(WebSocketSession session) {
         sendMessage(session, new PongMessage());
     }
 
+    /**
+     * 鍚戞寚瀹氱殑WebSocket浼氳瘽鍙戦�佹枃鏈秷鎭�
+     *
+     * @param session WebSocket浼氳瘽
+     * @param message 瑕佸彂閫佺殑鏂囨湰娑堟伅鍐呭
+     */
     public static void sendMessage(WebSocketSession session, String message) {
         sendMessage(session, new TextMessage(message));
     }
 
+    /**
+     * 鍚戞寚瀹氱殑WebSocket浼氳瘽鍙戦�乄ebSocket娑堟伅瀵硅薄
+     *
+     * @param session WebSocket浼氳瘽
+     * @param message 瑕佸彂閫佺殑WebSocket娑堟伅瀵硅薄
+     */
     private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
         if (session == null || !session.isOpen()) {
             log.warn("[send] session浼氳瘽宸茬粡鍏抽棴");
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
index 0cdb675..559e1d5 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
@@ -3,10 +3,12 @@
 import cn.dev33.satoken.secure.BCrypt;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.io.FileUtil;
+import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.file.MimeTypeUtils;
 import org.dromara.common.encrypt.annotation.ApiEncrypt;
+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.satoken.utils.LoginHelper;
@@ -19,9 +21,7 @@
 import org.dromara.system.domain.vo.SysOssVo;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.service.ISysOssService;
-import org.dromara.system.service.ISysRoleService;
 import org.dromara.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
 import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -57,12 +57,14 @@
     }
 
     /**
-     * 淇敼鐢ㄦ埛
+     * 淇敼鐢ㄦ埛淇℃伅
      */
+    @RepeatSubmit
     @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
     @PutMapping
-    public R<Void> updateProfile(@RequestBody SysUserProfileBo profile) {
+    public R<Void> updateProfile(@Validated @RequestBody SysUserProfileBo profile) {
         SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
+        user.setUserId(LoginHelper.getUserId());
         String username = LoginHelper.getUsername();
         if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
             return R.fail("淇敼鐢ㄦ埛'" + username + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
@@ -70,7 +72,6 @@
         if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
             return R.fail("淇敼鐢ㄦ埛'" + username + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
         }
-        user.setUserId(LoginHelper.getUserId());
         if (userService.updateUserProfile(user) > 0) {
             return R.ok();
         }
@@ -82,6 +83,7 @@
      *
      * @param bo 鏂版棫瀵嗙爜
      */
+    @RepeatSubmit
     @ApiEncrypt
     @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
     @PutMapping("/updatePwd")
@@ -106,6 +108,7 @@
      *
      * @param avatarfile 鐢ㄦ埛澶村儚
      */
+    @RepeatSubmit
     @Log(title = "鐢ㄦ埛澶村儚", businessType = BusinessType.UPDATE)
     @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
     public R<AvatarVo> avatar(@RequestPart("avatarfile") MultipartFile avatarfile) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
index 053ff17..60be68a 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
@@ -144,7 +144,7 @@
     @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
     @GetMapping("/dynamic/{tenantId}")
     public R<Void> dynamicTenant(@NotBlank(message = "绉熸埛ID涓嶈兘涓虹┖") @PathVariable String tenantId) {
-        TenantHelper.setDynamic(tenantId);
+        TenantHelper.setDynamic(tenantId, true);
         return R.ok();
     }
 
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java
index fb4c605..846dd79 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserProfileBo.java
@@ -1,14 +1,16 @@
 package org.dromara.system.domain.bo;
 
-import org.dromara.common.core.xss.Xss;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.sensitive.annotation.Sensitive;
-import org.dromara.common.sensitive.core.SensitiveStrategy;
 import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.Pattern;
 import jakarta.validation.constraints.Size;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.dromara.common.core.constant.RegexConstants;
+import org.dromara.common.core.xss.Xss;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.sensitive.annotation.Sensitive;
+import org.dromara.common.sensitive.core.SensitiveStrategy;
 
 /**
  * 涓汉淇℃伅涓氬姟澶勭悊
@@ -20,11 +22,6 @@
 @NoArgsConstructor
 @EqualsAndHashCode(callSuper = true)
 public class SysUserProfileBo extends BaseEntity {
-
-    /**
-     * 鐢ㄦ埛ID
-     */
-    private Long userId;
 
     /**
      * 鐢ㄦ埛鏄电О
@@ -44,6 +41,7 @@
     /**
      * 鎵嬫満鍙风爜
      */
+    @Pattern(regexp = RegexConstants.MOBILE, message = "鎵嬫満鍙锋牸寮忎笉姝g‘")
     @Sensitive(strategy = SensitiveStrategy.PHONE)
     private String phonenumber;
 
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
index 93f1cc7..d8f481d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
@@ -37,6 +37,7 @@
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.mapper.*;
 import org.dromara.system.service.ISysUserService;
+import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -338,6 +339,7 @@
      * @return 缁撴灉
      */
     @Override
+    @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId")
     @Transactional(rollbackFor = Exception.class)
     public int updateUser(SysUserBo user) {
         // 鏂板鐢ㄦ埛涓庤鑹茬鐞�
@@ -386,6 +388,7 @@
      * @param user 鐢ㄦ埛淇℃伅
      * @return 缁撴灉
      */
+    @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId")
     @Override
     public int updateUserProfile(SysUserBo user) {
         return baseMapper.update(null,
@@ -636,7 +639,10 @@
         if (CollUtil.isEmpty(userIds)) {
             return List.of();
         }
-        List<SysUserVo> list = this.selectUserByIds(userIds, null);
+        List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>()
+            .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName)
+            .eq(SysUser::getStatus, UserConstants.USER_NORMAL)
+            .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds));
         return BeanUtil.copyToList(list, UserDTO.class);
     }
 
diff --git a/ruoyi-modules/ruoyi-workflow/README.md b/ruoyi-modules/ruoyi-workflow/README.md
new file mode 100644
index 0000000..59096b1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/README.md
@@ -0,0 +1,3 @@
+# 宸ヤ綔娴佽鏄�
+
+宸ヤ綔娴佺洰鍓嶅湪鏈垚鐔熼樁娈� 鍚庣画浠嶄細缁忓巻閲嶆瀯 鐢氳嚦閲嶅啓(鐢熶骇浣跨敤鍓嶈鎱庨噸鑰冭檻鍚庣画鏄惁瑕佹洿鏂扮淮鎶�)
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-workflow/pom.xml b/ruoyi-modules/ruoyi-workflow/pom.xml
index 0217098..9ed4097 100644
--- a/ruoyi-modules/ruoyi-workflow/pom.xml
+++ b/ruoyi-modules/ruoyi-workflow/pom.xml
@@ -109,7 +109,10 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-common-tenant</artifactId>
         </dependency>
-
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-security</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/annotation/FlowListenerAnnotation.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/annotation/FlowListenerAnnotation.java
deleted file mode 100644
index 5ea262d..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/annotation/FlowListenerAnnotation.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.dromara.workflow.annotation;
-
-
-import java.lang.annotation.*;
-
-/**
- * 娴佺▼浠诲姟鐩戝惉娉ㄨВ
- *
- * @author may
- * @date 2023-12-27
- */
-@Target({ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-@Inherited
-public @interface FlowListenerAnnotation {
-
-    /**
-     * 娴佺▼瀹氫箟key
-     */
-    String processDefinitionKey();
-
-    /**
-     * 鑺傜偣id
-     */
-    String taskDefId() default "";
-}
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 df27d3c..c3fcafa 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
@@ -71,9 +71,9 @@
     String ZIP = "ZIP";
 
     /**
-     * 娴佺▼瀹炰緥瀵硅薄
+     * 涓氬姟涓庢祦绋嬪疄渚嬪叧鑱斿璞�
      */
-    String PROCESS_INSTANCE_VO = "processInstanceVo";
+    String BUSINESS_INSTANCE_DTO = "businessInstanceDTO";
 
     /**
      * 娴佺▼瀹氫箟閰嶇疆
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
index 142386b..931b9f5 100644
--- 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
@@ -58,33 +58,33 @@
     }
 
     /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥�
+     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥�
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
-    @GetMapping("/getHistoryImage/{processInstanceId}")
-    public R<String> getHistoryImage(@NotBlank(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String processInstanceId) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryImage(processInstanceId));
+    @GetMapping("/getHistoryImage/{businessKey}")
+    public R<String> getHistoryImage(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
+        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryImage(businessKey));
     }
 
     /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
+     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
-    @GetMapping("/getHistoryList/{processInstanceId}")
-    public R<Map<String, Object>> getHistoryList(@NotBlank(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String processInstanceId) {
-        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryList(processInstanceId));
+    @GetMapping("/getHistoryList/{businessKey}")
+    public R<Map<String, Object>> getHistoryList(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
+        return R.ok("鎿嶄綔鎴愬姛", actProcessInstanceService.getHistoryList(businessKey));
     }
 
     /**
      * 鑾峰彇瀹℃壒璁板綍
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
-    @GetMapping("/getHistoryRecord/{processInstanceId}")
-    public R<List<ActHistoryInfoVo>> getHistoryRecord(@NotBlank(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String processInstanceId) {
-        return R.ok(actProcessInstanceService.getHistoryRecord(processInstanceId));
+    @GetMapping("/getHistoryRecord/{businessKey}")
+    public R<List<ActHistoryInfoVo>> getHistoryRecord(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
+        return R.ok(actProcessInstanceService.getHistoryRecord(businessKey));
     }
 
     /**
@@ -102,37 +102,37 @@
     /**
      * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
+     * @param businessKeys 涓氬姟id
      */
     @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.DELETE)
     @RepeatSubmit()
-    @DeleteMapping("/deleteRunAndHisInstance/{processInstanceIds}")
-    public R<Void> deleteRunAndHisInstance(@NotNull(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String[] processInstanceIds) {
-        return toAjax(actProcessInstanceService.deleteRunAndHisInstance(Arrays.asList(processInstanceIds)));
+    @DeleteMapping("/deleteRunAndHisInstance/{businessKeys}")
+    public R<Void> deleteRunAndHisInstance(@NotNull(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String[] businessKeys) {
+        return toAjax(actProcessInstanceService.deleteRunAndHisInstance(Arrays.asList(businessKeys)));
     }
 
     /**
      * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
+     * @param businessKeys 涓氬姟id
      */
     @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.DELETE)
     @RepeatSubmit()
-    @DeleteMapping("/deleteFinishAndHisInstance/{processInstanceIds}")
-    public R<Void> deleteFinishAndHisInstance(@NotNull(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String[] processInstanceIds) {
-        return toAjax(actProcessInstanceService.deleteFinishAndHisInstance(Arrays.asList(processInstanceIds)));
+    @DeleteMapping("/deleteFinishAndHisInstance/{businessKeys}")
+    public R<Void> deleteFinishAndHisInstance(@NotNull(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String[] businessKeys) {
+        return toAjax(actProcessInstanceService.deleteFinishAndHisInstance(Arrays.asList(businessKeys)));
     }
 
     /**
      * 鎾ら攢娴佺▼鐢宠
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
     @Log(title = "娴佺▼瀹炰緥绠$悊", businessType = BusinessType.INSERT)
     @RepeatSubmit()
-    @PostMapping("/cancelProcessApply/{processInstanceId}")
-    public R<Void> cancelProcessApply(@NotBlank(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖") @PathVariable String processInstanceId) {
-        return toAjax(actProcessInstanceService.cancelProcessApply(processInstanceId));
+    @PostMapping("/cancelProcessApply/{businessKey}")
+    public R<Void> cancelProcessApply(@NotBlank(message = "涓氬姟id涓嶈兘涓虹┖") @PathVariable String businessKey) {
+        return toAjax(actProcessInstanceService.cancelProcessApply(businessKey));
     }
 
     /**
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
index 7fc9b95..75f9d9b 100644
--- 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
@@ -225,7 +225,7 @@
     @RepeatSubmit()
     @PostMapping("/backProcess")
     public R<String> backProcess(@Validated({AddGroup.class}) @RequestBody BackProcessBo backProcessBo) {
-        return R.ok(actTaskService.backProcess(backProcessBo));
+        return R.ok("鎿嶄綔鎴愬姛", actTaskService.backProcess(backProcessBo));
     }
 
     /**
@@ -279,7 +279,7 @@
      */
     @GetMapping("/getTaskUserIdsByAddMultiInstance/{taskId}")
     public R<String> getTaskUserIdsByAddMultiInstance(@PathVariable String taskId) {
-        return R.ok(actTaskService.getTaskUserIdsByAddMultiInstance(taskId));
+        return R.ok("鎿嶄綔鎴愬姛", actTaskService.getTaskUserIdsByAddMultiInstance(taskId));
     }
 
     /**
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/TestLeaveController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/TestLeaveController.java
index 17b6755..e1c246f 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/TestLeaveController.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/TestLeaveController.java
@@ -32,7 +32,7 @@
 @Validated
 @RequiredArgsConstructor
 @RestController
-@RequestMapping("/demo/leave")
+@RequestMapping("/workflow/leave")
 public class TestLeaveController extends BaseController {
 
     private final ITestLeaveService testLeaveService;
@@ -40,7 +40,7 @@
     /**
      * 鏌ヨ璇峰亣鍒楄〃
      */
-    @SaCheckPermission("demo:leave:list")
+    @SaCheckPermission("workflow:leave:list")
     @GetMapping("/list")
     public TableDataInfo<TestLeaveVo> list(TestLeaveBo bo, PageQuery pageQuery) {
         return testLeaveService.queryPageList(bo, pageQuery);
@@ -49,7 +49,7 @@
     /**
      * 瀵煎嚭璇峰亣鍒楄〃
      */
-    @SaCheckPermission("demo:leave:export")
+    @SaCheckPermission("workflow:leave:export")
     @Log(title = "璇峰亣", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     public void export(TestLeaveBo bo, HttpServletResponse response) {
@@ -62,7 +62,7 @@
      *
      * @param id 涓婚敭
      */
-    @SaCheckPermission("demo:leave:query")
+    @SaCheckPermission("workflow:leave:query")
     @GetMapping("/{id}")
     public R<TestLeaveVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
                                   @PathVariable Long id) {
@@ -72,7 +72,7 @@
     /**
      * 鏂板璇峰亣
      */
-    @SaCheckPermission("demo:leave:add")
+    @SaCheckPermission("workflow:leave:add")
     @Log(title = "璇峰亣", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
@@ -83,7 +83,7 @@
     /**
      * 淇敼璇峰亣
      */
-    @SaCheckPermission("demo:leave:edit")
+    @SaCheckPermission("workflow:leave:edit")
     @Log(title = "璇峰亣", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -96,7 +96,7 @@
      *
      * @param ids 涓婚敭涓�
      */
-    @SaCheckPermission("demo:leave:remove")
+    @SaCheckPermission("workflow:leave:remove")
     @Log(title = "璇峰亣", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/TestLeave.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/TestLeave.java
index 0e26467..7d42a9b 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/TestLeave.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/TestLeave.java
@@ -54,5 +54,10 @@
      */
     private String remark;
 
+    /**
+     * 鐘舵��
+     */
+    private String status;
+
 
 }
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
index 35d5652..41e51c2 100644
--- 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
@@ -19,10 +19,10 @@
     private static final long serialVersionUID = 1L;
 
     /**
-     * 娴佺▼瀹炰緥id
+     * 涓氬姟id
      */
-    @NotBlank(message = "娴佺▼瀹炰緥id涓嶈兘涓虹┖", groups = {AddGroup.class})
-    private String processInstanceId;
+    @NotBlank(message = "涓氬姟id涓嶈兘涓虹┖", groups = {AddGroup.class})
+    private String businessKey;
 
     /**
      * 浣滃簾鍘熷洜
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 e71be59..877e981 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
@@ -71,5 +71,10 @@
      */
     private String remark;
 
+    /**
+     * 鐘舵��
+     */
+    private String status;
+
 
 }
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
index 31b9722..e4c1142 100644
--- 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
@@ -37,6 +37,10 @@
      */
     private String processInstanceId;
     /**
+     * 鐗堟湰
+     */
+    private Integer version;
+    /**
      * 寮�濮嬫椂闂�
      */
     private Date startTime;
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TestLeaveVo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TestLeaveVo.java
index c62a356..47886d7 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TestLeaveVo.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/TestLeaveVo.java
@@ -62,9 +62,9 @@
     private String remark;
 
     /**
-     * 娴佺▼瀹炰緥瀵硅薄
+     * 鐘舵��
      */
-    private ProcessInstanceVo processInstanceVo;
-
+    @ExcelProperty(value = "鐘舵��")
+    private String status;
 
 }
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
new file mode 100644
index 0000000..17dba8c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/handler/FlowProcessEventHandler.java
@@ -0,0 +1,48 @@
+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 keyNode     娴佺▼瀹氫箟key涓庢祦绋嬭妭鐐规爣璇�(鎷兼帴鏂瑰紡锛氭祦绋嬪畾涔塳ey_娴佺▼鑺傜偣)
+     * @param taskId      浠诲姟id
+     * @param businessKey 涓氬姟id
+     */
+    public void processTaskHandler(String keyNode, String taskId, String businessKey) {
+        ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
+        processTaskEvent.setKeyNode(keyNode);
+        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
index 7685423..61c9388 100644
--- 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
@@ -8,7 +8,6 @@
 import org.flowable.job.service.JobHandler;
 import org.flowable.job.service.impl.persistence.entity.JobEntity;
 import org.flowable.task.api.Task;
-import org.flowable.task.api.TaskQuery;
 import org.flowable.variable.api.delegate.VariableScope;
 
 /**
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowEventStrategy.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowEventStrategy.java
deleted file mode 100644
index 9da5776..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowEventStrategy.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.dromara.workflow.flowable.strategy;
-
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.workflow.annotation.FlowListenerAnnotation;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.stereotype.Component;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 娴佺▼浠诲姟鐩戝惉绛栫暐
- *
- * @author may
- * @date 2023-12-27
- */
-@Component
-public class FlowEventStrategy implements BeanPostProcessor {
-
-    private final Map<String, FlowTaskEventHandler> flowTaskEventHandlers = new HashMap<>();
-    private final Map<String, FlowProcessEventHandler> flowProcessEventHandlers = new HashMap<>();
-
-    @Override
-    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
-        if (bean instanceof FlowTaskEventHandler) {
-            FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class);
-            if (null != annotation) {
-                if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isNotBlank(annotation.taskDefId())) {
-                    String id = annotation.processDefinitionKey() + "_" + annotation.taskDefId();
-                    if (!flowTaskEventHandlers.containsKey(id)) {
-                        flowTaskEventHandlers.put(id, (FlowTaskEventHandler) bean);
-                    }
-                }
-            }
-        }
-        if (bean instanceof FlowProcessEventHandler) {
-            FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class);
-            if (null != annotation) {
-                if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isBlank(annotation.taskDefId())) {
-                    if (!flowProcessEventHandlers.containsKey(annotation.processDefinitionKey())) {
-                        flowProcessEventHandlers.put(annotation.processDefinitionKey(), (FlowProcessEventHandler) bean);
-                    }
-                }
-            }
-        }
-        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
-    }
-
-    /**
-     * 鑾峰彇鍙墽琛宐ean
-     *
-     * @param key key
-     */
-    public FlowTaskEventHandler getTaskHandler(String key) {
-        if (!flowTaskEventHandlers.containsKey(key)) {
-            return null;
-        }
-        return flowTaskEventHandlers.get(key);
-    }
-
-    /**
-     * 鑾峰彇鍙墽琛宐ean
-     *
-     * @param key key
-     */
-    public FlowProcessEventHandler getProcessHandler(String key) {
-        if (!flowProcessEventHandlers.containsKey(key)) {
-            return null;
-        }
-        return flowProcessEventHandlers.get(key);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowProcessEventHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowProcessEventHandler.java
deleted file mode 100644
index 4af2c47..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowProcessEventHandler.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.dromara.workflow.flowable.strategy;
-
-
-/**
- * 娴佺▼鐩戝惉
- *
- * @author may
- * @date 2023-12-27
- */
-public interface FlowProcessEventHandler {
-
-    /**
-     * 鎵ц鍔炵悊浠诲姟鐩戝惉
-     *
-     * @param businessKey 涓氬姟id
-     * @param status      鐘舵��
-     * @param submit      褰撲负true鏃朵负鐢宠浜鸿妭鐐瑰姙鐞�
-     */
-    void handleProcess(String businessKey, String status, boolean submit);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowTaskEventHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowTaskEventHandler.java
deleted file mode 100644
index b338900..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/flowable/strategy/FlowTaskEventHandler.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.dromara.workflow.flowable.strategy;
-
-
-/**
- * 娴佺▼浠诲姟鐩戝惉
- *
- * @author may
- * @date 2023-12-27
- */
-public interface FlowTaskEventHandler {
-
-    /**
-     * 鎵ц鍔炵悊浠诲姟鐩戝惉
-     *
-     * @param taskId      浠诲姟ID
-     * @param businessKey 涓氬姟id
-     */
-    void handleTask(String taskId, String businessKey);
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomProcessHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomProcessHandler.java
deleted file mode 100644
index 29886d8..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomProcessHandler.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.dromara.workflow.listener;
-
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.workflow.annotation.FlowListenerAnnotation;
-import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
-import org.springframework.stereotype.Component;
-
-/**
- * 鑷畾涔夌洃鍚祴璇�
- *
- * @author may
- * @date 2023-12-27
- */
-@Slf4j
-@Component
-@FlowListenerAnnotation(processDefinitionKey = "leave1")
-public class TestCustomProcessHandler implements FlowProcessEventHandler {
-
-
-    /**
-     * 鎵ц鍔炵悊浠诲姟鐩戝惉
-     *
-     * @param businessKey 涓氬姟id
-     * @param status      鐘舵��
-     * @param submit      褰撲负true鏃朵负鐢宠浜鸿妭鐐瑰姙鐞�
-     */
-    @Override
-    public void handleProcess(String businessKey, String status, boolean submit) {
-        log.info("涓氬姟ID:" + businessKey + ",鐘舵��:" + status);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomTaskHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomTaskHandler.java
deleted file mode 100644
index d85286d..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestCustomTaskHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.dromara.workflow.listener;
-
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.workflow.annotation.FlowListenerAnnotation;
-import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler;
-import org.springframework.stereotype.Component;
-
-/**
- * 鑷畾涔夌洃鍚祴璇�
- *
- * @author may
- * @date 2023-12-27
- */
-@Slf4j
-@Component
-@FlowListenerAnnotation(processDefinitionKey = "leave1", taskDefId = "Activity_14633hx")
-public class TestCustomTaskHandler implements FlowTaskEventHandler {
-
-    @Override
-    public void handleTask(String taskId, String businessKey) {
-        log.info("浠诲姟ID:" + taskId + ",涓氬姟ID:" + businessKey);
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveExecutionListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveExecutionListener.java
deleted file mode 100644
index 11f844e..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveExecutionListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.dromara.workflow.listener;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.workflow.utils.QueryUtils;
-import org.flowable.engine.TaskService;
-import org.flowable.engine.delegate.DelegateExecution;
-import org.flowable.engine.delegate.ExecutionListener;
-import org.flowable.task.api.Task;
-import org.springframework.stereotype.Component;
-
-/**
- * 娴佺▼瀹炰緥鐩戝惉娴嬭瘯
- *
- * @author may
- * @date 2023-12-12
- */
-@Slf4j
-@RequiredArgsConstructor
-@Component("testLeaveExecutionListener")
-public class TestLeaveExecutionListener implements ExecutionListener {
-
-    @Override
-    public void notify(DelegateExecution execution) {
-        Task task = QueryUtils.taskQuery().executionId(execution.getId()).singleResult();
-        log.info("鎵ц鐩戝惉銆�" + task.getName() + "銆�");
-    }
-}
diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveTaskListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveTaskListener.java
deleted file mode 100644
index 5c62417..0000000
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/TestLeaveTaskListener.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.dromara.workflow.listener;
-
-import lombok.extern.slf4j.Slf4j;
-import org.flowable.task.service.delegate.DelegateTask;
-import org.flowable.task.service.delegate.TaskListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 娴佺▼浠诲姟鐩戝惉娴嬭瘯
- *
- * @author may
- * @date 2023-12-12
- */
-@Slf4j
-@Component("testLeaveTaskListener")
-public class TestLeaveTaskListener implements TaskListener {
-    @Override
-    public void notify(DelegateTask delegateTask) {
-        log.info("鎵ц鐩戝惉銆�" + delegateTask.getName() + "銆�");
-    }
-}
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
index 2fc0c1a..ca3b6fb 100644
--- 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
@@ -20,18 +20,18 @@
     /**
      * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥�
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 娴佺▼瀹炰緥id
      * @return 缁撴灉
      */
-    String getHistoryImage(String processInstanceId);
+    String getHistoryImage(String businessKey);
 
     /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
+     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      * @return 缁撴灉
      */
-    Map<String, Object> getHistoryList(String processInstanceId);
+    Map<String, Object> getHistoryList(String businessKey);
 
     /**
      * 鍒嗛〉鏌ヨ姝e湪杩愯鐨勬祦绋嬪疄渚�
@@ -54,10 +54,10 @@
     /**
      * 鑾峰彇瀹℃壒璁板綍
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      * @return 缁撴灉
      */
-    List<ActHistoryInfoVo> getHistoryRecord(String processInstanceId);
+    List<ActHistoryInfoVo> getHistoryRecord(String businessKey);
 
     /**
      * 浣滃簾娴佺▼瀹炰緥锛屼笉浼氬垹闄ゅ巻鍙茶褰�(鍒犻櫎杩愯涓殑瀹炰緥)
@@ -70,34 +70,26 @@
     /**
      * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
-     * @return 缁撴灉
-     */
-    boolean deleteRunAndHisInstance(List<String> processInstanceIds);
-
-    /**
-     * 鎸夌収涓氬姟id鍒犻櫎 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
      * @param businessKeys 涓氬姟id
      * @return 缁撴灉
      */
-    boolean deleteRunAndHisInstanceByBusinessKeys(List<String> businessKeys);
+    boolean deleteRunAndHisInstance(List<String> businessKeys);
 
     /**
      * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
+     * @param businessKeys 涓氬姟id
      * @return 缁撴灉
      */
-    boolean deleteFinishAndHisInstance(List<String> processInstanceIds);
+    boolean deleteFinishAndHisInstance(List<String> businessKeys);
 
     /**
      * 鎾ら攢娴佺▼鐢宠
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      * @return 缁撴灉
      */
-    boolean cancelProcessApply(String processInstanceId);
+    boolean cancelProcessApply(String businessKey);
 
     /**
      * 鍒嗛〉鏌ヨ褰撳墠鐧诲綍浜哄崟鎹�
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
index b64c79e..dafd059 100644
--- 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
@@ -16,7 +16,7 @@
 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.BusinessStatusEnum;
+import org.dromara.common.core.enums.BusinessStatusEnum;
 import org.dromara.workflow.common.enums.TaskStatusEnum;
 import org.dromara.workflow.domain.ActHiProcinst;
 import org.dromara.workflow.domain.bo.ProcessInstanceBo;
@@ -26,8 +26,7 @@
 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.strategy.FlowEventStrategy;
-import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
+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;
@@ -75,9 +74,9 @@
     private final TaskService taskService;
     private final IActHiProcinstService actHiProcinstService;
     private final ManagementService managementService;
-    private final FlowEventStrategy flowEventStrategy;
     private final IWfTaskBackNodeService wfTaskBackNodeService;
     private final IWfNodeConfigService wfNodeConfigService;
+    private final FlowProcessEventHandler flowProcessEventHandler;
 
     @Value("${flowable.activity-font-name}")
     private String activityFontName;
@@ -184,28 +183,28 @@
     }
 
     /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥�
+     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥�
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
     @SneakyThrows
     @Override
-    public String getHistoryImage(String processInstanceId) {
+    public String getHistoryImage(String businessKey) {
         String processDefinitionId;
         // 鑾峰彇褰撳墠鐨勬祦绋嬪疄渚�
-        ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId).singleResult();
+        ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey).singleResult();
         // 濡傛灉娴佺▼宸茬粡缁撴潫锛屽垯寰楀埌缁撴潫鑺傜偣
         if (Objects.isNull(processInstance)) {
-            HistoricProcessInstance pi = QueryUtils.hisInstanceQuery(processInstanceId).singleResult();
+            HistoricProcessInstance pi = QueryUtils.hisInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();
             processDefinitionId = pi.getProcessDefinitionId();
         } else {
             // 鏍规嵁娴佺▼瀹炰緥ID鑾峰緱褰撳墠澶勪簬娲诲姩鐘舵�佺殑ActivityId鍚堥泦
-            ProcessInstance pi = QueryUtils.instanceQuery(processInstanceId).singleResult();
+            ProcessInstance pi = QueryUtils.instanceQuery(processInstance.getProcessInstanceId()).singleResult();
             processDefinitionId = pi.getProcessDefinitionId();
         }
 
         // 鑾峰緱娲诲姩鐨勮妭鐐�
-        List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
+        List<HistoricActivityInstance> highLightedFlowList = QueryUtils.hisActivityInstanceQuery(processInstance.getProcessInstanceId()).orderByHistoricActivityInstanceStartTime().asc().list();
 
         List<String> highLightedFlows = new ArrayList<>();
         List<String> highLightedNodes = new ArrayList<>();
@@ -240,15 +239,16 @@
     }
 
     /**
-     * 閫氳繃娴佺▼瀹炰緥id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
+     * 閫氳繃涓氬姟id鑾峰彇鍘嗗彶娴佺▼鍥捐繍琛屼腑锛屽巻鍙茬瓑鑺傜偣
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
     @Override
-    public Map<String, Object> getHistoryList(String processInstanceId) {
+    public Map<String, Object> getHistoryList(String businessKey) {
         Map<String, Object> map = new HashMap<>();
         List<Map<String, Object>> taskList = new ArrayList<>();
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult();
+        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
+        String processInstanceId = historicProcessInstance.getId();
         StringBuilder xml = new StringBuilder();
         ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
         // 鑾峰彇鑺傜偣
@@ -280,7 +280,7 @@
             }
         }
         map.put("taskList", taskList);
-        List<ActHistoryInfoVo> historyTaskList = getHistoryTaskList(processInstanceId);
+        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));
@@ -292,8 +292,9 @@
      * 鑾峰彇鍘嗗彶浠诲姟鑺傜偣淇℃伅
      *
      * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param version           鐗堟湰
      */
-    private List<ActHistoryInfoVo> getHistoryTaskList(String processInstanceId) {
+    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());
@@ -305,27 +306,48 @@
             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();
-            BeanUtils.copyProperties(entry.getValue().get(0), historyInfoVo);
-            actHistoryInfoVoList.stream().filter(e -> e.getTaskDefinitionKey().equals(entry.getKey()) && e.getEndTime() == null).findFirst()
-                .ifPresent(e -> {
-                    historyInfoVo.setStatus("寰呭鐞�");
-                    historyInfoVo.setStartTime(e.getStartTime());
-                    historyInfoVo.setEndTime(null);
-                    historyInfoVo.setRunDuration(null);
-                    if (ObjectUtil.isEmpty(e.getAssignee())) {
-                        ParticipantVo participantVo = WorkflowUtils.getCurrentTaskParticipant(e.getId());
+            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());
                         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());
+                            if (ObjectUtil.isNotEmpty(participantVo) && CollUtil.isNotEmpty(participantVo.getCandidate())) {
+                                historyInfoVo.setAssignee(StreamUtils.join(participantVo.getCandidate(), Convert::toStr));
+                            }
+                        }
+                    });
+
+            }
             historyInfoVoList.add(historyInfoVo);
+
         }
         return historyInfoVoList;
     }
@@ -333,13 +355,15 @@
     /**
      * 鑾峰彇瀹℃壒璁板綍
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
     @Override
-    public List<ActHistoryInfoVo> getHistoryRecord(String processInstanceId) {
+    public List<ActHistoryInfoVo> getHistoryRecord(String businessKey) {
         // 鏌ヨ浠诲姟鍔炵悊璁板綍
-        List<HistoricTaskInstance> list = QueryUtils.hisTaskInstanceQuery(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list();
+        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);
         //闄勪欢
@@ -440,7 +464,8 @@
     @Transactional(rollbackFor = Exception.class)
     public boolean deleteRunInstance(ProcessInvalidBo processInvalidBo) {
         try {
-            List<Task> list = QueryUtils.taskQuery(processInvalidBo.getProcessInstanceId()).list();
+            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()));
@@ -452,14 +477,13 @@
             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(processInvalidBo.getProcessInstanceId()).singleResult();
+            HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult();
             BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus());
-            runtimeService.updateBusinessStatus(processInvalidBo.getProcessInstanceId(), BusinessStatusEnum.INVALID.getStatus());
-            runtimeService.deleteProcessInstance(processInvalidBo.getProcessInstanceId(), deleteReason);
-            FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey());
-            if (processHandler != null) {
-                processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false);
-            }
+            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) {
             e.printStackTrace();
@@ -470,40 +494,11 @@
     /**
      * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public boolean deleteRunAndHisInstance(List<String> processInstanceIds) {
-        try {
-            // 1.鍒犻櫎杩愯涓祦绋嬪疄渚�
-            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) {
-            e.printStackTrace();
-            throw new ServiceException(e.getMessage());
-        }
-    }
-
-    /**
-     * 鎸夌収涓氬姟id鍒犻櫎 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
-     *
      * @param businessKeys 涓氬姟id
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean deleteRunAndHisInstanceByBusinessKeys(List<String> businessKeys) {
+    public boolean deleteRunAndHisInstance(List<String> businessKeys) {
         try {
             // 1.鍒犻櫎杩愯涓祦绋嬪疄渚�
             List<ActHiProcinst> actHiProcinsts = actHiProcinstService.selectByBusinessKeyIn(businessKeys);
@@ -534,12 +529,18 @@
     /**
      * 宸插畬鎴愮殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
      *
-     * @param processInstanceIds 娴佺▼瀹炰緥id
+     * @param businessKeys 涓氬姟id
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean deleteFinishAndHisInstance(List<String> processInstanceIds) {
+    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;
@@ -552,13 +553,13 @@
     /**
      * 鎾ら攢娴佺▼鐢宠
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
+     * @param businessKey 涓氬姟id
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean cancelProcessApply(String processInstanceId) {
+    public boolean cancelProcessApply(String businessKey) {
         try {
-            ProcessInstance processInstance = QueryUtils.instanceQuery(processInstanceId)
+            ProcessInstance processInstance = QueryUtils.businessKeyQuery(businessKey)
                 .startedBy(String.valueOf(LoginHelper.getUserId())).singleResult();
             if (ObjectUtil.isNull(processInstance)) {
                 throw new ServiceException("鎮ㄤ笉鏄祦绋嬪彂璧蜂汉,鎾ら攢澶辫触!");
@@ -566,13 +567,14 @@
             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().finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0);
+            HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery(processInstanceId).finished().orderByHistoricTaskInstanceEndTime().asc().list().get(0);
             List<String> nodeIds = StreamUtils.toList(taskList, Task::getTaskDefinitionKey);
             runtimeService.createChangeActivityStateBuilder()
                 .processInstanceId(processInstanceId)
@@ -588,10 +590,9 @@
                 managementService.executeCommand(deleteExecutionCmd);
             }
             runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.CANCEL.getStatus());
-            FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
-            if (processHandler != null) {
-                processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false);
-            }
+            //娴佺▼浣滃簾鐩戝惉
+            flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
+                processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false);
             return true;
         } catch (Exception e) {
             e.printStackTrace();
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
index 1a4866d..523a77c 100644
--- 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
@@ -18,16 +18,14 @@
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.workflow.common.constant.FlowConstant;
-import org.dromara.workflow.common.enums.BusinessStatusEnum;
+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.strategy.FlowEventStrategy;
-import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
-import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler;
+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;
@@ -75,13 +73,13 @@
     private final HistoryService historyService;
     private final IdentityService identityService;
     private final ManagementService managementService;
-    private final FlowEventStrategy flowEventStrategy;
     private final ActTaskMapper actTaskMapper;
     private final IWfTaskBackNodeService wfTaskBackNodeService;
     private final ActHiTaskinstMapper actHiTaskinstMapper;
     private final IWfNodeConfigService wfNodeConfigService;
     private final IWfDefinitionConfigService wfDefinitionConfigService;
     private final UserService userService;
+    private final FlowProcessEventHandler flowProcessEventHandler;
 
     /**
      * 鍚姩浠诲姟
@@ -159,15 +157,8 @@
     @Transactional(rollbackFor = Exception.class)
     public boolean completeTask(CompleteTaskBo completeTaskBo) {
         try {
-            List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
             String userId = String.valueOf(LoginHelper.getUserId());
-            TaskQuery taskQuery = QueryUtils.taskQuery();
-            taskQuery.taskId(completeTaskBo.getTaskId()).taskCandidateOrAssigned(userId);
-            if (CollUtil.isNotEmpty(roles)) {
-                List<String> groupIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId()));
-                taskQuery.taskCandidateGroupIn(groupIds);
-            }
-            Task task = taskQuery.singleResult();
+            Task task = WorkflowUtils.getTaskByCurrentUser(completeTaskBo.getTaskId());
             if (task == null) {
                 throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
             }
@@ -186,19 +177,15 @@
             //闄勪欢涓婁紶
             AttachmentCmd attachmentCmd = new AttachmentCmd(completeTaskBo.getFileId(), task.getId(), task.getProcessInstanceId());
             managementService.executeCommand(attachmentCmd);
-            FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
-            String businessStatus = WorkflowUtils.getBusinessStatus(task.getProcessInstanceId());
+            String businessStatus = WorkflowUtils.getBusinessStatus(processInstance.getBusinessKey());
+            //娴佺▼鎻愪氦鐩戝惉
             if (BusinessStatusEnum.DRAFT.getStatus().equals(businessStatus) || BusinessStatusEnum.BACK.getStatus().equals(businessStatus) || BusinessStatusEnum.CANCEL.getStatus().equals(businessStatus)) {
-                if (processHandler != null) {
-                    processHandler.handleProcess(processInstance.getBusinessKey(), businessStatus, true);
-                }
+                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(), businessStatus, true);
             }
             runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.WAITING.getStatus());
-            String key = processInstance.getProcessDefinitionKey() + "_" + task.getTaskDefinitionKey();
-            FlowTaskEventHandler taskHandler = flowEventStrategy.getTaskHandler(key);
-            if (taskHandler != null) {
-                taskHandler.handleTask(task.getId(), processInstance.getBusinessKey());
-            }
+            //鍔炵悊鐩戝惉
+            String keyNode = processInstance.getProcessDefinitionKey() + "_" + task.getTaskDefinitionKey();
+            flowProcessEventHandler.processTaskHandler(keyNode, task.getId(), processInstance.getBusinessKey());
             //鍔炵悊鎰忚
             taskService.addComment(completeTaskBo.getTaskId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isBlank(completeTaskBo.getMessage()) ? "鍚屾剰" : completeTaskBo.getMessage());
             //鍔炵悊浠诲姟
@@ -214,9 +201,8 @@
             if (pi == null) {
                 UpdateBusinessStatusCmd updateBusinessStatusCmd = new UpdateBusinessStatusCmd(task.getProcessInstanceId(), BusinessStatusEnum.FINISH.getStatus());
                 managementService.executeCommand(updateBusinessStatusCmd);
-                if (processHandler != null) {
-                    processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.FINISH.getStatus(), false);
-                }
+                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(),
+                    BusinessStatusEnum.FINISH.getStatus(), false);
             } else {
                 List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
                 for (Task t : list) {
@@ -470,8 +456,8 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean delegateTask(DelegateBo delegateBo) {
-        TaskQuery query = QueryUtils.taskQuery();
-        TaskEntity task = (TaskEntity) query.taskId(delegateBo.getTaskId()).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())).singleResult();
+        Task task = WorkflowUtils.getTaskByCurrentUser(delegateBo.getTaskId());
+
         if (ObjectUtil.isEmpty(task)) {
             throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
         }
@@ -527,10 +513,9 @@
                 runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.TERMINATION.getStatus());
                 runtimeService.deleteProcessInstance(task.getProcessInstanceId(), StrUtil.EMPTY);
             }
-            FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey());
-            if (processHandler != null) {
-                processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false);
-            }
+            //娴佺▼缁堟鐩戝惉
+            flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(),
+                historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false);
             return true;
         } catch (Exception e) {
             throw new ServiceException(e.getMessage());
@@ -544,7 +529,7 @@
      */
     @Override
     public boolean transferTask(TransmitBo transmitBo) {
-        Task task = QueryUtils.taskQuery().taskId(transmitBo.getTaskId()).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId())).singleResult();
+        Task task = WorkflowUtils.getTaskByCurrentUser(transmitBo.getTaskId());
         if (ObjectUtil.isEmpty(task)) {
             throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
         }
@@ -669,9 +654,9 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public String backProcess(BackProcessBo backProcessBo) {
-        TaskQuery query = QueryUtils.taskQuery();
         String userId = String.valueOf(LoginHelper.getUserId());
-        Task task = query.taskId(backProcessBo.getTaskId()).taskCandidateOrAssigned(userId).singleResult();
+        Task task = WorkflowUtils.getTaskByCurrentUser(backProcessBo.getTaskId());
+
         if (ObjectUtil.isEmpty(task)) {
             throw new ServiceException(FlowConstant.MESSAGE_CURRENT_TASK_IS_NULL);
         }
@@ -705,7 +690,9 @@
             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()));
-                actHiTaskinstMapper.deleteBatchIds(StreamUtils.toList(tasks, Task::getId));
+                if (CollUtil.isNotEmpty(tasks)) {
+                    actHiTaskinstMapper.deleteBatchIds(StreamUtils.toList(tasks, Task::getId));
+                }
             }
 
 
@@ -728,10 +715,8 @@
             WfTaskBackNode wfTaskBackNode = wfTaskBackNodeService.getListByInstanceIdAndNodeId(task.getProcessInstanceId(), backProcessBo.getTargetActivityId());
             if (ObjectUtil.isNotNull(wfTaskBackNode) && wfTaskBackNode.getOrderNo() == 0) {
                 runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.BACK.getStatus());
-                FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
-                if (processHandler != null) {
-                    processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false);
-                }
+                flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
+                    processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false);
             }
             //鍒犻櫎椹冲洖鍚庣殑娴佺▼鑺傜偣
             wfTaskBackNodeService.deleteBackTaskNode(processInstanceId, backProcessBo.getTargetActivityId());
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 bee5627..b938a98 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,10 +1,14 @@
 package org.dromara.workflow.service.impl;
 
-import cn.hutool.core.collection.CollUtil;
 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.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;
@@ -15,9 +19,8 @@
 import org.dromara.workflow.domain.bo.TestLeaveBo;
 import org.dromara.workflow.domain.vo.TestLeaveVo;
 import org.dromara.workflow.mapper.TestLeaveMapper;
-import org.dromara.workflow.service.IActProcessInstanceService;
 import org.dromara.workflow.service.ITestLeaveService;
-import org.dromara.workflow.utils.WorkflowUtils;
+import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -32,19 +35,18 @@
  */
 @RequiredArgsConstructor
 @Service
+@Slf4j
 public class TestLeaveServiceImpl implements ITestLeaveService {
 
     private final TestLeaveMapper baseMapper;
-    private final IActProcessInstanceService actProcessInstanceService;
+    private final WorkflowService workflowService;
 
     /**
      * 鏌ヨ璇峰亣
      */
     @Override
     public TestLeaveVo queryById(Long id) {
-        TestLeaveVo testLeaveVo = baseMapper.selectVoById(id);
-        WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(id));
-        return testLeaveVo;
+        return baseMapper.selectVoById(id);
     }
 
     /**
@@ -54,13 +56,7 @@
     public TableDataInfo<TestLeaveVo> queryPageList(TestLeaveBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<TestLeave> lqw = buildQueryWrapper(bo);
         Page<TestLeaveVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        TableDataInfo<TestLeaveVo> build = TableDataInfo.build(result);
-        List<TestLeaveVo> rows = build.getRows();
-        if (CollUtil.isNotEmpty(rows)) {
-            List<String> ids = StreamUtils.toList(rows, e -> String.valueOf(e.getId()));
-            WorkflowUtils.setProcessInstanceListVo(rows, ids, "id");
-        }
-        return build;
+        return TableDataInfo.build(result);
     }
 
     /**
@@ -87,13 +83,14 @@
     @Override
     public TestLeaveVo insertByBo(TestLeaveBo bo) {
         TestLeave add = MapstructUtils.convert(bo, TestLeave.class);
+        if (StringUtils.isBlank(add.getStatus())) {
+            add.setStatus(BusinessStatusEnum.DRAFT.getStatus());
+        }
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());
         }
-        TestLeaveVo testLeaveVo = MapstructUtils.convert(add, TestLeaveVo.class);
-        WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(add.getId()));
-        return testLeaveVo;
+        return MapstructUtils.convert(add, TestLeaveVo.class);
     }
 
     /**
@@ -103,9 +100,7 @@
     public TestLeaveVo updateByBo(TestLeaveBo bo) {
         TestLeave update = MapstructUtils.convert(bo, TestLeave.class);
         baseMapper.updateById(update);
-        TestLeaveVo testLeaveVo = MapstructUtils.convert(update, TestLeaveVo.class);
-        WorkflowUtils.setProcessInstanceVo(testLeaveVo, String.valueOf(update.getId()));
-        return testLeaveVo;
+        return MapstructUtils.convert(update, TestLeaveVo.class);
     }
 
     /**
@@ -115,7 +110,38 @@
     @Transactional(rollbackFor = Exception.class)
     public Boolean deleteWithValidByIds(Collection<Long> ids) {
         List<String> idList = StreamUtils.toList(ids, String::valueOf);
-        actProcessInstanceService.deleteRunAndHisInstanceByBusinessKeys(idList);
+        workflowService.deleteRunAndHisInstance(idList);
         return baseMapper.deleteBatchIds(ids) > 0;
     }
+
+    /**
+     * 鎬讳綋娴佺▼鐩戝惉(渚嬪: 鎻愪氦 閫�鍥� 鎾ら攢 缁堟 浣滃簾绛�)
+     *
+     * @param processEvent 鍙傛暟
+     */
+    @EventListener(condition = "#processEvent.key=='leave1'")
+    public void processHandler(ProcessEvent processEvent) {
+        log.info("褰撳墠浠诲姟鎵ц浜唟}", processEvent.toString());
+        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessKey()));
+        testLeave.setStatus(processEvent.getStatus());
+        if (processEvent.isSubmit()) {
+            testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
+        }
+        baseMapper.updateById(testLeave);
+    }
+
+    /**
+     * 鎵ц鍔炵悊浠诲姟鐩戝惉
+     *
+     * @param processTaskEvent 鍙傛暟
+     */
+    @EventListener(condition = "#processTaskEvent.keyNode=='leave1_Activity_14633hx'")
+    public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
+        log.info("褰撳墠浠诲姟鎵ц浜唟}", processTaskEvent.toString());
+        TestLeave testLeave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessKey()));
+        testLeave.setStatus(BusinessStatusEnum.WAITING.getStatus());
+        baseMapper.updateById(testLeave);
+    }
+
+
 }
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
new file mode 100644
index 0000000..11f6ef1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java
@@ -0,0 +1,119 @@
+package org.dromara.workflow.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.RequiredArgsConstructor;
+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.RuntimeService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 閫氱敤 宸ヤ綔娴佹湇鍔″疄鐜�
+ *
+ * @author may
+ */
+@RequiredArgsConstructor
+@Service
+public class WorkflowServiceImpl implements WorkflowService {
+
+    private final IActProcessInstanceService iActProcessInstanceService;
+    private final RuntimeService runtimeService;
+    private final IActHiProcinstService iActHiProcinstService;
+    /**
+     * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅
+     *
+     * @param businessKeys 涓氬姟id
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean deleteRunAndHisInstance(List<String> businessKeys) {
+        return iActProcessInstanceService.deleteRunAndHisInstance(businessKeys);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠娴佺▼鐘舵��
+     *
+     * @param taskId 浠诲姟id
+     */
+    @Override
+    public String getBusinessStatusByTaskId(String taskId) {
+        return WorkflowUtils.getBusinessStatusByTaskId(taskId);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠娴佺▼鐘舵��
+     *
+     * @param businessKey 涓氬姟id
+     */
+    @Override
+    public String getBusinessStatus(String businessKey) {
+        return WorkflowUtils.getBusinessStatus(businessKey);
+    }
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
+     *
+     * @param taskId       浠诲姟id
+     * @param variableName 鍙橀噺鍚嶇О
+     * @param value        鍙橀噺鍊�
+     */
+    @Override
+    public void setVariable(String taskId, String variableName, Object value) {
+        runtimeService.setVariable(taskId, variableName, value);
+    }
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺(鍏ㄥ眬鍙橀噺)
+     *
+     * @param taskId    浠诲姟id
+     * @param variables 娴佺▼鍙橀噺
+     */
+    @Override
+    public void setVariables(String taskId, Map<String, Object> variables) {
+        runtimeService.setVariables(taskId, variables);
+    }
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
+     *
+     * @param taskId       浠诲姟id
+     * @param variableName 鍙橀噺鍚嶇О
+     * @param value        鍙橀噺鍊�
+     */
+    @Override
+    public void setVariableLocal(String taskId, String variableName, Object value) {
+        runtimeService.setVariableLocal(taskId, variableName, value);
+    }
+
+    /**
+     * 璁剧疆娴佺▼鍙橀噺(鏈湴鍙橀噺,闈炲叏灞�鍙橀噺)
+     *
+     * @param taskId    浠诲姟id
+     * @param variables 娴佺▼鍙橀噺
+     */
+    @Override
+    public void setVariablesLocal(String taskId, Map<String, Object> variables) {
+        runtimeService.setVariablesLocal(taskId, variables);
+    }
+
+    /**
+     * 鎸夌収涓氬姟id鏌ヨ娴佺▼瀹炰緥id
+     *
+     * @param businessKey 涓氬姟id
+     * @return 缁撴灉
+     */
+    @Override
+    public String getInstanceIdByBusinessKey(String businessKey) {
+        ActHiProcinst actHiProcinst = iActHiProcinstService.selectByBusinessKey(businessKey);
+        if (actHiProcinst == null) {
+            return StrUtil.EMPTY;
+        }
+        return actHiProcinst.getId();
+    }
+}
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
index 944d9d7..df928dc 100644
--- 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
@@ -12,6 +12,7 @@
 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;
@@ -75,6 +76,10 @@
         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()) {
@@ -85,6 +90,10 @@
 
     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) {
@@ -101,6 +110,10 @@
 
     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) {
@@ -145,9 +158,11 @@
         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.getProcessInstanceId());
+        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 f475f19..385bd23 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
@@ -1,34 +1,30 @@
 package org.dromara.workflow.utils;
 
-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.update.LambdaUpdateWrapper;
 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.core.utils.reflect.ReflectUtils;
 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.workflow.common.enums.BusinessStatusEnum;
 import org.dromara.workflow.common.enums.MessageTypeEnum;
 import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.domain.ActHiProcinst;
 import org.dromara.workflow.domain.ActHiTaskinst;
 import org.dromara.workflow.domain.vo.MultiInstanceVo;
 import org.dromara.workflow.domain.vo.ParticipantVo;
-import org.dromara.workflow.domain.vo.ProcessInstanceVo;
 import org.dromara.workflow.flowable.cmd.UpdateHiTaskInstCmd;
 import org.dromara.workflow.mapper.ActHiTaskinstMapper;
-import org.dromara.workflow.service.IActHiProcinstService;
 import org.flowable.bpmn.model.BpmnModel;
 import org.flowable.bpmn.model.FlowNode;
 import org.flowable.common.engine.api.delegate.Expression;
@@ -38,12 +34,11 @@
 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 java.util.*;
-
-import static org.dromara.workflow.common.constant.FlowConstant.PROCESS_INSTANCE_VO;
 
 /**
  * 宸ヤ綔娴佸伐鍏�
@@ -54,8 +49,6 @@
 public class WorkflowUtils {
 
     private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class);
-    private static final UserService USER_SERVICE = SpringUtils.getBean(UserService.class);
-    private static final IActHiProcinstService ACT_HI_PROCINST_SERVICE = SpringUtils.getBean(IActHiProcinstService.class);
     private static final ActHiTaskinstMapper ACT_HI_TASKINST_MAPPER = SpringUtils.getBean(ActHiTaskinstMapper.class);
 
     /**
@@ -133,6 +126,7 @@
      * @param taskId 浠诲姟id
      */
     public static ParticipantVo getCurrentTaskParticipant(String taskId) {
+        UserService userService = SpringUtils.getBean(UserService.class);
         ParticipantVo participantVo = new ParticipantVo();
         List<HistoricIdentityLink> linksForTask = PROCESS_ENGINE.getHistoryService().getHistoricIdentityLinksForTask(taskId);
         Task task = QueryUtils.taskQuery().taskId(taskId).singleResult();
@@ -140,10 +134,10 @@
             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 = USER_SERVICE.selectUserIdsByRoleIds(groupIds);
+                List<Long> userIds = userService.selectUserIdsByRoleIds(groupIds);
                 if (CollUtil.isNotEmpty(userIds)) {
                     participantVo.setGroupIds(groupIds);
-                    List<UserDTO> userList = USER_SERVICE.selectListByIds(userIds);
+                    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);
@@ -162,7 +156,7 @@
 
                     }
                 }
-                List<UserDTO> userList = USER_SERVICE.selectListByIds(userIdList);
+                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);
@@ -225,70 +219,11 @@
     /**
      * 鑾峰彇褰撳墠娴佺▼鐘舵��
      *
-     * @param processInstanceId 娴佺▼瀹炰緥id
-     */
-    public static String getBusinessStatus(String processInstanceId) {
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(processInstanceId).singleResult();
-        return historicProcessInstance.getBusinessStatus();
-    }
-
-    /**
-     * 璁剧疆娴佺▼瀹炰緥瀵硅薄
-     *
-     * @param obj         涓氬姟瀵硅薄
      * @param businessKey 涓氬姟id
      */
-    public static void setProcessInstanceVo(Object obj, String businessKey) {
-        if (StringUtils.isBlank(businessKey) || obj == null) {
-            return;
-        }
-        ActHiProcinst actHiProcinst = ACT_HI_PROCINST_SERVICE.selectByBusinessKey(businessKey);
-        if (actHiProcinst == null) {
-            ProcessInstanceVo processInstanceVo = new ProcessInstanceVo();
-            processInstanceVo.setBusinessStatus(BusinessStatusEnum.DRAFT.getStatus());
-            ReflectUtils.invokeSetter(obj, PROCESS_INSTANCE_VO, processInstanceVo);
-            return;
-        }
-        ProcessInstanceVo processInstanceVo = BeanUtil.toBean(actHiProcinst, ProcessInstanceVo.class);
-        processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstanceVo.getBusinessStatus()));
-        ReflectUtils.invokeSetter(obj, PROCESS_INSTANCE_VO, processInstanceVo);
-    }
-
-    /**
-     * 璁剧疆娴佺▼瀹炰緥瀵硅薄
-     *
-     * @param obj       涓氬姟瀵硅薄
-     * @param idList    涓氬姟id
-     * @param fieldName 涓婚敭灞炴�у悕绉�
-     */
-    public static void setProcessInstanceListVo(Object obj, List<String> idList, String fieldName) {
-        if (CollUtil.isEmpty(idList) || obj == null) {
-            return;
-        }
-        List<ActHiProcinst> actHiProcinstList = ACT_HI_PROCINST_SERVICE.selectByBusinessKeyIn(idList);
-        if (obj instanceof Collection<?> collection) {
-            for (Object o : collection) {
-                String fieldValue = ReflectUtils.invokeGetter(o, fieldName).toString();
-                if (CollUtil.isEmpty(actHiProcinstList)) {
-                    ProcessInstanceVo processInstanceVo = new ProcessInstanceVo();
-                    processInstanceVo.setBusinessStatus(BusinessStatusEnum.DRAFT.getStatus());
-                    processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstanceVo.getBusinessStatus()));
-                    ReflectUtils.invokeSetter(o, PROCESS_INSTANCE_VO, processInstanceVo);
-                } else {
-                    ActHiProcinst actHiProcinst = actHiProcinstList.stream().filter(e -> e.getBusinessKey().equals(fieldValue)).findFirst().orElse(null);
-                    if (ObjectUtil.isNotEmpty(actHiProcinst)) {
-                        ProcessInstanceVo processInstanceVo = BeanUtil.toBean(actHiProcinst, ProcessInstanceVo.class);
-                        processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstanceVo.getBusinessStatus()));
-                        ReflectUtils.invokeSetter(o, PROCESS_INSTANCE_VO, processInstanceVo);
-                    } else {
-                        ProcessInstanceVo processInstanceVo = new ProcessInstanceVo();
-                        processInstanceVo.setBusinessStatus(BusinessStatusEnum.DRAFT.getStatus());
-                        processInstanceVo.setBusinessStatusName(BusinessStatusEnum.findByStatus(processInstanceVo.getBusinessStatus()));
-                        ReflectUtils.invokeSetter(o, PROCESS_INSTANCE_VO, processInstanceVo);
-                    }
-                }
-            }
-        }
+    public static String getBusinessStatus(String businessKey) {
+        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
+        return historicProcessInstance.getBusinessStatus();
     }
 
     /**
@@ -300,6 +235,7 @@
      * @param message     娑堟伅鍐呭锛屼负绌哄垯鍙戦�侀粯璁ら厤缃殑娑堟伅鍐呭
      */
     public static void sendMessage(List<Task> list, String name, List<String> messageType, String message) {
+        UserService userService = SpringUtils.getBean(UserService.class);
         Set<Long> userIds = new HashSet<>();
         if (StringUtils.isBlank(message)) {
             message = "鏈夋柊鐨勩��" + name + "銆戝崟鎹凡缁忔彁浜よ嚦鎮ㄧ殑寰呭姙锛岃鎮ㄥ強鏃跺鐞嗐��";
@@ -307,7 +243,7 @@
         for (Task t : list) {
             ParticipantVo taskParticipant = WorkflowUtils.getCurrentTaskParticipant(t.getId());
             if (CollUtil.isNotEmpty(taskParticipant.getGroupIds())) {
-                List<Long> userIdList = USER_SERVICE.selectUserIdsByRoleIds(taskParticipant.getGroupIds());
+                List<Long> userIdList = userService.selectUserIdsByRoleIds(taskParticipant.getGroupIds());
                 if (CollUtil.isNotEmpty(userIdList)) {
                     userIds.addAll(userIdList);
                 }
@@ -318,7 +254,7 @@
             }
         }
         if (CollUtil.isNotEmpty(userIds)) {
-            List<UserDTO> userList = USER_SERVICE.selectListByIds(new ArrayList<>(userIds));
+            List<UserDTO> userList = userService.selectListByIds(new ArrayList<>(userIds));
             for (String code : messageType) {
                 MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code);
                 if (ObjectUtil.isNotEmpty(messageTypeEnum)) {
@@ -340,4 +276,22 @@
             }
         }
     }
+
+    /**
+     * 鏍规嵁浠诲姟id鏌ヨ 褰撳墠鐢ㄦ埛鐨勪换鍔★紝妫�鏌� 褰撳墠浜哄憳 鏄惁鏄 taskId 鐨勫姙鐞嗕汉
+     *
+     * @param taskId 浠诲姟id
+     * @return 缁撴灉
+     */
+    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);
+        }
+        return taskQuery.singleResult();
+    }
 }
diff --git "a/script/bpmn/\346\250\241\345\236\213.zip" "b/script/bpmn/\346\250\241\345\236\213.zip"
index d886e0f..6f30952 100644
--- "a/script/bpmn/\346\250\241\345\236\213.zip"
+++ "b/script/bpmn/\346\250\241\345\236\213.zip"
Binary files differ
diff --git a/script/sql/flowable.sql b/script/sql/flowable.sql
index c3f7428..e8dc798 100644
--- a/script/sql/flowable.sql
+++ b/script/sql/flowable.sql
@@ -27,6 +27,7 @@
     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 '鍒涘缓鏃堕棿',
@@ -112,7 +113,7 @@
 )
     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', '/demo/leaveEdit/index', NULL, '000000', 103, 1, sysdate(), 1, sysdate());
+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());
 
 create table wf_node_config
 (
@@ -134,12 +135,12 @@
     comment '鑺傜偣閰嶇疆';
 
 
-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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo:leave:export', '#', 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, '琛ㄥ崟绫诲瀷鍒楄〃');
diff --git a/script/sql/oracle/flowable.sql b/script/sql/oracle/flowable.sql
index afd5c0b..65474f4 100644
--- a/script/sql/oracle/flowable.sql
+++ b/script/sql/oracle/flowable.sql
@@ -30,6 +30,7 @@
     END_DATE    DATE,
     LEAVE_DAYS  NUMBER(10),
     REMARK      VARCHAR2(255),
+    STATUS      VARCHAR2(255),
     CREATE_DEPT NUMBER(20),
     CREATE_BY   NUMBER(20),
     CREATE_TIME DATE,
@@ -45,6 +46,7 @@
 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 '鍒涘缓鏃堕棿';
@@ -182,7 +184,7 @@
 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', '/demo/leaveEdit/index', NULL, '000000', 103, 1, sysdate, 1, sysdate);
+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);
 
 create table WF_NODE_CONFIG
 (
@@ -218,12 +220,12 @@
 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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo:leave:export', '#', 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, '琛ㄥ崟绫诲瀷鍒楄〃');
diff --git a/script/sql/oracle/oracle_ry_vue_5.X.sql b/script/sql/oracle/oracle_ry_vue_5.X.sql
index 06ea5fe..0aed89d 100644
--- a/script/sql/oracle/oracle_ry_vue_5.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_5.X.sql
@@ -443,7 +443,6 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊',     '1',   '9', 'log',              '',                             '', 1, 0, 'M', '0', '0', '',                            'log',           103, 1, sysdate, null, null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛',     '2',   '1', 'online',           'monitor/online/index',         '', 1, 0, 'C', '0', '0', 'monitor:online:list',         'online',        103, 1, sysdate, null, null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶',     '2',   '5', 'cache',            'monitor/cache/index',          '', 1, 0, 'C', '0', '0', 'monitor:cache:list',          'redis',         103, 1, sysdate, null, null, '缂撳瓨鐩戞帶鑿滃崟');
-insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓',     '3',   '1', 'build',            'tool/build/index',             '', 1, 0, 'C', '0', '0', 'tool:build:list',             'build',         103, 1, sysdate, null, null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate, null, null, '浠g爜鐢熸垚鑿滃崟');
 insert into sys_menu values('121',  '绉熸埛绠$悊',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate, null, null, '绉熸埛绠$悊鑿滃崟');
 insert into sys_menu values('122',  '绉熸埛濂楅绠$悊', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate, null, null, '绉熸埛濂楅绠$悊鑿滃崟');
diff --git a/script/sql/postgres/flowable.sql b/script/sql/postgres/flowable.sql
index eff4eeb..6e75e4b 100644
--- a/script/sql/postgres/flowable.sql
+++ b/script/sql/postgres/flowable.sql
@@ -29,6 +29,7 @@
     end_date    timestamp,
     leave_days  bigint,
     remark      varchar(255),
+    status      varchar(255),
     create_dept bigint,
     create_by   bigint,
     create_time timestamp,
@@ -48,6 +49,8 @@
 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 '鍒涘缓閮ㄩ棬';
 
@@ -251,7 +254,7 @@
 
 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', '/demo/leaveEdit/index', NULL, '000000', 103, 1, now(), 1, now());
+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
 (
@@ -300,12 +303,12 @@
 
 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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo:leave:export', '#', 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 (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, '琛ㄥ崟绫诲瀷鍒楄〃');
diff --git a/script/sql/postgres/postgres_ry_vue_5.X.sql b/script/sql/postgres/postgres_ry_vue_5.X.sql
index 9b2169e..995d738 100644
--- a/script/sql/postgres/postgres_ry_vue_5.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_5.X.sql
@@ -444,7 +444,6 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊',     '1',   '9', 'log',              '',                             '', '1', '0', 'M', '0', '0', '',                            'log',           103, 1, now(), null, null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛',     '2',   '1', 'online',           'monitor/online/index',         '', '1', '0', 'C', '0', '0', 'monitor:online:list',         'online',        103, 1, now(), null, null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶',     '2',   '5', 'cache',            'monitor/cache/index',          '', '1', '0', 'C', '0', '0', 'monitor:cache:list',          'redis',         103, 1, now(), null, null, '缂撳瓨鐩戞帶鑿滃崟');
-insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓',     '3',   '1', 'build',            'tool/build/index',             '', '1', '0', 'C', '0', '0', 'tool:build:list',             'build',         103, 1, now(), null, null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚',     '3',   '2', 'gen',              'tool/gen/index',               '', '1', '0', 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, now(), null, null, '浠g爜鐢熸垚鑿滃崟');
 insert into sys_menu values('121',  '绉熸埛绠$悊',     '6',   '1', 'tenant',           'system/tenant/index',          '', '1', '0', 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, now(), null, null, '绉熸埛绠$悊鑿滃崟');
 insert into sys_menu values('122',  '绉熸埛濂楅绠$悊', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', '1', '0', 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, now(), null, null, '绉熸埛濂楅绠$悊鑿滃崟');
diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql
index 396178f..3e3562d 100644
--- a/script/sql/ry_vue_5.X.sql
+++ b/script/sql/ry_vue_5.X.sql
@@ -278,7 +278,6 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊',     '1',   '9', 'log',              '',                             '', 1, 0, 'M', '0', '0', '',                            'log',           103, 1, sysdate(), null, null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛',     '2',   '1', 'online',           'monitor/online/index',         '', 1, 0, 'C', '0', '0', 'monitor:online:list',         'online',        103, 1, sysdate(), null, null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶',     '2',   '5', 'cache',            'monitor/cache/index',          '', 1, 0, 'C', '0', '0', 'monitor:cache:list',          'redis',         103, 1, sysdate(), null, null, '缂撳瓨鐩戞帶鑿滃崟');
-insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓',     '3',   '1', 'build',            'tool/build/index',             '', 1, 0, 'C', '0', '0', 'tool:build:list',             'build',         103, 1, sysdate(), null, null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate(), null, null, '浠g爜鐢熸垚鑿滃崟');
 insert into sys_menu values('121',  '绉熸埛绠$悊',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate(), null, null, '绉熸埛绠$悊鑿滃崟');
 insert into sys_menu values('122',  '绉熸埛濂楅绠$悊',  '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate(), null, null, '绉熸埛濂楅绠$悊鑿滃崟');
diff --git a/script/sql/sqlserver/flowable.sql b/script/sql/sqlserver/flowable.sql
index 11ee2be..2397c35 100644
--- a/script/sql/sqlserver/flowable.sql
+++ b/script/sql/sqlserver/flowable.sql
@@ -28,6 +28,7 @@
     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,
@@ -59,6 +60,9 @@
 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',
@@ -221,6 +225,7 @@
         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,
@@ -250,6 +255,10 @@
 
 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',
@@ -334,7 +343,7 @@
      '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', '/demo/leaveEdit/index', NULL, '000000', 103, 1, getdate(), 1, getdate());
+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
 (
@@ -406,12 +415,12 @@
      '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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo: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', 'demo:leave:export', '#', 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 (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, '琛ㄥ崟绫诲瀷鍒楄〃');
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
index 00f0771..ad9a0b5 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -1678,8 +1678,6 @@
 GO
 INSERT sys_menu VALUES (113, N'缂撳瓨鐩戞帶', 2, 5, N'cache', N'monitor/cache/index', N'', 1, 0, N'C', N'0', N'0', N'monitor:cache:list', N'redis', 103, 1, getdate(), NULL, NULL, N'缂撳瓨鐩戞帶鑿滃崟')
 GO
-INSERT sys_menu VALUES (114, N'琛ㄥ崟鏋勫缓', 3, 1, N'build', N'tool/build/index', N'', 1, 0, N'C', N'0', N'0', N'tool:build:list', N'build', 103, 1, getdate(), NULL, NULL, N'琛ㄥ崟鏋勫缓鑿滃崟')
-GO
 INSERT sys_menu VALUES (115, N'浠g爜鐢熸垚', 3, 2, N'gen', N'tool/gen/index', N'', 1, 0, N'C', N'0', N'0', N'tool:gen:list', N'code', 103, 1, getdate(), NULL, NULL, N'浠g爜鐢熸垚鑿滃崟')
 GO
 INSERT sys_menu VALUES (121, N'绉熸埛绠$悊', 6, 1, N'tenant', N'system/tenant/index', N'', 1, 0, N'C', N'0', N'0', N'system:tenant:list', N'code', 103, 1, getdate(), NULL, NULL, N'绉熸埛绠$悊鑿滃崟')
diff --git a/script/sql/update/oracle/update_5.1.2-5.2.0.sql b/script/sql/update/oracle/update_5.1.2-5.2.0.sql
index 0f87fd6..1aa585a 100644
--- a/script/sql/update/oracle/update_5.1.2-5.2.0.sql
+++ b/script/sql/update/oracle/update_5.1.2-5.2.0.sql
@@ -6,4 +6,4 @@
 COMMENT ON COLUMN sys_post.post_category IS '宀椾綅绫诲埆缂栫爜';
 UPDATE sys_post SET dept_id = 100;
 UPDATE sys_post SET dept_id = 103 where post_id = 1;
-UPDATE sys_menu SET path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;
+UPDATE sys_menu SET menu_name = 'SnailJob鎺у埗鍙�', path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;
diff --git a/script/sql/update/postgres/update_5.1.2-5.2.0.sql b/script/sql/update/postgres/update_5.1.2-5.2.0.sql
index dc36ebf..5089a09 100644
--- a/script/sql/update/postgres/update_5.1.2-5.2.0.sql
+++ b/script/sql/update/postgres/update_5.1.2-5.2.0.sql
@@ -6,4 +6,4 @@
 COMMENT ON COLUMN sys_post.post_category IS '宀椾綅绫诲埆缂栫爜';
 UPDATE sys_post SET dept_id = 100;
 UPDATE sys_post SET dept_id = 103 where post_id = 1;
-UPDATE sys_menu SET path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;
+UPDATE sys_menu SET menu_name = 'SnailJob鎺у埗鍙�', path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;
diff --git a/script/sql/update/sqlserver/update_5.1.2-5.2.0.sql b/script/sql/update/sqlserver/update_5.1.2-5.2.0.sql
index bf69f10..18daca4 100644
--- a/script/sql/update/sqlserver/update_5.1.2-5.2.0.sql
+++ b/script/sql/update/sqlserver/update_5.1.2-5.2.0.sql
@@ -25,5 +25,5 @@
 GO
 UPDATE sys_post SET dept_id = 103 where post_id = 1
 GO
-UPDATE sys_menu SET path = N'snailjob', component = N'monitor/snailjob/index', perms = N'monitor:snailjob:list', remark = N'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120
-GO
\ No newline at end of file
+UPDATE sys_menu SET menu_name = N'SnailJob鎺у埗鍙�', path = N'snailjob', component = N'monitor/snailjob/index', perms = N'monitor:snailjob:list', remark = N'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120
+GO
diff --git a/script/sql/update/update_5.1.2-5.2.0.sql b/script/sql/update/update_5.1.2-5.2.0.sql
index 11d71c8..33384e7 100644
--- a/script/sql/update/update_5.1.2-5.2.0.sql
+++ b/script/sql/update/update_5.1.2-5.2.0.sql
@@ -2,4 +2,4 @@
 ALTER TABLE sys_post ADD dept_id BIGINT(20) NOT NULL COMMENT '閮ㄩ棬id', ADD post_category VARCHAR(100) DEFAULT NULL COMMENT '宀椾綅绫诲埆缂栫爜';
 UPDATE sys_post SET dept_id = 100;
 UPDATE sys_post SET dept_id = 103 where post_id = 1;
-UPDATE sys_menu SET path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;
+UPDATE sys_menu SET menu_name = 'SnailJob鎺у埗鍙�', path = 'snailjob', component = 'monitor/snailjob/index', perms = 'monitor:snailjob:list', remark = 'SnailJob鎺у埗鍙拌彍鍗�' WHERE menu_id = 120;

--
Gitblit v1.9.3