diff --git "a/Database/250526/\350\241\245\345\205\205busFlow\347\232\204documentId\357\274\210\346\233\264\346\226\260portal\345\220\216\346\211\247\350\241\214\357\274\211.sql" "b/Database/250526/\350\241\245\345\205\205busFlow\347\232\204documentId\357\274\210\346\233\264\346\226\260portal\345\220\216\346\211\247\350\241\214\357\274\211.sql"
index 1b4549c222828a29b3ef245a2a614e0c9fc6089e..ca3793d0fea2cb7c329ddfbbbdecadbe8fd6167e 100644
--- "a/Database/250526/\350\241\245\345\205\205busFlow\347\232\204documentId\357\274\210\346\233\264\346\226\260portal\345\220\216\346\211\247\350\241\214\357\274\211.sql"
+++ "b/Database/250526/\350\241\245\345\205\205busFlow\347\232\204documentId\357\274\210\346\233\264\346\226\260portal\345\220\216\346\211\247\350\241\214\357\274\211.sql"
@@ -1,15 +1,20 @@
-#@instance_id鏇挎崲涓哄鏍¤瘑鍒玦d锛宐igint绫诲瀷
-
-
-#鏄惁寮€鍚洖閫€鍔熻兘
-INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
-	id, creator, updator, remark, available, create_date, update_date, version_date)
-SELECT 
-	'needShowRegress', 
-	'false', 
-	'鏄惁寮€鍚洖閫€鍔熻兘', 
-	@instance_id, 
-	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
-FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'needShowRegress' );
-
-
+#select filtered_er.process_instance_id,bf.* from  tb_bus_flow bf
+UPDATE tb_bus_flow bf
+JOIN (
+    SELECT 
+        bf.id,
+        bf.apply_code ,
+        bf.create_date,
+        er.process_instance_id,
+        ROW_NUMBER() OVER (
+            PARTITION BY bf.apply_code, bf.create_date 
+            ORDER BY er.create_date DESC
+        ) AS rn
+    FROM tb_bus_flow bf
+    JOIN v_expenseReimbursement_all er ON er.order_code = bf.apply_code
+    WHERE er.create_date <= bf.create_date
+    #and er.order_code in('')
+) AS filtered_er
+ON bf.id = filtered_er.id
+SET bf.document_id = filtered_er.process_instance_id
+WHERE filtered_er.rn = 1;
\ No newline at end of file
diff --git "a/Database/250530/\345\257\271\346\216\245\351\207\221\350\235\266\346\265\201\347\250\213\345\274\225\346\223\216\351\205\215\347\275\256.sql" "b/Database/250530/\345\257\271\346\216\245\351\207\221\350\235\266\346\265\201\347\250\213\345\274\225\346\223\216\351\205\215\347\275\256.sql"
new file mode 100644
index 0000000000000000000000000000000000000000..3702a1332cf05561b131fd28962b91bbeeecaee9
--- /dev/null
+++ "b/Database/250530/\345\257\271\346\216\245\351\207\221\350\235\266\346\265\201\347\250\213\345\274\225\346\223\216\351\205\215\347\275\256.sql"
@@ -0,0 +1,58 @@
+#@instance_id鏇挎崲涓哄鏍¤瘑鍒玦d锛宐igint绫诲瀷
+
+
+#閲戣澏娴佺▼寮曟搸鎺ュ彛鍦板潃
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'kingDeeUrl', 
+	'http://192.168.3.134:8022/ierp/kapi', 
+	'閲戣澏娴佺▼寮曟搸鎺ュ彛鍦板潃', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'kingDeeUrl' );
+
+#閲戣澏娴佺▼寮曟搸搴旂敤ID
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'kingDeeClientId', 
+	'SeaSky', 
+	'閲戣澏娴佺▼寮曟搸搴旂敤ID', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'kingDeeClientId' );
+
+#閲戣澏娴佺▼寮曟搸搴旂敤瀵嗛挜
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'kingDeeClientSecret', 
+	'U2FsdGVkX1/rCmWCgiwKWaS0kOfD8bdfLV4jyoOfhbw=', 
+	'閲戣澏娴佺▼寮曟搸搴旂敤瀵嗛挜', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'kingDeeClientSecret' );
+
+#閲戣澏娴佺▼寮曟搸搴旂敤浠g悊鐢ㄦ埛鍚�
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'kingDeeClientUserName', 
+	'jiekoudiaoyong', 
+	'閲戣澏娴佺▼寮曟搸搴旂敤浠g悊鐢ㄦ埛鍚�', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'kingDeeClientUserName' );
+
+#閲戣澏娴佺▼寮曟搸璐︽埛ID
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'kingDeeAccountId', 
+	'2178528630223669248', 
+	'閲戣澏娴佺▼寮曟搸璐︽埛ID', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'kingDeeAccountId' );
+
diff --git "a/Database/250530/\346\265\201\347\250\213\345\274\225\346\223\216\347\211\210\346\234\254\351\205\215\347\275\256.sql" "b/Database/250530/\346\265\201\347\250\213\345\274\225\346\223\216\347\211\210\346\234\254\351\205\215\347\275\256.sql"
new file mode 100644
index 0000000000000000000000000000000000000000..9ec994d2667eaab0656728e337a82ab406bde44c
--- /dev/null
+++ "b/Database/250530/\346\265\201\347\250\213\345\274\225\346\223\216\347\211\210\346\234\254\351\205\215\347\275\256.sql"
@@ -0,0 +1,13 @@
+#@instance_id鏇挎崲涓哄鏍¤瘑鍒玦d锛宐igint绫诲瀷
+
+
+#娴佺▼寮曟搸鐗堟湰
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'flowServiceName', 
+	'FlowServiceImpl', 
+	'娴佺▼寮曟搸鐗堟湰', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'flowServiceName' );
diff --git "a/Database/250604/\345\257\271\346\216\245\346\230\237\346\265\267\345\276\205\345\212\236\351\205\215\347\275\256.sql" "b/Database/250604/\345\257\271\346\216\245\346\230\237\346\265\267\345\276\205\345\212\236\351\205\215\347\275\256.sql"
new file mode 100644
index 0000000000000000000000000000000000000000..791e940a6764812b7c68bf6e742db826a5ad4dd7
--- /dev/null
+++ "b/Database/250604/\345\257\271\346\216\245\346\230\237\346\265\267\345\276\205\345\212\236\351\205\215\347\275\256.sql"
@@ -0,0 +1,48 @@
+#@instance_id鏇挎崲涓哄鏍¤瘑鍒玦d锛宐igint绫诲瀷
+
+
+#鏄熸捣寰呭姙鎺ュ彛鍦板潃
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'xingHaiUrl', 
+	'http://218.192.144.150:8089', 
+	'鏄熸捣寰呭姙鎺ュ彛鍦板潃', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'xingHaiUrl' );
+
+#鏄熸捣寰呭姙token鎺ュ彛鐢ㄦ埛鍚�
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'xingHaiUserName', 
+	'kkrest', 
+	'鏄熸捣寰呭姙token鎺ュ彛鐢ㄦ埛鍚�', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'xingHaiUserName' );
+
+#鏄熸捣寰呭姙token鎺ュ彛瀵嗙爜
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'xingHaiPassword', 
+	'a96b9d9c-dc17-4d18-9924-991d39ac0649', 
+	'鏄熸捣寰呭姙token鎺ュ彛瀵嗙爜', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'xingHaiPassword' );
+
+#鏄熸捣寰呭姙鎺ュ彛绯荤粺娉ㄥ唽缂栫爜
+INSERT INTO `tb_config` (config_key, config_value, config_remarks, instance_id, 
+	id, creator, updator, remark, available, create_date, update_date, version_date)
+SELECT 
+	'xingHaiRegisterCode', 
+	'3001', 
+	'鏄熸捣寰呭姙鎺ュ彛绯荤粺娉ㄥ唽缂栫爜', 
+	@instance_id, 
+	UUID_SHORT(), NULL, NULL, NULL, 'YES', NOW(), NOW(), NOW()
+FROM DUAL WHERE NOT EXISTS ( SELECT * FROM `tb_config` WHERE instance_id = @instance_id and config_key = 'xingHaiRegisterCode' );
+
+
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/api/IExternalController.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/api/IExternalController.java
index 69e512cb61b8515774f415fc3f151c00b05d8adb..e9cffc97125d87d7c565c9d4662aff4aa095dc5d 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/api/IExternalController.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/api/IExternalController.java
@@ -1,5 +1,6 @@
 package com.seasky.flowportal.api;
 
+import com.seasky.flowportal.dto.apply.ApplyListCmd;
 import com.seasky.flowportal.dto.approverUser.ApproverUserConfigOut;
 import com.seasky.flowportal.dto.approverUser.ApproverUserSFPPageOut;
 import com.seasky.flowportal.dto.approverUser.ApproverUserSFPQuery;
@@ -31,6 +32,11 @@ public interface IExternalController {
     @PostMapping(path = "/SavePreApply")
     BaseResultModel<String> savePreApply(@RequestBody PreExpenseApplyCmd preExpenseApplyCmd);
 
+    @ApiOperation("[C]02.鎺ユ敹鎶ラ攢鍗曞鎵圭姸鎬佸拰瀹℃壒鏄庣粏鏁版嵁锛堝澶栵級")
+    @PostMapping("/ApprovalDetail")
+    BaseResultModel<String> approvalDetail(@RequestBody ApplyListCmd cmd);
+
+
     @ApiOperation("[Q]01.淇濆瓨鎶ラ攢鍗曚簳鑾峰彇鍔犵浜洪厤缃�")
     @PostMapping("/ListApproverUserConfig")
     BaseResultModel<ApproverUserConfigOut> getApproverUserConfigList(@RequestBody ExpenseReimbursementSFPCmd cmd) throws Exception;
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyCmd.java
index 3c75ce6a4bbdf90f831e23891f7cdfed5796cd6a..921cf1cc1dfbbd0b7f6f79456c3cdaab4b11c5af 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyCmd.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyCmd.java
@@ -1,15 +1,13 @@
 package com.seasky.flowportal.dto.apply;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.seasky.flowportal.base.BaseCmd;
 import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
-import java.util.Date;
-
 /**
  * @author liyulu
  * @since 2022/1/5
@@ -21,32 +19,42 @@ import java.util.Date;
 @AllArgsConstructor
 public class ApplyCmd extends BaseCmd {
 
-    @JsonProperty(value = "approvalDetailID")
+    @ApiModelProperty(value = "鎶ラ攢鍗曞钩鍙癐D")
     private Long approvalDetailId;
 
+    @ApiModelProperty(value = "鍗曞彿")
     private String orderNo;
 
+    @ApiModelProperty(value = "鍗曟嵁骞冲彴鐘舵€�")
     private int orderState;
 
-    @JsonProperty(value = "personNO")
+    @ApiModelProperty(value = "褰撳墠澶勭悊浜哄伐鍙�")
     private String personNo;
 
+    @ApiModelProperty(value = "褰撳墠澶勭悊浜哄悕绉�")
     private String personName;
 
-    @JsonProperty(value = "approvalTime")
-    private Date approvalDate;
+    @ApiModelProperty(value = "澶勭悊鏃堕棿")
+    private String approvalTime;
 
+    @ApiModelProperty(value = "瀹℃壒鎰忚")
     private String approvalOpinion;
 
+    @ApiModelProperty(value = "鍗曟嵁鐘舵€�")
     private String approvalState;
 
+    @ApiModelProperty(value = "鍗曟嵁澶勭悊浜鸿妭鐐�")
     private String approvalNodeName;
 
+    @ApiModelProperty(value = "鍗曟嵁PDF")
     private String pdfUrl;
 
+    @ApiModelProperty(value = "绯荤粺ID")
     private String systemId;
 
+    @ApiModelProperty(value = "token")
     private String token;
 
+    @ApiModelProperty(value = "open")
     private String open;
 }
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyListCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyListCmd.java
new file mode 100644
index 0000000000000000000000000000000000000000..98facf901ab0b2ec765a97307030651041804497
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/apply/ApplyListCmd.java
@@ -0,0 +1,36 @@
+package com.seasky.flowportal.dto.apply;
+
+import com.seasky.flowportal.base.BaseCmd;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * @author liyulu
+ * @since 2022/1/5
+ */
+@ApiModel("Dto")
+@Data
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class ApplyListCmd extends BaseCmd {
+
+    @ApiModelProperty(value = "瀹℃壒璁板綍鍒楄〃")
+    List<ApplyCmd> approvalDetailList;
+
+    @ApiModelProperty(value = "鍗曞彿")
+    private String orderNo;
+
+    @ApiModelProperty(value = "绯荤粺ID")
+    private String systemId;
+
+    @ApiModelProperty(value = "token")
+    private String token;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalCmd.java
index 0e54f2dec35bd1f5633bef003e2844817e461392..9fdfe560690c7e53d2a31c359835d5ed53d733cf 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalCmd.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalCmd.java
@@ -106,27 +106,37 @@ public class ApprovalCmd extends BaseCmd {
 
     @ApiModelProperty(value = "椤圭洰鍚嶇О")
     protected String fundsProjectName;
+    public void setFundsProjectName(String fundsProjectName) {
+        this.fundsProjectName = fundsProjectName;
+        getFundsProjectNameList();
+    }
 
     protected String fundsProjectCode;
     public String getFundsProjectCode() {
-        fundsProjectCode = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).findFirst().orElse("");
+        fundsProjectCode = fundsProject == null ? null : Arrays.stream(fundsProject.split(",")).findFirst().orElse(null);
         return fundsProjectCode;
     }
 
     protected List<String> fundsProjectCodeList;
     public List<String> getFundsProjectCodeList() {
-        fundsProjectCodeList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).collect(Collectors.toList());
+        fundsProjectCodeList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProject.split(",")).collect(Collectors.toList());
         return fundsProjectCodeList;
     }
 
+    protected List<String> fundsProjectNameList;
+    public List<String> getFundsProjectNameList() {
+        fundsProjectNameList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProjectName.split(",")).collect(Collectors.toList());
+        return fundsProjectNameList;
+    }
+
     /**椤圭洰*/
     protected String fundsProjectCodeAndName;
 
     public String getFundsProjectCodeAndName() {
         fundsProjectCodeAndName = "";
         try {
-            List<String> fundsProjectNameList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProjectName, "").split(",")).collect(Collectors.toList());
-            List<String> fundsProjectCodeList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).collect(Collectors.toList());
+            List<String> fundsProjectNameList = getFundsProjectNameList();;
+            List<String> fundsProjectCodeList = getFundsProjectCodeList();
             for (int i = 0; i < fundsProjectNameList.size(); i++) {
                 String fundsProjectName = fundsProjectNameList.get(i);
                 String fundsProjectCode = fundsProjectCodeList.get(i);
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalOut.java
index 0e6aad69df91e531070363794e1e89ae614c78cf..8fcd7512977da72ab9e6702db7fab5ff769d5392 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalOut.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/approval/ApprovalOut.java
@@ -11,7 +11,6 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import org.apache.commons.lang3.ObjectUtils;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -101,13 +100,13 @@ public class ApprovalOut extends BaseDto implements Serializable {
     @ApiModelProperty("棣栦釜缁忚垂椤圭洰")
     public String fundsProjectCode;
     public String getFundsProjectCode() {
-        fundsProjectCode = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).findFirst().orElse("");
+        fundsProjectCode = fundsProject == null ? null : Arrays.stream(fundsProject.split(",")).findFirst().orElse(null);
         return fundsProjectCode;
     }
 
     protected List<String> fundsProjectCodeList;
     public List<String> getFundsProjectCodeList() {
-        fundsProjectCodeList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).collect(Collectors.toList());
+        fundsProjectCodeList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProject.split(",")).collect(Collectors.toList());
         return fundsProjectCodeList;
     }
 
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowCmd.java
index 34a6c2b8f2ad7fbd0c695f68b98375e48b64d131..ee3a35a6dc59196cc6ab77986449d149ddc799e0 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowCmd.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowCmd.java
@@ -2,6 +2,7 @@ package com.seasky.flowportal.dto.busFlow;
 
 import com.alibaba.fastjson.JSONObject;
 import com.seasky.flowportal.base.BaseCmd;
+import com.seasky.flowportal.enums.ExecutionStatusEnum;
 import io.swagger.annotations.ApiModel;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -94,4 +95,6 @@ public class BusFlowCmd extends BaseCmd implements Serializable {
 
     private Date createDate;
 
+    public boolean isSucceeded() { return Integer.valueOf(ExecutionStatusEnum.Succeeded.getIndex()).equals(executionStatus); }
+
 }
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowUserCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowUserCmd.java
index 569a8bdf139b58728286c6daa8b4596c432e6abb..abb7098bd7d38108dd14325a88002459c6297afb 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowUserCmd.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/busFlow/BusFlowUserCmd.java
@@ -1,5 +1,6 @@
 package com.seasky.flowportal.dto.busFlow;
 
+import com.seasky.flowportal.enums.ExecutionStatusEnum;
 import io.swagger.annotations.ApiModel;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -25,4 +26,6 @@ public class BusFlowUserCmd implements Serializable {
 
     private Integer executionStatus;
 
+    public boolean succeeded() { return Integer.valueOf(ExecutionStatusEnum.Succeeded.getIndex()).equals(executionStatus); }
+
 }
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementCmd.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementCmd.java
index 00c5bc6a8af997a1cffe75491906afee1a979cc2..f74c10e5e856c626591ef90793d416e553c22522 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementCmd.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementCmd.java
@@ -235,7 +235,7 @@ public class ExpenseReimbursementCmd extends ApprovalCmd implements Serializable
         return payTypeNameList;
     }
 
-    private Boolean doReturnApplicationStatus;
+    private Boolean doClaimsApi;
 
     private String statusFrom;
 
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementOut.java
index c7bcb768fbcdcd0a51e437e8eda48a5e4e54b038..05bc412d6a84b1c8c45e890a153e872e343c6da0 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementOut.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/expenseReimbursement/ExpenseReimbursementOut.java
@@ -134,8 +134,8 @@ public class ExpenseReimbursementOut extends BaseDto implements Serializable {
     public String getFundsProjectCodeAndName() {
         fundsProjectCodeAndName = "";
         try {
-            List<String> fundsProjectNameList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProjectName, "").split(",")).distinct().collect(Collectors.toList());
-            List<String> fundsProjectCodeList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).distinct().collect(Collectors.toList());
+            List<String> fundsProjectNameList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProjectName.split(",")).collect(Collectors.toList());
+            List<String> fundsProjectCodeList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProject.split(",")).collect(Collectors.toList());
             for (int i = 0; i < fundsProjectNameList.size(); i++) {
                 String fundsProjectName = fundsProjectNameList.get(i);
                 String fundsProjectCode = fundsProjectCodeList.get(i);
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeAddSalaryBillRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeAddSalaryBillRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..24e4f23ed9832551c94d312e7240073cad068f61
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeAddSalaryBillRequest.java
@@ -0,0 +1,95 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓钖祫娴佺▼鎺ュ彛璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeAddSalaryBillRequest implements Serializable {
+
+    /**钖祫鐢虫姤鍗曞彿*/
+    @JsonProperty(value = "DeclareBillNo")
+    @JSONField(name="DeclareBillNo")
+    protected String declareBillNo;
+    /**钖祫璐﹀*/
+    @JsonProperty(value = "LatoryName")
+    @JSONField(name="LatoryName")
+    protected String latoryName;
+    /**鍙戞斁骞村害*/
+    @JsonProperty(value = "Year")
+    @JSONField(name="Year")
+    protected String year;
+    /**鍙戞斁鏈堜唤*/
+    @JsonProperty(value = "Month")
+    @JSONField(name="Month")
+    protected String month;
+    /**鎻愪氦浜哄伐鍙�*/
+    @JsonProperty(value = "Submitter")
+    @JSONField(name="Submitter")
+    protected String submitter;
+    /**鎻愪氦鏃堕棿*/
+    @JsonProperty(value = "SubmitDateTime")
+    @JSONField(name="SubmitDateTime")
+    protected String submitDateTime;
+    /**鍙戞斁浜烘暟*/
+    @JsonProperty(value = "GrantNum")
+    @JSONField(name="GrantNum")
+    protected String grantNum;
+    /**鍙戞斁鍐呭*/
+    @JsonProperty(value = "GrantContent")
+    @JSONField(name="GrantContent")
+    protected String grantContent;
+    /**鍙戞斁閮ㄩ棬浠g爜*/
+    @JsonProperty(value = "DeptCode")
+    @JSONField(name="DeptCode")
+    protected String deptCode;
+    /**鍙戞斁閮ㄩ棬鍚嶇О*/
+    @JsonProperty(value = "DeptName")
+    @JSONField(name="DeptName")
+    protected String deptName;
+    /**缁忚垂椤圭洰缂栧彿*/
+    @JsonProperty(value = "ProjectCode")
+    @JSONField(name="ProjectCode")
+    protected String projectCode;
+    /**缁忚垂椤圭洰鍚嶇О*/
+    @JsonProperty(value = "ProjectName")
+    @JSONField(name="ProjectName")
+    protected String projectName;
+    /**缁忚垂椤圭洰璐熻矗浜哄伐鍙�*/
+    @JsonProperty(value = "Leader")
+    @JSONField(name="Leader")
+    protected String leader;
+    /**搴斾粯閲戦*/
+    @JsonProperty(value = "ShouldAmount")
+    @JSONField(name="ShouldAmount")
+    protected String shouldAmount;
+    /**鎵e彂閲戦*/
+    @JsonProperty(value = "DeductAmount")
+    @JSONField(name="DeductAmount")
+    protected String deductAmount;
+    /**绋庨噾*/
+    @JsonProperty(value = "RealAmount")
+    @JSONField(name="RealAmount")
+    protected String realAmount;
+    /**瀹炲彂閲戦*/
+    @JsonProperty(value = "RealTaxAmount")
+    @JSONField(name="RealTaxAmount")
+    protected String realTaxAmount;
+    /**Base64鐢虫姤鍗昉DF鏂囦欢娴�*/
+    @JsonProperty(value = "FileStream")
+    @JSONField(name="FileStream")
+    protected String fileStream;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeBaseResultOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeBaseResultOut.java
new file mode 100644
index 0000000000000000000000000000000000000000..634678089cda52cb81f9968f4be407c3ffb2397a
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeBaseResultOut.java
@@ -0,0 +1,26 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.ObjectUtils;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鎺ュ彛杩斿洖鍩虹妯″瀷")
+@Data
+//@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeBaseResultOut implements Serializable {
+    public static Integer CODE_SUCCESS = 0;
+    public boolean isSuccess() { return ObjectUtils.isNotEmpty(errorCode) && errorCode.equals(CODE_SUCCESS); }
+
+    protected Integer errorCode;
+    protected String message;
+    protected Boolean status;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemDetailRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemDetailRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e371d7607b6156bb6e34949da3ea84a60ba2a516
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemDetailRequest.java
@@ -0,0 +1,42 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛缁忚垂椤圭洰鏄庣粏璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeExpendItemDetailRequest implements Serializable {
+
+    /**鏀嚭鎺у埗椤�*/
+    @JsonProperty(value = "Controls")
+    @JSONField(name="Controls")
+    protected String controls;
+    /**鏀嚭椤圭洰*/
+    @JsonProperty(value = "ExpenseProject")
+    @JSONField(name="ExpenseProject")
+    protected String expenseProject;
+    /**鐢ㄩ€�*/
+    @JsonProperty(value = "Remark")
+    @JSONField(name="Remark")
+    protected String remark;
+    /**鎶ラ攢閲戦*/
+    @JsonProperty(value = "PayAmount")
+    @JSONField(name="PayAmount")
+    protected String payAmount;
+    /**闄勪欢寮犳暟*/
+    @JsonProperty(value = "InvoiceNumber")
+    @JSONField(name="InvoiceNumber")
+    protected String invoiceNumber;
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1355e0ff49e6b9c9ddce0a7b036fa7d9cfe1c3fa
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeExpendItemRequest.java
@@ -0,0 +1,60 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛鎶ラ攢缁忚垂椤圭洰璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeExpendItemRequest implements Serializable {
+
+    /**鎵€灞炵粡璐�*/
+    @JsonProperty(value = "FundCodeName")
+    @JSONField(name="FundCodeName")
+    protected String fundCodeName;
+    /**椤圭洰缂栧彿*/
+    @JsonProperty(value = "ProjectCode")
+    @JSONField(name="ProjectCode")
+    protected String projectCode;
+    /**椤圭洰鍚嶇О*/
+    @JsonProperty(value = "ProjectName")
+    @JSONField(name="ProjectName")
+    protected String projectName;
+    /**椤圭洰鍙敤閲戦*/
+    @JsonProperty(value = "ProUsedBalance")
+    @JSONField(name="ProUsedBalance")
+    protected String proUsedBalance;
+    /**椤圭洰鍐荤粨閲戦*/
+    @JsonProperty(value = "FreezeAmount")
+    @JSONField(name="FreezeAmount")
+    protected String freezeAmount;
+    /**椤圭洰浣欓*/
+    @JsonProperty(value = "ProjectBalance")
+    @JSONField(name="ProjectBalance")
+    protected String projectBalance;
+    /**椤圭洰璐熻矗浜�*/
+    @JsonProperty(value = "Leader")
+    @JSONField(name="Leader")
+    protected String leader;
+    /**椤圭洰鎵€灞為儴闂�*/
+    @JsonProperty(value = "Department")
+    @JSONField(name="Department")
+    protected String department;
+    /**鎶ラ攢缁忚垂椤圭洰*/
+    @JsonProperty(value = "ExpendItem")
+    @JSONField(name="ExpendItem")
+    protected List<KingDeeCommonNewExpenseBillByTypeExpendItemDetailRequest> expendItemDetailList;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeInvoiceInfoRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeInvoiceInfoRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..edc419916789b1d81745dc778ffe5d10d38d3d42
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeInvoiceInfoRequest.java
@@ -0,0 +1,39 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛鍙戠エ淇℃伅璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeInvoiceInfoRequest implements Serializable {
+
+    /**鍙戠エ鍙�*/
+    @JsonProperty(value = "InvoiceNo")
+    @JSONField(name="InvoiceNo")
+    protected String invoiceNo;
+    /**鍙戠エ浠g爜*/
+    @JsonProperty(value = "InvoiceCode")
+    @JSONField(name="InvoiceCode")
+    protected String invoiceCode;
+    /**鍙戠エ鏃ユ湡*/
+    @JsonProperty(value = "BillingDate")
+    @JSONField(name="BillingDate")
+    protected String billingDate;
+    /**鍙戠エ閲戦*/
+    @JsonProperty(value = "PretaxAmount")
+    @JSONField(name="PretaxAmount")
+    protected String pretaxAmount;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..44025ae91197f4a118ae3485fe40e8e1205347a8
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeRequest.java
@@ -0,0 +1,126 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.seasky.flowportal.dto.expenseReimbursement.ExpenseReimbursementCmd;
+import com.seasky.flowportal.dto.extendData.ExtendFieldCmd;
+import com.seasky.flowportal.dto.extendData.PayInfoCmd;
+import com.seasky.flowportal.enums.ReimbursementTypeEnum;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeRequest implements Serializable {
+
+    /**鎶ラ攢绫诲瀷锛屾灇涓惧€硷紙鐢ㄦ鐢宠鍗� = 1,鍥藉唴宸梾鍗� = 2,涓汉鍊熸 = 4, 寰€鏉ユ姤閿€鍗� = 10锛�*/
+    @JsonProperty(value = "BusinessType")
+    @JSONField(name="BusinessType")
+    protected String businessType;
+    /**鎶ラ攢鍗曞彿*/
+    @JsonProperty(value = "OrderNo")
+    @JSONField(name="OrderNo")
+    protected String orderNo;
+    /**鎶ラ攢浜哄伐鍙�*/
+    @JsonProperty(value = "PersonNo")
+    @JSONField(name="PersonNo")
+    protected String personNo;
+    /**鎶ラ攢浜哄鍚�*/
+    @JsonProperty(value = "PersonName")
+    @JSONField(name="PersonName")
+    protected String personName;
+    /**鎶ラ攢浜洪儴闂�*/
+    @JsonProperty(value = "OrgCodeName")
+    @JSONField(name="OrgCodeName")
+    protected String orgCodeName;
+    /**鎶ラ攢浜虹數璇�*/
+    @JsonProperty(value = "Mobile")
+    @JSONField(name="Mobile")
+    protected String mobile;
+    /**棰勭害鏃ユ湡*/
+    @JsonProperty(value = "ReserveDate")
+    @JSONField(name="ReserveDate")
+    protected String reserveDate;
+    /**棰勭害鏍″尯*/
+    @JsonProperty(value = "LocalName")
+    @JSONField(name="LocalName")
+    protected String localName;
+    /**閫€妗f牎鍖�*/
+    @JsonProperty(value = "SchoolName")
+    @JSONField(name="SchoolName")
+    protected String schoolName;
+    /**鎶ラ攢浜嬬敱*/
+    @JsonProperty(value = "Remark")
+    @JSONField(name="Remark")
+    protected String remark;
+    /**闄勪欢鎬绘暟*/
+    @JsonProperty(value = "TotalAttachments")
+    @JSONField(name="TotalAttachments")
+    protected String totalAttachments;
+    /**鎶ラ攢缁忚垂椤圭洰*/
+    @JsonProperty(value = "ExpendItem")
+    @JSONField(name="ExpendItem")
+    protected List<KingDeeCommonNewExpenseBillByTypeExpendItemRequest> expendItemList;
+    /**鏀粯淇℃伅*/
+    @JsonProperty(value = "SettlementInfo")
+    @JSONField(name="SettlementInfo")
+    protected List<KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest> settlementInfoList;
+    /**鍙戠エ淇℃伅*/
+    @JsonProperty(value = "InvoiceInfo")
+    @JSONField(name="InvoiceInfo")
+    protected List<KingDeeCommonNewExpenseBillByTypeInvoiceInfoRequest> invoiceInfoList;
+    /**宸梾淇℃伅*/
+    @JsonProperty(value = "TravelInfo")
+    @JSONField(name="TravelInfo")
+    protected KingDeeCommonNewExpenseBillByTypeTravelInfoRequest travelInfo;
+
+    public static KingDeeCommonNewExpenseBillByTypeRequest map(ExpenseReimbursementCmd from) {
+        if (ObjectUtils.isEmpty(from))
+            return null;
+        String businessType = toBusinessType(from.getOrderType());
+        ExtendFieldCmd extendFieldCmd = from.getExtendFieldCmd();
+        List<PayInfoCmd> payInfo = from.getPayInfo();
+        KingDeeCommonNewExpenseBillByTypeRequest to = KingDeeCommonNewExpenseBillByTypeRequest.builder()
+                .businessType(businessType)
+                .orderNo(from.getOrderCode())
+                .personNo(from.getApplicantNo())
+                .personName(from.getApplicantName())
+                .orgCodeName(String.format("%s-%s", from.getOrganizationCode(), from.getOrganizationName()))
+                .mobile(ObjectUtils.isEmpty(extendFieldCmd) ? null :extendFieldCmd.getApplicantMobile())
+                .reserveDate(FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss").format(from.getOrderDate()))
+                .remark(from.getReason())
+                //.expendItemList()
+                .build();
+        return to;
+    }
+    public static String toBusinessType(String orderType) {
+        ReimbursementTypeEnum reimbursementTypeEnum = ReimbursementTypeEnum.getValueByName(orderType);
+        return ObjectUtils.isEmpty(reimbursementTypeEnum) ? "" : reimbursementTypeEnum.getIndex();
+    }
+
+    public static List<KingDeeCommonNewExpenseBillByTypeRequest> map(List fromList) {
+        if (fromList == null)
+            return null;
+        List<KingDeeCommonNewExpenseBillByTypeRequest> toList = new ArrayList<>();
+        fromList.forEach(e -> {
+            if (e instanceof ExpenseReimbursementCmd)
+                toList.add(map((ExpenseReimbursementCmd) e));
+        });
+        return toList;
+    }
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..18c46a531e6dc9a08c89c80d829a357d1c8ed789
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest.java
@@ -0,0 +1,95 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.seasky.flowportal.dto.extendData.PayInfoCmd;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import org.apache.commons.lang3.ObjectUtils;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛鏀粯淇℃伅璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest implements Serializable {
+
+    /**缁撶畻绫诲瀷*/
+    @JsonProperty(value = "SettlementTypeName")
+    @JSONField(name="SettlementTypeName")
+    protected String settlementTypeName;
+    /**宸�/瀛﹀彿*/
+    @JsonProperty(value = "EmployeeNumber")
+    @JSONField(name="EmployeeNumber")
+    protected String employeeNumber;
+    /**濮撳悕*/
+    @JsonProperty(value = "EmployeeName")
+    @JSONField(name="EmployeeName")
+    protected String employeeName;
+    /**鏀舵浜�/鏀舵鍗曚綅*/
+    @JsonProperty(value = "CardName")
+    @JSONField(name="CardName")
+    protected String cardName;
+    /**鏀舵浜虹撼绋庤瘑鍒彿*/
+    @JsonProperty(value = "TaxIdentificationNo")
+    @JSONField(name="TaxIdentificationNo")
+    protected String taxIdentificationNo;
+    /**璐﹀彿*/
+    @JsonProperty(value = "CardNo")
+    @JSONField(name="CardNo")
+    protected String cardNo;
+    /**鎵€灞為摱琛�*/
+    @JsonProperty(value = "BankName")
+    @JSONField(name="BankName")
+    protected String bankName;
+    /**寮€鎴疯鍚嶇О*/
+    @JsonProperty(value = "CityName")
+    @JSONField(name="CityName")
+    protected String cityName;
+    /**寮€鎴疯鍦板潃*/
+    @JsonProperty(value = "RegAddress")
+    @JSONField(name="RegAddress")
+    protected String regAddress;
+    /**閲戦*/
+    @JsonProperty(value = "Amount")
+    @JSONField(name="Amount")
+    protected String amount;
+    /**鐢ㄩ€�(姹囨闄勮█)*/
+    @JsonProperty(value = "Remark")
+    @JSONField(name="Remark")
+    protected String remark;
+
+    public static KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest map(PayInfoCmd from) {
+        if (ObjectUtils.isEmpty(from))
+            return null;
+
+        BigDecimal payAmount = from.getPayAmount();
+        KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest to = KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest.builder()
+                .amount(ObjectUtils.isEmpty(payAmount) ? "" : payAmount.setScale(2, RoundingMode.HALF_UP).toString())
+                .build();
+        return to;
+    }
+
+    public static List<KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest> map(List fromList) {
+        if (fromList == null)
+            return null;
+        List<KingDeeCommonNewExpenseBillByTypeSettlementInfoRequest> toList = new ArrayList<>();
+        fromList.forEach(e -> {
+            if (e instanceof PayInfoCmd)
+                toList.add(map((PayInfoCmd) e));
+        });
+        return toList;
+    }
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelDetailRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelDetailRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a13ee72e106dd99c886c5b92f8e00898e8727d8
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelDetailRequest.java
@@ -0,0 +1,75 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛鍙戠エ淇℃伅璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeTravelDetailRequest implements Serializable {
+
+    /**鍑哄樊浜�*/
+    @JsonProperty(value = "TravelPersonName")
+    @JSONField(name="TravelPersonName")
+    protected String travelPersonName;
+    /**鑱屼綅鑱岀О*/
+    @JsonProperty(value = "ProfessionalName")
+    @JSONField(name="ProfessionalName")
+    protected String professionalName;
+    /**鎵€灞炲崟浣�*/
+    @JsonProperty(value = "Unit")
+    @JSONField(name="Unit")
+    protected String unit;
+    /**澶囨敞*/
+    @JsonProperty(value = "PersonRemark")
+    @JSONField(name="PersonRemark")
+    protected String personRemark;
+    /**鍚▼鏃ユ湡*/
+    @JsonProperty(value = "StartoffDate")
+    @JSONField(name="StartoffDate")
+    protected String startOffDate;
+    /**鍑哄彂鍦扮偣*/
+    @JsonProperty(value = "StartoffPlace")
+    @JSONField(name="StartoffPlace")
+    protected String startOffPlace;
+    /**鍒拌揪鏃ユ湡*/
+    @JsonProperty(value = "ArriveDate")
+    @JSONField(name="ArriveDate")
+    protected String arriveDate;
+    /**鍒拌揪鍦扮偣*/
+    @JsonProperty(value = "ArrivePlace")
+    @JSONField(name="ArrivePlace")
+    protected String arrivePlace;
+    /**鍩庨檯浜ら€氳垂*/
+    @JsonProperty(value = "Amount")
+    @JSONField(name="Amount")
+    protected String amount;
+    /**浼欓琛ュ姪璐�*/
+    @JsonProperty(value = "FoodAmount")
+    @JSONField(name="FoodAmount")
+    protected String foodAmount;
+    /**浣忓璐�*/
+    @JsonProperty(value = "StayAmount")
+    @JSONField(name="StayAmount")
+    protected String stayAmount;
+    /**浜ら€氳ˉ璐磋垂*/
+    @JsonProperty(value = "TrafficActual")
+    @JSONField(name="TrafficActual")
+    protected String trafficActual;
+    /**澶╂暟*/
+    @JsonProperty(value = "Days")
+    @JSONField(name="Days")
+    protected String days;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelInfoRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelInfoRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9838867027f8634791d195024cc30ab4f612c148
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCommonNewExpenseBillByTypeTravelInfoRequest.java
@@ -0,0 +1,36 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓缃戞姤娴佺▼鎺ュ彛宸梾淇℃伅璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCommonNewExpenseBillByTypeTravelInfoRequest implements Serializable {
+
+    /**鍑哄樊浜嬬敱*/
+    @JsonProperty(value = "TravelReasons")
+    @JSONField(name="TravelReasons")
+    protected String travelReasons;
+    /**鎺ュ緟鏂规槸鍚︾粺涓€瀹夋帓椋熷*/
+    @JsonProperty(value = "ArrangeAccommodation")
+    @JSONField(name="ArrangeAccommodation")
+    protected String arrangeAccommodation;
+    /**鍑哄樊鏄庣粏淇℃伅*/
+    @JsonProperty(value = "TravelDetail")
+    @JSONField(name="TravelDetail")
+    protected List<KingDeeCommonNewExpenseBillByTypeTravelDetailRequest> travelDetailList;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCreateFlowOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCreateFlowOut.java
new file mode 100644
index 0000000000000000000000000000000000000000..377ec28ffd4e85e1e1ae5d2b1619ff97dfdbf923
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeCreateFlowOut.java
@@ -0,0 +1,22 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鍒涘缓娴佺▼鎺ュ彛杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeCreateFlowOut extends KingDeeBaseResultOut implements Serializable {
+
+    protected String billId;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultDataOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultDataOut.java
new file mode 100644
index 0000000000000000000000000000000000000000..36cbe949584bfffee37e4052b676171fca5db179
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultDataOut.java
@@ -0,0 +1,37 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鑾峰彇Token鎺ュ彛杩斿洖Data妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeGetTokenResultDataOut implements Serializable {
+
+    /**token*/
+    @JsonProperty(value = "access_token")
+    @JSONField(name="access_token")
+    protected String accessToken;
+    /**浠ょ墝绫诲瀷锛岄粯璁や负Bearer锛屽嵆浠讳綍鎸佹湁token鐨勭敤鎴烽兘鍙互璁块棶瀵瑰簲鐨勮祫婧�*/
+    @JsonProperty(value = "token_type")
+    @JSONField(name="token_type")
+    protected String tokenType;
+    /**浣滅敤鍩燂紝鐢ㄦ埛鎺堟潈缁欑涓夋柟鐨勬潈闄愶紝榛樿涓篈PI*/
+    protected String scope;
+    /**鏈夋晥鏃堕棿*/
+    @JsonProperty(value = "expires_in")
+    @JSONField(name="expires_in")
+    protected Integer expiresIn;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultOut.java
new file mode 100644
index 0000000000000000000000000000000000000000..f41099c5edec45832a13d7b07e90f8d67f35ad1d
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeGetTokenResultOut.java
@@ -0,0 +1,22 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸鑾峰彇Token鎺ュ彛杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeGetTokenResultOut extends KingDeeBaseResultOut implements Serializable {
+
+    protected KingDeeGetTokenResultDataOut data;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultOut.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd4897e75c5e5a4432fa763fc478a04c1d15ee03
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultOut.java
@@ -0,0 +1,22 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸瀹℃壒缁撴灉鍙嶉鎺ュ彛杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeUpdateSeaSkyFiAuditResultOut extends KingDeeBaseResultOut implements Serializable {
+
+    protected String data;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c17139049837d2805de1922bce6d616e5dfb9ea
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/kingDee/KingDeeUpdateSeaSkyFiAuditResultRequest.java
@@ -0,0 +1,37 @@
+package com.seasky.flowportal.dto.kingDee;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("閲戣澏娴佺▼寮曟搸瀹℃壒缁撴灉鍙嶉鎺ュ彛璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class KingDeeUpdateSeaSkyFiAuditResultRequest implements Serializable {
+
+    /**鎶ラ攢绫诲瀷锛屾灇涓惧€硷紙鐢ㄦ鐢宠鍗� = 1,鍥藉唴宸梾鍗� = 2,涓汉鍊熸 = 4, 寰€鏉ユ姤閿€鍗� = 10锛�*/
+    @JsonProperty(value = "BusinessType")
+    @JSONField(name="BusinessType")
+    protected String businessType;
+    /**鎶ラ攢鍗曞彿*/
+    @JsonProperty(value = "OrderNo")
+    @JSONField(name="OrderNo")
+    protected String orderNo;
+    /**钖祫鐢虫姤鍗曞彿*/
+    @JsonProperty(value = "DeclareBillNo")
+    @JSONField(name="DeclareBillNo")
+    protected String declareBillNo;
+    /**瀹℃壒缁撴灉淇℃伅*/
+    protected String auditMessage;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/preExpenseApply/PreExpenseApplyOut.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/preExpenseApply/PreExpenseApplyOut.java
index b76cc58bcfd3415e2a5a7267ba414c4ef0502350..f6911cf3ad8f910c2c91882847dbd65db90e31ec 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/preExpenseApply/PreExpenseApplyOut.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/preExpenseApply/PreExpenseApplyOut.java
@@ -104,8 +104,8 @@ public class PreExpenseApplyOut extends BaseOut implements Serializable {
     public String getFundsProjectCodeAndName() {
         fundsProjectCodeAndName = "";
         try {
-            List<String> fundsProjectNameList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProjectName, "").split(",")).distinct().collect(Collectors.toList());
-            List<String> fundsProjectCodeList = Arrays.stream(ObjectUtils.defaultIfNull(fundsProject, "").split(",")).distinct().collect(Collectors.toList());
+            List<String> fundsProjectNameList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProjectName.split(",")).collect(Collectors.toList());
+            List<String> fundsProjectCodeList = fundsProject == null ? new ArrayList<>() : Arrays.stream(fundsProject.split(",")).collect(Collectors.toList());
             for (int i = 0; i < fundsProjectNameList.size(); i++) {
                 String fundsProjectName = fundsProjectNameList.get(i);
                 String fundsProjectCode = fundsProjectCodeList.get(i);
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskErrorMsgResponse.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskErrorMsgResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b631b2148e93d31ea2d3e1b5ae0e04aefeec3a2
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskErrorMsgResponse.java
@@ -0,0 +1,29 @@
+package com.seasky.flowportal.dto.xingHai;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("鏄熸捣寰呭姙鎺ュ彛浠诲姟閿欒淇℃伅杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class XingHaiTaskErrorMsgResponse implements Serializable {
+
+    /**閿欒鏄庣粏*/
+    protected String errorDetail;
+
+    /**閿欒绫诲瀷*/
+    protected String errorType;
+
+    /**閿欒缂栫爜*/
+    protected Integer errorCode;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskRequest.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c1bc9fde01aa65c692498ba3ee78ddb1f91cc01
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskRequest.java
@@ -0,0 +1,60 @@
+package com.seasky.flowportal.dto.xingHai;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("鏄熸捣寰呭姙鎺ュ彛浠诲姟璇锋眰妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class XingHaiTaskRequest implements Serializable {
+
+    /**浠诲姟id*/
+    protected String taskId;
+
+    /**绯荤粺娉ㄥ唽缂栫爜*/
+    protected String registerCode;
+
+    /**寰呭姙鏍囬*/
+    protected String title;
+
+    /**绗笁鏂瑰緟鍔炲彂璧蜂汉涓婚敭*/
+    protected String thirdSenderId;
+
+    /**绗笁鏂瑰緟鍔炲彂璧蜂汉濮撳悕*/
+    protected String senderName;
+
+    /**绗笁鏂瑰緟鍔炴帴鏀朵汉涓婚敭锛堜繚璇佸敮涓€锛�*/
+    protected String thirdReceiverId;
+
+    /**寰呭姙鍒涘缓鏃堕棿锛堟牸寮忥細yyyy-MM-dd HH:mm:ss锛�*/
+    protected String creationDate;
+
+    /**鐘舵€侊細0:鏈姙鐞嗭紱1:宸插姙鐞�*/
+    protected String state;
+
+    /**澶勭悊鍚庣姸鎬侊細0/1/2/3 鍚屾剰宸插姙/涓嶅悓鎰忓凡鍔�/鍙栨秷/椹冲洖*/
+    protected String subState;
+
+    /**PC绔┛閫忛摼鎺�*/
+    protected String url;
+
+    /**绉诲姩绔┛閫忛摼鎺�*/
+    protected String h5url;
+
+    /**鐧诲綍鍚嶇О/浜哄憳缂栫爜/鎵嬫満鍙�/鐢靛瓙閭欢*/
+    protected String noneBindingSender;
+
+    /**鐧诲綍鍚嶇О/浜哄憳缂栫爜/鎵嬫満鍙�/鐢靛瓙閭欢*/
+    protected String noneBindingReceiver;
+
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskResponse.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..081914b9876128ae4e87a422b59df143a661d05c
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTaskResponse.java
@@ -0,0 +1,33 @@
+package com.seasky.flowportal.dto.xingHai;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@ApiModel("鏄熸捣寰呭姙鎺ュ彛浠诲姟杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class XingHaiTaskResponse implements Serializable {
+
+    public boolean isSuccess() { return Boolean.TRUE.equals(success); }
+
+    /**鏄惁鎴愬姛*/
+    protected Boolean success;
+
+    /**閿欒淇℃伅鍒楄〃*/
+    @JsonProperty(value = "errorMsgs")
+    @JSONField(name="errorMsgs")
+    protected List<XingHaiTaskErrorMsgResponse> errorMsgList;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTokenResponse.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTokenResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b4577d640bb8225032dce1241bfca6151cb2410
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/dto/xingHai/XingHaiTokenResponse.java
@@ -0,0 +1,25 @@
+package com.seasky.flowportal.dto.xingHai;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@ApiModel("鏄熸捣寰呭姙鎺ュ彛Token杩斿洖妯″瀷")
+@Data
+@Builder
+@Accessors(chain = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class XingHaiTokenResponse implements Serializable {
+
+    /**userName*/
+    protected String userName;
+    /**token*/
+    protected String id;
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/HaiYangActionEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowActionEnum.java
similarity index 83%
rename from ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/HaiYangActionEnum.java
rename to ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowActionEnum.java
index fabaef1da7a6aaafe4c4f5675084bbffda28711f..5a78286575b21038add76f641681dd325c6a297a 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/HaiYangActionEnum.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowActionEnum.java
@@ -1,7 +1,7 @@
 package com.seasky.flowportal.enums;
 
 
-public enum HaiYangActionEnum {
+public enum BusFlowActionEnum {
 
     FinishTodo("瀹屾垚", 0),
     CancelTodo("鍙栨秷", 1),
@@ -14,7 +14,7 @@ public enum HaiYangActionEnum {
 
     private final int index;
 
-    HaiYangActionEnum(String name, int index) {
+    BusFlowActionEnum(String name, int index) {
         this.name = name;
         this.index = index;
     }
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowServiceNameEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowServiceNameEnum.java
index f0d5b08df3157e7d1d1d641ce0b10993f8335a0a..bcbd0df8b13f0724d915b745d620389d58751bd2 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowServiceNameEnum.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/BusFlowServiceNameEnum.java
@@ -10,6 +10,7 @@ public enum BusFlowServiceNameEnum {
     SUDI("BusFlowServiceSudiImpl"),
     HAIYANG("BusFlowServiceHaiYangImpl"),
     GUANGZHONGYI("BusFlowServiceGuangZhongYiImpl"),
+    XINGHAI("BusFlowServiceXingHaiImpl"),
     ;
 
     /**
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowEngineEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowEngineEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..85d5b06bac32941f5f83a044832b46ea3f8f25ae
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowEngineEnum.java
@@ -0,0 +1,41 @@
+package com.seasky.flowportal.enums;
+
+/**
+ * @author liyulu
+ * @since 2022/1/5
+ */
+public enum FlowEngineEnum {
+
+    SEA_SKY("娴峰ぉ"),
+    KING_DEE("閲戣澏"),
+    ;
+
+    /**
+     * 鏋氫妇灞炴€ц鏄�
+     */
+    private final String name;
+
+    FlowEngineEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName(){
+        return  this.name;
+    }
+
+
+    /**
+     * 閫氳繃key 鏌ユ壘鎻忚堪 鏂规硶
+     *
+     * @param name
+     */
+    public static FlowEngineEnum getValueByName(String name) {
+        for (FlowEngineEnum anEnum : FlowEngineEnum.values()) {
+            if (anEnum.getName().equals(name)) {
+                return anEnum;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowServiceNameEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowServiceNameEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbd82aebe81ea9ed4689ed28f2de8fa119a2464e
--- /dev/null
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/FlowServiceNameEnum.java
@@ -0,0 +1,41 @@
+package com.seasky.flowportal.enums;
+
+/**
+ * @author chenmin
+ * @since 2022/1/5
+ */
+public enum FlowServiceNameEnum {
+
+    SEA_SKY("FlowServiceImpl"),
+    KING_DEE("FlowServiceKingDeeImpl"),
+    ;
+
+    /**
+     * 鏋氫妇灞炴€ц鏄�
+     */
+    private final String name;
+
+    FlowServiceNameEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName(){
+        return  this.name;
+    }
+
+
+    /**
+     * 閫氳繃key 鏌ユ壘鎻忚堪 鏂规硶
+     *
+     * @param name
+     */
+    public static FlowServiceNameEnum getValueByName(String name) {
+        for (FlowServiceNameEnum anEnum : FlowServiceNameEnum.values()) {
+            if (anEnum.getName().equals(name)) {
+                return anEnum;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/GuangZhongYiActionEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/GuangZhongYiActionEnum.java
deleted file mode 100644
index 29ed8ad52019d5253433d09021f18cd184de7327..0000000000000000000000000000000000000000
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/GuangZhongYiActionEnum.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.seasky.flowportal.enums;
-
-
-public enum GuangZhongYiActionEnum {
-
-    FinishTodo("瀹屾垚", 0),
-    CancelTodo("鍙栨秷", 1),
-    CreateTodo("鍒涘缓", 2);
-
-    /**
-     * 鏋氫妇灞炴€ц鏄�
-     */
-    private final String name;
-
-    private final int index;
-
-    GuangZhongYiActionEnum(String name, int index) {
-        this.name = name;
-        this.index = index;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public int getIndex() {
-        return index;
-    }
-
-}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/SudiActionEnum.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/SudiActionEnum.java
deleted file mode 100644
index dfcdf3d6ad17b17f7bc6f388a1fc55d4b90eb41f..0000000000000000000000000000000000000000
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/enums/SudiActionEnum.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.seasky.flowportal.enums;
-
-
-public enum SudiActionEnum {
-
-    FinishTodo("瀹屾垚", 0),
-    CancelTodo("鍙栨秷", 1),
-    CreateTodo("鍒涘缓", 2);
-
-    /**
-     * 鏋氫妇灞炴€ц鏄�
-     */
-    private final String name;
-
-    private final int index;
-
-    SudiActionEnum(String name, int index) {
-        this.name = name;
-        this.index = index;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public int getIndex() {
-        return index;
-    }
-
-}
diff --git a/ServiceSite/facade/src/main/java/com/seasky/flowportal/pojo/ExternalPostPojo.java b/ServiceSite/facade/src/main/java/com/seasky/flowportal/pojo/ExternalPostPojo.java
index 2cd4a6033d62d6dd70aee9e6d2a745ba4f55f2c8..8c354241aaec0a153b9c0eb2a69409468c02baa3 100644
--- a/ServiceSite/facade/src/main/java/com/seasky/flowportal/pojo/ExternalPostPojo.java
+++ b/ServiceSite/facade/src/main/java/com/seasky/flowportal/pojo/ExternalPostPojo.java
@@ -86,5 +86,6 @@ public class ExternalPostPojo extends BaseDto implements Serializable {
     private String projectFilter;
 
     private String configKey;
+    private String declareBillNo;
 
 }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/config/BaseConfigProperties.java b/ServiceSite/src/main/java/com/seasky/flowportal/config/BaseConfigProperties.java
index 3dfa4feeef6fcd6e4f88d6c2cf9271b22954ff1f..e0c522e41700701fd99264c2fdc64a27d7da6231 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/config/BaseConfigProperties.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/config/BaseConfigProperties.java
@@ -2,6 +2,7 @@ package com.seasky.flowportal.config;
 
 import com.seasky.flowportal.enums.BusFlowServiceNameEnum;
 import com.seasky.flowportal.enums.FileStatusEnum;
+import com.seasky.flowportal.enums.FlowServiceNameEnum;
 import com.seasky.flowportal.enums.SchoolEnum;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -240,6 +241,7 @@ public class BaseConfigProperties extends ConstantConfigProperties implements Se
     public boolean isBusFlowServiceSudiImpl() { return BusFlowServiceNameEnum.SUDI.getName().equals(busFlowServiceName); }
     public boolean isBusFlowServiceHaiYangImpl() { return BusFlowServiceNameEnum.HAIYANG.getName().equals(busFlowServiceName); }
     public boolean isBusFlowServiceGuangZhongYiImpl() { return BusFlowServiceNameEnum.GUANGZHONGYI.getName().equals(busFlowServiceName); }
+    public boolean isBusFlowServiceXingHaiImpl() { return BusFlowServiceNameEnum.XINGHAI.getName().equals(busFlowServiceName); }
 
     /**骞夸腑鍖诲緟鍔炴帴鍙e湴鍧€*/
     private String guangZhongYiUrl;
@@ -270,5 +272,33 @@ public class BaseConfigProperties extends ConstantConfigProperties implements Se
     /**鏄惁寮€鍚洖閫€鍔熻兘*/
     private Boolean needShowRegress;
 
+    /**娴佺▼寮曟搸鐗堟湰*/
+    protected String flowServiceName;
+    public boolean isFlowServiceImpl() {
+        FlowServiceNameEnum flowServiceNameEnum = FlowServiceNameEnum.getValueByName(flowServiceName);
+        return ObjectUtils.isEmpty(flowServiceNameEnum) || FlowServiceNameEnum.SEA_SKY.equals(flowServiceNameEnum);
+    }
+    public boolean isFlowServiceKingDeeImpl() { return FlowServiceNameEnum.KING_DEE.getName().equals(flowServiceName); }
+
+    /**閲戣澏娴佺▼寮曟搸鎺ュ彛鍦板潃*/
+    private String kingDeeUrl;
+    /**閲戣澏娴佺▼寮曟搸搴旂敤ID*/
+    private String kingDeeClientId;
+    /**閲戣澏娴佺▼寮曟搸搴旂敤瀵嗛挜*/
+    private String kingDeeClientSecret;
+    /**閲戣澏娴佺▼寮曟搸搴旂敤浠g悊鐢ㄦ埛鍚�*/
+    private String kingDeeClientUserName;
+    /**閲戣澏娴佺▼寮曟搸璐︽埛ID*/
+    private String kingDeeAccountId;
+
+    /**鏄熸捣寰呭姙鎺ュ彛鍦板潃*/
+    private String xingHaiUrl;
+    /**鏄熸捣寰呭姙token鎺ュ彛鐢ㄦ埛鍚�*/
+    private String xingHaiUserName;
+    /**鏄熸捣寰呭姙token鎺ュ彛瀵嗙爜*/
+    private String xingHaiPassword;
+    /**鏄熸捣寰呭姙鎺ュ彛绯荤粺娉ㄥ唽缂栫爜*/
+    private String xingHaiRegisterCode;
+
 
 }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/constant/InterfaceUrlConstant.java b/ServiceSite/src/main/java/com/seasky/flowportal/constant/InterfaceUrlConstant.java
index 18a860ff95d2b12b8602f19ada18554e68aff865..ad5775fd432987d3d40f6a774e801e9ff104cbb7 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/constant/InterfaceUrlConstant.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/constant/InterfaceUrlConstant.java
@@ -48,6 +48,8 @@ public class InterfaceUrlConstant {
     public static final String EXTERNAL_QUERY_AUDIT_SUPPLEMENT_FLAGS = "externalInterfaceUrl" + "/ClaimsInterface/QueryAuditSupplementFlags";
 
     public static final String EXTERNAL_QUERY_FILE_INFO = "externalInterfaceUrl" + "/ClaimsInterface/QueryFileInfo";
+    public static final String EXTERNAL_QUERY_ORDER_INFO = "externalInterfaceUrl" + "/ClaimsInterface/QueryOrderInfo";
+    public static final String EXTERNAL_GET_SALARY_DECLARE_ORDER_DETAIL = "externalInterfaceUrl" + "/ClaimsInterface/GetSalaryDeclareOrderDetail";
     //#endregion externalInterfaceUrl
 
     //#region innerInterfaceUrl
@@ -195,6 +197,19 @@ public class InterfaceUrlConstant {
     public static final String GUANGZHONGYI_PUSH_TASK = "guangZhongYiUrl" + "/third/api/third/task.push.push-task";
     //#endregion guangZhongYiUrl
 
+    //#region kingDeeUrl
+    public static final String KINGDEE_GET_TOKEN = "kingDeeUrl" + "/oauth2/getToken";
+    public static final String KINGDEE_COMMON_NEW_EXPENSE_BILL_BY_TYPE = "kingDeeUrl" + "/v2/shkd/exp/commonNewExpenseBillByType";
+    public static final String KINGDEE_ADD_SALARY_BILL = "kingDeeUrl" + "/v2/shkd/shkd_exp_ext/addSalaryBill";
+    public static final String KINGDEE_UPDATE_AUDIT_RESULT = "kingDeeUrl" + "/v2/shkd/shkd_exp_ext/updateSeaSkyFiAuditResult";
+    //#endregion kingDeeUrl
+
+    //#region xingHaiUrl
+    public static final String XINGHAI_TOKEN = "xingHaiUrl" + "/seeyon/rest/token";
+    public static final String XINGHAI_RECEIVE_PENDING = "xingHaiUrl" + "/seeyon/rest/thirdpartyPending/receive";
+    public static final String XINGHAI_UPDATE_PENDING_STATE = "xingHaiUrl" + "/seeyon/rest/thirdpartyPending/updatePendingState";
+    //#endregion xingHaiUrl
+
     //#region 寮冪敤
     public static final String DIGITAL_AUTH_ADD_USER = "signatureDigitalAuthUrl" + "/AuthSignService/user/v2/cert/addUser";
 
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/controller/AttachFileController.java b/ServiceSite/src/main/java/com/seasky/flowportal/controller/AttachFileController.java
index 110bc5cca58a51190efbd4a80cf1e0e2aee19490..c59a9de14451e573d807e05d6fc5e8cbf2c92a3d 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/controller/AttachFileController.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/controller/AttachFileController.java
@@ -18,11 +18,7 @@ import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.enums.PortalResponseCode;
 import com.seasky.flowportal.mapper.ExpenseReimbursementMapper;
 import com.seasky.flowportal.service.AttachFileService;
-import com.seasky.flowportal.service.FlowService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
-import com.seasky.flowportal.utils.FileUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,9 +39,6 @@ public class AttachFileController implements IAttachFileController {
     @Autowired
     private AttachFileService attachFileService;
 
-    @Autowired
-    private FlowService flowService;
-
     @Autowired
     @Lazy
     protected ExpenseReimbursementMapper expenseReimbursementMapper;
@@ -70,7 +63,7 @@ public class AttachFileController implements IAttachFileController {
         String processInstanceId = po.getProcessInstanceId();
         if (ObjectUtils.isEmpty(processInstanceId))
             return ok(PortalResponseCode.SUCCESS, true);
-        NodeOut curNodeInfo = flowService.getCurNodeInfo(FlowQuery.builder().processInstanceId(processInstanceId).build());
+        NodeOut curNodeInfo = FlowUtil.INSTANCE(instanceId).getCurNodeInfo(FlowQuery.builder().processInstanceId(processInstanceId).build());
         String orderStatus = ObjectUtils.isEmpty(curNodeInfo) ? "" : curNodeInfo.getNodeName();
         boolean isFinish = OrderStatusEnum.FINISH.getName().equals(orderStatus);
         if (!isFinish)
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/controller/ExternalController.java b/ServiceSite/src/main/java/com/seasky/flowportal/controller/ExternalController.java
index 4d3e55fa47ab81e340b4c221c7cc73d3aa2f349b..7f9a50d0a5fe2ee7b6f2998ff9c205f38b3b4c30 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/controller/ExternalController.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/controller/ExternalController.java
@@ -3,6 +3,7 @@ package com.seasky.flowportal.controller;
 import com.seasky.core.common.Pagination;
 import com.seasky.core.ddd.utils.MapperUtils;
 import com.seasky.flowportal.api.IExternalController;
+import com.seasky.flowportal.dto.apply.ApplyListCmd;
 import com.seasky.flowportal.dto.approverUser.*;
 import com.seasky.flowportal.dto.expenseReimbursement.ExpenseReimbursementCmd;
 import com.seasky.flowportal.dto.expenseReimbursement.ExpenseReimbursementSFP2Cmd;
@@ -26,6 +27,7 @@ import lombok.SneakyThrows;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.ArrayList;
@@ -57,6 +59,12 @@ public class ExternalController implements IExternalController {
         return ok(PortalResponseCode.SUCCESS, preExpenseApplyService.savePreExpenseApply(preExpenseApplyCmd));
     }
 
+    @Override
+    @SneakyThrows
+    public BaseResultModel<String> approvalDetail(@RequestBody ApplyListCmd cmd) {
+        return ok(PortalResponseCode.SUCCESS, "");
+    }
+
 
     @Override
     @SneakyThrows
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/controller/MyFlowController.java b/ServiceSite/src/main/java/com/seasky/flowportal/controller/MyFlowController.java
index dc4bf8f5d9984e02cd5cac48437b4f272160f871..43174577dcc05a90ab40f69bdf5861741a33becb 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/controller/MyFlowController.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/controller/MyFlowController.java
@@ -21,7 +21,6 @@ import com.seasky.flowportal.enums.FlowQueryEnum;
 import com.seasky.flowportal.enums.PortalResponseCode;
 import com.seasky.flowportal.enums.SchoolEnum;
 import com.seasky.flowportal.service.ExpenseReimbursementService;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -37,16 +36,13 @@ import static com.seasky.flowportal.dto.response.PortalResponse.ok;
 @Slf4j
 public class MyFlowController implements IMyFlowController {
 
-    @Autowired
-    private FlowService flowService;
-
     @Autowired
     private ExpenseReimbursementService expenseReimbursementService;
 
     @Override
     public BaseResultModel<String> remindToDo(ApprovalRemindTodoCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
-        return ok(PortalResponseCode.SUCCESS, flowService.remindToDo(cmd));
+        return ok(PortalResponseCode.SUCCESS, FlowUtil.INSTANCE(instanceId).remindToDo(cmd));
     }
 
     @Override
@@ -54,7 +50,7 @@ public class MyFlowController implements IMyFlowController {
         log.info("MyFlowController, listFlowTool, flowOpen: " + flowOpen);
         log.info("MyFlowController, listFlowTool, query: " + JSONObject.toJSONString(query));
         Long instanceId = BaseInOutUtil.verifyInstanceId(query);
-        return ok(PortalResponseCode.SUCCESS, flowService.listFlowTool(query, flowOpen));
+        return ok(PortalResponseCode.SUCCESS, FlowUtil.INSTANCE(instanceId).listFlowTool(query, flowOpen));
     }
 //
 //    @Override
@@ -95,7 +91,7 @@ public class MyFlowController implements IMyFlowController {
         instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
         UserInfoOut loginUser = LoginUtil.getLoginUser();
         FlowQuery flowQuery = FlowQuery.builder().userId(loginUser.getUserNo()).build();
-        return ok(PortalResponseCode.SUCCESS, flowService.listTodoAll(flowQuery).size());
+        return ok(PortalResponseCode.SUCCESS, FlowUtil.INSTANCE(instanceId).listTodoAll(flowQuery).size());
     }
 
     @Override
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/ExternalDataService.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/ExternalDataService.java
index 0ea43e28d961214e2c18b24ae24223a8a01654d1..19632c7494e8fde361b1f9f6a057a3dbd1c75919 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/ExternalDataService.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/ExternalDataService.java
@@ -21,6 +21,8 @@ import com.seasky.flowportal.dto.departmentInfo.DepartmentInfoOut;
 import com.seasky.flowportal.dto.extendData.ExtendFieldCmd;
 import com.seasky.flowportal.dto.fapiao.FapiaoDownloadOut;
 import com.seasky.flowportal.dto.fundsFlowDetail.FundsFlowDetailClaimsOut;
+import com.seasky.flowportal.dto.kingDee.KingDeeAddSalaryBillRequest;
+import com.seasky.flowportal.dto.kingDee.KingDeeCommonNewExpenseBillByTypeRequest;
 import com.seasky.flowportal.dto.organization.OrganizationInfoOut;
 import com.seasky.flowportal.dto.personInfo.PersonFromOrgInfoOut;
 import com.seasky.flowportal.dto.personInfo.PersonInfoOut;
@@ -234,4 +236,15 @@ public interface ExternalDataService {
     Pagination<DanaCountryInfoOut> queryDanaCountry(DanaCountryInfoQuery qry);
     Pagination<DanaProvinceInfoOut> queryDanaProvince(DanaProvinceInfoQuery qry);
     Pagination<DanaCityInfoOut> queryDanaCity(DanaCityInfoQuery qry);
+
+    public String getKingDeeToken(Long instanceId);
+
+    public String commonNewExpenseBillByType(Long instanceId, String orderCode);
+
+    public String addSalaryBill(Long instanceId, String orderCode);
+    public String updateSeaSkyFiAuditResult(ApplyOut applyOut);
+    public String updateSeaSkyFiAuditResult(Long instanceId, String orderCode, String orderType, String approvalOpinion);
+
+    public KingDeeCommonNewExpenseBillByTypeRequest queryClaimsOrderInfo(Long instanceId, String orderCode);
+    public KingDeeAddSalaryBillRequest getSalaryDeclareOrderDetail(Long instanceId, String orderCode);
 }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/FlowService.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/FlowService.java
index 7fbb9e7b7135658eb469574db703fabd25c45a20..e326de04edb4693c37a93911b38a1f43683da197 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/FlowService.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/FlowService.java
@@ -1,11 +1,13 @@
 package com.seasky.flowportal.service;
 
+import com.alibaba.fastjson.JSON;
 import com.seasky.core.ddd.utils.MapperUtils;
 import com.seasky.core.util.ExceptionUtil;
 import com.seasky.flow.dto.flow.*;
 import com.seasky.flow.dto.processDefinition.ProcessDefinitionOut;
 import com.seasky.flow.dto.task.NodeOut;
 import com.seasky.flowportal.domain.po.ApprovalPo;
+import com.seasky.flowportal.dto.apply.ApplyListOut;
 import com.seasky.flowportal.dto.approval.ApprovalCmd;
 import com.seasky.flowportal.dto.approval.ApprovalQuery;
 import com.seasky.flowportal.dto.approval.ApprovalRemindTodoCmd;
@@ -13,18 +15,23 @@ import com.seasky.flowportal.dto.flow.FlowCmd;
 import com.seasky.flowportal.dto.flow.FlowOut;
 import com.seasky.flowportal.dto.flow.FlowQuery;
 import com.seasky.flowportal.dto.flowTool.FlowToolOut;
-import com.seasky.flowportal.enums.FlowOpenEnum;
+import com.seasky.flowportal.enums.FlowEngineEnum;
 import com.seasky.flowportal.enums.OpenEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.utils.ApprovalUtil;
 import com.seasky.flowportal.utils.BaseInOutUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+@Slf4j
 public abstract class FlowService {
+    
+    public FlowEngineEnum getFlowEngine() { return FlowEngineEnum.SEA_SKY; }
 
     public String remindToDo(ApprovalRemindTodoCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
@@ -51,83 +58,120 @@ public abstract class FlowService {
      * @param enumMyAppsOpen
      * @return
      */
-    public abstract FlowToolOut listFlowTool(FlowQuery flowQuery, String flowOpen);
+    public FlowToolOut listFlowTool(FlowQuery flowQuery, String flowOpen) { return null; }
     /**
      * 娴佺▼缁熶竴鎿嶄綔
      * @param open
      * @param flowCmd
      * @return
      */
-    public abstract String saveFlow(Long instanceId, OpenEnum open, FlowCmd flowCmd);
+    public String saveFlow(Long instanceId, OpenEnum open, FlowCmd flowCmd) {
+        log.info("鎿嶄綔锛歿},鍙傛暟锛歿}", open.getName(), JSON.toJSONString(flowCmd));
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        flowCmd.setInstanceId(instanceId);
+        String result = "";
+        switch (open) {
+            case CREATE:
+                result = createFlow(flowCmd);
+                break;
+            case SUBMIT:
+                result = submitFlow(flowCmd);
+                break;
+            case BACK:
+                result = backFlow(flowCmd);
+                break;
+            case REVOKE:
+                result = revokeFlow(flowCmd);
+                break;
+            case REGRESS:
+                result = regressFlow(flowCmd);
+                break;
+            case COPY:
+                result = copyFlow(flowCmd);
+                break;
+            case CHECK_COPY:
+                result = checkCopyFlow(flowCmd);
+                break;
+            case AUTHORIZE:
+                result = authorizeFlow(flowCmd);
+                break;
+            case SET_CO_AUDIT:
+                result = setCoAuditFlow(flowCmd);
+                break;
+            default:
+                throw ExceptionUtil.getException(null, "娌℃湁褰撳墠鎿嶄綔鏂规硶");
+        }
+        return result;
+    }
     /**
      * 鍙戣捣娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String createFlow(FlowCmd flowCmd);
-    public abstract boolean isStartProcessAndAutoComplete(FlowCmd flowCmd);
+    public String createFlow(FlowCmd flowCmd) { return null; }
+    public boolean isStartProcessAndAutoComplete(FlowCmd flowCmd) { return true; }
     /**
      * 鎻愪氦娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String submitFlow(FlowCmd flowCmd);
+    public String submitFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 鎾ゅ洖娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String revokeFlow(FlowCmd flowCmd);
+    public String revokeFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 瀹℃壒椹冲洖娴佺▼锛屽彲璺宠浆鍒般€愬鎵归┏鍥炪€戣妭鐐�
      * @param flowCmd
      * @return
      */
-    public abstract String backFlow(FlowCmd flowCmd);
+    public String backFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 璺宠浆椹冲洖娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String regressFlow(FlowCmd flowCmd);
+    public String regressFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 璺宠浆娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String jumpFlow(FlowCmd flowCmd);
+    public String jumpFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 鎶勯€佹祦绋�
      * @param flowCmd
      * @return
      */
-    public abstract String copyFlow(FlowCmd flowCmd);
+    public String copyFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 鏌ラ槄鎶勯€佹祦绋�
      * @param flowCmd
      * @return
      */
-    public abstract String checkCopyFlow(FlowCmd flowCmd);
+    public String checkCopyFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 鎺堟潈瀹℃壒娴佺▼
      * @param flowCmd
      * @return
      */
-    public abstract String authorizeFlow(FlowCmd flowCmd);
+    public String authorizeFlow(FlowCmd flowCmd) { return null; }
 
     /**
      * 璁剧疆鍗忓姙骞舵彁浜ゆ祦绋�
      * @param flowCmd
      * @return
      */
-    public abstract String setCoAuditFlow(FlowCmd flowCmd);
+    public String setCoAuditFlow(FlowCmd flowCmd) { return null; }
 
 
 
@@ -136,140 +180,145 @@ public abstract class FlowService {
      * @param flowQuery
      * @return
      */
-    public abstract List<NodeOut> getNextNodes(FlowQuery flowQuery);
+    public List<NodeOut> getNextNodes(FlowQuery flowQuery) { return null; }
 
-    /**
-     * 鑾峰彇褰撳墠瀹℃牳浜篿d
-     * @param flowQuery
-     * @return
-     */
-    public abstract List<String> getCurAuditorId(FlowQuery flowQuery);
+//    /**
+//     * 鑾峰彇褰撳墠瀹℃牳浜篿d
+//     * @param flowQuery
+//     * @return
+//     */
+//    public List<String> getCurAuditorId(FlowQuery flowQuery) { return null; }
 
     /**
      * 鑾峰彇鎵€鏈夌粡杩囩殑娴佺▼鑺傜偣
      * @param flowQuery
      * @return
      */
-    public abstract List<HistoryInfoOut> getFlowHistory(FlowQuery flowQuery);
+    public List<HistoryInfoOut> getFlowHistory(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      * 鑾峰彇鎵€鏈夌粡杩囩殑娴佺▼鑺傜偣
      * @param flowQuery
      * @return
      */
-    public abstract List<HistoryInfo2Out> getFlowHistory2(FlowQuery flowQuery);
+    public List<HistoryInfo2Out> getFlowHistory2(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      * 鑾峰彇鎵€鏈夌粡杩囩殑娴佺▼鑺傜偣
      * @param flowQuery
      * @return
      */
-    public abstract List<HistoryInfoOut> getSubTaskHistory(FlowQuery flowQuery);
+    public List<HistoryInfoOut> getSubTaskHistory(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      * 瀹℃壒鍘嗗彶
      * @param flowQuery
      * @return
      */
-    public abstract  List<HistoricActivityInstanceOut> getApproveHistory(FlowQuery flowQuery);
+    public  List<HistoricActivityInstanceOut> getApproveHistory(FlowQuery flowQuery) { return new ArrayList<>(); }
 
-    /**
-     * 鏍规嵁娴佺▼ID鑾峰彇娴佺▼鐨勬墍鏈夎妭鐐�
-     * @param flowId
-     * @return
-     */
-   // public abstract List<FlowNodeOut> getFlowInfo(String flowId);
+//    /**
+//     * 鏍规嵁娴佺▼ID鑾峰彇娴佺▼鐨勬墍鏈夎妭鐐�
+//     * @param flowId
+//     * @return
+//     */
+//    public List<FlowNodeOut> getFlowInfo(String flowId) { return new ArrayList<>(); }
 
     /**
      * 鑾峰彇褰撳墠瀹℃牳鐘舵€�
      * @param flowQuery
      * @return
      */
-    public abstract NodeOut getCurNodeInfo(FlowQuery flowQuery);
+    public NodeOut getCurNodeInfo(FlowQuery flowQuery) { return null; }
 
     /**
      *
      * @param flowQuery
      * @return
      */
-    public abstract List<FlowOut> getTodoListByProcessInstanceId(FlowQuery flowQuery);
+    public List<FlowOut> getTodoListByProcessInstanceId(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      * 鑾峰彇涓婁竴鍓嶅鏍歌妭鐐圭姸鎬�
      * @param
      * @return
      */
-    public abstract NodeOut getPreviousNodeInfo(FlowQuery flowQuery);
+    public NodeOut getPreviousNodeInfo(FlowQuery flowQuery) { return null; }
 
     /**
      *
      * @param flowQuery
      * @return
      */
-    public abstract List<TaskOut> listTodoAll(FlowQuery flowQuery);
+    public List<TaskOut> listTodoAll(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      *
      * @param flowQuery
      * @return
      */
-    public abstract List<HistoricActivityInstanceOut> listDoneAll(FlowQuery flowQuery);
+    public List<HistoricActivityInstanceOut> listDoneAll(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      *
      * @param flowQuery
      * @return
      */
-    public abstract List<HistoricActivityInstanceOut> listFinishAll(FlowQuery flowQuery);
+    public List<HistoricActivityInstanceOut> listFinishAll(FlowQuery flowQuery) { return new ArrayList<>(); }
 
-    /**
-     *
-     * @param flowQuery
-     * @param flowOpenEnum
-     * @return
-     */
-    public abstract Integer createFlowAgain(FlowQuery flowQuery, FlowOpenEnum flowOpenEnum);
+//    /**
+//     *
+//     * @param flowQuery
+//     * @param flowOpenEnum
+//     * @return
+//     */
+//    public Integer createFlowAgain(FlowQuery flowQuery, FlowOpenEnum flowOpenEnum) { return null; }
 
     /**
      * 鑾峰彇鍙挙鍥炶妭鐐�
      * @param flowQuery
      * @return
      */
-    public abstract NodeOut getCanRevokeNode(FlowQuery flowQuery);
+    public NodeOut getCanRevokeNode(FlowQuery flowQuery) { return null; }
 
     /**
      * 鑾峰彇鎶勯€佷俊鎭�
      * @param flowQuery
      * @return
      */
-    public abstract List<TaskOut> listCopyByTaskId(FlowQuery flowQuery);
+    public List<TaskOut> listCopyByTaskId(FlowQuery flowQuery) { return new ArrayList<>(); }
 
     /**
      * 鑾峰彇鍗曚釜娴佺▼瀹氫箟淇℃伅
      * @param processInstanceId
      * @return
      */
-    public abstract ProcessDefinitionOut getProcessDefinitionInfo(String processInstanceId);
+    public ProcessDefinitionOut getProcessDefinitionInfo(String processInstanceId) { return null; }
 
     /**
      * 鑾峰彇鍗曚釜鑺傜偣瀹氫箟淇℃伅
      * @param activityId
      * @return
      */
-    public abstract FlowNode getFlowNodeInfoById(String processInstanceId, String activityId);
+    public FlowNode getFlowNodeInfoById(String processInstanceId, String activityId) { return null; }
 
     /**
      * 鑾峰彇鍗曚釜娴佺▼瀹氫箟淇℃伅
      * @param processDefinitionKey
      * @return
      */
-    public abstract ProcessDefinitionOut getProcessDefinitionInfoByKey(String processDefinitionKey);
-    public abstract Map<String, Object> getProcessVariableList(String processInstanceId);
+    public ProcessDefinitionOut getProcessDefinitionInfoByKey(String processDefinitionKey) { return null; }
+    public Map<String, Object> getProcessVariableList(String processInstanceId) { return null; }
 
-    public abstract String getProcessVariableByProcessInstanceIdAndName(String processInstanceId, String variableName);
+    public String getProcessVariableByProcessInstanceIdAndName(String processInstanceId, String variableName) { return null; }
 
-    public abstract Date getCurrentDate();
+    public Date getCurrentDate() { return null; }
 
-    //public abstract FlowEngineEnum GetFlowEngine() { return FlowEngineEnum.MyApps; }
+    /**
+     * 鏇存柊瀹℃壒缁撴灉鑷冲閮ㄦ祦绋嬪紩鎿�
+     * @param applyListOut
+     * @return
+     */
+    public String updateAuditResult(ApplyListOut applyListOut) { return null; }
 
 }
\ No newline at end of file
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/context/BusFlowServiceContext.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/context/BusFlowServiceContext.java
index e33cf440cb64f326bf3448d6ea1965b0492af158..557f2ac47bc73f1c468338f8b9226779f66bce55 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/context/BusFlowServiceContext.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/context/BusFlowServiceContext.java
@@ -23,7 +23,7 @@ public class BusFlowServiceContext {
     public BusFlowService getTaskService(Long instanceId) {
         String type = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId).getBusFlowServiceName();
         if (ObjectUtils.isEmpty(type))
-            return serviceMap.get(BusFlowServiceNameEnum.HAIYANG.getName());
+            return serviceMap.get(BusFlowServiceNameEnum.SUDI.getName());
         return serviceMap.get(type);
     }
 
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/context/FlowServiceContext.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/context/FlowServiceContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..e64c2412be113953cac9881a6eaa0b0e20c10aa8
--- /dev/null
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/context/FlowServiceContext.java
@@ -0,0 +1,41 @@
+package com.seasky.flowportal.service.context;
+
+import com.seasky.flowportal.enums.FlowServiceNameEnum;
+import com.seasky.flowportal.service.FlowService;
+import com.seasky.flowportal.utils.BaseConfigUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 鍔ㄦ€佽皟鐢� FlowService 澶勭悊绫�
+ */
+@Service
+@Slf4j
+public class FlowServiceContext {
+
+    @Resource
+    private Map<String, FlowService> serviceMap;
+
+    public FlowService getTaskService(Long instanceId) {
+        try {
+            String type = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId).getFlowServiceName();
+            if (ObjectUtils.isEmpty(type))
+                return serviceMap.get(FlowServiceNameEnum.SEA_SKY.getName());
+            return serviceMap.get(type);
+        }
+        catch (Exception e) {
+            return serviceMap.get(FlowServiceNameEnum.SEA_SKY.getName());
+        }
+    }
+
+    public FlowService getTaskService(FlowServiceNameEnum flowServiceNameEnum) {
+        if (ObjectUtils.isEmpty(flowServiceNameEnum))
+            return serviceMap.get(FlowServiceNameEnum.SEA_SKY.getName());
+        return serviceMap.get(flowServiceNameEnum.getName());
+    }
+
+}
\ No newline at end of file
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ApproverUserServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ApproverUserServiceImpl.java
index c13eaff2a62bf19d53d28b8cd2848bd2d0cbe58a..85c77bea0e843bf8aa850b7a9be9e8ade08fa9a2 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ApproverUserServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ApproverUserServiceImpl.java
@@ -26,11 +26,7 @@ import com.seasky.flowportal.mapper.ApprovalMapper;
 import com.seasky.flowportal.mapper.ApproverUserMapper;
 import com.seasky.flowportal.mapper.ExpenseReimbursementMapper;
 import com.seasky.flowportal.service.ApproverUserService;
-import com.seasky.flowportal.service.FlowService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
-import com.seasky.flowportal.utils.PageUtil;
+import com.seasky.flowportal.utils.*;
 import org.activiti.bpmn.model.ExtensionAttribute;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,10 +42,6 @@ public class ApproverUserServiceImpl implements ApproverUserService {
     @Lazy
     private ApproverUserMapper approverUserMapper;
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     @Autowired
     @Lazy
     private ExpenseReimbursementMapper expenseReimbursementMapper;
@@ -98,7 +90,7 @@ public class ApproverUserServiceImpl implements ApproverUserService {
     @Override
     public Pagination<UserInfoOut> listApproverUser(ApproverUserQuery query) {
         Long instanceId = query.getInstanceId();
-        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(query.getProcessInstanceId(), query.getSelectApproverName());
+        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(query.getProcessInstanceId(), query.getSelectApproverName());
         List<UserInfoOut> userInfoOutList = null;
         try { userInfoOutList = JSONArray.parseArray(processVariable, UserInfoOut.class); } catch (Exception ignored) { }
         if (ObjectUtils.isEmpty(userInfoOutList)) {
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceGuangZhongYiImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceGuangZhongYiImpl.java
index 0e31b806950f1a27eab91d7bba7d61145aa93c84..9aabb40f2dde1474d586cd90dfa48b5d8a2f01ae 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceGuangZhongYiImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceGuangZhongYiImpl.java
@@ -22,7 +22,7 @@ import com.seasky.flowportal.dto.response.BaseResultModel;
 import com.seasky.flowportal.dto.response.ErrorResultModel;
 import com.seasky.flowportal.dto.response.SuccessResultModel;
 import com.seasky.flowportal.enums.ExecutionStatusEnum;
-import com.seasky.flowportal.enums.GuangZhongYiActionEnum;
+import com.seasky.flowportal.enums.BusFlowActionEnum;
 import com.seasky.flowportal.enums.OpenEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.mapper.ApprovalMapper;
@@ -78,7 +78,7 @@ public class BusFlowServiceGuangZhongYiImpl extends BusFlowServiceImpl {
         OpenEnum openEnum = OpenEnum.getValueByIndex(cmd.getOpen());
         switch (openEnum) {
             case CREATE:
-                result = executeTodo(cmd, GuangZhongYiActionEnum.CreateTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.CreateTodo);
                 break;
             case SUBMIT:
             case BACK:
@@ -86,11 +86,11 @@ public class BusFlowServiceGuangZhongYiImpl extends BusFlowServiceImpl {
             case CHECK_COPY:
             case AUTHORIZE:
             case SET_CO_AUDIT:
-                result = executeTodo(cmd, GuangZhongYiActionEnum.FinishTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.FinishTodo);
                 break;
             case REVOKE:
             case REGRESS:
-                result = executeTodo(cmd, GuangZhongYiActionEnum.CancelTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.CancelTodo);
                 break;
             default:
                 BaseResultModel<Boolean> ErrorResult = new BaseResultModel<>();
@@ -111,7 +111,7 @@ public class BusFlowServiceGuangZhongYiImpl extends BusFlowServiceImpl {
     }
 
     //#region 鐢ㄦ埛寰呭姙鎿嶄綔
-    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, GuangZhongYiActionEnum actionEnum) {
+    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, BusFlowActionEnum actionEnum) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
         BaseResultModel<Boolean> result = new SuccessResultModel<>();
@@ -504,7 +504,7 @@ public class BusFlowServiceGuangZhongYiImpl extends BusFlowServiceImpl {
     }
     public String getToken(Long instanceId) {
         instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        String token = MyRedisUtil.getGuangZhongYiToken(instanceId);
+        String token =  MyRedisUtil.getToken(instanceId, "GuangZhongYi");
         if (ObjectUtils.isNotEmpty(token))
             return token;
 
@@ -527,7 +527,7 @@ public class BusFlowServiceGuangZhongYiImpl extends BusFlowServiceImpl {
             throw ExceptionUtil.getException(null, "鑾峰彇token澶辫触");
         Integer expiresIn = tokenResponse.getExpiresIn();
         if (ObjectUtils.isNotEmpty(expiresIn))
-            MyRedisUtil.setGuangZhongYiToken(instanceId, token, expiresIn);
+            MyRedisUtil.setToken(instanceId, "GuangZhongYi", token, expiresIn);
         return token;
     }
     public <T> T toGuangZhongYiDataOut(String response, Class<T> clazz) {
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceHaiYangImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceHaiYangImpl.java
index a7a90a664f518040be3b1b845e9c72b133ccca61..31448e55d14194ef5027218dea2401835b033611 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceHaiYangImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceHaiYangImpl.java
@@ -71,7 +71,7 @@ public class BusFlowServiceHaiYangImpl extends BusFlowServiceImpl {
         OpenEnum openEnum = OpenEnum.getValueByIndex(cmd.getOpen());
         switch (openEnum) {
             case CREATE:
-                result = executeTodo(cmd, HaiYangActionEnum.CreateTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.CreateTodo);
                 break;
             case SUBMIT:
             case BACK:
@@ -79,11 +79,11 @@ public class BusFlowServiceHaiYangImpl extends BusFlowServiceImpl {
             case CHECK_COPY:
             case AUTHORIZE:
             case SET_CO_AUDIT:
-                result = executeTodo(cmd, HaiYangActionEnum.FinishTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.FinishTodo);
                 break;
             case REVOKE:
             case REGRESS:
-                result = executeTodo(cmd, HaiYangActionEnum.CancelTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.CancelTodo);
                 break;
             default:
                 BaseResultModel<Boolean> ErrorResult = new BaseResultModel<>();
@@ -103,7 +103,7 @@ public class BusFlowServiceHaiYangImpl extends BusFlowServiceImpl {
     }
 
     //#region 鐢ㄦ埛寰呭姙鎿嶄綔
-    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, HaiYangActionEnum actionEnum) {
+    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, BusFlowActionEnum actionEnum) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
         BaseResultModel<Boolean> result = new SuccessResultModel<>();
@@ -529,7 +529,7 @@ public class BusFlowServiceHaiYangImpl extends BusFlowServiceImpl {
     }
     public String getOAuth2Token(Long instanceId) {
         instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        String token = MyRedisUtil.getHaiYangOAuth2Token(instanceId);
+        String token = MyRedisUtil.getToken(instanceId, "HaiYangOAuth2");
         if (ObjectUtils.isNotEmpty(token))
             return token;
 
@@ -560,7 +560,7 @@ public class BusFlowServiceHaiYangImpl extends BusFlowServiceImpl {
             throw ExceptionUtil.getException(null, "鑾峰彇token澶辫触");
         Integer expiresIn = resultJSONObj.getInteger("expires_in");
         if (ObjectUtils.isNotEmpty(expiresIn))
-            MyRedisUtil.setHaiYangOAuth2Token(instanceId, token, expiresIn);
+            MyRedisUtil.setToken(instanceId, "HaiYangOAuth2", token, expiresIn);
         return token;
     }
     public <T> T toHaiYangDataOut(String response, Class<T> clazz) {
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceSudiImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceSudiImpl.java
index a03fb84bef4b4ccbe9fb076c8f88f648771da39c..f9d6d861c1224c3068ac0fcfe7c9c484a6bd52e8 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceSudiImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceSudiImpl.java
@@ -18,7 +18,7 @@ import com.seasky.flowportal.dto.sudi.SudiResultOut;
 import com.seasky.flowportal.enums.ExecutionStatusEnum;
 import com.seasky.flowportal.enums.OpenEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
-import com.seasky.flowportal.enums.SudiActionEnum;
+import com.seasky.flowportal.enums.BusFlowActionEnum;
 import com.seasky.flowportal.mapper.ApprovalMapper;
 import com.seasky.flowportal.service.convert.BusFlowConvert;
 import com.seasky.flowportal.utils.BaseConfigUtil;
@@ -91,11 +91,11 @@ public class BusFlowServiceSudiImpl extends BusFlowServiceImpl {
                 case CHECK_COPY:
                 case AUTHORIZE:
                 case SET_CO_AUDIT:
-                    result = executeTodo(cmd, SudiActionEnum.FinishTodo);
+                    result = executeTodo(cmd, BusFlowActionEnum.FinishTodo);
                     break;
                 case REVOKE:
                 case REGRESS:
-                    result = executeTodo(cmd, SudiActionEnum.CancelTodo);
+                    result = executeTodo(cmd, BusFlowActionEnum.CancelTodo);
                     break;
                 default:
                     BaseResultModel<Boolean> ErrorResult = new BaseResultModel<>();
@@ -105,7 +105,7 @@ public class BusFlowServiceSudiImpl extends BusFlowServiceImpl {
         }
         if (result.getIsSuccess()) {
             if (ObjectUtils.isNotEmpty(cmd.getNextAuditorCmdList()))
-                result = executeTodo(cmd, SudiActionEnum.CreateTodo);
+                result = executeTodo(cmd, BusFlowActionEnum.CreateTodo);
         }
         cmd.setExecutionStatus(result.getIsSuccess() ? ExecutionStatusEnum.Succeeded.getIndex() : ExecutionStatusEnum.Retry.getIndex());
         BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
@@ -120,12 +120,12 @@ public class BusFlowServiceSudiImpl extends BusFlowServiceImpl {
     }
 
     //#region 鐢ㄦ埛寰呭姙鎿嶄綔
-    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, SudiActionEnum sudiActionEnum) {
+    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, BusFlowActionEnum actionEnum) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
         BaseResultModel<Boolean> result = new SuccessResultModel<>();
         for (int i = 0; i < baseConfigProperties.getSendTimes(); i++) {
-            switch (sudiActionEnum) {
+            switch (actionEnum) {
                 case FinishTodo:
                     result = finishTodo(cmd);
                     break;
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceXingHaiImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceXingHaiImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ea64f630331dc3ba4b87fdaa8d6ea2acb830f1c
--- /dev/null
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/BusFlowServiceXingHaiImpl.java
@@ -0,0 +1,519 @@
+package com.seasky.flowportal.service.impl;
+
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.seasky.core.common.ResponseCode;
+import com.seasky.core.util.ExceptionUtil;
+import com.seasky.flowportal.config.BaseConfigProperties;
+import com.seasky.flowportal.constant.Constant;
+import com.seasky.flowportal.constant.InterfaceUrlConstant;
+import com.seasky.flowportal.domain.po.ApprovalPo;
+import com.seasky.flowportal.domain.po.BusFlowPo;
+import com.seasky.flowportal.dto.busFlow.BusFlowCmd;
+import com.seasky.flowportal.dto.busFlow.BusFlowQuery;
+import com.seasky.flowportal.dto.busFlow.BusFlowUserCmd;
+import com.seasky.flowportal.dto.response.BaseResultModel;
+import com.seasky.flowportal.dto.response.ErrorResultModel;
+import com.seasky.flowportal.dto.response.SuccessResultModel;
+import com.seasky.flowportal.dto.xingHai.XingHaiTaskErrorMsgResponse;
+import com.seasky.flowportal.dto.xingHai.XingHaiTaskRequest;
+import com.seasky.flowportal.dto.xingHai.XingHaiTaskResponse;
+import com.seasky.flowportal.dto.xingHai.XingHaiTokenResponse;
+import com.seasky.flowportal.enums.*;
+import com.seasky.flowportal.mapper.ApprovalMapper;
+import com.seasky.flowportal.service.convert.BusFlowConvert;
+import com.seasky.flowportal.utils.BaseConfigUtil;
+import com.seasky.flowportal.utils.BaseInOutUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @program:
+ * @author: chenmin
+ * @create: 2025-01-23 10:31
+ **/
+@Service("BusFlowServiceXingHaiImpl")
+@Slf4j
+public class BusFlowServiceXingHaiImpl extends BusFlowServiceImpl {
+
+    protected final static Integer timeout = 60000;
+
+    @Autowired
+    @Lazy
+    private ApprovalMapper approvalMapper;
+
+
+    @Override
+    public boolean executeBusFlow(BusFlowCmd cmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(cmd))
+            ExceptionUtil.getException(null,"浼犲叆鍙傛暟涓嶈兘涓虹┖");
+        if (ObjectUtils.isEmpty(cmd.getId()))
+            ExceptionUtil.getException(null,"涓婚敭涓嶈兘涓虹┖");
+        if (ObjectUtils.isEmpty(cmd.getOpen()))
+            ExceptionUtil.getException(null,"鎿嶄綔涓嶈兘涓虹┖");
+
+        boolean isRejected = OpenEnum.BACK.getIndex().equals(cmd.getOpen()) || (OpenEnum.REVOKE.getIndex().equals(cmd.getOpen()) && OrderStatusEnum.APPLY.getName().equals(cmd.getNextOrderStatus()));
+        boolean isOrderStatusChanged = !Objects.equals(cmd.getOrderStatus(), cmd.getNextOrderStatus());
+        cmd.setIsRejected(isRejected);
+        cmd.setIsOrderStatusChanged(isOrderStatusChanged);
+        BaseResultModel<Boolean> result = new SuccessResultModel<>();
+        OpenEnum openEnum = OpenEnum.getValueByIndex(cmd.getOpen());
+        if (ObjectUtils.isNotEmpty(cmd.getAuditorCmd())) {
+            switch (openEnum) {
+                case CREATE:
+                    break;
+                case SUBMIT:
+                case BACK:
+                case COPY:
+                case CHECK_COPY:
+                case AUTHORIZE:
+                case SET_CO_AUDIT:
+                    result = executeTodo(cmd, BusFlowActionEnum.FinishTodo);
+                    break;
+                case REVOKE:
+                case REGRESS:
+                    result = executeTodo(cmd, BusFlowActionEnum.CancelTodo);
+                    break;
+                default:
+                    BaseResultModel<Boolean> ErrorResult = new BaseResultModel<>();
+                    ErrorResult.setErrorMessage("娌℃湁褰撳墠鎿嶄綔鏂规硶");
+                    ErrorResult.setErrorCode(ResponseCode.DATA_VERIFY_EXCEPTION.value());
+            }
+        }
+        if (result.getIsSuccess()) {
+            if (ObjectUtils.isNotEmpty(cmd.getNextAuditorCmdList()))
+                result = executeTodo(cmd, BusFlowActionEnum.CreateTodo);
+        }
+        cmd.setExecutionStatus(result.getIsSuccess() ? ExecutionStatusEnum.Succeeded.getIndex() : ExecutionStatusEnum.Retry.getIndex());
+        BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+        int i = busFlowMapper.updateById(busFlowPo);
+        if (i < 1) {
+            BaseResultModel<Boolean> ErrorResult1 = new BaseResultModel<>();
+            ErrorResult1.setErrorMessage("鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            ErrorResult1.setErrorCode(ResponseCode.DATA_VERIFY_EXCEPTION.value());
+            result = ErrorResult1;
+        }
+        return result.getIsSuccess();
+    }
+
+    //#region 鐢ㄦ埛寰呭姙鎿嶄綔
+    private BaseResultModel<Boolean> executeTodo(BusFlowCmd cmd, BusFlowActionEnum actionEnum) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        BaseResultModel<Boolean> result = new SuccessResultModel<>();
+        for (int i = 0; i < baseConfigProperties.getSendTimes(); i++) {
+            switch (actionEnum) {
+                case FinishTodo:
+                    result = finishTodo(cmd);
+                    break;
+                case CancelTodo:
+                    result = cancelTodo(cmd);
+                    break;
+                case CreateTodo:
+                    result = createTodo(cmd);
+                    break;
+                default:
+                    break;
+            }
+            if (result.getIsSuccess()) {
+                cmd.setLog(JSONObject.toJSONString(new ArrayList<String>()));
+                break;
+            } else {
+                List<String> logList = JSONObject.parseArray(cmd.getLog(), String.class);
+                logList.add(result.getErrorMessage());
+                cmd.setLog(JSONObject.toJSONString(logList));
+            }
+        }
+        BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+        int updated = busFlowMapper.updateById(busFlowPo);
+        if (updated < 1) {
+            ExceptionUtil.getException(null, "鏇存柊娴佺▼澶勭悊澶辫触");
+        }
+        return result;
+    }
+
+    private BaseResultModel<Boolean> finishTodo(BusFlowCmd cmd) {
+        try {
+            Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+            BaseResultModel<Boolean> result = new SuccessResultModel<>();
+            int updated = 0;
+            BusFlowUserCmd auditorCmd = cmd.getAuditorCmd();
+            if (ObjectUtils.isEmpty(auditorCmd) || auditorCmd.succeeded())
+                return result;
+            BusFlowQuery qry = BusFlowQuery.builder().applyCode(cmd.getApplyCode()).nextOrderStatus(cmd.getOrderStatus()).createDate(cmd.getCreateDate()).build();
+            qry.setInstanceId(instanceId);
+            List<BusFlowPo> busFlowList = listPrevOrderStatusBusFlow(qry);
+            BusFlowPo busFlow = getBusFlowToHandle(auditorCmd.getUserCode(), busFlowList);
+            boolean isOrderStatusChanged = Boolean.TRUE.equals(cmd.getIsOrderStatusChanged());
+            List<BusFlowPo> sameOrderStatusBusFlowList = !isOrderStatusChanged || busFlow == null ? new ArrayList<>()
+                    : busFlowList.subList(1, busFlowList.size());
+            Long taskBizId = ObjectUtils.isEmpty(busFlow) ? null : busFlow.getId();
+            if (ObjectUtils.isEmpty(taskBizId))
+                return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "鏈壘鍒伴渶瑕佸畬鎴愮殑寰呭姙ID");
+            cmd.setTaskBizId(taskBizId.toString());
+            //#region 瀹屾垚寰呭姙
+            if (ExecutionStatusEnum.Unexecuted.getIndex() == auditorCmd.getExecutionStatus())
+            {
+                updatePendingState(cmd);
+                auditorCmd.setExecutionStatus(isOrderStatusChanged ? ExecutionStatusEnum.ToTerminateOrsignTask.getIndex() : ExecutionStatusEnum.Succeeded.getIndex());
+                cmd.setAuditorCmd(auditorCmd);
+                BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+                updated = busFlowMapper.updateById(busFlowPo);
+                if (updated < 1)
+                    ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, "鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            }
+            //#endregion
+            //#region 鑻ユ敼鍙樿妭鐐癸紝鍒欑粓姝㈡垨绛惧緟鍔�
+            if (ExecutionStatusEnum.ToTerminateOrsignTask.getIndex() == auditorCmd.getExecutionStatus())
+            {
+                if (isOrderStatusChanged)
+                {
+                    List<BusFlowCmd> sameOrderStatusBusFlowCmdList =  BusFlowConvert.listPoToCmd(sameOrderStatusBusFlowList);
+                    List<BusFlowUserCmd> sameOrderStatusAuditorList = ObjectUtils.isEmpty(sameOrderStatusBusFlowCmdList) ? new ArrayList<>()
+                            : sameOrderStatusBusFlowCmdList.stream().map(BusFlowCmd::getAuditorCmd).collect(Collectors.toList());
+                    sameOrderStatusAuditorList.add(auditorCmd);
+                    BusFlowCmd busFlowCmd = BusFlowConvert.poToCmd(busFlow);
+                    List<BusFlowUserCmd> busFlowNextAuditorCmdList = ObjectUtils.isEmpty(busFlowCmd) ? null : busFlowCmd.getNextAuditorCmdList();
+                    List<BusFlowUserCmd> auditorsToTaskTerminate = ObjectUtils.isEmpty(busFlowNextAuditorCmdList) ? null
+                            : busFlowNextAuditorCmdList.stream().filter(e -> sameOrderStatusAuditorList.stream().noneMatch(a -> Objects.equals(a.getUserId(), e.getUserId()))).collect(Collectors.toList());
+                    updatePendingState(cmd, auditorsToTaskTerminate);
+                }
+            }
+            //#endregion
+            auditorCmd.setExecutionStatus(ExecutionStatusEnum.Succeeded.getIndex());
+            cmd.setAuditorCmd(auditorCmd);
+            BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+            updated = busFlowMapper.updateById(busFlowPo);
+            if (updated < 1)
+                ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, "鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            return result;
+        }
+        catch (Exception e) {
+            log.error("瀹屾垚寰呭姙鍙戠敓寮傚父", e);
+            return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "瀹屾垚寰呭姙鍙戠敓寮傚父锛�" + e.getMessage());
+        }
+    }
+
+    private BaseResultModel<Boolean> cancelTodo(BusFlowCmd cmd) {
+        try {
+            Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+            BaseResultModel<Boolean> result = new SuccessResultModel<>();
+            int updated = 0;
+            BusFlowUserCmd auditorCmd = cmd.getAuditorCmd();
+            if (ObjectUtils.isEmpty(auditorCmd) || auditorCmd.succeeded())
+                return result;
+            boolean isOrderStatusChanged = Boolean.TRUE.equals(cmd.getIsOrderStatusChanged());
+            boolean isRejected = Boolean.TRUE.equals(cmd.getIsRejected());
+            //#region 浠诲姟鎾ゅ洖
+            if (ExecutionStatusEnum.Unexecuted.getIndex() == auditorCmd.getExecutionStatus()) {
+                BusFlowQuery qry = BusFlowQuery.builder().applyCode(cmd.getApplyCode()).nextOrderStatus(cmd.getNextOrderStatus()).createDate(cmd.getCreateDate()).auditorCode(auditorCmd.getUserCode()).build();
+                qry.setInstanceId(instanceId);
+                BusFlowPo busFlow = getBusFlowToHandle(qry);
+                Long taskBizId = ObjectUtils.isEmpty(busFlow) ? null : busFlow.getId();
+                if (ObjectUtils.isEmpty(taskBizId))
+                    return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "鏈壘鍒伴渶瑕佹挙閿€鐨勫緟鍔濱D");
+                cmd.setTaskBizId(taskBizId.toString());
+                updatePendingState(cmd);
+                auditorCmd.setExecutionStatus(isOrderStatusChanged ? ExecutionStatusEnum.ToTerminateTaskCreatedBeforeWithdraw.getIndex() : ExecutionStatusEnum.Succeeded.getIndex());
+                cmd.setAuditorCmd(auditorCmd);
+                BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+                updated = busFlowMapper.updateById(busFlowPo);
+                if (updated < 1)
+                    ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, "鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            }
+            //#endregion
+            //#region 鑻ユ敼鍙樿妭鐐癸紝鍒欑粓姝㈠鏍歌妭鐐圭殑寰呭姙浠诲姟
+            if (ExecutionStatusEnum.ToTerminateTaskCreatedBeforeWithdraw.getIndex() == auditorCmd.getExecutionStatus()) {
+                if (isOrderStatusChanged && !isRejected) {
+                    BusFlowQuery qry = BusFlowQuery.builder().applyCode(cmd.getApplyCode()).nextOrderStatus(cmd.getOrderStatus()).createDate(cmd.getCreateDate()).auditorCode(auditorCmd.getUserCode()).build();
+                    qry.setInstanceId(instanceId);
+                    BusFlowPo busFlow = getBusFlowToHandle(qry);
+                    Long taskBizId = ObjectUtils.isEmpty(busFlow) ? null : busFlow.getId();
+                    if (ObjectUtils.isEmpty(taskBizId))
+                        return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "鏈壘鍒伴渶瑕佹挙閿€鐨勫緟鍔濱D");
+                    cmd.setTaskBizId(taskBizId.toString());
+                    BusFlowCmd busFlowCmd = BusFlowConvert.poToCmd(busFlow);
+                    List<BusFlowUserCmd> busFlowNextAuditorCmdList = ObjectUtils.isEmpty(busFlowCmd) ? null : busFlowCmd.getNextAuditorCmdList();
+                    updatePendingState(cmd, "2", busFlowNextAuditorCmdList);
+                }
+            }
+            //#endregion
+            auditorCmd.setExecutionStatus(ExecutionStatusEnum.Succeeded.getIndex());
+            cmd.setAuditorCmd(auditorCmd);
+            BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+            updated = busFlowMapper.updateById(busFlowPo);
+            if (updated < 1)
+                ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, "鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            return result;
+        }
+        catch (Exception e) {
+            log.error("鎾ら攢寰呭姙鍙戠敓寮傚父", e);
+            return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "鎾ら攢寰呭姙鍙戠敓寮傚父锛�" + e.getMessage());
+        }
+    }
+
+    private BaseResultModel<Boolean> createTodo(BusFlowCmd cmd) {
+        try {
+            Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+            BaseResultModel<Boolean> result = new SuccessResultModel<>();
+            List<BusFlowUserCmd> nextAuditorCmdList = cmd.getNextAuditorCmdList();
+            if (ObjectUtils.isEmpty(nextAuditorCmdList))
+                return result;
+
+            boolean isRejected = Boolean.TRUE.equals(cmd.getIsRejected());
+
+            for (int i = 0; i < nextAuditorCmdList.size(); i++) {
+                BusFlowUserCmd auditor = nextAuditorCmdList.get(i);
+                if (auditor.succeeded())
+                    continue;
+                if (isRejected)
+                    continue;
+
+                boolean isTaskCreated = isTaskCreated(cmd, auditor);
+                if (!isTaskCreated)
+                    receivePending(cmd, auditor);
+                auditor.setExecutionStatus(ExecutionStatusEnum.Succeeded.getIndex());
+                nextAuditorCmdList.set(i, auditor);
+                cmd.setNextAuditorCmdList(nextAuditorCmdList);
+                BusFlowPo busFlowPo = BusFlowConvert.cmdToPo(cmd);
+                int updated = busFlowMapper.updateById(busFlowPo);
+                if (updated < 1)
+                    ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, "鏇存柊娴佺▼澶勭悊杩囩▼澶辫触");
+            }
+            return result;
+        }
+        catch (Exception e) {
+            log.error("鍒涘缓寰呭姙鍙戠敓寮傚父", e);
+            return new ErrorResultModel<>(ResponseCode.BUSINESS_EXCEPTION.value(), "鍒涘缓寰呭姙鍙戠敓寮傚父锛�" + e.getMessage());
+        }
+    }
+
+    public boolean isTaskCreated(BusFlowCmd cmd, BusFlowUserCmd auditor) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        boolean isOrderStatusChanged = Boolean.TRUE.equals(cmd.getIsOrderStatusChanged());
+        if (isOrderStatusChanged)
+            return false;
+        boolean isRejected = Boolean.TRUE.equals(cmd.getIsRejected());
+        if (isRejected)
+            return false;
+
+        boolean isRevoke = OpenEnum.REVOKE.getIndex().equals(cmd.getOpen());
+        BusFlowUserCmd auditorCmd = cmd.getAuditorCmd();
+        boolean isRevokedAuditor = isRevoke && ObjectUtils.isNotEmpty(auditorCmd) && Objects.equals(auditorCmd.getUserId(), auditor.getUserId());
+        if (isRevokedAuditor)
+            return false;
+
+        BusFlowQuery qry = BusFlowQuery.builder().applyCode(cmd.getApplyCode()).nextOrderStatus(cmd.getOrderStatus()).createDate(cmd.getCreateDate()).auditorCode(auditor.getUserCode()).build();
+        qry.setInstanceId(instanceId);
+        BusFlowPo busFlow = getBusFlowToHandle(qry);
+        BusFlowCmd busFlowCmd = BusFlowConvert.poToCmd(busFlow);
+        List<BusFlowUserCmd> busFlowNextAuditorCmdList = ObjectUtils.isEmpty(busFlowCmd) ? null : busFlowCmd.getNextAuditorCmdList();
+        if (ObjectUtils.isEmpty(busFlowNextAuditorCmdList))
+            return false;
+        boolean isTaskCreated = busFlowNextAuditorCmdList.stream().anyMatch(na -> Objects.equals(na.getUserId(), auditor.getUserId()));
+        return isTaskCreated;
+    }
+
+    //#endregion
+
+    //#region 鏄熸捣寰呭姙鎺ュ彛
+
+    protected static String ErrorMessageXingHai = "鏄熸捣寰呭姙鎺ュ彛杩斿洖锛�";
+
+    private Boolean receivePending(BusFlowCmd cmd, List<BusFlowUserCmd> auditorCmdList) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(auditorCmdList))
+            return true;
+
+        Boolean result = false;
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        String registerCode = baseConfigProperties.getXingHaiRegisterCode();
+        BusFlowUserCmd creator = !OpenEnum.CREATE.getIndex().equals(cmd.getOpen()) ? cmd.getAuditorCmd()
+                : ObjectUtils.isEmpty(auditorCmdList) ? new BusFlowUserCmd()
+                : auditorCmdList.get(0);
+        String creatorUserName = ObjectUtils.isEmpty(creator) ? null : creator.getUserName();
+        String creatorUserCode = ObjectUtils.isEmpty(creator) ? null : creator.getUserCode();
+        String webUrl = baseConfigProperties.getWebUrl() + cmd.getWebUrl();
+        ApprovalPo order = approvalMapper.selectApprovalByOrderCode(instanceId, cmd.getApplyCode(), cmd.getCreateDate());
+        String applyReason = ObjectUtils.isEmpty(order) ? "" : order.getApplyReason();
+        String title = cmd.getApplyCode() + applyReason;
+        for (BusFlowUserCmd auditor : auditorCmdList) {
+            String auditorUserCode = auditor.getUserCode();
+            String auditorUserName = auditor.getUserName();
+            String taskId = String.format("%s-%s", cmd.getId(), auditorUserCode);
+            XingHaiTaskRequest data = XingHaiTaskRequest.builder()
+                    .registerCode(registerCode)
+                    .taskId(taskId)
+                    .title(title)
+                    .state("0")
+                    .thirdSenderId(creatorUserCode)
+                    .senderName(creatorUserName)
+                    .thirdReceiverId(auditorUserCode)
+                    .creationDate(Constant.L_DATE_FORMAT.format(new Date()))
+                    .url(webUrl)
+                    .h5url(webUrl)
+                    .noneBindingSender(creatorUserName)
+                    .noneBindingReceiver(auditorUserName)
+                    .build();
+            result = receivePending(instanceId, creatorUserName, data);
+        }
+        return result;
+    }
+    private Boolean receivePending(BusFlowCmd cmd, BusFlowUserCmd auditorCmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(auditorCmd))
+            return true;
+
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        String registerCode = baseConfigProperties.getXingHaiRegisterCode();
+        BusFlowUserCmd creator = !OpenEnum.CREATE.getIndex().equals(cmd.getOpen()) ? cmd.getAuditorCmd() : auditorCmd;
+        String creatorUserName = ObjectUtils.isEmpty(creator) ? null : creator.getUserName();
+        String creatorUserCode = ObjectUtils.isEmpty(creator) ? null : creator.getUserCode();
+        String webUrl = baseConfigProperties.getWebUrl() + cmd.getWebUrl();
+        String auditorUserCode = auditorCmd.getUserCode();
+        String auditorUserName = auditorCmd.getUserName();
+        String taskId = String.format("%s-%s", cmd.getId(), auditorUserCode);
+        ApprovalPo order = approvalMapper.selectApprovalByOrderCode(instanceId, cmd.getApplyCode(), cmd.getCreateDate());
+        String applyReason = ObjectUtils.isEmpty(order) ? "" : order.getApplyReason();
+        String title = cmd.getApplyCode() + applyReason;
+        XingHaiTaskRequest data = XingHaiTaskRequest.builder()
+                .registerCode(registerCode)
+                .taskId(taskId)
+                .title(title)
+                .state("0")
+                .thirdSenderId(creatorUserCode)
+                .senderName(creatorUserName)
+                .thirdReceiverId(auditorUserCode)
+                .creationDate(Constant.L_DATE_FORMAT.format(new Date()))
+                .url(webUrl)
+                .h5url(webUrl)
+                .noneBindingSender(creatorUserName)
+                .noneBindingReceiver(auditorUserName)
+                .build();
+        return receivePending(instanceId, creatorUserName, data);
+    }
+    private Boolean receivePending(Long instanceId, String creatorUserName, XingHaiTaskRequest data) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        String request = JSON.toJSONString(data);
+        String token = getToken(instanceId, creatorUserName);
+        Map<String, String> queryMap = new HashMap<String, String>() {{
+            put("token", token);
+        }};
+        String queryString = com.seasky.flowportal.utils.HttpUtil.queryString(queryMap);
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.XINGHAI_RECEIVE_PENDING) + queryString;
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.post(interfaceUrl, request, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        XingHaiTaskResponse taskResponse = toXingHaiTaskResponse(response);
+        return taskResponse.getSuccess();
+    }
+
+    private Boolean updatePendingState(BusFlowCmd cmd) {
+        return updatePendingState(cmd, cmd.getAuditorCmd());
+    }
+    private Boolean updatePendingState(BusFlowCmd cmd, BusFlowUserCmd auditorCmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(auditorCmd))
+            return true;
+        return updatePendingState(cmd, Collections.singletonList(auditorCmd));
+    }
+    private Boolean updatePendingState(BusFlowCmd cmd, List<BusFlowUserCmd> auditorCmdList) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(auditorCmdList))
+            return true;
+
+        boolean isRegress = OpenEnum.REGRESS.getIndex().equals(cmd.getOpen());
+        boolean isRejected = Boolean.TRUE.equals(cmd.getIsRejected());
+        boolean isRevoke = OpenEnum.REVOKE.getIndex().equals(cmd.getOpen()) && !isRejected;
+        String subState = isRejected ? "3" : isRevoke ? "2" : isRegress ? "1" : "0";
+        return updatePendingState(cmd, subState, auditorCmdList);
+    }
+    private Boolean updatePendingState(BusFlowCmd cmd, String subState, List<BusFlowUserCmd> auditorCmdList) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        if (ObjectUtils.isEmpty(auditorCmdList))
+            return true;
+
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        String registerCode = baseConfigProperties.getXingHaiRegisterCode();
+        BusFlowUserCmd creator = cmd.getAuditorCmd();
+        String creatorUserName = ObjectUtils.isEmpty(creator) ? null : creator.getUserName();
+        Boolean result = false;
+        for (BusFlowUserCmd auditorCmd : auditorCmdList) {
+            String auditorUserCode = auditorCmd.getUserCode();
+            String taskId = String.format("%s-%s", cmd.getTaskBizId(), auditorUserCode);
+            XingHaiTaskRequest data = XingHaiTaskRequest.builder()
+                    .registerCode(registerCode)
+                    .taskId(taskId)
+                    .state("1")
+                    .subState(subState)
+                    .build();
+            result = updatePendingState(instanceId, creatorUserName, data);
+        }
+        return result;
+    }
+    private Boolean updatePendingState(Long instanceId, String creatorUserName, XingHaiTaskRequest data) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        String request = JSON.toJSONString(data);
+        String token = getToken(instanceId, creatorUserName);
+        Map<String, String> queryMap = new HashMap<String, String>() {{
+            put("token", token);
+        }};
+        String queryString = com.seasky.flowportal.utils.HttpUtil.queryString(queryMap);
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.XINGHAI_UPDATE_PENDING_STATE) + queryString;
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.post(interfaceUrl, request, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        XingHaiTaskResponse taskResponse = toXingHaiTaskResponse(response);
+        return taskResponse.getSuccess();
+    }
+
+
+    public String getToken(Long instanceId, String loginName) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        String token = null;
+
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        String userName = baseConfigProperties.getXingHaiUserName();
+        String password = baseConfigProperties.getXingHaiPassword();
+        Map<String, Object> paramMap = new HashMap<String, Object>() {{
+            put("userName", userName);
+            put("password", password);
+            put("loginName", loginName);
+        }};
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.XINGHAI_TOKEN);
+        String request = JSON.toJSONString(paramMap);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.post(interfaceUrl, paramMap, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        XingHaiTokenResponse tokenResponse = JSONObject.parseObject(response, XingHaiTokenResponse.class);
+        token = tokenResponse.getId();
+        if (ObjectUtils.isEmpty(token))
+            throw ExceptionUtil.getException(null, "鑾峰彇token澶辫触");
+        return token;
+    }
+
+
+    public XingHaiTaskResponse toXingHaiTaskResponse(String response) {
+        XingHaiTaskResponse taskResponse = JSONObject.parseObject(response, XingHaiTaskResponse.class);
+        if (ObjectUtils.isEmpty(taskResponse))
+            ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, ErrorMessageXingHai + response);
+        if (!taskResponse.isSuccess()) {
+            List<XingHaiTaskErrorMsgResponse> errorMsgList = taskResponse.getErrorMsgList();
+            String errorMsg = ObjectUtils.isEmpty(errorMsgList) ? "" : errorMsgList.get(0).getErrorDetail();
+            ExceptionUtil.getException(ResponseCode.BUSINESS_EXCEPTION, ErrorMessageXingHai + errorMsg);
+        }
+        return taskResponse;
+    }
+
+
+    //#endregion
+
+}
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ChuangZhi_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ChuangZhi_VerifyReimbursementServiceImpl.java
index b27ff800328fc78fb4360f30c021f0e141f9d38c..a93e36d48b81285f6ff6dd3812c439b6b4b86c1a 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ChuangZhi_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ChuangZhi_VerifyReimbursementServiceImpl.java
@@ -16,15 +16,13 @@ import com.seasky.flowportal.dto.user.UserInfoQuery;
 import com.seasky.flowportal.enums.ApplyCategoryEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.enums.ReimbursementTypeEnum;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
 import com.seasky.flowportal.utils.ApprovalUtil;
 import com.seasky.flowportal.utils.BaseInOutUtil;
 import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.FlowUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -41,12 +39,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class ChuangZhi_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
-
     @Override
     public String verifyReimbursementSelectUser(ExpenseReimbursementCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
@@ -177,7 +169,7 @@ public class ChuangZhi_VerifyReimbursementServiceImpl extends VerifyReimbursemen
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                     }
@@ -220,7 +212,7 @@ public class ChuangZhi_VerifyReimbursementServiceImpl extends VerifyReimbursemen
                     String processInstanceId = cmd.getProcessInstanceId();
                     if (ObjectUtils.isNotEmpty(processInstanceId)) {
                         try {
-                            String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                            String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                             JSONObject jsonObject = JSONObject.parseObject(processVariable);
                             claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                         }
@@ -245,7 +237,7 @@ public class ChuangZhi_VerifyReimbursementServiceImpl extends VerifyReimbursemen
                     String processInstanceId = cmd.getProcessInstanceId();
                     if (ObjectUtils.isNotEmpty(processInstanceId)) {
                         try {
-                            String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                            String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                             JSONObject jsonObject = JSONObject.parseObject(processVariable);
                             claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                         }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/DianLi_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/DianLi_VerifyReimbursementServiceImpl.java
index 0971a8e6b7591a86671f19755a1a2090a268440c..14f0dfb52c8ff27066f0c920dd9f686f2befdba1 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/DianLi_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/DianLi_VerifyReimbursementServiceImpl.java
@@ -20,16 +20,10 @@ import com.seasky.flowportal.dto.user.UserInfoQuery;
 import com.seasky.flowportal.dto.userContainingVerification.UserContainingVerificationOut;
 import com.seasky.flowportal.dto.userContainingVerification.UserContainingVerificationsOut;
 import com.seasky.flowportal.enums.*;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -47,11 +41,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class DianLi_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     private static List<String> laborCostList = Arrays.asList("绉戠爺鍔冲姟璐�", "鏍″浜哄憳鍔冲姟璐�", "绉戠爺鍔冲姟璐筥娲鹃仯浜哄憳", "杩旇仒澶栬仒", "瀛︾敓鍔冲姟璐�");
     private static List<String> payList = Arrays.asList("宸ヨ祫钖噾", "璐㈡斂宸ヨ祫", "鏍″唴娲ヨ创", "瀛︾敓濂栧姪閲�"
             , "骞寸粓濂�", "骞寸粓濂朹浜轰簨娲鹃仯", "鏍″唴娲ヨ创_浜轰簨娲鹃仯", "鏍″唴娲ヨ创_鍗氬+鍚�", "骞寸粓濂朹鍗氬+鍚�");
@@ -297,7 +286,7 @@ public class DianLi_VerifyReimbursementServiceImpl extends VerifyReimbursementSe
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                     }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExpenseReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExpenseReimbursementServiceImpl.java
index f2722b8b5a4e9979350fb3c316f68214e88cad17..4acf902afab3201319c92685e199054b680ac4dc 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExpenseReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExpenseReimbursementServiceImpl.java
@@ -151,10 +151,6 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
     @Lazy
     private IdempotentService idempotentService;
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     @Autowired
     @Lazy
     private FlowFileService flowFileService;
@@ -295,14 +291,13 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 if (ObjectUtils.isNotEmpty(busFlowCmd)) {
                     BusFlowCmd backBusFlowCmd = BusFlowCmd.builder()
                             .open(OpenEnum.BACK.getIndex())
-                            .documentId("")
+                            .documentId(busFlowCmd.getDocumentId())
                             .applyCode(busFlowCmd.getApplyCode())
                             .orderStatus(busFlowCmd.getNextOrderStatus())
                             .nextOrderStatus("")
                             .webUrl(busFlowCmd.getWebUrl())
                             .applicantNo(busFlowCmd.getApplicantNo())
                             .applicantName(busFlowCmd.getApplicantName())
-                            .documentId(busFlowCmd.getDocumentId())
                             .build();
                     BusFlowUserCmd auditorCmd = BusFlowUserCmd.builder().userId(cmd.getApplicantId()).userCode(cmd.getApplicantNo()).userName(cmd.getApplicantName()).build();
                     backBusFlowCmd.setAuditorCmd(auditorCmd);
@@ -369,7 +364,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 throw ExceptionUtil.getException(null, "鍥為€€鐞嗙敱涓嶈兘涓虹┖");
         }
 //        FlowQuery flowQuery = FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build();
-//        List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+//        List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
 //        //鑻ュ綋鍓嶇櫥褰曚汉瀛樺湪寰呭姙锛屽垯绛涢€�
 //        if (flowOutList.stream().anyMatch(s -> loginUser.getUserNo().equals(s.getApprover()))) {
 //            flowOutList = flowOutList.stream().filter(s -> loginUser.getUserNo().equals(s.getApprover())).collect(Collectors.toList());
@@ -529,15 +524,15 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         List<HistoricActivityInstanceOut> historicList;
         switch (flowQuery.getFlowQueryEnum()) {
             case ListTodo:
-                List<TaskOut> taskList = flowService.listTodoAll(flowQuery);
+                List<TaskOut> taskList = FlowUtil.INSTANCE(instanceId).listTodoAll(flowQuery);
                 processInstanceIds = taskList.stream().map(TaskOut::getProcessInstanceId).collect(Collectors.toList());
                 break;
             case ListDone:
-                historicList = flowService.listDoneAll(flowQuery);
+                historicList = FlowUtil.INSTANCE(instanceId).listDoneAll(flowQuery);
                 processInstanceIds = historicList.stream().map(HistoricActivityInstanceOut::getProcessInstanceId).collect(Collectors.toList());
                 break;
             case ListFinish:
-                historicList = flowService.listFinishAll(flowQuery);
+                historicList = FlowUtil.INSTANCE(instanceId).listFinishAll(flowQuery);
                 processInstanceIds = historicList.stream().map(HistoricActivityInstanceOut::getProcessInstanceId).collect(Collectors.toList());
                 break;
             default:
@@ -608,7 +603,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 }
             }
             //璁剧疆娴佺▼淇℃伅flowCmd
-            List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(reimbursementOut.getProcessInstanceId()).build());
+            List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(reimbursementOut.getProcessInstanceId()).build());
             //鑻ュ綋鍓嶇櫥褰曚汉瀛樺湪寰呭姙锛屽垯绛涢€�
             if (flowOutList.stream().anyMatch(s -> loginUser.getUserNo().equals(s.getApprover()))) {
                 flowOutList = flowOutList.stream().filter(s -> loginUser.getUserNo().equals(s.getApprover())).collect(Collectors.toList());
@@ -1197,7 +1192,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         //#endregion
         //#region 鑾峰彇鍗曟嵁褰撳墠寰呭姙
         FlowQuery flowQuery = FlowQuery.builder().processInstanceId(approvalPo.getProcessInstanceId()).build();
-        List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+        List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
         //#endregion
         //#region 鑾峰彇瀹屾垚鑺傜偣id
         ProcessDefinitionOut processDefinitionInfo = ApprovalUtil.getProcessDefinitionInfoByKey(approvalCmd);
@@ -1246,7 +1241,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 .approver(LoginUtil.getLoginUserNo())
                 .opinion("鍚庣画娴佺▼绾夸笅绛惧瓧")
                 .build();
-        String resultJumpFlow = flowService.jumpFlow(flowCmd);
+        String resultJumpFlow = FlowUtil.INSTANCE(instanceId).jumpFlow(flowCmd);
         //#endregion
         //#region 闈炲墠缃崟鎹秷鎭拰鍥炲啓
         boolean isReimbursementApply = ApplyCategoryEnum.ReimbursementApply.getName().equals(approvalPo.getApplyCategory());
@@ -1275,67 +1270,79 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
     }
 
     @Override
-    public String claimsApprovalRejected(ExpenseReimbursementCmd expenseReimbursementCmd) {
-        Long instanceId = BaseInOutUtil.verifyInstanceId(expenseReimbursementCmd);
-        final String orderCode = expenseReimbursementCmd.getReimbursementCode();
+    public String claimsApprovalRejected(ExpenseReimbursementCmd cmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        String orderCode = cmd.getReimbursementCode();
         if (ObjectUtils.isEmpty(orderCode))
             throw ExceptionUtil.getException(null, "鍗曞彿涓嶈兘涓虹┖");
-        if (ObjectUtils.isEmpty(expenseReimbursementCmd.getApplicantName()))
+        if (ObjectUtils.isEmpty(cmd.getApplicantName()))
             throw ExceptionUtil.getException(null, "鐢宠浜哄鍚嶄笉鑳戒负绌�");
-        if (ObjectUtils.isEmpty(expenseReimbursementCmd.getFinStatus()) || !expenseReimbursementCmd.getFinStatus())
+        if (!Boolean.TRUE.equals(cmd.getFinStatus()))
             throw ExceptionUtil.getException(null, "鍗曟嵁鏄惁鏄綉鎶ラ┏鍥炰紶鍊奸敊璇�");
-        PortalUtil.verifyToken(instanceId, expenseReimbursementCmd.getKey(), expenseReimbursementCmd.getToken());
+        PortalUtil.verifyToken(instanceId, cmd.getKey(), cmd.getToken());
 
 
         ExpenseReimbursementQuery query = ExpenseReimbursementQuery.builder().reimbursementCode(orderCode).build();
         query.setInstanceId(instanceId);
-        ExpenseReimbursementPo expenseReimbursementPo = getExpenseReimbursementPo(query);
-        expenseReimbursementPo.setFinStatus(true);
+        ExpenseReimbursementPo po = getExpenseReimbursementPo(query);
+        po.setFinStatus(true);
+        String backStatus = OrderStatusEnum.BACK.getName();
+        String approvalOpinion = "缁忓姙浜哄洖鎾�";
         ApplyOut approval = ApplyOut.builder()
-                .approvalDetailId(expenseReimbursementPo.getApprovalDetailId())
-                .orderNo(expenseReimbursementPo.getReimbursementCode())
-                .personNo(expenseReimbursementPo.getApplicantNo())
-                .personName(expenseReimbursementPo.getApplicantName())
-                .approvalState(OrderStatusEnum.BACK.getName())
-                .pdfUrl(expenseReimbursementPo.getReimbursementPdf())
-                .approvalOpinion("")
-                .approvalTime(Constant.L_DATE_FORMAT.format(expenseReimbursementPo.getUpdateDate()))
+                .approvalDetailId(po.getApprovalDetailId())
+                .orderNo(orderCode)
+                .personNo(po.getApplicantNo())
+                .personName(po.getApplicantName())
+                .approvalState(backStatus)
+                .pdfUrl(po.getReimbursementPdf())
+                .approvalOpinion(approvalOpinion)
+                .approvalTime(Constant.L_DATE_FORMAT.format(po.getUpdateDate()))
                 .orderState(11)
                 .build();
         //Back
-        if (!OrderStatusEnum.BACK.getName().equals(expenseReimbursementPo.getOrderStatus())) {
-            expenseReimbursementCmd = MapperUtils.INSTANCE.map(ExpenseReimbursementCmd.class, expenseReimbursementPo);
-            expenseReimbursementCmd.setDoReturnApplicationStatus(false);
-            expenseReimbursementCmd.setOpen(OpenEnum.BACK.getIndex());
-            UserInfoOut userInfo = UserInfoOut.builder().userNo(expenseReimbursementCmd.getApplicantNo()).userName(expenseReimbursementCmd.getApplicantName()).build();
-            if (ObjectUtils.isEmpty(expenseReimbursementPo.getProcessInstanceId())) {
-                expenseReimbursementCmd.setOrderStatus(OrderStatusEnum.BACK.getName());
-                ApprovalUtil.claimsFlowLog(expenseReimbursementCmd, userInfo);
-            } else {
-                //璁剧疆娴佺▼淇℃伅flowCmd
-                List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(expenseReimbursementPo.getProcessInstanceId()).build());
-                List<FlowCmd> flowList = MapperUtils.INSTANCE.mapAsList(FlowCmd.class, flowOutList);
-                expenseReimbursementCmd.setFlowList(flowList);
-                if (OrderStatusEnum.FINISH.getName().equals(flowList.get(0).getNodeName())) {
-                    expenseReimbursementCmd.setOrderStatus(OrderStatusEnum.BACK.getName());
-                    ApprovalUtil.claimsFlowLog(expenseReimbursementCmd, userInfo);
-                } else if (!OrderStatusEnum.BACK.getName().equals(flowList.get(0).getNodeName())) {
-                    flowList.get(0).setOpinion("缁忓姙浜哄洖鎾�");
-                    approvalProcessing(OpenEnum.BACK.getIndex(), expenseReimbursementCmd, userInfo);
-                }
+        if (backStatus.equals(po.getOrderStatus()))
+            return JSONObject.toJSONString(approval);
+
+        cmd = MapperUtils.INSTANCE.map(ExpenseReimbursementCmd.class, po);
+        cmd.setDoClaimsApi(false);
+        cmd.setOpen(OpenEnum.BACK.getIndex());
+        UserInfoOut userInfo = UserInfoOut.builder().userNo(cmd.getApplicantNo()).userName(cmd.getApplicantName()).build();
+
+        FlowEngineEnum flowEngine = FlowUtil.getFlowEngine(instanceId);
+        boolean isSeaSkyFlowEngine = FlowEngineEnum.SEA_SKY.equals(flowEngine);
+        String processInstanceId = po.getProcessInstanceId();
+        boolean needSeaSkyFlowAudit = isSeaSkyFlowEngine && ObjectUtils.isNotEmpty(processInstanceId);
+
+        if (needSeaSkyFlowAudit) {
+            //璁剧疆娴佺▼淇℃伅flowCmd
+            List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(processInstanceId).build());
+            List<FlowCmd> flowList = MapperUtils.INSTANCE.mapAsList(FlowCmd.class, flowOutList);
+            cmd.setFlowList(flowList);
+            if (OrderStatusEnum.FINISH.getName().equals(flowList.get(0).getNodeName())) {
+                cmd.setOrderStatus(backStatus);
+                ApprovalUtil.claimsFlowLog(cmd, userInfo);
+            } else if (!backStatus.equals(flowList.get(0).getNodeName())) {
+                flowList.get(0).setOpinion(approvalOpinion);
+                approvalProcessing(OpenEnum.BACK.getIndex(), cmd, userInfo);
             }
-            //鏇存柊瀹℃壒鐘舵€�
-            expenseReimbursementPo.setOrderStatus(OrderStatusEnum.BACK.getName());
-            expenseReimbursementPo.setBackCount(1);
-            expenseReimbursementMapper.updateById(expenseReimbursementPo);
-            //鍒犻櫎绛剧珷璁板綍
-            final SignatureCmd signatureCmd = SignatureCmd.builder().orderCode(orderCode).build();
-            signatureCmd.setInstanceId(instanceId);
-            signatureService.removeSignature(signatureCmd);
-            AttachFileListCmd attachFileListCmd = AttachFileListCmd.builder().fkId(orderCode).build();
-            attachFileListCmd.setInstanceId(instanceId);
-            attachFileService.deleteAttachFileList(attachFileListCmd);
-        }
+        } else {
+            cmd.setOrderStatus(backStatus);
+            ApprovalUtil.claimsFlowLog(cmd, userInfo);
+            ApplyListOut applyListOut = ApplyListOut.builder().applyOutList(Collections.singletonList(approval)).build();
+            applyListOut.setInstanceId(instanceId);
+            FlowUtil.INSTANCE(instanceId).updateAuditResult(applyListOut);
+        }
+        //鏇存柊瀹℃壒鐘舵€�
+        po.setOrderStatus(backStatus);
+        po.setBackCount(1);
+        expenseReimbursementMapper.updateById(po);
+        //鍒犻櫎绛剧珷璁板綍
+        final SignatureCmd signatureCmd = SignatureCmd.builder().orderCode(orderCode).build();
+        signatureCmd.setInstanceId(instanceId);
+        signatureService.removeSignature(signatureCmd);
+        AttachFileListCmd attachFileListCmd = AttachFileListCmd.builder().fkId(orderCode).build();
+        attachFileListCmd.setInstanceId(instanceId);
+        attachFileService.deleteAttachFileList(attachFileListCmd);
         return JSONObject.toJSONString(approval);
     }
 
@@ -1405,7 +1412,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             cmd.setCurAuditerName(cmd.getApplicantName());
         }
 
-        Date approveStartDate = flowService.getCurrentDate();
+        Date approveStartDate = FlowUtil.INSTANCE(instanceId).getCurrentDate();
         if (ObjectUtils.isEmpty(cmd.getProcessInstanceId())) {
             //鍒涘缓鎶ラ攢鍗� 2-鍒涘缓鎶ラ攢鍗曟暟鎹�
             //log.info("createExpenseReimbursement: 淇濆瓨鍗曟嵁");
@@ -1421,7 +1428,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 boolean isXiNanZhengFa = SchoolEnum.XiNanZhengFa.equals(schoolEnum);
                 FlowCmd flowCmd = FlowCmd.builder().approver(cmd.getApplicantNo()).build();
                 flowCmd.setInstanceId(instanceId);
-                boolean isStartProcessAndAutoComplete = flowService.isStartProcessAndAutoComplete(flowCmd);
+                boolean isStartProcessAndAutoComplete = FlowUtil.INSTANCE(instanceId).isStartProcessAndAutoComplete(flowCmd);
                 boolean isNotCreateSignature = !isStartProcessAndAutoComplete;
                 if (!isNotCreateSignature) {
                     Integer signatureStatus = signatureService.getSignatureStatus(instanceId);
@@ -1609,7 +1616,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 applyOut.setPersonName(expenseReimbursementCmd.getApplicantName());
             } else {
                 FlowQuery flowQuery = FlowQuery.builder().processInstanceId(expenseReimbursementCmd.getProcessInstanceId()).build();
-                List<HistoryInfoOut> flowHistoryList = flowService.getFlowHistory(flowQuery);
+                List<HistoryInfoOut> flowHistoryList = FlowUtil.INSTANCE(instanceId).getFlowHistory(flowQuery);
                 HistoryInfoOut lastFlowHisInfoOut = ObjectUtils.isNotEmpty(flowHistoryList) ? flowHistoryList.get(flowHistoryList.size() - 1)
                         : HistoryInfoOut.builder()
                         .flowState("娴佺▼寮€濮�")
@@ -1683,7 +1690,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         }
         //鑾峰彇娴佺▼鍘嗗彶
         FlowQuery flowQuery = FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build();
-        List<HistoryInfoOut> flowHistoryList = flowService.getFlowHistory(flowQuery);
+        List<HistoryInfoOut> flowHistoryList = FlowUtil.INSTANCE(instanceId).getFlowHistory(flowQuery);
         if (ObjectUtils.isEmpty(flowHistoryList)) {
             flowHistoryList = Collections.singletonList(HistoryInfoOut.builder()
                     .flowState("娴佺▼寮€濮�")
@@ -1700,7 +1707,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         List<String> hisUserNoList = ObjectUtils.isEmpty(flowHistoryList) ? null : flowHistoryList.stream().map(HistoryInfoOut::getAuditor).collect(Collectors.toList());
         if (ObjectUtils.isNotEmpty(hisUserNoList))
             userNoList.addAll(hisUserNoList);
-        List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+        List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
         List<String> todoUserNoList = ObjectUtils.isEmpty(flowOutList) ? null : flowOutList.stream().map(FlowOut::getApprover).collect(Collectors.toList());
         if (ObjectUtils.isNotEmpty(todoUserNoList))
             userNoList.addAll(todoUserNoList);
@@ -1796,7 +1803,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             throw ExceptionUtil.getException(null, "鍒涘缓娴佺▼澶辫触锛屾湭鍖归厤鐨勬祦绋嬪畾涔夛細" + orderType);
         }
         flowCmd.setProcessDefinitionKey(defKey);
-        String save = flowService.saveFlow(instanceId, OpenEnum.CREATE, flowCmd);
+        String save = FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.CREATE, flowCmd);
         expenseReimbursementCmd.setBusFlowId(flowCmd.getBusFlowId());
         expenseReimbursementCmd.setProcessInstanceId(save);
         //return getAndSaveSignature(expenseReimbursementCmd);
@@ -1811,7 +1818,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             throw ExceptionUtil.getException(null, "瀹℃牳閿欒锛屾湭鎵惧埌瀹℃牳璁板綍");
         }
         FlowCmd flowCmd = cmd.getFlowList().get(0);
-        FlowNode activityNode = flowService.getFlowNodeInfoById(cmd.getProcessInstanceId(), flowCmd.getActivityId());
+        FlowNode activityNode = FlowUtil.INSTANCE(instanceId).getFlowNodeInfoById(cmd.getProcessInstanceId(), flowCmd.getActivityId());
         if (ObjectUtils.isEmpty(flowCmd.getBusinessData())) {
             flowCmd.setBusinessData(new HashMap<String, Object>());
         }
@@ -1869,7 +1876,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         try {
             verifySubmitFlow(cmd);
             flowCmd.setOpinion(ObjectUtils.isEmpty(flowCmd.getOpinion()) ? "瀹℃壒閫氳繃" : flowCmd.getOpinion());
-            flowService.saveFlow(instanceId, OpenEnum.SUBMIT, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.SUBMIT, flowCmd);
         } catch (Exception e) {
             IdempotentCmd idempotentCmd = IdempotentCmd.builder().pkId(cmd.getId().toString()).orderStatus(IdempotentEnum.SubmitFlow.getIndex()).build();
             idempotentCmd.setInstanceId(instanceId);
@@ -1883,7 +1890,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
     private void verifyAndRevokeFlow(ExpenseReimbursementCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         FlowCmd flowCmd = cmd.getFlowList().get(0);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(cmd.getProcessInstanceId());
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(cmd.getProcessInstanceId());
         if (ObjectUtils.isEmpty(processDefinitionInfo) || ObjectUtils.isEmpty(processDefinitionInfo.getFlowNodeList())) {
             throw ExceptionUtil.getException(null, "娴佺▼瀹氫箟淇℃伅涓嶅瓨鍦�");
         }
@@ -1897,14 +1904,14 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd))
-            flowService.saveFlow(instanceId, OpenEnum.REVOKE, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.REVOKE, flowCmd);
     }
 
     /**楠岃瘉骞跺洖閫€娴佺▼*/
     private void verifyAndRegressFlow(ExpenseReimbursementCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         FlowCmd flowCmd = cmd.getFlowList().get(0);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(cmd.getProcessInstanceId());
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(cmd.getProcessInstanceId());
         if (ObjectUtils.isEmpty(processDefinitionInfo) || ObjectUtils.isEmpty(processDefinitionInfo.getFlowNodeList())) {
             throw ExceptionUtil.getException(null, "娴佺▼瀹氫箟淇℃伅涓嶅瓨鍦�");
         }
@@ -1918,14 +1925,14 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd))
-            flowService.saveFlow(instanceId, OpenEnum.REGRESS, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.REGRESS, flowCmd);
     }
 
     /**楠岃瘉骞堕┏鍥炴祦绋�*/
     private void verifyAndBackFlow(ExpenseReimbursementCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         FlowCmd flowCmd = cmd.getFlowList().get(0);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(cmd.getProcessInstanceId());
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(cmd.getProcessInstanceId());
         if (ObjectUtils.isEmpty(processDefinitionInfo) || ObjectUtils.isEmpty(processDefinitionInfo.getFlowNodeList())) {
             throw ExceptionUtil.getException(null, "娴佺▼瀹氫箟淇℃伅涓嶅瓨鍦�");
         }
@@ -1941,7 +1948,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd)) {
-            flowService.saveFlow(instanceId, OpenEnum.BACK, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.BACK, flowCmd);
             cmd.setOrderStatus(OrderStatusEnum.BACK.getName());
         }
     }
@@ -1970,7 +1977,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd))
-            flowService.saveFlow(instanceId, OpenEnum.COPY, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.COPY, flowCmd);
     }
 
     /**楠岃瘉骞舵煡闃呮妱閫佹祦绋�*/
@@ -1995,7 +2002,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd))
-            flowService.saveFlow(instanceId, OpenEnum.CHECK_COPY, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.CHECK_COPY, flowCmd);
     }
 
     /**楠岃瘉骞舵巿鏉冩祦绋�*/
@@ -2020,7 +2027,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         flowCmd.getBusinessData().put("applicantNo", cmd.getApplicantNo());
         flowCmd.getBusinessData().put("applicantName", cmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd))
-            flowService.saveFlow(instanceId, OpenEnum.AUTHORIZE, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.AUTHORIZE, flowCmd);
     }
 
     /**楠岃瘉骞舵巿鏉冩祦绋�*/
@@ -2034,7 +2041,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             verifySubmitFlow(cmd);
             String opinion = ObjectUtils.isEmpty(flowCmd.getOpinion()) ? "瀹℃壒閫氳繃" : flowCmd.getOpinion();
             flowCmd.setOpinion("璁剧疆鍗忓姙锛�" + opinion);
-            flowService.saveFlow(instanceId, OpenEnum.SET_CO_AUDIT, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.SET_CO_AUDIT, flowCmd);
         } catch (Exception e) {
             log.error("瀹℃壒楠岃瘉澶辫触锛�" + e.getMessage() + e.getStackTrace());
             throw ExceptionUtil.getException(null, "瀹℃壒楠岃瘉澶辫触锛�" + e.getMessage());
@@ -2078,7 +2085,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             cmd.setFinStatus(false);
         }
 
-        Date approveStartDate =  flowService.getCurrentDate();
+        Date approveStartDate =  FlowUtil.INSTANCE(instanceId).getCurrentDate();
         if (ObjectUtils.isEmpty(cmd.getFlowList()) || ObjectUtils.isEmpty(cmd.getFlowList().get(0).getTaskId())) {
             throw ExceptionUtil.getException(null, "瀹℃牳閿欒锛屾湭鎵惧埌瀹℃牳璁板綍");
         }
@@ -2094,7 +2101,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         }
         NodeOut canRevokeNode = null;
         if (OpenEnum.REVOKE.getIndex().equals(open)) {
-            canRevokeNode = flowService.getCanRevokeNode(flowQuery);
+            canRevokeNode = FlowUtil.INSTANCE(instanceId).getCanRevokeNode(flowQuery);
             if (ObjectUtils.isEmpty(canRevokeNode)) {
                 throw ExceptionUtil.getException(null, "褰撳墠鑺傜偣涓嶅彲鎾ゅ洖");
             }
@@ -2110,7 +2117,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 //閫氳繃-姝e父鎻愪氦鍒颁笅涓€鑺傜偣
                 verifyAndSubmitFlow(cmd);
 //                //璁剧疆瀹℃壒鍚庡崟鎹姸鎬�
-//                List<HistoryInfoOut> flowHistory = flowService.getFlowHistory(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
+//                List<HistoryInfoOut> flowHistory = FlowUtil.INSTANCE(instanceId).getFlowHistory(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
 //                cmd.setOrderStatus(flowHistory.get(flowHistory.size() - 1).getEndNodeName());
                 break;
             case REVOKE:
@@ -2195,7 +2202,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
         finally {
             log.info("approvalProcessing: 鍥炲啓鐘舵€�");
             boolean isExternalDataServiceJavaImpl = ReimbursementTypeEnum.isExternalDataServiceJavaImpl(cmd.getOrderType());
-            applyOut = Boolean.FALSE.equals(cmd.getDoReturnApplicationStatus()) ? returnApplicationStatusOpen(cmd)
+            applyOut = Boolean.FALSE.equals(cmd.getDoClaimsApi()) ? returnApplicationStatusOpen(cmd)
                     : isExternalDataServiceJavaImpl ? returnApplicationStatus2(cmd) : returnApplicationStatus(cmd);
         }
         return applyOut;
@@ -2481,7 +2488,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
             try {
                 //璁剧疆娴佺▼淇℃伅flowCmd
                 FlowQuery flowQuery = FlowQuery.builder().processInstanceId(approvalPo.getProcessInstanceId()).build();
-                List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+                List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
                 List<FlowCmd> flowList = MapperUtils.INSTANCE.mapAsList(FlowCmd.class, flowOutList);
                 if (ObjectUtils.isEmpty(loginUser))
                     loginUser = UserInfoOut.builder().userNo(approvalPo.getApplicantNo()).userName(approvalPo.getApplicantName()).build();
@@ -2533,7 +2540,7 @@ public class ExpenseReimbursementServiceImpl implements ExpenseReimbursementServ
                 }
                 else if (OpenEnum.SUBMIT.getIndex().equals(open)) {
                     //Submit
-                    List<NodeOut> nextNodeList = flowService.getNextNodes(flowQuery);
+                    List<NodeOut> nextNodeList = FlowUtil.INSTANCE(instanceId).getNextNodes(flowQuery);
                     if (ObjectUtils.isEmpty(nextNodeList))
                         throw ExceptionUtil.getException(null, "鏃犱笅涓€鑺傜偣锛屼笉鑳芥壒閲忓鎵归€氳繃");
                     if (ObjectUtils.isNotEmpty(nextNodeList) && nextNodeList.size() > 1)
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExternalDataServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExternalDataServiceImpl.java
index 7c79a7845890c52fa8bcd0aa3eda8f56ceb73671..bcd08fe5572beeddb10916953a0227e70796bad5 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExternalDataServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ExternalDataServiceImpl.java
@@ -40,6 +40,7 @@ import com.seasky.flowportal.dto.extendData.InvoicingTaxCmd;
 import com.seasky.flowportal.dto.fapiao.FapiaoDownloadOut;
 import com.seasky.flowportal.dto.fapiao.FapiaoDownloadResponse;
 import com.seasky.flowportal.dto.fundsFlowDetail.FundsFlowDetailClaimsOut;
+import com.seasky.flowportal.dto.kingDee.*;
 import com.seasky.flowportal.dto.personInfo.PersonFromOrgInfoOut;
 import com.seasky.flowportal.dto.personInfo.PersonInfoOut;
 import com.seasky.flowportal.dto.personInfo.PersonInfoQuery;
@@ -63,6 +64,8 @@ import com.seasky.flowportal.dto.user.ExcludedUserInfoQuery;
 import com.seasky.flowportal.dto.user.UserInfoOut;
 import com.seasky.flowportal.dto.user.UserInfoQuery;
 import com.seasky.flowportal.enums.BusinessSystemEnum;
+import com.seasky.flowportal.enums.OrderTypesEnum;
+import com.seasky.flowportal.enums.ReimbursementTypeEnum;
 import com.seasky.flowportal.enums.SchoolEnum;
 import com.seasky.flowportal.pojo.ExternalPostPojo;
 import com.seasky.flowportal.pojo.FileContentPojo;
@@ -75,6 +78,7 @@ import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -1731,6 +1735,200 @@ public abstract class ExternalDataServiceImpl implements ExternalDataService {
         return cityInfoList;
     }
 
+
+
+    protected static String ErrorMessageKingDee = "閲戣澏娴佺▼鎺ュ彛杩斿洖锛�";
+
+    private String getNonce()
+    {
+        int length = new Random().nextInt(6)+5;
+        return RandomStringUtils.randomAlphabetic(length);
+    }
+
+    @Override
+    @SneakyThrows
+    public String getKingDeeToken(Long instanceId) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        String token = MyRedisUtil.getToken(instanceId, "KingDee");
+        if (ObjectUtils.isNotEmpty(token))
+            return token;
+
+        BaseConfigProperties baseConfigProperties = BaseConfigUtil.INSTANCE.getBaseConfigProperties(instanceId);
+        Map<String, Object> paramMap = new HashMap<String, Object>() {{
+            put("client_id", baseConfigProperties.getKingDeeClientId());
+            put("client_secret", baseConfigProperties.getKingDeeClientSecret());
+            put("username", baseConfigProperties.getKingDeeClientUserName());
+            put("accountId", baseConfigProperties.getKingDeeAccountId());
+            put("nonce", getNonce());
+            put("timestamp", Constant.L_DATE_FORMAT.format(new Date()));
+            put("language", "zh_CN");
+        }};
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.KINGDEE_GET_TOKEN);
+        String request = JSON.toJSONString(paramMap);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.get(interfaceUrl, paramMap, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+
+        KingDeeGetTokenResultOut resultOut = null;
+        try { resultOut = JSONObject.parseObject(response, KingDeeGetTokenResultOut.class); } catch (Exception ignored) {}
+        if (ObjectUtils.isEmpty(resultOut))
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + response);
+        if (!resultOut.isSuccess())
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + resultOut.getMessage());
+        KingDeeGetTokenResultDataOut data = resultOut.getData();
+        token = ObjectUtils.isEmpty(data) ? null : data.getAccessToken();
+        if (ObjectUtils.isEmpty(token))
+            throw ExceptionUtil.getException(null, "鑾峰彇token澶辫触");
+        Integer expiresIn = ObjectUtils.isEmpty(data) ? null : data.getExpiresIn() / 1000;
+        if (ObjectUtils.isNotEmpty(expiresIn))
+            MyRedisUtil.setToken(instanceId, "KingDee", token, expiresIn);
+        return token;
+    }
+
+    @Override
+    @SneakyThrows
+    public String commonNewExpenseBillByType(Long instanceId, String orderCode) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        KingDeeCommonNewExpenseBillByTypeRequest data = queryClaimsOrderInfo(instanceId, orderCode);
+        String token = getKingDeeToken(instanceId);
+        Map<String, String> headerMap = new HashMap<String, String>() {{
+//            put("Authorization",String.format("Bearer %s", token));
+            put("accessToken", token);
+        }};
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.KINGDEE_COMMON_NEW_EXPENSE_BILL_BY_TYPE);
+        String request = JSON.toJSONString(data);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s,璇锋眰澶达細%s", interfaceUrl, request, JSON.toJSONString(headerMap)));
+        String response = com.seasky.flowportal.utils.HttpUtil.post(interfaceUrl, request, timeout, headerMap);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        KingDeeCreateFlowOut resultOut = null;
+        try { resultOut = JSONObject.parseObject(response, KingDeeCreateFlowOut.class); } catch (Exception ignored) {}
+        if (ObjectUtils.isEmpty(resultOut))
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + response);
+        if (!resultOut.isSuccess())
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + resultOut.getMessage());
+        return resultOut.getBillId();
+    }
+
+    @Override
+    @SneakyThrows
+    public String addSalaryBill(Long instanceId, String orderCode) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        KingDeeAddSalaryBillRequest data = getSalaryDeclareOrderDetail(instanceId, orderCode);
+        String token = getKingDeeToken(instanceId);
+        Map<String, String> headerMap = new HashMap<String, String>() {{
+//            put("Authorization",String.format("Bearer %s", token));
+            put("accessToken", token);
+        }};
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.KINGDEE_ADD_SALARY_BILL);
+        String request = JSON.toJSONString(data);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s,璇锋眰澶达細%s", interfaceUrl, request, JSON.toJSONString(headerMap)));
+        String response = com.seasky.flowportal.utils.HttpUtil.post(interfaceUrl, request, timeout, headerMap);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        KingDeeCreateFlowOut resultOut = null;
+        try { resultOut = JSONObject.parseObject(response, KingDeeCreateFlowOut.class); } catch (Exception ignored) {}
+        if (ObjectUtils.isEmpty(resultOut))
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + response);
+        if (!resultOut.isSuccess())
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + resultOut.getMessage());
+        return resultOut.getBillId();
+    }
+
+    @Override
+    @SneakyThrows
+    public String updateSeaSkyFiAuditResult(ApplyOut out) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(out);
+        return updateSeaSkyFiAuditResult(instanceId, out.getOrderNo(), out.getOrderType(), out.getApprovalOpinion());
+    }
+
+    @Override
+    @SneakyThrows
+    public String updateSeaSkyFiAuditResult(Long instanceId, String orderCode, String orderType, String approvalOpinion) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        ReimbursementTypeEnum reimbursementTypeEnum = ReimbursementTypeEnum.getValueByName(orderType);
+        String businessType = ObjectUtils.isEmpty(reimbursementTypeEnum) ? "" : reimbursementTypeEnum.getIndex();
+        KingDeeUpdateSeaSkyFiAuditResultRequest data = KingDeeUpdateSeaSkyFiAuditResultRequest.builder()
+                .businessType(businessType)
+                .orderNo(!OrderTypesEnum.isSalary(orderType) ? orderCode : null)
+                .declareBillNo(OrderTypesEnum.isSalary(orderType) ? orderCode : null)
+                .auditMessage(approvalOpinion)
+                .build();
+        String token = getKingDeeToken(instanceId);
+        Map<String, String> headerMap = new HashMap<String, String>() {{
+//            put("Authorization",String.format("Bearer %s", token));
+            put("accessToken", token);
+        }};
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.KINGDEE_UPDATE_AUDIT_RESULT);
+        String request = JSON.toJSONString(data);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s,璇锋眰澶达細%s", interfaceUrl, request, JSON.toJSONString(headerMap)));
+        String response = com.seasky.flowportal.utils.HttpUtil.post(interfaceUrl, request, timeout, headerMap);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        KingDeeUpdateSeaSkyFiAuditResultOut resultOut = null;
+        try { resultOut = JSONObject.parseObject(response, KingDeeUpdateSeaSkyFiAuditResultOut.class); } catch (Exception ignored) {}
+        if (ObjectUtils.isEmpty(resultOut))
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + response);
+        if (!resultOut.isSuccess())
+            throw ExceptionUtil.getException(null, ErrorMessageKingDee + resultOut.getMessage());
+        return resultOut.getData();
+    }
+
+
+    @Override
+    @SneakyThrows
+    public KingDeeCommonNewExpenseBillByTypeRequest queryClaimsOrderInfo(Long instanceId, String orderCode) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        KingDeeCommonNewExpenseBillByTypeRequest data = null;
+        ExternalPostPojo baseExternalPost = PortalUtil.getBaseExternalPost(instanceId);
+        baseExternalPost.setOrderNo(orderCode);
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.EXTERNAL_QUERY_ORDER_INFO);
+        String request = JSON.toJSONString(baseExternalPost);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.post(interfaceUrl, request, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        JSONObject resultJSONObj = JSONObject.parseObject(response);
+        boolean isSuccess = Boolean.TRUE.equals(resultJSONObj.getBoolean("isSuccess"));
+        if (!isSuccess) {
+            String errorMessage = resultJSONObj.getString("errorMessage");
+            throw ExceptionUtil.getException(null, "鏌ヨ缃戞姤鍗曟嵁寮傚父锛�" + errorMessage);
+        }
+        try {
+            data = resultJSONObj.getObject("data", KingDeeCommonNewExpenseBillByTypeRequest.class);
+        }
+        catch (Exception e) {
+            log.info("鏌ヨ缃戞姤鍗曟嵁寮傚父锛�" + e.getMessage(), e);
+            throw ExceptionUtil.getException(null, "鏌ヨ缃戞姤鍗曟嵁寮傚父锛�" + e.getMessage());
+        }
+        return data;
+    }
+
+    @Override
+    @SneakyThrows
+    public KingDeeAddSalaryBillRequest getSalaryDeclareOrderDetail(Long instanceId, String orderCode) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        KingDeeAddSalaryBillRequest data = null;
+        ExternalPostPojo baseExternalPost = PortalUtil.getBaseExternalPost(instanceId);
+        baseExternalPost.setDeclareBillNo(orderCode);
+        String interfaceUrl = BaseConfigUtil.INSTANCE.getInterfaceUrl(instanceId, InterfaceUrlConstant.EXTERNAL_GET_SALARY_DECLARE_ORDER_DETAIL);
+        String request = JSON.toJSONString(baseExternalPost);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,璇锋眰鍙傛暟锛�%s", interfaceUrl, request));
+        String response = HttpUtil.post(interfaceUrl, request, timeout);
+        log.info(String.format("璇锋眰鎺ュ彛锛氳姹傚湴鍧€锛�%s,鍝嶅簲缁撴灉锛�%s", interfaceUrl, response));
+        JSONObject resultJSONObj = JSONObject.parseObject(response);
+        boolean isSuccess = Boolean.TRUE.equals(resultJSONObj.getBoolean("isSuccess"));
+        if (!isSuccess) {
+            String errorMessage = resultJSONObj.getString("errorMessage");
+            throw ExceptionUtil.getException(null, "鏌ヨ钖祫鍗曟嵁寮傚父锛�" + errorMessage);
+        }
+        try {
+            data = resultJSONObj.getObject("data", KingDeeAddSalaryBillRequest.class);
+        }
+        catch (Exception e) {
+            log.info("鏌ヨ钖祫鍗曟嵁寮傚父锛�" + e.getMessage(), e);
+            throw ExceptionUtil.getException(null, "鏌ヨ钖祫鍗曟嵁寮傚父锛�" + e.getMessage());
+        }
+        return data;
+    }
+
+
     //#region 寮冪敤
 
     @Override
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceImpl.java
index fbd38e533dd0f73b1dadd9f0f72312787caf12dd..72616933ba093d0941726eeffc43aeaea6a25f97 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceImpl.java
@@ -25,7 +25,6 @@ import com.seasky.flow.enums.FlowStateEnum;
 import com.seasky.flowportal.config.BaseConfigProperties;
 import com.seasky.flowportal.config.SchoolProperties;
 import com.seasky.flowportal.domain.po.ApprovalPo;
-import com.seasky.flowportal.domain.po.BusFlowPo;
 import com.seasky.flowportal.domain.po.ExpenseReimbursementPo;
 import com.seasky.flowportal.domain.po.PreExpenseApplyPo;
 import com.seasky.flowportal.dto.approval.ApprovalCmd;
@@ -63,7 +62,7 @@ import org.springframework.stereotype.Service;
 import java.util.*;
 import java.util.stream.Collectors;
 
-@Service
+@Service("FlowServiceImpl")
 @Slf4j
 public class FlowServiceImpl extends FlowService {
 
@@ -332,8 +331,8 @@ public class FlowServiceImpl extends FlowService {
         String userNos = "";
         List<UserInfoOut> userInfoList = userList.stream().filter(user -> ObjectUtils.isNotEmpty(approverNoList) && approverNoList.contains(user.getUserNo())).collect(Collectors.toList());
         if (ObjectUtils.isNotEmpty(userInfoList)) {
-            userNames = userInfoList.stream().map(UserInfoOut::getUserName).collect(Collectors.joining(","));
-            userNos = userInfoList.stream().map(UserInfoOut::getUserNo).collect(Collectors.joining(","));
+            userNames = userInfoList.stream().map(UserInfoOut::getUserName).distinct().collect(Collectors.joining(","));
+            userNos = userInfoList.stream().map(UserInfoOut::getUserNo).distinct().collect(Collectors.joining(","));
         }
         flowToolOut.setUser(userNames);
         flowToolOut.setUserNo(userNos);
@@ -502,51 +501,21 @@ public class FlowServiceImpl extends FlowService {
 
     @Override
     public String saveFlow(Long instanceId, OpenEnum open, FlowCmd flowCmd) {
-        log.info("鎿嶄綔锛歿},鍙傛暟锛歿}", open.getName(), JSON.toJSONString(flowCmd));
         instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
         flowCmd.setInstanceId(instanceId);
-        String result = "";
         String orderStatus = "";
-        BusFlowPo busFlowPo = new BusFlowPo();
-        if (open != OpenEnum.CREATE) {
+        boolean isCreate = OpenEnum.CREATE.equals(open);
+        if (!isCreate) {
             NodeOut curNodeInfo = getCurNodeInfo(FlowQuery.builder().processInstanceId(flowCmd.getProcessInstanceId()).build());
             orderStatus = ObjectUtils.isEmpty(curNodeInfo) ? "" : curNodeInfo.getNodeName();
         }
-        switch (open) {
-            case CREATE:
-                result = createFlow(flowCmd);
-                if (ObjectUtils.isNotEmpty(result)) {
-                    TaskQueryQry taskQueryQry = new TaskQueryQry();
-                    taskQueryQry.setProcessInstanceId(result);
-                    flowCmd.setProcessInstanceId(result);
-                }
-                break;
-            case SUBMIT:
-                result = submitFlow(flowCmd);
-                break;
-            case BACK:
-                result = backFlow(flowCmd);
-                break;
-            case REVOKE:
-                result = revokeFlow(flowCmd);
-                break;
-            case REGRESS:
-                result = regressFlow(flowCmd);
-                break;
-            case COPY:
-                result = copyFlow(flowCmd);
-                break;
-            case CHECK_COPY:
-                result = checkCopyFlow(flowCmd);
-                break;
-            case AUTHORIZE:
-                result = authorizeFlow(flowCmd);
-                break;
-            case SET_CO_AUDIT:
-                result = setCoAuditFlow(flowCmd);
-                break;
-            default:
-                throw ExceptionUtil.getException(null, "娌℃湁褰撳墠鎿嶄綔鏂规硶");
+        String result = super.saveFlow(instanceId, open, flowCmd);
+        if (isCreate) {
+            if (ObjectUtils.isNotEmpty(result)) {
+                TaskQueryQry taskQueryQry = new TaskQueryQry();
+                taskQueryQry.setProcessInstanceId(result);
+                flowCmd.setProcessInstanceId(result);
+            }
         }
         saveBusFlow(instanceId, open, flowCmd, orderStatus);
         return result;
@@ -562,8 +531,9 @@ public class FlowServiceImpl extends FlowService {
             if (ObjectUtils.isNotEmpty(flowCmd.getApprover()))
                 userNoList.add(loginUserNo);
 
+            String processInstanceId = flowCmd.getProcessInstanceId();
             //鑾峰彇寰呭姙鑺傜偣
-            NodeOut curNodeInfo = getCurNodeInfo(FlowQuery.builder().processInstanceId(flowCmd.getProcessInstanceId()).build());
+            NodeOut curNodeInfo = getCurNodeInfo(FlowQuery.builder().processInstanceId(processInstanceId).build());
             List<String> assigneeList = ObjectUtils.isEmpty(curNodeInfo) || ObjectUtils.isEmpty(curNodeInfo.getAssignee()) ? new ArrayList<>()
                     : Arrays.asList(curNodeInfo.getAssignee().split(","));
             String nextOrderStatus = ObjectUtils.isEmpty(curNodeInfo) ? "" : curNodeInfo.getNodeName();
@@ -577,7 +547,6 @@ public class FlowServiceImpl extends FlowService {
             if (ObjectUtils.isEmpty(loginUser))
                 loginUser = LoginUtil.getLoginUser();
 
-            String auditor = "{}";
             //鑾峰彇鍗曞彿
             String applyCode = flowCmd.getBusinessKey();
             if ("null".equals(applyCode)) {
@@ -588,7 +557,8 @@ public class FlowServiceImpl extends FlowService {
 
             //鑾峰彇瀹℃牳浜�
             BusFlowUserCmd auditorCmd = null;
-            boolean noAuditor = OpenEnum.CREATE.equals(open) || OrderStatusEnum.FINISH.getName().equals(orderStatus);
+            boolean isCreate = OpenEnum.CREATE.equals(open);
+            boolean noAuditor = OrderStatusEnum.FINISH.getName().equals(orderStatus);
             if (!noAuditor) {
                 //鐢ㄦ埛id  鐢ㄦ埛宸ュ彿  鐢ㄦ埛鍚�   userId  userCode   userName
                 auditorCmd = BusFlowUserCmd.builder()
@@ -599,7 +569,6 @@ public class FlowServiceImpl extends FlowService {
             }
 
             //鑾峰彇寰呭姙浜�
-            String nextAuditor = "[]";
             List<BusFlowUserCmd> nextAuditorCmdList = new ArrayList<>();
             if (!noNextAuditor) {
                 for (String assignee : assigneeList) {
@@ -614,9 +583,31 @@ public class FlowServiceImpl extends FlowService {
                 }
             }
             //璋冪敤 busflowService  createAndPushBusFlow
+            String openIndex = open.getIndex();
+            if (isCreate) {
+                BusFlowCmd cmd = BusFlowCmd.builder()
+                        .open(openIndex)
+                        .documentId(processInstanceId)
+                        .applyCode(applyCode)
+                        .orderStatus("")
+                        .nextOrderStatus(OrderStatusEnum.APPLY.getName())
+                        .webUrl(flowCmd.getWebUrl())
+                        .executionStatus(ExecutionStatusEnum.Unexecuted.getIndex())
+                        .log("[]")
+                        .applicantNo(applicantNo)
+                        .applicantName(applicantName)
+                        .build();
+                cmd.setAuditorCmd(null);
+                cmd.setNextAuditorCmdList(Collections.singletonList(auditorCmd));
+                cmd.setInstanceId(instanceId);
+                BusFlowUtil.INSTANCE(instanceId).createAndPushBusFlow(cmd);
+
+                openIndex = OpenEnum.SUBMIT.getIndex();
+                orderStatus = OrderStatusEnum.APPLY.getName();
+            }
             BusFlowCmd cmd = BusFlowCmd.builder()
-                    .open(open.getIndex())
-                    .documentId("")
+                    .open(openIndex)
+                    .documentId(processInstanceId)
                     .applyCode(applyCode)
                     .orderStatus(orderStatus)
                     .nextOrderStatus(nextOrderStatus)
@@ -625,7 +616,6 @@ public class FlowServiceImpl extends FlowService {
                     .log("[]")
                     .applicantNo(applicantNo)
                     .applicantName(applicantName)
-                    .documentId(flowCmd.getProcessInstanceId())
                     .build();
             cmd.setAuditorCmd(auditorCmd);
             cmd.setNextAuditorCmdList(nextAuditorCmdList);
@@ -794,11 +784,6 @@ public class FlowServiceImpl extends FlowService {
         return nextNode.getData();
     }
 
-    @Override
-    public List<String> getCurAuditorId(FlowQuery flowQuery) {
-        return null;
-    }
-
     @Override
     public List<HistoryInfoOut> getFlowHistory(FlowQuery flowQuery) {
         List<HistoryInfoOut> historyInfoOutList = new ArrayList<>();
@@ -955,11 +940,6 @@ public class FlowServiceImpl extends FlowService {
         return finishList.getData();
     }
 
-    @Override
-    public Integer createFlowAgain(FlowQuery flowQuery, FlowOpenEnum flowOpenEnum) {
-        return 0;
-    }
-
     @Override
     public NodeOut getCanRevokeNode(FlowQuery flowQuery) {
         UserInfoOut loginUser = LoginUtil.getLoginUser();
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceKingDeeImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceKingDeeImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..db25eb80ca9bc0360474400c0f46e4b4011e36d5
--- /dev/null
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/FlowServiceKingDeeImpl.java
@@ -0,0 +1,59 @@
+package com.seasky.flowportal.service.impl;
+
+import com.seasky.core.util.ExceptionUtil;
+import com.seasky.flowportal.domain.po.ApprovalPo;
+import com.seasky.flowportal.dto.apply.ApplyListOut;
+import com.seasky.flowportal.dto.apply.ApplyOut;
+import com.seasky.flowportal.dto.approval.ApprovalQuery;
+import com.seasky.flowportal.dto.flow.FlowCmd;
+import com.seasky.flowportal.enums.OrderTypesEnum;
+import com.seasky.flowportal.service.FlowService;
+import com.seasky.flowportal.utils.ApprovalUtil;
+import com.seasky.flowportal.utils.BaseInOutUtil;
+import com.seasky.flowportal.utils.ExternalDataUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service("FlowServiceKingDeeImpl")
+@Slf4j
+public class FlowServiceKingDeeImpl extends FlowService {
+
+    @Override
+    public String createFlow(FlowCmd flowCmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(flowCmd);
+        String orderCode = flowCmd.getBusinessKey();
+        ApprovalQuery qry = ApprovalQuery.builder().orderCode(orderCode).build();
+        qry.setInstanceId(instanceId);
+        ApprovalPo po = ApprovalUtil.getApproval(qry);
+        if (ObjectUtils.isEmpty(po))
+            throw ExceptionUtil.getException(null, "鏍规嵁鎶ラ攢鍗曞彿鏈煡璇㈠埌鍗曟嵁");
+        String billId = null;
+        String orderType = po.getOrderType();
+        if (OrderTypesEnum.isOnlineReimbursement(orderType))
+            billId = ExternalDataUtil.INSTANCE.commonNewExpenseBillByType(instanceId, orderCode);
+        else if (OrderTypesEnum.isSalary(orderType))
+            billId = ExternalDataUtil.INSTANCE.addSalaryBill(instanceId, orderCode);
+        return billId;
+    }
+
+    @Override
+    public String updateAuditResult(ApplyListOut applyListOut) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(applyListOut);
+        String result = "";
+        List<ApplyOut> applyOutList = applyListOut.getApplyOutList();
+        for (ApplyOut applyOut : applyOutList) {
+            applyOut.setInstanceId(instanceId);
+            try {
+                result = ExternalDataUtil.INSTANCE.updateSeaSkyFiAuditResult(applyOut);
+            }
+            catch (Exception e) {
+                log.info("鏇存柊瀹℃壒缁撴灉澶辫触锛�" + e.getMessage(), e);
+            }
+        }
+        return result;
+    }
+
+}
\ No newline at end of file
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangXiZhiZao_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangXiZhiZao_VerifyReimbursementServiceImpl.java
index d459298b3c20473425c72e249e7b65908b027474..580ae6c81ae0ddda74d722f7d308a17c9132e62f 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangXiZhiZao_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangXiZhiZao_VerifyReimbursementServiceImpl.java
@@ -17,16 +17,10 @@ import com.seasky.flowportal.enums.ApplyCategoryEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.enums.PreExpenseTypeEnum;
 import com.seasky.flowportal.enums.ReimbursementTypeEnum;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
@@ -40,10 +34,6 @@ import java.util.stream.Collectors;
 public class GuangXiZhiZao_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     @Override
     public String verifyReimbursementSelectUser(ExpenseReimbursementCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
@@ -121,6 +111,10 @@ public class GuangXiZhiZao_VerifyReimbursementServiceImpl extends VerifyReimburs
                     case DailyReimbursementV5:
                         result = dailyReimbursementProcess(cmd);
                         break;
+                    case ComeGoReimbursement:
+                    case ComeGoReimbursementV5:
+                        result = comeGoReimbursementProcess(cmd);
+                        break;
                     default:
                         break;
                 }
@@ -160,7 +154,7 @@ public class GuangXiZhiZao_VerifyReimbursementServiceImpl extends VerifyReimburs
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
                     }
@@ -173,6 +167,28 @@ public class GuangXiZhiZao_VerifyReimbursementServiceImpl extends VerifyReimburs
         result.add(OrderStatusEnum.FINISH.getName());
         return result;
     }
+    private List<String> comeGoReimbursementProcess(ApprovalCmd cmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
+        List<String> result = new ArrayList<>();
+        ExpenseReimbursementCmd model = (ExpenseReimbursementCmd) ApprovalUtil.toActualType(cmd);
+
+        List<String> leaderEndorserNoList = model.getLeaderEndorserNoList();
+        if (ObjectUtils.isEmpty(leaderEndorserNoList)) {
+            String processInstanceId = cmd.getProcessInstanceId();
+            if (ObjectUtils.isNotEmpty(processInstanceId)) {
+                try {
+                    String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                    JSONObject jsonObject = JSONObject.parseObject(processVariable);
+                    leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
+                }
+                catch (Exception ignored) { }
+            }
+        }
+        if (ObjectUtils.isNotEmpty(leaderEndorserNoList))
+            result.add(AssigneeEnum.AuditOrg.getNodeName());
+        result.add(OrderStatusEnum.FINISH.getName());
+        return result;
+    }
 
     @Override
     public List<String> getApproverUserNodeNameList(ExpenseReimbursementCmd cmd) {
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangZhongYi_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangZhongYi_VerifyReimbursementServiceImpl.java
index 1be85317fa1c3c70061fbfee9f97376d2a98f108..8d5fb75e00e8bc94e84a0dff2069fbcb9dc9036b 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangZhongYi_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/GuangZhongYi_VerifyReimbursementServiceImpl.java
@@ -21,17 +21,14 @@ import com.seasky.flowportal.dto.personInfo.PersonInfoOut;
 import com.seasky.flowportal.dto.signature.SignatureCmd;
 import com.seasky.flowportal.dto.user.UserInfoOut;
 import com.seasky.flowportal.dto.user.UserInfoQuery;
-import com.seasky.flowportal.enums.*;
-import com.seasky.flowportal.service.FlowService;
+import com.seasky.flowportal.enums.ApplyCategoryEnum;
+import com.seasky.flowportal.enums.OrderStatusEnum;
+import com.seasky.flowportal.enums.OrderTypesEnum;
+import com.seasky.flowportal.enums.ReimbursementTypeEnum;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -49,10 +46,6 @@ import java.util.stream.Collectors;
 public class GuangZhongYi_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     private static List<String> foundationProcessProjectCodeList = Arrays.asList(
             "A-0000-00-441-001", "A-0000-00-441-002", "A-0000-00-441-003", "A-0000-00-441-004", "A-0000-00-441-005");
 
@@ -221,7 +214,7 @@ public class GuangZhongYi_VerifyReimbursementServiceImpl extends VerifyReimburse
             result.add(AssigneeEnum.OptionalCounterSignatory.getNodeName());
         else if (ObjectUtils.isNotEmpty(processInstanceId)) {
             try {
-                String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                 JSONObject jsonObject = JSONObject.parseObject(processVariable);
                 List<String> leaderEndorserNoList = jsonObject.getJSONArray("borrowerEndorserNoList").toJavaList(String.class);
                 if (ObjectUtils.isNotEmpty(leaderEndorserNoList))
@@ -254,7 +247,7 @@ public class GuangZhongYi_VerifyReimbursementServiceImpl extends VerifyReimburse
                     result.add(AssigneeEnum.SubSchoolLeader.getNodeName());
                     if (ObjectUtils.isNotEmpty(processInstanceId)) {
                         try {
-                            String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "approval");
+                            String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "approval");
                             JSONObject jsonObject = JSONObject.parseObject(processVariable);
                             List<String> subSchoolLeaderList = jsonObject.getJSONArray("subSchoolLeaderAssigneeList").toJavaList(String.class);
                             if (subSchoolLeaderList.contains(model.getApplicantNo()) && super.checkApplyUserEqualsProjectCharge(cmd))
@@ -372,7 +365,7 @@ public class GuangZhongYi_VerifyReimbursementServiceImpl extends VerifyReimburse
             result.add(AssigneeEnum.OptionalCounterSignatory.getNodeName());
         else if (ObjectUtils.isNotEmpty(processInstanceId)) {
             try {
-                String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                 JSONObject jsonObject = JSONObject.parseObject(processVariable);
                 List<String> leaderEndorserNoList = jsonObject.getJSONArray("borrowerEndorserNoList").toJavaList(String.class);
                 if (ObjectUtils.isNotEmpty(leaderEndorserNoList))
@@ -421,7 +414,7 @@ public class GuangZhongYi_VerifyReimbursementServiceImpl extends VerifyReimburse
             result.add(AssigneeEnum.OptionalCounterSignatory.getNodeName());
         else if (ObjectUtils.isNotEmpty(processInstanceId)) {
             try {
-                String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                 JSONObject jsonObject = JSONObject.parseObject(processVariable);
                 List<String> leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
                 if (ObjectUtils.isNotEmpty(leaderEndorserNoList))
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/HaiYang_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/HaiYang_VerifyReimbursementServiceImpl.java
index ee600f39710309aa3de797687954d6634265756e..14c89c842597f621e06b5c56f143a7cf196bdcdf 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/HaiYang_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/HaiYang_VerifyReimbursementServiceImpl.java
@@ -17,16 +17,15 @@ import com.seasky.flowportal.enums.ApplyCategoryEnum;
 import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.enums.OrderTypesEnum;
 import com.seasky.flowportal.enums.ReimbursementTypeEnum;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.SpecialProjectService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
 import com.seasky.flowportal.utils.ApprovalUtil;
 import com.seasky.flowportal.utils.BaseInOutUtil;
 import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.FlowUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -44,11 +43,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class HaiYang_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     @Autowired
     private SpecialProjectService specialProjectService;
 
@@ -219,7 +213,7 @@ public class HaiYang_VerifyReimbursementServiceImpl extends VerifyReimbursementS
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                     }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/PreExpenseApplyServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/PreExpenseApplyServiceImpl.java
index 92389273f96a8faa0493924b166eb25538abca41..d7c65676787b8d4d4df92dd6b96ceeb55ddcf211 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/PreExpenseApplyServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/PreExpenseApplyServiceImpl.java
@@ -97,10 +97,6 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
     @Lazy
     private PreApplyAuthMapper preApplyAuthMapper;
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     @Autowired
     @Lazy
     private ApproverUserService approverUserService;
@@ -390,7 +386,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         //鍐荤粨閲戦
         if (isCreate)
             freezeBud(instanceId, cmd.getId());
-        Date approveStartDate = flowService.getCurrentDate();
+        Date approveStartDate = FlowUtil.INSTANCE(instanceId).getCurrentDate();
         saveFlow(cmd, loginUser);
         ApprovalUtil.setCurFlowInfo(cmd);
         ApprovalUtil.createApproverSignature(cmd, approveStartDate);
@@ -530,7 +526,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         String auditResult = isBack ? "瀹℃壒椹冲洖" : "瀹℃壒閫氳繃";
 
         FlowQuery flowQuery = FlowQuery.builder().processInstanceId(po.getProcessInstanceId()).build();
-        List<HistoryInfoOut> approveHistory = flowService.getFlowHistory(flowQuery);
+        List<HistoryInfoOut> approveHistory = FlowUtil.INSTANCE(instanceId).getFlowHistory(flowQuery);
         HistoryInfoOut lastHistory = ObjectUtils.isEmpty(approveHistory) ? null : approveHistory.get(approveHistory.size() - 1);
         Date auditDate = ObjectUtils.isEmpty(lastHistory) ? null : lastHistory.getEndTime();
         String auditReason = isFinish || ObjectUtils.isEmpty(lastHistory) ? null : lastHistory.getDeleteReason();
@@ -590,7 +586,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         }
         flowCmd.setProcessDefinitionKey(defKey);
 
-        String save = flowService.saveFlow(instanceId, OpenEnum.CREATE, flowCmd);
+        String save = FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.CREATE, flowCmd);
         preExpenseApplyCmd.setProcessInstanceId(save);
     }
 
@@ -614,7 +610,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         }
         flowCmd.setOpinion(ObjectUtils.defaultIfNull(flowCmd.getOpinion(), ""));
         FlowQuery flowQuery = FlowQuery.builder().processInstanceId(preExpenseApplyCmd.getProcessInstanceId()).build();
-        List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+        List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
         //鑻ュ綋鍓嶇櫥褰曚汉瀛樺湪寰呭姙锛屽垯绛涢€�
         if (flowOutList.stream().anyMatch(s -> loginUser.getUserNo().equals(s.getApprover()))) {
             flowOutList = flowOutList.stream().filter(s -> loginUser.getUserNo().equals(s.getApprover())).collect(Collectors.toList());
@@ -628,7 +624,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         flowQuery = MapperUtils.INSTANCE.map(FlowQuery.class, flowCmd);
         NodeOut canRevokeNode = null;
         if (OpenEnum.REVOKE.equals(openEnum)) {
-            canRevokeNode = flowService.getCanRevokeNode(flowQuery);
+            canRevokeNode = FlowUtil.INSTANCE(instanceId).getCanRevokeNode(flowQuery);
             if (ObjectUtils.isEmpty(canRevokeNode)) {
                 throw ExceptionUtil.getException(null, "褰撳墠鑺傜偣涓嶅彲鎾ゅ洖");
             }
@@ -641,13 +637,13 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
                 //閫氳繃-姝e父鎻愪氦鍒颁笅涓€鑺傜偣
                 verifyAndSubmitFlow(preExpenseApplyCmd);
 //                //璁剧疆瀹℃壒鍚庡崟鎹姸鎬�
-//                List<HistoryInfoOut> flowHistory = flowService.getFlowHistory(FlowQuery.builder().processInstanceId(preExpenseApplyCmd.getProcessInstanceId()).build());
+//                List<HistoryInfoOut> flowHistory = FlowUtil.INSTANCE(instanceId).getFlowHistory(FlowQuery.builder().processInstanceId(preExpenseApplyCmd.getProcessInstanceId()).build());
 //                preExpenseApplyCmd.setOrderStatus(flowHistory.get(flowHistory.size() - 1).getEndNodeName());
                 break;
             case REVOKE:
                 //鎾ゅ洖鍒颁笂涓€鑺傜偣
                 flowCmd.setApprover(loginUser.getUserNo());
-                flowService.revokeFlow(flowCmd);
+                FlowUtil.INSTANCE(instanceId).revokeFlow(flowCmd);
                 break;
             case BACK: {
                 //椹冲洖鍒板鎵归┏鍥炶妭鐐�
@@ -671,7 +667,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         }
         FlowCmd flowCmd = preExpenseApplyCmd.getFlowList().get(0);
         try {
-            ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(preExpenseApplyCmd.getProcessInstanceId());
+            ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(preExpenseApplyCmd.getProcessInstanceId());
             Optional<FlowNode> activityNodeOptional = processDefinitionInfo.getFlowNodeList().stream().filter(s -> flowCmd.getActivityId().equals(s.getId())).findFirst();
             if (ObjectUtils.isEmpty(flowCmd.getBusinessData())) {
                 flowCmd.setBusinessData(new HashMap<String, Object>());
@@ -707,7 +703,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
             flowCmd.setOpinion(ObjectUtils.isEmpty(flowCmd.getOpinion()) ? "瀹℃壒閫氳繃" : flowCmd.getOpinion());
             flowCmd.setBusinessKey(preExpenseApplyCmd.getApplyCode());
             flowCmd.setWebUrl(PreApplyUtil.getWebUrlPreFix(instanceId, preExpenseApplyCmd.getApplyType()) + preExpenseApplyCmd.getApplyCode());
-            flowService.saveFlow(instanceId, OpenEnum.SUBMIT, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.SUBMIT, flowCmd);
         } catch (Exception e) {
             IdempotentCmd idempotentCmd = IdempotentCmd.builder().pkId(preExpenseApplyCmd.getId().toString()).orderStatus(IdempotentEnum.SubmitFlow.getIndex()).build();
             idempotentCmd.setInstanceId(instanceId);
@@ -721,7 +717,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
     private void verifyAndBackFlow(PreExpenseApplyCmd preExpenseApplyCmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(preExpenseApplyCmd);
         FlowCmd flowCmd = preExpenseApplyCmd.getFlowList().get(0);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(preExpenseApplyCmd.getProcessInstanceId());
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(preExpenseApplyCmd.getProcessInstanceId());
         if (ObjectUtils.isEmpty(processDefinitionInfo) || ObjectUtils.isEmpty(processDefinitionInfo.getFlowNodeList())) {
             throw ExceptionUtil.getException(null, "娴佺▼瀹氫箟淇℃伅涓嶅瓨鍦�");
         }
@@ -738,7 +734,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
         flowCmd.getBusinessData().put("applicantName", preExpenseApplyCmd.getApplicantName());
         if (ObjectUtils.isNotEmpty(flowCmd)) {
             log.info("璋冪敤activiti瀹℃壒椹冲洖:" + flowCmd);
-            flowService.saveFlow(instanceId, OpenEnum.BACK, flowCmd);
+            FlowUtil.INSTANCE(instanceId).saveFlow(instanceId, OpenEnum.BACK, flowCmd);
             preExpenseApplyCmd.setOrderStatus(OrderStatusEnum.BACK.getName());
         }
     }
@@ -899,7 +895,7 @@ public class PreExpenseApplyServiceImpl implements PreExpenseApplyService {
             }
             preExpenseApply.setAttachFileList(attachFileOutList);
             //璁剧疆娴佺▼淇℃伅flowCmd
-            List<FlowOut> flowOutList = flowService.getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(preExpenseApply.getProcessInstanceId()).build());
+            List<FlowOut> flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(preExpenseApply.getProcessInstanceId()).build());
             //鑻ュ綋鍓嶇櫥褰曚汉瀛樺湪寰呭姙锛屽垯绛涢€�
             if (flowOutList.stream().anyMatch(s -> LoginUtil.getLoginUserNo().equals(s.getApprover()))) {
                 flowOutList = flowOutList.stream().filter(s -> LoginUtil.getLoginUserNo().equals(s.getApprover())).collect(Collectors.toList());
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ShangDa_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ShangDa_VerifyReimbursementServiceImpl.java
index 208824d357995fab41898699beaa032144bb220a..ade627a127e3725127897b649c595941de7b364c 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ShangDa_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/ShangDa_VerifyReimbursementServiceImpl.java
@@ -27,13 +27,9 @@ import com.seasky.flowportal.enums.OrderStatusEnum;
 import com.seasky.flowportal.enums.PreExpenseTypeEnum;
 import com.seasky.flowportal.enums.ReimbursementTypeEnum;
 import com.seasky.flowportal.mapper.PreTravelOnBusinessPersonMapper;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.SignatureService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -52,7 +48,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-
     @Autowired
     @Lazy
     private SignatureService signatureService;
@@ -60,10 +55,6 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
     @Autowired
     private PreTravelOnBusinessPersonMapper preTravelOnBusinessPersonMapper;
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
 
 
     @Override
@@ -215,7 +206,7 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
                     String processInstanceId = cmd.getProcessInstanceId();
                     if (ObjectUtils.isNotEmpty(processInstanceId)) {
                         try {
-                            String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                            String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                             JSONObject jsonObject = JSONObject.parseObject(processVariable);
                             borrowerEndorserNoList = jsonObject.getJSONArray("borrowerEndorserNoList").toJavaList(String.class);
                         }
@@ -230,7 +221,7 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                     }
@@ -244,7 +235,7 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
                     }
@@ -293,7 +284,7 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
             String processInstanceId = cmd.getProcessInstanceId();
             if (ObjectUtils.isNotEmpty(processInstanceId)) {
                 try {
-                    String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                    String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                     JSONObject jsonObject = JSONObject.parseObject(processVariable);
                     claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                 }
@@ -307,7 +298,7 @@ public class ShangDa_VerifyReimbursementServiceImpl extends VerifyReimbursementS
             String processInstanceId = cmd.getProcessInstanceId();
             if (ObjectUtils.isNotEmpty(processInstanceId)) {
                 try {
-                    String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                    String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                     JSONObject jsonObject = JSONObject.parseObject(processVariable);
                     leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
                 }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/SignatureServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/SignatureServiceImpl.java
index ef5abf288263aecbabffd9f54f9ce8aaa47678c7..aa3af7524dfa9b038bafe3a98a3555722bc25ea8 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/SignatureServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/SignatureServiceImpl.java
@@ -32,7 +32,6 @@ import com.seasky.flowportal.enums.SignatureTypeEnum;
 import com.seasky.flowportal.mapper.SignatureDigitalAuthAuditMapper;
 import com.seasky.flowportal.mapper.SignatureDigitalAuthUserMapper;
 import com.seasky.flowportal.mapper.SignatureMapper;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.IdempotentService;
 import com.seasky.flowportal.service.SignatureService;
 import com.seasky.flowportal.utils.*;
@@ -55,9 +54,6 @@ public class SignatureServiceImpl implements SignatureService {
     @Lazy
     private IdempotentService idempotentService;
 
-    @Autowired
-    private FlowService flowService;
-
 
     @Autowired
     @Lazy
@@ -152,7 +148,7 @@ public class SignatureServiceImpl implements SignatureService {
             String processInstanceId = ObjectUtils.isEmpty(po) ? null : po.getProcessInstanceId();
             if (ObjectUtils.isNotEmpty(processInstanceId)) {
                 FlowQuery flowQuery = FlowQuery.builder().processInstanceId(processInstanceId).build();
-                flowHistoryList = flowService.getFlowHistory(flowQuery);
+                flowHistoryList = FlowUtil.INSTANCE(instanceId).getFlowHistory(flowQuery);
             }
         }
         for (SignatureOut signature : signatureOutList) {
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/WaiMao_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/WaiMao_VerifyReimbursementServiceImpl.java
index 641eb6fca2a74ab5ee1baab19e570138f9d006e4..d4fa5ab310b470d5d76245b486e544b7a1026933 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/WaiMao_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/WaiMao_VerifyReimbursementServiceImpl.java
@@ -18,16 +18,10 @@ import com.seasky.flowportal.dto.user.UserInfoQuery;
 import com.seasky.flowportal.dto.userContainingVerification.UserContainingVerificationOut;
 import com.seasky.flowportal.dto.userContainingVerification.UserContainingVerificationsOut;
 import com.seasky.flowportal.enums.*;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -42,10 +36,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class WaiMao_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
     private static List<String> laborCostList = Arrays.asList( "鏍″浜哄憳鍔冲姟璐�", "瀛︾敓鍔冲姟璐�", "瀛︾敓鍏朵粬");
     @Override
     public Map<String, Object> getCreateFlowBusinessData(ApprovalCmd cmd) {
@@ -123,6 +113,7 @@ public class WaiMao_VerifyReimbursementServiceImpl extends VerifyReimbursementSe
     }
 
     private boolean needAddSigner(ExpenseReimbursementCmd cmd) {
+        Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         boolean notAddSigner = cmd.getFundsProjectCodeList().stream().anyMatch(code ->
                 ObjectUtils.isNotEmpty(code) && code.length() >= 3 && 'C' == Character.toUpperCase(code.charAt(2))
         );
@@ -146,7 +137,7 @@ public class WaiMao_VerifyReimbursementServiceImpl extends VerifyReimbursementSe
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         claimsEndorserNoList = jsonObject.getJSONArray("claimsEndorserNoList").toJavaList(String.class);
                     }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/XingHai_VerifyReimbursementServiceImpl.java b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/XingHai_VerifyReimbursementServiceImpl.java
index 7f52e1142a55f3a457928297aae01cbe2590ba57..3fad12db3198da4690e638e57fdbe4673bcae625 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/XingHai_VerifyReimbursementServiceImpl.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/service/impl/XingHai_VerifyReimbursementServiceImpl.java
@@ -18,17 +18,11 @@ import com.seasky.flowportal.dto.projectInfo.ProjectInfoOut;
 import com.seasky.flowportal.dto.user.UserInfoOut;
 import com.seasky.flowportal.dto.user.UserInfoQuery;
 import com.seasky.flowportal.enums.*;
-import com.seasky.flowportal.service.FlowService;
 import com.seasky.flowportal.service.VerifyReimbursementService;
-import com.seasky.flowportal.utils.ApprovalUtil;
-import com.seasky.flowportal.utils.BaseConfigUtil;
-import com.seasky.flowportal.utils.BaseInOutUtil;
-import com.seasky.flowportal.utils.ExternalDataUtil;
+import com.seasky.flowportal.utils.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -46,11 +40,6 @@ import java.util.stream.Collectors;
 @Slf4j
 public class XingHai_VerifyReimbursementServiceImpl extends VerifyReimbursementService {
 
-    @Autowired
-    @Lazy
-    private FlowService flowService;
-
-
     @Override
     public Map<String, Object> getCreateFlowBusinessData(ApprovalCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
@@ -243,7 +232,7 @@ public class XingHai_VerifyReimbursementServiceImpl extends VerifyReimbursementS
                 String processInstanceId = cmd.getProcessInstanceId();
                 if (ObjectUtils.isNotEmpty(processInstanceId)) {
                     try {
-                        String processVariable = flowService.getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
+                        String processVariable = FlowUtil.INSTANCE(instanceId).getProcessVariableByProcessInstanceIdAndName(processInstanceId, "model");
                         JSONObject jsonObject = JSONObject.parseObject(processVariable);
                         leaderEndorserNoList = jsonObject.getJSONArray("leaderEndorserNoList").toJavaList(String.class);
                     }
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/utils/ApprovalUtil.java b/ServiceSite/src/main/java/com/seasky/flowportal/utils/ApprovalUtil.java
index 39fbd7a874635569bd4cf4e9ec0d56c179b392e5..0385f35efb7067f25e012721b18d308e004bf0bc 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/utils/ApprovalUtil.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/utils/ApprovalUtil.java
@@ -59,10 +59,6 @@ import java.util.stream.Collectors;
 @EnableScheduling
 public class ApprovalUtil {
 
-    private static FlowService flowService;
-    @Autowired
-    public void setFlowService(FlowService flowService) { ApprovalUtil.flowService = flowService; }
-
     private static SignatureService signatureService;
     @Autowired
     public void setSignatureService(SignatureService signatureService) { ApprovalUtil.signatureService = signatureService; }
@@ -368,7 +364,7 @@ public class ApprovalUtil {
         if (ObjectUtils.isEmpty(cmd.getProcessInstanceId())) {
             userList = Collections.singletonList(loginUser);
         } else {
-            flowOutList = flowService.getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
+            flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
             isBackOrFinish = OrderStatusEnum.FINISH.getName().equals(cmd.getOrderStatus()) || OrderStatusEnum.BACK.getName().equals(cmd.getOrderStatus()) || ObjectUtils.isEmpty(flowOutList) || ObjectUtils.isEmpty(flowOutList.get(0).getApprover());
             if (isBackOrFinish) {
                 userList = Collections.singletonList(loginUser);
@@ -828,13 +824,13 @@ public class ApprovalUtil {
             userList = Collections.singletonList(loginUser);
         } else {
             FlowQuery flowQuery = FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build();
-            flowOutList = flowService.getTodoListByProcessInstanceId(flowQuery);
+            flowOutList = FlowUtil.INSTANCE(instanceId).getTodoListByProcessInstanceId(flowQuery);
             isBackOrFinish = OrderStatusEnum.FINISH.getName().equals(cmd.getOrderStatus()) || OrderStatusEnum.BACK.getName().equals(cmd.getOrderStatus()) || ObjectUtils.isEmpty(flowOutList) || ObjectUtils.isEmpty(flowOutList.get(0).getApprover());
             if (!isBackOrFinish) {
                 List<String> approverList = flowOutList.stream().map(FlowOut::getApprover).collect(Collectors.toList());
                 userList = ExternalDataUtil.INSTANCE.getUserInfoListByUserNos(instanceId, approverList, true);
             }
-            ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfo(cmd.getProcessInstanceId());
+            ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfo(cmd.getProcessInstanceId());
             if (ObjectUtils.isNotEmpty(processDefinitionInfo))
                 flowName = processDefinitionInfo.getDescription();
         }
@@ -890,7 +886,7 @@ public class ApprovalUtil {
         try {
 
             FlowQuery flowQuery = FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).businessKey(cmd.getOrderCode()).build();
-            List<HistoryInfoOut> approveHistory = flowService.getFlowHistory(flowQuery);
+            List<HistoryInfoOut> approveHistory = FlowUtil.INSTANCE(instanceId).getFlowHistory(flowQuery);
             approveHistory = approveHistory.stream().filter(s -> ObjectUtils.isEmpty(s.getDeleteReason())
                     && !(OrderStatusEnum.START.getName().equals(s.getStartNodeName()) && OrderStatusEnum.APPLY.getName().equals(s.getEndNodeName()))
                     && ObjectUtils.isNotEmpty(s.getEndTime())
@@ -967,7 +963,7 @@ public class ApprovalUtil {
 
     public static void setCurFlowInfo(ApprovalCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
-        NodeOut curNodeInfo = flowService.getCurNodeInfo(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
+        NodeOut curNodeInfo = FlowUtil.INSTANCE(instanceId).getCurNodeInfo(FlowQuery.builder().processInstanceId(cmd.getProcessInstanceId()).build());
         if (ObjectUtils.isNotEmpty(curNodeInfo)) {
             cmd.setOrderStatus(curNodeInfo.getNodeName());
             if (ObjectUtils.isNotEmpty(curNodeInfo.getAssignee())) {
@@ -1021,13 +1017,13 @@ public class ApprovalUtil {
     public static ProcessDefinitionOut getProcessDefinitionInfoByKey(Long instanceId, String orderType) {
         instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
         String defKey = selectFlowConfig(instanceId, orderType);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfoByKey(defKey);
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfoByKey(defKey);
         return processDefinitionInfo;
     }
     public static ProcessDefinitionOut getProcessDefinitionInfoByKey(ApprovalCmd cmd) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(cmd);
         String defKey = selectFlowConfig(cmd);
-        ProcessDefinitionOut processDefinitionInfo = flowService.getProcessDefinitionInfoByKey(defKey);
+        ProcessDefinitionOut processDefinitionInfo = FlowUtil.INSTANCE(instanceId).getProcessDefinitionInfoByKey(defKey);
         return processDefinitionInfo;
     }
 
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/utils/FlowUtil.java b/ServiceSite/src/main/java/com/seasky/flowportal/utils/FlowUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe1e9223a6d50d2b1c98c3711d54971fd63d6e4f
--- /dev/null
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/utils/FlowUtil.java
@@ -0,0 +1,35 @@
+package com.seasky.flowportal.utils;
+
+import com.seasky.flowportal.enums.FlowEngineEnum;
+import com.seasky.flowportal.enums.FlowServiceNameEnum;
+import com.seasky.flowportal.service.FlowService;
+import com.seasky.flowportal.service.context.FlowServiceContext;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @author chenmin
+ * @since 2022/1/10
+ */
+@Component
+public class FlowUtil {
+
+    private static FlowServiceContext ServiceContext;
+    @Resource
+    private void setServiceContext(FlowServiceContext serviceContext) { FlowUtil.ServiceContext = serviceContext; }
+
+
+    public static FlowService INSTANCE(Long instanceId) { try {
+        return ServiceContext.getTaskService(instanceId);
+    } catch (Exception e) {
+        throw new RuntimeException(e);
+    } }
+
+    public static FlowService INSTANCE(FlowServiceNameEnum serviceNameEnum) { return ServiceContext.getTaskService(serviceNameEnum); }
+
+    public static FlowEngineEnum getFlowEngine(Long instanceId) { return INSTANCE(instanceId).getFlowEngine(); }
+    public static boolean isSeaSkyFlowEngine(Long instanceId) { return FlowEngineEnum.SEA_SKY.equals(getFlowEngine(instanceId)); }
+    public static boolean isKingDeeFlowEngine(Long instanceId) { return FlowEngineEnum.KING_DEE.equals(getFlowEngine(instanceId)); }
+
+}
diff --git a/ServiceSite/src/main/java/com/seasky/flowportal/utils/MyRedisUtil.java b/ServiceSite/src/main/java/com/seasky/flowportal/utils/MyRedisUtil.java
index 6d642ac53171cc9cf2cdcf0a66dad91e4977f619..c9b59fb7e360f278d567362b6a4fc0949922e09a 100644
--- a/ServiceSite/src/main/java/com/seasky/flowportal/utils/MyRedisUtil.java
+++ b/ServiceSite/src/main/java/com/seasky/flowportal/utils/MyRedisUtil.java
@@ -247,47 +247,6 @@ public class MyRedisUtil {
         catch (Exception e) { return null; }
     }
 
-
-    public static String getHaiYangOAuth2TokenKey(Long instanceId) {
-        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        return String.format("%s-%s:%s", applicationName, instanceId, "HaiYangOAuth2Token");
-    }
-    public static void setHaiYangOAuth2Token(Long instanceId, String haiYangOAuth2Token, int seconds) {
-        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        String key = getHaiYangOAuth2TokenKey(instanceId);
-        log.info(String.format("RedisSet: key: %s, value: %s", key, haiYangOAuth2Token));
-        RedisUtil.getRedisCommand().set(key, haiYangOAuth2Token, seconds);
-    }
-    public static String getHaiYangOAuth2Token(Long instanceId) {
-        try {
-            instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-            String key = getHaiYangOAuth2TokenKey(instanceId);
-            return (String) RedisUtil.getRedisCommand().get(key);
-        }
-        catch (Exception e) { return null; }
-    }
-
-
-    public static String getGuangZhongYiTokenKey(Long instanceId) {
-        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        return String.format("%s-%s:%s", applicationName, instanceId, "GuangZhongYiToken");
-    }
-    public static void setGuangZhongYiToken(Long instanceId, String guangZhongYiToken, int seconds) {
-        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-        String key = getGuangZhongYiTokenKey(instanceId);
-        log.info(String.format("RedisSet: key: %s, value: %s", key, guangZhongYiToken));
-        RedisUtil.getRedisCommand().set(key, guangZhongYiToken, seconds);
-    }
-    public static String getGuangZhongYiToken(Long instanceId) {
-        try {
-            instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
-            String key = getGuangZhongYiTokenKey(instanceId);
-            return (String) RedisUtil.getRedisCommand().get(key);
-        }
-        catch (Exception e) { return null; }
-    }
-
-
     public static String getListProcessKey(FlowQuery qry) {
         Long instanceId = BaseInOutUtil.verifyInstanceId(qry);
         Integer pageIndex = ObjectUtils.defaultIfNull(qry.getPageIndex(), 1);
@@ -313,4 +272,23 @@ public class MyRedisUtil {
         catch (Exception e) { return null; }
     }
 
+    public static String getTokenKey(Long instanceId, String name) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        return String.format("%s-%s:%s%s", applicationName, instanceId, name, "Token");
+    }
+    public static void setToken(Long instanceId, String name, String Token, int seconds) {
+        instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+        String key = getTokenKey(instanceId, name);
+        log.info(String.format("RedisSet: key: %s, value: %s", key, Token));
+        RedisUtil.getRedisCommand().set(key, Token, seconds);
+    }
+    public static String getToken(Long instanceId, String name) {
+        try {
+            instanceId = ObjectUtils.isNotEmpty(instanceId) ? instanceId : BaseInOutUtil.verifyInstanceId();
+            String key = getTokenKey(instanceId, name);
+            return (String) RedisUtil.getRedisCommand().get(key);
+        }
+        catch (Exception e) { return null; }
+    }
+
 }