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

Merge remote-tracking branch 'origin/master'

“lqy месяцев назад: 3
Родитель
Сommit
593446e415
23 измененных файлов с 968 добавлено и 110 удалено
  1. 35 14
      mjava-hengyilong/src/main/java/com/malk/hengyilong/service/impl/EqbHylServiceImpl.java
  2. 1 1
      mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/MjavaHengyilongApplicationTests.java
  3. 91 15
      mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/ToEqbTest.java
  4. 45 35
      mjava-jinlun/src/main/java/com/malk/jinlun/service/impl/JinlunTaskServiceImpl.java
  5. 2 2
      mjava-lingmingguangzi/src/main/java/com/malk/lingmingguangzi/service/LingmingguangziServiceImpl.java
  6. 4 2
      mjava-mc/src/main/java/com/malk/mc/controller/McYdController.java
  7. 4 0
      mjava-mc/src/main/java/com/malk/mc/service/McYdService.java
  8. 225 0
      mjava-mc/src/main/java/com/malk/mc/service/impl/McYdServiceImpl.java
  9. 1 1
      mjava-mc/src/main/resources/application.yml
  10. 137 28
      mjava-siku/src/main/java/com/malk/siku/service/impl/SikuServiceImpl.java
  11. 7 0
      mjava-siku/src/main/java/com/malk/siku/utils/MkBxUtil.java
  12. 63 0
      mjava-siku/src/test/java/com.malk.siku/SkTest.java
  13. 3 2
      mjava-xiaoliu/src/main/resources/application-dev.yml
  14. 4 3
      mjava-xiaoliu/src/main/resources/application-prod.yml
  15. 21 0
      mjava-zhongche/src/main/java/com/malk/zhongche/config/StartupRunner.java
  16. 12 0
      mjava-zhongche/src/main/java/com/malk/zhongche/controller/ZhongcheController.java
  17. 7 0
      mjava-zhongche/src/main/java/com/malk/zhongche/service/McProjectService.java
  18. 4 0
      mjava-zhongche/src/main/java/com/malk/zhongche/service/ZhongcheService.java
  19. 29 0
      mjava-zhongche/src/main/java/com/malk/zhongche/service/impl/McProjectServiceImpl.java
  20. 266 6
      mjava-zhongche/src/main/java/com/malk/zhongche/service/impl/ZhongcheServiceImpl.java
  21. 3 0
      mjava-zhongche/src/main/resources/application-dev.yml
  22. 3 0
      mjava-zhongche/src/main/resources/application-prod.yml
  23. 1 1
      mjava-zhongche/src/main/resources/application.yml

+ 35 - 14
mjava-hengyilong/src/main/java/com/malk/hengyilong/service/impl/EqbHylServiceImpl.java

@@ -49,7 +49,8 @@ public class EqbHylServiceImpl implements EqbHylService {
     @Value("${server.host}")
     @Value("${server.host}")
     private String serverHost;
     private String serverHost;
 
 
-    private static String bjd_docTemplateId ="1d2f50e82f514144b72313b1dddcb552";
+    private static String bjdHYL_docTemplateId ="1d2f50e82f514144b72313b1dddcb552";
+    private static String bjdSH_docTemplateId ="e7440c3f38724b239d7e9dcf7329804a";
 
 
     private static String ht_docTemplateId ="d481b2222879447f84d992bac20784d0";
     private static String ht_docTemplateId ="d481b2222879447f84d992bac20784d0";
 
 
@@ -78,6 +79,7 @@ public class EqbHylServiceImpl implements EqbHylService {
                 case "quotation":
                 case "quotation":
                     fileName = UtilMap.getString(formData, "textField_mn5mis1m");
                     fileName = UtilMap.getString(formData, "textField_mn5mis1m");
                     getQuotation(formData, components, reqBodyObj, fileName);
                     getQuotation(formData, components, reqBodyObj, fileName);
+                    shouldExecutePost = true;
                     break;
                     break;
                 case "contract":
                 case "contract":
                     String signStatus = UtilMap.getString(formData, "radioField_mkcbpvh8");
                     String signStatus = UtilMap.getString(formData, "radioField_mkcbpvh8");
@@ -96,7 +98,7 @@ public class EqbHylServiceImpl implements EqbHylService {
             }
             }
             Map fileResult = eqbPost("/v3/files/create-by-doc-template", reqBodyObj);
             Map fileResult = eqbPost("/v3/files/create-by-doc-template", reqBodyObj);
             String fileId = UtilMap.getString(fileResult,"fileId");
             String fileId = UtilMap.getString(fileResult,"fileId");
-            //文档转换pdf需时间--否则文档未成功转换成pdf
+//            文档转换pdf需时间--否则文档未成功转换成pdf
             try {
             try {
                 Thread.sleep(3000);
                 Thread.sleep(3000);
             } catch (InterruptedException e) {
             } catch (InterruptedException e) {
@@ -244,16 +246,26 @@ public class EqbHylServiceImpl implements EqbHylService {
         List<Map> productDetail = new ArrayList<>();
         List<Map> productDetail = new ArrayList<>();
         productDetail.add(getRowMap(false));
         productDetail.add(getRowMap(false));
         for (int i = 0; i < productTable.size(); i++) {
         for (int i = 0; i < productTable.size(); i++) {
-            String productName = productTable.get(i).containsKey("textField_mn5wpqov")?UtilMap.getString(productTable.get(i), "textField_mn5wpqov"):"";//产品名称
-            String productModel = productTable.get(i).containsKey("textField_mogxdk7x")?UtilMap.getString(productTable.get(i), "textField_mogxdk7x"):"";//产品型号
-            String productUnit = productTable.get(i).containsKey("textField_mogxdk7y")?UtilMap.getString(productTable.get(i), "textField_mogxdk7y"):"";//产品规格
+            String productType = productTable.get(i).containsKey("selectField_mq6g5d7h")?UtilMap.getString(productTable.get(i), "selectField_mq6g5d7h"):"";//产品类型
+            String productName = productTable.get(i).containsKey("textField_mq505rze")?UtilMap.getString(productTable.get(i), "textField_mq505rze"):"";//产品名称
+//            String productModel = productTable.get(i).containsKey("textField_mogxdk7x")?UtilMap.getString(productTable.get(i), "textField_mogxdk7x"):"";//产品型号--舍弃
+            String productSize = productTable.get(i).containsKey("textField_mogxdk7y")?UtilMap.getString(productTable.get(i), "textField_mogxdk7y"):"";//产品规格
             String productNum = productTable.get(i).containsKey("numberField_mkdl67qd")?UtilMap.getString(productTable.get(i), "numberField_mkdl67qd"):"";//数量
             String productNum = productTable.get(i).containsKey("numberField_mkdl67qd")?UtilMap.getString(productTable.get(i), "numberField_mkdl67qd"):"";//数量
+            String productUnit = productTable.get(i).containsKey("numberField_mkdl67qd")?UtilMap.getString(productTable.get(i), "numberField_mkdl67qd"):"";//单位
             double productPrice = productTable.get(i).containsKey("numberField_mkdl67qe")?UtilMap.getDouble(productTable.get(i), "numberField_mkdl67qe"):0;//单价
             double productPrice = productTable.get(i).containsKey("numberField_mkdl67qe")?UtilMap.getDouble(productTable.get(i), "numberField_mkdl67qe"):0;//单价
-            String note = productTable.get(i).containsKey("textField_mjb71qaq")?UtilMap.getString(productTable.get(i), "textField_mjb71qaq"):"";//备注
-            if (i == 0){
-                productDetail.add(getRowMap(false,productName,productModel,productUnit,productNum,productPrice,note));
-            }else {
-                productDetail.add(getRowMap(true,productName,productModel,productUnit,productNum,productPrice,note));
+            String note = productTable.get(i).containsKey("textField_mkdl67qg")?UtilMap.getString(productTable.get(i), "textField_mkdl67qg"):"";//备注
+            if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
+                if (i == 0){
+                    productDetail.add(getRowMap(false,productType,productName,productSize,productNum,productUnit,productPrice,note));
+                }else {
+                    productDetail.add(getRowMap(true,productType,productName,productSize,productNum,productUnit,productPrice,note));
+                }
+            }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
+                if (i == 0){
+                    productDetail.add(getRowMap(false,productName,productSize,productNum,productUnit,productPrice,note));
+                }else {
+                    productDetail.add(getRowMap(true,productName,productSize,productNum,productUnit,productPrice,note));
+                }
             }
             }
         }
         }
         Map productDetailMap = new HashMap();
         Map productDetailMap = new HashMap();
@@ -274,7 +286,11 @@ public class EqbHylServiceImpl implements EqbHylService {
         components.add(company);
         components.add(company);
         components.add(companyEng);
         components.add(companyEng);
         components.add(companySeal);
         components.add(companySeal);
-        reqBodyObj.put("docTemplateId", bjd_docTemplateId);
+        if ("恒益隆贸易(上海)有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))) {
+            reqBodyObj.put("docTemplateId", bjdHYL_docTemplateId);
+        }else  if ("上海绍贺贸易有限公司".equals(UtilMap.getString(formData, "selectField_mjmlcp4y"))){
+            reqBodyObj.put("docTemplateId", bjdSH_docTemplateId);
+        }
         reqBodyObj.put("fileName", fileName+".pdf");
         reqBodyObj.put("fileName", fileName+".pdf");
         reqBodyObj.put("components", components);
         reqBodyObj.put("components", components);
         }catch (Exception e){
         }catch (Exception e){
@@ -304,6 +320,10 @@ public class EqbHylServiceImpl implements EqbHylService {
             Map supplier = new HashMap();
             Map supplier = new HashMap();
             supplier.put("componentKey", "supplier");
             supplier.put("componentKey", "supplier");
             supplier.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");
             supplier.put("componentValue", formData.containsKey("selectField_mjmlcp4y")?UtilMap.getString(formData, "selectField_mjmlcp4y"):"");
+            //送货地址
+            Map productAddress = new HashMap();
+            productAddress.put("componentKey", "productAddress");
+            productAddress.put("componentValue", formData.containsKey("textareaField_ml3g7xro")?UtilMap.getString(formData, "textareaField_ml3g7xro"):"");
 
 
             //需方
             //需方
             Map buyer = new HashMap();
             Map buyer = new HashMap();
@@ -389,13 +409,13 @@ public class EqbHylServiceImpl implements EqbHylService {
             List<Map> productDetail = new ArrayList<>();
             List<Map> productDetail = new ArrayList<>();
             productDetail.add(getRowMap(false));
             productDetail.add(getRowMap(false));
             for (int i = 0; i < productTable.size(); i++) {
             for (int i = 0; i < productTable.size(); i++) {
-                String productName = productTable.get(i).containsKey("textField_mkdlflks")?UtilMap.getString(productTable.get(i), "textField_mkdlflks"):"";//产品名称
+                String productName = productTable.get(i).containsKey("textField_mq505rze")?UtilMap.getString(productTable.get(i), "textField_mq505rze"):"";//产品名称
                 String productModel = productTable.get(i).containsKey("textField_mp5c1fkt")?UtilMap.getString(productTable.get(i), "textField_mp5c1fkt"):"";//规格型号
                 String productModel = productTable.get(i).containsKey("textField_mp5c1fkt")?UtilMap.getString(productTable.get(i), "textField_mp5c1fkt"):"";//规格型号
                 String productUnit = productTable.get(i).containsKey("textField_mp5c1fku")?UtilMap.getString(productTable.get(i), "textField_mp5c1fku"):"";//产品单位
                 String productUnit = productTable.get(i).containsKey("textField_mp5c1fku")?UtilMap.getString(productTable.get(i), "textField_mp5c1fku"):"";//产品单位
                 String productNum = productTable.get(i).containsKey("numberField_mkdlflkt")?UtilMap.getString(productTable.get(i), "numberField_mkdlflkt"):"";//数量
                 String productNum = productTable.get(i).containsKey("numberField_mkdlflkt")?UtilMap.getString(productTable.get(i), "numberField_mkdlflkt"):"";//数量
                 double productPrice = productTable.get(i).containsKey("numberField_mkdlflku")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflku"):0;//单价
                 double productPrice = productTable.get(i).containsKey("numberField_mkdlflku")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflku"):0;//单价
                 double productSum = productTable.get(i).containsKey("numberField_mkdlflkv")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflkv"):0;//金额小计
                 double productSum = productTable.get(i).containsKey("numberField_mkdlflkv")?UtilMap.getDouble(productTable.get(i), "numberField_mkdlflkv"):0;//金额小计
-                String note = productTable.get(i).containsKey("textField_mjb71qaq")?UtilMap.getString(productTable.get(i), "textField_mjb71qaq"):"";//备注
+                String note = productTable.get(i).containsKey("textField_mkdlflkw")?UtilMap.getString(productTable.get(i), "textField_mkdlflkw"):"";//备注
                 if (i == 0){
                 if (i == 0){
                     productDetail.add(getRowMap(false,productName,productModel,productUnit,productNum,productPrice,productSum,note));
                     productDetail.add(getRowMap(false,productName,productModel,productUnit,productNum,productPrice,productSum,note));
                 }else{
                 }else{
@@ -403,7 +423,7 @@ public class EqbHylServiceImpl implements EqbHylService {
                 }
                 }
             }
             }
             if (!productTable.isEmpty()) {
             if (!productTable.isEmpty()) {
-                productDetail.add(getRowMap(true, "金额合计", "大写金额(人民币):",  UtilMap.getDouble(formData, "textField_mpandaox"), "", "", "小写(RMB):", UtilMap.getDouble(formData, "numberfield_WAUnrcAf")));
+                productDetail.add(getRowMap(true, "金额合计", "大写金额(人民币):",UtilMap.getString(formData, "textField_mpandaox"), "", "", "小写(RMB):", UtilMap.getDouble(formData, "numberfield_WAUnrcAf")));
             }
             }
             Map productDetailMap = new HashMap();
             Map productDetailMap = new HashMap();
             productDetailMap.put("componentKey", "productDetail");
             productDetailMap.put("componentKey", "productDetail");
@@ -412,6 +432,7 @@ public class EqbHylServiceImpl implements EqbHylService {
             components.add(companyTitle);
             components.add(companyTitle);
             components.add(companyEng);
             components.add(companyEng);
             components.add(supplier);
             components.add(supplier);
+            components.add(productAddress);
             components.add(buyer);
             components.add(buyer);
             components.add(contractNo);
             components.add(contractNo);
             components.add(signDate);
             components.add(signDate);

+ 1 - 1
mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/MjavaHengyilongApplicationTests.java

@@ -32,7 +32,7 @@ class MjavaHengyilongApplicationTests {
 
 
     @Test
     @Test
     void quotationToEqb(){
     void quotationToEqb(){
-//        McR mcR = eqbHylService.quotationToEqb(UtilMap.map("formInstance, type","65b19c02-6b53-455f-937e-73e9135c561d, contract"));
+//        McR mcR = eqbHylService.quotationToEqb(UtilMap.map("formInstance, type","5f1b8f91-2056-4fa4-a4de-2f1d9501c3c2, contract"));
     }
     }
 
 
 }
 }

+ 91 - 15
mjava-hengyilong/src/test/java/com/malk/hengyilong/mjavahengyilong/ToEqbTest.java

@@ -46,22 +46,24 @@ public class ToEqbTest {
         String appKey = "7e464621b3aa4a0e39a6557009b38214";
         String appKey = "7e464621b3aa4a0e39a6557009b38214";
         // e签宝接口调用域名(正式环境)
         // e签宝接口调用域名(正式环境)
         String host = "https://openapi.esign.cn";
         String host = "https://openapi.esign.cn";
-        //   报价单模板文件     fileId
-//        String fileId ="cacddedc33ff45cea8acd4e8a8f81ac4";
-        //     报价单模板文件   docTemplateId
-//        String docTemplateId ="1d2f50e82f514144b72313b1dddcb552";
-        //     报价单模板文件   filecontentMd5
-//        String filecontentMd5 ="nJsZC4SzKUudj0awHel4oQ==";
+//           报价单模板文件     fileId
+        String fileId ="cacddedc33ff45cea8acd4e8a8f81ac4";
+//             报价单模板文件   docTemplateId
+//        String docTemplateId ="1d2f50e82f514144b72313b1dddcb552";//恒益隆模板id
+        String docTemplateId ="e7440c3f38724b239d7e9dcf7329804a";//绍贺模板id
+
+//             报价单模板文件   filecontentMd5
+        String filecontentMd5 ="nJsZC4SzKUudj0awHel4oQ==";
 
 
        //   购销合同模板文件     fileId
        //   购销合同模板文件     fileId
-        String fileId ="c39361f5ca74466a81287f90e94f06c3";
-        //        购销合同模板文件docTemplateId
-//        0064564bea704fc587a249680064b98c
-//        0cc8c51361444dc7bd39385898893812
-//        0064564bea704fc587a249680064b98c
-        String docTemplateId ="d481b2222879447f84d992bac20784d0";
-        //     购销合同模板文件   filecontentMd5
-        String filecontentMd5 ="kPALmlC0o3nU8O6U1HuaxQ==";
+//        String fileId ="c39361f5ca74466a81287f90e94f06c3";
+//        //        购销合同模板文件docTemplateId
+////        0064564bea704fc587a249680064b98c
+////        0cc8c51361444dc7bd39385898893812
+////        0064564bea704fc587a249680064b98c
+//        String docTemplateId ="d481b2222879447f84d992bac20784d0";
+//        //     购销合同模板文件   filecontentMd5
+//        String filecontentMd5 ="kPALmlC0o3nU8O6U1HuaxQ==";
 
 
         //步骤1:上传本地文件并转成HTML格式
         //步骤1:上传本地文件并转成HTML格式
         //1.1获取文件上传地址
         //1.1获取文件上传地址
@@ -80,6 +82,8 @@ public class ToEqbTest {
 //        getDocTemplateEditUrl(appId,appKey,host,docTemplateId);
 //        getDocTemplateEditUrl(appId,appKey,host,docTemplateId);
 //
 //
 //
 //
+//        复制合同模板
+//        copyDocTemplate(appId,appKey,host,docTemplateId,"报价单-绍贺");
 //        //获取 HTML 模板中控件ID和控件Key
 //        //获取 HTML 模板中控件ID和控件Key
 //        getDocTemplateInfo(appId,appKey,host,docTemplateId);
 //        getDocTemplateInfo(appId,appKey,host,docTemplateId);
 //
 //
@@ -87,7 +91,9 @@ public class ToEqbTest {
         //6.1填写模板生成文件
         //6.1填写模板生成文件
 //        createByDocTemplate(appId,appKey,host,docTemplateId);
 //        createByDocTemplate(appId,appKey,host,docTemplateId);
 //        //6.2开发者使用【查询文件上传状态】接口获取填充后文件链接,通过此链接可查看填充后文件效果
 //        //6.2开发者使用【查询文件上传状态】接口获取填充后文件链接,通过此链接可查看填充后文件效果
-//        getFileInfo(appId,appKey,host,"a271121e3434431996e8a67fb1d8e61c");
+//        253a487cfc1c464190006e7b8532479f
+//b97b73a033a341129bf788281a064f43
+//        getFileInfo(appId,appKey,host,"be504ec0e51a4d61885a0339bc216561");
 
 
 
 
         //基于文件发起签署
         //基于文件发起签署
@@ -474,6 +480,76 @@ public class ToEqbTest {
         }
         }
     }
     }
 
 
+    /***
+     * 复制合同模板页面
+     */
+    public static void copyDocTemplate(String appId, String appKey, String host,String docTemplateId,String renameDocTemplate) {
+        // 计算签名拼接的url
+        String postUrl = "/v3/doc-templates/" + docTemplateId + "/copy";
+        // 完整的请求地址
+        String postAllUrl = host + postUrl;
+
+
+        try {
+            // 构建请求Body体
+            JSONObject reqBodyObj = new JSONObject();
+            reqBodyObj.put("renameDocTemplate", renameDocTemplate);
+
+            // 请求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");
+            JSONObject resultObj = JSONObject.parseObject(result);
+            System.out.println("请求返回信息: " + resultObj.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            String msg = MessageFormat.format("请求签名鉴权方式调用接口出现异常: {0}", e.getMessage());
+            System.out.println(msg);
+        }
+    }
+
+
     /**
     /**
      * 查询合同模板中控件详情
      * 查询合同模板中控件详情
      */
      */

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


+ 2 - 2
mjava-lingmingguangzi/src/main/java/com/malk/lingmingguangzi/service/LingmingguangziServiceImpl.java

@@ -285,7 +285,7 @@ public class LingmingguangziServiceImpl implements LingmingguangziService {
             body.put("comments", formData.get("textareaField_lwpqbm7x").toString());
             body.put("comments", formData.get("textareaField_lwpqbm7x").toString());
         }
         }
         //erp环境
         //erp环境
-        String type = formData.get("selectField_m3fgkfz9").toString();
+        String type = formData.get("selectField_m3fgkfz9_id").toString();
         String erpUrl = getErpUrl(type);
         String erpUrl = getErpUrl(type);
 
 
         Map<String, Object> result = post(erpUrl + "pws/mak/makCustomer/add", null, getHeader(type), body);
         Map<String, Object> result = post(erpUrl + "pws/mak/makCustomer/add", null, getHeader(type), body);
@@ -374,7 +374,7 @@ public class LingmingguangziServiceImpl implements LingmingguangziService {
         }
         }
 
 
         //erp环境
         //erp环境
-        String type = formData.get("selectField_m3fgkfz9").toString();
+        String type = formData.get("selectField_m3fgkfz9_id").toString();
 
 
         Map<String, Object> result = put(getErpUrl(type) + "pws/mak/makCustomer/customEdit", null, getHeader(type), body);
         Map<String, Object> result = put(getErpUrl(type) + "pws/mak/makCustomer/customEdit", null, getHeader(type), body);
         if ((boolean) result.get("success")){
         if ((boolean) result.get("success")){

+ 4 - 2
mjava-mc/src/main/java/com/malk/mc/controller/McYdController.java

@@ -161,13 +161,15 @@ public class McYdController {
     //海天二期开发部分(出库)
     //海天二期开发部分(出库)
     @PostMapping("/multiLocationOutbound")
     @PostMapping("/multiLocationOutbound")
     public McR multiLocationOutbound(@RequestBody Map map) {
     public McR multiLocationOutbound(@RequestBody Map map) {
-        return mcYdService.multiLocationOutbound(map);
+//        return mcYdService.multiLocationOutbound(map);
+        return mcYdService.multiLocationOutboundAI(map);
     }
     }
 
 
     //海天二期开发部分(入库)
     //海天二期开发部分(入库)
     @PostMapping("/WarehouseStorage")
     @PostMapping("/WarehouseStorage")
     public McR WarehouseStorage(@RequestBody Map map) {
     public McR WarehouseStorage(@RequestBody Map map) {
-        return mcYdService.WarehouseStorage(map);
+//        return mcYdService.WarehouseStorage(map);
+        return mcYdService.WarehouseStorageAI(map);
     }
     }
 
 
     //海天二期开发(退货)
     //海天二期开发(退货)

+ 4 - 0
mjava-mc/src/main/java/com/malk/mc/service/McYdService.java

@@ -19,8 +19,12 @@ public interface McYdService {
 
 
     McR multiLocationOutbound(Map map);
     McR multiLocationOutbound(Map map);
 
 
+    McR multiLocationOutboundAI(Map map);
+
     McR WarehouseStorage(Map map);
     McR WarehouseStorage(Map map);
 
 
+    McR WarehouseStorageAI(Map map);
+
     McR ProductReturn(Map map);
     McR ProductReturn(Map map);
 
 
     McR allocateTransfer(Map map);
     McR allocateTransfer(Map map);

+ 225 - 0
mjava-mc/src/main/java/com/malk/mc/service/impl/McYdServiceImpl.java

@@ -38,6 +38,7 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.LocalTime;
 import java.util.*;
 import java.util.*;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 @Slf4j
 @Slf4j
@@ -59,6 +60,7 @@ public class McYdServiceImpl implements McYdService {
 
 
     @Autowired
     @Autowired
     private DDClient_Contacts ddClient_contacts;
     private DDClient_Contacts ddClient_contacts;
+
     @Override
     @Override
     @Async
     @Async
     public void updateFormDataVersion(Map map) {
     public void updateFormDataVersion(Map map) {
@@ -344,6 +346,100 @@ public class McYdServiceImpl implements McYdService {
         return McR.success();
         return McR.success();
     }
     }
 
 
+    @Override
+    public McR multiLocationOutboundAI(Map map) {
+        String formInstId = UtilMap.getString(map, "formInstId");
+        log.info("出库单实例id:" + formInstId);
+
+        // 查询出库单主数据(支持重试)
+        Map d = executeWithRetry(() -> ydClient.queryData(YDParam.builder()
+                                .formInstId(formInstId)
+                                .formUuid("FORM-3208DFE5463549A9A57FB94358A75E80PV5F")
+                                .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                                .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                                .userId("332051151139376769").build(),
+                        YDConf.FORM_QUERY.retrieve_id).getFormData(),
+                "查询出库单主数据", 3, 1000);
+
+        System.out.println("出库单数据:" + d);
+        List<Map> mapList = (List<Map>) d.get("tableField_m8mo8506");
+        System.out.println("出库单明细数据:" + mapList);
+
+        for (Map map1 : mapList) {
+            String componentInstId = map1.get("textField_ma1usp6o").toString();
+            BigDecimal outQuantity = new BigDecimal(map1.get("numberField_m8mo8508").toString());
+            processOutboundComponent(componentInstId, map1, outQuantity);
+        }
+        return McR.success();
+    }
+
+    private void processOutboundComponent(String componentInstId, Map detailRow, BigDecimal outQuantity) {
+        String componentName = detailRow.get("textField_m99kztjo").toString();
+        executeWithRetry(() -> {
+            // 1. 查询零部件当前完整数据
+            Map partData = ydClient.queryData(YDParam.builder()
+                            .formInstId(componentInstId)
+                            .formUuid("FORM-2353BE632D97434DAD55AEBD0866C44DVAT5")
+                            .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                            .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                            .userId("332051151139376769").build(),
+                    YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+            // 2. 获取当前可用库存(正确字段:numberField_m8gz97nk)
+            BigDecimal currentAvailable = parseBigDecimal(partData.get("numberField_m8gz97nk"));
+            // 计算出库后数量(应该 = currentAvailable - outQuantity)
+            BigDecimal newAvailable = currentAvailable.subtract(outQuantity);
+            System.out.println("当前可用库存:" + currentAvailable + ",出库后数量:" + newAvailable);
+
+            // 3. 解析子表仓库信息(取第一条)
+            String subTableJson = partData.get("tableField_m96gje14").toString();
+            JSONArray subArray = JSON.parseArray(subTableJson);
+            if (subArray == null || subArray.isEmpty()) {
+                throw new RuntimeException("零部件[" + componentName + "]子表数据为空,无法更新库存");
+            }
+            JSONObject warehouseObj = subArray.getJSONObject(0);
+            String warehouse = warehouseObj.getString("selectField_m88f1qi8");
+            String warehouseLocation = warehouseObj.getString("textField_m8mnxgql");
+            String safetyValue = warehouseObj.getString("numberField_m8873fn4");
+            BigDecimal currentWarehouseQty = parseBigDecimal(warehouseObj.getString("numberField_m9c8n9go"));
+            BigDecimal newWarehouseQty = currentWarehouseQty.subtract(outQuantity);
+            System.out.println("当前仓库数量:" + currentWarehouseQty + ",出库后仓库数量:" + newWarehouseQty);
+
+            // 4. 获取冻结数量(字段:numberField_m8obn6wl)并计算新冻结数量
+            BigDecimal currentFreeze = parseBigDecimal(partData.get("numberField_m8obn6wl"));
+            BigDecimal newFreeze = currentFreeze.add(outQuantity);
+            System.out.println("当前冻结数量:" + currentFreeze + ",新冻结数量:" + newFreeze);
+
+            // 5. 构建子表更新数据(完整替换)
+            List<Map<String, Object>> newSubTable = new ArrayList<>();
+            Map<String, Object> newRow = new HashMap<>();
+            newRow.put("selectField_m88f1qi8", warehouse);
+            newRow.put("textField_m8mnxgql", warehouseLocation);
+            newRow.put("numberField_m8873fn4", safetyValue);
+            newRow.put("numberField_m9c8n9go", newWarehouseQty);   // 仓库数量更新为出库后数量
+            newSubTable.add(newRow);
+
+            // 6. 构建主表更新字段
+            Map<String, Object> updateData = new HashMap<>();
+            updateData.put("tableField_m96gje14", newSubTable);
+            updateData.put("numberField_m8obn6wl", newFreeze);      // 冻结数量累加
+            updateData.put("numberField_m8gz97nk", newAvailable);   // 可用库存更新为出库后数量
+
+            // 7. 执行原子更新(一次调用同时修改主表和子表)
+            ydClient.operateData(YDParam.builder()
+                            .formInstId(componentInstId)
+                            .formUuid("FORM-2353BE632D97434DAD55AEBD0866C44DVAT5")
+                            .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                            .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                            .updateFormDataJson(JSONObject.toJSONString(updateData))
+                            .userId("332051151139376769").build(),
+                    YDConf.FORM_OPERATION.update);
+
+            System.out.println("----------------------零部件[" + componentName + "]主表及子表数据原子更新完毕!------------------");
+            return null;
+        }, "处理出库零部件[" + componentName + "]实例[" + componentInstId + "]", 3, 1000);
+    }
+
     @Override
     @Override
     public McR WarehouseStorage(Map map) {
     public McR WarehouseStorage(Map map) {
         String formInstId = UtilMap.getString(map,"formInstId");//实例id(入库单)
         String formInstId = UtilMap.getString(map,"formInstId");//实例id(入库单)
@@ -420,6 +516,135 @@ public class McYdServiceImpl implements McYdService {
         return McR.success();
         return McR.success();
     }
     }
 
 
+
+    @Override
+    public McR WarehouseStorageAI(Map map) {
+        String formInstId = UtilMap.getString(map, "formInstId");
+        log.info("入库单实例id:" + formInstId);
+
+        Map d = executeWithRetry(() -> ydClient.queryData(YDParam.builder()
+                                .formInstId(formInstId)
+                                .formUuid("FORM-6DED8EB4CF0446DB8841C7798E106F2886OH")
+                                .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                                .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                                .userId("332051151139376769").build(),
+                        YDConf.FORM_QUERY.retrieve_id).getFormData(),
+                "查询入库单主数据", 3, 1000);
+
+        System.out.println("入库单数据:" +   d);
+        List<Map> mapList = (List<Map>) d.get("tableField_m8mseubi");
+        System.out.println("入库单明细数据:" + mapList);
+
+        for (Map map1 : mapList) {
+            String componentInstId = map1.get("textField_ma3jhnpr").toString();
+            BigDecimal inQuantity = new BigDecimal(map1.get("numberField_m8mseubm").toString());
+            processComponent(componentInstId, map1, inQuantity);
+        }
+        return McR.success();
+    }
+
+    private void processComponent(String componentInstId, Map detailRow, BigDecimal inQuantity) {
+        String componentName = detailRow.get("textField_m9b1vd2w").toString();
+        executeWithRetry(() -> {
+            Map partData = ydClient.queryData(YDParam.builder()
+                            .formInstId(componentInstId)
+                            .formUuid("FORM-2353BE632D97434DAD55AEBD0866C44DVAT5")
+                            .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                            .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                            .userId("332051151139376769").build(),
+                    YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+            String subTableJson = partData.get("tableField_m96gje14").toString();
+            JSONArray subArray = JSON.parseArray(subTableJson);
+            if (subArray == null || subArray.isEmpty()) {
+                // 改用 RuntimeException,此类业务错误不应重试
+                throw new RuntimeException("零部件[" + componentName + "]子表数据为空,无法更新库存");
+            }
+            JSONObject warehouseObj = subArray.getJSONObject(0);
+            String warehouse = warehouseObj.getString("selectField_m88f1qi8");
+            String warehouseLocation = warehouseObj.getString("textField_m8mnxgql");
+            String safetyValue = warehouseObj.getString("numberField_m8873fn4");
+            BigDecimal currentWarehouseQty = parseBigDecimal(warehouseObj.getString("numberField_m9c8n9go"));
+
+            BigDecimal currentVirtual = parseBigDecimal(partData.get("numberField_m8obn6wq"));
+            BigDecimal currentAvailable = parseBigDecimal(partData.get("numberField_m8gz97nk"));
+
+            BigDecimal newWarehouseQty = currentWarehouseQty.add(inQuantity);
+            BigDecimal newVirtual = currentVirtual.add(inQuantity);
+            BigDecimal newAvailable = currentAvailable.add(inQuantity);
+
+            List<Map<String, Object>> newSubTable = new ArrayList<>();
+            Map<String, Object> newRow = new HashMap<>();
+            newRow.put("selectField_m88f1qi8", warehouse);
+            newRow.put("textField_m8mnxgql", warehouseLocation);
+            newRow.put("numberField_m8873fn4", safetyValue);
+            newRow.put("numberField_m9c8n9go", newWarehouseQty);
+            newSubTable.add(newRow);
+
+            Map<String, Object> updateData = new HashMap<>();
+            updateData.put("tableField_m96gje14", newSubTable);
+            updateData.put("numberField_m8obn6wq", newVirtual);
+            updateData.put("numberField_m8gz97nk", newAvailable);
+
+            ydClient.operateData(YDParam.builder()
+                            .formInstId(componentInstId)
+                            .formUuid("FORM-2353BE632D97434DAD55AEBD0866C44DVAT5")
+                            .appType("APP_GNQ1RGK68X4JNZUEU8RQ")
+                            .systemToken("XH866P81QDOTQ0218TGZM9WCNXOF24WIP488M7A5")
+                            .updateFormDataJson(JSONObject.toJSONString(updateData))
+                            .userId("332051151139376769").build(),
+                    YDConf.FORM_OPERATION.update);
+
+            System.out.println("----------------------零部件[" + componentName + "]主表及子表数据原子更新完毕!------------------");
+            return null;
+        }, "处理零部件[" + componentName + "]实例[" + componentInstId + "]", 3, 1000);
+    }
+
+    private <T> T executeWithRetry(Supplier<T> action, String operationName, int maxRetries, long initialDelayMs) {
+        int attempt = 0;
+        while (true) {
+            try {
+                return action.get();
+            } catch (McException e) {
+                boolean isTemporary = e.getMessage() != null && e.getMessage().contains("temporary failure");
+                if (!isTemporary || attempt >= maxRetries) {
+                    log.error("操作[{}]失败,非临时异常或已达最大重试次数({}),异常信息:", operationName, maxRetries, e);
+                    throw e;
+                }
+                attempt++;
+                long delay = initialDelayMs * (1L << (attempt - 1));
+                log.warn("操作[{}]遇到临时故障,第{}次重试,等待{}ms", operationName, attempt, delay);
+                try {
+                    Thread.sleep(delay);
+                } catch (InterruptedException ie) {
+                    Thread.currentThread().interrupt();
+                    // 重试被中断,改为抛出 RuntimeException,避免编译错误
+                    throw new RuntimeException("重试被中断", ie);
+                }
+            } catch (RuntimeException e) {
+                // 业务异常(如子表为空)直接抛出,不重试
+                log.error("操作[{}]遇到业务异常,不重试", operationName, e);
+                throw e;
+            } catch (Exception e) {
+                log.error("操作[{}]遇到非McException异常,不重试", operationName, e);
+                throw e;
+            }
+        }
+    }
+
+
+    private BigDecimal parseBigDecimal(Object value) {
+        if (value == null) return BigDecimal.ZERO;
+        String str = value.toString().trim();
+        if (str.isEmpty()) return BigDecimal.ZERO;
+        try {
+            return new BigDecimal(str);
+        } catch (NumberFormatException e) {
+            log.warn("解析BigDecimal失败,值:{},返回0", str);
+            return BigDecimal.ZERO;
+        }
+    }
+
     @Override
     @Override
     public McR ProductReturn(Map map) {
     public McR ProductReturn(Map map) {
         String formInstId = UtilMap.getString(map,"formInstId");//实例id(退货单)
         String formInstId = UtilMap.getString(map,"formInstId");//实例id(退货单)

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

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

+ 137 - 28
mjava-siku/src/main/java/com/malk/siku/service/impl/SikuServiceImpl.java

@@ -149,12 +149,11 @@ public class SikuServiceImpl implements SikuService {
 
 
             List<Map> data2 = UtilMap.getList(result2, "data");
             List<Map> data2 = UtilMap.getList(result2, "data");
             String status2 = UtilMap.getString(data2.get(0), "status");
             String status2 = UtilMap.getString(data2.get(0), "status");
-            if ("ALL_FAIL".equals(status2)){
-                String message = UtilMap.getString(data2.get(0), "message");
-
+            String message2 = UtilMap.getString(data2.get(0), "message");
+            if ("ALL_FAIL".equals(status2) || Strings.isNotBlank(message2)){
                 ydClient.operateData(YDParam.builder()
                 ydClient.operateData(YDParam.builder()
                         .formInstanceId(formInstId)
                         .formInstanceId(formInstId)
-                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mmx7nk6m, textareaField_mmx7nk6r","入库成功,账号保存失败",message)))
+                        .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mmx7nk6m, textareaField_mmx7nk6r","入库成功,账号保存失败",message2)))
                         .build(), YDConf.FORM_OPERATION.update);
                         .build(), YDConf.FORM_OPERATION.update);
             }else {
             }else {
                 ydClient.operateData(YDParam.builder()
                 ydClient.operateData(YDParam.builder()
@@ -288,7 +287,9 @@ public class SikuServiceImpl implements SikuService {
     private boolean isTrue(Map result){
     private boolean isTrue(Map result){
         String messageCode = UtilMap.getString(result, "messageCode");
         String messageCode = UtilMap.getString(result, "messageCode");
 
 
-        if (Objects.nonNull(messageCode) && "SUCCESS".equals(messageCode)){
+        String code = UtilMap.getString(result,"code");
+
+        if ((Objects.nonNull(messageCode) && "SUCCESS".equals(messageCode)) || (Objects.nonNull(code) && "ACK".equals(code))){
             return true;
             return true;
         }else {
         }else {
             return false;
             return false;
@@ -477,16 +478,17 @@ public class SikuServiceImpl implements SikuService {
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwt2wcn"));//逾期天数
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwt2wcn"));//逾期天数
 
 
+                Map consumeAmount = new HashMap();
+                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij5e")));//结算金额
+                consumeAmount.put("currency","CNY");
+
+                customObject.put("CF42",consumeAmount);//采购金额
 
 
                 body.put("customObject",customObject);
                 body.put("customObject",customObject);
 
 
                 //报销单费用导入
                 //报销单费用导入
                 Map expenseListItem = new HashMap();
                 Map expenseListItem = new HashMap();
 
 
-                Map consumeAmount = new HashMap();
-                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij5e")));//结算金额
-                consumeAmount.put("currency","CNY");
-
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 String gysej = UtilMap.getString(detail, "selectField_mkkkw28y");//供应商二级
                 String gysej = UtilMap.getString(detail, "selectField_mkkkw28y");//供应商二级
@@ -507,7 +509,17 @@ public class SikuServiceImpl implements SikuService {
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("expenseList",Arrays.asList(expenseListItem));
                 body2.put("expenseList",Arrays.asList(expenseListItem));
 
 
-                List<String> expenseCodes = MkBxUtil.receiveExpense(body2);
+                List<String> expenseCodes = new ArrayList<>();
+                try {
+                    expenseCodes = MkBxUtil.receiveExpense(body2);
+                }catch (Exception e){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",e.getMessage())))
+                            .build(), YDConf.FORM_OPERATION.update);
+
+                    continue;
+                }
 
 
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
 
 
@@ -524,6 +536,18 @@ public class SikuServiceImpl implements SikuService {
 
 
                 Map result = MkBxUtil.receiveReimburse(body);
                 Map result = MkBxUtil.receiveReimburse(body);
 
 
+                if (isTrue(result)){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送成功","")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }else {
+                    String message = UtilMap.getString(result, "message");
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",message)))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
             }
             }
         }else {
         }else {
             List<Map> detailList = UtilMap.getList(formData, "tableField_mkkmij61");//free-采购明细
             List<Map> detailList = UtilMap.getList(formData, "tableField_mkkmij61");//free-采购明细
@@ -554,7 +578,7 @@ public class SikuServiceImpl implements SikuService {
                 }
                 }
                 body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
                 body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
 
 
-                body.put("reimburseName","FREE-" + UtilMap.getString(detail,"selectField_mkkixdd7"));//报销事由
+                body.put("reimburseName","FREE-" + UtilMap.getString(detail,"textareaField_mkkmij64"));//报销事由
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
 
 
@@ -567,15 +591,17 @@ public class SikuServiceImpl implements SikuService {
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkx"));//逾期天数
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkx"));//逾期天数
 
 
+                Map consumeAmount = new HashMap();
+                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij6p")));//结算金额
+                consumeAmount.put("currency","CNY");
+
+                customObject.put("CF42",consumeAmount);//采购金额
+
                 body.put("customObject",customObject);
                 body.put("customObject",customObject);
 
 
                 //报销单费用导入
                 //报销单费用导入
                 Map expenseListItem = new HashMap();
                 Map expenseListItem = new HashMap();
 
 
-                Map consumeAmount = new HashMap();
-                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij6p")));//结算金额
-                consumeAmount.put("currency","CNY");
-
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 String gysej = UtilMap.getString(detail, "selectField_mmwuzaql");//供应商二级
                 String gysej = UtilMap.getString(detail, "selectField_mmwuzaql");//供应商二级
@@ -596,7 +622,17 @@ public class SikuServiceImpl implements SikuService {
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("expenseList",Arrays.asList(expenseListItem));
                 body2.put("expenseList",Arrays.asList(expenseListItem));
 
 
-                List<String> expenseCodes = MkBxUtil.receiveExpense(body2);
+                List<String> expenseCodes = new ArrayList<>();
+                try {
+                    expenseCodes = MkBxUtil.receiveExpense(body2);
+                }catch (Exception e){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",e.getMessage())))
+                            .build(), YDConf.FORM_OPERATION.update);
+
+                    continue;
+                }
 
 
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
 
 
@@ -613,6 +649,18 @@ public class SikuServiceImpl implements SikuService {
 
 
                 Map result = MkBxUtil.receiveReimburse(body);
                 Map result = MkBxUtil.receiveReimburse(body);
 
 
+                if (isTrue(result)){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送成功","")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }else {
+                    String message = UtilMap.getString(result, "message");
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",message)))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
             }
             }
 
 
         }
         }
@@ -1296,15 +1344,17 @@ public class SikuServiceImpl implements SikuService {
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkv"));//逾期天数
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkv"));//逾期天数
 
 
+                Map consumeAmount = new HashMap();
+                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij5e")));//结算金额
+                consumeAmount.put("currency","CNY");
+
+                customObject.put("CF42",consumeAmount);//采购金额
+
                 body.put("customObject",customObject);
                 body.put("customObject",customObject);
 
 
                 //报销单费用导入
                 //报销单费用导入
                 Map expenseListItem = new HashMap();
                 Map expenseListItem = new HashMap();
 
 
-                Map consumeAmount = new HashMap();
-                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij5e")));//结算金额
-                consumeAmount.put("currency","CNY");
-
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 String gysej = UtilMap.getString(detail, "selectField_mkkkw28y");//供应商二级
                 String gysej = UtilMap.getString(detail, "selectField_mkkkw28y");//供应商二级
@@ -1325,7 +1375,17 @@ public class SikuServiceImpl implements SikuService {
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("expenseList",Arrays.asList(expenseListItem));
                 body2.put("expenseList",Arrays.asList(expenseListItem));
 
 
-                List<String> expenseCodes = MkBxUtil.receiveExpense(body2);
+                List<String> expenseCodes = new ArrayList<>();
+                try {
+                    expenseCodes = MkBxUtil.receiveExpense(body2);
+                }catch (Exception e){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",e.getMessage())))
+                            .build(), YDConf.FORM_OPERATION.update);
+
+                    continue;
+                }
 
 
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
 
 
@@ -1342,6 +1402,18 @@ public class SikuServiceImpl implements SikuService {
 
 
                 Map result = MkBxUtil.receiveReimburse(body);
                 Map result = MkBxUtil.receiveReimburse(body);
 
 
+                if (isTrue(result)){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送成功","")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }else {
+                    String message = UtilMap.getString(result, "message");
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",message)))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
             }
             }
         }else {
         }else {
             List<Map> detailList = UtilMap.getList(formData, "tableField_mkkmij61");//free-采购明细
             List<Map> detailList = UtilMap.getList(formData, "tableField_mkkmij61");//free-采购明细
@@ -1373,7 +1445,7 @@ public class SikuServiceImpl implements SikuService {
                 body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
                 body.put("coverDepartmentBizCode",coverDepartmentBizCode);//承担部门编码
 
 
 
 
-                body.put("reimburseName","FREE-" + UtilMap.getString(detail,"selectField_mkkixdd7"));//报销事由
+                body.put("reimburseName","FREE-" + UtilMap.getString(detail,"textareaField_mkkmij64"));//报销事由
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
                 body.put("legalEntityBizCode",legalEntityBizCode);//公司抬头编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
                 body.put("tradingPartnerBizCode",UtilMap.getString(detail,"textField_mmekbfa2"));//往来单位编码
 
 
@@ -1386,15 +1458,17 @@ public class SikuServiceImpl implements SikuService {
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF1",projectCode);//项目
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkx"));//逾期天数
                 customObject.put("CF7",UtilMap.getString(detail,"numberField_mmwswtkx"));//逾期天数
 
 
+                Map consumeAmount = new HashMap();
+                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij6p")));//结算金额
+                consumeAmount.put("currency","CNY");
+
+                customObject.put("CF42",consumeAmount);//采购金额
+
                 body.put("customObject",customObject);
                 body.put("customObject",customObject);
 
 
                 //报销单费用导入
                 //报销单费用导入
                 Map expenseListItem = new HashMap();
                 Map expenseListItem = new HashMap();
 
 
-                Map consumeAmount = new HashMap();
-                consumeAmount.put("amount",String.format("%.2f", UtilMap.getDouble(detail,"numberField_mkkmij6p")));//结算金额
-                consumeAmount.put("currency","CNY");
-
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("consumeAmount",consumeAmount);
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 expenseListItem.put("corpExpense",true);//是否对公费用,需要填写true
                 String gysej = UtilMap.getString(detail, "selectField_mmwuzaql");//供应商二级
                 String gysej = UtilMap.getString(detail, "selectField_mmwuzaql");//供应商二级
@@ -1415,7 +1489,17 @@ public class SikuServiceImpl implements SikuService {
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("employeeId",mktdrgh);//需要导入的对应员工的工号
                 body2.put("expenseList",Arrays.asList(expenseListItem));
                 body2.put("expenseList",Arrays.asList(expenseListItem));
 
 
-                List<String> expenseCodes = MkBxUtil.receiveExpense(body2);
+                List<String> expenseCodes = new ArrayList<>();
+                try {
+                    expenseCodes = MkBxUtil.receiveExpense(body2);
+                }catch (Exception e){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",e.getMessage())))
+                            .build(), YDConf.FORM_OPERATION.update);
+
+                    continue;
+                }
 
 
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
                 body.put("expenseCodes",expenseCodes);//费用类型业务编码
 
 
@@ -1431,12 +1515,27 @@ public class SikuServiceImpl implements SikuService {
 
 
 
 
                 Map result = MkBxUtil.receiveReimburse(body);
                 Map result = MkBxUtil.receiveReimburse(body);
+
+                if (isTrue(result)){
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送成功","")))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }else {
+                    String message = UtilMap.getString(result, "message");
+                    ydClient.operateData(YDParam.builder()
+                            .formInstanceId(formInstId)
+                            .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("selectField_mpp9c6w9, textareaField_mpp9c6wa","推送失败",message)))
+                            .build(), YDConf.FORM_OPERATION.update);
+                }
             }
             }
         }
         }
 
 
         return McR.success();
         return McR.success();
     }
     }
 
 
+
+
     @Override
     @Override
     public McR checkBudgetAmt(Map map) {
     public McR checkBudgetAmt(Map map) {
         String projectCode = UtilMap.getString(map, "projectCode");
         String projectCode = UtilMap.getString(map, "projectCode");
@@ -1755,6 +1854,7 @@ public class SikuServiceImpl implements SikuService {
         }
         }
     }
     }
 
 
+    @Async
     @Override
     @Override
     public void invoiceWriteBack6(Map map) {
     public void invoiceWriteBack6(Map map) {
         String formCode = UtilMap.getString(map, "formCode");//单据号
         String formCode = UtilMap.getString(map, "formCode");//单据号
@@ -1851,6 +1951,7 @@ public class SikuServiceImpl implements SikuService {
 
 
     }
     }
 
 
+    @Async
     @Override
     @Override
     public void invoiceWriteBack7(Map map) {
     public void invoiceWriteBack7(Map map) {
         String formDataCode = UtilMap.getString(map, "formDataCode");//单据类型
         String formDataCode = UtilMap.getString(map, "formDataCode");//单据类型
@@ -1920,6 +2021,7 @@ public class SikuServiceImpl implements SikuService {
 
 
     }
     }
 
 
+    @Async
     @Override
     @Override
     public void invoiceWriteBack8(Map map) {
     public void invoiceWriteBack8(Map map) {
         String formCode = UtilMap.getString(map, "formCode");//单据号
         String formCode = UtilMap.getString(map, "formCode");//单据号
@@ -2423,8 +2525,15 @@ public class SikuServiceImpl implements SikuService {
     private static Long getMkDateValue(Map formData, String entityName) {
     private static Long getMkDateValue(Map formData, String entityName) {
         Map title = UtilMap.getMap(formData, entityName);
         Map title = UtilMap.getMap(formData, entityName);
         Map value = UtilMap.getMap(title, "value");
         Map value = UtilMap.getMap(title, "value");
+        String type = UtilMap.getString(title, "type");
 
 
-        long currentTime = UtilMap.getLong(value, "currentTime");
+        long currentTime = new Date().getTime();
+
+        if ("DateTimeInput".equals(type)){
+            currentTime = UtilMap.getLong(value, "currentTime");
+        }else if ("DateRangeInput".equals(type)){
+            currentTime = UtilMap.getLong(value, "startTime");
+        }
 
 
         return currentTime;
         return currentTime;
     }
     }

+ 7 - 0
mjava-siku/src/main/java/com/malk/siku/utils/MkBxUtil.java

@@ -148,6 +148,13 @@ public class MkBxUtil {
 
 
         log.info("Result:{}",result);
         log.info("Result:{}",result);
 
 
+        String code = UtilMap.getString(result, "code");
+        if ("NACK".equals(code)){
+            String message = UtilMap.getString(result, "message");
+
+            throw new RuntimeException(message);
+        }
+
         Map data = UtilMap.getMap(result, "data");
         Map data = UtilMap.getMap(result, "data");
 
 
         List<String> expenseCodes = new ArrayList<>();
         List<String> expenseCodes = new ArrayList<>();

+ 63 - 0
mjava-siku/src/test/java/com.malk.siku/SkTest.java

@@ -1,6 +1,14 @@
 package com.malk.siku;
 package com.malk.siku;
 
 
+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.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.siku.service.SikuService;
 import com.malk.siku.service.SikuTaskService;
 import com.malk.siku.service.SikuTaskService;
+import com.malk.utils.UtilMap;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.junit.Test;
 import org.junit.Test;
@@ -14,6 +22,8 @@ import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchAlgorithmException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.*;
 
 
 @Slf4j
 @Slf4j
@@ -23,6 +33,12 @@ public class SkTest {
     @Autowired
     @Autowired
     private SikuTaskService sikuTaskService;
     private SikuTaskService sikuTaskService;
 
 
+    @Autowired
+    private SikuService sikuService;
+
+    @Autowired
+    private YDClient ydClient;
+
     @Test
     @Test
     public void getSecret(){
     public void getSecret(){
         //每刻报销-测试环境
         //每刻报销-测试环境
@@ -61,6 +77,53 @@ public class SkTest {
         sikuTaskService.syncLoanManage();
         sikuTaskService.syncLoanManage();
     }
     }
 
 
+    //批量触发供应商推送每刻
+    @Test
+    public void test2() throws ParseException {
+        String createTime = "2026-06-8 00:00:00";
+        //createTime转换为时间戳
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Date date = sdf.parse(createTime);
+        long timestamp = date.getTime(); // 毫秒时间戳
+
+        List<Map> dataList = getYdFormDataList("FORM-A4B7986899BF42BE8E6B5B9BC85839484PTG", JSONObject.toJSONString(Arrays.asList(new YDSearch("createTime", timestamp, "创建时间", YDSearch.Type.DATE_FIELD, YDSearch.Operator.GE))), YDConf.FORM_QUERY.retrieve_list_all);
+
+        /*List<Map> dataList = (List<Map>)(ydClient.queryData(YDParam.builder()
+                .formUuid("FORM-A4B7986899BF42BE8E6B5B9BC85839484PTG")
+                .searchCondition(JSONObject.toJSONString(Arrays.asList(new YDSearch("createTime",timestamp,"创建时间", YDSearch.Type.DATE_FIELD,YDSearch.Operator.GE))))
+                .pageSize(100)
+                .pageNumber(1)
+                .build(), YDConf.FORM_QUERY.retrieve_list_all).getData());*/
+
+        for (Map data : dataList) {
+            String formInstanceId = UtilMap.getString(data, "formInstanceId");
+
+            Map<String, Object> map = UtilMap.map("formInstId, type", formInstanceId, "供应商");
+
+            sikuService.saveTradingPartner(map);
+        }
+
+
+    }
+
+
+    private List<Map> getYdFormDataList(String formUuid, String searchCondition, YDConf.FORM_QUERY formQuery) {
+        List<Map> list = new ArrayList<>();
+        DDR_New ddrNew;
+        int pageNumber = 1;
+        int pageSize = 100;
+        do {
+            ddrNew = ydClient.queryData(YDParam.builder().formUuid(formUuid)
+                    .searchCondition(searchCondition)
+                    .pageNumber(pageNumber)
+                    .pageSize(pageSize).build(), formQuery);
+
+            list.addAll((List<Map>) ddrNew.getData());
+            pageNumber++;
+        }while (ddrNew.getTotalCount() > ddrNew.getPageNumber() * pageSize);
+        return list;
+    }
+
     //java md5算法
     //java md5算法
     public static String md5(String plainText)
     public static String md5(String plainText)
     {
     {

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

@@ -7,9 +7,10 @@ enable:
   scheduling: ture
   scheduling: ture
 logging:
 logging:
   config: classpath:logback-spring.xml
   config: classpath:logback-spring.xml
-  path: /home/server/xiaoliu/log/
   level:
   level:
     com.malk.*: info
     com.malk.*: info
+  file:
+    path: /home/server/xiaoliu/log/
 
 
 
 
 mybatis-plus:
 mybatis-plus:
@@ -18,7 +19,7 @@ mybatis-plus:
     map-underscore-to-camel-case: false
     map-underscore-to-camel-case: false
     #开启日志打印
     #开启日志打印
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-  type-aliases-package: com.malk.hengyilong.entity
+  type-aliases-package: com.malk.xiaoliu.entity
   #扫描mapper文件
   #扫描mapper文件
   mapper-locations: classpath:mapper/*.xml
   mapper-locations: classpath:mapper/*.xml
 
 

+ 4 - 3
mjava-xiaoliu/src/main/resources/application-prod.yml

@@ -7,9 +7,10 @@ enable:
   scheduling: ture
   scheduling: ture
 logging:
 logging:
   config: classpath:logback-spring.xml
   config: classpath:logback-spring.xml
-  path: /home/server/xiaoliu/log/
   level:
   level:
     com.malk.*: info
     com.malk.*: info
+  file:
+    path: /home/server/xiaoliu/log/
 
 
 mybatis-plus:
 mybatis-plus:
   configuration:
   configuration:
@@ -32,8 +33,8 @@ dingtalk:
   operator:
   operator:
 
 
 aliwork:
 aliwork:
-  appType: APP_QX8IOI1D22HK3GC413L5
-  systemToken: AXD66JB143P1C5Q8K93RR75ZEXSK2379ZYHJMP09
+  appType: APP_UGY7IRUWT1C8619BR7VV
+  systemToken: O7G66671RZX4QKZMI2M5V5AOY7WZ2BQR351OM11
 
 
 rhr:
 rhr:
   host: https://app91651.eapps.dingtalkcloud.com
   host: https://app91651.eapps.dingtalkcloud.com

+ 21 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/config/StartupRunner.java

@@ -0,0 +1,21 @@
+package com.malk.zhongche.config;
+
+import com.malk.zhongche.service.McProjectService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StartupRunner implements ApplicationRunner {
+
+    @Autowired
+    private McProjectService mcProjectService;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        mcProjectService.init();
+//        System.out.println("项目启动完毕,可以根据启动参数执行相应操作!");
+//        args.getOptionNames().forEach(System.out::println); // 打印所有选项参数名
+    }
+}

+ 12 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/controller/ZhongcheController.java

@@ -21,6 +21,12 @@ public class ZhongcheController {
         return zhongcheService.getTaskInfo(taskId,projectId);
         return zhongcheService.getTaskInfo(taskId,projectId);
     }
     }
 
 
+    //获取项目信息
+    @GetMapping("/getProjectInfo")
+    public McR getProjectInfo(String projectId){
+        return zhongcheService.getProjectInfo(projectId);
+    }
+
     //更新任务延期信息
     //更新任务延期信息
     @PostMapping("/updateTaskDelayInfo")
     @PostMapping("/updateTaskDelayInfo")
     public McR updateTaskDelayInfo(@RequestBody Map map){
     public McR updateTaskDelayInfo(@RequestBody Map map){
@@ -32,4 +38,10 @@ public class ZhongcheController {
     public McR updateParentTaskType(@RequestBody Map map){
     public McR updateParentTaskType(@RequestBody Map map){
         return zhongcheService.updateParentTaskType(map);
         return zhongcheService.updateParentTaskType(map);
     }
     }
+
+    //上传附件完成任务
+    @PostMapping("/finishTask")
+    public McR finishTask(@RequestBody Map map){
+        return zhongcheService.finishTask(map);
+    }
 }
 }

+ 7 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/service/McProjectService.java

@@ -0,0 +1,7 @@
+package com.malk.zhongche.service;
+
+public interface McProjectService {
+
+    void init();
+
+}

+ 4 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/service/ZhongcheService.java

@@ -13,4 +13,8 @@ public interface ZhongcheService {
 
 
     void updateLastTaskSfc();
     void updateLastTaskSfc();
 
 
+    McR finishTask(Map map);
+
+    McR getProjectInfo(String projectId);
+
 }
 }

+ 29 - 0
mjava-zhongche/src/main/java/com/malk/zhongche/service/impl/McProjectServiceImpl.java

@@ -0,0 +1,29 @@
+package com.malk.zhongche.service.impl;
+
+import com.malk.core.McProject;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.PublicUtil;
+import com.malk.utils.UtilMap;
+import com.malk.zhongche.service.McProjectService;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class McProjectServiceImpl implements McProjectService {
+    @Override
+    public void init() {
+        MDC.put("MDC_KEY_PID","1001");
+        McProject.addYida("1001",new String[] {"APP_SL9V2KUH6GBEISLNXXTJ","HOE66T71Z9H2PLVHM6EU85Q7H2AJ2YV2GRKKMWL1"});//对接TB
+        McProject.addYida("1002",new String[] {"APP_F90E02RA0Y7DJ5KLZ1W9","0YE66JA1RXGTAAJC7TJP09R8QELM3QPG7YW7MY6"});//车辆档案管理
+    }
+}

+ 266 - 6
mjava-zhongche/src/main/java/com/malk/zhongche/service/impl/ZhongcheServiceImpl.java

@@ -1,5 +1,6 @@
 package com.malk.zhongche.service.impl;
 package com.malk.zhongche.service.impl;
 
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.algorithms.Algorithm;
 import com.auth0.jwt.algorithms.Algorithm;
@@ -7,6 +8,7 @@ import com.malk.server.aliwork.YDConf;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.aliwork.YDParam;
 import com.malk.server.common.McR;
 import com.malk.server.common.McR;
 import com.malk.server.teambition.TBConf;
 import com.malk.server.teambition.TBConf;
+import com.malk.server.teambition.TBR;
 import com.malk.service.aliwork.YDClient;
 import com.malk.service.aliwork.YDClient;
 import com.malk.service.dingtalk.DDClient;
 import com.malk.service.dingtalk.DDClient;
 import com.malk.service.dingtalk.DDClient_Contacts;
 import com.malk.service.dingtalk.DDClient_Contacts;
@@ -18,9 +20,17 @@ import com.malk.zhongche.service.ZhongcheService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.util.Strings;
 import org.apache.logging.log4j.util.Strings;
+import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
 import java.time.Instant;
 import java.time.Instant;
 import java.time.ZoneId;
 import java.time.ZoneId;
@@ -46,6 +56,12 @@ public class ZhongcheServiceImpl implements ZhongcheService {
     @Autowired
     @Autowired
     private TBConf tbConf;
     private TBConf tbConf;
 
 
+    @Autowired
+    private YDConf ydConf;
+
+    @Value("${file.path}")
+    private String filePath;
+
     @Override
     @Override
     public McR getTaskInfo(String taskId,String projectId) {
     public McR getTaskInfo(String taskId,String projectId) {
         Map taskInfo = tbClient.queryTaskDetail(taskId,null,null).get(0);
         Map taskInfo = tbClient.queryTaskDetail(taskId,null,null).get(0);
@@ -126,6 +142,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
 
 
     @Override
     @Override
     public McR updateTaskDelayInfo(Map map) {
     public McR updateTaskDelayInfo(Map map) {
+        MDC.put("MDC_KEY_PID","1001");
+
         String formInstId = UtilMap.getString(map, "formInstId");
         String formInstId = UtilMap.getString(map, "formInstId");
 
 
         Map formData = ydClient.queryData(YDParam.builder()
         Map formData = ydClient.queryData(YDParam.builder()
@@ -161,6 +179,32 @@ public class ZhongcheServiceImpl implements ZhongcheService {
             }
             }
         }
         }
 
 
+        //获取管理员审批人
+        String tbOperatorId = tbConf.getOperatorId();
+
+        Map param = new HashMap();
+        param.put("appType",ydConf.getAppType());
+        param.put("systemToken",ydConf.getSystemToken());
+        param.put("userId","yida_pub_account");
+        param.put("processInstanceId",formInstId);
+        Map jsonMap = (Map) JSONObject.parse(UtilHttp.doGet("https://api.dingtalk.com/v1.0/yida/processes/operationRecords", ddClient.initTokenHeader(), param));
+        List<Map> result = UtilMap.getList(jsonMap, "result");
+        for (Map map1 : result) {
+            String activityId = UtilMap.getString(map1, "activityId");
+
+            //管理员审批节点
+            if ("node_ocmouwh06v1".equals(activityId)){
+                String operatorUserId = UtilMap.getString(map1, "operatorUserId");
+
+                Map jsonMap2 = (Map) JSONObject.parse(UtilHttp.doGet("https://open.teambition.com/api/idmap/dingtalk/getTbUserId", initHeaderToken(), UtilMap.map("dingUserIds", operatorUserId)));
+                List<Map> result2 = UtilMap.getList(jsonMap2, "result");
+                if (Objects.nonNull(result2) && !result2.isEmpty()){
+                    Map map2 = result2.get(0);
+                    tbOperatorId = UtilMap.getString(map2, "tbUserId");
+                }
+            }
+        }
+
         //更新任务截止时间
         //更新任务截止时间
 
 
         // 1. 转换为 Instant(UTC 时间点)
         // 1. 转换为 Instant(UTC 时间点)
@@ -172,7 +216,7 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         String utcDateTime = utcTime.format(utcFormatter);
         String utcDateTime = utcTime.format(utcFormatter);
         System.out.println("UTC date-time (比上海早8小时): " + utcDateTime); // 输出: 2026-03-20T01:30:00Z
         System.out.println("UTC date-time (比上海早8小时): " + utcDateTime); // 输出: 2026-03-20T01:30:00Z
 
 
-        tbClient.updateTaskDueDate(taskId, utcDateTime, tbConf.getOperatorId());
+        tbClient.updateTaskDueDate(taskId, utcDateTime, tbOperatorId);
 
 
         //更新任务延期次数
         //更新任务延期次数
         Map body = new HashMap();
         Map body = new HashMap();
@@ -182,7 +226,7 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         value.put("title",delayNum + 1 + "");
         value.put("title",delayNum + 1 + "");
         body.put("value",Arrays.asList(value));
         body.put("value",Arrays.asList(value));
 
 
-        Map map1 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
+        Map map1 = tbClient.updateTaskCustomField(taskId, tbOperatorId, body);
 
 
         log.info("map1:{}",JSONObject.toJSONString(map1));
         log.info("map1:{}",JSONObject.toJSONString(map1));
 
 
@@ -197,9 +241,9 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         }
         }
         body2.put("value",value2);
         body2.put("value",value2);
 
 
-        Map map2 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body2);
+        Map map2 = tbClient.updateTaskCustomField(taskId, tbOperatorId, body2);
 
 
-        log.info("map1:{}",JSONObject.toJSONString(map1));
+        log.info("map2:{}",JSONObject.toJSONString(map2));
 
 
         return McR.success();
         return McR.success();
     }
     }
@@ -230,8 +274,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
                 String id = UtilMap.getString(resultMap, "id");
                 String id = UtilMap.getString(resultMap, "id");
 
 
                 switch (name){
                 switch (name){
-                    case "任务企业":sfcId2 = id;break;
-                    case "末级任务(企业)":sfcId3 = id;break;
+                    case "任务企业":sfcId2 = id;break;
+                    case "末级任务企业":sfcId3 = id;break;
                     default:break;
                     default:break;
                 }
                 }
             }
             }
@@ -292,6 +336,220 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         }
         }
     }
     }
 
 
+    @Override
+    public McR finishTask(Map map) {
+        MDC.put("MDC_KEY_PID","1002");
+
+        String formInstId = UtilMap.getString(map, "formInstId");
+
+        Map formData = ydClient.queryData(YDParam.builder()
+                .formInstanceId(formInstId)
+                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+
+        String taskId = UtilMap.getString(formData, "textField_mkkrgg8y");
+        String projectId = UtilMap.getString(formData, "textField_mkkrgg8u");
+
+        if (Objects.nonNull(formData.get("attachmentField_mpzbe3w8"))){
+            List<Map> addValues = new ArrayList<>();
+
+            List<Map> fileList = (List<Map>) JSONArray.parse(String.valueOf(formData.get("attachmentField_mpzbe3w8")));
+            for (Map fileMap : fileList) {
+                String ydDownloadUrl = fileMap.get("downloadUrl").toString();
+                String fileName = fileMap.get("name").toString();
+
+                try {
+                    //下载宜搭附件
+                    downloadYdFile(ydDownloadUrl, filePath + fileName);
+                    System.out.println("文件下载成功!");
+
+                    //TB文件创建文件上传凭证
+                    Path path = Paths.get(filePath + fileName);
+                    String mimeType = Files.probeContentType(path);
+                    System.out.println(mimeType); // application/pdf
+
+                    File file = new File(fileName);
+                    long fileSize = file.length();
+
+                    Map body = new HashMap();
+                    body.put("scope", "task:"+taskId+"/attachment");
+                    body.put("fileSize", fileSize);
+                    body.put("fileType", mimeType);
+                    body.put("fileName", fileName);
+                    body.put("category", "attachment");
+
+                    TBR tbr = (TBR) UtilHttp.doPost("https://open.teambition.com/api/v3/awos/upload-token", initHeaderToken(), null, body, TBR.class);
+                    Map result = (Map) tbr.getResult();
+                    String uploadUrl = UtilMap.getString(result, "uploadUrl");
+                    String token = UtilMap.getString(result, "token");
+
+                    //上传文件
+                    uploadFile(filePath + fileName, uploadUrl, mimeType);
+
+                    Map value = new HashMap();
+                    value.put("title",fileName);
+                    value.put("metaString",JSONObject.toJSONString(UtilMap.map("fileToken",token)));
+
+                    addValues.add(value);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            //更新tb任务附件
+            Map body = new HashMap();
+            body.put("customfieldId", "67e372b0142aea12588c2d22");
+            body.put("addValues",addValues);
+
+            Map map2 = tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body);
+            log.info("map2:{}",JSONObject.toJSONString(map2));
+
+            //查询任务所在工作流的任务状态列表
+            TBR tbr = (TBR) UtilHttp.doGet("https://open.teambition.com/api/v3/task/" + taskId + "/tfs", initHeaderToken(), null, TBR.class);
+
+            List<Map> tfsList = (List<Map>) tbr.getResult();
+
+            for (Map tfsMap : tfsList) {
+                String tfsName = UtilMap.getString(tfsMap, "name");
+
+                if ("已完成".equals(tfsName)){
+                    String tfsId = UtilMap.getString(tfsMap, "id");
+                    //完成tb任务
+                    tbClient.updateTaskFlowStatus(taskId, tbConf.getOperatorId(), tfsId,null);
+                }
+            }
+        }
+
+        return McR.success();
+    }
+
+    @Override
+    public McR getProjectInfo(String projectId) {
+        List<Map> results = tbClient.projectDetail(projectId, null, null);
+
+        Map result = (Map) results.get(0);
+
+        Map map = new HashMap();
+
+        List<Map> customfields = UtilMap.getList(result, "customfields");
+
+        for (Map customfield : customfields) {
+            String customfieldId = UtilMap.getString(customfield, "customfieldId");
+
+            //项目号
+            if ("6805ecf00763b2e708d760bc".equals(customfieldId)){
+                List<Map> values = UtilMap.getList(customfield, "value");
+
+                Map value = values.get(0);
+
+                String title = UtilMap.getString(value, "title");
+
+                map.put("projectNo",title);
+            }
+        }
+
+        return McR.success(map);
+    }
+
+    /**
+     * 上传文件(核心方法)
+     * @param filePath 本地文件路径(如"2.png")
+     * @param uploadUrl 接口地址(如Postman中的PUT URL)
+     * @param contentType 文件类型(如"image/png",可留空由服务端自动识别)
+     * @return 服务端响应内容
+     */
+    public static String uploadFile(String filePath, String uploadUrl, String contentType) throws IOException {
+        File file = new File(filePath);
+        if (!file.exists()) {
+            throw new FileNotFoundException("文件不存在:" + filePath);
+        }
+
+        // 1. 创建URL并打开连接
+        URL url = new URL(uploadUrl);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+        try {
+            // 2. 配置请求属性(必须为PUT,允许写入请求体)
+            conn.setRequestMethod("PUT");
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            conn.setConnectTimeout(30000); // 连接超时30秒
+            conn.setReadTimeout(30000);    // 读取超时30秒
+
+            // 3. 设置请求头(关键:Content-Type需与文件类型匹配)
+//            if (contentType != null && !contentType.isEmpty()) {
+//                conn.setRequestProperty("Content-Type", contentType);
+//            }
+            // 可选:添加其他头信息(如鉴权Token)
+            // conn.setRequestProperty("Authorization", "Bearer your_token");
+
+            // 4. 读取文件并写入请求体(分块读取,避免大文件内存溢出)
+            try (FileInputStream fis = new FileInputStream(file);
+                 OutputStream os = conn.getOutputStream()) {
+
+                byte[] buffer = new byte[4096]; // 4KB缓冲区
+                int bytesRead;
+                long totalBytes = 0;
+
+                while ((bytesRead = fis.read(buffer)) != -1) {
+                    os.write(buffer, 0, bytesRead);
+                    totalBytes += bytesRead;
+                    // 可选:打印上传进度(每1MB打印一次)
+                    if (totalBytes % (1024 * 1024) == 0) {
+                        System.out.println("已上传:" + (totalBytes / (1024 * 1024)) + " MB");
+                    }
+                }
+            }
+
+            // 5. 获取响应码并读取响应内容
+            int responseCode = conn.getResponseCode();
+            System.out.println("响应码:" + responseCode);
+
+            // 读取响应内容(服务端返回的数据)
+            try (BufferedReader in = new BufferedReader(
+                    new InputStreamReader(conn.getInputStream()))) {
+                StringBuilder response = new StringBuilder();
+                String line;
+                while ((line = in.readLine()) != null) {
+                    response.append(line);
+                }
+                return response.toString();
+            }
+
+        } finally {
+            // 6. 断开连接(确保资源释放)
+            conn.disconnect();
+        }
+    }
+
+    //下载宜搭附件
+    private void downloadYdFile(String fileURL, String savePath) throws IOException {
+        //若是宜搭附件url 则需获得附件临时免登地址
+        fileURL = ydClient.convertTemporaryUrl(fileURL);
+
+        URL url = new URL(fileURL);
+        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+        int responseCode = httpConn.getResponseCode();
+
+        // 检查HTTP响应代码是否为200
+        if (responseCode == HttpURLConnection.HTTP_OK) {
+            InputStream inputStream = httpConn.getInputStream();
+            FileOutputStream outputStream = new FileOutputStream(savePath);
+
+            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();
+    }
+
     private Map getRootTask(String taskId) {
     private Map getRootTask(String taskId) {
         Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
         Map taskInfo = tbClient.queryTaskDetail(taskId, null, null).get(0);
 
 
@@ -353,6 +611,8 @@ public class ZhongcheServiceImpl implements ZhongcheService {
         header.put("Authorization", getAccessToken());
         header.put("Authorization", getAccessToken());
         header.put("X-Tenant-Id", tbConf.getTenantId());
         header.put("X-Tenant-Id", tbConf.getTenantId());
         header.put("X-Tenant-Type", "organization");
         header.put("X-Tenant-Type", "organization");
+        header.put("X-Operator-Id", tbConf.getOperatorId());
+
         return header;
         return header;
     }
     }
 
 

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

@@ -30,3 +30,6 @@ teambition:
   AppSecret: X77qcnv2AICiv70R41YZxGVFXRrFGCta
   AppSecret: X77qcnv2AICiv70R41YZxGVFXRrFGCta
   OperatorId: 67ce737aaec2f7379c7bbf6f
   OperatorId: 67ce737aaec2f7379c7bbf6f
   TenantId: 658a6467d87ead477d2d3f9d
   TenantId: 658a6467d87ead477d2d3f9d
+
+file:
+  path: d:\\

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

@@ -30,3 +30,6 @@ teambition:
   AppSecret: X77qcnv2AICiv70R41YZxGVFXRrFGCta
   AppSecret: X77qcnv2AICiv70R41YZxGVFXRrFGCta
   OperatorId: 67ce737aaec2f7379c7bbf6f
   OperatorId: 67ce737aaec2f7379c7bbf6f
   TenantId: 658a6467d87ead477d2d3f9d
   TenantId: 658a6467d87ead477d2d3f9d
+
+file:
+  path: /home/server/zhongche/files/

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

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