Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

hxx недель назад: 3
Родитель
Сommit
10fb6f26ce
100 измененных файлов с 12268 добавлено и 711 удалено
  1. 5 0
      mjava-boyang/src/main/java/com/malk/boyang/controller/BoyangController.java
  2. 2 0
      mjava-boyang/src/main/java/com/malk/boyang/service/BoyangService.java
  3. 280 47
      mjava-boyang/src/main/java/com/malk/boyang/service/impl/BoyangServiceImpl.java
  4. 2 2
      mjava-boyang/src/main/resources/application-dev.yml
  5. 6 6
      mjava-boyang/src/main/resources/application-prod.yml
  6. 1 1
      mjava-boyang/src/main/resources/application.yml
  7. 105 4
      mjava-boyang/src/test/java/com/malk/boyang/DdTest.java
  8. 51 9
      mjava-boyang/src/test/java/com/malk/boyang/EqbTest.java
  9. 1 1
      mjava-demo/src/main/java/com/malk/xzkj/DemoApplication.java
  10. 88 0
      mjava-fenggefushi/pom.xml
  11. 14 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/MjavaFenggefushiApplication.java
  12. 116 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/controller/HeiHuOrderController.java
  13. 12 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/ImageField.java
  14. 78 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/Order.java
  15. 50 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/TableField.java
  16. 31 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/schedule/ScheduleTask.java
  17. 53 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/service/HeiHuOrderService.java
  18. 2300 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/service/Impl/HeiHuOrderServiceImpl.java
  19. 465 0
      mjava-fenggefushi/src/main/java/com/malk/fenggefushi/test/test.java
  20. 88 0
      mjava-fenggefushi/src/main/resources/application-dev.yml
  21. 77 0
      mjava-fenggefushi/src/main/resources/application-prod.yml
  22. 3 0
      mjava-fenggefushi/src/main/resources/application.yml
  23. 13 0
      mjava-fenggefushi/src/test/java/com/malk/fenggefushi/MjavaFenggefushiApplicationTests.java
  24. 2 2
      mjava-huagao/pom.xml
  25. 151 0
      mjava-huagao/src/main/java/com/malk/huagao/controller/HgEqbController.java
  26. 15 0
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdHuagaoController.java
  27. 46 4
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdCustomerController.java
  28. 3 3
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdCustomerReferrerController.java
  29. 8 2
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdDeliveryController.java
  30. 7 2
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdMaterialController.java
  31. 7 2
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdOrderController.java
  32. 3 3
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdOutboundController.java
  33. 13 2
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdReceivableController.java
  34. 8 2
      mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdTransferController.java
  35. 6 0
      mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdCustomer.java
  36. 8 3
      mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdMaterial.java
  37. 4 0
      mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdOrderDetail.java
  38. 4 0
      mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdTransfer.java
  39. 4 0
      mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdTransferDetail.java
  40. 6 0
      mjava-huagao/src/main/java/com/malk/huagao/schedule/KdScheduleTask.java
  41. 1 1
      mjava-huagao/src/main/java/com/malk/huagao/schedule/ScheduleTask.java
  42. 43 4
      mjava-huagao/src/main/java/com/malk/huagao/schedule/YdScheduleTask.java
  43. 12 0
      mjava-huagao/src/main/java/com/malk/huagao/service/EqbService.java
  44. 1 1
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdCustomerReferrerService.java
  45. 1 1
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdCustomerService.java
  46. 3 1
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdDeliveryService.java
  47. 2 0
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdMaterialService.java
  48. 4 1
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdOrderService.java
  49. 1 1
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdOutboundService.java
  50. 4 0
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdReceivableService.java
  51. 1 0
      mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdTransferService.java
  52. 2 0
      mjava-huagao/src/main/java/com/malk/huagao/service/KdHuaGaoService.java
  53. 6 0
      mjava-huagao/src/main/java/com/malk/huagao/service/YdHuaGaoService.java
  54. 976 0
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/EqbServiceImpl.java
  55. 315 22
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdHuaGaoServiceImpl.java
  56. 1 0
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerLiaisonServiceImpl.java
  57. 138 52
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerReferrerServiceImpl.java
  58. 332 88
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerServiceImpl.java
  59. 428 123
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdDeliveryServiceImpl.java
  60. 347 2
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdMaterialServiceImpl.java
  61. 744 176
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdOrderServiceImpl.java
  62. 357 102
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdOutboundServiceImpl.java
  63. 615 2
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdReceivableServiceImpl.java
  64. 390 3
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdTransferServiceImpl.java
  65. 1 0
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdZpServiceImpl.java
  66. 39 1
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/McProjectServiceImpl.java
  67. 370 18
      mjava-huagao/src/main/java/com/malk/huagao/service/impl/YdHuaGaoServiceImpl.java
  68. 270 0
      mjava-huagao/src/main/java/com/malk/huagao/utils/HTTPHelper.java
  69. 17 5
      mjava-huagao/src/main/resources/application-dev.yml
  70. 16 5
      mjava-huagao/src/main/resources/application-prod.yml
  71. 77 0
      mjava-huagao/src/main/resources/application-prod2.yml
  72. 1420 0
      mjava-huagao/src/test/java/com/malk/huagao/EqbTest.java
  73. 20 1
      mjava-huagao/src/test/java/com/malk/huagao/KdTest.java
  74. 3 3
      mjava-huagao/src/test/java/com/malk/huagao/YyYdTest.java
  75. 13 0
      mjava-jinlun/pom.xml
  76. 21 0
      mjava-jinlun/src/main/java/com/malk/jinlun/controller/JinlunController.java
  77. 16 0
      mjava-jinlun/src/main/java/com/malk/jinlun/mapper/JinlunMapper.java
  78. 4 0
      mjava-jinlun/src/main/java/com/malk/jinlun/service/JinlunService.java
  79. 18 0
      mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunServiceImpl.java
  80. 2 1
      mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunTaskServiceImpl.java
  81. 7 0
      mjava-jinlun/src/main/resources/application-dev.yml
  82. 7 0
      mjava-jinlun/src/main/resources/application-prod.yml
  83. 81 0
      mjava-jinlun/src/main/resources/mapper/JinlunMapper.xml
  84. 13 0
      mjava-jinlun/src/test/java/com/malk/jinlun/DdTest.java
  85. 88 0
      mjava-junengtai/pom.xml
  86. 14 0
      mjava-junengtai/src/main/java/com/malk/junengtai/MjavaJunengtaiApplication.java
  87. 78 0
      mjava-junengtai/src/main/java/com/malk/junengtai/controller/PurchaseController.java
  88. 59 0
      mjava-junengtai/src/main/java/com/malk/junengtai/schedule/Schedule.java
  89. 304 0
      mjava-junengtai/src/main/java/com/malk/junengtai/service/Impl/PurchaseServiceImpl.java
  90. 27 0
      mjava-junengtai/src/main/java/com/malk/junengtai/service/PurchaseService.java
  91. 85 0
      mjava-junengtai/src/main/java/com/malk/junengtai/test/test.java
  92. 88 0
      mjava-junengtai/src/main/resources/application-dev.yml
  93. 76 0
      mjava-junengtai/src/main/resources/application-prod.yml
  94. 3 0
      mjava-junengtai/src/main/resources/application.yml
  95. 13 0
      mjava-junengtai/src/test/java/com/malk/junengtai/MjavaJunengtaiApplicationTests.java
  96. 5 2
      mjava-kabeiyi/src/main/java/com/malk/kabeiyi/controller/KabeiyiController.java
  97. 85 0
      mjava-lianan/pom.xml
  98. 17 0
      mjava-lianan/src/main/java/com/malk/lianan/LianAnApplication.java
  99. 51 0
      mjava-lianan/src/main/java/com/malk/lianan/controller/LianAnBudgetController.java
  100. 0 0
      mjava-lianan/src/main/java/com/malk/lianan/controller/LianAnGyPayController.java

+ 5 - 0
mjava-boyang/src/main/java/com/malk/boyang/controller/BoyangController.java

@@ -63,6 +63,11 @@ public class BoyangController {
             log.info("info:{},重复回调,不做处理",info);
         }else {
             eventList.put(info, System.currentTimeMillis());
+            //签署开始回写签署详情地址
+            if ("SIGN_FLOW_START".equals(callBackDesc)) {
+//                String signPreUrl = UtilMap.getString(callBackProcessVO, "signPreUrl");
+                boyangService.start(processInstanceId,signFlowId);
+            }
             //签署完成回写审批单
             if ("SIGN_FLOW_FINISH".equals(callBackDesc)) {
                 boyangService.signed(processInstanceId,signFlowId);

+ 2 - 0
mjava-boyang/src/main/java/com/malk/boyang/service/BoyangService.java

@@ -12,4 +12,6 @@ public interface BoyangService {
     void signed(String processInstanceId,String signFlowId);
 
     McR getOrganization(String name);
+
+    void start(String processInstanceId,String signFlowId);
 }

+ 280 - 47
mjava-boyang/src/main/java/com/malk/boyang/service/impl/BoyangServiceImpl.java

@@ -7,27 +7,22 @@ import com.malk.boyang.utils.HTTPHelper;
 import com.malk.server.common.McR;
 import com.malk.server.dingtalk.DDConf;
 import com.malk.server.dingtalk.DDR_New;
-import com.malk.service.dingtalk.DDClient;
-import com.malk.service.dingtalk.DDClient_Storage;
-import com.malk.service.dingtalk.DDClient_Workflow;
+import com.malk.service.dingtalk.*;
 import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
-import okhttp3.*;
-import okio.BufferedSink;
-import okio.Okio;
-import okio.Sink;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.codec.digest.HmacAlgorithms;
 import org.apache.commons.codec.digest.HmacUtils;
+import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.text.MessageFormat;
 import java.util.*;
 
 @Slf4j
@@ -36,9 +31,18 @@ public class BoyangServiceImpl implements BoyangService {
     @Autowired
     private DDClient ddClient;
 
+    @Autowired
+    private DDConf ddConf;
+
     @Autowired
     private DDClient_Workflow ddClient_workflow;
 
+    @Autowired
+    private DDClient_Personnel ddClient_personnel;
+
+    @Autowired
+    private DDClient_Contacts ddClient_contacts;
+
     @Value("${dingtalk.downloadPath}")
     private String downloadPath;
 
@@ -54,12 +58,43 @@ public class BoyangServiceImpl implements BoyangService {
     @Value("${dingtalk.parentDentryUuid}")
     private String parentDentryUuid;
 
-    //测试环境
+    /*//测试环境
     final static String projectId = "1000004";// 应用ID
     final static String secret = "96Uh7CR83NkN3TA6";// 应用密钥
     final static String businessTypeCode = "889726e889ab84fea3514748d6df565c";// 钉钉对接测试业务模板
+    final static String organizationCode = "b60a9c18b8cc4ecc80e30f36b4267a68";// 宁波博洋家纺集团有限公司
     final static String host = "http://122.227.225.202:9011/";// 接口调用域名
     final static String intranet_host = "http://11.0.11.62/";// 接口调用域名(内网)
+    final static String signerUser = "wangze";// 签署人
+    final static String cw_signerUser = "wozy";// 财务签署人
+    final static String uploadFileUrlHost = "http://11.0.11.62:8199/";// 返回的上传文件url host*/
+
+    //==================================================== (本地)e签宝对接测试-用印申请 ====================================================
+//    final static String signActivityId = "802c_7eaf";//签署区设置节点
+//    final static String[] activityIds = new String[]{"f0e3_8ef9","2af6_ccd3","68d8_0e65"};//签署节点:e签宝签署节点id、e签宝财务签署节点id、e签宝会签签署节点id
+
+
+    //==================================================== e签宝对接测试-用印申请 ====================================================
+//    final static String signActivityId = "802c_7eaf";//签署区设置节点
+//    final static String[] activityIds = new String[]{"f0e3_8ef9","2af6_ccd3","b8e5_160a"};//签署节点:e签宝签署节点id、e签宝财务签署节点id、e签宝会签签署节点id
+
+    //==================================================== 用印申请 ====================================================
+    final static String signActivityId = "c331_1d4f";//签署区设置节点
+    final static String[] activityIds = new String[]{"19b2_ec4a","bfeb_c637","433b_839a"};//签署节点:e签宝签署节点id、e签宝财务签署节点id、e签宝会签签署节点id
+
+    //正式环境
+    final static String projectId = "1000003";// 应用ID
+    final static String secret = "5V6xsY3q8JWZ9Qik";// 应用密钥
+    final static String businessTypeCode = "f5e84fdb04ef4ead57f37e2a60729066";// 钉钉OA对接业务模板
+    final static String organizationCode = "0c8dd6496e7f4d228ec033aeef95a526";// 宁波博洋家纺集团有限公司
+    final static String host = "https://dzqz.beyond-it-service.com/";// 接口调用域名
+    final static String intranet_host = "http://11.0.11.82/";// 接口调用域名(内网)
+    final static String signerUser = "22060093";// 签署人
+    final static String cw_signerUser = "13586834789";// 财务签署人
+    final static String uploadFileUrlHost = "http://11.0.11.82:8199/";// 返回的上传文件url host
+
+
+
 
     @Override
     public McR eSignSubmit(Map map) {
@@ -75,7 +110,8 @@ public class BoyangServiceImpl implements BoyangService {
         String remark = "";
         String url = "https://aflow.dingtalk.com/dingtalk/web/query/pchomepage.htm?from=oflow&op=true&corpid=ding76a1e955807327f7f5bf40eda33b7ba0#/plainapproval?procInstId="+processInstanceId;
         List<String> sealTypeCodeList = new ArrayList<>();
-
+        List<Map> companyList = new ArrayList<>();
+        boolean hasFiance = false;
 
         for (Map formComponentValue : formComponentValues) {
             String id = UtilMap.getString(formComponentValue, "id");
@@ -100,8 +136,8 @@ public class BoyangServiceImpl implements BoyangService {
                     String fileQty = UtilMap.getString(formComponentValue, "value");
                     break;
                 case "DDMultiSelectField_1L3KU3TLX6PS0"://印章所属公司
-                    String companyStr = UtilMap.getString(formComponentValue, "value");
-                    List<Map> companyList = (List<Map>) JSONObject.parse(companyStr);
+                    String companyStr = UtilMap.getString(formComponentValue, "extValue");
+                    companyList = (List<Map>) JSONObject.parse(companyStr);
                     break;
                 case "DDMultiSelectField_1FW3TFDTJ6V40"://印章类型
                     String yzlxStr = UtilMap.getString(formComponentValue, "value");
@@ -111,7 +147,7 @@ public class BoyangServiceImpl implements BoyangService {
                            switch (yzlx){
                                case "公章":sealTypeCodeList.add("PUBLIC");break;
                                case "合同章":sealTypeCodeList.add("CONTRACT");break;
-                               case "财务章":sealTypeCodeList.add("FINANCE");break;
+                               case "财务章":sealTypeCodeList.add("FINANCE");hasFiance = true;break;
                                case "其他":sealTypeCodeList.add("COMMON");break;
                                case "人事专用章":sealTypeCodeList.add("PERSONNEL");break;
                                case "法人章":sealTypeCodeList.add("LEGAL-PERSON-SEAL");break;
@@ -150,6 +186,57 @@ public class BoyangServiceImpl implements BoyangService {
             }
         }
 
+        //查询钉钉用户信息
+        String name = "";
+        String mobile = "";
+        String originatorUserId = UtilMap.getString(result, "originatorUserId");
+
+        List<Map> employeeInfos = ddClient_personnel.getEmployeeInfos(ddClient.getAccessToken(), Arrays.asList(originatorUserId), ddConf.getAgentId(), Arrays.asList("sys00-name", "sys00-mobile"));
+        Map employeeInfo = employeeInfos.get(0);
+
+        List<Map> fieldDataList = UtilMap.getList(employeeInfo, "field_data_list");
+
+        for (Map fieldData : fieldDataList) {
+            String fieldCode = UtilMap.getString(fieldData, "field_code");
+            List<Map> fieldValueList = UtilMap.getList(fieldData, "field_value_list");
+
+            switch (fieldCode){
+                case "sys00-name":
+                    name = UtilMap.getString(fieldValueList.get(0),"value");
+                    break;
+                case "sys00-mobile":
+                    mobile = UtilMap.getString(fieldValueList.get(0),"value").replace("+86-","");
+                    break;
+                default:break;
+            }
+        }
+
+        String eqbUserCode = "";
+
+        //查询钉钉用户在e签宝是否存在
+        Map body = new HashMap();
+        body.put("name", name);
+        body.put("mobile", mobile);
+        List<Map> eqbUsers = (List<Map>) eqbPost(host + "manage/v1/innerUsers/detail", body);
+        if (!eqbUsers.isEmpty()){
+            Map eqbUser = eqbUsers.get(0);
+
+            eqbUserCode = UtilMap.getString(eqbUser, "userCode");
+        }else {
+            //新增e签宝用户
+            Map eqbUser = new HashMap();
+            eqbUser.put("name", name);
+            eqbUser.put("mobile", mobile);
+            eqbUser.put("customAccountNo", mobile);
+            eqbUser.put("mainOrganizationCode", organizationCode);//默认组织账号
+
+            Map map1 = (Map) eqbPost(host + "manage/v1/innerUsers/create",Arrays.asList(eqbUser));
+
+            List<Map> successData = UtilMap.getList(map1, "successData");
+
+            eqbUserCode = UtilMap.getString(successData.get(0), "userCode");
+        }
+
         // 创建主Map
         Map<String, Object> requestMap = new HashMap<>();
 
@@ -158,7 +245,7 @@ public class BoyangServiceImpl implements BoyangService {
         requestMap.put("businessNo", processInstanceId);
         requestMap.put("businessTypeCode", businessTypeCode);
         requestMap.put("remark", remark);
-        requestMap.put("redirectUrl", url);
+//        requestMap.put("redirectUrl", url);
 
         // 2. manualConfig 嵌套对象
         Map<String, Object> manualConfig = new HashMap<>();
@@ -174,12 +261,12 @@ public class BoyangServiceImpl implements BoyangService {
 
         // 3. initiatorInfo 嵌套对象
         Map<String, Object> initiatorInfo = new HashMap<>();
-        initiatorInfo.put("userCode", "wozy");
-        initiatorInfo.put("customAccountNo", "");
+        initiatorInfo.put("userCode", eqbUserCode);
+        /*initiatorInfo.put("customAccountNo", "");
         initiatorInfo.put("departmentCode", "");
         initiatorInfo.put("customDepartmentNo", "");
-        initiatorInfo.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
-        initiatorInfo.put("customOrgNo", "");
+        initiatorInfo.put("organizationCode", "");
+        initiatorInfo.put("customOrgNo", "");*/
 
         requestMap.put("initiatorInfo", initiatorInfo);
 
@@ -201,20 +288,40 @@ public class BoyangServiceImpl implements BoyangService {
         // 5. signerInfos 列表
         List<Map<String, Object>> signerInfos = new ArrayList<>();
 
-        Map<String, Object> signer = new HashMap<>();
-        signer.put("userType", "1");
-        signer.put("userCode", "wozy");
-        signer.put("organizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");
-        signer.put("signNode", 1);
-        signer.put("signMode", "0");
-        signer.put("signOrder", 1);
-//        signer.put("sealTypeCode", String.join(",",sealTypeCodeList));
+        for (int i = 0; i < companyList.size(); i++) {
+            Map<String, Object> signer = new HashMap<>();
+            signer.put("userType", "1");
+//            signer.put("userCode", "FINANCE".equals(sealType) ? cw_signerUser : signerUser);
+            signer.put("userCode", signerUser);
+            signer.put("organizationCode", UtilMap.getString(companyList.get(i),"key"));
+//            signer.put("organizationCode", organizationCode);
+            signer.put("signNode", 1);
+            if (hasFiance){
+                signer.put("signMode", "1");//0:顺序签  1:无序签
+                signer.put("signOrder", 1);
+            }else {
+                signer.put("signMode", "0");//0:顺序签  1:无序签
+                signer.put("signOrder", i + 1);
+            }
+
+//            signer.put("sealTypeCode", String.join(",",sealTypeCodeList));
+
+            signerInfos.add(signer);
+
+            if (hasFiance){
+                Map signer2 = new HashMap<>(signer);
+                signer2.put("userCode", cw_signerUser);
+                signer2.put("signOrder", 1);
+
+                signerInfos.add(signer2);
+            }
+        }
+
 
-        signerInfos.add(signer);
         requestMap.put("signerInfos", signerInfos);
 
         // 打印结果(可选)
-        System.out.println(requestMap);
+        System.out.println("入参:"+JSONObject.toJSONString(requestMap));
 
         //使用文件发起签署(一步发起签署)
         Map data = (Map) eqbPost(host + "/esign-signs/v1/signFlow/createAndStart", requestMap);
@@ -228,14 +335,22 @@ public class BoyangServiceImpl implements BoyangService {
 
         String newSigningAreaPageUrl = signingAreaPageUrl.replace(intranet_host,host);
 
-        comment(processInstanceId,"344749020127590108","签署区设置地址:"+newSigningAreaPageUrl,null);
+        comment(processInstanceId,originatorUserId,"签署区设置地址:"+newSigningAreaPageUrl,null);
 
         return McR.success();
     }
 
+    @Async
     @Override
     public void signed(String processInstanceId,String signFlowId) {
         try {
+            Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
+            String originatorUserId = UtilMap.getString(result, "originatorUserId");
+
+            /*Map userInfo = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), originatorUserId);
+
+            String originatorUserIdUnionid = UtilMap.getString(userInfo, "unionid");*/
+
             // 获取签署流程进度详情
             Map data = (Map) eqbGet(host + "/esign-signs/v1/signFlow/signDetail?signFlowId=" + signFlowId);
             List<Map> signFiles = UtilMap.getList(data, "signFiles");
@@ -249,28 +364,83 @@ public class BoyangServiceImpl implements BoyangService {
 
                 String signedFileName = fileName.substring(0, suffixIndex) + "(已签署)" + fileName.substring(suffixIndex);
 
-                //todo 1、评论签署后附件下载链接
-//                    comment(processInstanceId,userId,"接口测试 "+ fileName + "已签署,签署文件下载地址:" + signDownloadOuterUrl,null);
+                //todo 方案1、评论签署后附件下载链接
+//                    comment(processInstanceId,userId,"接口测试 "+ "已签署,签署文件下载地址:" + signDownloadOuterUrl,null);
 
 
 
-                //todo 2、评论签署后附件
-                //todo 签署后文件下载到本地
+                //方案2、评论签署后附件
+                //签署后文件下载到本地
                 downloadFile(signDownloadOuterUrl,downloadPath + signedFileName);
-                //todo 签署后文件上传到钉盘
+                //签署后文件上传到钉盘
                 Map dentry = uploadDdFile(spaceId, parentDentryUuid, downloadPath + signedFileName, operatorUnionId);
-                //todo 审批单添加评论
-                comment(processInstanceId,operator,"接口测试 "+ fileName + "已签署",Arrays.asList(dentry));
+
+                //添加权限 OA发起人可下载
+                setPermissions(dentry, originatorUserId,"DOWNLOADER");
+
+                //审批单添加评论
+                comment(processInstanceId,originatorUserId,fileName + "已签署",Arrays.asList(dentry));
+            }
+
+            //自动通过节点
+            List<Map> tasks = UtilMap.getList(result, "tasks");
+            for (Map task : tasks) {
+                String activityId = UtilMap.getString(task, "activityId");
+                for (String id : activityIds) {
+                    if (id.equals(activityId)){
+                        long taskId = UtilMap.getLong(task, "taskId");
+                        String userId = UtilMap.getString(task, "userId");
+
+                        Map body = new HashMap();
+                        body.put("processInstanceId",processInstanceId);
+                        body.put("remark","签署完成自动通过");
+                        body.put("result","agree");
+                        body.put("actionerUserId",userId);
+                        body.put("taskId",taskId);
+
+                        UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/execute", ddClient.initTokenHeader(), null, body);
+                    }
+                }
+
             }
+
         } catch (Exception e) {
-            e.printStackTrace();
-            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
-            System.out.println(msg);
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void setPermissions(Map dentry, String userId,String roleId) {
+        String dentryUuid = dentry.get("uuid").toString();
+
+        //添加权限
+        Map<String,Object> param3 = new HashMap<>();
+        param3.put("unionId",operatorUnionId);
+
+        List<Map> dentryPermissionList = new ArrayList<>();
+        //OWNER: 拥有者   MANAGER: 管理者   EDITOR: 编辑者   DOWNLOADER: 查看下载者   READER: 仅可查看者
+        dentryPermissionList.add(new HashMap<String,Object>(){{
+            put("type","USER");
+            put("id",userId);//发起人userid
+        }});
+
+        Map body3 = new HashMap();
+        body3.put("roleId",roleId);
+        body3.put("members",dentryPermissionList);
+
+        DDR_New ddrNew3 = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/dentries/" + dentryUuid + "/permissions", ddClient.initTokenHeader(), param3, body3, DDR_New.class);
+        if (ddrNew3.isSuccess()){
+            log.info("权限设置成功!");
+        }else {
+            log.error("权限设置失败!" + ddrNew3.getCode() + " " + ddrNew3.getMessage());
         }
     }
 
     @Override
     public McR getOrganization(String name) {
+        if (Strings.isBlank(name)){
+            return McR.success(new ArrayList<>());
+        }
+
         Map body = new HashMap();
         body.put("name",name);
         List<Map> data = (List<Map>) eqbPost(host + "manage/v1/innerOrganizations/detail",body);
@@ -278,19 +448,73 @@ public class BoyangServiceImpl implements BoyangService {
         List<Map> options = new ArrayList<>();
 
         for (Map datum : data) {
-            String organizationName = UtilMap.getString(datum, "name");
-            String organizationCode = UtilMap.getString(datum, "organizationCode");
+            String organizationType = UtilMap.getString(datum, "organizationType");
 
-            Map option = new HashMap();
-            option.put("label",organizationName);
-            option.put("value",organizationCode);
+            if ("COMPANY".equals(organizationType)){
+                String organizationName = UtilMap.getString(datum, "name");
+                String organizationCode = UtilMap.getString(datum, "organizationCode");
+
+                Map option = new HashMap();
+                option.put("label",organizationName);
+                option.put("value",organizationCode);
 
-            options.add(option);
+                options.add(option);
+            }
         }
 
+        //options按label排序
+        options.sort(Comparator.comparing(m -> UtilMap.getString(m, "label")));
+
         return McR.success(options);
     }
 
+    @Override
+    public void start(String processInstanceId,String signFlowId) {
+        try {
+            Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), processInstanceId);
+            String originatorUserId = UtilMap.getString(result, "originatorUserId");
+
+            //获取签署地址列表
+            Map eqbData = (Map) eqbGet(host + "/esign-signs/v1/signFlow/signUrls?signFlowId=" + signFlowId);
+
+            List<Map> signUrlInfos = UtilMap.getList(eqbData, "signUrlInfos");
+
+            for (Map signUrlInfo : signUrlInfos) {
+                String userName = UtilMap.getString(signUrlInfo, "userName");
+                String organizationName = UtilMap.getString(signUrlInfo, "organizationName");
+                String signUrlShort = UtilMap.getString(signUrlInfo, "signUrlShort");
+
+                //审批单添加评论
+                comment(processInstanceId,originatorUserId,"签署人:" + userName + ",签署组织:" + organizationName + ",签署地址:" + signUrlShort,null);
+            }
+
+            //自动通过节点
+            List<Map> tasks = UtilMap.getList(result, "tasks");
+            for (Map task : tasks) {
+                String activityId = UtilMap.getString(task, "activityId");
+                //e签宝设置签署区节点id
+                if (signActivityId.equals(activityId)){
+                    long taskId = UtilMap.getLong(task, "taskId");
+                    String userId = UtilMap.getString(task, "userId");
+
+                    Map body = new HashMap();
+                    body.put("processInstanceId",processInstanceId);
+                    body.put("remark","签署区设置完成自动通过");
+                    body.put("result","agree");
+                    body.put("actionerUserId",userId);
+                    body.put("taskId",taskId);
+
+                    UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/execute", ddClient.initTokenHeader(), null, body);
+
+                    return;
+                }
+            }
+
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     //下载钉钉OA审批单附件
     private void downloadDdFile(String processInstanceId,String fileId,String downloadPath){
         try {
@@ -470,7 +694,8 @@ public class BoyangServiceImpl implements BoyangService {
 
             String url = UtilMap.getString(data, "url");
 
-            url = url.replace("http://11.0.11.62:8199/",host);
+            url = url.replace(uploadFileUrlHost,host);
+
 
             //2、上传文件到指定链接
             Map<String,Object> body = new HashMap<>();
@@ -520,7 +745,9 @@ public class BoyangServiceImpl implements BoyangService {
             header.put("Content-Type", contentType);
 
             // 发送GET请求
+            log.info("eqb请求入参,url:{},header:{}",url,header);
             String resultStr = HTTPHelper.sendGet(url, header, "UTF-8");
+            log.info("eqb请求响应:{}",resultStr);
             Map result = (Map) JSONObject.parse(resultStr);
 
             isSuccess(result);
@@ -534,7 +761,7 @@ public class BoyangServiceImpl implements BoyangService {
     }
 
     //e签宝-post请求(application/json)
-    private Object eqbPost(String url,Map body){
+    private Object eqbPost(String url,Object body){
         try {
             // 请求Body体数据
             String reqBodyData = JSONObject.toJSONString(body);
@@ -551,8 +778,12 @@ public class BoyangServiceImpl implements BoyangService {
             header.put("Accept", "*/*");
             header.put("Content-Type", "application/json; charset=UTF-8");
 
+            log.info("eqb请求入参,url:{},reqBodyData:{},header:{}",url,reqBodyData,header);
+
             String resultStr = HTTPHelper.sendPOST(url, reqBodyData, header, "UTF-8");
 
+            log.info("eqb请求响应:{}",resultStr);
+
             Map result = (Map) JSONObject.parse(resultStr);
 
             isSuccess(result);
@@ -576,7 +807,9 @@ public class BoyangServiceImpl implements BoyangService {
             header.put("X-timevale-signature", reqSignature);
             header.put("Accept", "*/*");
 
+            log.info("eqb请求入参,url:{},filePath:{},body:{},header:{}",url,filePath,body,header);
             String resultStr = HTTPHelper.uploadFile(url,  "file", filePath, body,  header, "UTF-8");
+            log.info("eqb请求响应:{}",resultStr);
 
             Map result = (Map) JSONObject.parse(resultStr);
 

+ 2 - 2
mjava-boyang/src/main/resources/application-dev.yml

@@ -13,7 +13,7 @@ logging:
 
 # dingtalk
 dingtalk:
-  agentId:
+  agentId: 4111300995
   appKey: dingt4kem6twzlqehm58
   appSecret: ZgE_XOfccVlSOcbw3cN0Ad_dJFqBB_PfPPmqJzGTgKXPu5tsh17KibxG7WEB6_hc
   corpId:
@@ -21,7 +21,7 @@ dingtalk:
   token:
   operator: "065965353428672133" #潘麒卿
   operatorUnionId: AfZv5MOJ80W2STOhUbbOcAiEiE #潘麒卿
-  downloadPath: d:\\
+  downloadPath: C:\\Users\\EDY\\Desktop\\项目\\博洋家纺\\files\\
   spaceId: 27829762189 #钉盘-e签宝
   parentDentryUuid: y20BglGWO23pGpLOsaALnnz98A7depqY #钉盘-e签宝-签署后文件
 

+ 6 - 6
mjava-boyang/src/main/resources/application-prod.yml

@@ -1,5 +1,5 @@
 server:
-  port: 9033
+  port: 30001
   servlet:
     context-path: /boyang
 
@@ -7,21 +7,21 @@ enable:
   scheduling: false
 logging:
   config: classpath:logback-spring.xml
-  path: /home/server/boyang/log/
+  path: d:\\boyang_eqb\\log\\
   level:
-    com.malk.*: debug
+    com.malk.*: info
 
 # dingtalk
 dingtalk:
-  agentId:
+  agentId: 4111300995
   appKey: dingt4kem6twzlqehm58
   appSecret: ZgE_XOfccVlSOcbw3cN0Ad_dJFqBB_PfPPmqJzGTgKXPu5tsh17KibxG7WEB6_hc
   corpId:
   aesKey:
   token:
-  operator: 065965353428672133 #潘麒卿
+  operator: "065965353428672133" #潘麒卿
   operatorUnionId: AfZv5MOJ80W2STOhUbbOcAiEiE #潘麒卿
-  downloadPath: d:\\
+  downloadPath: d:\\boyang_eqb\\files\\
   spaceId: 27829762189 #钉盘-e签宝
   parentDentryUuid: y20BglGWO23pGpLOsaALnnz98A7depqY #钉盘-e签宝-签署后文件
 

+ 1 - 1
mjava-boyang/src/main/resources/application.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: dev
+    active: prod
   servlet:
     multipart:
       max-file-size: 100MB

+ 105 - 4
mjava-boyang/src/test/java/com/malk/boyang/DdTest.java

@@ -1,8 +1,11 @@
 package com.malk.boyang;
 
+import cn.hutool.core.date.DateUtil;
 import com.malk.boyang.service.BoyangService;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Contacts;
+import com.malk.service.dingtalk.DDClient_Workflow;
 import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
@@ -16,12 +19,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -36,6 +37,12 @@ public class DdTest {
     @Autowired
     private BoyangService boyangService;
 
+    @Autowired
+    private DDClient_Contacts ddClient_contacts;
+
+    @Autowired
+    private DDClient_Workflow ddClient_workflow;
+
     @Test
     public void test(){
         try {
@@ -88,5 +95,99 @@ public class DdTest {
     public void test2(){
         boyangService.eSignSubmit(UtilMap.map("processInstanceId","9L_PKi71S8W3kL_nftFpXw01161764152519"));
     }
+
+    @Test
+    //上传钉盘附件
+    public void testUpload() {
+        //获取当前时间戳
+        long beginTimestamp = System.currentTimeMillis();
+        System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
+
+        //文件
+        File file = new File("C:\\Users\\EDY\\Pictures\\2.png");
+
+        //获取文件上传信息
+        Map param = new HashMap();
+        param.put("unionId","5PK3cMYhiStn7HDoNabweEgiEiE");//wzy
+        Map body = new HashMap();
+        body.put("protocol","HEADER_SIGNATURE");
+        body.put("multipart",false);
+
+        Map header = UtilMap.map("x-acs-dingtalk-access-token","5747a3e5c3823be0bd982dccdf78289e");
+
+        DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + "27105381865" + "/files/uploadInfos/query", header, param, body, DDR_New.class);
+        String uploadKey = ddr.getUploadKey();
+        Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
+        Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
+        List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
+        String resourceUrl = resourceUrls.get(0);
+
+        Map dentry = new HashMap();
+        //使用OSS的header加签方式上传文件
+        try {
+            URL url = new URL(resourceUrl);
+            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+            if (headers != null) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.setDoOutput(true);
+            connection.setRequestMethod("PUT");
+            connection.setUseCaches(false);
+            connection.setReadTimeout(10000);
+            connection.setConnectTimeout(10000);
+            connection.connect();
+            OutputStream out = connection.getOutputStream();
+            InputStream is = new FileInputStream(file);
+            byte[] b =new byte[1024];
+            int temp;
+            while ((temp=is.read(b))!=-1){
+                out.write(b,0,temp);
+            }
+            out.flush();
+            out.close();
+            int responseCode = connection.getResponseCode();
+            connection.disconnect();
+            if (responseCode == 200) {
+                System.out.println("上传成功");
+            } else {
+                System.out.println("上传失败");
+            }
+            //提交文件
+            Map body2 = new HashMap();
+            Map option = new HashMap();
+            option.put("conflictStrategy","OVERWRITE");
+            body2.put("uploadKey",uploadKey);
+            body2.put("name",file.getName());
+            body2.put("option",option);
+
+//            param.put("unionId","58FDG7fqGyXrGziPavPO4kQiEiE");//lqy
+
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/"+ "DEN7dx2rn0JbYn37a7acrVMGjLRb3o1v" +"/commit", header, param, body2, DDR_New.class);
+            dentry = ddrNew.getDentry();
+
+        }catch (IOException e){
+            log.info("上传文件异常:{}",e);
+        }
+
+        long endTimestamp = System.currentTimeMillis();
+        System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
+        System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
+        System.out.println(dentry);
+    }
+
+    @Test
+    public void test3() {
+        Map result = ddClient_workflow.getProcessInstanceId(ddClient.getAccessToken(), "yY-nxf1UTUWxEUXnjDv7Yg01161768554568");
+        String originatorUserId = UtilMap.getString(result, "originatorUserId");
+
+        Map userInfo = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), originatorUserId);
+
+        String originatorUserIdUnionid = UtilMap.getString(userInfo, "unionid");
+
+        System.out.println(originatorUserIdUnionid);
+
+    }
 }
 

+ 51 - 9
mjava-boyang/src/test/java/com/malk/boyang/EqbTest.java

@@ -11,10 +11,7 @@ import java.nio.file.Path;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 
 import com.malk.boyang.service.BoyangService;
 import com.malk.boyang.utils.HTTPHelper;
@@ -42,26 +39,26 @@ public class EqbTest {
 
     //测试环境
     // 应用ID
-    final static String projectId = "1000004";
+    /*final static String projectId = "1000004";
     // 应用密钥
     final static String secret = "96Uh7CR83NkN3TA6";
     // 接口调用域名
-    final static String host = "http://122.227.225.202:9011/";
+    final static String host = "http://122.227.225.202:9011/";*/
 
     //===============================================================================================
 
     //正式环境
-    /*// 应用ID
+    // 应用ID
     final static String projectId = "1000003";
     // 应用密钥
     final static String secret = "5V6xsY3q8JWZ9Qik";
     // 接口调用域名
-    final static String host = "https://dzqz.beyond-it-service.com/";*/
+    final static String host = "https://dzqz.beyond-it-service.com/";
 
 
     /*public static void main(String[] args) {
         // 请求签名鉴权-POST请求
-        testPost(projectId, secret, host);
+//        testPost(projectId, secret, host);
 
         // 请求签名鉴权-GET请求
 //        testGet(projectId, secret, host);
@@ -543,5 +540,50 @@ public class EqbTest {
         }
     }
 
+    @Test
+    public void test11(){
+        Map eqbUser = new HashMap();
+        eqbUser.put("name", "张三");
+        eqbUser.put("mobile", "15900010001");
+        eqbUser.put("customAccountNo", "15900010001");
+        eqbUser.put("mainOrganizationCode", "b60a9c18b8cc4ecc80e30f36b4267a68");//默认组织账号
+
+        Map map = (Map) eqbPost2(host + "/manage/v1/innerUsers/create", Arrays.asList(eqbUser));
+
+        System.out.println(map);
+    }
+
+
+    //e签宝-post请求(application/json)
+    private Object eqbPost2(String url,Object body){
+        try {
+            // 请求Body体数据
+            String reqBodyData = JSONObject.toJSONString(body);
+
+            // 计算请求签名值
+            String reqSignature = sign(reqBodyData, secret);
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<>();
+
+            // 构建待签名字符串
+            header.put("X-timevale-project-id", projectId);
+            header.put("X-timevale-signature", reqSignature);
+            header.put("Accept", "*/*");
+            header.put("Content-Type", "application/json; charset=UTF-8");
+
+            String resultStr = HTTPHelper.sendPOST(url, reqBodyData, header, "UTF-8");
+
+            Map result = (Map) JSONObject.parse(resultStr);
+
+
+            Object data = result.get("data");
+
+            return data;
+        }catch (Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
 
 }

+ 1 - 1
mjava-demo/src/main/java/com/malk/xzkj/DemoApplication.java

@@ -1,4 +1,4 @@
-package com.malk.xzkj;
+package com.malk.lianan;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;

+ 88 - 0
mjava-fenggefushi/pom.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.malk</groupId>
+    <artifactId>fenggefushi</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>mjava-fenggefushi</name>
+    <description>mjava-fenggefushi</description>
+
+    <!-- ✅ 使用统一的 parent -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.18</version>
+        <relativePath/>
+    </parent>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.83</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.14.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- MyBatis Starter -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.2.2</version>
+        </dependency>
+        <!-- MySQL驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.28</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>fenggefushi</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <executable>true</executable>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 14 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/MjavaFenggefushiApplication.java

@@ -0,0 +1,14 @@
+package com.malk.fenggefushi;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+public class MjavaFenggefushiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(MjavaFenggefushiApplication.class, args);
+        System.out.println("Fenggefushi_SpringBoot项目启动----------");
+    }
+
+}

+ 116 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/controller/HeiHuOrderController.java

@@ -0,0 +1,116 @@
+package com.malk.fenggefushi.controller;
+
+import com.malk.fenggefushi.service.HeiHuOrderService;
+import com.malk.server.common.McR;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.framework.qual.PostconditionAnnotation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@Slf4j
+@RequestMapping("/HeiHuOrder")
+public class HeiHuOrderController {
+    @Autowired
+    private HeiHuOrderService huOrderService;
+
+    /*=======================会用到的接口========================*/
+
+    /*TODO:获取黑湖工单登录token*/
+    @SneakyThrows
+    @PostMapping("/getToken")
+    McR HeiHuAccessToken(){
+        log.info("------------获取到黑湖工单的token------------");
+        return McR.success(huOrderService.HeiHuAccessToken());
+    }
+
+    /*TODO:【采购订单】发起宜搭审批流程*/
+    @SneakyThrows
+    @PostMapping("/startYidaProcurementAproval")
+    McR startYidaProcurementAproval(@RequestParam String OrderNo, @RequestParam String FormUuType){
+        log.info("-----------开始抓取黑湖采购工单,准备发起宜搭审批流程---------");
+        return McR.success(huOrderService.startYidaProcurementAproval(OrderNo,FormUuType));
+    }
+
+    /*TODO:采购订单创建触发*/
+    @SneakyThrows
+    @PostMapping("/Procurement")
+    McR Procurement(@RequestBody Map body){
+        log.info("【接收到黑湖采购工单创建请求】");
+        return McR.success(huOrderService.Procurement(body));
+    }
+
+    /*TODO:销售订单修改*/
+    @SneakyThrows
+    @PostMapping("/salesUpdate")
+    McR salesUpdate(@RequestBody Map body){
+        log.info("[接收到销售订单审批单修改],{}",body);
+        return McR.success(huOrderService.salesUpdate(body));
+    }
+
+    /*todo:销售订单创建触发*/
+    @SneakyThrows
+    @PostMapping("/salesAproval")
+    McR salesAproval(@RequestBody Map body){
+        log.info("【接收到黑湖销售工单创建请求】,{}",body);
+        return McR.success(huOrderService.salesAproval(body));
+    }
+
+    /*todo:销售订单不单独走审批,存入销售订单流程档案*/
+    @SneakyThrows
+    @PostMapping("/startYidaSalesAproval")
+    McR startYidaSalesAproval(@RequestParam String OrderNo,@RequestParam String fromUuid) {
+        return McR.success(huOrderService.StartYidaAproval(OrderNo,fromUuid));
+    }
+
+    /*todo:查询产品颜色接口*/
+    @SneakyThrows
+    @PostMapping("/getProductColor")
+    McR getProductColor(@RequestParam List list){
+        return McR.success(huOrderService.getProductColor(list));
+    }
+
+
+
+    /*todo:销售订单审批结束后同步黑湖工单状态*/
+    @SneakyThrows
+    @PostMapping("/SyncOrderStatus")
+    McR SyncOrderStatus(@RequestParam String formInstanceId,@RequestParam String Approvalresult){
+        log.info("-----------【开始回传销售订单状态】----------");
+        return McR.success(huOrderService.SyncOrderStatus(formInstanceId,Approvalresult));
+    }
+
+    /*todo:采购订单审批结束同步黑湖工单状态*/
+    @SneakyThrows
+    @PostMapping("/SyncPurchaseOrderStatus")
+    McR SyncPurchaseOrderStatus(@RequestParam String formInstanceId,@RequestParam String Approvalresult){
+        log.info("------------【开始回传采购订单状态】--------");
+        return McR.success(huOrderService.SyncPurchaseOrderStatus(formInstanceId,Approvalresult));
+    }
+
+    /*todo:定时抓取采购订单*/
+    @SneakyThrows
+    @PostMapping("/test12")
+    @Scheduled(cron = "0 */5 * * * ?")
+    McR purchaseSchedule(){
+        List<Map<String, Object>> dataList = huOrderService.queryAllPurchase();
+
+        return McR.success(huOrderService.purchaseSchedule(dataList));
+    }
+
+//    /*todo:定时抓取修改采购订单*/
+//    @SneakyThrows
+//    @PostMapping("/testUpdate")
+//    @Scheduled(cron = "0 3,8 * * * ?")
+//    McR purchaseUpdateSchedule(){
+//        log.info("开始执行定时抓取修改后的采购订单数据");
+//        System.out.println("开始执行定时抓取修改后的采购订单数据");
+//        return McR.success(huOrderService.purchaseUpdateSchedule());
+//    }
+
+}

+ 12 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/ImageField.java

@@ -0,0 +1,12 @@
+package com.malk.fenggefushi.entity;
+
+import lombok.Data;
+
+@Data
+public class ImageField {
+    private String name;
+    private String previewUrl;
+    private String downloadUrl;
+    private Long size;
+    private String url;
+}

+ 78 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/Order.java

@@ -0,0 +1,78 @@
+package com.malk.fenggefushi.entity;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class Order {
+
+    @JsonProperty("orderCode")
+    private String orderCode;//1、订单编码
+
+    @JsonProperty("customer")
+    private String customer;//2、客户
+
+    @JsonProperty("orderDate")
+    private Long orderDate;//3、下单日期
+
+    @JsonProperty("plannedDeliveryDate")
+    private Long plannedDeliveryDate;//4、计划交货日期
+
+    @JsonProperty("contractNumber")
+    private String contractNumber;//5、合同号
+
+    @JsonProperty("salesperson")
+    private List<String> salesperson;//6、业务员
+
+    @JsonProperty("orderDiscount")
+    private Integer orderDiscount;//7、整单折扣
+
+    @JsonProperty("orderType")
+    private String orderType;//8、订单类型
+
+    @JsonProperty("tableField")
+    private List<TableField> tableField;//销售明细
+
+    @JsonProperty("estimatedAccessoryUnitPrice")
+    private String estimatedAccessoryUnitPrice;//1、辅料预估单价
+
+    @JsonProperty("relatedPrePurchaseOrderId")
+    private String relatedPrePurchaseOrderId;//2、对应预采购单号
+
+    @JsonProperty("qualityApproval")
+    private String qualityApproval;//3、品质确认
+
+    @JsonProperty("itemCycle")
+    private String itemCycle;//4、物料周期
+
+    @JsonProperty("productPhoto")
+    private List<ImageField> productPhoto;//5、产品照片
+
+    @JsonProperty("notes")
+    private String notes;//6、备注
+
+    @JsonProperty("customerName")
+    private String customerName;//7、客户名称
+
+    @JsonProperty("craftType")
+    private String craftType;//8、工艺类型
+
+    @JsonProperty("productCategory")
+    private String productCategory;//9、产品类型
+
+    @JsonProperty("department")
+    private String department;//10、部门
+
+    @JsonProperty("season")
+    private String season;//11、季节
+
+    @JsonProperty("brand")
+    private String brand;//12、品牌
+
+    @JsonProperty("plannedOrderQty")
+    private Integer plannedOrderQty;//13、预计下单量
+
+
+}

+ 50 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/entity/TableField.java

@@ -0,0 +1,50 @@
+package com.malk.fenggefushi.entity;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class TableField {
+
+    @JsonProperty("productCode")
+    private String productCode;//产品编号
+
+    @JsonProperty("productName")
+    private String productName;//产品名称
+
+    @JsonProperty("productSpec")
+    private String productSpec;//产品规格
+
+    @JsonProperty("productOriginType")
+    private String productOriginType;//产品属性
+
+    @JsonProperty("productStockQty")
+    private Integer productStockQty;//库存数量
+
+    @JsonProperty("qty")
+    private Integer qty;//数量
+
+    @JsonProperty("productUnitName")
+    private String productUnitName;//单位
+
+    @JsonProperty("unitPrice")
+    private Integer unitPrice;//单价
+
+    @JsonProperty("amount")
+    private Integer amount;//报价金额
+
+    @JsonProperty("discount")
+    private Integer discount;//折扣
+
+    @JsonProperty("taxInclusiveAmount")
+    private Integer taxInclusiveAmount;//含税金额
+
+    @JsonProperty("taxRate")
+    private Integer taxRate;//税率
+
+    @JsonProperty("arrivalPlanTime")
+    private Long arrivalPlanTime;//产品交货日期
+
+}

+ 31 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/schedule/ScheduleTask.java

@@ -0,0 +1,31 @@
+package com.malk.fenggefushi.schedule;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.fenggefushi.service.HeiHuOrderService;
+import com.malk.utils.UtilHttp;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import java.util.HashMap;
+
+/**
+ * @EnableScheduling 开启定时任务 [配置参考McScheduleTask]
+ */
+@Slf4j
+@Configuration
+@EnableScheduling
+@ConditionalOnProperty(name = {"enable.scheduling"})
+public class ScheduleTask {
+    @Autowired
+    private HeiHuOrderService huOrderService;
+
+
+
+
+
+}

+ 53 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/service/HeiHuOrderService.java

@@ -0,0 +1,53 @@
+package com.malk.fenggefushi.service;
+
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.malk.server.common.McR;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public interface HeiHuOrderService {
+    /*获取登录黑湖工单token*/
+    McR HeiHuAccessToken() throws JacksonException;
+
+    /*发起宜搭审批流程:销售订单*/
+    McR StartYidaAproval(@RequestParam String OrderNo,@RequestParam String formUuid) throws JacksonException;
+
+    /*根据客户名字搜索userid*/
+    String getDDToken(@RequestParam String Name);
+
+    /*发起宜搭审批流程:采购订单*/
+    McR startYidaProcurementAproval(@RequestParam String OrderNo,@RequestParam String FromUuType) throws JsonProcessingException;
+
+    /*回传销售订单状态*/
+    McR SyncOrderStatus(@RequestParam  String formInstanceId,@RequestParam String Approvalresult) throws JsonProcessingException;
+
+    /*回传采购订单状态*/
+    McR SyncPurchaseOrderStatus(@RequestParam String formInstanceId,@RequestParam String Approvalresult) throws JsonProcessingException;
+
+    /*【新】销售订单*/
+    McR salesAproval(Map body) throws JacksonException;
+
+    /*【新】采购订单*/
+    McR Procurement(Map body) throws JacksonException;
+
+    /*销售订单修改*/
+    McR salesUpdate(Map body) throws JacksonException;
+
+    /*查询产品颜色*/
+    String getProductColor(@RequestParam List list) throws JacksonException;
+
+    /*采购订单定时同步*/
+    McR purchaseSchedule(List<Map<String, Object>> dataList) throws JacksonException;
+
+    List<Map<String, Object>> queryAllPurchase();
+
+    McR purchaseUpdateSchedule() throws JacksonException;
+
+
+}

Разница между файлами не показана из-за своего большого размера
+ 2300 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/service/Impl/HeiHuOrderServiceImpl.java


+ 465 - 0
mjava-fenggefushi/src/main/java/com/malk/fenggefushi/test/test.java

@@ -0,0 +1,465 @@
+package com.malk.fenggefushi.test;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.malk.fenggefushi.service.HeiHuOrderService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McR;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.formula.functions.Na;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+@RestController
+@Slf4j
+@RequestMapping("/test")
+public class test {
+
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private YDConf ydConf;
+    @Autowired
+    private YDService ydService;
+    @Autowired
+    private DDConf ddConf;
+    @Autowired
+    private HeiHuOrderService huOrderService;
+
+    @PostMapping("/test1")
+    McR test1(){
+        System.out.println("接口正常!");
+        return McR.success("接口正常!");
+    }
+
+    //测试程序发起下拉单选是否生效
+    @GetMapping("/test76")
+    McR test76(){
+        HashMap formdata = new HashMap();
+        formdata.put("selectField_mg5y3rcr","贸易公司订单");
+
+        // 图片/附件字段 - 使用完整的结构化格式
+        List<Map<String, Object>> imageAttachments = new ArrayList<>();
+        Map<String, Object> imageInfo = new HashMap<>();
+        imageInfo.put("name", "CWC-1758612192087.png");
+        imageInfo.put("downloadUrl", "https://filebase-prod-oss.blacklake.cn/CWC-1758612192087.png");
+        imageInfo.put("previewUrl", "https://filebase-prod-oss.blacklake.cn/CWC-1758612192087.png");
+        imageInfo.put("url", "https://filebase-prod-oss.blacklake.cn/CWC-1758612192087.png");
+        imageInfo.put("ext", "png");
+        imageAttachments.add(imageInfo);
+        formdata.put("imageField_mfqgmwde",imageAttachments);
+        
+        String string = ydClient.operateData(YDParam.builder()
+                .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                .formUuid("FORM-472F0C1BD8DF41FA965A0B4525779B67S421")
+                .userId("3320511511-1158713155")
+                .formDataJson(JSON.toJSONString(formdata))
+                .build(), YDConf.FORM_OPERATION.start).toString();
+        return McR.success(string);
+    }
+
+    //根据员工名字匹配员工id
+    String getDDToken(@RequestParam String Name){
+        HashMap body = new HashMap();
+        body.put("appKey","dingie28nalt6tcnzizl");
+        body.put("appSecret","Ss7na86M_BWPEXhKffiQDA-8jXvuBhBklfD8C-ot7xGwiDKfFMIf9y00mXYutfCB");
+        String s = UtilHttp.doPost("https://api.dingtalk.com/v1.0/oauth2/accessToken", null, null, body);
+        String accessToken  = JSONObject.parseObject(s).getString("accessToken");
+
+        HashMap header = new HashMap();
+        header.put("x-acs-dingtalk-access-token",accessToken);
+        HashMap bodyy = new HashMap();
+        bodyy.put("queryWord", Name);
+        bodyy.put("offset",0);
+        bodyy.put("size",10);
+        String s1 = UtilHttp.doPost("https://api.dingtalk.com/v1.0/contact/users/search", header, null, bodyy);
+        List<String> list = JSONObject.parseObject(s1).getJSONArray("list").toJavaList(String.class);
+        String userId = "";
+        if(list!= null && !list.isEmpty()){
+            userId = list.get(0);
+        }
+        return userId;
+    }
+
+    //创建宜搭普通表单
+    @PostMapping("/test77")
+    McR test77(){
+        HashMap formdata = new HashMap();
+        formdata.put("textField_mgq90lwf","1");
+        formdata.put("dateField_mgq90lwg","1760457600");
+        String dd = ydClient.operateData(YDParam.builder()
+                .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                .formUuid("FORM-1693380A673E498C827CD0A4C2D8214CIK90")
+                .userId("3320511511-1158713155")
+                .formDataJson(JSON.toJSONString(formdata))
+                .build(), YDConf.FORM_OPERATION.create).toString();
+        return McR.success(dd);
+    }
+
+    @PostMapping("/test78")
+    McR test78(){
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 获取当前日期的零点时间
+        LocalDateTime todayMidnight = LocalDate.now().atStartOfDay();
+        String formattedToday = todayMidnight.format(formatter);
+
+        System.out.println("今天零点时间: " + formattedToday);
+        return McR.success();
+    }
+
+    @SneakyThrows
+    @PostMapping("/test79")
+    McR test79(){
+        HashMap header = new HashMap();
+        header.put("X-AUTH",huOrderService.HeiHuAccessToken().getData().toString());
+        header.put("Content-Type","application/json");
+        HashMap body = new HashMap();
+        body.put("orderCode","PO20250235");
+        /*TODO:对json进行处理*/
+        String jsonString  = UtilHttp.doPost("https://liteweb.blacklake.cn/api/dytin/external/purchaseOrder/queryList2", header, null, body);//todo:查询采购订单
+        List<String> orderNoList = new ArrayList<>();//存在这个orderList里面
+        ObjectMapper objectMapper = new ObjectMapper();
+        JsonNode rootNode = objectMapper.readTree(jsonString);
+        JsonNode dataNode = rootNode.get("data");
+        String orderNumber = "";
+        if (dataNode != null && dataNode.isArray()) {
+            for (JsonNode item : dataNode) {
+                JsonNode orderNoNode = item.get("orderCode");
+                JsonNode saleOrders = item.get("relationSaleOrders");
+                System.out.println("关联销售订单号:"+ saleOrders);
+                System.out.println("采购订单编号:" + orderNoNode);
+                if (saleOrders != null && saleOrders.isArray() && saleOrders.size() > 0) {
+                    orderNumber = saleOrders.get(0).asText();
+                    System.out.println("关联销售订单号(字符串):" + orderNumber);
+                }
+
+                //采购订单编号
+                if (orderNoNode != null) {
+                    String purchaseOrderNo = orderNoNode.asText();
+                    System.out.println("采购订单编号(字符串):" + purchaseOrderNo);
+                }
+            }
+        }
+        System.out.println(orderNoList);
+        return McR.success();
+    }
+
+    @SneakyThrows
+    @PostMapping("/test80")
+    McR test80(){
+        HashMap header = new HashMap();
+        header.put("X-AUTH",huOrderService.HeiHuAccessToken().getData().toString());
+        header.put("Content-Type","application/json");
+        HashMap body = new HashMap();
+        body.put("orderNo","882698-1107444");
+        /*TODO:对json进行处理*/
+        String jsonString  = UtilHttp.doPost("https://liteweb.blacklake.cn/api/dytin/external/saleOrder/queryList2", header, null, body);//todo:查询采购订单
+        ObjectMapper objectMapper = new ObjectMapper();
+        JsonNode rootNode = objectMapper.readTree(jsonString);
+        JsonNode dataNode = rootNode.get("data");
+        if (dataNode != null && dataNode.isArray()) {
+            for (JsonNode item : dataNode) {
+                JsonNode customFieldValues = item.get("customFieldValues");
+                System.out.println("自定义字段列表:"+ customFieldValues);
+                if (customFieldValues != null && customFieldValues.isArray()) {
+                    for (JsonNode field : customFieldValues) {
+                        JsonNode fieldIdNode = field.get("fieldId");
+                        // 查找fieldId为47771的字段
+                        if (fieldIdNode != null && fieldIdNode.asInt() == 47771) {
+                            JsonNode valueNode = field.get("value");
+                            if (valueNode != null) {
+                                String value = valueNode.asText();
+                                System.out.println("fieldId为47771的value值:" + value);
+                                // 找到后可以跳出内层循环
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return McR.success();
+    }
+
+    @SneakyThrows
+    @PostMapping("/test81")
+    McR test81(){
+        HashMap head = new HashMap();
+        head.put("X-AUTH",huOrderService.HeiHuAccessToken().getData().toString());
+        head.put("Content-Type","application/json");
+        HashMap body = new HashMap();
+        body.put("orderNo","3300--");//订单编号
+        String s = UtilHttp.doPost("https://liteweb.blacklake.cn/api/dytin/external/saleOrder/queryList2", head, null, body);
+        JSONObject jsonObject = JSONObject.parseObject(s);
+        JSONArray products = jsonObject.getJSONArray("data").getJSONObject(0).getJSONArray("saleManageOrderDetailRowApiVOList");
+        for (int i = 0; i < products.size(); i++) {
+            JSONObject detail = products.getJSONObject(i);
+            String customFieldValues = detail.getString("customFieldValues");
+            System.out.println("自定义字段:" + customFieldValues);
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode jsonArray = mapper.readTree(customFieldValues);
+            for (JsonNode node : jsonArray) {
+                if (node.get("fieldId").asInt() == 47919) {
+                    String value = node.get("value").asText();
+                    System.out.println("找到的 value: " + value); // 输出: CNY
+                    break;
+                }
+            }
+        }
+
+        return McR.success();
+    }
+
+    @SneakyThrows
+    @PostMapping("/getPurchaseList")
+    McR getPurchaseList(){
+        log.info("开始查询宜搭采购订单汇总表");
+        String formUuid = "FORM-56E11C4FAB6E4FB594169BB779736FF0ZG91";
+        YDParam ydParam = YDParam.builder().formUuid(formUuid).build();
+        ydParam.setPageSize(1);
+        long totalCount = ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getTotalCount();
+        List<Map> datalist = new ArrayList<>();
+        ydParam.setCurrentPage(1);
+        ydParam.setPageSize(100);
+        int totalPages = (int)Math.ceil((double) totalCount / ydParam.getPageSize());
+
+        for (int page = 1;page <= totalPages;page++){
+            ydParam.setCurrentPage(page);
+            datalist.addAll((List<Map>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getData());
+        }
+        int i =0;
+        String jsonStr = "";
+        Map<String, String> orderMap = new HashMap<>();//格式:采购订单/关联销售订单
+        for(Map li : datalist){
+            i++;
+//            log.info("{}/{}",i,datalist.size());
+            jsonStr = li.get("formData").toString();
+            String orderNum = new ObjectMapper().readTree(jsonStr).get("textField_mgq932hi").asText();
+            String relatedOrderNum = new ObjectMapper().readTree(jsonStr).get("textField_mhyh7ues").asText();
+            orderMap.put(orderNum, relatedOrderNum);
+        }
+        return McR.success(orderMap);
+    }
+
+    @PostMapping("/updateTable")
+    McR updateTable(){
+        HashMap map = new HashMap();
+        ArrayList<Map> list = new ArrayList<>();
+        HashMap map1 = new HashMap();
+        map1.put("textField_mi2tln2x","测试1");
+        map1.put("numberField_mi2tln2y",1);
+        list.add(map1);
+        map.put("tableField_mi2tln2w",list);
+        ydService.operateData(YDParam.builder()
+                .appType(ydConf.getAppType())
+                .systemToken(ydConf.getSystemToken())
+                .formInstanceId("FINST-B7D66XA1ODP09SY6N5AB47TE5JAZ2YB5XT2IMNU")
+                .updateFormDataJson(JSONObject.toJSONString(map))
+                .build(),YDConf.FORM_OPERATION.update);
+        return McR.success();
+    }
+
+    @PostMapping("/test82")
+    McR test82(){
+
+        List<Map> dataList = (List<Map>) ydClient.queryData(YDParam.builder()
+                .appType("APP_Q6XXLRDPRA0DDRMF3VL4")
+                .systemToken("BVG665B18O0Z0EXND3DCR44WX4MC22YQOFQFMCT6")
+                .formUuid("FORM-472F0C1BD8DF41FA965A0B4525779B67S421")
+                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mfqgmwcw", "S20250070")))
+                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+        ArrayList<Map<String, Object>> productlist = new ArrayList<>();
+        Map<String, Object> firstData = dataList.get(0);
+        Map<String, Object> formData = (Map<String, Object>) firstData.get("formData");
+        List<Map<String, Object>> tableData = (List<Map<String, Object>>) formData.get("tableField_mfqgmwe0");
+        for (Map<String, Object> row : tableData) {
+            Map<String, Object> productMap = new HashMap<>();
+            // 提取需要的字段
+            productMap.put("qty", row.get("numberField_mfqgmwe6"));           // 数量:12
+            productMap.put("unitPrice", row.get("numberField_mfqgmwe9"));     // 单价:1.2
+            productMap.put("productCode", row.get("textField_mfqgmwe1"));     // 产品编号:CP202503171676
+            productMap.put("productName", row.get("textField_mfqgmwe2"));     // 产品名称:10856磨毛纱卡(轻水洗)(SF)
+            productlist.add(productMap);
+        }
+        System.out.println("结果是:" + productlist);
+        return McR.success();
+    }
+
+    @PostMapping("/test83")
+    McR test83(){
+        ArrayList<Map<String, Object>> originalList = new ArrayList<>();
+        Map<String, Object> productMap = new HashMap<>();
+        productMap.put("qty", 12);           // 数量:12
+        productMap.put("unitPrice", 1.2);     // 单价:1.2
+        productMap.put("productCode", "CP202503171676");     // 产品编号:CP202503171676
+        productMap.put("productName", "10856磨毛纱卡(轻水洗)(SF)");     // 产品名称:10856磨毛纱卡(轻水洗)(SF)
+        originalList.add(productMap);
+        Map<String, Object> productMap1 = new HashMap<>();
+        productMap1.put("qty", 1);           // 数量:12
+        productMap1.put("unitPrice", 6.3);     // 单价:6.3
+        productMap1.put("productCode", "CP202503171676");     // 产品编号:CP202503171676
+        productMap1.put("productName", "纱卡(轻水洗)");     // 产品名称:纱卡(轻水洗)
+        originalList.add(productMap1);
+        System.out.println("更新前数据:" + originalList);
+
+
+        ArrayList<Map<String, Object>> updatedList  = new ArrayList<>();
+        Map<String, Object> productMap_B = new HashMap<>();
+        productMap_B.put("qty", 10);           // 数量:12
+        productMap_B.put("unitPrice", 1.2);     // 单价:1.2
+        productMap_B.put("productCode", "CP202503171676");     // 产品编号:CP202503171676
+        productMap_B.put("productName", "10856磨毛纱卡(轻水洗)(SF)");     // 产品名称:10856磨毛纱卡(轻水洗)(SF)
+        updatedList.add(productMap_B);
+        Map<String, Object> productMap_B1 = new HashMap<>();
+        productMap_B1.put("qty", 2);           // 数量:12
+        productMap_B1.put("unitPrice", 6.3);     // 单价:1.2
+        productMap_B1.put("productCode", "CP202503171676");     // 产品编号:CP202503171676
+        productMap_B1.put("productName", "纱卡(轻水洗)");     // 产品名称:10856磨毛纱卡(轻水洗)(SF)
+        updatedList.add(productMap_B1);
+        System.out.println("更新后数据:" + updatedList);
+
+        List<Map<String, Object>> changedProducts = new ArrayList<>();
+        // 遍历数据,找出发生改变的产品
+        for (int i = 0; i < updatedList.size(); i++) {
+            Map<String, Object> updatedProduct = updatedList.get(i);
+            Map<String, Object> originalProduct = originalList.get(i);
+
+            // 检查数量或单价是否发生变化
+            if (!updatedProduct.get("qty").equals(originalProduct.get("qty")) ||
+                    !updatedProduct.get("unitPrice").equals(originalProduct.get("unitPrice"))) {
+
+                Map<String, Object> changedProduct = new HashMap<>();
+                changedProduct.put("productCode", updatedProduct.get("productCode"));
+                changedProduct.put("productName", updatedProduct.get("productName"));
+                changedProduct.put("qty_old", originalProduct.get("qty"));
+                changedProduct.put("unitPrice_old", originalProduct.get("unitPrice"));
+
+                changedProducts.add(changedProduct);
+            }
+        }
+        System.out.println("变化的值:" + changedProducts);
+        return McR.success();
+    }
+
+    @PostMapping("/test84")
+    McR test84(){
+        String formInstanceId_bqb= "";
+        List<Map> dataList = (List<Map>) ydClient.queryData(YDParam.builder()
+                .appType("APP_Q6XXLRDPRA0DDRMF3VL4")
+                .systemToken("BVG665B18O0Z0EXND3DCR44WX4MC22YQOFQFMCT6")
+                .formUuid("FORM-A98E291B02DA400B84C05BAEF735F8AFUBQP")
+                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mi2twkgd", "F3D66D91MEL0EV3TO3YUB6FYUS5S3IC9453IMJ9S")))
+                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+        if(dataList != null && dataList.size() > 0){
+            for(Map M : dataList){
+                formInstanceId_bqb = M.get("formInstanceId").toString();
+            }
+        }
+        System.out.println(formInstanceId_bqb);
+        return McR.success();
+    }
+
+    /*采购订单修改流程发起*/
+    @PostMapping("/test85")
+    McR test85(){
+        HashMap formdata = new HashMap();
+        formdata.put("textField_mfqia327",System.currentTimeMillis());
+        formdata.put("textField_mfqia328","东莞市元伊纺织有限公司");//供应商变更后的值
+        String gys = "如东知品服饰有限公司";//供应商变更前的值
+        formdata.put("textareaField_mjghnmvv","{\"textField_mfqia328\":\"<article class=\\\"4ever-xarticle\\\"><p style=\\\"text-align:left;text-indent:0;margin-left:0;margin-top:0;margin-bottom:0\\\"><span style=\\\"color:#FE0300\\\">" + gys + "</span></p></article>\"}");
+        ArrayList<Map> list = new ArrayList<>();
+        HashMap map1 = new HashMap();
+        map1.put("textField_mjsamf3j","童装");
+        map1.put("textField_mjsamf3k",null);
+        map1.put("textField_mjsamf3l","A款");
+        map1.put("textField_mjsamf3m",null);
+        map1.put("textField_mjsamf3n","1");
+        map1.put("numberField_mjsamf3o",1);
+        map1.put("numberField_mjsamf3p",1);
+        map1.put("numberField_mjsamf3q",1);
+        map1.put("textField_mjsamf3r",null);
+        map1.put("textField_mjsamf3s",null);
+        map1.put("numberField_mjsamf3t",1);
+        map1.put("numberField_mjsamf3u",1);
+        map1.put("numberField_mjsamf3v",1);
+        list.add(map1);
+        formdata.put("tableField_mjsamf3w",list);
+        ArrayList<Map> list_AAA = new ArrayList<>();
+        HashMap map2 = new HashMap();
+        map2.put("textField_mhsj6gtn","1");
+        map2.put("textField_mhsj6gto","1");
+        map2.put("textField_mhsj6gtp","1");
+        map2.put("textField_mhsj6gtq","1");
+        map2.put("textField_mhsj6gtr","1");
+        map2.put("numberField_mhsj6gts",1);
+        map2.put("numberField_mhsj6gtt",1);
+        map2.put("numberField_mhsj6gtu",1);
+        map2.put("textField_mhtxft3p","1");
+        map2.put("textField_mhsj6gtv","1");
+        map2.put("numberField_mhsj6gtw",1);
+        map2.put("numberField_mhtxft3q",1);
+        map2.put("numberField_mhsj6gtx",1);
+        list_AAA.add(map2);
+        formdata.put("tableField_mhsj6gtm",list_AAA);
+        ydClient.operateData(YDParam.builder()
+                .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                .formUuid("FORM-7EB4796C4B054EEAA1B0FD52FC54C8387ZUN")
+                .userId("3320511511-1158713155")
+                .formDataJson(JSON.toJSONString(formdata))
+                .build(), YDConf.FORM_OPERATION.start).toString();
+        return McR.success();
+    }
+
+    /*条件查询宜搭数据*/
+    @PostMapping("/test86")
+    McR test86(){
+        List<Map> list  = (List<Map>) ydClient.queryData(YDParam.builder()
+                        .formUuid("FORM-472F0C1BD8DF41FA965A0B4525779B67S421")
+                        .searchCondition(JSONObject.toJSONString(Arrays.asList(new YDSearch(
+                                "textField_mfqgmwcw", "S20260003", "订单编号", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ))))
+                        .build()
+                ,YDConf.FORM_QUERY.retrieve_list).getData();
+        log.info("[销售订单流程档案数据],{}",list);
+        String formInstanceId = (String) list.get(0).get("formInstanceId");
+        log.info("[销售订单流程的实例ID],{}",formInstanceId);
+        Map data = (Map) ydClient.queryData(YDParam.builder().formInstId(formInstanceId)
+                .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                .userId(ddConf.getOperator()).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+        List<Map<String, Object>> table = (List<Map<String, Object>>) data.get("tableField_mfqgmwe0");
+        for (Map<String, Object> row : table) {
+            System.out.println("客户: " + data.get("textField_mfqgmwcx"));
+            System.out.println("订单号: " + data.get("textField_mfqgmwcw"));
+            System.out.println("款号: " + row.get("textField_mfqgmwe1"));
+            System.out.println("产品描述: " + row.get("textField_mfqgmwe2"));
+            System.out.println("颜色: " + row.get("textField_mk0jz9i1"));
+            System.out.println("数量: " + row.get("numberField_mfqgmwe6"));
+            System.out.println("销售单价: " + row.get("numberField_mfqgmwe8"));
+            System.out.println("销售金额: " + row.get("numberField_mfqgmweb") );
+            System.out.println("币别: " + row.get("textField_mk0xio3b")  );
+            System.out.println("-----------------------------");
+        }
+        return McR.success();
+    }
+
+
+
+}

+ 88 - 0
mjava-fenggefushi/src/main/resources/application-dev.yml

@@ -0,0 +1,88 @@
+# 环境配置
+server:
+  port: 9033
+  servlet:
+    context-path: /api/fengge
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+#      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: ounuo_user
+    password: OUNUO123!
+    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+  jpa:
+    hibernate:
+      ddl-auto: none
+    show-sql: true
+    database: oracle
+  hikari:
+    pool-name: DateHikariCP
+    minimum-idle: 0
+    maximum-pool-size: 10
+    idle-timeout: 30000
+    max-lifetime: 120000          # 小于数据库超时大于业务执行返回时间[hikari默认30m, mysql默认10m]
+    connection-timeout: 30000     # 数据库连接超时时间,默认30秒,即30000
+
+
+
+  #    # 主库
+#    primary:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#    # 从库
+#    slave:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#  jpa:
+#    hibernate:
+#      ddl-auto: none      # JPA对表没有任何操作
+#    show-sql: true
+#    database: ORACLE
+#    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# filepath
+file:
+  path:
+    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+  source:
+    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+logging:
+  file:
+    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk 钉钉
+dingtalk:
+  agentId: 4023219667
+  appKey: dingie28nalt6tcnzizl
+  appSecret: Ss7na86M_BWPEXhKffiQDA-8jXvuBhBklfD8C-ot7xGwiDKfFMIf9y00mXYutfCB
+  corpId: ding9b4b07dc53a2d53b35c2f4657eb6378f
+  aesKey:
+  token:
+  operator: 3320511511-1158713155   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_Q6XXLRDPRA0DDRMF3VL4
+  systemToken: BVG665B18O0Z0EXND3DCR44WX4MC22YQOFQFMCT6
+
+# MyBatis配置
+mybatis:
+  mapper-locations: classpath:mapper/*.xml
+  type-aliases-package: com.malk.tuosi.entity
+  configuration:
+    map-underscore-to-camel-case: true
+
+#定时器
+enable:
+  scheduling: true

+ 77 - 0
mjava-fenggefushi/src/main/resources/application-prod.yml

@@ -0,0 +1,77 @@
+# 环境配置
+server:
+  port: 8083
+  servlet:
+    context-path: /api/fengge
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+    #      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: ounuo_user
+    password: OUNUO123!
+    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+
+
+  #    # 主库
+  #    primary:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  #    # 从库
+  #    slave:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: ORACLE
+    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# filepath
+file:
+  path:
+    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+  source:
+    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+logging:
+  file:
+    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk 钉钉
+dingtalk:
+  agentId: 4023219667
+  appKey: dingie28nalt6tcnzizl
+  appSecret: Ss7na86M_BWPEXhKffiQDA-8jXvuBhBklfD8C-ot7xGwiDKfFMIf9y00mXYutfCB
+  corpId: ding9b4b07dc53a2d53b35c2f4657eb6378f
+  aesKey:
+  token:
+  operator: 3320511511-1158713155   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_Q6XXLRDPRA0DDRMF3VL4
+  systemToken: BVG665B18O0Z0EXND3DCR44WX4MC22YQOFQFMCT6
+
+
+# MyBatis配置
+mybatis:
+  mapper-locations: classpath:mapper/*.xml
+  type-aliases-package: com.malk.tuosi.entity
+  configuration:
+    map-underscore-to-camel-case: true
+
+#定时器
+enable:
+  scheduling: true

+ 3 - 0
mjava-fenggefushi/src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: prod

+ 13 - 0
mjava-fenggefushi/src/test/java/com/malk/fenggefushi/MjavaFenggefushiApplicationTests.java

@@ -0,0 +1,13 @@
+package com.malk.fenggefushi;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class MjavaFenggefushiApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}

+ 2 - 2
mjava-huagao/pom.xml

@@ -7,7 +7,7 @@
     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>2.2.0.RELEASE</version> <!-- 使用最新的稳定版或其他适用版本 -->
+        <version>2.7.18</version> <!-- 使用最新的稳定版或其他适用版本 -->
         <relativePath/> <!-- lookup parent from repository -->
     </parent>
 
@@ -67,7 +67,7 @@
         <dependency>
             <groupId>com.malk</groupId>
             <artifactId>base</artifactId>
-            <version>1.1-SNAPSHOT</version>
+            <version>1.3</version>
             <scope>compile</scope>
         </dependency>
         <dependency>

+ 151 - 0
mjava-huagao/src/main/java/com/malk/huagao/controller/HgEqbController.java

@@ -0,0 +1,151 @@
+package com.malk.huagao.controller;
+
+import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.Resource;
+import com.alibaba.fastjson.JSON;
+import com.malk.huagao.service.EqbService;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RestController
+@RequestMapping("/eqb")
+public class HgEqbController {
+    @Autowired
+    private EqbService eqbService;
+
+    @Value(value = "${eqb.downloadFilePath}")
+    private String fileStoragePath;
+
+
+    @PostMapping("/sign")
+    public McR sign(@RequestBody Map map){
+        eqbService.sign(map);
+        return McR.success();
+    }
+
+    // 使用ConcurrentHashMap保证线程安全
+    private final ConcurrentMap<String, Long> eventList = new ConcurrentHashMap<>();
+    // 记录最后一次清理时间
+    private volatile long lastCleanTime = System.currentTimeMillis();
+    // 清理间隔时间(毫秒)
+    private static final long CLEAN_INTERVAL = 60_000;
+
+
+    @PostMapping("/callback")
+    public McR callback(@RequestBody Map map){
+        System.out.println(map);
+
+        log.info("e签宝回调: {}", JSON.toJSONString(map));
+
+        //签署回调通知:SIGN_MISSON_COMPLETE   事件订阅-签署流程完成:SIGN_FLOW_FINISH
+        String action = UtilMap.getString(map, "action");
+        String signFlowId = UtilMap.getString(map, "signFlowId");//e签宝签署流程id
+
+        String info = action + "-" + signFlowId;
+
+        // 定期清理过期记录
+        cleanExpiredEvents();
+
+        if (isCallbackProcessed(info)){
+            log.info("info:{},重复回调,不做处理",info);
+        }else {
+            eventList.put(info, System.currentTimeMillis());
+            //签署回调结束
+            if ("SIGN_MISSON_COMPLETE".equals(action)) {
+                int signResult = UtilMap.getInt(map, "signResult");//2 - 签署完成,4 - 拒签
+                if (2 == signResult) {
+                    String processInstanceId = UtilMap.getString(map, "customBizNum");//宜搭审批实例id
+                    //自动同意审批节点
+                    eqbService.autoAgree(signFlowId,processInstanceId);
+                }
+            }
+        }
+
+        return McR.success();
+    }
+
+    @GetMapping("/files/{fileId}")
+    public ResponseEntity<Resource> getFileResource(
+            @PathVariable String fileId,
+            @RequestParam(defaultValue = "download") String option) throws IOException {
+
+        // 根据fileId获取实际文件路径,这里简化处理,实际可能需要从数据库查询
+        Path filePath = Paths.get(fileStoragePath).resolve(fileId).normalize();
+
+        // 检查文件是否存在
+        if (!Files.exists(filePath)) {
+            return ResponseEntity.notFound().build();
+        }
+
+        // 创建Resource对象
+        Resource resource =  new UrlResource(filePath.toUri());
+
+        // 根据选项设置响应头
+        HttpHeaders headers = new HttpHeaders();
+        if ("preview".equalsIgnoreCase(option)) {
+            // 预览模式 - 尝试确定内容类型
+            String contentType = Files.probeContentType(filePath);
+            // 强制修正 PDF 的 Content-Type
+            if (filePath.toString().toLowerCase().endsWith(".pdf")) {
+                contentType = "application/pdf";
+            } else if (contentType == null) {
+                contentType = "application/octet-stream";
+            }
+            headers.setContentType(MediaType.parseMediaType(contentType));
+            headers.add("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
+            headers.add("X-Content-Type-Options", "nosniff"); // 防止浏览器忽略 Content-Type
+        } else {
+            // 下载模式 - 默认处理
+            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+            headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
+        }
+
+        return ResponseEntity.ok()
+                .headers(headers)
+                .contentLength(resource.contentLength())
+                .body(resource);
+    }
+
+    /**
+     * 检查并清理过期事件
+     */
+    private void cleanExpiredEvents() {
+        long currentTime = System.currentTimeMillis();
+        // 只在达到清理间隔时执行清理
+        if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+            synchronized (this) {
+                // 双重检查,避免重复清理
+                if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
+                    long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(1);
+                    eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
+                    lastCleanTime = currentTime;
+                }
+            }
+        }
+    }
+
+    /**
+     * 检查该回调事件在一分钟内是否处理过
+     */
+    private boolean isCallbackProcessed(String detail) {
+        return eventList.containsKey(detail);
+    }
+
+}

+ 15 - 0
mjava-huagao/src/main/java/com/malk/huagao/controller/KdHuagaoController.java

@@ -1,12 +1,20 @@
 package com.malk.huagao.controller;
 
+import cn.hutool.core.date.DateUtil;
 import com.malk.huagao.service.KdHuaGaoService;
 import com.malk.server.common.McR;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
 @RestController
 @RequestMapping("/kd")
 public class KdHuagaoController {
@@ -22,5 +30,12 @@ public class KdHuagaoController {
         return McR.success();
     }
 
+    //更新采购订单
+    @RequestMapping("/syncPUROrder")
+    @ResponseBody
+    public McR syncPUROrder(String userId){
+        kdHuaGaoService.syncPUROrder(userId);
 
+        return McR.success();
+    }
 }

+ 46 - 4
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdCustomerController.java

@@ -1,5 +1,6 @@
 package com.malk.huagao.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.malk.huagao.service.IKdYdCustomerService;
 import com.malk.huagao.service.IKdYdZpService;
@@ -7,7 +8,11 @@ import com.malk.huagao.service.YdHuaGaoService;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.common.McR;
+import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Contacts;
+import com.malk.service.dingtalk.DDClient_Workflow;
 import com.malk.utils.UtilMap;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -36,31 +42,67 @@ public class KdYdCustomerController {
     private YdHuaGaoService ydHuaGaoService;
     @Autowired
     private IKdYdZpService kdYdZpService;
+    @Autowired
+    private DDClient_Contacts ddClient_contacts;
+    @Autowired
+    private DDClient ddClient;
 @Autowired
 private YDClient ydClient;
     @PostMapping("/test30")
     McR test13(@RequestBody Map data) {
         MDC.put("MDC_KEY_PID","1003");
+//        Map userInfoByMobile1 = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), "yzsyzid2");
+//        if (userInfoByMobile1 != null && userInfoByMobile1.containsKey("mobile")) {
+//            mobile = String.valueOf(userInfoByMobile1.get("mobile"));
+//        }
 //        String ins = String.valueOf(data.get("formInstId"));
 //
 //
+//        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+//                .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+//                .build(), YDConf.FORM_QUERY.retrieve_search_form_id);
+//
+//        System.out.println(ddrNew.getTotalCount());
+//
+//        ydClient.operateData(YDParam.builder()
+//                .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+//                .asynchronousExecution(true)
+//                .formInstanceIdList((List<String>) ddrNew.getData())
+//                .build(), YDConf.FORM_OPERATION.delete_batch);
+
+//        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+//                .formInstId("FINST-DZ966471VB228QLYJ6WXG6I7YGV631VYLW0KMBQE")
+//                .build(), YDConf.FORM_QUERY.retrieve_id);
+////
+////        if (ddrNew == null || ddrNew.getFormData() == null) {
+////            throw new RuntimeException("未找到订单信息");
+////        }
+////
+//        Map formData1 = ddrNew.getFormData();
+//        System.out.println("======"+formData1);
+
+//        String ddje = UtilMap.getString(formData1, "numberField_mjm9k35k");
+//        String dddate = UtilMap.getString(formData1, "dateField_mjm9k35j");
 //
+//        System.out.println(dddate);
+//        System.out.println(ddje);
 //        ydClient.operateData(YDParam.builder()
 //                .formInstanceId(ins)
 //      .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("numberField_mhirg0kz","156")))//xz04
 ////                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map(employ,id)))//xz04
 //                .useLatestVersion(true)
 //                .build(), YDConf.FORM_OPERATION.update);
-        ydHuaGaoService.synckdYdMaterial();
+//        ydHuaGaoService.synckdYdMaterial();
 //        ydHuaGaoService.synckdYdPayment();
+//        ydHuaGaoService.synckdYdTRANSFER();
 //        ydHuaGaoService.syncKdYdReceivable();
 //        kdYdZpService.insertkdYdZp(data);
 //        ydHuaGaoService.synckdYdOutbound();
         return McR.success();
     }
     @PostMapping("/kdYdCustomer")
-    McR insertCustomer(@RequestBody Map map) {
-        kdYdCustomerService.insertCustomer(map);
-        return McR.success();
+    Map<String, Object> insertCustomer(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdCustomerService.insertCustomer(map);
+        return stringObjectMap;
     }
 }

+ 3 - 3
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdCustomerReferrerController.java

@@ -25,8 +25,8 @@ public class KdYdCustomerReferrerController {
     @Autowired
     private IKdYdCustomerReferrerService kdYdCustomerReferrerService;
     @PostMapping("/kdYdCustomerReferrer")
-    McR kdYdCustomerReferrer(@RequestBody Map map) {
-        kdYdCustomerReferrerService.insertCustomerReferrer(map);
-        return McR.success();
+    Map<String, Object> kdYdCustomerReferrer(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdCustomerReferrerService.insertCustomerReferrer(map);
+        return stringObjectMap;
     }
 }

+ 8 - 2
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdDeliveryController.java

@@ -29,8 +29,14 @@ public class KdYdDeliveryController {
     @Autowired
     private IKdYdDeliveryService kdYdDeliveryService;
     @PostMapping("/kdYdDelivery")
-    McR insertDelivery(@RequestBody Map map) {
-        kdYdDeliveryService.insertDelivery(map);
+    Map<String, Object> insertDelivery(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdDeliveryService.insertDelivery(map);
+        return stringObjectMap;
+    }
+
+    @PostMapping("/CfkdYdDelivery")
+    McR CfkdYdDelivery(@RequestBody Map map) {
+        kdYdDeliveryService.CfkdYdDelivery(map);
         return McR.success();
     }
 }

+ 7 - 2
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdMaterialController.java

@@ -28,9 +28,14 @@ public class KdYdMaterialController {
     private YDClient ydClient;
     @Autowired
     private IKdYdMaterialService kdYdMaterialService;
-    @PostMapping("/kdYdMaterial")
-    McR insertkdYdMaterial(@RequestBody Map map) {
+    @PostMapping("/kdYdMaterial1")
+    McR insertkdYdMaterial1(@RequestBody Map map) {
         kdYdMaterialService.insertkdYdMaterial(map);
         return McR.success();
     }
+    @PostMapping("/kdYdMaterial")
+    Map<String, Object> insertkdYdMaterial(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdMaterialService.addkdYdMaterial(map);
+        return stringObjectMap;
+    }
 }

+ 7 - 2
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdOrderController.java

@@ -28,8 +28,13 @@ public class KdYdOrderController {
     @Autowired
     private IKdYdOrderService kdYdOrderService;
     @PostMapping("/kdYdOrder")
-    McR insertkdYdOrder(@RequestBody Map map) {
-        kdYdOrderService.insertkdYdOrder(map);
+    Map<String, Object> insertkdYdOrder(@RequestBody Map map) {
+       Map result = kdYdOrderService.insertkdYdOrder(map);
+        return result;
+    }
+    @PostMapping("/SckdYdOrder")
+    McR SckdYdOrder(@RequestBody Map map) {
+        kdYdOrderService.SckdYdOrder(map);
         return McR.success();
     }
 }

+ 3 - 3
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdOutboundController.java

@@ -29,8 +29,8 @@ public class KdYdOutboundController {
     @Autowired
     private IKdYdOutboundService kdYdOutboundService;
     @PostMapping("/kdYdOutbound")
-    McR insertkdYdOutbound(@RequestBody Map map) {
-        kdYdOutboundService.insertkdYdOutbound(map);
-        return McR.success();
+    Map<String, Object> insertkdYdOutbound(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdOutboundService.insertkdYdOutbound(map);
+        return stringObjectMap;
     }
 }

+ 13 - 2
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdReceivableController.java

@@ -28,9 +28,20 @@ public class KdYdReceivableController {
     private YDClient ydClient;
     @Autowired
     private IKdYdReceivableService kdYdReceivableService;
-    @PostMapping("/kdYdReceivable")
-    McR insertkdYdReceivable(@RequestBody Map map) {
+    @PostMapping("/kdYdReceivable1")
+    McR insertkdYdReceivable1(@RequestBody Map map) {
         kdYdReceivableService.insertkdYdReceivable(map);
         return McR.success();
     }
+    @PostMapping("/kdYdReceivable")
+    Map<String, Object> insertkdYdReceivable(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap =kdYdReceivableService.insertkdYdReceivable1(map);
+        return stringObjectMap;
+    }
+
+    @PostMapping("/kdYdpayment")
+    Map<String, Object> insertkdYdpayment(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap =kdYdReceivableService.insertkdYdpayment(map);
+        return stringObjectMap;
+    }
 }

+ 8 - 2
mjava-huagao/src/main/java/com/malk/huagao/controller/KdYdTransferController.java

@@ -28,9 +28,15 @@ public class KdYdTransferController {
     private YDClient ydClient;
     @Autowired
     private IKdYdTransferService kdYdTransferService;
-    @PostMapping("/kdYdTransfer")
-    McR insertTransfer(@RequestBody Map map) {
+    @PostMapping("/kdYdTransfer1")
+    McR insertTransfer1(@RequestBody Map map) {
         kdYdTransferService.insertTransfer(map);
         return McR.success();
     }
+
+    @PostMapping("/kdYdTransfer")
+    Map<String, Object> insertTransfer(@RequestBody Map map) {
+        Map<String, Object> stringObjectMap = kdYdTransferService.insertTransfer1(map);
+        return stringObjectMap;
+    }
 }

+ 6 - 0
mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdCustomer.java

@@ -77,6 +77,12 @@ public class KdYdCustomer implements Serializable {
 
     private String qyxygl;
 
+    private String khlx;
+
+    private String sfjtkh;
+
+    private String dyjtkh;
+
     private LocalDateTime createTime;
 
     private LocalDateTime updateTime;

+ 8 - 3
mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdMaterial.java

@@ -1,8 +1,7 @@
 package com.malk.huagao.entity;
 
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.*;
+
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
@@ -38,6 +37,10 @@ public class KdYdMaterial implements Serializable {
 
     private String jbdw;
 
+    private String ksrq;
+
+    private String jzrq;
+
     private String ssxl;
 
     private String jx;
@@ -71,6 +74,8 @@ public class KdYdMaterial implements Serializable {
     private LocalDateTime updateTime;
 
     private String forminstid;
+@TableField("FMATERIALID")
+    private int FMATERIALID;
 
       @TableId(value = "id", type = IdType.AUTO)
       private Long id;

+ 4 - 0
mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdOrderDetail.java

@@ -47,6 +47,8 @@ public class KdYdOrderDetail implements Serializable {
 
     private String sfzp;
 
+    private String bz;
+
     private Integer sl;
 
     private BigDecimal se;
@@ -57,6 +59,8 @@ public class KdYdOrderDetail implements Serializable {
 
     private BigDecimal jj;
 
+    private BigDecimal cxzkje;
+
     private BigDecimal zkl;
 
     private BigDecimal zke;

+ 4 - 0
mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdTransfer.java

@@ -67,4 +67,8 @@ public class KdYdTransfer implements Serializable {
     private String kdgs;
 
     private String fkfs;
+
+    private String ddbh;
+
+    private String fhtzdbh;
 }

+ 4 - 0
mjava-huagao/src/main/java/com/malk/huagao/entity/KdYdTransferDetail.java

@@ -48,6 +48,10 @@ public class KdYdTransferDetail implements Serializable {
 
     private String drck;
 
+    private String xlh;
+
+    private String kddh;
+
     private String drcw;
 
     private String drckzt;

+ 6 - 0
mjava-huagao/src/main/java/com/malk/huagao/schedule/KdScheduleTask.java

@@ -48,4 +48,10 @@ public class KdScheduleTask {
     public void syncDLVNotice(){
         kdHuaGaoService.syncDLVNotice(null);
     }
+
+    //每天00:02定时同步采购订单
+    @Scheduled(cron = "0 2 0 * * ?")
+    public void syncPUROrder(){
+        kdHuaGaoService.syncPUROrder(null);
+    }
 }

+ 1 - 1
mjava-huagao/src/main/java/com/malk/huagao/schedule/ScheduleTask.java

@@ -44,7 +44,7 @@ public class ScheduleTask {
     /**
      *
      */
-//    @Scheduled(cron = "0 5 2 1 * ?")
+    @Scheduled(cron = "0 5 2 1 * ?")
     public void syncMonths() {
         log.info("考勤同步-月度");
         LocalDateTime startTime = LocalDate.now().minusMonths(1).atTime(LocalTime.MIN);

+ 43 - 4
mjava-huagao/src/main/java/com/malk/huagao/schedule/YdScheduleTask.java

@@ -8,9 +8,11 @@ import com.malk.huagao.service.YdHuaGaoService;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.aliwork.YDSearch;
+import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
@@ -124,43 +126,80 @@ private YdHuaGaoService ydHuaGaoService;
 
 
 
-    @Scheduled(cron = "0 0/15 * * * ?")
+//    @Scheduled(cron = "0 0/15 * * * ?")
     public void synckdYdOutbound() {
         log.info("定时同步-出库单");
         try {
+            MDC.put("MDC_KEY_PID","1003");
             ydHuaGaoService.synckdYdOutbound();
         } catch (Exception e) {
             log.error("【出库单同步任务】执行过程中发生严重错误", e);
         }
     }
 
-    @Scheduled(cron = "0 0/15 * * * ?")
+//    @Scheduled(cron = "0 0/15 * * * ?")
     public void syncKdYdReceivable() {
         log.info("定时同步-应收单");
         try {
+            MDC.put("MDC_KEY_PID","1003");
             ydHuaGaoService.syncKdYdReceivable();
         } catch (Exception e) {
             log.error("【应收单同步任务】执行过程中发生严重错误", e);
         }
     }
 //    @Scheduled(fixedRate = 5 * 60 * 1000)
-    @Scheduled(cron = "0 0/15 * * * ?")
+//    @Scheduled(cron = "0 0/15 * * * ?")
+//@Scheduled(cron = "0/1 * * * * ?")
     public void synckdYdMaterial() {
         log.info("定时同步-物料信息");
         try {
+            MDC.put("MDC_KEY_PID","1003");
             ydHuaGaoService.synckdYdMaterial();
         } catch (Exception e) {
             log.error("【物料信息同步任务】执行过程中发生严重错误", e);
         }
     }
 
-    @Scheduled(cron = "0 0/15 * * * ?")
+//    @Scheduled(cron = "0 0/15 * * * ?")
     public void synckdYdPayment() {
         log.info("定时同步-synckdYdPayment");
         try {
+            MDC.put("MDC_KEY_PID","1003");
             ydHuaGaoService.synckdYdPayment();
         } catch (Exception e) {
             log.error("【synckdYdPayment同步任务】执行过程中发生严重错误", e);
         }
     }
+
+//    @Scheduled(cron = "0 0/15 * * * ?")
+    public void synckdYdTRANSFER() {
+        log.info("定时同步-synckdYdTRANSFER");
+        try {
+            MDC.put("MDC_KEY_PID","1003");
+            ydHuaGaoService.synckdYdTRANSFER();
+        } catch (Exception e) {
+            log.error("【synckdYdTRANSFER同步任务】执行过程中发生严重错误", e);
+        }
+    }
+
+//    @Scheduled(cron = "0/1 * * * * ?")
+    public void synckddel() {
+        log.info("定时删除物料表");
+        try {
+            MDC.put("MDC_KEY_PID","1003");
+            DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+                    .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+                    .build(), YDConf.FORM_QUERY.retrieve_search_form_id);
+
+            System.out.println(ddrNew.getTotalCount());
+
+            ydClient.operateData(YDParam.builder()
+                    .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+                    .asynchronousExecution(true)
+                    .formInstanceIdList((List<String>) ddrNew.getData())
+                    .build(), YDConf.FORM_OPERATION.delete_batch);
+        } catch (Exception e) {
+            log.error("【synckdYdTRANSFER同步任务】执行过程中发生严重错误", e);
+        }
+    }
 }

+ 12 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/EqbService.java

@@ -0,0 +1,12 @@
+package com.malk.huagao.service;
+
+import com.malk.server.common.McR;
+
+import java.util.Map;
+
+public interface EqbService {
+
+    void autoAgree(String signFlowId,String processInstanceId);
+
+    McR sign(Map map);
+}

+ 1 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdCustomerReferrerService.java

@@ -15,5 +15,5 @@ import java.util.Map;
  */
 public interface IKdYdCustomerReferrerService extends IService<KdYdCustomerReferrer> {
 
-    void insertCustomerReferrer(Map map);
+    Map<String, Object> insertCustomerReferrer(Map map);
 }

+ 1 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdCustomerService.java

@@ -15,5 +15,5 @@ import java.util.Map;
  */
 public interface IKdYdCustomerService {
 
-    void insertCustomer(Map map);
+    Map<String, Object> insertCustomer(Map map);
 }

+ 3 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdDeliveryService.java

@@ -15,5 +15,7 @@ import java.util.Map;
  */
 public interface IKdYdDeliveryService extends IService<KdYdDelivery> {
 
-    void insertDelivery(Map map);
+    Map<String, Object> insertDelivery(Map map);
+
+    void CfkdYdDelivery(Map map);
 }

+ 2 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdMaterialService.java

@@ -16,4 +16,6 @@ import java.util.Map;
 public interface IKdYdMaterialService extends IService<KdYdMaterial> {
 
     void insertkdYdMaterial(Map map);
+
+    Map<String, Object> addkdYdMaterial(Map map);
 }

+ 4 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdOrderService.java

@@ -2,6 +2,7 @@ package com.malk.huagao.service;
 
 import com.malk.huagao.entity.KdYdOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.server.common.McR;
 
 import java.util.Map;
 
@@ -15,5 +16,7 @@ import java.util.Map;
  */
 public interface IKdYdOrderService extends IService<KdYdOrder> {
 
-    void insertkdYdOrder(Map map);
+    Map<String, Object> insertkdYdOrder(Map map);
+
+    void SckdYdOrder(Map map);
 }

+ 1 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdOutboundService.java

@@ -15,5 +15,5 @@ import java.util.Map;
  */
 public interface IKdYdOutboundService extends IService<KdYdOutbound> {
 
-    void insertkdYdOutbound(Map map);
+    Map<String, Object> insertkdYdOutbound(Map map);
 }

+ 4 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdReceivableService.java

@@ -16,4 +16,8 @@ import java.util.Map;
 public interface IKdYdReceivableService extends IService<KdYdReceivable> {
 
     void insertkdYdReceivable(Map map);
+
+    Map<String, Object> insertkdYdReceivable1(Map map);
+
+    Map<String, Object> insertkdYdpayment(Map map);
 }

+ 1 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/IKdYdTransferService.java

@@ -17,4 +17,5 @@ public interface IKdYdTransferService extends IService<KdYdTransfer> {
 
     void insertTransfer(Map map);
 
+    Map<String, Object> insertTransfer1(Map map);
 }

+ 2 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/KdHuaGaoService.java

@@ -12,4 +12,6 @@ public interface KdHuaGaoService {
     void syncPendingProducts();
 
     void syncDLVNotice(String userId);
+
+    void syncPUROrder(String userId);
 }

+ 6 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/YdHuaGaoService.java

@@ -1,5 +1,7 @@
 package com.malk.huagao.service;
 
+import com.malk.server.common.McR;
+
 public interface YdHuaGaoService {
     void syncKdYdCustomer();
 
@@ -20,4 +22,8 @@ public interface YdHuaGaoService {
     void syncKdYdDeliveryDetail();
 
     void synckdYdPayment();
+
+    void synckdYdTRANSFER();
+
+
 }

+ 976 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/impl/EqbServiceImpl.java

@@ -0,0 +1,976 @@
+package com.malk.huagao.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.huagao.service.EqbService;
+import com.malk.huagao.utils.HTTPHelper;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Service
+public class EqbServiceImpl implements EqbService {
+    @Autowired
+    private YDConf ydConf;
+
+    @Autowired
+    private YDClient ydClient;
+
+    @Autowired
+    private DDClient ddClient;
+
+    // 应用ID
+    final static String appId = "5112033166";
+    // 应用密钥(AppSecret)
+    final static String appKey = "c0641a1f648a68a7014be5a490f0159a";
+    // e签宝接口调用域名(正式环境)
+    final static String host = "https://openapi.esign.cn";
+
+    //正式环境模板id 经销商模板
+    final static String jxs_templateId = "6a23f76742d74b858cdc2259a5d5c32f";
+    //正式环境模板id 其他客户模板
+    final static String qtkh_templateId = "8b7fef2257bc4093ada330dbf7c874c5";
+    //正式环境模板id 采购订单模板
+    final static String cgdd_templateId = "a0827f8946994ebfbed7f44e6b8a6ed8";
+
+    @Value(value = "${eqb.downloadFilePath}")
+    private String downloadFilePath;
+
+    @Value(value = "${server.host}")
+    private String serverHost;
+
+    @Value(value = "${eqb.signatoryPsnId}")
+    private String signatoryPsnId;
+
+    @Value(value = "${dingtalk.atUserId}")
+    private String atUserId;
+
+
+
+    @Async
+    @Override
+    public void autoAgree(String signFlowId,String processInstanceId) {
+        MDC.put("MDC_KEY_PID","1003");
+
+        //1、签署后文件回写宜搭
+        Map fileInfo = downloadSignedFile(signFlowId);
+        String fileId = UtilMap.getString(fileInfo, "fileId");
+        String fileName = UtilMap.getString(fileInfo, "fileName");
+
+        String downloadUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=download";
+        String previewUrl = serverHost + "/huagao/eqb/files/" + fileId + ".pdf?option=preview";
+
+        //更新宜搭实例签署后文件
+        Map formData = new HashMap();
+        Map file = new HashMap();
+        file.put("downloadUrl",downloadUrl);
+        file.put("name",fileName);
+        file.put("previewUrl",previewUrl);
+        file.put("url",downloadUrl);
+        file.put("ext","pdf");
+
+        formData.put("attachmentField_mj8dt3g2",Arrays.asList(file));
+
+        ydClient.operateData(YDParam.builder()
+                .updateFormDataJson(JSONObject.toJSONString(formData))
+                .formInstanceId(processInstanceId)
+                .build(), YDConf.FORM_OPERATION.update);
+
+        //2、自动同意宜搭审批节点
+        String activityId = "node_ockpz6phx73";//审批节点id【e签宝签署(系统节点,禁止删除!)】
+        long taskId = 0;
+        String userId = "";//审批人id
+
+        //获取审批记录
+        List<Map> result = (List<Map>) ydClient.queryData(YDParam.builder()
+                .processInstanceId(processInstanceId)
+                .build(), YDConf.FORM_QUERY.retrieve_approval_record).getResult();
+        for (Map approveInfo : result) {
+            if (activityId.equals(UtilMap.getString(approveInfo, "activityId"))){
+                //获取taskId
+                taskId = UtilMap.getLong(approveInfo, "taskId");
+                userId = UtilMap.getString(approveInfo, "operatorUserId");
+                break;
+            }
+        }
+
+        //审批
+        Map body = new HashMap();
+        body.put("outResult","AGREE");//AGREE:同意 DISAGREE:拒绝。
+        body.put("appType",ydConf.getAppType());
+        body.put("systemToken",ydConf.getSystemToken());
+        body.put("remark","e签宝签署完成,自动通过");//审批意见
+        body.put("processInstanceId",processInstanceId);//审批实例id
+        body.put("userId",userId);//用户userid
+        body.put("taskId",taskId);//任务id
+
+        UtilHttp.doPost("https://api.dingtalk.com/v1.0/yida/tasks/execute", ddClient.initTokenHeader(), null,body);
+    }
+
+    @Async
+    @Override
+    public McR sign(Map map) {
+        MDC.put("MDC_KEY_PID","1003");
+        //1、查询宜搭实例详情
+        String formInstId = UtilMap.getString(map, "formInstId");
+
+        Map formData = ydClient.queryData(YDParam.builder()
+                .formInstanceId(formInstId)
+                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+        String type = UtilMap.getString(formData, "selectField_mj89qndi");//用印文件类型
+
+        String fileName = UtilMap.getString(formData, "textField_meqr38kq");//用印文件名称
+
+        String signType = UtilMap.getString(formData, "radioField_mk0s5sf9");//签章类型
+
+        JSONObject reqBodyObj = new JSONObject();
+
+        List<Map> components = new ArrayList<>();
+
+
+        switch (type){
+            case "销售合同-经销商":
+                getJxsObj(formData, components, reqBodyObj, fileName);
+                break;
+            case "销售合同-其他客户":
+                getQtkhObj(formData,components,reqBodyObj,fileName);
+                break;
+            case "采购订单":
+                getCgddObj(formData,components,reqBodyObj,fileName);
+                break;
+            default:break;
+        }
+
+        //2、填充模板生成文件
+        Map result = eqbPost("/v3/files/create-by-doc-template", reqBodyObj);
+
+        String fileId = UtilMap.getString(result,"fileId");
+
+        //文档转换pdf需时间
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+
+        //3、基于文件发起签署
+        JSONObject reqBodyObj2 = new JSONObject();
+        //设置待签署文件信息
+        Map docs = new HashMap();
+        docs.put("fileId", fileId);
+        reqBodyObj2.put("docs", Arrays.asList(docs));
+
+        //签署流程配置项
+        Map signFlowConfig = new HashMap();
+        signFlowConfig.put("signFlowTitle",fileName);
+        signFlowConfig.put("autoFinish",true);
+        signFlowConfig.put("notifyUrl",serverHost + "/huagao/eqb/callback");//回调地址
+        reqBodyObj2.put("signFlowConfig",signFlowConfig);
+
+        //签署方信息
+        //我方
+        Map signer = new HashMap();
+        signer.put("signerType",1);//签署方类型,0 - 个人,1 - 企业/机构,2 - 法定代表人,3 - 经办人
+
+        Map orgSignerInfo = new HashMap();
+        orgSignerInfo.put("orgId","a5ec8fb7d8cc4276bd486824df0ec640");//华高机构id
+        //企业/机构经办人信息
+        Map transactorInfo = new HashMap();
+        transactorInfo.put("psnId",signatoryPsnId);//陈伟东
+        orgSignerInfo.put("transactorInfo",transactorInfo);
+        signer.put("orgSignerInfo",orgSignerInfo);
+
+        /*Map psnSignerInfo = new HashMap();
+        psnSignerInfo.put("psnId",signatoryPsnId);//陈伟东
+        signer.put("psnSignerInfo",psnSignerInfo);*/
+
+        Map signField = new HashMap();
+        signField.put("fileId",fileId);
+        signField.put("customBizNum",formInstId);
+        Map normalSignFieldConfig = new HashMap();
+        normalSignFieldConfig.put("freeMode",true);
+            /*normalSignFieldConfig.put("autoSign",true);
+            normalSignFieldConfig.put("signFieldStyle",1);
+            Map signFieldPosition = new HashMap();
+            signFieldPosition.put("positionPage",1);
+            normalSignFieldConfig.put("signFieldPosition",signFieldPosition);*/
+        signField.put("normalSignFieldConfig",normalSignFieldConfig);
+        signer.put("signFields",Arrays.asList(signField));
+
+        reqBodyObj2.put("signers",Arrays.asList(signer));
+
+        //他方
+        String jbr = "";
+        String jbrdh = "";
+        String orgName = "";
+        if ("双方签章".equals(signType)){
+            switch (type){
+                case "销售合同-经销商":
+                    jbr = UtilMap.getString(formData, "textField_mk0s5sfa");//需方经办人
+                    jbrdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方经办人电话
+                    orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称
+                    break;
+                case "销售合同-其他客户":
+                    jbr = UtilMap.getString(formData, "textField_mk0s5sfh");//需方经办人
+                    jbrdh = UtilMap.getString(formData, "textField_mk0s5sfg");//需方经办人电话
+                    orgName = UtilMap.getString(formData, "textField_mjaukh2p");//需方名称
+                    break;
+                case "采购订单":
+                    jbr = UtilMap.getString(formData, "textField_mj8dt3g8");//供方经办人
+                    jbrdh = UtilMap.getString(formData, "textField_mj8dt3g9");//供方经办人电话
+                    orgName = UtilMap.getString(formData, "textField_mj8dt3g7");//供方名称
+                    break;
+                default:break;
+            }
+
+            Map signer2 = new HashMap();
+            signer2.put("signerType",1);//签署方类型,0 - 个人,1 - 企业/机构,2 - 法定代表人,3 - 经办人
+
+            Map orgSignerInfo2 = new HashMap();
+            orgSignerInfo2.put("orgName",orgName);//对方机构名称
+            //企业/机构经办人信息
+            Map transactorInfo2 = new HashMap();
+            transactorInfo2.put("psnAccount",jbrdh);//经办人账号标识,手机号或邮箱,必须配合psnName(经办人姓名)传入
+            Map psnInfo = new HashMap();
+            psnInfo.put("psnName",jbr);//经办人姓名
+            transactorInfo2.put("psnInfo",psnInfo);
+            orgSignerInfo2.put("transactorInfo",transactorInfo2);
+            signer2.put("orgSignerInfo",orgSignerInfo2);
+
+            Map signField2 = new HashMap();
+            signField2.put("fileId",fileId);
+            signField2.put("customBizNum",formInstId);
+            Map normalSignFieldConfig2 = new HashMap();
+            normalSignFieldConfig2.put("freeMode",true);
+
+            signField2.put("normalSignFieldConfig",normalSignFieldConfig2);
+            signer2.put("signFields",Arrays.asList(signField2));
+
+            reqBodyObj2.put("signers",Arrays.asList(signer,signer2));
+        }
+
+        Map result2 = eqbPost("/v3/sign-flow/create-by-file", reqBodyObj2);
+
+        String signFlowId = UtilMap.getString(result2, "signFlowId");
+
+
+        //4、回写签署地址
+        JSONObject reqBodyObj3 = new JSONObject();
+        Map operator = new HashMap();
+        operator.put("psnId", signatoryPsnId);
+        reqBodyObj3.put("operator", operator);
+        Map result3 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj3);
+
+        String shortUrl = UtilMap.getString(result3, "shortUrl");
+
+        ydClient.operateData(YDParam.builder()
+                .formInstanceId(formInstId)
+                .content("签署地址:"+shortUrl)
+                .userId("yida_pub_account")
+                .atUserId(atUserId)//陈伟东
+                .build(), YDConf.FORM_OPERATION.remarks);
+
+        if ("双方签章".equals(signType)){
+            System.out.println("获取对方签署地址");
+            JSONObject reqBodyObj4 = new JSONObject();
+            Map operator2 = new HashMap();
+            operator2.put("psnAccount", jbrdh);
+            reqBodyObj4.put("operator", operator2);
+            reqBodyObj4.put("needLogin", true);
+            Map result4 = eqbPost("/v3/sign-flow/" + signFlowId + "/sign-url", reqBodyObj4);
+
+            String shortUrl2 = UtilMap.getString(result4, "shortUrl");
+
+            ydClient.operateData(YDParam.builder()
+                    .formInstanceId(formInstId)
+                    .content("对方签署地址:"+shortUrl2)
+                    .userId("yida_pub_account")
+                    .build(), YDConf.FORM_OPERATION.remarks);
+        }
+
+
+        return McR.success();
+    }
+
+    private void getJxsObj(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
+        String dgdbh = UtilMap.getString(formData, "textField_mjas1rkm");//订购单编号
+        String xf = UtilMap.getString(formData, "textField_mjaukh2p");//需方
+        String xfdz = UtilMap.getString(formData, "textareaField_mf50cbqt");//需方地址
+        String xfdh = UtilMap.getString(formData, "textField_mf50cbqw");//需方电话
+        String xfjbr = UtilMap.getString(formData, "textField_mj8dt3fj");//需方经办人
+        String gfdh = UtilMap.getString(formData, "textField_mjau7ffr");//供方电话
+        String gfjbr = UtilMap.getString(formData, "textField_mjauqjr9");//供方经办人
+        long ddrq = UtilMap.getLong(formData, "dateField_mj8dt3fa");//订单日期
+        String ghkjxybh = UtilMap.getString(formData, "textField_mjas1rkn");//供货框架协议编号
+        Double jehj = UtilMap.getDouble(formData, "numberField_me1335n7");//金额合计
+        String jehjdx = UtilMap.getString(formData, "textField_mf50cbvj");//金额合计大写
+        String fktj = UtilMap.getString(formData, "radioField_mf50cbu7");//付款条件
+        String xfnsrsbh = UtilMap.getString(formData, "textField_mf50cbuj");//需方纳税人识别号
+        String xfkhyh = UtilMap.getString(formData, "textField_mf50cbup");//需方开户银行
+        String xfzh = UtilMap.getString(formData, "textField_mf50cbuk");//需方账号
+
+        List<Map> xshtmxList = UtilMap.getList(formData, "tableField_mf50cbre");//销售合同明细
+        List<Map> jhdzList = UtilMap.getList(formData, "tableField_mj8dt3fk");//交货地址
+
+        //订购单编号
+        Map jxsComponent = new HashMap();
+        jxsComponent.put("componentKey", "dgdbh");
+        jxsComponent.put("componentValue", dgdbh);
+
+        //需方
+        Map jxsComponent2 = new HashMap();
+        jxsComponent2.put("componentKey", "xf");
+        jxsComponent2.put("componentValue", xf);
+
+        //需方地址
+        Map jxsComponent3 = new HashMap();
+        jxsComponent3.put("componentKey", "xfdz");
+        jxsComponent3.put("componentValue", xfdz);
+
+        //需方电话
+        Map jxsComponent4 = new HashMap();
+        jxsComponent4.put("componentKey", "xfdh");
+        jxsComponent4.put("componentValue", xfdh);
+
+        //需方经办人
+        Map jxsComponent5 = new HashMap();
+        jxsComponent5.put("componentKey", "xfjbr");
+        jxsComponent5.put("componentValue", xfjbr);
+
+        //供方电话
+        Map jxsComponent6 = new HashMap();
+        jxsComponent6.put("componentKey", "gfdh");
+        jxsComponent6.put("componentValue", gfdh);
+
+        //供方经办人
+        Map jxsComponent7 = new HashMap();
+        jxsComponent7.put("componentKey", "gfjbr");
+        jxsComponent7.put("componentValue", gfjbr);
+
+        //订单日期
+        Map jxsComponent8 = new HashMap();
+        jxsComponent8.put("componentKey", "ddrq");
+        jxsComponent8.put("componentValue", ddrq);
+
+        //供货框架协议编号
+        Map jxsComponent9 = new HashMap();
+        jxsComponent9.put("componentKey", "ghkjxybh");
+        jxsComponent9.put("componentValue", ghkjxybh);
+
+        //金额合计
+        Map jxsComponent10 = new HashMap();
+        jxsComponent10.put("componentKey", "jehj");
+        jxsComponent10.put("componentValue", jehj);
+
+        //金额合计大写
+        Map jxsComponent11 = new HashMap();
+        jxsComponent11.put("componentKey", "jehjdx");
+        jxsComponent11.put("componentValue", jehjdx);
+
+        //付款条件
+        Map jxsComponent12 = new HashMap();
+        if ("款到发货".equals(fktj)){
+            jxsComponent12.put("componentKey", "xkhh");
+            jxsComponent12.put("componentValue", true);
+        }else {
+            jxsComponent12.put("componentKey", "qt");
+            jxsComponent12.put("componentValue", true);
+        }
+
+        //需方纳税人识别号
+        Map jxsComponent13 = new HashMap();
+        jxsComponent13.put("componentKey", "xfnsrsbh");
+        jxsComponent13.put("componentValue", xfnsrsbh);
+
+        //需方开户银行
+        Map jxsComponent14 = new HashMap();
+        jxsComponent14.put("componentKey", "xfkhyh");
+        jxsComponent14.put("componentValue", xfkhyh);
+
+        //需方账号
+        Map jxsComponent15 = new HashMap();
+        jxsComponent15.put("componentKey", "xfzh");
+        jxsComponent15.put("componentValue", xfzh);
+
+        //销售合同明细
+        List<Map> xshtmx = new ArrayList<>();
+        xshtmx.add(getRowMap(false));
+        for (int i = 0; i < xshtmxList.size(); i++) {
+            String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrf");//产品名称
+            String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrg");//产品型号
+            String dw = UtilMap.getString(xshtmxList.get(i), "textField_mf50cbrh");//单位
+            String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mfbx1pr4");//销售数量
+            double lsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbri");//零售单价
+            double pfyhdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mf50cbrj");//批发优惠单价
+            String zbq = UtilMap.getString(xshtmxList.get(i), "textField_mjas1rkx");//质保期
+
+            if (i == 0){
+                xshtmx.add(getRowMap(false,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbq));
+            }else {
+                xshtmx.add(getRowMap(true,i+1,cpmc,cpxh,dw,lsdj,pfyhdj,zbq));
+            }
+        }
+        Map jxsComponent16 = new HashMap();
+        jxsComponent16.put("componentKey", "xshtmx");
+        jxsComponent16.put("componentValue", JSONObject.toJSONString(xshtmx));
+
+        //交货地址
+        List<Map> jhdz = new ArrayList<>();
+        jhdz.add(getRowMap(false));
+        for (int i = 0; i < jhdzList.size(); i++) {
+            String shdz = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fl");//收货地址
+            String shr = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fm");//收货人
+            String shrlxdh = UtilMap.getString(jhdzList.get(i), "textField_mj8dt3fn");//收货人联系电话
+
+            if (i == 0){
+                jhdz.add(getRowMap(false,i+1,shdz,shr,shrlxdh));
+            }else {
+                jhdz.add(getRowMap(true,i+1,shdz,shr,shrlxdh));
+            }
+        }
+        Map jxsComponent17 = new HashMap();
+        jxsComponent17.put("componentKey", "jhdz");
+        jxsComponent17.put("componentValue", JSONObject.toJSONString(jhdz));
+
+        Map jxsComponent19 = new HashMap();
+        jxsComponent19.put("componentKey", "xf2");
+        jxsComponent19.put("componentValue", xf);
+
+        Map jxsComponent20 = new HashMap();
+        jxsComponent20.put("componentKey", "xfdz2");
+        jxsComponent20.put("componentValue", xfdz);
+
+        components.add(jxsComponent);
+        components.add(jxsComponent2);
+        components.add(jxsComponent3);
+        components.add(jxsComponent4);
+        components.add(jxsComponent5);
+        components.add(jxsComponent6);
+        components.add(jxsComponent7);
+        components.add(jxsComponent8);
+        components.add(jxsComponent9);
+        components.add(jxsComponent10);
+        components.add(jxsComponent11);
+        components.add(jxsComponent12);
+        components.add(jxsComponent13);
+        components.add(jxsComponent14);
+        components.add(jxsComponent15);
+        components.add(jxsComponent16);
+        components.add(jxsComponent17);
+        components.add(jxsComponent19);
+        components.add(jxsComponent20);
+
+        if (!"款到发货".equals(fktj)){
+            Map jxsComponent18 = new HashMap();
+            jxsComponent18.put("componentKey", "qtnr");
+            jxsComponent18.put("componentValue", fktj);
+            components.add(jxsComponent18);
+        }
+
+        // 构建请求Body体
+        reqBodyObj.put("docTemplateId", jxs_templateId);
+        reqBodyObj.put("fileName", fileName+".pdf");
+        reqBodyObj.put("components", components);
+    }
+
+    private void getQtkhObj(Map formData, List<Map> components, JSONObject reqBodyObj, String fileName){
+        String htbh = UtilMap.getString(formData, "textField_mjb71q95");//合同编号
+        String jf = UtilMap.getString(formData, "textField_mjaukh2p");//甲方
+        double xsze = UtilMap.getDouble(formData, "numberField_mjb71qac");//销售总额
+        String fkfs = UtilMap.getString(formData, "textField_mjb886fw");//付款方式
+        String jfnsrsbh = UtilMap.getString(formData, "textField_mjb71q9w");//甲方纳税人识别号
+        String jfdb = UtilMap.getString(formData, "textField_mjb886fx");//甲方代表
+        String yfdb = UtilMap.getString(formData, "textField_mj8dt3fj");//乙方代表
+
+        List<Map> xshtmxList = UtilMap.getList(formData, "tableField_mjb71qab");//销售合同明细
+
+        //订购单编号
+        Map jxsComponent = new HashMap();
+        jxsComponent.put("componentKey", "htbh");
+        jxsComponent.put("componentValue", htbh);
+
+        //甲方
+        Map jxsComponent2 = new HashMap();
+        jxsComponent2.put("componentKey", "jf");
+        jxsComponent2.put("componentValue", jf);
+
+        //销售总额
+        Map jxsComponent3 = new HashMap();
+        jxsComponent3.put("componentKey", "xsze");
+        jxsComponent3.put("componentValue", xsze);
+
+        //付款方式
+        Map jxsComponent4 = new HashMap();
+        jxsComponent4.put("componentKey", "fkfs");
+        jxsComponent4.put("componentValue", fkfs);
+
+        //甲方纳税人识别号
+        Map jxsComponent5 = new HashMap();
+        jxsComponent5.put("componentKey", "jfnsrsbh");
+        jxsComponent5.put("componentValue", jfnsrsbh);
+
+        //甲方代表
+        Map jxsComponent7 = new HashMap();
+        jxsComponent7.put("componentKey", "jfdb");
+        jxsComponent7.put("componentValue", jfdb);
+
+        //乙方代表
+        Map jxsComponent8 = new HashMap();
+        jxsComponent8.put("componentKey", "yfdb");
+        jxsComponent8.put("componentValue", yfdb);
+
+        //销售合同明细
+        List<Map> xshtmx = new ArrayList<>();
+        xshtmx.add(getRowMap(false));
+        for (int i = 0; i < xshtmxList.size(); i++) {
+            String cpmc = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa4");//产品名称
+            String cpxh = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa5");//产品型号
+            String dw = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qa6");//单位
+            String xssl = UtilMap.getString(xshtmxList.get(i), "numberField_mjb71qa7");//销售数量
+            double hsdj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qa8");//含税单价
+            int zbq = UtilMap.getInt(xshtmxList.get(i), "numberField_mjb71qaw");//质保期
+            String smzs = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qam");//扫描张数
+            double jshj = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qan");//价税合计
+            double zke = UtilMap.getDouble(xshtmxList.get(i), "numberField_mjb71qao");//折扣额
+            String bz = UtilMap.getString(xshtmxList.get(i), "textField_mjb71qaq");//备注
+
+            if (i == 0){
+                xshtmx.add(getRowMap(false,cpmc,cpxh,dw,xssl,hsdj,zbq+"年",smzs,jshj,zke,bz));
+            }else {
+                xshtmx.add(getRowMap(true,cpmc,cpxh,dw,xssl,hsdj,zbq+"年",smzs,jshj,zke,bz));
+            }
+        }
+        Map jxsComponent9 = new HashMap();
+        jxsComponent9.put("componentKey", "xshtmx");
+        jxsComponent9.put("componentValue", JSONObject.toJSONString(xshtmx));
+
+        //甲方
+        Map jxsComponent10 = new HashMap();
+        jxsComponent10.put("componentKey", "jf2");
+        jxsComponent10.put("componentValue", jf);
+
+        //甲方
+        Map jxsComponent11 = new HashMap();
+        jxsComponent11.put("componentKey", "jf3");
+        jxsComponent11.put("componentValue", jf);
+
+        //日期
+        Map jxsComponent12 = new HashMap();
+        jxsComponent12.put("componentKey", "rq");
+        jxsComponent12.put("componentValue", System.currentTimeMillis());
+
+
+        components.add(jxsComponent);
+        components.add(jxsComponent2);
+        components.add(jxsComponent3);
+        components.add(jxsComponent4);
+        components.add(jxsComponent5);
+        components.add(jxsComponent7);
+        components.add(jxsComponent8);
+        components.add(jxsComponent9);
+        components.add(jxsComponent10);
+        components.add(jxsComponent11);
+        components.add(jxsComponent12);
+
+        // 构建请求Body体
+        reqBodyObj.put("docTemplateId", qtkh_templateId);
+        reqBodyObj.put("fileName", fileName+".pdf");
+        reqBodyObj.put("components", components);
+    }
+
+    private void getCgddObj(Map formData,List<Map> components,JSONObject reqBodyObj,String fileName){
+        String cgddbh = UtilMap.getString(formData, "textField_mj9msq4v");//采购订单编号
+        long date = UtilMap.getLong(formData, "dateField_mj8dt3g6");//签订日期
+        String yf = UtilMap.getString(formData, "textField_mj8dt3g7");//乙方
+        String yfdz = UtilMap.getString(formData, "textField_mj8dt3gt");//乙方地址
+        String yflxr = UtilMap.getString(formData, "textField_mj8dt3g8");//乙方联系人
+        String yfdh = UtilMap.getString(formData, "textField_mj8dt3g9");//乙方电话
+        String nsrsbh = UtilMap.getString(formData, "textField_mj8dt3gs");//乙方纳税人识别号
+        String khyh = UtilMap.getString(formData, "textField_mj8dt3gq");//乙方开户银行
+        String zh = UtilMap.getString(formData, "textField_mj8dt3gr");//乙方账号
+        String zlyq = UtilMap.getString(formData, "textField_mj8dt3gn");//质量要求
+        String jsfs = UtilMap.getString(formData, "textField_mj8dt3go");//结算方式及付款期限
+        String bz = UtilMap.getString(formData, "textareaField_mj9msq4w");//备注
+        List<Map> cgmx = UtilMap.getList(formData, "tableField_mizdd3qf");//采购明细
+        double zjyf = UtilMap.getDouble(formData, "numberField_mj9msq4x");//总计应付
+        String jflxr = UtilMap.getString(formData, "textField_mjb2kuhf");//甲方联系人
+        String jflxdh = UtilMap.getString(formData, "textField_mjb2kuhh");//甲方联系电话
+
+        //订单编号
+        Map component = new HashMap();
+        component.put("componentKey", "ddbh");
+        component.put("componentValue", cgddbh);
+
+        //签订日期
+        Map component2 = new HashMap();
+        component2.put("componentKey", "qdrq");
+        component2.put("componentValue", date);
+
+        //乙方
+        Map component3 = new HashMap();
+        component3.put("componentKey", "yf");
+        component3.put("componentValue", yf);
+
+        //乙方联系人
+        Map component4 = new HashMap();
+        component4.put("componentKey", "yflxr");
+        component4.put("componentValue", yflxr);
+
+        //乙方联系电话
+        Map component5 = new HashMap();
+        component5.put("componentKey", "yflxdh");
+        component5.put("componentValue", yfdh);
+
+        //备注
+        Map component6 = new HashMap();
+        component6.put("componentKey", "bz");
+        component6.put("componentValue", bz);
+
+        //销售合同明细
+        List<Map> cghtmx = new ArrayList<>();
+        cghtmx.add(getRowMap(false));
+        for (int i = 0; i < cgmx.size(); i++) {
+            String wlbm = UtilMap.getString(cgmx.get(i), "textField_mizdd3qg");//物料编码
+            String wlmc = UtilMap.getString(cgmx.get(i), "textField_mizdd3qh");//物料名称
+            String ggxh = UtilMap.getString(cgmx.get(i), "textField_mizdd3qi");//规格型号
+            String cgdw = UtilMap.getString(cgmx.get(i), "textField_mizdd3qj");//采购单位
+            double cgsl = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3ql");//采购数量
+            double hsdj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qs");//含税单价
+            double jshj = UtilMap.getDouble(cgmx.get(i), "numberField_mizdd3qx");//价税合计
+            long jhrq = UtilMap.getLong(cgmx.get(i), "dateField_mizdd3qp");//交货日期
+            //时间戳转化为年月日
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            String jhrqStr = sdf.format(new Date(jhrq));
+
+            String mxbz = UtilMap.getString(cgmx.get(i), "textField_mizdd3r0");//备注
+
+            if (i == 0){
+                cghtmx.add(getRowMap(false,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz));
+            }else {
+                cghtmx.add(getRowMap(true,i+1,wlbm,wlmc,null,ggxh,cgsl,cgdw,hsdj,jshj,jhrqStr,mxbz));
+            }
+        }
+        Map component7 = new HashMap();
+        component7.put("componentKey", "cgmx");
+        component7.put("componentValue", JSONObject.toJSONString(cghtmx));
+
+        //总计应付
+        Map component8 = new HashMap();
+        component8.put("componentKey", "zjyf");
+        component8.put("componentValue", zjyf);
+
+        //质量要求
+        Map component9 = new HashMap();
+        component9.put("componentKey", "zlyq");
+        component9.put("componentValue", zlyq);
+
+        //结算方式及付款期限
+        Map component10 = new HashMap();
+        component10.put("componentKey", "jsfs");
+        component10.put("componentValue", jsfs);
+
+        //乙方
+        Map component11 = new HashMap();
+        component11.put("componentKey", "yf2");
+        component11.put("componentValue", yf);
+
+        //乙方开户银行
+        Map component12 = new HashMap();
+        component12.put("componentKey", "yfkhyh");
+        component12.put("componentValue", khyh);
+
+        //乙方账号
+        Map component13 = new HashMap();
+        component13.put("componentKey", "yfzh");
+        component13.put("componentValue", zh);
+
+        //乙方纳税人识别号
+        Map component14 = new HashMap();
+        component14.put("componentKey", "yfnsrsbh");
+        component14.put("componentValue", nsrsbh);
+
+        //乙方地址
+        Map component15 = new HashMap();
+        component15.put("componentKey", "yfdz");
+        component15.put("componentValue", yfdz);
+
+        //甲方联系人
+        Map component16 = new HashMap();
+        component16.put("componentKey", "jflxr");
+        component16.put("componentValue", jflxr);
+
+        //甲方联系电话
+        Map component17 = new HashMap();
+        component17.put("componentKey", "jflxdh");
+        component17.put("componentValue", jflxdh);
+
+        components.add(component);
+        components.add(component2);
+        components.add(component3);
+        components.add(component4);
+        components.add(component5);
+        components.add(component6);
+        components.add(component7);
+        components.add(component8);
+        components.add(component9);
+        components.add(component10);
+        components.add(component11);
+        components.add(component12);
+        components.add(component13);
+        components.add(component14);
+        components.add(component15);
+        components.add(component16);
+        components.add(component17);
+
+        // 构建请求Body体
+        reqBodyObj.put("docTemplateId", cgdd_templateId);
+        reqBodyObj.put("fileName", fileName+".pdf");
+        reqBodyObj.put("components", components);
+    }
+
+    /***
+     * e签宝post请求
+     */
+    public static Map eqbPost(String postUrl,JSONObject reqBodyObj) {
+        // 完整的请求地址
+        String postAllUrl = host + postUrl;
+
+        try {
+            // 请求Body体数据
+            String reqBodyData = reqBodyObj.toString();
+            // 对请求Body体内的数据计算ContentMD5
+            String contentMD5 = doContentMD5(reqBodyData);
+            System.out.println("请求body数据:"+reqBodyData);
+            System.out.println("body的md5值:"+ contentMD5);
+
+            // 构建待签名字符串
+            String method = "POST";
+            String accept = "*/*";
+            String contentType = "application/json";
+            String url = postUrl;
+            String date = "";
+            String headers = "";
+
+            StringBuffer sb = new StringBuffer();
+            sb.append(method).append("\n").append(accept).append("\n").append(contentMD5).append("\n")
+                    .append(contentType).append("\n").append(date).append("\n");
+            if ("".equals(headers)) {
+                sb.append(headers).append(url);
+            } else {
+                sb.append(headers).append("\n").append(url);
+            }
+
+            // 构建参与请求签名计算的明文
+            String plaintext = sb.toString();
+            // 计算请求签名值
+            String reqSignature = doSignatureBase64(plaintext, appKey);
+            System.out.println("计算请求签名值:"+reqSignature);
+
+            // 获取时间戳(精确到毫秒)
+            long timeStamp = timeStamp();
+
+            // 构建请求头
+            LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
+            header.put("X-Tsign-Open-App-Id", appId);
+            header.put("X-Tsign-Open-Auth-Mode", "Signature");
+            header.put("X-Tsign-Open-Ca-Timestamp", String.valueOf(timeStamp));
+            header.put("Accept", accept);
+            header.put("Content-Type", contentType);
+            header.put("X-Tsign-Open-Ca-Signature", reqSignature);
+            header.put("Content-MD5", contentMD5);
+
+            // 发送POST请求
+            String result = HTTPHelper.sendPOST(postAllUrl, reqBodyData, header, "UTF-8");
+
+            System.out.println("请求返回信息: " + result);
+
+            Map resultObj =(Map) JSONObject.parse(result);
+
+            Map data = UtilMap.getMap(resultObj, "data");
+
+            return data;
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+            throw new RuntimeException(e);
+        }
+    }
+
+    private Map downloadSignedFile(String signFlowId){
+        // 计算签名拼接的url
+        String postUrl = "/v3/sign-flow/" + signFlowId + "/file-download-url";
+
+        Map result = eqbPost(postUrl, new JSONObject());
+
+        List<Map> files =(List<Map>) UtilMap.getList(result, "files");
+
+        String downloadUrl = UtilMap.getString(files.get(0), "downloadUrl");
+        String fileName = UtilMap.getString(files.get(0), "fileName");
+        UUID fileId = UUID.randomUUID();
+
+        String downloadPath = downloadFilePath + fileId + ".pdf";
+
+        downloadFile(downloadUrl,downloadPath);
+
+        Map result2 = new HashMap();
+        result2.put("downloadPath",downloadPath);
+        result2.put("fileName",fileName);
+        result2.put("fileId",fileId);
+
+        return result2;
+    }
+
+    //文件下载到本地
+    private void downloadFile(String downloadUri,String downloadPath){
+        try {
+            URL url = new URL(downloadUri);
+
+            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+            int responseCode = httpConn.getResponseCode();
+
+            // 检查HTTP响应代码是否为200
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                InputStream inputStream = httpConn.getInputStream();
+                FileOutputStream outputStream = new FileOutputStream(downloadPath);
+
+                byte[] buffer = new byte[4096];
+                int bytesRead = -1;
+
+                while ((bytesRead = inputStream.read(buffer)) != -1) {
+                    outputStream.write(buffer, 0, bytesRead);
+                }
+
+                outputStream.close();
+                inputStream.close();
+            } else {
+                System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
+            }
+            httpConn.disconnect();
+        }catch (Exception e){
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    /***
+     *
+     * @param str 待计算的消息
+     * @return MD5计算后摘要值的Base64编码(ContentMD5)
+     * @throws Exception 加密过程中的异常信息
+     */
+    public static String doContentMD5(String str) throws Exception {
+        byte[] md5Bytes = null;
+        MessageDigest md5 = null;
+        String contentMD5 = null;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+            // 计算md5函数
+            md5.update(str.getBytes("UTF-8"));
+            // 获取文件MD5的二进制数组(128位)
+            md5Bytes = md5.digest();
+            // 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码(而不是对32位的16进制字符串进行编码)
+            contentMD5 = new String(Base64.encodeBase64(md5Bytes), "UTF-8");
+        } catch (NoSuchAlgorithmException e) {
+            String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
+            Exception ex = new Exception(msg);
+            ex.initCause(e);
+            throw ex;
+        } catch (UnsupportedEncodingException e) {
+            String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
+            Exception ex = new Exception(msg);
+            ex.initCause(e);
+            throw ex;
+        }
+        return contentMD5;
+    }
+
+    /***
+     * 计算请求签名值
+     *
+     * @param message 待计算的消息
+     * @param secret 密钥
+     * @return HmacSHA256计算后摘要值的Base64编码
+     * @throws Exception 加密过程中的异常信息
+     */
+    public static String doSignatureBase64(String message, String secret) throws Exception {
+        String algorithm = "HmacSHA256";
+        Mac hmacSha256;
+        String digestBase64 = null;
+        try {
+            hmacSha256 = Mac.getInstance(algorithm);
+            byte[] keyBytes = secret.getBytes("UTF-8");
+            byte[] messageBytes = message.getBytes("UTF-8");
+            hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
+            // 使用HmacSHA256对二进制数据消息Bytes计算摘要
+            byte[] digestBytes = hmacSha256.doFinal(messageBytes);
+            // 把摘要后的结果digestBytes使用Base64进行编码
+            digestBase64 = new String(Base64.encodeBase64(digestBytes), "UTF-8");
+        } catch (NoSuchAlgorithmException e) {
+            String msg = MessageFormat.format("不支持此算法: {0}", e.getMessage());
+            Exception ex = new Exception(msg);
+            ex.initCause(e);
+            throw ex;
+        } catch (UnsupportedEncodingException e) {
+            String msg = MessageFormat.format("不支持的字符编码: {0}", e.getMessage());
+            Exception ex = new Exception(msg);
+            ex.initCause(e);
+            throw ex;
+        } catch (InvalidKeyException e) {
+            String msg = MessageFormat.format("无效的密钥规范: {0}", e.getMessage());
+            Exception ex = new Exception(msg);
+            ex.initCause(e);
+            throw ex;
+        }
+        return digestBase64;
+    }
+
+
+    /***
+     * 获取时间戳(毫秒级)
+     *
+     * @return 毫秒级时间戳,如 1578446909000
+     */
+    public static long timeStamp() {
+        long timeStamp = System.currentTimeMillis();
+        return timeStamp;
+    }
+
+    private static Map getRowMap(boolean insertRow,Object... columnValues) {
+        Map row = new HashMap();
+
+        for (int i = 0; i < columnValues.length; i++) {
+            row.put("column" + (i + 1), columnValues[i]);
+        }
+
+        Map result = new HashMap();
+        result.put("row",row);
+        result.put("insertRow",insertRow);
+
+        return result;
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 315 - 22
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdHuaGaoServiceImpl.java


+ 1 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerLiaisonServiceImpl.java

@@ -47,6 +47,7 @@ public class KdYdCustomerLiaisonServiceImpl extends ServiceImpl<KdYdCustomerLiai
             String bm = UtilMap.getString(map, "bm");
             KdYdCustomerLiaison kdYdCustomerLiaison = new KdYdCustomerLiaison();
             kdYdCustomerLiaison.setOperationType("3");
+            kdYdCustomerLiaison.setSyncStatus("0");
             kdYdCustomerLiaisonMapper.update(kdYdCustomerLiaison,
                     new LambdaQueryWrapper<KdYdCustomerLiaison>().eq(KdYdCustomerLiaison::getBm, bm));
             return; // 或者根据你的业务逻辑返回相应的结果

+ 138 - 52
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerReferrerServiceImpl.java

@@ -1,5 +1,9 @@
 package com.malk.huagao.service.impl;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.malk.huagao.entity.KdYdCustomerLiaison;
 import com.malk.huagao.entity.KdYdCustomerReferrer;
@@ -11,10 +15,13 @@ import com.malk.server.aliwork.YDParam;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -26,60 +33,139 @@ import java.util.Map;
  * @since 2025-10-14
  */
 @Service
+@Slf4j
 public class KdYdCustomerReferrerServiceImpl extends ServiceImpl<KdYdCustomerReferrerMapper, KdYdCustomerReferrer> implements IKdYdCustomerReferrerService {
-@Autowired
-private YDClient ydClient;
-@Autowired
-private KdYdCustomerReferrerMapper kdYdCustomerReferrerMapper;
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private KdYdCustomerReferrerMapper kdYdCustomerReferrerMapper;
+    @Value(value = "${kd.host}")
+    private String kdHost;
     @Override
-    public void insertCustomerReferrer(Map map) {
-        MDC.put("MDC_KEY_PID", "1003");
-        String formInstId = UtilMap.getString(map, "formInstId");
-        String type = UtilMap.getString(map, "type");
-
-        if ("3".equals(type)) {
-            String bm = UtilMap.getString(map, "bm");
-            KdYdCustomerReferrer kdYdCustomerReferrer = new KdYdCustomerReferrer();
-            kdYdCustomerReferrer.setOperationType("3");
-            kdYdCustomerReferrerMapper.update(kdYdCustomerReferrer,
-                    new LambdaQueryWrapper<KdYdCustomerReferrer>().eq(KdYdCustomerReferrer::getBm, bm));
-            return; // 或者根据你的业务逻辑返回相应的结果
-        }
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
-                .formInstId(formInstId)
-                .build(), YDConf.FORM_QUERY.retrieve_id);
-        Map formData = ddrNew.getFormData();
-        String mc = UtilMap.getString(formData, "textField_mgqbiouh");
-        String sfzh = UtilMap.getString(formData, "textField_mgqbioux");
-        String sjh = UtilMap.getString(formData, "textField_mgqbioui");
-        String bm = UtilMap.getString(formData, "serialNumberField_mhiycezm");
-//        String skrmc = UtilMap.getString(formData, "textField_mgqbioun");
-//        String skzh = UtilMap.getString(formData, "textField_mgqbious");
-//        String khh = UtilMap.getString(formData, "textField_mgqbiov0");
-//        String ms = UtilMap.getString(formData, "textField_mgqbiov1");
-        String tjruuid = UtilMap.getString(formData, "textField_mgqbiov3");
-        String xsy = UtilMap.getString(formData, "employeeField_mgqbiouz").replace("[\"", "").replace("\"]", "").trim();
-        KdYdCustomerReferrer kdYdCustomerReferrer = new KdYdCustomerReferrer();
-        kdYdCustomerReferrer.setMc(mc);
-        kdYdCustomerReferrer.setSfzh(sfzh);
-        kdYdCustomerReferrer.setSjh(sjh);
-//        kdYdCustomerReferrer.setSkrmc(skrmc);
-//        kdYdCustomerReferrer.setSkzh(skzh);
-//        kdYdCustomerReferrer.setKhh(khh);
-//        kdYdCustomerReferrer.setMs(ms);
-        kdYdCustomerReferrer.setXsy(xsy);
-//        kdYdCustomerReferrer.setTjruuid(tjruuid);
-        kdYdCustomerReferrer.setBm(bm);
-        kdYdCustomerReferrer.setSyncStatus("0");
-        kdYdCustomerReferrer.setOperationType("1");
-//        kdYdCustomerReferrer.setFormInstId(formInstId);
-
-        if ("2".equals(type)) {
-            kdYdCustomerReferrer.setOperationType(type);
-            kdYdCustomerReferrerMapper.update(kdYdCustomerReferrer,
-                    new LambdaQueryWrapper<KdYdCustomerReferrer>().eq(KdYdCustomerReferrer::getBm, bm));
-        } else {
-            this.save(kdYdCustomerReferrer);
+    public Map<String, Object> insertCustomerReferrer(Map map) {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            String formInstId = UtilMap.getString(map, "formInstId");
+            String action = UtilMap.getString(map, "type");
+
+            // 处理特殊操作类型
+            if ("del".equals(action)) {
+                String bm = UtilMap.getString(map, "bm");
+
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+                Map<String, Object> formParams = new HashMap<>();
+                Map<String, Object> djbh = new HashMap<>();
+                djbh.put("djbh", bm);
+                result.put("data", djbh);
+                String jsonStr = JSON.toJSONString(result);
+                formParams.put("jsons", jsonStr);
+
+                System.out.println("====" + formParams);
+                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+
+                String responseBody = response.body();
+                // 返回删除操作的格式
+                result.put("table", "KD_YD_CUSTOMER_REFERRER");
+                result.put("action", "del");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("bm", bm);  // 删除的主键或标识
+                    put("msg", "删除成功");
+                }});
+                return result;
+            }
+
+            // 查询表单数据
+            DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+                    .formInstId(formInstId)
+                    .build(), YDConf.FORM_QUERY.retrieve_id);
+            Map formData = ddrNew.getFormData();
+
+            // 提取表单字段
+            String mc = UtilMap.getString(formData, "textField_mgqbiouh");
+//            String mc = "张三11";
+            String sfzh = UtilMap.getString(formData, "textField_mgqbioux");
+//            String sfzh = "1656455654";
+            String sjh = UtilMap.getString(formData, "textField_mgqbioui");
+//            String sjh = "1656455654";
+            String bm = UtilMap.getString(formData, "serialNumberField_mhiycezm");
+//            String bm = "TJR202615000";
+
+            String xsy = UtilMap.getString(formData, "employeeField_mgqbiouz").replace("[\"", "").replace("\"]", "").trim();
+
+            // 构建返回数据
+            Map<String, Object> cusRefData = new HashMap<>();
+            cusRefData.put("mc", mc);
+            cusRefData.put("sfzh", sfzh);
+            cusRefData.put("sjh", sjh);
+            cusRefData.put("bm", bm);
+            cusRefData.put("xsy", xsy);
+
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+            result.put("data", cusRefData);
+// 将result转换为JSON字符串
+            String jsonStr = JSON.toJSONString(result);
+// 构建form参数
+            Map<String, Object> formParams = new HashMap<>();
+            formParams.put("jsons", jsonStr);
+// 发送请求
+            System.out.println("formParams====" + formParams);
+            HttpResponse response = null;
+            if ("add".equals(action)) {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbcreatecusttjr")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            } else {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            }
+
+            String responseBody = response.body();
+//            System.out.println("res"+responseBody);
+            try {
+                String code = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("code");
+                String msg = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("msg");
+                System.out.println("msg"+msg);
+                ydClient.operateData(
+                        YDParam.builder()
+                                .formInstanceId(formInstId)
+                                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkxqgrvq",code, msg)))
+                                .useLatestVersion(true).build(),
+                        YDConf.FORM_OPERATION.update);
+            } catch (Exception e) {
+                System.out.println("解析JSON失败: " + e.getMessage());
+            }
+            log.info("客户推荐人信息同步成功: formInstId={}, mc={}, bm={}", formInstId, mc, bm);
+
+        } catch (Exception e) {
+            log.error("客户推荐人信息同步异常", e);
+
+            // 异常处理
+            result.put("table", "KD_YD_ORDER");
+            result.put("action", "error");
+            result.put("data", new HashMap<String, Object>() {{
+                put("errorMsg", "操作失败:" + e.getMessage());
+            }});
         }
+
+        return result;
     }
+
 }

+ 332 - 88
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdCustomerServiceImpl.java

@@ -1,22 +1,34 @@
 package com.malk.huagao.service.impl;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.malk.huagao.entity.KdYdCustomer;
+import com.malk.huagao.entity.KdYdCustomerLiaison;
+import com.malk.huagao.entity.KdYdDeliveryDetail;
+import com.malk.huagao.mapper.KdYdCustomerLiaisonMapper;
 import com.malk.huagao.mapper.KdYdCustomerMapper;
 import com.malk.huagao.service.IKdYdCustomerService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McException;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
-import java.util.Map;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * <p>
@@ -27,103 +39,335 @@ import java.util.Map;
  * @since 2025-10-09
  */
 @Service
+@Slf4j
 public class KdYdCustomerServiceImpl extends ServiceImpl<KdYdCustomerMapper, KdYdCustomer> implements IKdYdCustomerService {
     @Autowired
     private YDClient ydClient;
     @Autowired
     private KdYdCustomerMapper kdYdCustomerMapper;
+    @Autowired
+    private KdYdCustomerLiaisonMapper kdYdCustomerLiaisonMapper;
+
+    @Value(value = "${kd.host}")
+    private String kdHost;
 
     @Override
-    public void insertCustomer(Map map) {
-        MDC.put("MDC_KEY_PID", "1003");
-        String formInstId = UtilMap.getString(map, "formInstId");
-        String type = UtilMap.getString(map, "type");
-
-        if ("3".equals(type)) {
-            String bm = UtilMap.getString(map, "bm");
-            KdYdCustomer kdYdCustomer = new KdYdCustomer();
-            kdYdCustomer.setOperationType("3");
-            kdYdCustomerMapper.update(kdYdCustomer, new LambdaQueryWrapper<KdYdCustomer>().eq(KdYdCustomer::getKhbm, bm));
-            return; // 或者根据你的业务逻辑返回相应的结果
+    public Map<String, Object> insertCustomer(Map map) {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            String formInstId = UtilMap.getString(map, "formInstId");
+            String action = UtilMap.getString(map, "type");
+
+            // 处理特殊操作类型
+            if ("del".equals(action)) {
+                String bm = UtilMap.getString(map, "bm");
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+                Map<String, Object> formParams = new HashMap<>();
+                Map<String, Object> djbh = new HashMap<>();
+                djbh.put("djbh", bm);
+                result.put("data", djbh);
+                String jsonStr = JSON.toJSONString(result);
+
+                formParams.put("jsons", jsonStr);
+
+                System.out.println("====" + formParams);
+                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbdeletecust")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+
+                String responseBody = response.body();
+                // 返回删除操作的格式
+                result.put("table", "KD_YD_CUSTOMER");
+                result.put("action", "del");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("bm", bm);  // 删除的主键或标识
+                    put("msg", "删除成功");
+                }});
+                return result;
+            }
+
+            // === 获取表单数据 ===
+            DDR_New ddrNew = retryQueryData(
+                    YDParam.builder().formInstId(formInstId).build(),
+                    YDConf.FORM_QUERY.retrieve_id
+            );
+            Map formData = ddrNew.getFormData();
+
+            // === 提取主表字段 ===
+            String khmc = UtilMap.getString(formData, "textField_lqanqe6j");
+//            String khmc = "26228测试客户11";
+            String khbm = UtilMap.getString(formData, "textField_meqhqqvg");
+            String xssx = UtilMap.getString(formData, "selectField_megi74y7");
+            String khxypj = UtilMap.getString(formData, "selectField_mewirdx4");
+            String khsx = UtilMap.getString(formData, "selectField_megi74y8");
+            String jxr = cleanEmployeeField(UtilMap.getString(formData, "employeeField_megi74yl"));
+            String khlb = UtilMap.getString(formData, "selectField_lqanqe6l");
+            String khfz = UtilMap.getString(formData, "selectField_lqanqe6q");
+            String fptt = UtilMap.getString(formData, "textField_llujklkr");
+            String nsdjh = UtilMap.getString(formData, "textField_meqhqqvm");
+//            String nsdjh = "121212";
+            String khyh = UtilMap.getString(formData, "textField_meqhqqvn");
+            String yhzh = UtilMap.getString(formData, "textField_meqhqqvs");
+            String jxslx = UtilMap.getString(formData, "selectField_mis6kl56");
+            String kplx = UtilMap.getString(formData, "selectField_lwopqbye");
+            String kplxdh = UtilMap.getString(formData, "textField_llujklkp");
+            String kptxdz = UtilMap.getString(formData, "textField_llujklkv");
+            String tyshxydm = UtilMap.getString(formData, "textField_mfxrrysq");
+            String spdzyx = UtilMap.getString(formData, "textField_mg0fq6l4");
+            String khtjr = UtilMap.getString(formData, "textField_mfdrrg87");
+            String sktj = UtilMap.getString(formData, "selectField_meqhqqvh");
+            String xsy = cleanEmployeeField(UtilMap.getString(formData, "employeeField_lqanqe6n"));
+            String jsbb = UtilMap.getString(formData, "selectField_mfxrryt0");
+            String khyxj = UtilMap.getString(formData, "numberField_mfxs7rd3");
+            if (khyxj == null || khyxj.trim().isEmpty()) {
+                khyxj = "1";
+            }
+            String qyxygl = UtilMap.getString(formData, "radioField_mfxs7rd2");
+            String mrsl = UtilMap.getString(formData, "selectField_mfxrryt3");
+            String sfl = UtilMap.getString(formData, "selectField_mfxrryt2");
+            String sfjtkh = UtilMap.getString(formData, "radioField_mhe8e937");
+            String dyjtkh = UtilMap.getString(formData, "textField_mis6kl57");
+
+            // 构建主表数据
+            Map<String, Object> customData = new HashMap<>();
+            customData.put("khmc", khmc);
+            if("edit".equals(action)){
+                customData.put("khbm", khbm);
+            }
+            customData.put("xssx", xssx);
+            customData.put("khxypj", khxypj);
+            customData.put("khsx", khsx);
+            customData.put("jxr", jxr);
+            customData.put("khlb", khlb);
+            customData.put("khfz", khfz);
+            customData.put("fptt", fptt);
+            customData.put("nsdjh", nsdjh);
+            customData.put("khyh", khyh);
+            customData.put("yhzh", yhzh);
+            customData.put("khlx", jxslx);
+            customData.put("kplx", kplx);
+            customData.put("kplxdh", kplxdh);
+            customData.put("kptxdz", kptxdz);
+            customData.put("tyshxydm", tyshxydm);
+            customData.put("spdzyx", spdzyx);
+            customData.put("khtjr", khtjr);
+            customData.put("sktj", sktj);
+            customData.put("xsy", xsy);
+            customData.put("jsbb", jsbb);
+            customData.put("khyxj", khyxj);
+            customData.put("qyxygl", qyxygl);
+            customData.put("mrsl", mrsl);
+            customData.put("sfl", sfl);
+            customData.put("sfjtkh", sfjtkh);
+            customData.put("dyjtkh", dyjtkh);
+            System.out.println("====="+customData);
+            // 处理子表数据
+            List<Map<String, Object>> contactList = new ArrayList<>();
+            List<Map> tableField = (List<Map>) formData.get("tableField_mfkks8ww");
+
+            if (tableField != null && !tableField.isEmpty()) {
+                // 用于收集回写用的子表行
+                List<Map> updatedTableRowsForYD = new ArrayList<>();
+
+                for (Map item : tableField) {
+                    Map<String, Object> contactData = new HashMap<>();
+                    String xm = safeGetString(item, "textField_l3s6ubhq");
+                    String yddh = safeGetString(item, "textField_lqbzc3gq");
+                    String zw = safeGetString(item, "textField_l3s6ubht");
+                    String gddh = safeGetString(item, "textField_mfxu5dnk");
+                    String bm = safeGetString(item, "textField_mfkp33s5");
+                    String yx = safeGetString(item, "textField_lqbzc3gr");
+
+                    // 添加到联系人列表
+                    contactData.put("xm", xm);
+                    contactData.put("yddh", yddh);
+                    contactData.put("zw", zw);
+                    contactData.put("gddh", gddh);
+                    contactData.put("bm", bm);
+                    contactData.put("yx", yx);
+                    contactList.add(contactData);
+
+                }
+
+                // 将联系人列表添加到主数据
+                customData.put("contactList", contactList);
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+                result.put("data", customData);
+// 将result转换为JSON字符串
+                String jsonStr = JSON.toJSONString(result);
+// 构建form参数
+                Map<String, Object> formParams = new HashMap<>();
+                formParams.put("jsons", jsonStr);
+                log.info("客户请求参数:" + formParams);
+// 发送请求
+                HttpResponse response = null;
+                if ("add".equals(action)) {
+                    response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbcreatecust")
+                            .headerMap(headers, true)
+                            .form(formParams)
+                            .timeout(30000)  // 30秒超时
+                            .execute();
+                } else {
+                    response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbupdatecust")
+                            .headerMap(headers, true)
+                            .form(formParams)
+                            .timeout(30000)  // 30秒超时
+                            .execute();
+                }
+
+                String responseBody = response.body();
+                try {
+                    // 一行代码提取
+                    String khbh = JSON.parseArray(responseBody)
+                            .getJSONObject(0)
+                            .getJSONObject("data")
+                            .getString("djbh");
+                    String msg = JSON.parseArray(responseBody)
+                            .getJSONObject(0)
+                            .getString("msg");
+                    String code = JSON.parseArray(responseBody)
+                            .getJSONObject(0)
+                            .getString("code");
+                    retryOperateData(
+                            YDParam.builder()
+                                    .formInstanceId(formInstId)
+                                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkxqgrvq, textField_meqhqqvg", code, msg, khbh)))
+                                    .useLatestVersion(true).build(),
+                            YDConf.FORM_OPERATION.update);
+//
+                    log.info("回写数据到宜搭成功,formInstId: {},responseBody:{}", formInstId, responseBody);
+                } catch (Exception e) {
+                    log.warn("回写数据到宜搭失败,formInstId: {}, 错误: {}", formInstId, e.getMessage());
+                }
+            }
+
+            // 构建返回结果
+            result.put("data", customData);
+
+            log.info("客户信息同步成功: formInstId={}, khmc={}", formInstId, khmc);
+
+        } catch (Exception e) {
+            log.error("客户信息同步异常", e);
+            result.put("table", "KD_YD_CUSTOMER");
+            result.put("action", "error");
+            result.put("data", new HashMap<String, Object>() {{
+                put("errorMsg", "操作失败:" + e.getMessage());
+            }});
         }
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
-                .formInstId(formInstId)
-                .build(), YDConf.FORM_QUERY.retrieve_id);
-        Map formData = ddrNew.getFormData();
-
-        String khmc = UtilMap.getString(formData, "textField_lqanqe6j");
-        String khbm = UtilMap.getString(formData, "textField_meqhqqvg");
-        String xssx = UtilMap.getString(formData, "selectField_megi74y7");
-        String khxypj = UtilMap.getString(formData, "selectField_mewirdx4");
-        String khsx = UtilMap.getString(formData, "selectField_megi74y8");
-        String jxr = UtilMap.getString(formData, "employeeField_megi74yl").replace("[\"", "").replace("\"]", "").trim();
-        String khlb = UtilMap.getString(formData, "selectField_lqanqe6l");
-        String khfz = UtilMap.getString(formData, "selectField_lqanqe6q");
-        String fptt = UtilMap.getString(formData, "textField_llujklkr");
-        String nsdjh = UtilMap.getString(formData, "textField_meqhqqvm");
-        String khyh = UtilMap.getString(formData, "textField_meqhqqvn");
-        String yhzh = UtilMap.getString(formData, "textField_meqhqqvs");
-        String kplx = UtilMap.getString(formData, "selectField_lwopqbye");
-        String kplxdh = UtilMap.getString(formData, "textField_llujklkp");
-        String kptxdz = UtilMap.getString(formData, "textField_llujklkv");
-        String uuid = UtilMap.getString(formData, "textField_mgowmnlf");
-        String tyshxydm = UtilMap.getString(formData, "textField_mfxrrysq");
-        String spdzyx = UtilMap.getString(formData, "textField_mg0fq6l4");
-        String khtjr = UtilMap.getString(formData, "textField_mfdrrg87");
-        String sktj = UtilMap.getString(formData, "selectField_meqhqqvh");
-        String xsy = UtilMap.getString(formData, "employeeField_lqanqe6n").replace("[\"", "").replace("\"]", "").trim();
-        String jsbb = UtilMap.getString(formData, "selectField_mfxrryt0");
-        String khyxj = UtilMap.getString(formData, "numberField_mfxs7rd3");
-        String qyxygl = UtilMap.getString(formData, "radioField_mfxs7rd2");
-        String mrsl = UtilMap.getString(formData, "selectField_mfxrryt3");
-        String sfl = UtilMap.getString(formData, "selectField_mfxrryt2");
-        String tjruuid = UtilMap.getString(formData, "textField_mgqbiov3");
-        KdYdCustomer kdYdCustomer = new KdYdCustomer();
-        kdYdCustomer.setKhmc(khmc);
-        kdYdCustomer.setXssx(xssx);
-        kdYdCustomer.setSpdzyx(spdzyx);
-        kdYdCustomer.setKhsx(khsx);
-        kdYdCustomer.setKhlb(khlb);
-        kdYdCustomer.setKhfz(khfz);
-        kdYdCustomer.setFptt(fptt);
-        kdYdCustomer.setNsdjh(nsdjh);
-        kdYdCustomer.setKhyh(khyh);
-        kdYdCustomer.setYhzh(yhzh);
-        kdYdCustomer.setKplx(kplx);
-        kdYdCustomer.setKplxdh(kplxdh);
-        kdYdCustomer.setKptxdz(kptxdz);
-        kdYdCustomer.setTyshxydm(tyshxydm);
-        kdYdCustomer.setKhtjr(khtjr);
-//        kdYdCustomer.setUuid(uuid);
-        kdYdCustomer.setSktj(sktj);
-        kdYdCustomer.setXsy(xsy);
-        kdYdCustomer.setJsbb(jsbb);
-        kdYdCustomer.setKhyxj(khyxj);
-        kdYdCustomer.setQyxygl(qyxygl);
-        kdYdCustomer.setMrsl(mrsl);
-        kdYdCustomer.setSfl(sfl);
-        kdYdCustomer.setKhbm(khbm);
-        kdYdCustomer.setJxr(jxr);
-        kdYdCustomer.setKhxypj(khxypj);
-//        kdYdCustomer.setFormInstId(formInstId);
-//        kdYdCustomer.setTjruuid(tjruuid);
-        kdYdCustomer.setSyncStatus("0");
-        kdYdCustomer.setOperationType("1");
-        if ("2".equals(type)) {
-            kdYdCustomer.setOperationType(type);
-            kdYdCustomerMapper.update(kdYdCustomer, new LambdaQueryWrapper<KdYdCustomer>().eq(KdYdCustomer::getKhbm, khbm));
+
+        return result;
+    }
+
+    // 清理员工字段格式
+    private String cleanEmployeeField(String employeeField) {
+        if (employeeField == null) return "";
+        return employeeField.replace("[\"", "").replace("\"]", "").trim();
+    }
+
+    // === 工具方法(保持不变)===
+    private String safeGetString(Map formData, String key) {
+        Object val = formData.get(key);
+        return val == null ? "" : String.valueOf(val);
+    }
+
+    /**
+     * 从编码如 CXR04454 生成 CXR04455
+     */
+    private String incrementCode(String code) {
+        if (code == null || code.isEmpty()) {
+            return "CXR00001";
+        }
+        Pattern pattern = Pattern.compile("^(\\D*)(\\d+)$");
+        Matcher matcher = pattern.matcher(code.trim());
+        if (matcher.matches()) {
+            String prefix = matcher.group(1);
+            String numberPart = matcher.group(2);
+            long number = Long.parseLong(numberPart);
+            String newNumber = String.format("%0" + numberPart.length() + "d", number + 1);
+            return prefix + newNumber;
         } else {
-            this.save(kdYdCustomer);
+            return "CXR00001";
+        }
+    }
+
+    //自带重试的operateData方法
+    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        Object result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.operateData(param, formOperation);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_OPERATION:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formOperation,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}", JSONObject.toJSONString(param), formOperation,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
         }
 
-//        LambdaQueryWrapper<KdYdCustomer> YdCustomerLambdaQueryWrapper = new LambdaQueryWrapper<>();
-//        YdCustomerLambdaQueryWrapper.eq(KdYdCustomer::getFormInstId, formInstId);
-//        KdYdCustomer kdYdCustomer1 = kdYdCustomerMapper.selectOne(YdCustomerLambdaQueryWrapper);
-//        Long id = kdYdCustomer1.getId();
-//        ydClient.operateData(
-//                YDParam.builder()
-//                        .formInstanceId(formInstId)
-//                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mgowmnli", id)))
-//                        .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_OPERATION:{}"+formOperation);
     }
+
+
+    //自带重试的queryData方法
+    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        DDR_New result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.queryData(param, formQuery);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_QUERY:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formQuery,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_QUERY:{},异常信息:{}", JSONObject.toJSONString(param), formQuery,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_QUERY:{}"+formQuery);
+    }
+
 }

+ 428 - 123
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdDeliveryServiceImpl.java

@@ -1,5 +1,9 @@
 package com.malk.huagao.service.impl;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.malk.huagao.entity.*;
@@ -11,11 +15,15 @@ import com.malk.huagao.service.IKdYdDeliveryService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McException;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringEscapeUtils;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -23,18 +31,18 @@ import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * <p>
- *  服务实现类
+ * 服务实现类
  * </p>
  *
  * @author LQY
  * @since 2025-10-15
  */
 @Service
+@Slf4j
 public class KdYdDeliveryServiceImpl extends ServiceImpl<KdYdDeliveryMapper, KdYdDelivery> implements IKdYdDeliveryService {
     @Autowired
     private YDClient ydClient;
@@ -42,136 +50,357 @@ public class KdYdDeliveryServiceImpl extends ServiceImpl<KdYdDeliveryMapper, KdY
     private KdYdDeliveryMapper kdYdDeliveryMapper;
     @Autowired
     private KdYdDeliveryDetailMapper kdYdDeliveryDetailMapper;
+    @Value(value = "${kd.host}")
+    private String kdHost;
+
     @Override
-    public void insertDelivery(Map map) {
+    public Map<String, Object> insertDelivery(Map map) {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            String formInstId = UtilMap.getString(map, "formInstId");
+            String action = UtilMap.getString(map, "type");
+
+            // 处理特殊操作类型
+            if ("del".equals(action)) {
+                String bm = UtilMap.getString(map, "bm");
+
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+                Map<String, Object> formParams = new HashMap<>();
+                Map<String, Object> djbh = new HashMap<>();
+                djbh.put("djbh", bm);
+                result.put("data", djbh);
+                String jsonStr = JSON.toJSONString(result);
+                formParams.put("jsons", jsonStr);
+
+                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbdeletefhtzd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+
+                String responseBody = response.body();
+//                System.out.println("responseBody===="+responseBody);
+                log.info("删除返回值responseBody===="+responseBody);
+                // 返回删除操作的格式
+                result.put("table", "KD_YD_DELIVERY");
+                result.put("action", "del");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("bm", bm);  // 删除的主键或标识
+                    put("msg", "删除成功");
+                }});
+                return result;
+            }
+
+            // 查询表单数据
+            DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+                    .formInstId(formInstId)
+                    .build(), YDConf.FORM_QUERY.retrieve_id);
+            Map formData = ddrNew.getFormData();
+
+            // 提取主表字段
+            String djlx = UtilMap.getString(formData, "selectField_mg3fuqvg");
+            String orderId = UtilMap.getString(formData, "textField_mf6a0h6f");
+            LocalDateTime rq = parseTimestamp(UtilMap.getString(formData, "dateField_krbgloam"));
+            String kh = UtilMap.getString(formData, "textField_mejnamf2");
+            String jsbb = UtilMap.getString(formData, "selectField_mg3fuqvn");
+            String djbh = UtilMap.getString(formData, "serialNumberField_mheazm7w");
+            String xsbm = UtilMap.getString(formData, "textField_krnn5bmr");
+            String lllx = UtilMap.getString(formData, "selectField_mejowmnc");
+            String jjr = UtilMap.getString(formData, "textField_mf6a0h5f");
+            String jjrdh = UtilMap.getString(formData, "textField_mf6a0h5g");
+            String jjdz = UtilMap.getString(formData, "textareaField_mf6a0h5h");
+            String xslx = UtilMap.getString(formData, "selectField_mgrn6p2d");
+            String bzfs = UtilMap.getString(formData, "selectField_mf6a0h5y");
+            String bz = UtilMap.getString(formData, "textareaField_mejnamfb");
+//            LocalDateTime hhsj = parseTimestamp(UtilMap.getString(formData, "dateField_mf6a0h67"));
+            LocalDateTime hhsj = Optional.ofNullable(
+                            parseTimestamp(UtilMap.getString(formData, "dateField_mf6a0h67"))
+                    )
+                    .orElseGet(() -> LocalDateTime.now()
+                            .withHour(17)
+                            .withMinute(0)
+                            .withSecond(0)
+                            .withNano(0));
+            String ysfs = UtilMap.getString(formData, "selectField_mf6a0h5z");
+            String hdfs = UtilMap.getString(formData, "selectField_mf6a0h60");
+            String kdgs = UtilMap.getString(formData, "selectField_mf6a0h61");
+            String fkfs = UtilMap.getString(formData, "selectField_mf6a0h66");
+
+            // 处理明细数据
+            List<Map<String, Object>> deliveryList = new ArrayList<>();
+            List<Map> tableField = (List<Map>) formData.get("tableField_mejnamfd");
+
+            if (tableField != null && !tableField.isEmpty()) {
+//                int detailId = 1;
+                for (Map item : tableField) {
+                    Map<String, Object> table1Map = new HashMap<>();
+                    int detailId = parseInt(safeGetString(item, "numberField_mjzg06br"), 1);
+                    String wlbm = safeGetString(item, "textField_mejnamff");
+                    String wlmc = safeGetString(item, "textField_mejnamfg");
+                    String ggxh = safeGetString(item, "textField_mejnamfh");
+                    String xsdw = safeGetString(item, "textField_mejnamfk");
+                    int jjsl = parseInt(safeGetString(item, "numberField_mf6a0h6r"), 0);
+//                    int count = parseInt(safeGetString(item, "numberField_mjzg06br"), 0);
+                    String ssxl = safeGetString(item, "textField_mejnamfx");
+                    String sfzp = safeGetString(item, "radioField_mf6a0h6h");
+                    String ckck = safeGetString(item, "textField_mf6a0h6l");
+                    String ckcw = safeGetString(item, "textField_mf6a0h6k");
+                    String sjr = safeGetString(item, "textField_mejnamf6");
+                    String sjdh = safeGetString(item, "textField_mejnamf7");
+                    String sjdz = safeGetString(item, "textareaField_mf6a0h5e");
+                    String bz1 = safeGetString(item, "textareaField_mf6a0h6q");
+                    String zbq = safeGetString(item, "numberField_mf6a0h6v");
+                    String kddh = safeGetString(item, "textField_mf6a0h6w");
+                    String mdh = safeGetString(item, "textField_mf6a0h6y");
+                    LocalDateTime yhrq = parseTimestamp(safeGetString(item, "dateField_mejnamfo"));
+
+                    table1Map.put("wlbm", wlbm);
+                    table1Map.put("detailId", detailId);
+                    table1Map.put("wlmc", wlmc);
+                    table1Map.put("ggxh", ggxh);
+                    table1Map.put("xsdw", xsdw);
+                    table1Map.put("jjsl", jjsl);
+//                    table1Map.put("count", count);
+                    table1Map.put("bz1", bz1);
+                    table1Map.put("ssxl", ssxl);
+                    table1Map.put("yhrq", yhrq);
+                    table1Map.put("sfzp", sfzp);
+                    table1Map.put("ckck", ckck);
+                    table1Map.put("ckcw", ckcw);
+                    table1Map.put("sjr", sjr);
+                    table1Map.put("sjdh", sjdh);
+                    table1Map.put("sjdz", sjdz);
+                    table1Map.put("zbq", zbq);
+                    table1Map.put("kddh", kddh);
+                    table1Map.put("mdh", mdh);
+
+                    deliveryList.add(table1Map);
+//                    detailId++;
+                }
+            }
+
+            // 构建返回数据
+            Map<String, Object> deliveryData = new HashMap<>();
+            deliveryData.put("djlx", djlx);
+            deliveryData.put("orderId", orderId);
+            deliveryData.put("rq", rq);
+            deliveryData.put("kh", kh);
+            deliveryData.put("jsbb", jsbb);
+            deliveryData.put("djbh", djbh);
+            deliveryData.put("xsbm", xsbm);
+            deliveryData.put("lllx", lllx);
+            deliveryData.put("jjr", jjr);
+            deliveryData.put("jjrdh", jjrdh);
+            deliveryData.put("jjdz", jjdz);
+            deliveryData.put("xslx", xslx);
+            deliveryData.put("bzfs", bzfs);
+            deliveryData.put("bz", bz);
+            deliveryData.put("hhsj", hhsj);
+            deliveryData.put("ysfs", ysfs);
+            deliveryData.put("hdfs", hdfs);
+            deliveryData.put("kdgs", kdgs);
+            deliveryData.put("fkfs", fkfs);
+            deliveryData.put("DeliveryList", deliveryList);
+
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+            result.put("data", deliveryData);
+// 将result转换为JSON字符串
+            String jsonStr = JSON.toJSONString(result);
+// 构建form参数
+            Map<String, Object> formParams = new HashMap<>();
+            formParams.put("jsons", jsonStr);
+            log.info("请求参数:" + formParams);
+// 发送请求
+            HttpResponse response = null;
+            if ("add".equals(action)) {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbcreatefhtzd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            } else {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            }
+
+            String responseBody = response.body();
+            log.info("返回结果responseBody:" + responseBody);
+            try {
+
+                String msg = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("msg");
+                String code = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("code");
+                ydClient.operateData(
+                        YDParam.builder()
+                                .formInstanceId(formInstId)
+                                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkz9u4p9", code, msg)))
+                                .useLatestVersion(true).build(),
+                        YDConf.FORM_OPERATION.update);
+
+            } catch (Exception e) {
+                System.out.println("解析JSON失败: " + e.getMessage());
+            }
+        } catch (Exception e) {
+            log.error("发货通知单同步异常", e);
+            result.put("table", "KD_YD_DELIVERY");
+            result.put("action", "error");
+            result.put("data", new HashMap<String, Object>() {{
+                put("errorMsg", "操作失败:" + e.getMessage());
+            }});
+        }
+
+        return result;
+    }
+
+    @Override
+    public void CfkdYdDelivery(Map map) {
         MDC.put("MDC_KEY_PID", "1003");
         String formInstId = UtilMap.getString(map, "formInstId");
-        String type = UtilMap.getString(map, "type");
-
-        if ("3".equals(type)) {
-            String bm = UtilMap.getString(map, "bm");
-            KdYdDelivery kdYdDelivery = new KdYdDelivery();
-            kdYdDelivery.setOperationType("3");
-            kdYdDeliveryMapper.update(kdYdDelivery, new LambdaQueryWrapper<KdYdDelivery>().eq(KdYdDelivery::getDjbh, bm));
-            return; // 或者根据你的业务逻辑返回相应的结果
-        }
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
-                .formInstId(formInstId)
-                .build(), YDConf.FORM_QUERY.retrieve_id);
-        Map formData = ddrNew.getFormData();
-
-        String djlx = UtilMap.getString(formData, "selectField_mg3fuqvg");
-        String orderId = UtilMap.getString(formData, "textField_mf6a0h6f");
-//        long orderId = 6L;
-        LocalDateTime rq = parseTimestamp(UtilMap.getString(formData, "dateField_krbgloam"));
-        String kh = UtilMap.getString(formData, "textField_mejnamf2");
-        String jsbb = UtilMap.getString(formData, "selectField_mg3fuqvn");
-        String djbh = UtilMap.getString(formData, "serialNumberField_mheazm7w");
-        String xsbm = UtilMap.getString(formData, "textField_krnn5bmr");
-//        String xsy = UtilMap.getString(formData, "employeeField_mejowmng").replace("[\"", "").replace("\"]", "").trim();
-        String lllx = UtilMap.getString(formData, "selectField_mejowmnc");
-        String jjr = UtilMap.getString(formData, "textField_mf6a0h5f");
-        String jjrdh = UtilMap.getString(formData, "textField_mf6a0h5g");
-        String jjdz = UtilMap.getString(formData, "textareaField_mf6a0h5h");
-        String xslx = UtilMap.getString(formData, "selectField_mgrn6p2d");
-        String bzfs = UtilMap.getString(formData, "selectField_mf6a0h5y");
-        String bz = UtilMap.getString(formData, "textareaField_mejnamfb");
-        LocalDateTime hhsj = parseTimestamp(UtilMap.getString(formData, "dateField_mf6a0h67"));
-        String ysfs = UtilMap.getString(formData, "selectField_mf6a0h5z");
-        String hdfs = UtilMap.getString(formData, "selectField_mf6a0h60");
-        String kdgs = UtilMap.getString(formData, "selectField_mf6a0h61");
-        String fkfs = UtilMap.getString(formData, "selectField_mf6a0h66");
-
-        List<Map> tableField = (List<Map>) formData.get("tableField_mejnamfd");
-        KdYdDelivery kdYdDelivery = new KdYdDelivery();
-        kdYdDelivery.setDjlx(djlx);
-        kdYdDelivery.setOrderId(orderId);
-        kdYdDelivery.setRq(rq);
-        kdYdDelivery.setKh(kh);
-        kdYdDelivery.setDjbh(djbh);
-        kdYdDelivery.setJsbb(jsbb);
-        kdYdDelivery.setSyncStatus("0");
-        kdYdDelivery.setOperationType("1");
-        kdYdDelivery.setXsbm(xsbm);
-        kdYdDelivery.setLllx(lllx);
-        kdYdDelivery.setJjr(jjr);
-        kdYdDelivery.setJjrdh(jjrdh);
-        kdYdDelivery.setJjdz(jjdz);
-        kdYdDelivery.setXslx(xslx);
-        kdYdDelivery.setBzfs(bzfs);
-        kdYdDelivery.setBz(bz);
-        kdYdDelivery.setHhsj(hhsj);
-        kdYdDelivery.setYsfs(ysfs);
-        kdYdDelivery.setHdfs(hdfs);
-        kdYdDelivery.setKdgs(kdgs);
-        kdYdDelivery.setFkfs(fkfs);
-//        kdYdDelivery.setForminstid(formInstId);
-        if ("2".equals(type)) {
-            kdYdDelivery.setOperationType(type);
-            kdYdDeliveryMapper.update(kdYdDelivery, new LambdaQueryWrapper<KdYdDelivery>().eq(KdYdDelivery::getDjbh, djbh));
-        } else {
-            kdYdDeliveryMapper.insert(kdYdDelivery);
+
+        // 查询原表单数据
+        DDR_New ddrNew = retryQueryData(
+                YDParam.builder().formInstId(formInstId).build(),
+                YDConf.FORM_QUERY.retrieve_id
+        );
+        Map formData1 = ddrNew.getFormData();
+
+        // 提取需要特殊处理的主表字段
+        String glbdjson = String.valueOf(formData1.get("associationFormField_mejmml36_id"));
+        String sqr = String.valueOf(formData1.get("employeeField_krbgloal_id"));
+        String xsy = String.valueOf(formData1.get("employeeField_mejnamf3_id"));
+        String xszg = String.valueOf(formData1.get("employeeField_mmsna3tn_id"));
+        String zssj = String.valueOf(formData1.get("employeeField_mmsna3tm_id"));
+        String fhtzd = String.valueOf(formData1.get("serialNumberField_mheazm7w"));
+
+        // 解析关联字段 JSON
+        List<Map> sealjsonlist = parseJsonList(glbdjson);
+
+
+        // 获取原表单的子表数据
+        List<Map> tableField = UtilMap.getList(formData1, "tableField_mejnamfd");
+        if (tableField == null || tableField.isEmpty()) {
+            return;
         }
 
-        Long id = kdYdDelivery.getId();
-        System.out.println("id:"+id);
-        int count = 1;
+        // 按 dz 分组
+        Map<String, List<Map>> groupedByDz = new LinkedHashMap<>();
         for (Map item : tableField) {
-            String wlbm = safeGetString(item, "textField_mejnamff");
-            String wlmc = safeGetString(item, "textField_mejnamfg");
-            String ggxh = safeGetString(item, "textField_mejnamfh");
-            String xsdw = safeGetString(item, "textField_mejnamfk");
-            int jjsl = parseInt(safeGetString(item, "numberField_mf6a0h6r"), 0); // 如果为空或格式错误,返回 0
-            String ssxl = safeGetString(item, "textField_mejnamfx");
-            String sfzp = safeGetString(item, "radioField_mf6a0h6h");
-            String ckck = safeGetString(item, "textField_mf6a0h6l");
-            String ckcw = safeGetString(item, "textField_mf6a0h6k");
-            String sjr = safeGetString(item, "textField_mejnamf6");
-            String sjdh = safeGetString(item, "textField_mejnamf7");
-            String sjdz = safeGetString(item, "textareaField_mf6a0h5e");
-            String zbq = safeGetString(item, "numberField_mf6a0h6v");
-            String kddh = safeGetString(item, "textField_mf6a0h6w");
-            String mdh = safeGetString(item, "textField_mf6a0h6y");
-            KdYdDeliveryDetail kdYdDeliveryDetail = new KdYdDeliveryDetail();
-            kdYdDeliveryDetail.setDeliveryId(id);
-            kdYdDeliveryDetail.setWlbm(wlbm);
-            kdYdDeliveryDetail.setWlmc(wlmc);
-            kdYdDeliveryDetail.setGgxh(ggxh);
-            kdYdDeliveryDetail.setDetailId(count);
-            kdYdDeliveryDetail.setXsdw(xsdw);
-            kdYdDeliveryDetail.setJjsl(jjsl);
-            kdYdDeliveryDetail.setSsxl(ssxl);
-            kdYdDeliveryDetail.setYhrq(parseTimestamp(safeGetString(item, "dateField_mejnamfo")));
-            kdYdDeliveryDetail.setGgxh(ggxh);
-            kdYdDeliveryDetail.setSfzp(sfzp);
-            kdYdDeliveryDetail.setCkck(ckck);
-            kdYdDeliveryDetail.setCkcw(ckcw);
-            kdYdDeliveryDetail.setSjr(sjr);
-            kdYdDeliveryDetail.setSjdh(sjdh);
-            kdYdDeliveryDetail.setSyncStatus("0");
-            kdYdDeliveryDetail.setOperationType("1");
-            kdYdDeliveryDetail.setSjdz(sjdz);
-            kdYdDeliveryDetail.setZbq(zbq);
-            kdYdDeliveryDetail.setKddh(kddh);
-            kdYdDeliveryDetail.setMdh(mdh);
-            if ("2".equals(type) || "3".equals(type)) {
-                kdYdDeliveryDetail.setOperationType(type);
-                kdYdDeliveryDetailMapper.update(kdYdDeliveryDetail, new LambdaQueryWrapper<KdYdDeliveryDetail>()
-                        .eq(KdYdDeliveryDetail::getWlbm, wlbm)
-                        .eq(KdYdDeliveryDetail::getDeliveryId, id));
-            } else {
-                kdYdDeliveryDetailMapper.insert(kdYdDeliveryDetail);
+            String dz = UtilMap.getString(item, "textareaField_mf6a0h5e");
+            if (dz == null) dz = "";
+            groupedByDz.computeIfAbsent(dz, k -> new ArrayList<>()).add(item);
+        }
+
+        // 对每个 dz 分组,创建一条新表单
+        for (Map.Entry<String, List<Map>> entry : groupedByDz.entrySet()) {
+            String dz = entry.getKey();
+            List<Map> subTableRows = entry.getValue();
+
+            // 构建新子表数据
+            List<Map> newSubTable = new ArrayList<>();
+            for (Map row : subTableRows) {
+                newSubTable.add(new HashMap<>(row));
+            }
+
+            // 构建新表单的formData
+            HashMap<String, Object> updateMap = new HashMap<>();
+
+            // 1. 首先复制原表单的所有主表数据
+            for (Object obj : formData1.entrySet()) {
+                Map.Entry<String, Object> formEntry = (Map.Entry<String, Object>) obj;
+                String key = formEntry.getKey();
+                Object value = formEntry.getValue();
+
+                // 跳过不需要特殊处理的子表字段
+                if ("tableField_mejnamfd".equals(key)) {
+                    continue;
+                }
+
+                // 跳过需要特殊处理的主表关联字段
+                if (key.equals("associationFormField_mejmml36_id") ||
+                        key.equals("associationFormField_mfavc4ve_id") ||
+                        key.equals("associationFormField_mk0gzflu_id") ||
+                        key.equals("employeeField_krbgloal_id") ||
+                        key.equals("employeeField_mejnamf3_id") ||
+                        key.equals("employeeField_mmsna3tn_id") ||
+                        key.equals("employeeField_mmsna3tm_id") ||
+                        key.equals("serialNumberField_mheazm7w")) {
+                    continue;
+                }
+
+                // 复制其他字段
+                updateMap.put(key, value);
             }
 
-            count++;
-//save(kdYdDeliveryDetail);
+            // 2. 添加需要特殊处理的主表字段
+            updateMap.put("associationFormField_mejmml36", sealjsonlist);
+//            updateMap.put("associationFormField_mfavc4ve", khjsonlist);
+            updateMap.put("associationFormField_mk0gzflu", Arrays.asList(getfhdAss(fhtzd, formInstId)));
+            updateMap.put("employeeField_krbgloal", sqr);
+            updateMap.put("employeeField_mejnamf3", xsy);
+            updateMap.put("employeeField_mmsna3tn", xszg);
+            updateMap.put("employeeField_mmsna3tm", zssj);
+            updateMap.put("textField_mjzk47so", fhtzd);
+            // 3. 添加处理后的子表数据
+            updateMap.put("tableField_mejnamfd", newSubTable);
+            String sqrid = sqr.substring(2, sqr.length() - 2);
+            System.out.println("sqrid==" + sqrid);
+            // 创建新表单实例
+            try {
+                retryOperateData(
+                        YDParam.builder()
+                                .formUuid("FORM-FAE2575E112644ED914CAB4FEC9309F32AVR")
+                                .formDataJson(JSON.toJSONString(updateMap))
+                                .userId(sqrid)
+                                .build(),
+                        YDConf.FORM_OPERATION.create
+                );
+
+            } catch (Exception e) {
+                log.error("创建新单据失败,dz=" + dz, e);
+            }
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                log.error("线程被中断", e);
+            }
         }
-//        ydClient.operateData(
-//                YDParam.builder()
-//                        .formInstanceId(formInstId)
-//                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mgrqnxmm", id)))
-//                        .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
     }
+
+    // 工具方法:安全解析 JSON 列表(处理宜搭返回的带引号字符串)
+    private List<Map> parseJsonList(String jsonStr) {
+        if (jsonStr == null || "null".equals(jsonStr) || jsonStr.isEmpty()) {
+            return Collections.emptyList();
+        }
+        try {
+            // 宜搭有时返回的是 "\"[{...}]\"",需先 unescape
+            String clean = StringEscapeUtils.unescapeJava(jsonStr);
+            // 如果首尾是双引号,去掉
+            if (clean.startsWith("\"") && clean.endsWith("\"")) {
+                clean = clean.substring(1, clean.length() - 1);
+            }
+            return (List<Map>) JSONArray.parse(clean);
+        } catch (Exception e) {
+
+            return Collections.emptyList();
+        }
+    }
+
+    private Object getfhdAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-A7F03ACEE01D4F609550C86BF7FE87D35M6I", "receipt", id, title, "");
+    }
+
     private static LocalDateTime parseTimestamp(String timestampStr) {
         if (timestampStr == null || timestampStr.trim().isEmpty()) return null;
         try {
@@ -184,6 +413,7 @@ public class KdYdDeliveryServiceImpl extends ServiceImpl<KdYdDeliveryMapper, KdY
             return null;
         }
     }
+
     private static int parseInt(String str, int defaultValue) {
         if (str == null || str.trim().isEmpty()) {
             return defaultValue;
@@ -194,10 +424,12 @@ public class KdYdDeliveryServiceImpl extends ServiceImpl<KdYdDeliveryMapper, KdY
             return defaultValue;
         }
     }
+
     private String safeGetString(Map formData, String key) {
         Object val = formData.get(key);
         return val == null ? "" : String.valueOf(val);
     }
+
     public static BigDecimal toBigDecimal(String str) {
         if (str == null || str.trim().isEmpty()) {
             return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
@@ -221,4 +453,77 @@ public class KdYdDeliveryServiceImpl extends ServiceImpl<KdYdDeliveryMapper, KdY
         return new BigDecimal(number.toString())
                 .setScale(2, RoundingMode.HALF_UP);
     }
+
+    //自带重试的operateData方法
+    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        Object result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.operateData(param, formOperation);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_OPERATION:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formOperation,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}", JSONObject.toJSONString(param), formOperation,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_OPERATION:{}"+formOperation);
+    }
+
+
+    //自带重试的queryData方法
+    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        DDR_New result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.queryData(param, formQuery);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_QUERY:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formQuery,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_QUERY:{},异常信息:{}", JSONObject.toJSONString(param), formQuery,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_QUERY:{}"+formQuery);
+    }
 }

+ 347 - 2
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdMaterialServiceImpl.java

@@ -1,5 +1,7 @@
 package com.malk.huagao.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.malk.huagao.entity.KdYdCustomer;
 import com.malk.huagao.entity.KdYdMaterial;
 import com.malk.huagao.mapper.KdYdMaterialMapper;
@@ -7,16 +9,19 @@ import com.malk.huagao.service.IKdYdMaterialService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
+import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McException;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.Map;
+import java.util.*;
 
 /**
  * <p>
@@ -27,6 +32,7 @@ import java.util.Map;
  * @since 2025-10-16
  */
 @Service
+@Slf4j
 public class KdYdMaterialServiceImpl extends ServiceImpl<KdYdMaterialMapper, KdYdMaterial> implements IKdYdMaterialService {
     @Autowired
     private YDClient ydClient;
@@ -36,7 +42,7 @@ public class KdYdMaterialServiceImpl extends ServiceImpl<KdYdMaterialMapper, KdY
     public void insertkdYdMaterial(Map map) {
         MDC.put("MDC_KEY_PID", "1003");
         String formInstId = UtilMap.getString(map, "formInstId");
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+        DDR_New ddrNew = retryQueryData(YDParam.builder()
                 .formInstId(formInstId)
                 .build(), YDConf.FORM_QUERY.retrieve_id);
         Map formData = ddrNew.getFormData();
@@ -88,6 +94,273 @@ public class KdYdMaterialServiceImpl extends ServiceImpl<KdYdMaterialMapper, KdY
 
        
     }
+
+    @Override
+    public Map<String, Object> addkdYdMaterial(Map json) {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+
+            // 查询需要删除的数据
+            List<Map<String, Object>> kdYdMaterialdels = UtilMap.getList(json ,"data");
+            String action = json.get("action").toString();
+            String table = json.get("table").toString();
+
+            // 批量删除处理
+            if (!kdYdMaterialdels.isEmpty() && action.equals("del") && table.equals("KD_YD_MATERIAL")) {
+                log.info("开始处理删除操作,共{}条数据", kdYdMaterialdels.size());
+                ArrayList<String> list = new ArrayList<>();
+
+                for (Map item : kdYdMaterialdels) {
+                    try {
+                        // 修复:使用安全的方式转换FMATERIALID
+                        Object fmaterialidObj = item.get("FMATERIALID");
+                        String fmaterialidStr = String.valueOf(fmaterialidObj);
+
+                        List<Map> list1 = (List<Map>) retryQueryData(YDParam.builder()
+                                .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+                                .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                                .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                                .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_misfb2ft", fmaterialidStr)))
+                                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                        if (list1 != null && !list1.isEmpty()) {
+                            for (Map map : list1) {
+                                String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                                if (formInstanceId != null) {
+                                    list.add(formInstanceId);
+                                    log.info("找到待删除的表单实例: formInstanceId={}", formInstanceId);
+                                }
+                            }
+                        } else {
+                            log.info("未找到对应的物料数据: fmaterialid={}", fmaterialidStr);
+                        }
+
+                    } catch (Exception e) {
+                        log.info("删除物料数据查询异常: FMATERIALID={}", item.get("FMATERIALID"), e);
+                    }
+                }
+
+                // 执行批量删除
+                if (!list.isEmpty()) {
+                    try {
+                        Object deleteResult = retryOperateData(YDParam.builder()
+                                .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+                                .formInstanceIdList(list)
+                                .build(), YDConf.FORM_OPERATION.delete_batch);
+                        // 返回删除结果
+                        result.put("code", "200");
+                        result.put("msg", "删除成功,共删除" + list.size() + "条数据");
+                        result.put("data", new HashMap<String, Object>() {{
+                            put("deleteResult", "删除成功");
+                            put("deletedCount", list.size());
+                            put("deletedIds", list);
+                        }});
+                        return result;
+
+                    } catch (Exception e) {
+                        log.error("批量删除操作异常", e);
+                        result.put("code", "500");
+                        result.put("msg", "批量删除操作异常:" + e.getMessage());
+                        result.put("data", new HashMap<>());
+                        return result;
+                    }
+                } else {
+                    result.put("code", "200");
+                    result.put("msg", "未找到需要删除的数据");
+                    result.put("data", new HashMap<>());
+                    return result;
+                }
+            }
+
+            List<Map<String, Object>> kdYdMaterials = UtilMap.getList(json ,"data");
+            // 同步新增/更新数据
+            if (kdYdMaterials.isEmpty()) {
+                log.info("【物料单同步任务】无需要同步的数据,结束");
+                result.put("code", "200");
+                result.put("msg", "无需要同步的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            // 存储所有操作的结果
+            List<Map<String, Object>> operationResults = new ArrayList<>();
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map kdYdMaterial : kdYdMaterials) {
+                Map<String, Object> singleResult = new HashMap<>();
+
+                try {
+                    // 修复:安全地获取所有字段值
+                    String wlbm = safeGetStringValue(kdYdMaterial, "wlbm");
+                    String wlmc = safeGetStringValue(kdYdMaterial, "wlmc");
+                    String xh = safeGetStringValue(kdYdMaterial, "xh");
+                    String gg = safeGetStringValue(kdYdMaterial, "gg");
+                    String kssj = safeGetStringValue(kdYdMaterial, "kssj");
+                    String jzsj = safeGetStringValue(kdYdMaterial, "jzsj");
+
+                    // 修复:安全处理FMATERIALID,可能为字符串或数字
+                    Object fmaterialidObj = kdYdMaterial.get("FMATERIALID");
+                    String fmaterialidStr = String.valueOf(fmaterialidObj);
+
+                    String wlfz = safeGetStringValue(kdYdMaterial, "wlfz");
+                    String wlsx = safeGetStringValue(kdYdMaterial, "wlsx");
+                    String jbdw = safeGetStringValue(kdYdMaterial, "jbdw");
+                    String ssxl = safeGetStringValue(kdYdMaterial, "ssxl");
+                    String jx = safeGetStringValue(kdYdMaterial, "jx");
+
+                    // 修复:安全处理sd字段
+                    Object sdObj = kdYdMaterial.get("sd");
+                    Integer sd = null;
+                    if (sdObj != null) {
+                        try {
+                            if (sdObj instanceof Integer) {
+                                sd = (Integer) sdObj;
+                            } else if (sdObj instanceof String) {
+                                sd = Integer.parseInt((String) sdObj);
+                            } else if (sdObj instanceof Number) {
+                                sd = ((Number) sdObj).intValue();
+                            }
+                        } catch (Exception e) {
+                            log.warn("无法解析sd字段: {}", sdObj);
+                        }
+                    }
+
+                    String mrsl = safeGetStringValue(kdYdMaterial, "mrsl");
+                    String chlb = safeGetStringValue(kdYdMaterial, "chlb");
+                    String xsy = safeGetStringValue(kdYdMaterial, "xsy");
+
+                    // 修复:安全处理xsjzj字段
+                    Object xsjzjObj = kdYdMaterial.get("xsjzj");
+                    BigDecimal xsjzj = null;
+                    if (xsjzjObj != null) {
+                        try {
+                            if (xsjzjObj instanceof BigDecimal) {
+                                xsjzj = (BigDecimal) xsjzjObj;
+                            } else if (xsjzjObj instanceof String) {
+                                xsjzj = new BigDecimal((String) xsjzjObj);
+                            } else if (xsjzjObj instanceof Number) {
+                                xsjzj = new BigDecimal(xsjzjObj.toString());
+                            }
+                        } catch (Exception e) {
+                            log.warn("无法解析xsjzj字段: {}", xsjzjObj);
+                        }
+                    }
+
+                    String smzs = safeGetStringValue(kdYdMaterial, "smzs");
+                    String sjzt = safeGetStringValue(kdYdMaterial, "sjzt");
+                    String jyzt = safeGetStringValue(kdYdMaterial, "jyzt");
+                    String dzl = safeGetStringValue(kdYdMaterial, "dzl");
+                    String wlzl = safeGetStringValue(kdYdMaterial, "wlzl");
+                    String pzzt = safeGetStringValue(kdYdMaterial, "pzzt");
+                    String sdbb = safeGetStringValue(kdYdMaterial, "sdbb");
+                    String wlbt = wlmc + wlbm;
+
+                    Map updateFormData = new HashMap();
+                    updateFormData.put("textField_l43jpnsf", wlmc);
+                    updateFormData.put("textField_mfxbtcdh", wlbm);
+                    updateFormData.put("textField_l43jpnsg", xh);
+                    updateFormData.put("textField_lqbxkzbq", gg);
+                    updateFormData.put("textField_misfb2ft", fmaterialidStr); // 使用字符串类型
+                    updateFormData.put("textField_mhlbx8hi", wlfz);
+                    updateFormData.put("textField_l43jpnsh", wlsx);
+                    updateFormData.put("textField_mfxbtcdo", jbdw);
+                    updateFormData.put("textField_mfxbtcdp", ssxl);
+                    updateFormData.put("textField_mejl9nrs", jx);
+                    updateFormData.put("dateField_ml4ikfa0", kssj);
+                    updateFormData.put("dateField_ml4ikfa1", jzsj);
+                    updateFormData.put("textField_mfxbtce6", sjzt);
+
+                    if (sd != null) {
+                        updateFormData.put("numberField_mfxbtceb", sd);
+                    } else {
+                        updateFormData.put("numberField_mfxbtceb", 0);
+                    }
+
+                    updateFormData.put("textField_mejl9nrp", dzl);
+                    updateFormData.put("selectField_mejl9nrq", pzzt);
+                    updateFormData.put("textField_mfxbtcdq", mrsl);
+                    updateFormData.put("textField_mhabp7y0", sdbb);
+                    updateFormData.put("textField_mfxbtcdr", chlb);
+                    updateFormData.put("textField_mfxbtce5", xsy);
+
+                    // 确保金额字段保留两位小数
+                    if (xsjzj != null) {
+                        updateFormData.put("numberField_mejl9nsc", xsjzj.setScale(2, java.math.RoundingMode.HALF_UP));
+                    } else {
+                        updateFormData.put("numberField_mejl9nsc", java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP));
+                    }
+
+                    updateFormData.put("textField_mfxbtce4", smzs);
+                    updateFormData.put("textField_mfxbtcea", jyzt);
+                    updateFormData.put("textField_mg4h6mz5", wlbt);
+
+                    // 执行操作并获取结果
+                    Object operationResult = retryOperateData(YDParam.builder()
+                            .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
+                            .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                            .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                            .searchCondition(JSONObject.toJSONString(Arrays.asList(new YDSearch(
+                                    "textField_misfb2ft", fmaterialidStr, "金蝶内码", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ))))
+                            .formDataJson(JSONObject.toJSONString(updateFormData))
+                            .build(), YDConf.FORM_OPERATION.upsert);
+
+                    log.info("物料单同步成功: wlbm={}, wlmc={}", wlbm, wlmc);
+
+                    // 记录单个操作结果
+                    singleResult.put("FMATERIALID", fmaterialidStr);
+                    singleResult.put("operationResult", operationResult);
+                    singleResult.put("status", "success");
+                    successCount++;
+
+                } catch (Exception e) {
+                    log.error("物料单同步失败", e);
+
+                    // 修复:安全获取FMATERIALID
+                    Object fmaterialidObj = kdYdMaterial.get("FMATERIALID");
+                    String fmaterialidStr = fmaterialidObj != null ? String.valueOf(fmaterialidObj) : "unknown";
+
+                    singleResult.put("FMATERIALID", fmaterialidStr);
+                    singleResult.put("errorMsg", e.getMessage());
+                    singleResult.put("status", "fail");
+                    failCount++;
+                }
+
+                operationResults.add(singleResult);
+            }
+
+            // 构建返回结果
+            Map<String, Object> data = new HashMap<>();
+            data.put("operationResults", operationResults);
+            data.put("totalCount", kdYdMaterials.size());
+            data.put("successCount", successCount);
+            data.put("failCount", failCount);
+
+            result.put("code", failCount == 0 ? "200" : "300");
+            result.put("msg", "操作完成,成功" + successCount + "条,失败" + failCount + "条");
+            result.put("data", data);
+
+            return result;
+
+        } catch (Exception e) {
+            log.error("物料单同步任务执行异常", e);
+            result.put("code", "500");
+            result.put("msg", "系统异常:" + e.getMessage());
+            result.put("data", new HashMap<>());
+            return result;
+        }
+    }
+
+    // 辅助方法:安全获取字符串值
+    private String safeGetStringValue(Map map, String key) {
+        if (map == null) return "";
+        Object value = map.get(key);
+        if (value == null) return "";
+        return String.valueOf(value);
+    }
+
     private static int parseInt(String str, int defaultValue) {
         if (str == null || str.trim().isEmpty()) {
             return defaultValue;
@@ -125,4 +398,76 @@ public class KdYdMaterialServiceImpl extends ServiceImpl<KdYdMaterialMapper, KdY
         return new BigDecimal(number.toString())
                 .setScale(2, RoundingMode.HALF_UP);
     }
+    //自带重试的operateData方法
+    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        Object result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.operateData(param, formOperation);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_OPERATION:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formOperation,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}", JSONObject.toJSONString(param), formOperation,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_OPERATION:{}"+formOperation);
+    }
+
+
+    //自带重试的queryData方法
+    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        DDR_New result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.queryData(param, formQuery);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_QUERY:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formQuery,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_QUERY:{},异常信息:{}", JSONObject.toJSONString(param), formQuery,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_QUERY:{}"+formQuery);
+    }
 }

+ 744 - 176
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdOrderServiceImpl.java

@@ -1,6 +1,9 @@
 package com.malk.huagao.service.impl;
 
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -13,23 +16,28 @@ import com.malk.huagao.service.IKdYdOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
+import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McException;
+import com.malk.server.common.McR;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * <p>
@@ -40,6 +48,7 @@ import java.util.Map;
  * @since 2025-10-15
  */
 @Service
+@Slf4j
 public class KdYdOrderServiceImpl extends ServiceImpl<KdYdOrderMapper, KdYdOrder> implements IKdYdOrderService {
     @Autowired
     private YDClient ydClient;
@@ -49,191 +58,677 @@ public class KdYdOrderServiceImpl extends ServiceImpl<KdYdOrderMapper, KdYdOrder
     private KdYdOrderDetailMapper kdYdOrderDetailMapper;
     @Autowired
     private KdYdOrderPaymentMapper kdYdOrderPaymentMapper;
+    @Value(value = "${kd.host}")
+    private String kdHost;
 
+    @Override
+    public Map<String, Object> insertkdYdOrder(Map map) {
+        Map<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            String formInstId = UtilMap.getString(map, "formInstId");
+            String type = UtilMap.getString(map, "type");
+
+            // 处理特殊操作类型
+            if ("del".equals(type)) {
+                String bm = UtilMap.getString(map, "bm");
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+                Map<String, Object> formParams = new HashMap<>();
+                Map<String, Object> djbh = new HashMap<>();
+                djbh.put("djbh", bm);
+                result.put("data", djbh);
+                String jsonStr = JSON.toJSONString(result);
+
+                formParams.put("jsons", jsonStr);
+
+                System.out.println("====" + formParams);
+                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbdeletexsdd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+
+                String responseBody = response.body();
+                // 返回删除操作的格式
+                result.put("table", "KD_YD_ORDER");
+                result.put("action", "del");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("bm", bm);  // 删除的主键或标识
+                    put("msg", "删除成功");
+                }});
+                return result;
+            }
+
+            if ("cancel".equals(type)) {
+                String bm = UtilMap.getString(map, "bm");
+                Map<String, String> headers = new HashMap<>();
+                headers.put("Content-Type", "application/x-www-form-urlencoded");
+                Map<String, Object> formParams = new HashMap<>();
+                Map<String, Object> djbh = new HashMap<>();
+                djbh.put("djbh", bm);
+                result.put("data", djbh);
+                String jsonStr = JSON.toJSONString(result);
+                System.out.println("==" + jsonStr);
+                formParams.put("jsons", jsonStr);
+                HttpResponse response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbExcuteOperationxsdd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+
+                String responseBody = response.body();
+                String msg = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("msg");
+                String code = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("code");
+                retryOperateData(
+                        YDParam.builder()
+                                .formInstanceId(formInstId)
+                                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkxqgrvq", code, msg)))
+                                .useLatestVersion(true).build(),
+                        YDConf.FORM_OPERATION.update);
+                // 返回作废操作的格式
+                result.put("table", "KD_YD_ORDER");
+                result.put("action", "cancel"); // 作废通常是修改状态
+                result.put("data", new HashMap<String, Object>() {{
+                    put("bm", bm); // 作废状态
+                    put("msg", "作废成功");
+                    // 其他作废需要的数据
+                }});
+                return result;
+            }
+
+            // 查询表单数据
+            DDR_New ddrNew = retryQueryData(YDParam.builder()
+                    .formInstId(formInstId)
+                    .build(), YDConf.FORM_QUERY.retrieve_id);
+            Map formData = ddrNew.getFormData();
+
+            // 提取主表字段
+            String djlx = UtilMap.getString(formData, "selectField_mejowmna");
+            String khmc = UtilMap.getString(formData, "textField_mejnamf2");
+//            String khmc = "五岳";
+//            String djbh = UtilMap.getString(formData, "textField_mjs6fuwo");
+
+            // 判断操作类型对应的action
+            String actionType;
+            String djbh = null;
+            if ("edit".equals(type)) {
+//                djbh = UtilMap.getString(formData, "textField_mjs6fuwo");
+                djbh = UtilMap.getString(formData, "textField_miwvnkep");
+                actionType = "edit";
+            } else {
+                actionType = "add";
+                djbh = "";
+            }
+
+            // 提取其他字段...
+            LocalDateTime rq = parseTimestamp(UtilMap.getString(formData, "dateField_mejowmnb"));
+            String khxypj = UtilMap.getString(formData, "selectField_mewirdx4");
+            String ywlx = UtilMap.getString(formData, "textField_mfxv2vfz");
+            String xsy = UtilMap.getString(formData, "employeeField_mejowmng").replace("[\"", "").replace("\"]", "").trim();
+            String xslx = UtilMap.getString(formData, "selectField_mejowmnc");
+            String bzq = UtilMap.getString(formData, "selectField_mf6gyfkq");
+            String xsbm = UtilMap.getString(formData, "departmentSelectField_mfxv2vfu").replace("[\"", "").replace("\"]", "").trim();
+            String bz = UtilMap.getString(formData, "textareaField_mejnamfb");
+            String jsbb = UtilMap.getString(formData, "selectField_mejowmnk");
+            String sktj = UtilMap.getString(formData, "selectField_mgisux07");
+            String zdzkestr = UtilMap.getString(formData, "numberField_mejowmni");
+            BigDecimal zdzke = toBigDecimal(zdzkestr);
+            String sestr = UtilMap.getString(formData, "numberField_mfxv2vgh");
+            BigDecimal se = toBigDecimal(sestr);
+            String jestr = UtilMap.getString(formData, "numberField_mfxv2vgj");
+            BigDecimal je = toBigDecimal(jestr);
+            String jshjstr = UtilMap.getString(formData, "numberField_mewfgzkv");
+            BigDecimal jshj = toBigDecimal(jshjstr);
+            String sfhs = UtilMap.getString(formData, "radioField_mfxv2vg4");
+            String jws = UtilMap.getString(formData, "radioField_mfxv2vgm");
+            List<Map> tableField = (List<Map>) formData.get("tableField_mfbx1pqi");
+            List<Map> tableFieldPayment = (List<Map>) formData.get("tableField_mhiui6v5");
+
+            // 处理订单明细
+            List<Map<String, Object>> orderList = new ArrayList<>();
+            if (tableField != null) {
+                for (int i = 0; i < tableField.size(); i++) {
+                    Map item = tableField.get(i);
+                    Map<String, Object> table1Map = new HashMap<>();
+
+                    int detailId = parseInt(safeGetString(item, "numberField_mjzfodew"), 1);
+                    String wlbm = safeGetString(item, "textField_mfbx1pqt");
+//                    String wlbm = "010101010003";
+                    String wlmc = safeGetString(item, "textField_mfbx1pqs");
+                    String ggxh = safeGetString(item, "textField_mfbx1pqr");
+                    String xsdw = safeGetString(item, "textField_mfbx1pqq");
+                    int xssl = parseInt(safeGetString(item, "numberField_mfbx1pr4"), 0);
+                    String ssxl = safeGetString(item, "selectField_mfbx1pr1");
+                    BigDecimal dj = toBigDecimal(safeGetString(item, "numberField_mfbx1prf"));
+                    BigDecimal cxzkje = toBigDecimal(safeGetString(item, "numberField_mk56soin"));
+                    BigDecimal hsdj = toBigDecimal(safeGetString(item, "numberField_mfbx1prg"));
+                    String sfzp = safeGetString(item, "radioField_mfbx1prc");
+                    String bz1 = safeGetString(item, "textareaField_mjryuaok");
+                    int sl = parseInt(safeGetString(item, "numberField_mfbx1prb"), 0);
+                    BigDecimal zse = toBigDecimal(safeGetString(item, "numberField_mfbx1prh"));
+                    BigDecimal zje = toBigDecimal(safeGetString(item, "numberField_mfbx1pri"));
+                    BigDecimal zjshj = toBigDecimal(safeGetString(item, "numberField_mfbx1prj"));
+                    BigDecimal jj = toBigDecimal(safeGetString(item, "numberField_mfbx1prk"));
+                    BigDecimal zkl = toBigDecimal(safeGetString(item, "numberField_mfbx1pru"));
+                    BigDecimal zke = toBigDecimal(safeGetString(item, "numberField_mfbx1prt"));
+                    LocalDateTime yhrq = parseTimestamp(UtilMap.getString(item, "dateField_mfbx1prs"));
+                    BigDecimal xsjzj = toBigDecimal(safeGetString(item, "numberField_mfbx1pr0"));
+                    String zmzs = safeGetString(item, "textField_mfxv2vgv");
+
+                    // 设置明细字段
+                    table1Map.put("detailId", detailId);
+                    table1Map.put("wlbm", wlbm);
+                    table1Map.put("wlmc", wlmc);
+                    table1Map.put("ggxh", ggxh);
+                    table1Map.put("xsdw", xsdw);
+                    table1Map.put("xssl", xssl);
+                    table1Map.put("ssxl", ssxl);
+                    table1Map.put("dj", dj);
+                    table1Map.put("cxzkje", cxzkje);
+                    table1Map.put("hsdj", hsdj);
+                    table1Map.put("sfzp", sfzp);
+                    table1Map.put("bz", bz1);
+                    table1Map.put("sl", sl);
+                    table1Map.put("se1", zse);
+                    table1Map.put("je1", zje);
+                    table1Map.put("jshj1", zjshj);
+                    table1Map.put("jj", jj);
+                    table1Map.put("zkl", zkl);
+                    table1Map.put("zke", zke);
+                    table1Map.put("xsjzj", xsjzj);
+                    table1Map.put("zmzs", zmzs);
+                    table1Map.put("yhrq", yhrq);
+
+                    orderList.add(table1Map);
+                }
+            }
+
+            // 处理付款明细
+            List<Map<String, Object>> OrderPayList = new ArrayList<>();
+            if (tableFieldPayment != null) {
+                for (int i = 0; i < tableFieldPayment.size(); i++) {
+                    Map row = tableFieldPayment.get(i);
+                    Map<String, Object> table2Map = new HashMap<>();
+                    int detailId = i + 1;
+
+                    String sfys = safeGetString(row, "radioField_mhiui6v7");
+//                    String sjyskzfh = safeGetString(row, "radioField_ml7hg2oi");
+                    String gldh = safeGetString(row, "textField_mhiui6va");
+                    BigDecimal ysbl = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6v6"));
+                    BigDecimal ysje = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6v8"));
+                    BigDecimal ssje = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6vb"));
+                    LocalDateTime endTime = parseTimestamp(UtilMap.getString(row, "dateField_mhiui6v9"));
+
+                    table2Map.put("detailId", detailId);
+                    table2Map.put("sfys", sfys);
+//                    table2Map.put("sjyskzfh", sjyskzfh);
+                    table2Map.put("gldh", gldh);
+                    table2Map.put("ysbl", ysbl);
+                    table2Map.put("ysje", ysje);
+                    table2Map.put("ssje", ssje);
+                    table2Map.put("endTime", endTime);
+
+                    OrderPayList.add(table2Map);
+                }
+            }
+
+            // 构建主表数据,映射到数据库表字段
+            Map<String, Object> orderData = new HashMap<>();
+
+            // 注意:这里需要将字段名映射到数据库表字段名
+            // 示例映射,实际需要根据数据库表结构调整
+            orderData.put("djlx", djlx);                    // 单据类型
+            orderData.put("djbh", djbh);                    // 单据编号
+            orderData.put("khmc", khmc);                    // 客户名称
+            orderData.put("rq", rq);                        // 日期
+            orderData.put("khxypj", khxypj);                // 客户信用评级
+            orderData.put("ywlx", ywlx);                    // 业务类型
+            orderData.put("xslx", xslx);                    // 销售类型
+            orderData.put("bzq", bzq);                      // 保质期
+            orderData.put("xsy", xsy);                      // 销售员
+            orderData.put("xsbm", xsbm);                    // 销售部门
+            orderData.put("bz", bz);                        // 备注
+            orderData.put("jsbb", jsbb);                    // 结算币别
+            orderData.put("sktj", sktj);                    // 收款条件
+            orderData.put("zdzke", zdzke);                  // 整单折扣额
+            orderData.put("se", se);                        // 税额
+            orderData.put("je", je);                        // 金额
+            orderData.put("jshj", jshj);                    // 价税合计
+            orderData.put("sfhs", sfhs);                    // 是否含税
+            orderData.put("jws", jws);                      // 价位税
+
+            // 明细数据(需要根据实际数据库设计确定存储方式)
+            // 如果明细是单独的表,可能需要单独处理
+            orderData.put("OrderDetailList", orderList);         // 订单明细列表
+            orderData.put("PaymentDetailList", OrderPayList);    // 付款明细列表
+
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+            result.put("data", orderData);
+// 将result转换为JSON字符串
+            String jsonStr = JSON.toJSONString(result);
+// 构建form参数
+            Map<String, Object> formParams = new HashMap<>();
+            formParams.put("jsons", jsonStr);
+            log.info("订单请求参数:" + formParams);
+// 发送请求
+            HttpResponse response = null;
+            if ("add".equals(actionType)) {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbxsdd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            } else {
+                response = HttpRequest.post(kdHost+"/xk/dyzn/WsBasedyzn.asmx/hgdjydtbupdatexsdd")
+                        .headerMap(headers, true)
+                        .form(formParams)
+                        .timeout(30000)  // 30秒超时
+                        .execute();
+            }
+
+            String responseBody = response.body();
+            log.info("返回结果responseBody: " + responseBody);
+            try {
+                // 一行代码提取
+                String jdbh = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getJSONObject("data")
+                        .getString("djbh");
+                String msg = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("msg");
+                String code = JSON.parseArray(responseBody)
+                        .getJSONObject(0)
+                        .getString("code");
+                retryOperateData(
+                        YDParam.builder()
+                                .formInstanceId(formInstId)
+                                .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_ml08nk3y, textareaField_mkxqgrvq, textField_mjs6fuwo", code, msg, jdbh)))
+                                .useLatestVersion(true).build(),
+                        YDConf.FORM_OPERATION.update);
+
+            } catch (Exception e) {
+                System.out.println("解析JSON失败: " + e.getMessage());
+            }
+        } catch (Exception e) {
+            // 异常处理
+            result.put("table", "KD_YD_SALE_ORDER");
+            result.put("action", "error");
+            result.put("data", new HashMap<String, Object>() {{
+                put("errorMsg", "操作失败:" + e.getMessage());
+            }});
+            // 可以添加日志记录
+            // log.error("insertkdYdOrder error", e);
+        }
+
+        return result;
+    }
 
     @Override
-    public void insertkdYdOrder(Map map) {
+    public void SckdYdOrder(Map map) {
         MDC.put("MDC_KEY_PID", "1003");
-        String formInstId = UtilMap.getString(map, "formInstId");
-        String type = UtilMap.getString(map, "type");
-
-        if ("3".equals(type)) {
-            String bm = UtilMap.getString(map, "bm");
-            KdYdOrder kdYdOrder = new KdYdOrder();
-            kdYdOrder.setOperationType("3");
-            kdYdOrderMapper.update(kdYdOrder, new LambdaQueryWrapper<KdYdOrder>().eq(KdYdOrder::getDjbh, bm));
-            return; // 或者根据你的业务逻辑返回相应的结果
-        }
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
-                .formInstId(formInstId)
-                .build(), YDConf.FORM_QUERY.retrieve_id);
-        Map formData = ddrNew.getFormData();
-
-        String djlx = UtilMap.getString(formData, "selectField_mejowmna");
-        String khmc = UtilMap.getString(formData, "textField_mejnamf2");
-        String djbh = UtilMap.getString(formData, "serialNumberField_mewfgzku");
-        LocalDateTime rq = parseTimestamp(UtilMap.getString(formData, "dateField_mejowmnb"));
-        String khxypj = UtilMap.getString(formData, "selectField_mewirdx4");
-        String ywlx = UtilMap.getString(formData, "textField_mfxv2vfz");
-        String xsy = UtilMap.getString(formData, "employeeField_mejowmng").replace("[\"", "").replace("\"]", "").trim();
-        String xslx = UtilMap.getString(formData, "selectField_mejowmnc");
-        String bzq = UtilMap.getString(formData, "selectField_mf6gyfkq");
-        String xsbm = UtilMap.getString(formData, "departmentSelectField_mfxv2vfu").replace("[\"", "").replace("\"]", "").trim();
-        String bz = UtilMap.getString(formData, "textareaField_mejnamfb");
-        String jsbb = UtilMap.getString(formData, "selectField_mejowmnk");
-        String sktj = UtilMap.getString(formData, "selectField_mgisux07");
-        String zdzkestr = UtilMap.getString(formData, "numberField_mejowmni");
-        BigDecimal zdzke = toBigDecimal(zdzkestr);
-//        String fj = UtilMap.getString(formData, "attachmentField_mfoqcctz");
-//        JSONArray array = JSONObject.parseArray(fj);
-//        List<String> resultList = new ArrayList<>();
-//        if(array != null){
-//            for (int i = 0; i < array.size(); i++) {
-//                JSONObject jsonObject = array.getJSONObject(i);
-//                String url = jsonObject.getString("url");
-//                String s = ydClient.convertTemporaryUrl(url, 3600000);
-//                resultList.add(s);
-//            }
-//        }
-//        if(StringUtils.isNotBlank(fj)){
-//            List<Map> fjList =(List<Map>) JSON.parse(fj);
-//            resultList.add(ydClient.convertTemporaryUrl(UtilMap.getString(fjList.get(0),"url"), 3600000));
-//        }
-        String sestr = UtilMap.getString(formData, "numberField_mfxv2vgh");
-        BigDecimal se = toBigDecimal(sestr);
-        String jestr = UtilMap.getString(formData, "numberField_mfxv2vgj");
-        BigDecimal je = toBigDecimal(jestr);
-        String jshjstr = UtilMap.getString(formData, "numberField_mewfgzkv");
-        BigDecimal jshj = toBigDecimal(jshjstr);
-        String sfhs = UtilMap.getString(formData, "radioField_mfxv2vg4");
-        String jws = UtilMap.getString(formData, "radioField_mfxv2vgm");
-        List<Map> tableField = (List<Map>) formData.get("tableField_mfbx1pqi");
-        List<Map> tableFieldPayment = (List<Map>) formData.get("tableField_mhiui6v5");
-        KdYdOrder kdYdOrder = new KdYdOrder();
-        kdYdOrder.setDjlx(djlx);
-        kdYdOrder.setDjbh(djbh);
-        kdYdOrder.setKhmc(khmc);
-        kdYdOrder.setRq(rq);
-        kdYdOrder.setKhxypj(khxypj);
-        kdYdOrder.setYwlx(ywlx);
-        kdYdOrder.setXslx(xslx);
-        kdYdOrder.setBzq(bzq);
-        kdYdOrder.setXsy(xsy);
-        kdYdOrder.setXsbm(xsbm);
-        kdYdOrder.setBz(bz);
-        kdYdOrder.setJsbb(jsbb);
-        kdYdOrder.setSktj(sktj);
-        kdYdOrder.setZdzke(zdzke);
-        kdYdOrder.setSe(se);
-        kdYdOrder.setJe(je);
-        kdYdOrder.setJshj(jshj);
-        kdYdOrder.setSfhs(sfhs);
-        kdYdOrder.setJws(jws);
-        kdYdOrder.setSyncStatus("0");
-        kdYdOrder.setOperationType("1");
-//        kdYdOrder.setForminstid(formInstId);
-        if ("2".equals(type)) {
-            kdYdOrder.setOperationType(type);
-            kdYdOrderMapper.update(kdYdOrder, new LambdaQueryWrapper<KdYdOrder>().eq(KdYdOrder::getDjbh, djbh));
-        } else {
-            kdYdOrderMapper.insert(kdYdOrder);
-        }
 
-        Long id = kdYdOrder.getId();
-        int count = 1;
-        for (Map item : tableField) {
-
-            String wlbm = safeGetString(item, "textField_mfbx1pqt");
-            String wlmc = safeGetString(item, "textField_mfbx1pqs");
-            String ggxh = safeGetString(item, "textField_mfbx1pqr");
-            String xsdw = safeGetString(item, "textField_mfbx1pqq");
-            int xssl = parseInt(safeGetString(item, "numberField_mfbx1pr4"), 0); // 如果为空或格式错误,返回 0
-            String ssxl = safeGetString(item, "selectField_mfbx1pr1");
-            BigDecimal dj = toBigDecimal(safeGetString(item, "numberField_mfbx1prf"));
-            BigDecimal hsdj = toBigDecimal(safeGetString(item, "numberField_mfbx1prg"));
-            String sfzp = safeGetString(item, "radioField_mfbx1prc");
-            int sl = parseInt(safeGetString(item, "numberField_mfbx1prb"), 0);
-            BigDecimal zse = toBigDecimal(safeGetString(item, "numberField_mfbx1prh"));
-            BigDecimal zje = toBigDecimal(safeGetString(item, "numberField_mfbx1pri"));
-            BigDecimal zjshj = toBigDecimal(safeGetString(item, "numberField_mfbx1prj"));
-            BigDecimal jj = toBigDecimal(safeGetString(item, "numberField_mfbx1prk"));
-            BigDecimal zkl = toBigDecimal(safeGetString(item, "numberField_mfbx1pru"));
-            BigDecimal zke = toBigDecimal(safeGetString(item, "numberField_mfbx1prt"));
-            LocalDateTime yhrq = parseTimestamp(UtilMap.getString(item, "dateField_mfbx1prs"));
-            BigDecimal xsjzj = toBigDecimal(safeGetString(item, "numberField_mfbx1pr0"));
-            String zmzs = safeGetString(item, "textField_mfxv2vgv");
-            KdYdOrderDetail kdYdOrderDetail = new KdYdOrderDetail();
-            kdYdOrderDetail.setOrderId(id);
-            kdYdOrderDetail.setWlbm(wlbm);
-            kdYdOrderDetail.setWlmc(wlmc);
-            kdYdOrderDetail.setGgxh(ggxh);
-            kdYdOrderDetail.setXsdw(xsdw);
-            kdYdOrderDetail.setXssl(xssl);
-            kdYdOrderDetail.setSsxl(ssxl);
-            kdYdOrderDetail.setDj(dj);
-            kdYdOrderDetail.setHsdj(hsdj);
-            kdYdOrderDetail.setSfzp(sfzp);
-            kdYdOrderDetail.setSl(sl);
-            kdYdOrderDetail.setSe(zse);
-            kdYdOrderDetail.setJe(zje);
-            kdYdOrderDetail.setJshj(zjshj);
-            kdYdOrderDetail.setJj(jj);
-            kdYdOrderDetail.setZkl(zkl);
-            kdYdOrderDetail.setZke(zke);
-            kdYdOrderDetail.setYhrq(yhrq);
-            kdYdOrderDetail.setXsjzj(xsjzj);
-            kdYdOrderDetail.setDetailId(count);
-            kdYdOrderDetail.setSmzs(zmzs);
-            kdYdOrderDetail.setSyncStatus("0");
-            kdYdOrderDetail.setOperationType("1");
-//            kdYdOrderDetail.setForminstid(formInstId);
-            if ("2".equals(type) || "3".equals(type)) {
-                kdYdOrderDetail.setOperationType(type);
-                kdYdOrderDetailMapper.update(kdYdOrderDetail, new LambdaQueryWrapper<KdYdOrderDetail>()
-                        .eq(KdYdOrderDetail::getWlbm, wlbm)
-                        .eq(KdYdOrderDetail::getOrderId, id));
+        try {
+            String formInstId = UtilMap.getString(map, "formInstId");
+            String khbm = UtilMap.getString(map, "khbm");
+
+            // 参数校验
+            if (StringUtils.isBlank(formInstId)) {
+                throw new RuntimeException("订单ID不能为空");
+            }
+            if (StringUtils.isBlank(khbm)) {
+                throw new RuntimeException("客户编号不能为空");
+            }
+
+            // 1. 查询订单详情
+            DDR_New ddrNew = retryQueryData(YDParam.builder()
+                    .formInstId(formInstId)
+                    .build(), YDConf.FORM_QUERY.retrieve_id);
+
+            if (ddrNew == null || ddrNew.getFormData() == null) {
+                throw new RuntimeException("未找到订单信息,订单ID:" + formInstId);
+            }
+
+            Map formData1 = ddrNew.getFormData();
+            String ddje = UtilMap.getString(formData1, "numberField_mfxv2vgj");
+            Long zhcjrq = UtilMap.getLong(formData1, "dateField_mejowmnb");
+
+            // 订单金额校验
+            if (ddje == null || ddje.trim().isEmpty()) {
+                throw new RuntimeException("订单金额不能为空,订单ID:" + formInstId);
+            }
+
+            // 2. 计算订单金额
+            Double orderAmount = null;
+            try {
+                orderAmount = Double.parseDouble(ddje);
+                orderAmount = Math.round(orderAmount * 100.0) / 100.0;
+
+                // 订单金额合理性校验
+                if (orderAmount < 0) {
+                    throw new RuntimeException("订单金额不能为负数: " + orderAmount);
+                }
+            } catch (NumberFormatException e) {
+                throw new RuntimeException("订单金额格式错误: " + ddje, e);
+            }
+
+            System.out.println("订单信息:订单ID=" + formInstId +
+                    ", 订单金额=" + orderAmount +
+                    ", 客户编号=" + khbm);
+
+            // 3. 查询客户历史信息
+            Object result = retryQueryData(YDParam.builder()
+                    .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY")
+                    .searchFieldJson(JSONObject.toJSONString(Arrays.asList(
+                            new YDSearch("textField_mjm9k35n",
+                                    khbm,
+                                    "客户编号",
+                                    YDSearch.Type.TEXT_FIELD,
+                                    YDSearch.Operator.EQ)
+                    )))
+                    .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+            List<Map> list = (List<Map>) result;
+
+            if (list == null || list.isEmpty()) {
+                throw new RuntimeException("未找到客户信息,客户编号:" + khbm);
+            }
+
+            // 4. 获取客户现有信息并进行数据完整性校验
+            Map customerData = (Map) list.get(0).get("formData");
+            Double historicalAmount = UtilMap.getDouble(customerData, "numberField_mjm9k35k");
+            Long dddateTimestampStr = UtilMap.getLong(customerData, "dateField_mjqkkcsg");
+            Long sfdateTimestampStr = UtilMap.getLong(customerData, "dateField_mjm9k35l");
+            String originalSelectFieldValue = UtilMap.getString(customerData, "selectField_l3nrjuq0");
+            String originalKhsx = UtilMap.getString(customerData, "selectField_mjsco9d4");
+
+            // 关键字段完整性校验
+            if (dddateTimestampStr == null) {
+                throw new RuntimeException("最后成交日期不能为空,客户编号:" + khbm);
+            }
+
+            if (historicalAmount == null) {
+                // 历史金额为null时,记录错误日志并抛出异常,避免错误清零
+                System.err.println("严重错误:未能获取到客户历史金额,客户编号:" + khbm +
+                        ",返回数据:" + JSONObject.toJSONString(customerData));
+                throw new RuntimeException("无法获取客户历史金额,客户编号:" + khbm + ",请检查数据完整性");
+            }
+
+            // 记录更新前的数据快照,便于问题追踪
+            System.out.println("更新前数据快照:客户编号=" + khbm +
+                    ", 历史金额=" + historicalAmount +
+                    ", 最后成交日期=" + timestampToDateString(dddateTimestampStr) +
+                    ", 公海池日期=" + (sfdateTimestampStr != null ? timestampToDateString(sfdateTimestampStr) : "空") +
+                    ", 销售属性=" + originalKhsx +
+                    ", 选择字段=" + originalSelectFieldValue);
+
+            // 5. 金额计算和校验
+            historicalAmount = Math.round(historicalAmount * 100.0) / 100.0;
+            Double totalAmount = orderAmount + historicalAmount;
+            totalAmount = Math.round(totalAmount * 100.0) / 100.0;
+
+            // 金额变化监控:检测异常的大幅减少
+            if (totalAmount < historicalAmount && totalAmount < historicalAmount * 0.5) {
+                String errorMsg = String.format(
+                        "警告:金额异常减少!客户编号=%s, 订单金额=%.2f, 原历史金额=%.2f, 新总金额=%.2f, 减少比例=%.2f%%",
+                        khbm, orderAmount, historicalAmount, totalAmount,
+                        (historicalAmount - totalAmount) / historicalAmount * 100
+                );
+                System.err.println(errorMsg);
+                // 根据业务需求决定是否抛出异常
+                // throw new RuntimeException(errorMsg);
+            }
+
+            // 订单金额为0时的特殊处理:保持原金额不变
+            if (orderAmount == 0 && historicalAmount > 0) {
+                System.out.println("订单金额为0,保持原累计金额不变:" + historicalAmount);
+                totalAmount = historicalAmount;
+            }
+
+            System.out.println("金额计算:订单金额=" + orderAmount +
+                    ", 历史金额=" + historicalAmount +
+                    ", 总金额=" + totalAmount);
+
+            // 6. 时间计算
+            long currentTimestamp = System.currentTimeMillis();
+            long currentToDdDays = (currentTimestamp - dddateTimestampStr) / (1000 * 60 * 60 * 24);
+            long sfToDdDays = (sfdateTimestampStr != null && sfdateTimestampStr > 0) ?
+                    (sfdateTimestampStr - dddateTimestampStr) / (1000 * 60 * 60 * 24) : 0;
+
+            System.out.println("时间计算:当前时间=" + timestampToDateString(String.valueOf(currentTimestamp)) +
+                    ", 成交日期=" + timestampToDateString(String.valueOf(dddateTimestampStr)) +
+                    ", 当前-成交相差=" + currentToDdDays + "天" +
+                    ", 公海-成交相差=" + sfToDdDays + "天");
+
+            // 7. 业务规则计算
+            String ghcDateTimestamp = null;
+            String selectFieldValue = originalSelectFieldValue;
+            String khsx = originalKhsx;
+
+            // 设置客户属性
+            if (totalAmount >= 75000 && sfToDdDays <= 180) {
+                khsx = "自行开发";
+            }
+
+            // 业务规则判断
+            if (currentToDdDays < 90 && totalAmount > 0 && Math.abs(sfToDdDays - 180) <= 1) {
+                // 条件1:在成交日期上加90天
+                ghcDateTimestamp = String.valueOf(calculateTimestamp(sfdateTimestampStr, 90));
+                selectFieldValue = "半年金额不足";
+                System.out.println("条件1触发:公海池时间设为成交日期+90天=" +
+                        timestampToDateString(ghcDateTimestamp));
+            } else if (totalAmount >= 75000 && sfToDdDays <= 180) {
+                // 条件2:在成交日期上加180天
+                ghcDateTimestamp = String.valueOf(calculateTimestamp(sfdateTimestampStr, 180));
+                selectFieldValue = "半年金额不足";
+                System.out.println("条件2触发:公海池时间设为成交日期+180天=" +
+                        timestampToDateString(ghcDateTimestamp));
+            } else if (totalAmount < 150000 && sfToDdDays > 180) {
+                // 条件3:设置一年金额不足,但不设置公海池日期
+                selectFieldValue = "一年金额不足";
+                System.out.println("条件3触发:金额<15万且公海日期>180天,设置一年金额不足");
+            } else if (totalAmount > 150000) {
+                // 【新增】总金额大于15万:释放公海池日期设为成交日期的下一年第一天
+                ghcDateTimestamp = getNextYearFirstDay(dddateTimestampStr);
+                selectFieldValue = "金额充足";
+                System.out.println("条件4触发:总金额>15万,公海池时间设为成交日期下一年第一天=" +
+                        timestampToDateString(ghcDateTimestamp));
             } else {
-                kdYdOrderDetailMapper.insert(kdYdOrderDetail);
+                // 其他情况
+                if (totalAmount > 0) {
+                    ghcDateTimestamp = String.valueOf(calculateTimestamp(sfdateTimestampStr, 90));
+                    selectFieldValue = "半年金额不足";
+                    System.out.println("基础情况:金额大于0,公海池时间+90天=" +
+                            timestampToDateString(ghcDateTimestamp));
+                } else if (totalAmount < 75000) {
+                    selectFieldValue = "半年金额不足";
+                    System.out.println("金额<7.5万,但未设置公海池时间");
+                } else if (totalAmount < 150000) {
+                    selectFieldValue = "一年金额不足";
+                    System.out.println("金额7.5-15万,但未设置公海池时间");
+                }
             }
-            count++;
-        }
-        if (tableFieldPayment != null) {
-            for (int i = 0; i < tableFieldPayment.size(); i++) {
-                Map row = tableFieldPayment.get(i);
-                String sfys = safeGetString(row, "radioField_mhiui6v7");
-                String gldh = safeGetString(row, "textField_mhiui6va");
-                BigDecimal ysbl = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6v6"));
-                BigDecimal ysje = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6v8"));
-                BigDecimal ssje = toBigDecimal(UtilMap.getString(row, "numberField_mhiui6vb"));
-                int detailId = i + 1;
-                LocalDateTime endTime = parseTimestamp(UtilMap.getString(row, "dateField_mhiui6v9"));
-                KdYdOrderPayment kdYdOrderPayment = new KdYdOrderPayment();
-                kdYdOrderPayment.setOrderId(id);
-                kdYdOrderPayment.setSfys(sfys);
-                kdYdOrderPayment.setGldh(gldh);
-                kdYdOrderPayment.setYsbl(ysbl);
-                kdYdOrderPayment.setYsje(ysje);
-                kdYdOrderPayment.setSsje(ssje);
-                kdYdOrderPayment.setDetailId(detailId);
-                kdYdOrderPayment.setEndTime(endTime);
-                kdYdOrderPayment.setSyncStatus("0");
-                kdYdOrderPayment.setOperationType("1");
-                if ("2".equals(type) || "3".equals(type)) {
-                    kdYdOrderPayment.setOperationType(type);
-                    kdYdOrderPaymentMapper.update(kdYdOrderPayment, new LambdaQueryWrapper<KdYdOrderPayment>()
-                            .eq(KdYdOrderPayment::getDetailId, detailId)
-                            .eq(KdYdOrderPayment::getOrderId, id));
+
+            // 8. 构建更新数据(只更新需要变更的字段)
+            Map<String, Object> formData = new HashMap<>();
+
+            // 必须更新的字段
+            formData.put("dateField_mjm9k35j", zhcjrq);  // 最后成交日期
+            formData.put("numberField_mjm9k35k", totalAmount);       // 累计金额
+            formData.put("selectField_mjsco9d4", khsx);              // 销售属性
+
+            // 条件更新:只在有值时才更新 selectField
+            if (selectFieldValue != null && !selectFieldValue.isEmpty()) {
+                if (!selectFieldValue.equals(originalSelectFieldValue)) {
+                    formData.put("selectField_l3nrjuq0", selectFieldValue);
+                    System.out.println("更新选择字段:" + originalSelectFieldValue + " -> " + selectFieldValue);
+                }
+            }
+
+            // 条件更新:只在明确需要变更公海池日期时才更新
+            if (ghcDateTimestamp != null) {
+                // 只有当新值与旧值不同时才更新
+                String newDateStr = timestampToDateString(ghcDateTimestamp);
+                String oldDateStr = sfdateTimestampStr != null ? timestampToDateString(String.valueOf(sfdateTimestampStr)) : "空";
+                if (!newDateStr.equals(oldDateStr)) {
+                    formData.put("dateField_mjm9k35l", ghcDateTimestamp);
+                    System.out.println("更新公海池日期:" + oldDateStr + " -> " + newDateStr);
                 } else {
-                    kdYdOrderPaymentMapper.insert(kdYdOrderPayment);
+                    System.out.println("公海池日期未变化,跳过更新:" + newDateStr);
                 }
+            } else {
+                // 不设置该字段,upsert操作会保持原值不变
+                System.out.println("公海池日期无需变更,保持原值:" +
+                        (sfdateTimestampStr != null ? timestampToDateString(String.valueOf(sfdateTimestampStr)) : "空"));
             }
+
+            // 9. 数据变更前最终校验
+            if (totalAmount == 0 && historicalAmount > 0) {
+                System.err.println("警告:即将把客户金额从 " + historicalAmount + " 更新为 0,请确认业务逻辑!");
+                // 可选:根据业务需求决定是否继续执行
+                // throw new RuntimeException("金额异常清零,操作已阻止");
+            }
+
+            System.out.println("最终更新数据:" + JSONObject.toJSONString(formData));
+
+            // 10. 执行更新操作(retryOperateData已内置重试功能)
+            retryOperateData(YDParam.builder()
+                    .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY")
+                    .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                    .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                    .noExecuteExpression(false)
+                    .searchFieldJson(JSONObject.toJSONString(Arrays.asList(
+                            new YDSearch("textField_mjm9k35n",
+                                    khbm,
+                                    "客户编号",
+                                    YDSearch.Type.TEXT_FIELD,
+                                    YDSearch.Operator.EQ)
+                    )))
+                    .formDataJson(JSONObject.toJSONString(formData))
+                    .build(), YDConf.FORM_OPERATION.upsert);
+
+            System.out.println("客户信息更新成功,客户编号:" + khbm);
+
+        } catch (Exception e) {
+            System.err.println("处理订单失败: " + e.getMessage());
+            e.printStackTrace();
+            throw new RuntimeException("处理订单失败: " + e.getMessage(), e);
+        } finally {
+            MDC.remove("MDC_KEY_PID");
+        }
+    }
+
+    /**
+     * 获取指定时间戳的下一年第一天零点的时间戳
+     * @param timestamp 时间戳(毫秒)
+     * @return 下一年第一天零点的时间戳
+     */
+    private String getNextYearFirstDay(Long timestamp) {
+        if (timestamp == null || timestamp <= 0) {
+            // 如果时间戳无效,返回当前时间下一年第一天
+            timestamp = System.currentTimeMillis();
+        }
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(timestamp);
+
+        // 设置为下一年第一天
+        calendar.add(Calendar.YEAR, 1);
+        calendar.set(Calendar.MONTH, Calendar.JANUARY);
+        calendar.set(Calendar.DAY_OF_MONTH, 1);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+
+        return String.valueOf(calendar.getTimeInMillis());
+    }
+
+    /**
+     * 计算指定日期加上天数后的时间戳
+     */
+    private long calculateTimestamp(Long baseTimestamp, int daysToAdd) {
+        if (baseTimestamp == null || baseTimestamp <= 0) {
+            baseTimestamp = System.currentTimeMillis();
         }
-//        ydClient.operateData(
-//                YDParam.builder()
-//                        .formInstanceId(formInstId)
-//                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mgrmn66f", id)))
-//                        .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
+        return baseTimestamp + (daysToAdd * 24L * 60 * 60 * 1000);
+    }
 
+    /**
+     * 时间戳转日期字符串(用于日志)
+     */
+    private String timestampToDateString(Object timestamp) {
+        if (timestamp == null) {
+            return "空";
+        }
+        try {
+            long ts;
+            if (timestamp instanceof String) {
+                ts = Long.parseLong((String) timestamp);
+            } else if (timestamp instanceof Long) {
+                ts = (Long) timestamp;
+            } else {
+                return timestamp.toString();
+            }
+            if (ts <= 0) {
+                return "无效时间戳";
+            }
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            return sdf.format(new Date(ts));
+        } catch (Exception e) {
+            return timestamp.toString();
+        }
+    }
+
+    /**
+     * 计算时间戳:在基础时间戳上添加天数
+     *
+     * @param baseTimestamp 基础时间戳(毫秒)
+     * @param days          要添加的天数
+     * @return 计算后的时间戳(毫秒)
+     */
+    private long calculateTimestamp(long baseTimestamp, int days) {
+        try {
+            long oneDayMillis = 24L * 60L * 60L * 1000L;
+            long daysMillis = (long) days * oneDayMillis;
+            return baseTimestamp + daysMillis;
+        } catch (Exception e) {
+            System.err.println("时间戳计算失败:" + baseTimestamp + ", 天数:" + days);
+            return baseTimestamp + (days * 24L * 60L * 60L * 1000L);
+        }
+    }
+
+    /**
+     * 辅助方法:将时间戳转换为可读日期(仅用于调试)
+     */
+    private String timestampToDateString(String timestamp) {
+        try {
+            long ts = Long.parseLong(timestamp.trim());
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            return sdf.format(new Date(ts));
+        } catch (Exception e) {
+            return "无效时间戳:" + timestamp;
+        }
+    }
+
+    /**
+     * 重载方法:直接接收long类型时间戳
+     */
+    private String timestampToDateString(long timestamp) {
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            return sdf.format(new Date(timestamp));
+        } catch (Exception e) {
+            return "无效时间戳:" + timestamp;
+        }
     }
 
     private static LocalDateTime parseTimestamp(String timestampStr) {
@@ -288,4 +783,77 @@ public class KdYdOrderServiceImpl extends ServiceImpl<KdYdOrderMapper, KdYdOrder
         return new BigDecimal(number.toString())
                 .setScale(2, RoundingMode.HALF_UP);
     }
+
+    //自带重试的operateData方法
+    private Object retryOperateData(YDParam param, YDConf.FORM_OPERATION formOperation) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        Object result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.operateData(param, formOperation);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_OPERATION:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formOperation,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_OPERATION:{},异常信息:{}", JSONObject.toJSONString(param), formOperation,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_OPERATION:{}"+formOperation);
+    }
+
+
+    //自带重试的queryData方法
+    private DDR_New retryQueryData(YDParam param, YDConf.FORM_QUERY formQuery) {
+        int maxAttempts = 3; // 尝试的最大次数
+        int attempt = 0;
+
+        DDR_New result = null;
+
+        while (attempt < maxAttempts) {
+            try {
+                result = ydClient.queryData(param, formQuery);
+
+                return result;
+            } catch (McException e) {
+                log.info("错误信息:{}",e.getMessage());
+                if (e.getMessage().equals("The request has failed due to a temporary failure of the server.")) {
+                    attempt++;
+                    // 线程睡眠3秒
+                    try {
+                        Thread.sleep(5000);
+                        log.info("尝试第{}次,param:{},FORM_QUERY:{},异常信息:{}", attempt, JSONObject.toJSONString(param), formQuery,e.getMessage());
+                    } catch (InterruptedException ie) {
+                        Thread.currentThread().interrupt(); // 重新设置中断状态
+                        System.err.println("Sleep interrupted: " + ie.getMessage());
+                    }
+                }
+            } catch (Exception e) {
+                log.error("操作失败,param:{},FORM_QUERY:{},异常信息:{}", JSONObject.toJSONString(param), formQuery,e.getMessage());
+
+                throw new RuntimeException(e);
+            }
+
+        }
+
+        throw new RuntimeException("超出最大重试次数,param:"+JSONObject.toJSONString(param)+",FORM_QUERY:{}"+formQuery);
+    }
 }

+ 357 - 102
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdOutboundServiceImpl.java

@@ -1,6 +1,8 @@
 package com.malk.huagao.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.malk.huagao.entity.KdYdDelivery;
 import com.malk.huagao.entity.KdYdDeliveryDetail;
 import com.malk.huagao.entity.KdYdOutbound;
@@ -16,6 +18,7 @@ import com.malk.server.aliwork.YDParam;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -25,8 +28,8 @@ import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -37,6 +40,7 @@ import java.util.Map;
  * @since 2025-10-15
  */
 @Service
+@Slf4j
 public class KdYdOutboundServiceImpl extends ServiceImpl<KdYdOutboundMapper, KdYdOutbound> implements IKdYdOutboundService {
     @Autowired
     private YDClient ydClient;
@@ -45,107 +49,358 @@ public class KdYdOutboundServiceImpl extends ServiceImpl<KdYdOutboundMapper, KdY
     @Autowired
     private KdYdOutboundDetailMapper kdYdOutboundDetailMapper;
     @Override
-    public void insertkdYdOutbound(Map map) {
-        MDC.put("MDC_KEY_PID", "1003");
-        String formInstId = UtilMap.getString(map, "formInstId");
-        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
-                .formInstId(formInstId)
-                .build(), YDConf.FORM_QUERY.retrieve_id);
-        Map formData = ddrNew.getFormData();
-
-        String djlx = UtilMap.getString(formData, "selectField_mejowmna");
-//        String djbh = UtilMap.getString(formData, "serialNumberField_mheazm7w");
-        long deliceryId = UtilMap.getLong(formData, "textField_mgrqnxmm");
-//        long deliceryId = 6L;
-        String kh = UtilMap.getString(formData, "textField_mejnamf2");
-        String jsbb = UtilMap.getString(formData, "selectField_mg34txgn");
-        String ysdh = UtilMap.getString(formData, "textField_mg34txgz");
-        String xsy = UtilMap.getString(formData, "employeeField_mejnamf3").replace("[\"", "").replace("\"]", "").trim();
-        String xslx = UtilMap.getString(formData, "selectField_mejowmnc");
-        String khsx = UtilMap.getString(formData, "selectField_megi74y8");
-        String xssx = UtilMap.getString(formData, "selectField_mg34txgt");
-        String khtjr = UtilMap.getString(formData, "textField_mg34txgy");
-
-        List<Map> tableField = (List<Map>) formData.get("tableField_mejnamfd");
-        KdYdOutbound kdYdOutbound = new KdYdOutbound();
-        kdYdOutbound.setDjlx(djlx);
-//        kdYdOutbound.setDeliveryId(deliceryId);
-        kdYdOutbound.setKh(kh);
-        kdYdOutbound.setJsbb(jsbb);
-        kdYdOutbound.setYsdh(ysdh);
-        kdYdOutbound.setXslx(xslx);
-//        kdYdOutbound.setDjbh(djbh);
-        kdYdOutbound.setKhsx(khsx);
-        kdYdOutbound.setXssx(xssx);
-        kdYdOutbound.setKhtjr(khtjr);
-        kdYdOutbound.setXsy(xsy);
-//        kdYdOutbound.setForminstid(formInstId);
-        kdYdOutboundMapper.insert(kdYdOutbound);
-        Long id = kdYdOutbound.getId();
-        for (Map item : tableField) {
-            String wlbm = safeGetString(item, "textField_mejnamff");
-            String wlmc = safeGetString(item, "textField_mejnamfg");
-            String ggxh = safeGetString(item, "textField_mejnamfh");
-            String kcdw = safeGetString(item, "textField_mejnamfk");
-            String ssxl = safeGetString(item, "textField_mejnamfx");
-            BigDecimal dj = toBigDecimal(safeGetString(item, "numberField_mg34txh3"));
-            BigDecimal hsdj = toBigDecimal(safeGetString(item, "numberField_mg34txh4"));
-            BigDecimal sl = toBigDecimal(safeGetString(item, "numberField_mg34txh6"));
-            BigDecimal se = toBigDecimal(safeGetString(item, "numberField_mg34txh7"));
-            BigDecimal je = toBigDecimal(safeGetString(item, "numberField_mg34txh8"));
-            BigDecimal jshj = toBigDecimal(safeGetString(item, "numberField_mg34txh9"));
-            String ck = safeGetString(item, "textField_mf6a0h6l");
-            String cw = safeGetString(item, "textField_mf6a0h6k");
-            String kczt = safeGetString(item, "textField_mf6a0h6p");
-            String tpsb = safeGetString(item, "textField_mg34txh1");
-            String ph = safeGetString(item, "textField_mg34txh5");
-            BigDecimal jtc = toBigDecimal(safeGetString(item, "numberField_mg34txha"));
-            String sjr = safeGetString(item, "textField_mejnamf6");
-            String sjdh = safeGetString(item, "textField_mejnamf7");
-            String sjdz = safeGetString(item, "textareaField_mf6a0h5e");
-            String gg = safeGetString(item, "textField_mf6a0h6u");
-            String zbq = safeGetString(item, "numberField_mf6a0h6v");
-            LocalDateTime fwdqr = parseTimestamp(UtilMap.getString(item, "dateField_mg34txhb"));
-            String xlh = safeGetString(item, "textField_mf6a0h6w");
-            int zbqsf = parseInt(safeGetString(item, "numberField_mg34txhc"), 0);
-            String kddh = safeGetString(item, "textField_mf6a0h6x");
-            String jx = safeGetString(item, "textField_mf6a0h6y");
-            KdYdOutboundDetail kdYdOutboundDetail = new KdYdOutboundDetail();
-            kdYdOutboundDetail.setOutboundId(id);
-            kdYdOutboundDetail.setWlbm(wlbm);
-            kdYdOutboundDetail.setWlmc(wlmc);
-            kdYdOutboundDetail.setGgxh(ggxh);
-            kdYdOutboundDetail.setKcdw(kcdw);
-            kdYdOutboundDetail.setSsxl(ssxl);
-            kdYdOutboundDetail.setDj(dj);
-            kdYdOutboundDetail.setHsdj(hsdj);
-            kdYdOutboundDetail.setSl(sl);
-            kdYdOutboundDetail.setSe(se);
-            kdYdOutboundDetail.setJe(je);
-            kdYdOutboundDetail.setJshj(jshj);
-            kdYdOutboundDetail.setCk(ck);
-            kdYdOutboundDetail.setCw(cw);
-            kdYdOutboundDetail.setKczt(kczt);
-            kdYdOutboundDetail.setTpsb(tpsb);
-            kdYdOutboundDetail.setPh(ph);
-            kdYdOutboundDetail.setJtc(jtc);
-            kdYdOutboundDetail.setSjr(sjr);
-            kdYdOutboundDetail.setSjdh(sjdh);
-            kdYdOutboundDetail.setSjdz(sjdz);
-            kdYdOutboundDetail.setGg(gg);
-            kdYdOutboundDetail.setZbq(zbq);
-            kdYdOutboundDetail.setFwdqr(fwdqr);
-            kdYdOutboundDetail.setXlh(xlh);
-//            kdYdOutboundDetail.setZbqsf(zbqsf);
-            kdYdOutboundDetail.setKddh(kddh);
-            kdYdOutboundDetail.setJx(jx);
-            kdYdOutboundDetailMapper.insert(kdYdOutboundDetail);
+    public Map<String, Object> insertkdYdOutbound(Map json) {
+        HashMap<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            List<Map<String, Object>> kdYdOutbounddels = UtilMap.getList(json, "data");
+            String action = UtilMap.getString(json, "action");
+            String table = UtilMap.getString(json, "table");
+
+            // 批量删除处理
+            if (!kdYdOutbounddels.isEmpty() && action.equals("del") && table.equals("KD_YD_OUTBOUND")) {
+                log.info("开始处理出库单删除操作,共{}条数据", kdYdOutbounddels.size());
+                ArrayList<String> deleteList = new ArrayList<>();
+                int deleteSuccessCount = 0;
+
+                for (Map item : kdYdOutbounddels) {
+                    try {
+                        String djbh = String.valueOf(item.get("djbh"));
+
+                        List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-AADBCDA8126F41A0ADDEE3353828583192M8")
+                                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mg34txgm", djbh)))
+                                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                        if (list1 != null && !list1.isEmpty()) {
+                            for (Map map : list1) {
+                                String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                                if (formInstanceId != null) {
+                                    deleteList.add(formInstanceId);
+                                }
+                            }
+                            deleteSuccessCount++;
+                        } else {
+                            log.warn("未找到对应的出库单数据: djbh={}", djbh);
+                        }
+
+                    } catch (Exception e) {
+                        log.error("删除出库单数据查询异常: djbh={}", item.get("djbh"), e);
+                    }
+                }
+
+                // 执行批量删除
+                if (!deleteList.isEmpty()) {
+                    try {
+                        ydClient.operateData(YDParam.builder()
+                                .formUuid("FORM-AADBCDA8126F41A0ADDEE3353828583192M8")
+                                .formInstanceIdList(deleteList)
+                                .build(), YDConf.FORM_OPERATION.delete_batch);
+                        log.info("出库单批量删除完成,共删除{}条数据", deleteList.size());
+                    } catch (Exception e) {
+                        log.error("出库单批量删除操作异常", e);
+                    }
+                }
+
+                // 返回删除结果
+                result.put("code", "200");
+                result.put("msg", "删除成功,共删除" + deleteList.size() + "条数据");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("deletedCount", deleteList.size());
+                    put("deletedIds", deleteList);
+                }});
+                return result;
+            } else if (action.equals("del")) {
+                log.info("【出库单删除任务】无需要删除的数据");
+                result.put("code", "200");
+                result.put("msg", "无需要删除的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            List<Map<String, Object>> kdYdOutbounds = UtilMap.getList(json, "data");
+            // 同步新增/更新数据
+            if (kdYdOutbounds.isEmpty()) {
+                log.info("【出库单同步任务】无需要同步的数据,结束");
+                result.put("code", "200");
+                result.put("msg", "无需要同步的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            log.info("【出库单同步任务】开始同步,共{}条数据", kdYdOutbounds.size());
+
+            List<Map<String, Object>> operationResults = new ArrayList<>();
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map tableItem : kdYdOutbounds) {
+                Map<String, Object> singleResult = new HashMap<>();
+
+                try {
+                    String djbh = String.valueOf(tableItem.get("djbh"));
+                    List<Map<String, Object>> tableList1 = UtilMap.getList(tableItem, "tableList");
+                    String  deliveryId = UtilMap.getString(tableItem, "deliveryId");
+
+                    // 检查明细数据是否存在
+                    if (tableList1 == null || tableList1.isEmpty()) {
+                        log.warn("出库单明细数据为空: djbh={}", djbh);
+                        singleResult.put("djbh", djbh);
+                        singleResult.put("errorMsg", "明细数据为空");
+                        singleResult.put("status", "fail");
+                        failCount++;
+                        operationResults.add(singleResult);
+                        continue;
+                    }
+
+                    ArrayList<Object> tableList = new ArrayList<>();
+                    List<Map<String, Object>> tableListxlh = new ArrayList<>();
+
+                    // 处理明细数据
+                    for (Map item1 : tableList1) {
+                        HashMap<String, String> tablemap = new HashMap<>();
+//                        tablemap.put("textField_mg34txgm", String.valueOf(tableItem.get("djbh")));
+                        tablemap.put("textField_mejnamff", String.valueOf(item1.get("wlbm")));
+                        tablemap.put("textField_mejnamfg", String.valueOf(item1.get("wlmc")));
+                        tablemap.put("textField_mg34txh1", String.valueOf(item1.get("tpsb")));
+                        tablemap.put("textField_mejnamfh", String.valueOf(item1.get("ggxh")));
+                        tablemap.put("textField_mejnamfk", String.valueOf(item1.get("kcdw")));
+
+                        // 处理数值字段
+                        tablemap.put("numberField_mejnamfl", safeConvertBigDecimalToString(item1.get("yfsl")));
+                        tablemap.put("numberField_mg34txh2", safeConvertBigDecimalToString(item1.get("sfsl")));
+                        tablemap.put("numberField_mg34txh3", safeConvertBigDecimalToString(item1.get("dj")));
+                        tablemap.put("numberField_mg34txh4", safeConvertBigDecimalToString(item1.get("hsdj")));
+
+                        tablemap.put("textField_mg34txh5", String.valueOf(item1.get("ph")));
+                        tablemap.put("numberField_mg34txh6", safeConvertBigDecimalToString(item1.get("sl")));
+                        tablemap.put("numberField_mg34txh7", safeConvertBigDecimalToString(item1.get("se")));
+                        tablemap.put("numberField_mg34txh8", safeConvertBigDecimalToString(item1.get("je")));
+                        tablemap.put("numberField_mg34txh9", safeConvertBigDecimalToString(item1.get("jshj")));
+
+                        tablemap.put("textField_mf6a0h6l", String.valueOf(item1.get("ck")));
+                        tablemap.put("textField_mf6a0h6k", String.valueOf(item1.get("cw")));
+                        tablemap.put("textField_mf6a0h6p", String.valueOf(item1.get("kczt")));
+                        tablemap.put("numberField_mg34txha", safeConvertBigDecimalToString(item1.get("jtc")));
+
+                        tablemap.put("textField_mejnamf6", String.valueOf(item1.get("sjr")));
+                        tablemap.put("textField_mejnamf7", String.valueOf(item1.get("sjdh")));
+                        tablemap.put("textareaField_mf6a0h5e", String.valueOf(item1.get("sjdz")));
+                        tablemap.put("textField_mejnamfx", String.valueOf(item1.get("ssxl")));
+                        tablemap.put("textField_mf6a0h6u", String.valueOf(item1.get("gg")));
+                        tablemap.put("textField_mhlqeoas", String.valueOf(item1.get("zbq")));
+
+                        // 处理日期字段
+                        tablemap.put("dateField_mg34txhb", safeConvertDateTimeToString(item1.get("fwdqr")));
+                        tablemap.put("textField_mhlqeoat", String.valueOf(item1.get("zbqsf")));
+                        tablemap.put("textField_mf6a0h6x", String.valueOf(item1.get("kddh")));
+                        tablemap.put("textField_mf6a0h6y", String.valueOf(item1.get("jx")));
+                        tablemap.put("radioField_mf6a0h6h", String.valueOf(item1.get("sfzp")));
+
+                        tableList.add(tablemap);
+
+                        // 处理序列号明细
+                        String xlhjh = String.valueOf(item1.get("xlhjh"));
+                        if (xlhjh != null && !xlhjh.trim().isEmpty() && !"null".equals(xlhjh)) {
+                            List<Map<String, Object>> currentXlhList = Arrays.stream(xlhjh.split(","))
+                                    .map(String::trim)
+                                    .filter(item -> !item.isEmpty())
+                                    .map(item -> {
+                                        Map<String, Object> xlhMap = new HashMap<>();
+                                        xlhMap.put("textField_mf6a0h6w", item);
+                                        xlhMap.put("textField_mjqst61l", String.valueOf(item1.get("wlbm")));
+                                        xlhMap.put("textField_mjqst61m", String.valueOf(item1.get("ggxh")));
+                                        return xlhMap;
+                                    })
+                                    .collect(Collectors.toList());
+
+                            tableListxlh.addAll(currentXlhList);
+                        }
+                    }
+
+                    // 查询发货单数据
+                    String fhdformInstanceId = null;
+                    String fhdbh = null;
+                    if (deliveryId != null) {
+                        try {
+                            log.debug("开始查询发货单数据: deliveryId={}", deliveryId);
+
+                            List<Map> ddlist = (List<Map>) ydClient.queryData(
+                                    YDParam.builder()
+                                            .formUuid("FORM-FAE2575E112644ED914CAB4FEC9309F32AVR")
+                                                   .searchCondition(JSON.toJSONString(UtilMap.map("serialNumberField_mheazm7w", deliveryId)))
+                                            .build(),
+                                    YDConf.FORM_QUERY.retrieve_list_all
+                            ).getData();
+
+                            if (ddlist != null && !ddlist.isEmpty()) {
+                                for (Map<String, Object> khitem : ddlist) {
+                                    Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
+
+                                    if (khformData != null && deliveryId.equals(khformData.get("serialNumberField_mheazm7w"))) {
+                                        fhdformInstanceId = (String) khitem.get("formInstanceId");
+                                        fhdbh = (String) khformData.get("serialNumberField_mheazm7w");
+                                        break;
+                                    }
+                                }
+                            } else {
+                                log.warn("未查询到发货单数据: deliveryId={}", deliveryId);
+                            }
+
+                        } catch (Exception e) {
+                            log.error("查询发货单数据异常: deliveryId={}", deliveryId, e);
+                        }
+                    }
+
+                    // 构建更新数据
+                    HashMap<Object, Object> updateMap = new HashMap<>();
+                    updateMap.put("tableField_mejnamfd", tableList);
+                    updateMap.put("tableField_mips137b", tableListxlh);
+
+                    // 添加关联表单数据
+                    if (fhdbh != null && !"null".equals(fhdbh) && fhdformInstanceId != null) {
+                        updateMap.put("associationFormField_mejmml36",
+                                Arrays.asList(getfhdAss(fhdbh,fhdformInstanceId)));
+                    }
+
+                    // 添加主表字段
+                    updateMap.put("dateField_krbgloam", safeConvertDateTimeToString(tableItem.get("dateTime")));
+                    updateMap.put("textField_krnn5bmr", String.valueOf(tableItem.get("xsDept")));
+                    updateMap.put("textField_ml4qflc0", String.valueOf(tableItem.get("kdgs")));
+                    updateMap.put("textField_mhjxw689", String.valueOf(tableItem.get("fhDept")));
+                    updateMap.put("textField_mhjxw686", String.valueOf(tableItem.get("cgy")));
+                    updateMap.put("selectField_mejowmna", String.valueOf(tableItem.get("djlx")));
+                    updateMap.put("textField_mg34txgm", String.valueOf(tableItem.get("djbh")));
+                    updateMap.put("textField_mhlqeoar", String.valueOf(tableItem.get("jsbb")));
+                    updateMap.put("textField_mejnamf2", String.valueOf(tableItem.get("kh")));
+                    updateMap.put("selectField_mejowmnc", String.valueOf(tableItem.get("xslx")));
+                    updateMap.put("textField_mhjxw688", String.valueOf(tableItem.get("xsy")));
+                    updateMap.put("selectField_mg34txgt", String.valueOf(tableItem.get("xssx")));
+                    updateMap.put("selectField_megi74y8", String.valueOf(tableItem.get("khsx")));
+                    updateMap.put("textField_mg34txgy", String.valueOf(tableItem.get("khtjr")));
+                    updateMap.put("textField_mg34txgz", String.valueOf(tableItem.get("ysdh")));
+                    updateMap.put("textField_migw33w6", String.valueOf(deliveryId));
+
+                    // 执行同步操作
+                    Object operationResult = ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-AADBCDA8126F41A0ADDEE3353828583192M8")
+                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mg34txgm", String.valueOf(tableItem.get("djbh")))))
+                            .formDataJson(JSONObject.toJSONString(updateMap))
+                            .build(), YDConf.FORM_OPERATION.upsert);
+
+                    // 记录成功结果
+                    singleResult.put("djbh", djbh);
+                    singleResult.put("deliveryId", deliveryId);
+                    singleResult.put("operationResult", operationResult);
+                    singleResult.put("status", "success");
+                    successCount++;
+
+                    log.info("出库单同步成功: djbh={}, deliveryId={}", djbh, deliveryId);
+
+                } catch (Exception e) {
+                    String djbh = String.valueOf(tableItem.get("djbh"));
+                    log.error("同步出库单数据异常: djbh={}", djbh, e);
+
+                    singleResult.put("djbh", djbh);
+                    singleResult.put("errorMsg", e.getMessage());
+                    singleResult.put("status", "fail");
+                    failCount++;
+                }
+
+                operationResults.add(singleResult);
+            }
+
+            // 构建返回结果
+            Map<String, Object> data = new HashMap<>();
+            data.put("operationResults", operationResults);
+            data.put("totalCount", kdYdOutbounds.size());
+            data.put("successCount", successCount);
+            data.put("failCount", failCount);
+
+            result.put("code", failCount == 0 ? "200" : "300");
+            result.put("msg", "操作完成,成功" + successCount + "条,失败" + failCount + "条");
+            result.put("data", data);
+
+            log.info("【出库单同步任务】完成,共处理{}条数据,成功{}条,失败{}条",
+                    kdYdOutbounds.size(), successCount, failCount);
+
+        } catch (Exception e) {
+            log.error("出库单同步任务执行异常", e);
+            result.put("code", "500");
+            result.put("msg", "系统异常:" + e.getMessage());
+            result.put("data", new HashMap<>());
+        }
+
+        return result;
+    }
+
+    // 辅助方法:安全转换BigDecimal为字符串(保留2位小数)
+    private String safeConvertBigDecimalToString(Object value) {
+        try {
+            if (value == null) {
+                return java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP).toString();
+            }
+
+            if (value instanceof BigDecimal) {
+                return ((BigDecimal) value).setScale(2, java.math.RoundingMode.HALF_UP).toString();
+            } else if (value instanceof Number) {
+                return new BigDecimal(value.toString()).setScale(2, java.math.RoundingMode.HALF_UP).toString();
+            } else if (value instanceof String) {
+                return new BigDecimal((String) value).setScale(2, java.math.RoundingMode.HALF_UP).toString();
+            }
+
+            return java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP).toString();
+        } catch (Exception e) {
+            log.warn("转换BigDecimal异常: value={}", value);
+            return java.math.BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP).toString();
         }
-        ydClient.operateData(
-                YDParam.builder()
-                        .formInstanceId(formInstId)
-                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("textField_mgrsdayq", id)))
-                        .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
+    }
+
+    // 辅助方法:安全转换日期时间为字符串
+//    private String safeConvertDateTimeToString(Object dateTime) {
+//        try {
+//            if (dateTime == null) {
+//                return "";
+//            }
+//
+//            if (dateTime instanceof java.time.LocalDateTime) {
+//                java.time.LocalDateTime dt = (java.time.LocalDateTime) dateTime;
+//                return String.valueOf(dt.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli());
+//            }
+//
+//            return String.valueOf(dateTime);
+//        } catch (Exception e) {
+//            log.warn("转换日期时间异常: dateTime={}", dateTime);
+//            return "";
+//        }
+//    }
+    /**
+     * 最简化日期转换
+     */
+    private String safeConvertDateTimeToString(Object dateTime) {
+        try {
+            if (dateTime instanceof LocalDateTime) {
+                return String.valueOf(((LocalDateTime) dateTime)
+                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+            }
+            if (dateTime instanceof Date) return String.valueOf(((Date) dateTime).getTime());
+            if (dateTime instanceof Long) return String.valueOf(dateTime);
+            if (dateTime instanceof Integer) {
+                long t = ((Integer) dateTime).longValue();
+                return String.valueOf(t < 10000000000L ? t * 1000L : t);
+            }
+            if (dateTime instanceof String) {
+                String s = ((String) dateTime).trim();
+                if (s.matches("\\d+")) {
+                    return String.valueOf(s.length() == 10 ? Long.parseLong(s) * 1000L : Long.parseLong(s));
+                }
+            }
+            return "";
+        } catch (Exception e) { return ""; }
+    }
+    private Object getfhdAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-FAE2575E112644ED914CAB4FEC9309F32AVR", "receipt", id, title, "");
     }
     private static LocalDateTime parseTimestamp(String timestampStr) {
         if (timestampStr == null || timestampStr.trim().isEmpty()) return null;

+ 615 - 2
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdReceivableServiceImpl.java

@@ -1,5 +1,6 @@
 package com.malk.huagao.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.malk.huagao.entity.KdYdOutbound;
 import com.malk.huagao.entity.KdYdOutboundDetail;
@@ -16,6 +17,7 @@ import com.malk.server.aliwork.YDParam;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -25,8 +27,8 @@ import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.List;
-import java.util.Map;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 
 /**
  * <p>
@@ -37,6 +39,7 @@ import java.util.Map;
  * @since 2025-10-16
  */
 @Service
+@Slf4j
 public class KdYdReceivableServiceImpl extends ServiceImpl<KdYdReceivableMapper, KdYdReceivable> implements IKdYdReceivableService {
     @Autowired
     private YDClient ydClient;
@@ -145,6 +148,616 @@ public class KdYdReceivableServiceImpl extends ServiceImpl<KdYdReceivableMapper,
                         .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
     }
 
+
+    @Override
+    public Map<String, Object> insertkdYdReceivable1(Map json) {
+        HashMap<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            List<Map<String, Object>> kdYdReceivableDels = UtilMap.getList(json, "data");
+            String action = UtilMap.getString(json, "action");
+            String table = UtilMap.getString(json, "table");
+
+            // 批量删除处理
+            if (!kdYdReceivableDels.isEmpty() && "del".equals(action) && "KD_YD_RECEIVABLE".equals(table)) {
+                log.info("开始处理应收单删除操作,共{}条数据", kdYdReceivableDels.size());
+                ArrayList<String> deleteList = new ArrayList<>();
+                int deleteSuccessCount = 0;
+
+                for (Map<String, Object> item : kdYdReceivableDels) {
+                    try {
+                        String djbh = String.valueOf(item.get("djbh"));
+
+                        List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-4E1CE4550339494A9BE5498FB119FF2E9ERU")
+                                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mg3a0tgs", djbh)))
+                                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                        if (list1 != null && !list1.isEmpty()) {
+                            for (Map map : list1) {
+                                String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                                if (formInstanceId != null) {
+                                    deleteList.add(formInstanceId);
+                                }
+                            }
+                            deleteSuccessCount++;
+                        } else {
+                            log.warn("未找到对应的应收单数据: djbh={}", djbh);
+                        }
+
+                    } catch (Exception e) {
+                        log.error("删除应收单数据查询异常: djbh={}", item.get("djbh"), e);
+                    }
+                }
+
+                // 执行批量删除
+                if (!deleteList.isEmpty()) {
+                    try {
+                        ydClient.operateData(YDParam.builder()
+                                .formUuid("FORM-4E1CE4550339494A9BE5498FB119FF2E9ERU")
+                                .formInstanceIdList(deleteList)
+                                .build(), YDConf.FORM_OPERATION.delete_batch);
+                        log.info("应收单批量删除完成,共删除{}条数据", deleteList.size());
+                    } catch (Exception e) {
+                        log.error("应收单批量删除操作异常", e);
+                    }
+                }
+
+                // 返回删除结果
+                result.put("code", "200");
+                result.put("msg", "删除成功,共删除" + deleteList.size() + "条数据");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("deletedCount", deleteList.size());
+                    put("deletedIds", deleteList);
+                }});
+                return result;
+            } else if ("del".equals(action)) {
+                log.info("【应收单删除任务】无需要删除的数据");
+                result.put("code", "200");
+                result.put("msg", "无需要删除的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            // 同步新增/更新数据
+            List<Map<String, Object>> kdYdReceivables = UtilMap.getList(json, "data");
+            if (kdYdReceivables.isEmpty()) {
+                log.info("【应收单同步任务】无需要同步的数据,结束");
+                result.put("code", "200");
+                result.put("msg", "无需要同步的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            log.info("【应收单同步任务】开始同步,共{}条数据", kdYdReceivables.size());
+
+            List<Map<String, Object>> operationResults = new ArrayList<>();
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map<String, Object> receivableItem : kdYdReceivables) {
+                Map<String, Object> singleResult = new HashMap<>();
+
+                try {
+                    String djbh = String.valueOf(receivableItem.get("djbh"));
+                    List<Map<String, Object>> tableListData = UtilMap.getList(receivableItem, "tableList");
+                    List<Map<String, Object>> paymentListData = UtilMap.getList(receivableItem, "paymentList");
+//                    String  receivableId = UtilMap.getString(receivableItem, "receivableId");
+
+                    // 检查应收单明细数据是否存在
+                    if (tableListData == null || tableListData.isEmpty()) {
+                        log.warn("应收单明细数据为空: djbh={}", djbh);
+                        singleResult.put("errorMsg", "明细数据为空");
+                        singleResult.put("status", "fail");
+                        failCount++;
+                        operationResults.add(singleResult);
+                        continue;
+                    }
+
+                    // 处理应收单明细
+
+                    ArrayList<Object> tableList = new ArrayList<>();
+                    for (Map<String, Object> detailItem : tableListData) {
+                        HashMap<Object, Object> tablemap = new HashMap<>();
+
+                        // 使用辅助方法安全获取和格式化数据
+                        tablemap.put("textField_mf6el3zy", String.valueOf(detailItem.get("wlbm")));
+                        tablemap.put("textField_mf6el3zz", String.valueOf(detailItem.get("wlmc")));
+                        tablemap.put("textField_mejmtic5", String.valueOf(detailItem.get("ggxh")));
+                        tablemap.put("textField_mf6el400", String.valueOf(detailItem.get("jjdw")));
+                        tablemap.put("textField_mhllijwo", String.valueOf(detailItem.get("ssxl")));
+                        tablemap.put("numberField_mf6el402", safeFormatBigDecimal(detailItem.get("dj")));
+                        tablemap.put("numberField_mejmticb", safeFormatBigDecimal(detailItem.get("hsdj")));
+                        tablemap.put("numberField_mf6el403", safeFormatBigDecimal(detailItem.get("sl")));
+                        tablemap.put("numberField_mejmtic7", safeFormatBigDecimal(detailItem.get("jshj1")));
+                        tablemap.put("textField_mf6el409", String.valueOf(detailItem.get("kcdw")));
+                        tablemap.put("textField_mf6el408", String.valueOf(detailItem.get("ph")));
+                        tablemap.put("numberField_mf6el406", safeFormatBigDecimal(detailItem.get("se")));
+                        tablemap.put("numberField_mejmtic6", safeFormatBigDecimal(detailItem.get("jjsl")));
+                        tablemap.put("numberField_mf6el404", safeFormatBigDecimal(detailItem.get("zkl")));
+                        tablemap.put("numberField_mejmticc", safeFormatBigDecimal(detailItem.get("bhsje")));
+                        tablemap.put("numberField_mf6el407", safeFormatBigDecimal(detailItem.get("jjjbsl")));
+                        tablemap.put("numberField_mf6el40a", safeFormatBigDecimal(detailItem.get("kcsl")));
+                        tablemap.put("radioField_mejnamfn", String.valueOf(detailItem.get("sfzp")));
+                        tablemap.put("numberField_mf6el40c", safeFormatBigDecimal(detailItem.get("tc")));
+                        tablemap.put("textField_mf6el40d", String.valueOf(detailItem.get("jx")));
+                        tablemap.put("textField_mf6el40b", String.valueOf(detailItem.get("gg")));
+                        tablemap.put("numberField_mf6el405", safeFormatBigDecimal(detailItem.get("zke")));
+
+
+                        tableList.add(tablemap);
+                    }
+
+                    // 处理收款计划
+                    ArrayList<Object> tableListPay = new ArrayList<>();
+                    if (paymentListData != null && !paymentListData.isEmpty()) {
+                        for (Map<String, Object> paymentItem : paymentListData) {
+                            HashMap<Object, Object> tablemap1 = new HashMap<>();
+
+                            // 处理日期字段
+                            Object endTimeObj = paymentItem.get("endTime");
+                            tablemap1.put("dateField_mhiui6v9", safeConvertDateTimeToString(endTimeObj));
+                            tablemap1.put("textField_mhiui6va", String.valueOf(paymentItem.get("xsddh")));
+                            tablemap1.put("numberField_mhiui6v8", safeFormatBigDecimal(paymentItem.get("ysje")));
+                            tablemap1.put("numberField_mhiui6v6", safeFormatBigDecimal(paymentItem.get("ysbl")));
+                            tablemap1.put("numberField_mhiui6vb", safeFormatBigDecimal(paymentItem.get("ysjebwb")));
+                            tablemap1.put("numberField_mhjy9hzj", safeFormatBigDecimal(paymentItem.get("stkdglje")));
+                            tableListPay.add(tablemap1);
+                        }
+                    }
+
+                    // 查询关联的出库单数据
+                    String ckddjbh = String.valueOf(receivableItem.get("ckddjbh"));
+                    String ckdformInstanceId = null;
+                    String ckdbh = null;
+
+                    if (ckddjbh != null && !"null".equals(ckddjbh) && !ckddjbh.trim().isEmpty()) {
+                        try {
+                            List<Map> ddlist = (List<Map>) ydClient.queryData(
+                                    YDParam.builder()
+                                            .formUuid("FORM-AADBCDA8126F41A0ADDEE3353828583192M8")
+                                            .searchCondition(JSON.toJSONString(UtilMap.map("textField_mg34txgm", ckddjbh)))
+                                            .build(),
+                                    YDConf.FORM_QUERY.retrieve_list_all
+                            ).getData();
+
+                            if (ddlist != null && !ddlist.isEmpty()) {
+                                for (Map<String, Object> khitem : ddlist) {
+                                    Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
+                                    if (khformData != null) {
+                                        Object ckddjbhObj = khformData.get("textField_mg34txgm");
+                                        String ckddjbhStr = ckddjbhObj != null ? ckddjbhObj.toString() : null;
+
+                                        if (ckddjbh.equals(ckddjbhStr)) {
+                                            ckdformInstanceId = (String) khitem.get("formInstanceId");
+                                            ckdbh = ckddjbhStr;
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.error("查询出库单数据异常: ckddjbh={}", ckddjbh, e);
+                        }
+                    }
+
+                    // 构建主表数据
+                    HashMap<Object, Object> updateData = new HashMap<>();
+                    updateData.put("tableField_mf6el3zx", tableList);
+
+                    // 添加关联表单数据
+                    if (ckdbh != null && ckdformInstanceId != null) {
+                        updateData.put("associationFormField_mejmtick",
+                                Arrays.asList(getysdAss(ckdbh, ckdformInstanceId)));
+                    }
+
+                    updateData.put("tableField_mhiui6v5", tableListPay);
+                    updateData.put("textField_mg3a0tgs", djbh);
+                    updateData.put("textField_mj15q3dk", ckddjbh);
+                    updateData.put("selectField_mg3a0th4", String.valueOf(receivableItem.get("djlx")));
+                    updateData.put("selectField_mev13l3r", String.valueOf(receivableItem.get("sktj")));
+
+                    // 处理主表日期字段
+                    Object endTimeObj1 = receivableItem.get("endTime");
+                        updateData.put("dateField_mejmtic3", safeConvertDateTimeToString(endTimeObj1));
+
+                    Object businessTimeObj = receivableItem.get("businessTime");
+                        updateData.put("dateField_mejmtic2", safeConvertDateTimeToString(endTimeObj1));
+                    updateData.put("numberField_mejmtic8", safeFormatBigDecimal(receivableItem.get("jshj")));
+                    updateData.put("textField_mejmml3k", String.valueOf(receivableItem.get("kh")));
+                    updateData.put("textField_mhjy9hzh", String.valueOf(receivableItem.get("xsy")));
+                    updateData.put("selectField_mejowmnc", String.valueOf(receivableItem.get("xslx")));
+                    updateData.put("selectField_megi74y8", String.valueOf(receivableItem.get("khsx")));
+                    updateData.put("textField_krnn5bmr", String.valueOf(receivableItem.get("xsbm")));
+                    updateData.put("textField_mhjy9hzi", String.valueOf(receivableItem.get("lzlx")));
+                    updateData.put("textareaField_mg3a0tgx", String.valueOf(receivableItem.get("bz")));
+                    updateData.put("selectField_mg3fuqvn", String.valueOf(receivableItem.get("bb")));
+
+                    // 执行同步操作
+                    Object operationResult = ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-4E1CE4550339494A9BE5498FB119FF2E9ERU")
+                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mg3a0tgs", djbh)))
+                            .formDataJson(JSONObject.toJSONString(updateData))
+                            .build(), YDConf.FORM_OPERATION.upsert
+                    );
+
+                    // 记录成功结果
+                    singleResult.put("operationResult", operationResult);
+                    singleResult.put("status", "success");
+                    singleResult.put("ckdformInstanceId", ckdformInstanceId);
+                    singleResult.put("tableCount", tableList.size());
+                    singleResult.put("paymentCount", tableListPay.size());
+                    successCount++;
+
+//                    log.info("应收单同步成功: djbh={}, receivableId={}", djbh, receivableId);
+
+                } catch (Exception e) {
+                    String djbh = String.valueOf(receivableItem.get("djbh"));
+                    log.error("同步应收单数据异常: djbh={}", djbh, e);
+
+                    singleResult.put("djbh", djbh);
+                    singleResult.put("errorMsg", e.getMessage());
+                    singleResult.put("status", "fail");
+                    failCount++;
+                }
+
+                operationResults.add(singleResult);
+            }
+
+            // 构建返回结果
+            Map<String, Object> data = new HashMap<>();
+            data.put("operationResults", operationResults);
+            data.put("totalCount", kdYdReceivables.size());
+            data.put("successCount", successCount);
+            data.put("failCount", failCount);
+
+            result.put("code", failCount == 0 ? "200" : "300");
+            result.put("msg", "操作完成,成功" + successCount + "条,失败" + failCount + "条");
+            result.put("data", data);
+
+            log.info("【应收单同步任务】完成,共处理{}条数据,成功{}条,失败{}条",
+                    kdYdReceivables.size(), successCount, failCount);
+
+        } catch (Exception e) {
+            log.error("应收单同步任务执行异常", e);
+            result.put("code", "500");
+            result.put("msg", "系统异常:" + e.getMessage());
+            result.put("data", new HashMap<>());
+        } finally {
+            MDC.remove("MDC_KEY_PID");
+        }
+
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> insertkdYdpayment(Map json) {
+
+        HashMap<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003");
+            List<Map<String, Object>> kdYdPaymentReceiptDels = UtilMap.getList(json, "data");
+            String action = UtilMap.getString(json, "action");
+            String table = UtilMap.getString(json, "table");
+
+            // 批量删除处理
+            if (!kdYdPaymentReceiptDels.isEmpty() && "del".equals(action) && "KD_YD_PAYMENT_RECEIPT".equals(table)) {
+                log.info("开始处理收款单删除操作,共{}条数据", kdYdPaymentReceiptDels.size());
+                ArrayList<String> deleteList = new ArrayList<>();
+                int deleteSuccessCount = 0;
+
+                for (Map<String, Object> item : kdYdPaymentReceiptDels) {
+                    try {
+                        String djbh = String.valueOf(item.get("djbh"));
+
+                        List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-0569C06E47074C2981ADEEAFCE083EDAK5AM")
+                                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mh9woamt", djbh)))
+                                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                        if (list1 != null && !list1.isEmpty()) {
+                            for (Map map : list1) {
+                                String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                                if (formInstanceId != null) {
+                                    deleteList.add(formInstanceId);
+                                }
+                            }
+                            deleteSuccessCount++;
+                        } else {
+                            log.warn("未找到对应的收款单数据: djbh={}", djbh);
+                        }
+
+                    } catch (Exception e) {
+                        log.error("删除收款单数据查询异常: djbh={}", item.get("djbh"), e);
+                    }
+                }
+
+                // 执行批量删除
+                if (!deleteList.isEmpty()) {
+                    try {
+                        ydClient.operateData(YDParam.builder()
+                                .formUuid("FORM-0569C06E47074C2981ADEEAFCE083EDAK5AM")
+                                .formInstanceIdList(deleteList)
+                                .build(), YDConf.FORM_OPERATION.delete_batch);
+                        log.info("收款单批量删除完成,共删除{}条数据", deleteList.size());
+                    } catch (Exception e) {
+                        log.error("收款单批量删除操作异常", e);
+                    }
+                }
+
+                // 返回删除结果
+                result.put("code", "200");
+                result.put("msg", "删除成功,共删除" + deleteList.size() + "条数据");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("deletedCount", deleteList.size());
+                    put("deletedIds", deleteList);
+                }});
+                return result;
+            } else if ("del".equals(action)) {
+                log.info("【收款单删除任务】无需要删除的数据");
+                result.put("code", "200");
+                result.put("msg", "无需要删除的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            // 同步新增/更新数据
+            List<Map<String, Object>> kdYdPaymentReceipts = UtilMap.getList(json, "data");
+            if (kdYdPaymentReceipts.isEmpty()) {
+                log.info("【收款单同步任务】无需要同步的数据,结束");
+                result.put("code", "200");
+                result.put("msg", "无需要同步的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            log.info("【收款单同步任务】开始同步,共{}条数据", kdYdPaymentReceipts.size());
+
+            List<Map<String, Object>> operationResults = new ArrayList<>();
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map<String, Object> paymentItem : kdYdPaymentReceipts) {
+                Map<String, Object> singleResult = new HashMap<>();
+
+                try {
+                    String djbh = String.valueOf(paymentItem.get("djbh"));
+                    List<Map<String, Object>> tableListData = UtilMap.getList(paymentItem, "tableList");
+//                    String  paymentReceiptId = UtilMap.getString(paymentItem, "paymentReceiptId");
+
+                    // 检查明细数据是否存在
+                    if (tableListData == null || tableListData.isEmpty()) {
+                        log.warn("收款单明细数据为空: djbh={}", djbh);
+                        singleResult.put("errorMsg", "明细数据为空");
+                        singleResult.put("status", "fail");
+                        failCount++;
+                        operationResults.add(singleResult);
+                        continue;
+                    }
+
+                    // 处理收款单明细
+                    ArrayList<Object> tableList = new ArrayList<>();
+                    for (Map<String, Object> detailItem : tableListData) {
+                        HashMap<String, String> tablemap = new HashMap<>();
+                        tablemap.put("textField_mh9woanr", String.valueOf(detailItem.get("jsfs")));
+                        tablemap.put("textField_mh9woans", String.valueOf(detailItem.get("skyt")));
+                        tablemap.put("textField_mh9woant", String.valueOf(detailItem.get("ysxmlx")));
+                        tablemap.put("textField_mh9woanu", String.valueOf(detailItem.get("ysxsdd")));
+                        tablemap.put("numberField_mh9woanv", safeFormatBigDecimalToString(detailItem.get("ysje")));
+                        tablemap.put("numberField_mh9woanw", safeFormatBigDecimalToString(detailItem.get("sxf")));
+                        tablemap.put("textField_mhmr1ecr", String.valueOf(detailItem.get("cdk")));
+                        tablemap.put("textField_mh9woany", String.valueOf(detailItem.get("wfyhzh")));
+                        tablemap.put("textField_mh9woao2", String.valueOf(detailItem.get("xsddh")));
+                        tablemap.put("textField_mh9woao1", String.valueOf(detailItem.get("fyxm")));
+                        tablemap.put("numberField_mh9woanz", safeFormatBigDecimalToString(detailItem.get("ssje")));
+                        tablemap.put("numberField_mh9woao0", safeFormatBigDecimalToString(detailItem.get("zhje")));
+                        tableList.add(tablemap);
+                    }
+
+                    // 查询关联的订单数据
+                    String xsddbh = String.valueOf(paymentItem.get("xsddbh"));
+                    String ddformInstanceId = null;
+                    String ddbh = null;
+
+                    if (xsddbh != null && !"null".equals(xsddbh) && !xsddbh.trim().isEmpty()) {
+                        try {
+                            log.debug("开始查询订单数据: xsddbh={}", xsddbh);
+
+                            List<Map> ddlist = (List<Map>) ydClient.queryData(
+                                    YDParam.builder()
+                                            .formUuid("FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C")
+                                            .searchCondition(JSON.toJSONString(UtilMap.map("textField_mjs6fuwo", xsddbh)))
+                                            .build(),
+                                    YDConf.FORM_QUERY.retrieve_list_all
+                            ).getData();
+
+                            if (ddlist != null && !ddlist.isEmpty()) {
+                                for (Map<String, Object> khitem : ddlist) {
+                                    Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
+                                    if (khformData != null) {
+                                        Object xsddbhObj = khformData.get("textField_mjs6fuwo");
+                                        String xsddbhStr = xsddbhObj != null ? xsddbhObj.toString() : null;
+
+                                        if (xsddbh.equals(xsddbhStr)) {
+                                            ddformInstanceId = (String) khitem.get("formInstanceId");
+                                            ddbh = xsddbhStr;
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.error("查询订单数据异常: xsddbh={}", xsddbh, e);
+                        }
+                    }
+
+                    // 构建更新数据
+                    HashMap<Object, Object> updateMap = new HashMap<>();
+                    updateMap.put("tableField_mh9woanl", tableList);
+
+                    // 添加关联表单数据
+                    if (ddbh != null && ddformInstanceId != null) {
+                        updateMap.put("associationFormField_mh9woamy",
+                                Arrays.asList(getddAss(ddbh, ddformInstanceId)));
+                    }
+
+                    // 添加主表字段
+                    updateMap.put("textField_mh9woanm", String.valueOf(paymentItem.get("djlx")));
+                    updateMap.put("textField_mh9woann", String.valueOf(paymentItem.get("fkdwlx")));
+                    updateMap.put("textField_mh9woamt", djbh);
+                    updateMap.put("textField_mh9woamz", String.valueOf(paymentItem.get("skgld")));
+                    updateMap.put("textField_mh9woano", String.valueOf(paymentItem.get("bb")));
+
+                    // 处理日期字段
+                    Object ywrqObj = paymentItem.get("ywrq");
+                                updateMap.put("dateField_mh9woan5", safeConvertDateTimeToString(ywrqObj));
+
+
+                    updateMap.put("textField_mh9woanp", String.valueOf(paymentItem.get("wldwlx")));
+                    updateMap.put("textField_mh9woanq", String.valueOf(paymentItem.get("wldw")));
+                    updateMap.put("numberField_mh9woanc", safeFormatBigDecimalToString(paymentItem.get("ysje")));
+                    updateMap.put("numberField_mh9woand", safeFormatBigDecimalToString(paymentItem.get("ssje")));
+                    updateMap.put("textField_mhjxv2tf", String.valueOf(paymentItem.get("xsy")));
+                    updateMap.put("textField_mhjxv2tg", String.valueOf(paymentItem.get("xsbm")));
+                    updateMap.put("textareaField_mh9woank", String.valueOf(paymentItem.get("bz")));
+
+                    // 执行同步操作
+                    Object operationResult = ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-0569C06E47074C2981ADEEAFCE083EDAK5AM")
+                            .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                            .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mh9woamt", djbh)))
+                            .formDataJson(JSONObject.toJSONString(updateMap))
+                            .build(), YDConf.FORM_OPERATION.upsert);
+
+                    // 记录成功结果
+                    singleResult.put("operationResult", operationResult);
+                    singleResult.put("status", "success");
+                    singleResult.put("ddformInstanceId", ddformInstanceId);
+                    successCount++;
+
+//                    log.info("收款单同步成功: djbh={}, paymentReceiptId={}", djbh, paymentReceiptId);
+
+                } catch (Exception e) {
+                    String djbh = String.valueOf(paymentItem.get("djbh"));
+                    log.error("同步收款单数据异常: djbh={}", djbh, e);
+
+                    singleResult.put("djbh", djbh);
+                    singleResult.put("errorMsg", e.getMessage());
+                    singleResult.put("status", "fail");
+                    failCount++;
+                }
+
+                operationResults.add(singleResult);
+            }
+
+            // 构建返回结果
+            Map<String, Object> data = new HashMap<>();
+            data.put("operationResults", operationResults);
+            data.put("totalCount", kdYdPaymentReceipts.size());
+            data.put("successCount", successCount);
+            data.put("failCount", failCount);
+
+            result.put("code", failCount == 0 ? "200" : "300");
+            result.put("msg", "操作完成,成功" + successCount + "条,失败" + failCount + "条");
+            result.put("data", data);
+
+            log.info("【收款单同步任务】完成,共处理{}条数据,成功{}条,失败{}条",
+                    kdYdPaymentReceipts.size(), successCount, failCount);
+
+        } catch (Exception e) {
+            log.error("收款单同步任务执行异常", e);
+            result.put("code", "500");
+            result.put("msg", "系统异常:" + e.getMessage());
+            result.put("data", new HashMap<>());
+        } finally {
+            MDC.remove("MDC_KEY_PID");
+        }
+
+        return result;
+    }
+    private String safeConvertDateTimeToString(Object dateTime) {
+        try {
+            if (dateTime instanceof LocalDateTime) {
+                return String.valueOf(((LocalDateTime) dateTime)
+                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+            }
+            if (dateTime instanceof Date) return String.valueOf(((Date) dateTime).getTime());
+            if (dateTime instanceof Long) return String.valueOf(dateTime);
+            if (dateTime instanceof Integer) {
+                long t = ((Integer) dateTime).longValue();
+                return String.valueOf(t < 10000000000L ? t * 1000L : t);
+            }
+            if (dateTime instanceof String) {
+                String s = ((String) dateTime).trim();
+                if (s.matches("\\d+")) {
+                    return String.valueOf(s.length() == 10 ? Long.parseLong(s) * 1000L : Long.parseLong(s));
+                }
+            }
+            return "";
+        } catch (Exception e) { return ""; }
+    }
+    // 辅助方法 - 安全格式化 BigDecimal 为字符串(保留2位小数)
+    private String safeFormatBigDecimalToString(Object value) {
+        if (value == null) {
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
+        }
+        try {
+            if (value instanceof BigDecimal) {
+                return ((BigDecimal) value).setScale(2, RoundingMode.HALF_UP).toString();
+            } else if (value instanceof Number) {
+                return BigDecimal.valueOf(((Number) value).doubleValue())
+                        .setScale(2, RoundingMode.HALF_UP).toString();
+            } else if (value instanceof String) {
+                String strVal = ((String) value).trim();
+                if (strVal.isEmpty() || "null".equalsIgnoreCase(strVal)) {
+                    return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
+                }
+                return new BigDecimal(strVal).setScale(2, RoundingMode.HALF_UP).toString();
+            }
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
+        } catch (Exception e) {
+            log.warn("格式化BigDecimal数据异常: value={}", value, e);
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toString();
+        }
+    }
+
+    // 获取订单关联数据
+    private Object getddAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C", "receipt", id, title, "");
+    }
+
+    // 辅助方法 - 安全格式化 BigDecimal 数据(保留2位小数)
+    private BigDecimal safeFormatBigDecimal(Object value) {
+        if (value == null) {
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        }
+        try {
+            if (value instanceof BigDecimal) {
+                return ((BigDecimal) value).setScale(2, RoundingMode.HALF_UP);
+            } else if (value instanceof Number) {
+                return BigDecimal.valueOf(((Number) value).doubleValue()).setScale(2, RoundingMode.HALF_UP);
+            } else if (value instanceof String) {
+                String strVal = ((String) value).trim();
+                if (strVal.isEmpty() || "null".equalsIgnoreCase(strVal)) {
+                    return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+                }
+                return new BigDecimal(strVal).setScale(2, RoundingMode.HALF_UP);
+            }
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        } catch (Exception e) {
+            log.warn("格式化BigDecimal数据异常: value={}", value, e);
+            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
+        }
+    }
+
+    // 获取应收单关联数据
+    private Object getysdAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-AADBCDA8126F41A0ADDEE3353828583192M8", "receipt", id, title, "");
+    }
+
     private static LocalDateTime parseTimestamp(String timestampStr) {
         if (timestampStr == null || timestampStr.trim().isEmpty()) return null;
         try {

+ 390 - 3
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdTransferServiceImpl.java

@@ -1,5 +1,7 @@
 package com.malk.huagao.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.malk.huagao.entity.KdYdDelivery;
 import com.malk.huagao.entity.KdYdDeliveryDetail;
@@ -13,6 +15,7 @@ import com.malk.server.aliwork.YDParam;
 import com.malk.server.dingtalk.DDR_New;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -22,8 +25,9 @@ import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.List;
-import java.util.Map;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -34,6 +38,7 @@ import java.util.Map;
  * @since 2025-11-12
  */
 @Service
+@Slf4j
 public class KdYdTransferServiceImpl extends ServiceImpl<KdYdTransferMapper, KdYdTransfer> implements IKdYdTransferService {
     @Autowired
     private YDClient ydClient;
@@ -52,6 +57,7 @@ public class KdYdTransferServiceImpl extends ServiceImpl<KdYdTransferMapper, KdY
             String bm = UtilMap.getString(map, "bm");
             KdYdTransfer kdYdTransfer = new KdYdTransfer();
             kdYdTransfer.setOperationType("3");
+            kdYdTransfer.setSyncStatus("0");
             kdYdTransferMapper.update(kdYdTransfer, new LambdaQueryWrapper<KdYdTransfer>().eq(KdYdTransfer::getDjbh, bm));
             return; // 或者根据你的业务逻辑返回相应的结果
         }
@@ -160,6 +166,382 @@ public class KdYdTransferServiceImpl extends ServiceImpl<KdYdTransferMapper, KdY
 //                        .useLatestVersion(true).build(), YDConf.FORM_OPERATION.update);
     }
 
+    @Override
+    public Map<String, Object> insertTransfer1(Map json) {
+        HashMap<String, Object> result = new HashMap<>();
+
+        try {
+            MDC.put("MDC_KEY_PID", "1003"); // 设置不同的 PID 以便区分日志
+            List<Map<String, Object>> kdYdTransferDels = UtilMap.getList(json, "data");
+            String action = UtilMap.getString(json, "action");
+            String table = UtilMap.getString(json, "table");
+
+            // 批量删除处理
+            if (!kdYdTransferDels.isEmpty() && "del".equals(action) && "KD_YD_TRANSFER".equals(table)) {
+                log.info("开始处理调拨单删除操作,共{}条数据", kdYdTransferDels.size());
+                ArrayList<String> deleteList = new ArrayList<>();
+                int deleteSuccessCount = 0;
+
+                for (Map<String, Object> item : kdYdTransferDels) {
+                    try {
+                        String djbh = String.valueOf(item.get("djbh"));
+
+                        List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                                .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_miptelgc", djbh)))
+                                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                        if (list1 != null && !list1.isEmpty()) {
+                            for (Map map : list1) {
+                                String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                                if (formInstanceId != null) {
+                                    deleteList.add(formInstanceId);
+                                }
+                            }
+                            deleteSuccessCount++;
+                        } else {
+                            log.warn("未找到对应的调拨单数据: djbh={}", djbh);
+                        }
+
+                    } catch (Exception e) {
+                        log.error("删除调拨单数据查询异常: djbh={}", item.get("djbh"), e);
+                    }
+                }
+
+                // 执行批量删除
+                if (!deleteList.isEmpty()) {
+                    try {
+                        ydClient.operateData(YDParam.builder()
+                                .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                                .formInstanceIdList(deleteList)
+                                .build(), YDConf.FORM_OPERATION.delete_batch);
+                        log.info("调拨单批量删除完成,共删除{}条数据", deleteList.size());
+                    } catch (Exception e) {
+                        log.error("调拨单批量删除操作异常", e);
+                    }
+                }
+
+                // 返回删除结果
+                result.put("code", "200");
+                result.put("msg", "删除成功,共删除" + deleteList.size() + "条数据");
+                result.put("data", new HashMap<String, Object>() {{
+                    put("deletedCount", deleteList.size());
+                    put("deletedIds", deleteList);
+                }});
+                return result;
+            } else if ("del".equals(action)) {
+                log.info("【调拨单删除任务】无需要删除的数据");
+                result.put("code", "200");
+                result.put("msg", "无需要删除的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            // 同步新增/更新数据
+            List<Map<String, Object>> kdYdTransfers = UtilMap.getList(json, "data");
+            if (kdYdTransfers.isEmpty()) {
+                log.info("【调拨单同步任务】无需要同步的数据,结束");
+                result.put("code", "200");
+                result.put("msg", "无需要同步的数据");
+                result.put("data", new HashMap<>());
+                return result;
+            }
+
+            log.info("【调拨单同步任务】开始同步,共{}条数据", kdYdTransfers.size());
+
+            List<Map<String, Object>> operationResults = new ArrayList<>();
+            int successCount = 0;
+            int failCount = 0;
+
+            for (Map<String, Object> transferItem : kdYdTransfers) {
+                Map<String, Object> singleResult = new HashMap<>();
+
+                try {
+                    String djbh = String.valueOf(transferItem.get("djbh"));
+                    List<Map<String, Object>> tableListData = UtilMap.getList(transferItem, "tableList");
+                    String  transferId = UtilMap.getString(transferItem, "transferId");
+
+                    // 检查明细数据是否存在
+                    if (tableListData == null || tableListData.isEmpty()) {
+                        log.warn("调拨单明细数据为空: djbh={}", djbh);
+                        singleResult.put("errorMsg", "明细数据为空");
+                        singleResult.put("status", "fail");
+                        failCount++;
+                        operationResults.add(singleResult);
+                        continue;
+                    }
+
+                    ArrayList<Object> tableList = new ArrayList<>();
+                    List<Map<String, Object>> tableListxlh = new ArrayList<>();
+
+                    // 处理明细数据
+                    for (Map<String, Object> detailItem : tableListData) {
+                        HashMap<String, String> tablemap = new HashMap<>();
+                        tablemap.put("textField_mhubzsav", String.valueOf(detailItem.get("wlbm")));
+                        tablemap.put("textField_mhubzsaw", String.valueOf(detailItem.get("wlmc")));
+                        tablemap.put("textField_mhubzsax", String.valueOf(detailItem.get("ggxh")));
+                        tablemap.put("textField_mhubzsay", String.valueOf(detailItem.get("dw")));
+                        tablemap.put("textareaField_mjshnw4c", String.valueOf(detailItem.get("kddh")));
+                        tablemap.put("numberField_mhubzsaz", safeConvertBigDecimalToString(detailItem.get("dbsl")));
+                        tablemap.put("textField_mhubzsb0", String.valueOf(detailItem.get("ph")));
+                        tablemap.put("textField_mhubzsb1", String.valueOf(detailItem.get("dcck")));
+                        tablemap.put("textField_mhubzsb5", String.valueOf(detailItem.get("dcckzt")));
+                        tablemap.put("textField_mhubzsb2", String.valueOf(detailItem.get("dccw")));
+                        tablemap.put("textField_mhubzsb3", String.valueOf(detailItem.get("drck")));
+                        tablemap.put("textField_mhubzsb6", String.valueOf(detailItem.get("drckzt")));
+                        tablemap.put("textField_mhubzsb4", String.valueOf(detailItem.get("drcw")));
+
+                        // 处理序列号明细
+                        String xlhjh = String.valueOf(detailItem.get("xlh"));
+                        if (xlhjh != null && !xlhjh.trim().isEmpty() && !"null".equals(xlhjh)) {
+                            List<Map<String, Object>> currentXlhList = Arrays.stream(xlhjh.split(","))
+                                    .map(String::trim)
+                                    .filter(item -> !item.isEmpty())
+                                    .map(item -> {
+                                        Map<String, Object> xlhMap = new HashMap<>();
+                                        xlhMap.put("textField_mf6a0h6w", item);
+                                        xlhMap.put("textField_mjqst61l", String.valueOf(detailItem.get("wlbm")));
+                                        xlhMap.put("textField_mjqst61m", String.valueOf(detailItem.get("ggxh")));
+                                        return xlhMap;
+                                    })
+                                    .collect(Collectors.toList());
+
+                            tableListxlh.addAll(currentXlhList);
+                            tableList.add(tablemap);
+                        }
+                    }
+
+                    // 查询关联表单数据
+                    String xsddbh = String.valueOf(transferItem.get("ddbh"));
+                    String fhtzdbh = String.valueOf(transferItem.get("fhtzdbh"));
+                    String ddformInstanceId = null;
+                    String fhdformInstanceId = null;
+                    String ddbh = null;
+                    String fhdbh = null;
+                    String jydate = null;
+                    String ghrq = null;
+                    String jyyy = null;
+                    String jtyy = null;
+                    String xsy = null;
+                    String khxypj = null;
+                    String fj = null;
+
+                    try {
+                        log.debug("开始查询订单数据: xsddbh={}", xsddbh);
+
+                        // 查询订单数据
+                        if (xsddbh != null && !"null".equals(xsddbh) && !xsddbh.trim().isEmpty()) {
+                            List<Map<String, Object>> ddlist = (List<Map<String, Object>>) ydClient.queryData(
+                                    YDParam.builder()
+                                            .formUuid("FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C")
+                                            .searchCondition(JSON.toJSONString(UtilMap.map("textField_mjs6fuwo", xsddbh)))
+                                            .build(),
+                                    YDConf.FORM_QUERY.retrieve_list_all
+                            ).getData();
+
+                            if (ddlist != null && !ddlist.isEmpty()) {
+                                for (Map<String, Object> khitem : ddlist) {
+                                    Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
+                                    if (khformData == null) continue;
+
+                                    Object serialObj = khformData.get("textField_mjs6fuwo");
+                                    String serialStr = serialObj != null ? serialObj.toString() : null;
+
+                                    if (xsddbh.equals(serialStr)) {
+                                        ddformInstanceId = safeToString(khitem.get("formInstanceId"));
+                                        ddbh = serialStr;
+                                        jydate = safeToString(khformData.get("dateField_mdya1lom"));
+                                        ghrq = safeToString(khformData.get("dateField_meqpbxsj"));
+                                        jyyy = safeToString(khformData.get("multiSelectField_meqpbxsc"));
+                                        jtyy = safeToString(khformData.get("textareaField_meqpbxsd"));
+                                        khxypj = safeToString(khformData.get("selectField_mewirdx4"));
+                                        xsy = safeToString(khformData.get("employeeField_mejowmng_id"));
+                                        fj = safeToString(khformData.get("attachmentField_mfoqcctz"));
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                        // 查询发货单数据
+                        if (fhtzdbh != null && !"null".equals(fhtzdbh) && !fhtzdbh.trim().isEmpty()) {
+                            List<Map<String, Object>> fhdlist = (List<Map<String, Object>>) ydClient.queryData(
+                                    YDParam.builder()
+                                            .formUuid("FORM-FAE2575E112644ED914CAB4FEC9309F32AVR")
+                                            .searchCondition(JSON.toJSONString(UtilMap.map("serialNumberField_mheazm7w", fhtzdbh)))
+                                            .build(),
+                                    YDConf.FORM_QUERY.retrieve_list_all
+                            ).getData();
+
+                            if (fhdlist != null && !fhdlist.isEmpty()) {
+                                for (Map<String, Object> fhditem : fhdlist) {
+                                    Map<String, Object> fhdformData = (Map<String, Object>) fhditem.get("formData");
+                                    if (fhdformData == null) continue;
+
+                                    Object serialObj = fhdformData.get("serialNumberField_mheazm7w");
+                                    String serialStr = serialObj != null ? serialObj.toString() : null;
+
+                                    if (fhtzdbh.equals(serialStr)) {
+                                        fhdformInstanceId = safeToString(fhditem.get("formInstanceId"));
+                                        fhdbh = serialStr;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                    } catch (Exception e) {
+                        log.error("查询关联表单数据异常: xsddbh={}, fhtzdbh={}", xsddbh, fhtzdbh, e);
+                    }
+
+                    // 构建更新数据
+                    HashMap<String, Object> updateMap = new HashMap<>();
+                    updateMap.put("tableField_mhubzsau", tableList);
+                    updateMap.put("tableField_mips137b", tableListxlh);
+
+                    // 添加关联表单数据
+                    if (ddbh != null && ddformInstanceId != null) {
+                        updateMap.put("associationFormField_mhubzsaf",
+                                Collections.singletonList(getddAss(ddbh, ddformInstanceId)));
+                    }
+                    if (fhdbh != null && fhdformInstanceId != null) {
+                        updateMap.put("associationFormField_mjzervdt",
+                                Collections.singletonList(getfhdAss(fhdbh, fhdformInstanceId)));
+                    }
+
+                    // 添加订单相关字段(如果所有字段都存在)
+                    if (jydate != null && ghrq != null && jyyy != null && jtyy != null
+                            && xsy != null && khxypj != null) {
+                        updateMap.put("dateField_mdya1lom", jydate);
+                        updateMap.put("dateField_meqpbxsj", ghrq);
+                        updateMap.put("multiSelectField_meqpbxsc", jyyy);
+                        updateMap.put("textareaField_meqpbxsd", jtyy);
+                        updateMap.put("employeeField_mejowmng", xsy);
+                        updateMap.put("selectField_mewirdx4", khxypj);
+                        updateMap.put("attachmentField_mfoqcctz", fj);
+                    }
+
+                    // 添加主表字段
+                    updateMap.put("textField_mjzervdu", fhtzdbh);
+                    updateMap.put("textField_miquh5zj", ddformInstanceId);
+                    updateMap.put("selectField_mhubzsa5", String.valueOf(transferItem.get("djlx")));
+                    updateMap.put("textField_mhubzsas", String.valueOf(transferItem.get("kh")));
+                    updateMap.put("textField_miptelgh", String.valueOf(transferItem.get("ddbh")));
+                    updateMap.put("textField_miptelgc", djbh);
+                    updateMap.put("textField_miptelgd", String.valueOf(transferItem.get("cgy")));
+                    updateMap.put("selectField_mhubzsa7", String.valueOf(transferItem.get("dchzlx")));
+                    updateMap.put("textField_mhubzsa6", String.valueOf(transferItem.get("ywlx")));
+                    // 处理日期字段
+                    Object rq = transferItem.get("rq");
+                            updateMap.put("dateField_mhubzsab", safeConvertDateTimeToString(rq));
+                    updateMap.put("selectField_mhubzsa9", String.valueOf(transferItem.get("drhzlx")));
+                    updateMap.put("selectField_mhubzsaa", String.valueOf(transferItem.get("dbfx")));
+                    updateMap.put("selectField_mhubzsac", String.valueOf(transferItem.get("dbdlx")));
+                    updateMap.put("textField_miptelge", String.valueOf(transferItem.get("dcbm")));
+                    updateMap.put("textField_miptelgf", String.valueOf(transferItem.get("dchz")));
+                    updateMap.put("textField_miptelgg", String.valueOf(transferItem.get("drbm")));
+                    updateMap.put("selectField_mhubzsah", String.valueOf(transferItem.get("hdfs")));
+                    updateMap.put("selectField_mhubzsai", String.valueOf(transferItem.get("ysfs")));
+                    updateMap.put("selectField_mhubzsar", String.valueOf(transferItem.get("kdgs")));
+                    updateMap.put("selectField_mhubzsag", String.valueOf(transferItem.get("fkfs")));
+
+                    // 执行同步操作
+                    Object operationResult = ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                            .noExecuteExpression(false)
+                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_miptelgc", djbh)))
+                            .formDataJson(JSONObject.toJSONString(updateMap))
+                            .build(), YDConf.FORM_OPERATION.upsert);
+
+                    // 记录成功结果
+                    singleResult.put("operationResult", operationResult);
+                    singleResult.put("status", "success");
+                    singleResult.put("ddformInstanceId", ddformInstanceId);
+                    singleResult.put("fhdformInstanceId", fhdformInstanceId);
+                    successCount++;
+
+                    log.info("调拨单同步成功: djbh={}, transferId={}", djbh, transferId);
+
+                } catch (Exception e) {
+                    log.error("同步单条调拨单数据异常: djbh={}", transferItem.get("djbh"), e);
+                    singleResult.put("errorMsg", e.getMessage());
+                    singleResult.put("status", "fail");
+                    failCount++;
+                }
+
+                operationResults.add(singleResult);
+            }
+
+            // 构建返回结果
+            Map<String, Object> data = new HashMap<>();
+            data.put("operationResults", operationResults);
+            data.put("totalCount", kdYdTransfers.size());
+            data.put("successCount", successCount);
+            data.put("failCount", failCount);
+
+            result.put("code", failCount == 0 ? "200" : "300");
+            result.put("msg", "操作完成,成功" + successCount + "条,失败" + failCount + "条");
+            result.put("data", data);
+
+            log.info("【调拨单同步任务】完成,共处理{}条数据,成功{}条,失败{}条",
+                    kdYdTransfers.size(), successCount, failCount);
+
+        } catch (Exception e) {
+            log.error("调拨单同步任务执行异常", e);
+            result.put("code", "500");
+            result.put("msg", "系统异常:" + e.getMessage());
+            result.put("data", new HashMap<>());
+        }
+        return result;
+    }
+//    private String safeConvertDateTimeToString(Object dateTime) {
+//        try {
+//            if (dateTime instanceof LocalDateTime) {
+//                return String.valueOf(((LocalDateTime) dateTime)
+//                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
+//            }
+//            if (dateTime instanceof Date) return String.valueOf(((Date) dateTime).getTime());
+//            if (dateTime instanceof Long) return String.valueOf(dateTime);
+//            if (dateTime instanceof Integer) {
+//                long t = ((Integer) dateTime).longValue();
+//                return String.valueOf(t < 10000000000L ? t * 1000L : t);
+//            }
+//            if (dateTime instanceof String) {
+//                String s = ((String) dateTime).trim();
+//                if (s.matches("\\d+")) {
+//                    return String.valueOf(s.length() == 10 ? Long.parseLong(s) * 1000L : Long.parseLong(s));
+//                }
+//            }
+//            return "";
+//        } catch (Exception e) { return ""; }
+//    }
+    // 辅助方法 - 安全转换 BigDecimal 为字符串
+    private String safeConvertBigDecimalToString(Object value) {
+        if (value == null) {
+            return "";
+        }
+        if (value instanceof BigDecimal) {
+            return ((BigDecimal) value).toPlainString();
+        }
+        return String.valueOf(value);
+    }
+
+    // 辅助方法 - 安全转换日期时间为字符串
+    private String safeConvertDateTimeToString(Object value) {
+        if (value == null) {
+            return "";
+        }
+        if (value instanceof LocalDateTime) {
+            return ((LocalDateTime) value).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
+        }
+        return String.valueOf(value);
+    }
+
+    // 辅助方法 - 安全转换为字符串
+    private String safeToString(Object obj) {
+        return obj != null ? obj.toString() : null;
+    }
+
     private static LocalDateTime parseTimestamp(String timestampStr) {
         if (timestampStr == null || timestampStr.trim().isEmpty()) return null;
         try {
@@ -183,7 +565,12 @@ public class KdYdTransferServiceImpl extends ServiceImpl<KdYdTransferMapper, KdY
             return defaultValue;
         }
     }
-
+    private Object getddAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C", "receipt", id, title, "");
+    }
+    private Object getfhdAss(String title, String id) {
+        return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-FAE2575E112644ED914CAB4FEC9309F32AVR", "receipt", id, title, "");
+    }
     private String safeGetString(Map formData, String key) {
         Object val = formData.get(key);
         return val == null ? "" : String.valueOf(val);

+ 1 - 0
mjava-huagao/src/main/java/com/malk/huagao/service/impl/KdYdZpServiceImpl.java

@@ -53,6 +53,7 @@ public class KdYdZpServiceImpl extends ServiceImpl<KdYdZpMapper, KdYdZp> impleme
             String bm = UtilMap.getString(map, "bm");
             KdYdZp kdYdZp = new KdYdZp();
             kdYdZp.setOperationType("3");
+            kdYdZp.setSyncStatus("0");
             kdYdZpMapper.update(kdYdZp, new LambdaQueryWrapper<KdYdZp>().eq(KdYdZp::getDjbh, bm));
             return; // 或者根据你的业务逻辑返回相应的结果
         }

+ 39 - 1
mjava-huagao/src/main/java/com/malk/huagao/service/impl/McProjectServiceImpl.java

@@ -1,19 +1,31 @@
 package com.malk.huagao.service.impl;
 
 import com.malk.core.McProject;
+import com.malk.huagao.service.HuaGaoService;
 import com.malk.huagao.service.McProjectService;
 import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilDateTime;
+import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Arrays;
+import java.util.List;
+
 @Slf4j
 @Service
 public class McProjectServiceImpl implements McProjectService {
+    @Autowired
+    private Environment environment;
 
     @Autowired
-    private YDClient ydClient;
+    private HuaGaoService huaGaoService;
 
     @Override
     public void init() {
@@ -22,5 +34,31 @@ public class McProjectServiceImpl implements McProjectService {
         McProject.addYida("1002",new String[] {"APP_YONR16SZSUIZCKXJUNSY","TNA66KB1AEDXKQHQ8IJBG53BDW7Q27TM33HDMADI"});//数据分析看板
         McProject.addYida("1003",new String[] {"APP_VQDMMWS6OR1VHL8VMFD3","XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2"});//华高CRM
         log.info("项目加载完毕:1001,1002,1003");
+
+        // 生产环境2专属逻辑
+        if (isProdEnvironment()) {
+            executeProductionMethod();
+        }
+    }
+
+    private boolean isProdEnvironment() {
+        String[] activeProfiles = environment.getActiveProfiles();
+        for (String profile : activeProfiles) {
+            if ("prod2".equals(profile)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    @Profile("prod2")
+    private void executeProductionMethod() {
+        log.info("异常重启考勤同步-周度");
+        LocalDateTime startTime = LocalDate.now().minusWeeks(1).atTime(LocalTime.MIN);
+        LocalDateTime endTime = LocalDate.now().atTime(LocalTime.MIN);
+        try {
+            huaGaoService.syncKqData(startTime, endTime);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 }

+ 370 - 18
mjava-huagao/src/main/java/com/malk/huagao/service/impl/YdHuaGaoServiceImpl.java

@@ -10,16 +10,18 @@ import com.malk.huagao.service.YdHuaGaoService;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McR;
 import com.malk.server.dingtalk.DDConf;
 import com.malk.service.aliwork.YDClient;
 import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
-import org.checkerframework.checker.units.qual.A;
+import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -58,6 +60,10 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
     @Autowired
     private KdYdMaterialMapper kdYdMaterialMapper;
     @Autowired
+    private KdYdTransferMapper kdYdTransferMapper;
+    @Autowired
+    private KdYdTransferDetailMapper kdYdTransferDetailMapper;
+    @Autowired
     private YDConf ydConf;
     @Autowired
     private DDConf ddConf;
@@ -233,6 +239,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
 
     @Override
     public void synckdYdOutbound() {
+
         log.info("定时同步-出库单");
         // 查询需要删除的数据
         LambdaQueryWrapper<KdYdOutbound> outbounddel = new LambdaQueryWrapper<>();
@@ -332,7 +339,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 List<KdYdOutboundDetail> kdYdOutboundDetails = kdYdOutboundDetailMapper.selectList(outbounddetailqw);
 
                 ArrayList<Object> tableList = new ArrayList<>();
-                List<Map<String, Object>> tableListxlh = new ArrayList<>();
+                List<Map<String, Object>> tableListxlh = new ArrayList<>(); // 在循环外初始化
                 for (KdYdOutboundDetail kdYdOutboundDetail : kdYdOutboundDetails) {
                     HashMap<String, String> tablemap = new HashMap<>();
                     HashMap<String, String> tablemapxlh = new HashMap<>();
@@ -367,21 +374,30 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                     tablemap.put("textField_mf6a0h6y", kdYdOutboundDetail.getJx());
                     String xlhjh = kdYdOutboundDetail.getXlh();
                     if (xlhjh != null && !xlhjh.trim().isEmpty()) {
-                         tableListxlh = Arrays.stream(xlhjh.split(","))
+                        List<Map<String, Object>> currentXlhList = Arrays.stream(xlhjh.split(","))
                                 .map(String::trim)
                                 .filter(item -> !item.isEmpty())
                                 .map(item -> {
                                     Map<String, Object> map = new HashMap<>();
-                                    map.put("textField_mf6a0h6w", item);
+                                    map.put("textField_mf6a0h6w", item); // 序列号
+                                    map.put("textField_mjqst61l", kdYdOutboundDetail.getWlbm()); // 对应的物料编码
+                                    map.put("textField_mjqst61m", kdYdOutboundDetail.getGgxh());
                                     return map;
                                 })
                                 .collect(Collectors.toList());
+
+                        tableListxlh.addAll(currentXlhList); // 追加到总列表
                     }
+
+                    // 主表仍保留原始 xlh(可选)
+                    tablemap.put("textField_mf6a0h6w", kdYdOutboundDetail.getXlh());
                     tablemap.put("radioField_mf6a0h6h", kdYdOutboundDetail.getSfzp());
+
                     tableList.add(tablemap);
+
+                    // 更新同步状态
                     kdYdOutboundDetail.setSyncStatus("1");
                     kdYdOutboundDetailMapper.updateById(kdYdOutboundDetail);
-
                 }
 
                 String fhdformInstanceId = null;
@@ -391,7 +407,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
 
                     List<Map> ddlist = (List<Map>) ydClient.queryData(
                             YDParam.builder()
-                                    .formUuid("FORM-A7F03ACEE01D4F609550C86BF7FE87D35M6I")
+                                    .formUuid("FORM-FAE2575E112644ED914CAB4FEC9309F32AVR")
                                     .appType("APP_VQDMMWS6OR1VHL8VMFD3")
                                     .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
                                     .searchCondition(JSON.toJSONString(UtilMap.map("serialNumberField_mheazm7w", deliveryId)))
@@ -423,12 +439,12 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 }
                 HashMap<Object, Object> updateMap = new HashMap<>();
                 updateMap.put("tableField_mejnamfd", tableList);
-                updateMap.put("tableField_migw33w7", tableListxlh);
+                updateMap.put("tableField_mips137b", tableListxlh);
                 if (fhdbh != null && fhdformInstanceId != null) {
                     updateMap.put("associationFormField_mejmml36",
-                            Arrays.asList(getfhdAss(fhdbh, fhdformInstanceId)));
+                            Arrays.asList(getfhdAss(fhdformInstanceId,fhdbh)));
                 }
-                 updateMap.put("dateField_krbgloam", kdYdOutbound.getDateTime() != null ? String.valueOf(kdYdOutbound.getDateTime().atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli()) : "");
+                updateMap.put("dateField_krbgloam", kdYdOutbound.getDateTime() != null ? String.valueOf(kdYdOutbound.getDateTime().atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli()) : "");
                 updateMap.put("textField_krnn5bmr", kdYdOutbound.getXsDept());
                 updateMap.put("textField_mhjxw689", kdYdOutbound.getFhDept());
                 updateMap.put("textField_mhjxw686", kdYdOutbound.getCgy());
@@ -481,7 +497,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
         // 批量删除处理
         if (!kdYdReceivabledels.isEmpty()) {
             log.info("开始处理应收单删除操作,共{}条数据", kdYdReceivabledels.size());
-            ArrayList<String > deleteList = new ArrayList<>();
+            ArrayList<String> deleteList = new ArrayList<>();
             int deleteSuccessCount = 0;
 
             for (KdYdReceivable kdYdReceivable : kdYdReceivabledels) {
@@ -726,6 +742,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 }
                 updateData.put("tableField_mhiui6v5", tableListPay);
                 updateData.put("textField_mg3a0tgs", kdYdReceivable.getDjbh());
+                updateData.put("textField_mj15q3dk", ckddjbh);
                 updateData.put("selectField_mg3a0th4", kdYdReceivable.getDjlx());
                 updateData.put("selectField_mev13l3r", kdYdReceivable.getSktj());
                 updateData.put("dateField_mejmtic3", kdYdReceivable.getEndTime().atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli());
@@ -813,7 +830,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
         log.info("定时同步-物料单");
         // 查询需要删除的数据
         LambdaQueryWrapper<KdYdMaterial> materialdel = new LambdaQueryWrapper<>();
-        materialdel.eq(KdYdMaterial::getOperationType, 3)  // 修正:使用 materialdel 而不是 materialqw
+        materialdel.eq(KdYdMaterial::getOperationType, "3")
                 .eq(KdYdMaterial::getSyncStatus, "0");
         List<KdYdMaterial> kdYdMaterialdels = kdYdMaterialMapper.selectList(materialdel);
 
@@ -825,12 +842,12 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
 
             for (KdYdMaterial kdYdMaterial : kdYdMaterialdels) {
                 try {
-                    String wlbm = kdYdMaterial.getWlbm();
+                    String wlbm = String.valueOf(kdYdMaterial.getFMATERIALID());
                     List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
                             .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
                             .appType("APP_VQDMMWS6OR1VHL8VMFD3")  // 新增:添加应用参数
                             .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")  // 新增:添加系统令牌
-                            .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_mfxbtcdh", wlbm)))
+                            .searchFieldJson(JSONObject.toJSONString(UtilMap.map("textField_misfb2ft", wlbm)))
                             .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
 
                     if (list1 != null && !list1.isEmpty()) {
@@ -890,6 +907,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 String wlmc = kdYdMaterial.getWlmc();
                 String xh = kdYdMaterial.getXh();
                 String gg = kdYdMaterial.getGg();
+                String jdnm = String.valueOf(kdYdMaterial.getFMATERIALID());
                 String wlfz = kdYdMaterial.getWlfz();
                 String wlsx = kdYdMaterial.getWlsx();
                 String jbdw = kdYdMaterial.getJbdw();
@@ -905,6 +923,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 String jyzt = kdYdMaterial.getJyzt();
                 String dzl = kdYdMaterial.getDzl();
                 String pzzt = kdYdMaterial.getPzzt();
+                String sdbb = kdYdMaterial.getSpeedname();
                 String wlbt = wlmc + wlbm;
 //                String materialtitle = kdYdMaterial.getMaterialtitle();
                 Map updateFormData = new HashMap();
@@ -912,6 +931,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 updateFormData.put("textField_mfxbtcdh", wlbm);
                 updateFormData.put("textField_l43jpnsg", xh);
                 updateFormData.put("textField_lqbxkzbq", gg);
+                updateFormData.put("textField_misfb2ft", jdnm);
                 updateFormData.put("textField_mhlbx8hi", wlfz);
                 updateFormData.put("textField_l43jpnsh", wlsx);
                 updateFormData.put("textField_mfxbtcdo", jbdw);
@@ -921,8 +941,27 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 updateFormData.put("textField_mejl9nrp", dzl);
                 updateFormData.put("selectField_mejl9nrq", pzzt);
                 updateFormData.put("textField_mfxbtcdq", mrsl);
+                updateFormData.put("textField_mhabp7y0", sdbb);
                 updateFormData.put("textField_mfxbtcdr", chlb);
                 updateFormData.put("textField_mfxbtce5", xsy);
+                updateFormData.put("textField_mfxbtce6", sjzt);
+
+                updateFormData.put("dateField_ml4ikfa0",
+                        kdYdMaterial.getKsrq() != null && !kdYdMaterial.getKsrq().trim().isEmpty() ?
+                                java.time.LocalDate.parse(kdYdMaterial.getKsrq().trim())
+                                        .atStartOfDay(java.time.ZoneId.systemDefault())
+                                        .toInstant()
+                                        .toEpochMilli() :
+                                null
+                );
+                updateFormData.put("dateField_ml4ikfa1",
+                        kdYdMaterial.getJzrq() != null && !kdYdMaterial.getJzrq().trim().isEmpty() ?
+                                java.time.LocalDate.parse(kdYdMaterial.getJzrq().trim())
+                                        .atStartOfDay(java.time.ZoneId.systemDefault())
+                                        .toInstant()
+                                        .toEpochMilli() :
+                                null
+                );
 
                 //确保金额字段保留两位小数
                 if (xsjzj != null) {
@@ -938,8 +977,8 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                         .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90")
                         .appType("APP_VQDMMWS6OR1VHL8VMFD3")
                         .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
-//                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mg4h6mz5", wlbt)))
-                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_mfxbtcdh", wlbm)))
+                        .searchCondition(JSONObject.toJSONString(Arrays.asList(new YDSearch(
+                                "textField_misfb2ft", jdnm, "金蝶内码", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ))))
                         .formDataJson(JSONObject.toJSONString(updateFormData))
                         .build(), YDConf.FORM_OPERATION.upsert);
 
@@ -1211,7 +1250,7 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                     List<Map> ddlist = (List<Map>) ydClient.queryData(
                             YDParam.builder()
                                     .formUuid("FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C")
-                                    .searchCondition(JSON.toJSONString(UtilMap.map("serialNumberField_mewfgzku", xsddbh)))
+                                    .searchCondition(JSON.toJSONString(UtilMap.map("textField_mjs6fuwo", xsddbh)))
                                     .build(),
                             YDConf.FORM_QUERY.retrieve_list_all
                     ).getData();
@@ -1220,9 +1259,9 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                         for (Map<String, Object> khitem : ddlist) {
                             Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
 
-                            if (khformData != null && xsddbh.equals(khformData.get("serialNumberField_mewfgzku"))) {
+                            if (khformData != null && xsddbh.equals(khformData.get("textField_mjs6fuwo"))) {
                                 ddformInstanceId = (String) khitem.get("formInstanceId");
-                                ddbh = (String) khformData.get("serialNumberField_mewfgzku");
+                                ddbh = (String) khformData.get("textField_mjs6fuwo");
                                 break;
                             }
                         }
@@ -1284,6 +1323,319 @@ public class YdHuaGaoServiceImpl implements YdHuaGaoService {
                 successCount, failCount, kdYdPaymentReceipts.size());
     }
 
+    @Override
+    public void synckdYdTRANSFER() {
+        log.info("定时同步-调拨单");
+        LambdaQueryWrapper<KdYdTransfer> transferdel = new LambdaQueryWrapper<>();
+        transferdel.eq(KdYdTransfer::getOperationType, 3)
+                .eq(KdYdTransfer::getSyncStatus, "0");
+        List<KdYdTransfer> kdYdTRANSFERdels = kdYdTransferMapper.selectList(transferdel);
+
+        // 批量删除处理
+        if (!kdYdTRANSFERdels.isEmpty()) {
+            log.info("开始处理调拨单删除操作,共{}条数据", kdYdTRANSFERdels.size());
+            ArrayList<String> deleteList = new ArrayList<>();
+            int deleteSuccessCount = 0;
+
+            for (KdYdTransfer kdYdTransfer : kdYdTRANSFERdels) {
+                try {
+                    String djbh = kdYdTransfer.getDjbh();
+                    log.debug("查询需要删除的调拨单: djbh={}", djbh);
+
+                    List<Map> list1 = (List<Map>) ydClient.queryData(YDParam.builder()
+                            .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                            .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                            .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                            .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_miptelgc", djbh)))
+                            .build(), YDConf.FORM_QUERY.retrieve_list_all).getData();
+
+                    if (list1 != null && !list1.isEmpty()) {
+                        for (Map map : list1) {
+                            String formInstanceId = UtilMap.getString(map, "formInstanceId");
+                            if (formInstanceId != null) {
+                                deleteList.add(formInstanceId);
+                            }
+                        }
+                        deleteSuccessCount++;
+
+                        // 同时删除对应的子表数据
+                        Long transferId = kdYdTransfer.getId();
+                        LambdaQueryWrapper<KdYdTransferDetail> detailDelqw = new LambdaQueryWrapper<>();
+                        detailDelqw.eq(KdYdTransferDetail::getTransferId, transferId);
+                        List<KdYdTransferDetail> detailDels = kdYdTransferDetailMapper.selectList(detailDelqw);
+
+                        if (!detailDels.isEmpty()) {
+                            for (KdYdTransferDetail detail : detailDels) {
+                                detail.setSyncStatus("1");
+                                kdYdTransferDetailMapper.updateById(detail);
+                            }
+                        }
+                    } else {
+                        log.warn("未找到对应的调拨单数据: djbh={}", djbh);
+                    }
+
+                    // 删除操作完成后更新状态
+                    kdYdTransfer.setSyncStatus("1");
+                    kdYdTransferMapper.updateById(kdYdTransfer);
+
+                } catch (Exception e) {
+                    log.error("删除调拨单数据查询异常: djbh={}", kdYdTransfer.getDjbh(), e);
+                }
+            }
+
+            // 执行批量删除
+            if (!deleteList.isEmpty()) {
+                try {
+                    ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                            .appType("APP_VQDMMWS6OR1VHL8VMFD3")
+                            .systemToken("XE766X81JHKXK4Z27SYOI86CPCLQ3J1LV7ODMH2")
+                            .formInstanceIdList(deleteList)
+                            .build(), YDConf.FORM_OPERATION.delete_batch);
+                    log.info("调拨单批量删除完成,共删除{}条数据", deleteList.size());
+                } catch (Exception e) {
+                    log.error("调拨单批量删除操作异常", e);
+                }
+            }
+
+            log.info("调拨单删除操作处理完成: 成功查询={}, 待删除={}", deleteSuccessCount, deleteList.size());
+            return;
+        } else {
+            log.info("【调拨单删除任务】无需要删除的数据");
+        }
+        LambdaQueryWrapper<KdYdTransfer> paymentqw = new LambdaQueryWrapper<>();
+        paymentqw.eq(KdYdTransfer::getSyncStatus, "0");
+        List<KdYdTransfer> kdYdTransfers = kdYdTransferMapper.selectList(paymentqw);
+        if (kdYdTransfers.isEmpty()) {
+            log.info("【调拨单同步任务】无需要同步的数据,结束");
+            return;
+        }
+        log.info("【调拨单同步任务】开始同步,共{}条数据", kdYdTransfers.size());
+
+        int successCount = 0;
+        int failCount = 0;
+
+        for (KdYdTransfer kdYdTransfer : kdYdTransfers) {
+            try {
+                Long transferId = kdYdTransfer.getId();
+                String djbh = kdYdTransfer.getDjbh();
+
+                log.debug("开始同步调拨单: ID={}, 单据编号={}", transferId, djbh);
+
+                LambdaQueryWrapper<KdYdTransferDetail> transferdetailqw = new LambdaQueryWrapper<>();
+                transferdetailqw.eq(KdYdTransferDetail::getTransferId, transferId)
+                        .orderByAsc(KdYdTransferDetail::getDetailId);
+                List<KdYdTransferDetail> kdYdTransferDetails = kdYdTransferDetailMapper.selectList(transferdetailqw);
+                ArrayList<Object> tableList = new ArrayList<>();
+                List<Map<String, Object>> tableListxlh = new ArrayList<>();
+                for (KdYdTransferDetail kdYdTransferDetail : kdYdTransferDetails) {
+                    HashMap<String, String> tablemap = new HashMap<>();
+                    tablemap.put("textField_mhubzsav", kdYdTransferDetail.getWlbm());
+                    tablemap.put("textField_mhubzsaw", kdYdTransferDetail.getWlmc());
+                    tablemap.put("textField_mhubzsax", kdYdTransferDetail.getGgxh());
+                    tablemap.put("textField_mhubzsay", kdYdTransferDetail.getDw());
+                    tablemap.put("textareaField_mjshnw4c", kdYdTransferDetail.getKddh());
+                    tablemap.put("numberField_mhubzsaz", String.valueOf(kdYdTransferDetail.getDbsl()));
+                    tablemap.put("textField_mhubzsb0", kdYdTransferDetail.getPh());
+                    tablemap.put("textField_mhubzsb1", kdYdTransferDetail.getDcck());
+                    tablemap.put("textField_mhubzsb5", kdYdTransferDetail.getDcckzt());
+                    tablemap.put("textField_mhubzsb2", kdYdTransferDetail.getDccw());
+                    tablemap.put("textField_mhubzsb3", kdYdTransferDetail.getDrck());
+                    tablemap.put("textField_mhubzsb6", kdYdTransferDetail.getDrckzt());
+                    tablemap.put("textField_mhubzsb4", kdYdTransferDetail.getDrcw());
+                    String xlhjh = kdYdTransferDetail.getXlh();
+                    if (xlhjh != null && !xlhjh.trim().isEmpty()) {
+                        List<Map<String, Object>> currentXlhList = Arrays.stream(xlhjh.split(","))
+                                .map(String::trim)
+                                .filter(item -> !item.isEmpty())
+                                .map(item -> {
+                                    Map<String, Object> map = new HashMap<>();
+                                    map.put("textField_mf6a0h6w", item); // 序列号
+                                    map.put("textField_mjqst61l", kdYdTransferDetail.getWlbm()); // 对应的物料编码
+                                    map.put("textField_mjqst61m", kdYdTransferDetail.getGgxh());
+                                    return map;
+                                })
+                                .collect(Collectors.toList());
+
+                        tableListxlh.addAll(currentXlhList); // 追加到总列表
+                    }
+
+                    // 主表仍保留原始 xlh(可选)
+                    tablemap.put("textField_mf6a0h6w", kdYdTransferDetail.getXlh());
+//                    tablemap.put("radioField_mf6a0h6h", kdYdTransferDetail.getSfzp());
+
+                    tableList.add(tablemap);
+                    kdYdTransferDetail.setSyncStatus("1");
+                    kdYdTransferDetailMapper.updateById(kdYdTransferDetail);
+
+                }
+                String xsddbh = kdYdTransfer.getDdbh();
+                String fhtzdbh = kdYdTransfer.getFhtzdbh();
+                String ddformInstanceId = null;
+                String fhdformInstanceId = null;
+                String ddbh = null;
+                String fhdbh = null;
+                String jydate = null;
+                String ghrq = null;
+                String jyyy = null;
+                String jtyy = null;
+                String xsy = null;
+                String khxypj = null;
+                String fj = null;
+
+                try {
+                    log.debug("开始查询订单数据: xsddbh={}", xsddbh);
+
+                    // 宜搭返回的数据结构:List<Map<String, Object>>
+                    List<Map<String, Object>> ddlist = (List<Map<String, Object>>) ydClient.queryData(
+                            YDParam.builder()
+                                    .formUuid("FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C")
+                                    .searchCondition(JSON.toJSONString(UtilMap.map("textField_mjs6fuwo", xsddbh)))
+                                    .build(),
+                            YDConf.FORM_QUERY.retrieve_list_all
+                    ).getData();
+
+                    List<Map<String, Object>> fhdlist = (List<Map<String, Object>>) ydClient.queryData(
+                            YDParam.builder()
+                                    .formUuid("FORM-FAE2575E112644ED914CAB4FEC9309F32AVR")
+                                    .searchCondition(JSON.toJSONString(UtilMap.map("serialNumberField_mheazm7w", fhtzdbh)))
+                                    .build(),
+                            YDConf.FORM_QUERY.retrieve_list_all
+                    ).getData();
+                    if (fhdlist != null && !fhdlist.isEmpty()) {
+                        for (Map<String, Object> fhditem : fhdlist) {
+                            Map<String, Object> fhdformData = (Map<String, Object>) fhditem.get("formData");
+                            if (fhdformData == null) continue;
+                            Object serialObj1 = fhdformData.get("serialNumberField_mheazm7w");
+                            String serialStr1 = serialObj1 != null ? serialObj1.toString() : null;
+                            if (fhtzdbh.equals(serialStr1)) {
+                                fhdformInstanceId = safeToString(fhditem.get("formInstanceId"));
+                                fhdbh = serialStr1;
+                                break;
+                            }
+                        }
+                    }
+                    if (ddlist != null && !ddlist.isEmpty()) {
+                        for (Map<String, Object> khitem : ddlist) {
+                            Map<String, Object> khformData = (Map<String, Object>) khitem.get("formData");
+                            if (khformData == null) continue;
+
+                            // 安全获取字段值(避免 ClassCastException)
+                            Object serialObj = khformData.get("textField_mjs6fuwo");
+                            String serialStr = serialObj instanceof String ? (String) serialObj : String.valueOf(serialObj);
+
+                            if (xsddbh.equals(serialStr)) {
+                                ddformInstanceId = safeToString(khitem.get("formInstanceId"));
+                                ddbh = serialStr;
+                                jydate = safeToString(khformData.get("dateField_mdya1lom"));
+                                ghrq = safeToString(khformData.get("dateField_meqpbxsj"));
+                                jyyy = safeToString(khformData.get("multiSelectField_meqpbxsc"));
+                                jtyy = safeToString(khformData.get("textareaField_meqpbxsd"));
+                                khxypj = safeToString(khformData.get("selectField_mewirdx4"));
+                                xsy = safeToString(khformData.get("employeeField_mejowmng_id"));
+                                fj = safeToString(khformData.get("attachmentField_mfoqcctz"));
+                                break;
+                            }
+                        }
+
+                        if (ddformInstanceId == null) {
+                            log.warn("未找到与 xsddbh={} 完全匹配的订单数据", xsddbh);
+                        }
+                    } else {
+                        log.warn("未查询到订单数据: xsddbh={}", xsddbh);
+                    }
+
+                } catch (Exception e) {
+                    log.error("查询订单数据异常: xsddbh={}, 错误信息={}", xsddbh, e.getMessage(), e);
+                }
+
+// 构建更新数据
+                HashMap<String, Object> updateMap = new HashMap<>();
+                updateMap.put("tableField_mhubzsau", tableList);
+                updateMap.put("tableField_mips137b", tableListxlh);
+                if (ddbh != null && ddformInstanceId != null) {
+                    updateMap.put("associationFormField_mhubzsaf",
+                            Collections.singletonList(getddAss(ddbh, ddformInstanceId)));
+                }
+                if (fhdbh != null && fhdformInstanceId != null) {
+                    updateMap.put("associationFormField_mjzervdt",
+                            Collections.singletonList(getddAss(fhdbh, fhdformInstanceId)));
+
+                }
+// 只有所有必要字段都非空时才填充关联字段
+                if (jydate != null && ghrq != null && jyyy != null && jtyy != null
+                        && xsy != null && khxypj != null) {
+
+                    updateMap.put("dateField_mdya1lom", jydate);
+                    updateMap.put("dateField_meqpbxsj", ghrq);
+                    updateMap.put("multiSelectField_meqpbxsc", jyyy);
+                    updateMap.put("textareaField_meqpbxsd", jtyy); // 注意:原代码这里写成了 jyyy,已修正为 jtyy
+                    updateMap.put("employeeField_mejowmng", xsy);
+                    updateMap.put("selectField_mewirdx4", khxypj);
+                    updateMap.put("attachmentField_mfoqcctz", fj);
+                }
+                updateMap.put("textField_mjzervdu", kdYdTransfer.getFhtzdbh());
+// 基础字段同步(这些字段即使为空也会覆盖,符合原逻辑)
+                updateMap.put("textField_miquh5zj", ddformInstanceId);
+                updateMap.put("selectField_mhubzsa5", kdYdTransfer.getDjlx());
+                updateMap.put("textField_mhubzsas", kdYdTransfer.getKh());
+                updateMap.put("textField_miptelgh", kdYdTransfer.getDdbh());
+                updateMap.put("textField_miptelgc", kdYdTransfer.getDjbh());
+                updateMap.put("textField_miptelgd", kdYdTransfer.getCgy());
+                updateMap.put("selectField_mhubzsa7", kdYdTransfer.getDchzlx());
+                updateMap.put("textField_mhubzsa6", kdYdTransfer.getYwlx());
+
+// 日期字段:转为毫秒字符串(保持原逻辑)
+                String rqMillis = "";
+                if (kdYdTransfer.getRq() != null) {
+                    rqMillis = String.valueOf(kdYdTransfer.getRq()
+                            .atZone(ZoneId.systemDefault())
+                            .toInstant()
+                            .toEpochMilli());
+                }
+                updateMap.put("dateField_mhubzsab", rqMillis);
+
+                updateMap.put("selectField_mhubzsa9", kdYdTransfer.getDrhzlx());
+                updateMap.put("selectField_mhubzsaa", kdYdTransfer.getDbfx());
+                updateMap.put("selectField_mhubzsac", kdYdTransfer.getDbdlx());
+                updateMap.put("textField_miptelge", kdYdTransfer.getDcbm());
+                updateMap.put("textField_miptelgf", kdYdTransfer.getDchz());
+                updateMap.put("textField_miptelgg", kdYdTransfer.getDrbm());
+                updateMap.put("selectField_mhubzsah", kdYdTransfer.getHdfs());
+                updateMap.put("selectField_mhubzsai", kdYdTransfer.getYsfs());
+                updateMap.put("selectField_mhubzsar", kdYdTransfer.getKdgs());
+                updateMap.put("selectField_mhubzsag", kdYdTransfer.getFkfs());
+
+                log.debug("开始同步到宜搭: 单据编号={}, 表单UUID=FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR", kdYdTransfer.getDjbh());
+
+                ydClient.operateData(YDParam.builder()
+                        .formUuid("FORM-F1B2BA2AF310476C88F4756F4DB50667VXDR")
+                        .noExecuteExpression(false)
+                        .searchCondition(JSONObject.toJSONString(UtilMap.map("textField_miptelgc", kdYdTransfer.getDjbh())))
+                        .formDataJson(JSONObject.toJSONString(updateMap))
+                        .build(), YDConf.FORM_OPERATION.upsert);
+
+// 更新同步状态
+                kdYdTransfer.setSyncStatus("1");
+                kdYdTransferMapper.updateById(kdYdTransfer);
+                successCount++;
+
+                log.info("调拨单同步成功: 单据编号={}", kdYdTransfer.getDjbh());
+            } catch (Exception e) {
+                failCount++;
+                log.error("同步单条调拨单数据异常: 单据编号={}, 错误信息={}",
+                        kdYdTransfer.getDjbh(), e.getMessage(), e);
+            }
+        }
+
+        log.info("【调拨单同步任务】完成: 成功={}, 失败={}, 总计={}",
+                successCount, failCount, kdYdTRANSFERdels.size());
+    }
+
+    private static String safeToString(Object obj) {
+        return obj == null ? null : obj.toString();
+    }
+
     private Object getddAss(String title, String id) {
         return UtilMap.map("appType, formUuid, formType, instanceId, title, subTitle", "APP_VQDMMWS6OR1VHL8VMFD3", "FORM-B62CAE3075CE4098B17BB86C90FFA21C9B7C", "receipt", id, title, "");
     }

+ 270 - 0
mjava-huagao/src/main/java/com/malk/huagao/utils/HTTPHelper.java

@@ -0,0 +1,270 @@
+package com.malk.huagao.utils;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HTTPHelper {
+    // slf4j日志记录器
+    private static final Logger LOG = LoggerFactory.getLogger(HTTPHelper.class);
+
+    /***
+     * 向指定URL发送GET方法的请求
+     *
+     * @param apiUrl
+     * @param data
+     * @param projectId
+     * @param signature
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    public static String sendGet(String apiUrl, HashMap<String, Object> param,
+                                 LinkedHashMap<String, String> headers, String encoding) throws Exception {
+        // 获得响应内容
+        String http_RespContent = null;
+        HttpURLConnection httpURLConnection = null;
+        int http_StatusCode = 0;
+        String http_RespMessage = null;
+        try {
+            // 实际请求完整Url
+            StringBuffer fullUrl = new StringBuffer();
+            if (null != param) {
+                if (0 != param.size()) {
+                    StringBuffer params = new StringBuffer();
+                    for (Entry<String, Object> entry : param.entrySet()) {
+                        params.append(entry.getKey());
+                        params.append("=");
+                        params.append(entry.getValue().toString());
+                        params.append("&");
+                    }
+                    if (params.length() > 0) {
+                        params.deleteCharAt(params.lastIndexOf("&"));
+                    }
+                    fullUrl.append(apiUrl).append((params.length() > 0) ? "?" + params.toString() : "");
+                } else {
+                    fullUrl.append(apiUrl);
+                }
+            } else {
+                fullUrl.append(apiUrl);
+            }
+
+            LOG.info(">>>> 实际请求Url: " + fullUrl.toString());
+
+            // 建立连接
+            URL url = new URL(fullUrl.toString());
+            httpURLConnection = (HttpURLConnection) url.openConnection();
+            // 需要输出
+            httpURLConnection.setDoOutput(true);
+            // 需要输入
+            httpURLConnection.setDoInput(true);
+            // 不允许缓存
+            httpURLConnection.setUseCaches(false);
+            // HTTP请求方式
+            httpURLConnection.setRequestMethod("GET");
+            // 设置Headers
+            if (null != headers) {
+                for (String key : headers.keySet()) {
+                    httpURLConnection.setRequestProperty(key, headers.get(key));
+                }
+            }
+            // 连接会话
+            httpURLConnection.connect();
+            // 获得响应状态(HTTP状态码)
+            http_StatusCode = httpURLConnection.getResponseCode();
+            // 获得响应消息(HTTP状态码描述)
+            http_RespMessage = httpURLConnection.getResponseMessage();
+            // 获得响应内容
+            if (HttpURLConnection.HTTP_OK == http_StatusCode) {
+                // 返回响应结果
+                http_RespContent = getResponseContent(httpURLConnection);
+            } else {
+                // 返回非200状态时响应结果
+                http_RespContent = getErrorResponseContent(httpURLConnection);
+                String msg =
+                        MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
+                LOG.info(msg);
+            }
+        } catch (UnknownHostException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (MalformedURLException e) {
+            String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (Exception e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            if (null != httpURLConnection) {
+                httpURLConnection.disconnect();
+            }
+        }
+        return http_RespContent;
+    }
+
+    /***
+     * 向指定URL发送POST方法的请求
+     *
+     * @param apiUrl
+     * @param data
+     * @param projectId
+     * @param signature
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    public static String sendPOST(String apiUrl, String data, LinkedHashMap<String, String> headers,
+                                  String encoding) throws Exception {
+        // 获得响应内容
+        String http_RespContent = null;
+        HttpURLConnection httpURLConnection = null;
+        int http_StatusCode = 0;
+        String http_RespMessage = null;
+        try {
+            // 建立连接
+            URL url = new URL(apiUrl);
+            httpURLConnection = (HttpURLConnection) url.openConnection();
+            // 需要输出
+            httpURLConnection.setDoOutput(true);
+            // 需要输入
+            httpURLConnection.setDoInput(true);
+            // 不允许缓存
+            httpURLConnection.setUseCaches(false);
+            // HTTP请求方式
+            httpURLConnection.setRequestMethod("POST");
+            // 设置Headers
+            if (null != headers) {
+                for (String key : headers.keySet()) {
+                    httpURLConnection.setRequestProperty(key, headers.get(key));
+                }
+            }
+            // 连接会话
+            httpURLConnection.connect();
+            // 建立输入流,向指向的URL传入参数
+            DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
+            // 设置请求参数
+            dos.write(data.getBytes(encoding));
+            dos.flush();
+            dos.close();
+            // 获得响应状态(HTTP状态码)
+            http_StatusCode = httpURLConnection.getResponseCode();
+            // 获得响应消息(HTTP状态码描述)
+            http_RespMessage = httpURLConnection.getResponseMessage();
+            // 获得响应内容
+            if (HttpURLConnection.HTTP_OK == http_StatusCode) {
+                // 返回响应结果
+                http_RespContent = getResponseContent(httpURLConnection);
+            } else {
+                // 返回非200状态时响应结果
+                http_RespContent = getErrorResponseContent(httpURLConnection);
+                String msg =
+                        MessageFormat.format("请求失败: Http状态码 = {0} , {1}", http_StatusCode, http_RespMessage);
+                LOG.info(msg);
+            }
+        } catch (UnknownHostException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (MalformedURLException e) {
+            String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } catch (Exception e) {
+            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
+            Exception ex = new Exception(message);
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            if (null != httpURLConnection) {
+                httpURLConnection.disconnect();
+            }
+        }
+        return http_RespContent;
+    }
+
+    /***
+     * 读取HttpResponse响应内容
+     *
+     * @param httpURLConnection
+     * @return
+     * @throws UnsupportedEncodingException
+     * @throws IOException
+     */
+    private static String getResponseContent(HttpURLConnection httpURLConnection)
+            throws UnsupportedEncodingException, IOException {
+        StringBuffer contentBuffer = null;
+        BufferedReader responseReader = null;
+        try {
+            contentBuffer = new StringBuffer();
+            String readLine = null;
+            responseReader =
+                    new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
+            while ((readLine = responseReader.readLine()) != null) {
+                contentBuffer.append(readLine);
+            }
+        } finally {
+            if (null != responseReader) {
+                responseReader.close();
+            }
+        }
+        return contentBuffer.toString();
+    }
+
+    /***
+     * 读取HttpResponse响应内容
+     *
+     * @param httpURLConnection
+     * @return
+     * @throws UnsupportedEncodingException
+     * @throws IOException
+     */
+    private static String getErrorResponseContent(HttpURLConnection httpURLConnection)
+            throws UnsupportedEncodingException, IOException {
+        StringBuffer contentBuffer = null;
+        BufferedReader responseReader = null;
+        try {
+            contentBuffer = new StringBuffer();
+            String readLine = null;
+            responseReader =
+                    new BufferedReader(new InputStreamReader(httpURLConnection.getErrorStream(), "UTF-8"));
+            while ((readLine = responseReader.readLine()) != null) {
+                contentBuffer.append(readLine);
+            }
+        } finally {
+            if (null != responseReader) {
+                responseReader.close();
+            }
+        }
+        return contentBuffer.toString();
+    }
+}

+ 17 - 5
mjava-huagao/src/main/resources/application-dev.yml

@@ -2,6 +2,7 @@ server:
   port: 7708
   servlet:
     context-path: /huagao
+  host: https://33d4c762.r23.cpolar.top
 
 enable:
   scheduling: false
@@ -15,7 +16,7 @@ spring:
   datasource:
     driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
     #trustServerCertificate=true 临时绕过证书验证的风险
-    url: jdbc:sqlserver://113.45.187.194:1433;databaseName=dingding;encrypt=true;trustServerCertificate=true;
+    url: jdbc:sqlserver://61.174.28.154:1433;databaseName=dingding;encrypt=true;trustServerCertificate=true;
     username: hgdd
     password: hgdd@2025
 
@@ -38,6 +39,7 @@ dingtalk:
   aesKey:
   token:
   operator:
+  atUserId: 15959870735792794 #陈伟东
 
 # aliwork
 aliwork:
@@ -46,15 +48,15 @@ aliwork:
 
 kingdee:
   # 第三方系统登录授权的账套ID
-  X-KDApi-AcctID: 626cda24137359
+  X-KDApi-AcctID: 697ecdcc4267e8
   # 第三方系统登录授权的用户
   X-KDApi-UserName: dingding
   # 第三方系统登录授权的应用ID
-  X-KDApi-AppID: 322503_566rSdHtylkb4+XoW1XoRdVGSqW85LOs
+  X-KDApi-AppID: 335775_R16NTZiFTpq/2+1vR74KQbSs2K0b0oms
   # 第三方系统登录授权的应用密钥
-  X-KDApi-AppSec: 7eaf6845da0540e6b8f328541b36dff6
+  X-KDApi-AppSec: ce7e0211058a428ca858d332e7f80f4d
   # 服务Url地址(公有云统一走网关sdk底层已处理,无需传X-KDApi-ServerUrl,下面这行需要注释)
-  X-KDApi-ServerUrl: http://113.45.187.194:81/k3cloud/
+  X-KDApi-ServerUrl: http://61.174.28.154:81/k3cloud/
   # 账套语系,默认2052
   # X-KDApi-LCID: 2052
   # 组织编码,启用多组织时配置对应的组织编码才有效
@@ -64,5 +66,15 @@ kingdee:
   # 允许的最大读取延时,单位为秒
   # X-KDApi-RequestTimeout: 120
 
+eqb:
+  downloadFilePath: C:\\Users\\EDY\\Desktop\\项目\\华高\\电子签\\files\\
+#  signatoryPsnId: c3fb35cb7e574baf97ed9f8917c6327b #签署人 陈伟东
+  signatoryPsnId: 95945af8f0864d15bf186e7808693176 #签署人 俞静妙
+
+#金蝶方开发服务
+kd:
+  host: https://61.174.28.154:70
+
+
 
 

+ 16 - 5
mjava-huagao/src/main/resources/application-prod.yml

@@ -2,6 +2,7 @@ server:
   port: 7708
   servlet:
     context-path: /huagao
+  host: http://61.174.28.154:7708
 
 enable:
   scheduling: true
@@ -15,7 +16,7 @@ spring:
   datasource:
     driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
     #trustServerCertificate=true 临时绕过证书验证的风险
-    url: jdbc:sqlserver://113.45.187.194:1433;databaseName=dingding;encrypt=true;trustServerCertificate=true;
+    url: jdbc:sqlserver://172.16.24.19:1433;databaseName=dingding;encrypt=true;trustServerCertificate=true;
     username: hgdd
     password: hgdd@2025
 
@@ -38,6 +39,7 @@ dingtalk:
   aesKey:
   token:
   operator:
+  atUserId: 15959870735792794 #陈伟东
 
 # aliwork
 aliwork:
@@ -46,15 +48,15 @@ aliwork:
 
 kingdee:
   # 第三方系统登录授权的账套ID
-  X-KDApi-AcctID: 626cda24137359
+  X-KDApi-AcctID: 697ecdcc4267e8
   # 第三方系统登录授权的用户
   X-KDApi-UserName: dingding
   # 第三方系统登录授权的应用ID
-  X-KDApi-AppID: 322503_566rSdHtylkb4+XoW1XoRdVGSqW85LOs
+  X-KDApi-AppID: 335775_R16NTZiFTpq/2+1vR74KQbSs2K0b0oms
   # 第三方系统登录授权的应用密钥
-  X-KDApi-AppSec: 7eaf6845da0540e6b8f328541b36dff6
+  X-KDApi-AppSec: ce7e0211058a428ca858d332e7f80f4d
   # 服务Url地址(公有云统一走网关sdk底层已处理,无需传X-KDApi-ServerUrl,下面这行需要注释)
-  X-KDApi-ServerUrl: http://113.45.187.194:81/k3cloud/
+  X-KDApi-ServerUrl: http://172.16.24.19:81/k3cloud/
   # 账套语系,默认2052
   # X-KDApi-LCID: 2052
   # 组织编码,启用多组织时配置对应的组织编码才有效
@@ -63,3 +65,12 @@ kingdee:
   # X-KDApi-ConnectTimeout: 120
   # 允许的最大读取延时,单位为秒
   # X-KDApi-RequestTimeout: 120
+
+eqb:
+  downloadFilePath: /home/server/huagao/files/
+#  signatoryPsnId: c3fb35cb7e574baf97ed9f8917c6327b #签署人 陈伟东
+  signatoryPsnId: 95945af8f0864d15bf186e7808693176 #签署人 俞静妙
+
+#金蝶方开发服务
+kd:
+  host: http://172.16.24.173:70

+ 77 - 0
mjava-huagao/src/main/resources/application-prod2.yml

@@ -0,0 +1,77 @@
+#异常重启 生产环境2
+server:
+  port: 7708
+  servlet:
+    context-path: /huagao
+    host: http://61.174.28.154:7708
+
+enable:
+  scheduling: true
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/huagao/log/
+  level:
+    com.malk.*: info
+
+spring:
+  datasource:
+    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
+    #trustServerCertificate=true 临时绕过证书验证的风险
+    url: jdbc:sqlserver://172.16.24.19:1433;databaseName=dingding;encrypt=true;trustServerCertificate=true;
+    username: hgdd
+    password: hgdd@2025
+
+mybatis-plus:
+  configuration:
+    #开启驼峰命名自动映射
+    map-underscore-to-camel-case: true
+    #开启日志打印
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  type-aliases-package: com.malk.huagao.entity
+  #扫描mapper文件
+  mapper-locations: classpath:mapper/*.xml
+
+# dingtalk
+dingtalk:
+  agentId: 3254218465
+  appKey: dingdhgwe3g6xrifq3iz
+  appSecret: xO9uBMFGvv79UAqv8HBPZQVXLBbLhf8ueX28Vtn_de-4ME7-K9wBRVFihCGFoeX4
+  corpId:
+  aesKey:
+  token:
+  operator:
+  atUserId: 15959870735792794 #陈伟东
+
+# aliwork
+aliwork:
+  appType: APP_BWPT6ET90UEE8IBEY9GJ
+  systemToken: 37766HD145ST2RBB9S4D37J2WMNU293GASC8M6Q
+
+kingdee:
+  # 第三方系统登录授权的账套ID
+  X-KDApi-AcctID: 697ecdcc4267e8
+  # 第三方系统登录授权的用户
+  X-KDApi-UserName: dingding
+  # 第三方系统登录授权的应用ID
+  X-KDApi-AppID: 335775_R16NTZiFTpq/2+1vR74KQbSs2K0b0oms
+  # 第三方系统登录授权的应用密钥
+  X-KDApi-AppSec: ce7e0211058a428ca858d332e7f80f4d
+  # 服务Url地址(公有云统一走网关sdk底层已处理,无需传X-KDApi-ServerUrl,下面这行需要注释)
+  X-KDApi-ServerUrl: http://172.16.24.19:81/k3cloud/
+  # 账套语系,默认2052
+  # X-KDApi-LCID: 2052
+  # 组织编码,启用多组织时配置对应的组织编码才有效
+  # X-KDApi-OrgNum: 100
+  # 允许的最大连接延时,单位为秒
+  # X-KDApi-ConnectTimeout: 120
+  # 允许的最大读取延时,单位为秒
+  # X-KDApi-RequestTimeout: 120
+
+eqb:
+  downloadFilePath: /home/server/huagao/files/
+#  signatoryPsnId: c3fb35cb7e574baf97ed9f8917c6327b #签署人 陈伟东
+  signatoryPsnId: 95945af8f0864d15bf186e7808693176 #签署人 俞静妙
+
+#金蝶方开发服务
+kd:
+  host: http://172.16.24.173:70

Разница между файлами не показана из-за своего большого размера
+ 1420 - 0
mjava-huagao/src/test/java/com/malk/huagao/EqbTest.java


+ 20 - 1
mjava-huagao/src/test/java/com/malk/huagao/KdTest.java

@@ -1,10 +1,13 @@
 package com.malk.huagao;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.kingdee.bos.webapi.entity.IdentifyInfo;
 import com.kingdee.bos.webapi.sdk.K3CloudApi;
 import com.malk.huagao.KdEntity.BillQuery;
 import com.malk.huagao.config.KDWebApiConf;
+import com.malk.huagao.entity.KdYdMaterial;
+import com.malk.huagao.mapper.KdYdMaterialMapper;
 import com.malk.huagao.service.KdHuaGaoService;
 import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
@@ -33,7 +36,18 @@ public class KdTest {
 
     @Autowired
     private YDClient ydClient;
-
+    @Autowired
+    private KdYdMaterialMapper kdYdMaterialMapper;
+@Test
+public void test50() throws Exception {
+    LambdaQueryWrapper<KdYdMaterial> materialdel = new LambdaQueryWrapper<>();
+//    materialdel.eq(KdYdMaterial::getOperationType, "3")  // 修正:使用 materialdel 而不是 materialqw
+//            .eq(KdYdMaterial::getSyncStatus, "0");
+
+    List<KdYdMaterial> kdYdMaterialdels = kdYdMaterialMapper.selectList(materialdel);
+    int size =kdYdMaterialdels.size();
+    System.out.println(size);
+}
     @Test
     public void test() throws Exception {
         K3CloudApi client = new K3CloudApi(initIden());
@@ -213,6 +227,11 @@ public class KdTest {
         System.out.println("aaa"+JSONObject.toJSONString(aaa));
     }
 
+    @Test
+    public void test10(){
+        kdHuaGaoService.syncPUROrder(null);
+    }
+
     private IdentifyInfo initIden(){
         //注意 1:此处不再使用参数形式传入用户名及密码等敏感信息,改为在登录配置文件中设置。
         //注意 2:必须先配置第三方系统登录授权信息后,再进行业务操作,详情参考各语言版本SDK介绍中的登录配置文件说明。

+ 3 - 3
mjava-huagao/src/test/java/com/malk/huagao/YyYdTest.java

@@ -114,9 +114,9 @@ public class YyYdTest {
 
     @Test
     public void test3() {
-        LocalDateTime startTime= LocalDate.now().minusDays(2).atTime(LocalTime.MIN);
-        LocalDateTime endTime= LocalDate.now().minusDays(1).atTime(LocalTime.MIN);
-//        LocalDateTime endTime= LocalDate.now().atTime(LocalTime.MIN);
+        LocalDateTime startTime= LocalDate.now().minusDays(4).atTime(LocalTime.MIN);
+//        LocalDateTime endTime= LocalDate.now().minusDays(4).atTime(LocalTime.MIN);
+        LocalDateTime endTime= LocalDate.now().atTime(LocalTime.MIN);
 
         huaGaoService.syncKqData(startTime,endTime);
     }

+ 13 - 0
mjava-jinlun/pom.xml

@@ -51,6 +51,19 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.32</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.3.2</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 21 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/controller/JinlunController.java

@@ -5,6 +5,7 @@ import com.malk.server.common.McR;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
 import java.util.Map;
 
 @RestController
@@ -72,4 +73,24 @@ public class JinlunController {
 
         return McR.success();
     }
+
+    /**
+     *
+     * 查询客户回款对账明细
+     * @param startDate
+     * @param endDate
+     * @param customerName
+     * @return
+     */
+    @GetMapping("/getCustomerDzmx")
+    public McR getCustomerDzmx(String startDate, String endDate, String customerName){
+        return jinlunService.getCustomerDzmx(startDate,endDate,customerName);
+//        return null;
+    }
+
+    @GetMapping("/getCustomerWqqk")
+    public McR getCustomerWqqk(String startDate, String customerName){
+        return jinlunService.getCustomerWqqk(startDate,customerName);
+//        return null;
+    }
 }

+ 16 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/mapper/JinlunMapper.java

@@ -0,0 +1,16 @@
+package com.malk.jinlun.mapper;
+
+import org.apache.ibatis.annotations.MapKey;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface JinlunMapper {
+    //查询客户对账明细
+    List<Map> getCustomerDzmx(@Param("start_date") String start_date,@Param("end_date") String end_date,@Param("customer") String customer);
+
+    Map getCustomerWqqk(@Param("start_date") String start_date,@Param("customer") String customer);
+}

+ 4 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/service/JinlunService.java

@@ -14,4 +14,8 @@ public interface JinlunService {
     McR addSaleOrder(Map map);
 
     McR createTbProject(Map map);
+
+    McR getCustomerDzmx(String startDate, String endDate, String customerName);
+
+    McR getCustomerWqqk(String startDate, String customerName);
 }

+ 18 - 0
mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunServiceImpl.java

@@ -10,6 +10,7 @@ import com.kingdee.bos.webapi.entity.RepoRet;
 import com.kingdee.bos.webapi.sdk.K3CloudApi;
 import com.malk.jinlun.config.KDWebApiConf;
 import com.malk.jinlun.entity.*;
+import com.malk.jinlun.mapper.JinlunMapper;
 import com.malk.jinlun.service.CpClient;
 import com.malk.jinlun.service.JinlunService;
 import com.malk.server.common.McR;
@@ -47,6 +48,9 @@ public class JinlunServiceImpl implements JinlunService {
     @Autowired
     private TBConf tbConf;
 
+    @Autowired
+    private JinlunMapper jinlunMapper;
+
     private final Object $lock = new Object[0];
 
     private static final Long EXPIRES_IN = 7200000L;
@@ -599,6 +603,20 @@ public class JinlunServiceImpl implements JinlunService {
         return McR.success(id);
     }
 
+    @Override
+    public McR getCustomerDzmx(String startDate, String endDate, String customerName) {
+        List<Map> customerDzmx = jinlunMapper.getCustomerDzmx(startDate, endDate, customerName);
+
+        return McR.success(customerDzmx);
+    }
+
+    @Override
+    public McR getCustomerWqqk(String startDate, String customerName) {
+        Map customerWqqk = jinlunMapper.getCustomerWqqk(startDate, customerName);
+
+        return McR.success(customerWqqk);
+    }
+
     private IdentifyInfo initIden(){
         //注意 1:此处不再使用参数形式传入用户名及密码等敏感信息,改为在登录配置文件中设置。
         //注意 2:必须先配置第三方系统登录授权信息后,再进行业务操作,详情参考各语言版本SDK介绍中的登录配置文件说明。

+ 2 - 1
mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunTaskServiceImpl.java

@@ -150,7 +150,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
 
         BillQuery billQuery = new BillQuery();
         billQuery.setFormId("SAL_OUTSTOCK");
-        billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FDate,FSettleCurrID.FName,FCustomerID.FName,FCustomerID.FShortName,FHeadLocationID.FName,FMaterialID.FNumber,FMaterialID.FName,FMaterialID.FSpecification,FMaterialID.F_Sl_ducengid,F_VMKV_Text_WLZT,FPriceUnitQty,FRealQty,FUnitID.FName,FPriceUnitId.FName,FAuxUnitID.FName,FAuxUnitQty,FIsFree,FPrice,FTaxPrice,FEntryTaxRate,FAmount,FAllAmount,FDiscount,FEntrynote");
+        billQuery.setFieldKeys("FBillNo,FBillTypeID.FName,FDate,FSettleCurrID.FName,FCustomerID.FName,FCustomerID.FShortName,FCustomerID.FNumber,FHeadLocationID.FName,FMaterialID.FNumber,FMaterialID.FName,FMaterialID.FSpecification,FMaterialID.F_Sl_ducengid,F_VMKV_Text_WLZT,FPriceUnitQty,FRealQty,FUnitID.FName,FPriceUnitId.FName,FAuxUnitID.FName,FAuxUnitQty,FIsFree,FPrice,FTaxPrice,FEntryTaxRate,FAmount,FAllAmount,FDiscount,FEntrynote");
         List<Map> filterString = new ArrayList<>();
 
         //审核日期为昨天至今天
@@ -189,6 +189,7 @@ public class JinlunTaskServiceImpl implements JinlunTaskService {
             data.put("ShortText1760153691233",UtilMap.getString(saleOut,"FSettleCurrID.FName"));//结算币别
             data.put("ShortText1760153707273",UtilMap.getString(saleOut,"FCustomerID.FName"));//客户名称
             data.put("ShortText1760153714871",UtilMap.getString(saleOut,"FCustomerID.FShortName"));//客户简称
+            data.put("ShortText1768439848740",UtilMap.getString(saleOut,"FCustomerID.FNumber"));//客户简称
             data.put("ShortText1760153722192",UtilMap.getString(saleOut,"FHeadLocationID.FName"));//交货地点
 
             List<Map> entry = new ArrayList<>();

+ 7 - 0
mjava-jinlun/src/main/resources/application-dev.yml

@@ -3,6 +3,13 @@ server:
   servlet:
     context-path: /jinlun
 
+spring:
+  datasource:
+    url: jdbc:mysql://192.168.0.12:3306/cloudpivot?serverTimezone=GMT%2B8
+    username: root
+    password: test123456!@#$%
+    driver-class-name: com.mysql.cj.jdbc.Driver
+
 enable:
   scheduling: false
 logging:

+ 7 - 0
mjava-jinlun/src/main/resources/application-prod.yml

@@ -3,6 +3,13 @@ server:
   servlet:
     context-path: /jinlun
 
+spring:
+  datasource:
+    url: jdbc:mysql://192.168.0.12:3306/cloudpivot?serverTimezone=GMT%2B8
+    username: root
+    password: test123456!@#$%
+    driver-class-name: com.mysql.cj.jdbc.Driver
+
 enable:
   scheduling: true
 logging:

+ 81 - 0
mjava-jinlun/src/main/resources/mapper/JinlunMapper.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.malk.jinlun.mapper.JinlunMapper">
+
+
+    <select id="getCustomerDzmx" resultType="java.util.Map">
+        SELECT
+            客户, 单据编号, 业务日期, 性能, 规格, 数量, 重量, 计价单价, 税率, 价税合计, 回款金额, NULL AS "往期欠款", 备注
+        FROM (
+                 -- 暂估应收数据
+                 SELECT
+                     t1.ShortText1760602119316 AS "客户",
+                     t1.ShortText1760602123650 AS "单据编号",
+                     t1.Date1760602205733 AS "业务日期",
+                     t2.Text1760602314150 AS "性能",
+                     t2.Text1760602292846 AS "规格",
+                     t2.Number1762915279108 AS "数量",
+                     t2.Number1762915289424 AS "重量",
+                     t2.Number1760602330651 AS "计价单价",
+                     t2.Number1760602343876 AS "税率",
+                     t2.Number1760602359012 AS "价税合计",
+                     NULL AS "回款金额",
+                     t2.Text1760602391849 AS "备注"
+                 FROM i940k_ysd t1
+                          LEFT JOIN i940k_sheet1760602277185 t2 ON t1.id = t2.parentId
+                 WHERE t1.ShortText1760602147441 = '暂估应收'
+                   AND t1.ShortText1760602123650 NOT LIKE '%-%'
+                   AND t1.Date1760602205733 between #{start_date} and #{end_date}
+                   AND t1.ShortText1760602119316 = #{customer}
+
+                 UNION ALL
+
+                 -- 回款数据
+                 SELECT
+                     t1.ShortText1760585132200 AS "客户",
+                     t1.ShortText1760585125989 AS "单据编号",
+                     t1.Date1760585187315 AS "业务日期",
+                     NULL AS "性能",
+                     NULL AS "规格",
+                     NULL AS "数量",
+                     NULL AS "重量",
+                     NULL AS "计价单价",
+                     NULL AS "税率",
+                     NULL AS "价税合计",
+                     t2.Number1760585242849 AS "回款金额",
+                     t2.ShortText1760585258640 AS "备注"
+                 FROM i940k_skd t1
+                          LEFT JOIN i940k_sheet1760585205663 t2 ON t1.id = t2.parentId
+                 WHERE t1.Date1760585187315 between #{start_date} and #{end_date}
+                   AND t1.ShortText1760585132200 = #{customer}
+                 -- 多个客户时用:AND FIND_IN_SET(t1.ShortText1760585132200, @target_customers) > 0
+             ) data
+        ORDER BY 业务日期,单据编号,性能  -- 同一天内应收行在前,回款行在后
+    </select>
+    <select id="getCustomerWqqk" resultType="java.util.Map">
+        SELECT
+        COALESCE(receivable.amount, 0) AS '往期应付',
+        COALESCE(paid.amount, 0) AS '往期已付',
+        COALESCE(receivable.amount, 0) - COALESCE(paid.amount, 0) AS '往期欠款'
+        FROM
+        (SELECT 1 AS dummy) AS base
+        LEFT JOIN (
+        SELECT SUM(t2.Number1760602359012) AS amount
+        FROM i940k_ysd t1
+        LEFT JOIN i940k_sheet1760602277185 t2 ON t1.id = t2.parentId
+        WHERE t1.ShortText1760602147441 = '暂估应收'
+        AND t1.ShortText1760602123650 NOT LIKE '%-%'
+        AND t1.Date1760602205733 &lt; #{start_date}
+        AND t1.ShortText1760602119316 = #{customer}
+        ) AS receivable ON 1=1
+        LEFT JOIN (
+        SELECT SUM(t2.Number1760585242849) AS amount
+        FROM i940k_skd t1
+        LEFT JOIN i940k_sheet1760585205663 t2 ON t1.id = t2.parentId
+        WHERE t1.Date1760585187315 &lt; #{start_date}
+        AND t1.ShortText1760585132200 = #{customer}
+        ) AS paid ON 1=1
+    </select>
+</mapper>
+

+ 13 - 0
mjava-jinlun/src/test/java/com/malk/jinlun/DdTest.java

@@ -14,6 +14,7 @@ import com.malk.jinlun.entity.*;
 import com.malk.jinlun.service.CpClient;
 import com.malk.jinlun.service.JinlunService;
 import com.malk.jinlun.service.JinlunTaskService;
+import com.malk.server.common.McR;
 import com.malk.utils.UtilHttp;
 import com.malk.utils.UtilMap;
 import com.malk.utils.UtilToken;
@@ -330,6 +331,18 @@ public class DdTest {
         jinlunTaskService.syncXingneng();
     }
 
+    @Test
+    public void test13() {
+        McR customerDzmx = jinlunService.getCustomerDzmx("2025-06-01", "2025-12-30", "ASTAR CO., LTD.");
+        System.out.println(customerDzmx);
+    }
+
+    @Test
+    public void test14() {
+        McR customerWqqk = jinlunService.getCustomerWqqk("2025-06-01", "ASTAR CO., LTD.");
+        System.out.println(customerWqqk);
+    }
+
     private IdentifyInfo initIden(){
         //注意 1:此处不再使用参数形式传入用户名及密码等敏感信息,改为在登录配置文件中设置。
         //注意 2:必须先配置第三方系统登录授权信息后,再进行业务操作,详情参考各语言版本SDK介绍中的登录配置文件说明。

+ 88 - 0
mjava-junengtai/pom.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.malk</groupId>
+    <artifactId>junengtai</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>mjava-junengtai</name>
+    <description>mjava-junengtai</description>
+
+    <!-- ✅ 使用统一的 parent -->
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.18</version>
+        <relativePath/>
+    </parent>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.83</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.14.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- MyBatis Starter -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.2.2</version>
+        </dependency>
+        <!-- MySQL驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.28</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>junengtai</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <executable>true</executable>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 14 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/MjavaJunengtaiApplication.java

@@ -0,0 +1,14 @@
+package com.malk.junengtai;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+public class MjavaJunengtaiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(MjavaJunengtaiApplication.class, args);
+        System.out.println("Junengtai项目启动-----------");
+    }
+
+}

+ 78 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/controller/PurchaseController.java

@@ -0,0 +1,78 @@
+package com.malk.junengtai.controller;
+
+import com.malk.junengtai.service.PurchaseService;
+import com.malk.server.common.McException;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+import com.malk.utils.UtilServlet;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+@RestController
+@Slf4j
+@RequestMapping("/Purchase")
+public class PurchaseController {
+    @Autowired
+    private PurchaseService purchaseService;
+
+    /*todo:手动同步档案表*/
+    @SneakyThrows
+    @PostMapping("/synchronizedArchiveTable")
+    McR synchronizedArchiveTable(@RequestParam String name,@RequestParam String date){
+        log.info("开始同步,{}",name);
+        purchaseService.synchronizedArchiveTable(name,date);
+        log.info("同步完成");
+        return McR.success();
+    }
+
+    /*todo:组件信息手动同步接口*/
+    @SneakyThrows
+    @PostMapping("/componentInfo")
+    McR ComponentInformation(@RequestParam String date){
+        log.info("----------开始全量同步组件信息----------");
+        purchaseService.ComponentInformation(date);
+        log.info("-----------组件信息已同步完成-----------");
+        return McR.success();
+    }
+
+    /*todo:供应商信息同步接口*/
+    @SneakyThrows
+    @PostMapping("/supplierInfo")
+    McR supplierInformation(@RequestParam String dateString1){
+        log.info("---------开始全量同步供应商信息---------");
+        purchaseService.supplierInformation(dateString1);
+        log.info("---------供应商信息同步完成-------------");
+        return McR.success();
+    }
+
+    /*todo:查询库存信息接口*/
+    @SneakyThrows
+    @PostMapping("/queryInventory")
+    McR queryInventory(@RequestBody Map<String,String> body){
+        return McR.success(purchaseService.queryInventory(body));
+    }
+
+    /*todo:创建采购订单接口*/
+    @SneakyThrows
+    @PostMapping("/purchaseOrder")
+    McR purchaseOrder(HttpServletRequest request){
+        Map<String, ?> data = UtilServlet.getParamMap(request);
+        log.info("采购订单, {}", data);
+        McException.assertParamException_Null(data, "instanceId");
+        return purchaseService.purchaseOrder(UtilMap.getString(data,"instanceId"));
+    }
+
+    /*todo:拣货单接口*/
+    @SneakyThrows
+    @PostMapping("/pickingList")
+    McR pickingList(@RequestBody Map<String,String> body){
+        log.info("开始查询拣货单明细");
+        return McR.success(purchaseService.pickingList(body));
+    }
+
+}

+ 59 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/schedule/Schedule.java

@@ -0,0 +1,59 @@
+package com.malk.junengtai.schedule;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.malk.junengtai.service.PurchaseService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @EnableScheduling 开启定时任务 [配置参考McScheduleTask]
+ */
+@Slf4j
+@Configuration
+@EnableScheduling
+@ConditionalOnProperty(name = {"enable.scheduling"})
+public class Schedule {
+    @Autowired
+    private PurchaseService purchaseService;
+
+    /*组件信息定时器*/
+    @Scheduled(cron = "0 0 22 * * ?")
+    public void purchaseList(){
+        log.info("开始同步组件信息");
+        try {
+            LocalDate today = LocalDate.now(); // 获取当前日期(基于系统默认时区)
+            String dateString = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            System.out.println("当前时间:" + dateString);
+            purchaseService.ComponentInformation(dateString);
+            System.out.println("同步组件信息完成");
+        } catch (JacksonException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /*供应商信息定时器*/
+    @Scheduled(cron = "0 0 23 * * ?")
+    public void supplierInformation(){
+        log.info("开始同步供应商信息");
+        try {
+            LocalDate today = LocalDate.now(); // 获取当前日期(基于系统默认时区)
+            String dateString1 = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            System.out.println("当前时间:" + dateString1);
+            purchaseService.supplierInformation(dateString1);
+            System.out.println("同步供应商信息完成");
+        } catch (JacksonException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+
+
+}

+ 304 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/service/Impl/PurchaseServiceImpl.java

@@ -0,0 +1,304 @@
+package com.malk.junengtai.service.Impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.malk.junengtai.service.PurchaseService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Slf4j
+@Service
+public class PurchaseServiceImpl implements PurchaseService {
+
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private YDConf ydConf;
+    @Autowired
+    private DDConf ddConf;
+
+    @Override
+    public McR synchronizedArchiveTable(String name,String date) throws JacksonException {
+        if(name.equals("组件信息")){
+            log.info("开始同步组件信息");
+            ComponentInformation(date);
+        } else if (name.equals("供应商信息")) {
+            log.info("开始同步供应商信息");
+            supplierInformation(date);
+        }
+        return McR.success();
+    }
+
+    @Override
+    public McR ComponentInformation(String date) throws JacksonException {
+        HashMap head = new HashMap();
+        head.put("Authorization","ccd9220f-db1d-4aa1-aa1d-8a2c9180f801");
+
+        HashMap<String,Object> body = new HashMap();
+        List<Map<String, String>> partsList = new ArrayList<>();
+
+        Map<String, String> part1 = new HashMap<>();
+        part1.put("PartNumber", "SSF0009");
+        partsList.add(part1);
+
+        body.put("Parts", partsList);
+
+        String dd = UtilHttp.doPost("http://192.168.3.80:10001/api/public/GetAllParts", head, null, body);
+
+        ObjectMapper objectMapper  = new ObjectMapper();
+        JsonNode rootNode = objectMapper.readTree(dd);
+        JsonNode partsNode = rootNode.get("parts");
+        List<Map<String, String>> List = new ArrayList<>();
+        Map<String, Map<String, String>> partsMap = new ConcurrentHashMap<>();
+        if (partsNode != null && partsNode.isArray()) {
+            for (JsonNode partNode : partsNode) {
+                Map<String, String> partData = new HashMap<>();
+                partData.put("partNumber", partNode.get("partNumber").asText());
+                partData.put("description", partNode.get("description").asText());
+                partData.put("unit", partNode.get("unit").asText());
+                partData.put("module",partNode.get("module").isNull() ? "" : partNode.get("module").asText());
+                partData.put("spec",partNode.get("spec").isNull() ? "" : partNode.get("spec").asText());
+                partData.put("mark",partNode.get("mark").isNull() ? "" : partNode.get("mark").asText());
+                partData.put("createDate",partNode.get("createDate").isNull() ? "" : partNode.get("createDate").asText());
+                List.add(partData);
+                partsMap.put(partNode.get("partNumber").asText(), partData);
+            }
+        }
+        System.out.println("\n=== 遍历所有零件 ===个数:"+List.size());
+        int i = 0;
+        for (Map<String, String> part : List) {
+            i++;
+            System.out.println(i +"/" + List.size() + "   零件编号: " + part.get("partNumber") +
+                    ", 描述: " + part.get("description") +
+                    ", 单位: " + part.get("unit") +", 型号: " + part.get("module") + ", 规格: " + part.get("spec") + ", 牌号:" + part.get("mark"));
+
+            //传过来的date数据
+            if(part.get("createDate").toString().equals(date)){
+                //TODO:向宜搭插入数据
+                String sc = "textField_logkj6a6, textField_logkj6ai, textField_logkj6aj, textField_mh4k26k6, textField_mh4k26k5, textField_mh4k26k7";//组件号 组件名称 单位 型号 规格 牌号
+                String partNumber = part.get("partNumber").toString()!= null?part.get("partNumber").toString():"数据库此字段为空";
+                String description = part.get("description").toString()!=null?part.get("description").toString():"数据库此字段为空";
+                String unit = part.get("unit").toString()!=null?part.get("unit").toString():"数据库此字段为空";
+                String module = part.get("module").toString()!=null?part.get("module").toString():"数据库此字段为空";
+                String spec = part.get("spec").toString()!=null?part.get("spec").toString():"数据库此字段为空";
+                String mark = part.get("mark").toString()!=null?part.get("mark").toString():"数据库此字段为空";
+                List<Map> conditions = Arrays.asList(  YDConf.searchCondition_TextFiled("textField_logkj6a6", part.get("partNumber"), "eq"));
+                List<Map> list  = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-4D1B011EF0CC4CB8A5272BE0B5C4D073FKK8")
+                                .searchCondition(JSONObject.toJSONString(conditions))
+                                .build()
+                        ,YDConf.FORM_QUERY.retrieve_list).getData();
+                Map formData = UtilMap.map(sc,partNumber,description,unit,module,spec,mark);
+                if(!list.isEmpty()){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(UtilMap.getString(list.get(0),"formInstanceId"))
+                            .updateFormDataJson(JSONObject.toJSONString(formData))
+                            .build(),YDConf.FORM_OPERATION.update);
+                }else{
+                    ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-4D1B011EF0CC4CB8A5272BE0B5C4D073FKK8")
+                            .formDataJson(JSONObject.toJSONString(formData))
+                            .build(), YDConf.FORM_OPERATION.create).toString();
+                }
+            }
+
+
+        }
+        return McR.success();
+    }
+
+    @Override
+    public McR supplierInformation(String dateString1) throws JacksonException {
+        HashMap head = new HashMap();
+        head.put("Authorization","ccd9220f-db1d-4aa1-aa1d-8a2c9180f801");
+
+        HashMap<String,Object> body = new HashMap();
+        ArrayList<Map<String,String>> partsList = new ArrayList<>();
+
+        HashMap<String, Object> part1 = new HashMap<>();
+        part1.put("supplierCode","");
+        part1.put("name","");
+
+        body.put("suppliers",partsList);
+
+        String dd = UtilHttp.doPost("http://192.168.3.80:10001/api/public/GetAllSuppliers", head, null, body);
+
+        ObjectMapper objectMapper  = new ObjectMapper();
+        JsonNode rootNode = objectMapper.readTree(dd);
+        JsonNode partsNode = rootNode.get("suppliers");
+        List<Map<String, String>> List = new ArrayList<>();
+        Map<String, Map<String, String>> partsMap = new ConcurrentHashMap<>();
+        if (partsNode != null && partsNode.isArray()) {
+            for (JsonNode partNode : partsNode) {
+                Map<String, String> partData = new HashMap<>();
+                partData.put("supplierCode", partNode.get("supplierCode").asText());
+                partData.put("name", partNode.get("name").asText());
+                partData.put("createDate",partNode.get("createDate").isNull() ? "" : partNode.get("createDate").asText());
+                List.add(partData);
+                partsMap.put(partNode.get("supplierCode").asText(), partData);
+            }
+        }
+        System.out.println("\n=== 遍历所有供应商 ===个数:"+List.size());
+        int i = 0;
+        for (Map<String, String> part : List) {
+            i++;
+            System.out.println(i +"/" + List.size() + "   供应商编码: " + part.get("supplierCode") +
+                    ", 供应商名称: " + part.get("name"));
+            //TODO:向宜搭插入数据
+            //传过来的date数据
+            if(part.get("createDate").toString().equals(dateString1)){
+                String sc = "textField_loggfrvk, textField_loggfrvp";//供应商编码 供应商名称
+                String supplierCode = part.get("supplierCode").toString()!= null?part.get("supplierCode").toString():"数据库此字段为空";
+                String name = part.get("name").toString()!=null?part.get("name").toString():"数据库此字段为空";
+                List<Map> conditions = Arrays.asList(  YDConf.searchCondition_TextFiled("textField_loggfrvk", part.get("supplierCode"), "eq"));
+                List<Map> list  = (List<Map>) ydClient.queryData(YDParam.builder()
+                                .formUuid("FORM-A9A0154249F940268F7313DDEC33925CFNPI")
+                                .searchCondition(JSONObject.toJSONString(conditions))
+                                .build()
+                        ,YDConf.FORM_QUERY.retrieve_list).getData();
+                Map formData = UtilMap.map(sc,supplierCode,name);
+                if(!list.isEmpty()){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(UtilMap.getString(list.get(0),"formInstanceId"))
+                            .updateFormDataJson(JSONObject.toJSONString(formData))
+                            .build(),YDConf.FORM_OPERATION.update);
+                }else{
+                    ydClient.operateData(YDParam.builder()
+                            .formUuid("FORM-A9A0154249F940268F7313DDEC33925CFNPI")
+                            .formDataJson(JSONObject.toJSONString(formData))
+                            .build(), YDConf.FORM_OPERATION.create).toString();
+                }
+            }
+
+        }
+
+        return McR.success();
+    }
+
+    @Override
+    public McR queryInventory(Map<String,String> boddy) throws JacksonException {
+        HashMap header = new HashMap();
+        header.put("Authorization","ccd9220f-db1d-4aa1-aa1d-8a2c9180f801");
+        HashMap body = new HashMap();
+        body.put("PartNumber",boddy.get("PartNumber").toString());
+        String dd = UtilHttp.doPost("http://192.168.3.80:10001/api/public/GetPartLocationInfos", header, null, body);
+
+        HashMap map = new HashMap();
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode rootNode = mapper.readTree(dd);
+        JsonNode warehouses = rootNode.path("waresehouses");
+        String warehouseName,partLocationName = "";//仓库:warehouseName   库位:partLocationName
+        double partLocationBalance;//库存余额:partLocationBalance
+        for (JsonNode warehouse : warehouses) {
+            warehouseName = warehouse.path("warehouseName").asText();
+            JsonNode partLocations = warehouse.path("partLocations");
+            for (JsonNode location : partLocations) {
+                partLocationName = location.path("partLocationName").asText();
+                partLocationBalance = location.path("partLocationBalance").asDouble();
+                map.put("warehouseName",warehouseName);
+                map.put("partLocationName",partLocationName);
+                map.put("partLocationBalance",partLocationBalance);
+            }
+        }
+        return McR.success(map);
+    }
+
+    @Override
+    public McR purchaseOrder(String instanceId) throws JacksonException {
+        Map data = (Map) ydClient.queryData(YDParam.builder().formInstId(instanceId)
+                .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                .userId(ddConf.getOperator()).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+        System.out.println(data);
+        HashMap header = new HashMap();
+        header.put("Authorization","ccd9220f-db1d-4aa1-aa1d-8a2c9180f801");
+        //创建主map
+        HashMap purchaseOrder  = new HashMap();
+        purchaseOrder.put("PurchaseOrderNumber",data.get("serialNumberField_mk21zzwk").toString());//采购订单编号
+        purchaseOrder.put("SupplierCode",data.get("textField_mhd2mu8c").toString());//供应商编码
+        purchaseOrder.put("OrderType",data.get("textField_mhd2mu8d").toString());//订单类型
+        purchaseOrder.put("Warehouse",data.get("selectField_mhd3jyfb").toString());//仓库
+        purchaseOrder.put("BusinessContactOrderNumber","");//采购合同编码
+        purchaseOrder.put("OurReference","");//我方联系人
+        purchaseOrder.put("GoodsLabel","");//行货物标签(不传)
+        purchaseOrder.put("Currency","元");//货币
+        // 创建Rows数组
+        List<Map<String, Object>> rows = new ArrayList<>();
+        List<Map> jsonString = (List<Map>)data.get("tableField_logke6sx");
+        for (Map map : jsonString){
+            HashMap rowItem = new HashMap();
+            rowItem.put("PartNumber",map.get("textField_logkj6au").toString());//组件号
+
+            String purchaseNum = new BigDecimal(map.get("numberField_logke6t1").toString())
+                    .setScale(2,BigDecimal.ROUND_HALF_UP).toString();
+            rowItem.put("OrderedQuantity",purchaseNum);//采购数量
+
+            String price = new BigDecimal(map.get("numberField_mh9x8r54").toString())
+                    .setScale(2,BigDecimal.ROUND_HALF_UP).toString();
+            rowItem.put("Price",price);//单价
+
+            rowItem.put("Unit",map.get("selectField_logkj6ak").toString().equals("") ? "" : map.get("selectField_logkj6ak").toString());//单位
+
+            long time = (long)data.get("dateField_loglna5u");
+            String utc = convertTimestampToDateString(time, "UTC", "yyyy-MM-dd");
+            rowItem.put("RequirementDate",utc);//交货日期
+
+            String vat = new BigDecimal(map.get("numberField_mhj15z8w").toString())
+                    .setScale(2,BigDecimal.ROUND_HALF_UP).toString();
+            rowItem.put("Vat",vat);
+
+            rows.add(rowItem);
+        }
+        purchaseOrder.put("Rows", rows);
+        System.out.println(purchaseOrder);
+        //调用接口
+        String dd = UtilHttp.doPost("http://192.168.3.80:10001/api/public/CreatePurchaseOrder", header, null, purchaseOrder);
+        System.out.println(dd);
+        return McR.success(dd);
+    }
+
+    @Override
+    public Map pickingList(Map<String,String> boddy) throws JacksonException {
+        HashMap header = new HashMap();
+        header.put("Authorization","ccd9220f-db1d-4aa1-aa1d-8a2c9180f801");
+        HashMap body = new HashMap();
+        body.put("PLNumber",boddy.get("PLNumber").toString());
+        String dd = UtilHttp.doPost("http://192.168.3.80:10001/api/public/GetPickingListInfos", header, null, body);
+        ObjectMapper mapper =new ObjectMapper();
+        Map node =mapper.readValue(dd,Map.class);
+        System.out.println("返回值:"+node);
+        return node;
+    }
+
+    public  String convertTimestampToDateString(long timestamp, String timeZone, String pattern) {
+        // 将时间戳转换为Instant
+        Instant instant = Instant.ofEpochMilli(timestamp);
+        // 将Instant转换为指定时区的日期
+        LocalDate date = instant.atZone(ZoneId.of(timeZone)).toLocalDate();
+        date = date.plusDays(1);
+        // 创建一个DateTimeFormatter来格式化日期
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
+        // 格式化LocalDate为字符串
+        String formattedDate = date.format(formatter);
+        // 返回格式化后的日期字符串
+        return formattedDate;
+    }
+
+}

+ 27 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/service/PurchaseService.java

@@ -0,0 +1,27 @@
+package com.malk.junengtai.service;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.malk.server.common.McR;
+
+import java.util.Map;
+
+public interface PurchaseService {
+
+    /*手动同步档案表数据*/
+    McR synchronizedArchiveTable(String name,String date) throws JacksonException;
+
+    /*同步组件信息*/
+    McR ComponentInformation(String date) throws JacksonException;
+
+    /*供应商信息*/
+    McR supplierInformation(String dateString1) throws  JacksonException;
+
+    /*查询库存信息*/
+    McR queryInventory(Map<String,String> body) throws JacksonException;
+
+    /*创建采购订单接口*/
+    McR purchaseOrder(String instanceId) throws  JacksonException;
+
+    /*查询拣货单接口*/
+    Map pickingList(Map<String,String> body) throws JacksonException;
+}

+ 85 - 0
mjava-junengtai/src/main/java/com/malk/junengtai/test/test.java

@@ -0,0 +1,85 @@
+package com.malk.junengtai.test;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@Slf4j
+@RequestMapping("/test")
+public class test {
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private YDConf ydConf;
+
+    @PostMapping("/test1")
+    McR test1(){
+        System.out.println("接口正常!");
+        return McR.success("接口正常!");
+    }
+
+    /*批量修改数据*/
+    @PostMapping("/test2")
+    McR test2(){
+        //1、查询所有的收票数据
+        String instanceId = "FORM-27421C0D0ACA41DFB85D05A9878161B1SDCE";
+        YDParam ydParam = YDParam.builder().formUuid(instanceId).build();
+        ydParam.setPageSize(1);
+        long totalCount = ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getTotalCount();
+        System.out.println(totalCount);
+
+        List<Map> dataList = new ArrayList<>();
+        ydParam.setCurrentPage(1);
+        ydParam.setPageSize(100);
+        for (int page = 1; page <= (Math.ceil(totalCount / 100 )!=0?Math.ceil(totalCount / 100 + 1):1); page++) {
+            ydParam.setCurrentPage(page);
+            dataList.addAll((List<Map>) ydClient.queryData(ydParam, YDConf.FORM_QUERY.retrieve_search_form).getData());
+        }
+        //2、遍历收票数据
+        int i = 0;
+        for(Map li: dataList){
+            i ++ ;
+            String currentInstanceId = (String) li.get("formInstanceId");
+            System.out.println(currentInstanceId);
+            //3、遍历子表单,求和明细数据
+            Map data =ydClient.queryData(YDParam.builder().formInstId(currentInstanceId)
+                    .appType(ydConf.getAppType()).systemToken(ydConf.getSystemToken())
+                    .userId("332051151139376769").build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+            Double A_total = 0.0;
+            List<Map> jsonString = (List<Map>)data.get("tableField_m8oaxbru");
+            for (Map map1 : jsonString) {
+                Object o = map1.get("numberField_m8oaxbry");
+                System.out.println(o);
+                double d = ((Number) o).doubleValue();
+                System.out.println(d);
+                A_total = A_total + d;
+            }
+            System.out.println("总金额:" + A_total);
+            //4、更新发票汇总字段
+            ydClient.operateData(YDParam.builder()
+                    .appType(ydConf.getAppType())
+                    .systemToken(ydConf.getSystemToken())
+                    .formInstanceId(currentInstanceId)
+                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("numberField_mkax9d6k",A_total)))
+                    .build(), YDConf.FORM_OPERATION.update);
+            log.info("{}/{}",i,dataList.size());
+        }
+        return McR.success();
+    }
+
+}

+ 88 - 0
mjava-junengtai/src/main/resources/application-dev.yml

@@ -0,0 +1,88 @@
+# 环境配置
+server:
+  port: 8086
+  servlet:
+    context-path: /api/junengtai
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+#      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: ounuo_user
+    password: OUNUO123!
+    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+  jpa:
+    hibernate:
+      ddl-auto: none
+    show-sql: true
+    database: oracle
+  hikari:
+    pool-name: DateHikariCP
+    minimum-idle: 0
+    maximum-pool-size: 10
+    idle-timeout: 30000
+    max-lifetime: 120000          # 小于数据库超时大于业务执行返回时间[hikari默认30m, mysql默认10m]
+    connection-timeout: 30000     # 数据库连接超时时间,默认30秒,即30000
+
+
+
+  #    # 主库
+#    primary:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#    # 从库
+#    slave:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#  jpa:
+#    hibernate:
+#      ddl-auto: none      # JPA对表没有任何操作
+#    show-sql: true
+#    database: ORACLE
+#    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# filepath
+file:
+  path:
+    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+  source:
+    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+logging:
+  file:
+    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk 钉钉
+dingtalk:
+  agentId: 4074144499
+  appKey: ding21enhh8fzggqyuwu
+  appSecret: PemxcBGHaEa083YRQt_q2jjGIYBATmw9ddXr6bYtFEkuBHTdqOD5NbYDj12b9-ua
+  corpId: dingfa48ac9cae50fe6ba1320dcb25e91351
+  aesKey:
+  token:
+  operator: 33205115111170152911   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_NJPKQLYOZNQ7P3JNCW6T
+  systemToken: S4E66I8119TYN5WO6MISKDTDJV5C2FWX24FFM0I
+
+# MyBatis配置
+mybatis:
+  mapper-locations: classpath:mapper/*.xml
+  type-aliases-package: com.malk.junengtai.entity
+  configuration:
+    map-underscore-to-camel-case: true
+
+#定时器
+enable:
+  scheduling: true

+ 76 - 0
mjava-junengtai/src/main/resources/application-prod.yml

@@ -0,0 +1,76 @@
+# 环境配置
+server:
+  port: 9001
+  servlet:
+    context-path: /api/junengtai
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+    #      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: ounuo_user
+    password: OUNUO123!
+    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+
+
+  #    # 主库
+  #    primary:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  #    # 从库
+  #    slave:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: ORACLE
+    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# filepath
+file:
+  path:
+    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+  source:
+    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+logging:
+  file:
+    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk 钉钉
+dingtalk:
+  agentId: 4074144499
+  appKey: ding21enhh8fzggqyuwu
+  appSecret: PemxcBGHaEa083YRQt_q2jjGIYBATmw9ddXr6bYtFEkuBHTdqOD5NbYDj12b9-ua
+  corpId: dingfa48ac9cae50fe6ba1320dcb25e91351
+  aesKey:
+  token:
+  operator: 33205115111170152911   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_NJPKQLYOZNQ7P3JNCW6T
+  systemToken: S4E66I8119TYN5WO6MISKDTDJV5C2FWX24FFM0I
+
+# MyBatis配置
+mybatis:
+  mapper-locations: classpath:mapper/*.xml
+  type-aliases-package: com.malk.junengtai.entity
+  configuration:
+    map-underscore-to-camel-case: true
+
+#定时器
+enable:
+  scheduling: true

+ 3 - 0
mjava-junengtai/src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: prod

+ 13 - 0
mjava-junengtai/src/test/java/com/malk/junengtai/MjavaJunengtaiApplicationTests.java

@@ -0,0 +1,13 @@
+package com.malk.junengtai;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class MjavaJunengtaiApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}

+ 5 - 2
mjava-kabeiyi/src/main/java/com/malk/kabeiyi/controller/KabeiyiController.java

@@ -82,12 +82,15 @@ public class KabeiyiController {
         return kabeiyiService.ocr(downloadUrl,name,type);
     }
 
+
+    //============================================== 发货量分析接口停用 =====================================================
+
     //每天0点定时同步出库单信息
-    @Scheduled(cron = "0 0 0 * * ?")
+    /*@Scheduled(cron = "0 0 0 * * ?")
     @GetMapping("getSaleoutInfo")
     public McR getSaleoutInfo(){
         return kabeiyiService.getSaleoutInfo();
-    }
+    }*/
 
 
     //============================================== 一期接口停用 =====================================================

+ 85 - 0
mjava-lianan/pom.xml

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.18</version> <!-- 使用最新的稳定版或其他适用版本 -->
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <groupId>com.malk</groupId>
+    <artifactId>mjava-lianan</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.30</version>
+        </dependency>
+        <!--RSA 依赖-->
+        <dependency>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <groupId>org.bouncycastle</groupId>
+            <version>1.70</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jolokia</groupId>
+            <artifactId>jolokia-core</artifactId>
+            <version>1.6.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>lianan</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <executable>true</executable>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 17 - 0
mjava-lianan/src/main/java/com/malk/lianan/LianAnApplication.java

@@ -0,0 +1,17 @@
+package com.malk.lianan;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+@EnableScheduling
+public class LianAnApplication {
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(LianAnApplication.class,args);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 51 - 0
mjava-lianan/src/main/java/com/malk/lianan/controller/LianAnBudgetController.java

@@ -0,0 +1,51 @@
+package com.malk.lianan.controller;
+
+import cn.hutool.crypto.digest.MD5;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.common.McR;
+import com.malk.utils.PublicUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/budget/")
+@Slf4j
+public class LianAnBudgetController {
+
+    private static String SIGN_KEY="be56e057f20f883e";
+
+    @PostMapping("datasync")
+    public McR dataSync(@RequestBody JSONObject param){
+        log.info("全面预算接口:{}",param);
+        if(PublicUtil.isNull(param,"timestamp","sign","msgType","data")){
+            return McR.error("201","参数校验不通过!");
+        }
+        if(!signCheck(param)){
+            return McR.error("202","签名校验不通过!");
+        }
+        String msgType = param.getString("msgType");
+        if("T01".equals(msgType)){
+            log.info("科目数据:{}",param.get("data"));
+        }else if("T02".equals(msgType)){
+            log.info("产品数据:{}",param.get("data"));
+        }else if("T03".equals(msgType)){
+            log.info("项目数据:{}",param.get("data"));
+        }else if("Y01".equals(msgType)){
+            log.info("预算数据:{}",param.get("data"));
+        }else{
+            return McR.error("203","msgType错误!");
+        }
+        return McR.success();
+    }
+
+    private static boolean signCheck(JSONObject param){
+        String data=SIGN_KEY+param.getString("timestamp")+param.getString("data");
+        MD5 md5 = new MD5();
+        String digestHex = md5.digestHex(data);
+        return digestHex.equals(param.getString("sign"));
+    }
+}

+ 0 - 0
mjava-lianan/src/main/java/com/malk/lianan/controller/LianAnGyPayController.java


Некоторые файлы не были показаны из-за большого количества измененных файлов