From 8c2dbd922448b88b1c28b5e87c26a31b882c28ac Mon Sep 17 00:00:00 2001
From: lty <876263681@qq.com>
Date: 星期四, 26 三月 2026 10:11:30 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java |  704 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 568 insertions(+), 136 deletions(-)

diff --git a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
index 783b114..f4f56be 100644
--- a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -20,9 +20,11 @@
 import com.zy.common.utils.NodeUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionTemplate;
 import com.alibaba.fastjson.JSON;
@@ -32,8 +34,10 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Created by vincent on 2022/4/9
@@ -70,6 +74,27 @@
     private ApiLogService apiLogService;
     @Autowired
     private PlatformTransactionManager transactionManager;
+
+    @Value("${mes-wk.base-url.test:http://192.168.0.41}")
+    private String mesWkBaseUrlTest;
+
+    @Value("${mes-wk.base-url.prod:http://192.168.0.42}")
+    private String mesWkBaseUrlProd;
+
+    @Value("${mes-wk.auth.ent-code:lfd}")
+    private String mesWkEntCode;
+
+    @Value("${mes-wk.auth.username:TL002}")
+    private String mesWkUsername;
+
+    @Value("${mes-wk.auth.password-md5:e10adc3949ba59abbe56e057f20f883e}")
+    private String mesWkPasswordMd5;
+
+    @Value("${mes-wk.auth.token-valid-minutes:30}")
+    private Integer mesWkTokenValidMinutes;
+
+    private final Map<String, MesWkTokenInfo> mesWkTokenCache = new ConcurrentHashMap<>();
+
     @Override
     @Transactional
     public void pakinOrderCreate(OpenOrderPakinParam param) {
@@ -677,7 +702,7 @@
     // 妯℃嫙璋冪敤浠撳簱1鎺ュ彛
     private String syncToWarehouse1(ErpMat mat) {
         log.info("Calling Warehouse 1 API for mat: {}", mat.getMatNr());
-        return callMatSyncApi(mat, "http://localhost:8081");
+        return callMatSyncApi(mat, "http://localhost:8888");
     }
 
     // 妯℃嫙璋冪敤浠撳簱2鎺ュ彛
@@ -752,9 +777,97 @@
             return "鎺ュ彛璋冪敤寮傚父锛�" + e.getMessage();
         }
     }
+    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
+    public void processOneOrder(OrderDto dto) {
 
+        if (dto == null) {
+            throw new CoolException("璁㈠崟鍙傛暟涓嶅畬鏁�");
+        }
+
+        ErpOrder order = new ErpOrder();
+        order.setOrderNo(dto.getOrderNo());
+        order.setOrderType(dto.getOrderType());
+        order.setWkType(dto.getWkType());
+        order.setBusinessTime(dto.getBusinessTime());
+        order.setCreateTime(dto.getCreateTime());
+        order.setWarehouseId(dto.getWareHouseId());
+        order.setOperateType(dto.getOperateType());
+        order.setSendStatus(dto.getSendStatus() != null ? dto.getSendStatus() : 0);
+
+        List<ErpOrderDetl> detls = dto.getOrderItems();
+
+        if (Cools.isEmpty(order.getOrderNo()) || order.getOrderType() == null
+                || Cools.isEmpty(order.getWkType()) || order.getBusinessTime() == null
+                || order.getCreateTime() == null || Cools.isEmpty(order.getWarehouseId())) {
+            throw new CoolException("璁㈠崟鍙傛暟涓嶅畬鏁达細" +
+                    "orderNo=" + order.getOrderNo() +
+                    "锛宱rderType=" + order.getOrderType() +
+                    "锛寃kType=" + order.getWkType() +
+                    "锛寃arehouseId=" + order.getWarehouseId());
+        }
+
+        if (Cools.isEmpty(detls)) {
+            throw new CoolException("璁㈠崟鏄庣粏涓虹┖锛�" + order.getOrderNo());
+        }
+
+        for (ErpOrderDetl d : detls) {
+            if (d == null || Cools.isEmpty(d.getLineId())
+                    || Cools.isEmpty(d.getMatNr())
+                    || d.getAnfme() == null) {
+                String lineId = d != null ? d.getLineId() : null;
+                String matnr = d != null ? d.getMatNr() : null;
+                throw new CoolException("鏄庣粏鍙傛暟涓嶅畬鏁达細" +
+                        "orderNo=" + order.getOrderNo() +
+                        "锛宭ineId=" + lineId +
+                        "锛宮atnr=" + matnr);
+            }
+        }
+
+        if (!erpOrderService.insert(order)) {
+            throw new CoolException("璁㈠崟鎻掑叆澶辫触锛�" + order.getOrderNo());
+        }
+
+        if (order.getId() == null) {
+            throw new CoolException("璁㈠崟鎻掑叆澶辫触锛屾湭杩斿洖orderId锛�" + order.getOrderNo());
+        }
+
+        for (ErpOrderDetl detl : detls) {
+            detl.setOrderId(order.getId());
+            if (!erpOrderDetlService.insert(detl)) {
+                throw new CoolException("璁㈠崟鏄庣粏鎻掑叆澶辫触锛�" +
+                        "orderNo=" + order.getOrderNo() +
+                        "锛宭ineId=" + detl.getLineId());
+            }
+        }
+
+        String syncError = null;
+        String whId = order.getWarehouseId();
+        Integer orderType = order.getOrderType();
+
+        if (!Cools.isEmpty(whId)) {
+            if ("WH01".equals(whId)) {
+                syncError = syncOrderToWarehouse1(order, detls, orderType);
+            } else if ("WH2".equals(whId)) {
+                syncError = syncOrderToWarehouse2(order, detls, orderType);
+            } else if ("WH3".equals(whId)) {
+                syncError = syncOrderToWarehouse3(order, detls, orderType);
+            } else {
+                throw new CoolException("鏈壘鍒板搴斾粨搴撶紪鍙凤細" +
+                        "orderNo=" + order.getOrderNo() +
+                        "锛寃arehouseId=" + whId);
+            }
+        }
+
+        if (syncError != null) {
+            throw new CoolException("澶栭儴鎺ュ彛鍚屾澶辫触锛�" +
+                    "orderNo=" + order.getOrderNo() +
+                    "锛寃arehouseId=" + whId +
+                    "锛屽師鍥�=" + syncError);
+        }
+    }
     @Override
     public Map<String, Object> addErpOrder(List<OrderDto> orders) {
+
         if (Cools.isEmpty(orders)) {
             Map<String, Object> res = new HashMap<>();
             res.put("result", "FAIL");
@@ -765,84 +878,27 @@
             return res;
         }
 
-        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
-        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
-
         List<String> successOrders = new ArrayList<>();
         List<Map<String, Object>> failOrders = new ArrayList<>();
 
         for (OrderDto dto : orders) {
             String orderNo = dto != null ? dto.getOrderNo() : null;
             try {
-                transactionTemplate.execute(status -> {
-                    if (dto == null) {
-                        throw new CoolException("璁㈠崟鍙傛暟涓嶅畬鏁�");
-                    }
-                    ErpOrder order = new ErpOrder();
-                    order.setOrderNo(dto.getOrderNo());
-                    order.setOrderType(dto.getOrderType());
-                    order.setWkType(dto.getWkType());
-                    order.setBusinessTime(dto.getBusinessTime());
-                    order.setCreateTime(dto.getCreateTime());
-                    order.setWarehouseId(dto.getWareHouseId());
-                    order.setOperateType(dto.getOperateType());
-                    order.setSendStatus(dto.getSendStatus() != null ? dto.getSendStatus() : 0);
-
-                    List<ErpOrderDetl> detls = dto.getOrderItems();
-
-                    if (Cools.isEmpty(order.getOrderNo()) || order.getOrderType() == null
-                            || Cools.isEmpty(order.getWkType()) || order.getBusinessTime() == null || order.getCreateTime() == null
-                            || Cools.isEmpty(order.getWarehouseId())) {
-                        throw new CoolException("璁㈠崟鍙傛暟涓嶅畬鏁�");
-                    }
-                    if (Cools.isEmpty(detls)) {
-                        throw new CoolException("璁㈠崟鏄庣粏涓虹┖");
-                    }
-
-                    String syncError = null;
-                    String whId = order.getWarehouseId();
-                    Integer orderType = order.getOrderType();
-
-                    if (!Cools.isEmpty(whId)) {
-                        if ("WH01".equals(whId)) {
-                            syncError = syncOrderToWarehouse1(order, detls, orderType);
-                        } else if ("WH2".equals(whId)) {
-                            syncError = syncOrderToWarehouse2(order, detls, orderType);
-                        } else if ("WH3".equals(whId)) {
-                            syncError = syncOrderToWarehouse3(order, detls, orderType);
-                        } else {
-                            throw new CoolException("鏈壘鍒板搴斾粨搴撶紪鍙�");
-                        }
-                    }
-
-                    if (syncError != null) {
-                        throw new CoolException(syncError);
-                    }
-
-                    if (!erpOrderService.insert(order)) {
-                        throw new CoolException("璁㈠崟鎻掑叆澶辫触");
-                    }
-                    if (order.getId() == null) {
-                        throw new CoolException("璁㈠崟鎻掑叆澶辫触锛屾湭杩斿洖orderId");
-                    }
-
-                    for (ErpOrderDetl detl : detls) {
-                        if (detl == null || Cools.isEmpty(detl.getLineId()) || Cools.isEmpty(detl.getMatNr())
-                                || Cools.isEmpty(detl.getMakTx()) || detl.getAnfme() == null) {
-                            throw new CoolException("鏄庣粏鍙傛暟涓嶅畬鏁�");
-                        }
-                        detl.setOrderId(order.getId());
-                        if (!erpOrderDetlService.insert(detl)) {
-                            throw new CoolException("璁㈠崟鏄庣粏鎻掑叆澶辫触");
-                        }
-                    }
-                    return null;
-                });
+                processOneOrder(dto);
                 successOrders.add(orderNo);
             } catch (Exception e) {
                 Map<String, Object> fail = new HashMap<>();
+                String whId = dto != null ? dto.getWareHouseId() : null;
+                Integer orderType = dto != null ? dto.getOrderType() : null;
                 fail.put("orderNo", orderNo);
+                fail.put("warehouseId", whId);
+                fail.put("orderType", orderType);
                 fail.put("msg", e.getMessage());
+                fail.put("exception", e.getClass().getSimpleName());
+                Throwable cause = e.getCause();
+                if (cause != null && cause != e) {
+                    fail.put("cause", cause.getClass().getSimpleName() + ":" + cause.getMessage());
+                }
                 failOrders.add(fail);
             }
         }
@@ -853,6 +909,7 @@
         res.put("successCount", successOrders.size());
         res.put("failCount", failOrders.size());
         res.put("result", failOrders.isEmpty() ? "SUCCESS" : (successOrders.isEmpty() ? "FAIL" : "PART_SUCCESS"));
+
         return res;
     }
 
@@ -864,8 +921,8 @@
         List<String> whIds = new ArrayList<>();
         if (Cools.isEmpty(wareHouseId)) {
             whIds.add("WH01");
-            whIds.add("WH02");
-            whIds.add("WH03");
+//            whIds.add("WH02");
+//            whIds.add("WH03");
         } else {
             whIds.add(wareHouseId);
         }
@@ -894,8 +951,8 @@
         List<String> whIds = new ArrayList<>();
         if (Cools.isEmpty(wareHouseId)) {
             whIds.add("WH01");
-            whIds.add("WH02");
-            whIds.add("WH03");
+//            whIds.add("WH02");
+//            whIds.add("WH03");
         } else {
             whIds.add(wareHouseId);
         }
@@ -916,13 +973,79 @@
         return result;
     }
 
+    @Override
+    public Map<String, Object> orderReport(OrderReportParam param) throws IOException {
+        if (param == null) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖");
+        }
+        if (Cools.isEmpty(param.getWkType())) {
+            throw new CoolException("鍙傛暟[wkType]涓嶈兘涓虹┖");
+        }
+        if (Cools.isEmpty(param.getOrderDetls())) {
+            throw new CoolException("鍙傛暟[orderDetls]涓嶈兘涓虹┖");
+        }
+
+        String baseUrl = resolveMesWkBaseUrl(param);
+        MesWkBizType bizType = resolveMesWkBizType(param.getWkType());
+
+        String token = getMesWkToken(baseUrl);
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("Authorization", token);
+
+        String path;
+        String bizDesc;
+        Map<String, Object> payload;
+
+        if (bizType == MesWkBizType.PURCHASE_IN_STOCK) {
+            path = "/purchaseInStock/lkPurchaseInStockAdd";
+            bizDesc = "绔嬪簱閲囪喘鍏ュ簱";
+            payload = buildPurchaseInStockPayload(param.getOrderDetls());
+        } else if (bizType == MesWkBizType.PRODUCT_ISSUE) {
+            path = "/productIssue/lkProductIssueAdd";
+            bizDesc = "绔嬪簱鐢熶骇鍙戞枡";
+            payload = buildProductBizPayload(param.getOrderDetls(), "productIssueDtls", "productIssueBoms");
+        } else if (bizType == MesWkBizType.PRODUCT_FEED) {
+            path = "/productFeed/lkProductFeedAdd";
+            bizDesc = "绔嬪簱鐢熶骇琛ユ枡";
+            payload = buildProductBizPayload(param.getOrderDetls(), "productFeedDtls", "productFeedBoms");
+        } else if (bizType == MesWkBizType.PRODUCT_RETURN) {
+            path = "/productReturn/lkProductReturnAdd";
+            bizDesc = "绔嬪簱鐢熶骇閫�鏂�";
+            payload = buildProductBizPayload(param.getOrderDetls(), "productReturnDtls", "productReturnBoms");
+        } else {
+            throw new CoolException("涓嶆敮鎸佺殑wkType锛�" + param.getWkType());
+        }
+
+        try {
+            Map<String, Object> res = callMesWkApi(baseUrl, path, headers, payload, bizDesc);
+            Map<String, Object> out = new HashMap<>();
+            out.put("wkType", param.getWkType());
+            out.put("baseUrl", baseUrl);
+            out.put("path", path);
+            out.put("result", res);
+            return out;
+        } catch (MesWkAuthException e) {
+            mesWkTokenCache.remove(baseUrl);
+            String newToken = getMesWkToken(baseUrl);
+            headers.put("Authorization", newToken);
+            Map<String, Object> res = callMesWkApi(baseUrl, path, headers, payload, bizDesc);
+            Map<String, Object> out = new HashMap<>();
+            out.put("wkType", param.getWkType());
+            out.put("baseUrl", baseUrl);
+            out.put("path", path);
+            out.put("result", res);
+            out.put("tokenRefreshed", true);
+            return out;
+        }
+    }
+
     private String getWarehouseBaseUrl(String wareHouseId) {
         if (Cools.isEmpty(wareHouseId)) {
             return null;
         }
         String wh = wareHouseId.trim();
         if ("WH01".equalsIgnoreCase(wh) || "WH1".equalsIgnoreCase(wh)) {
-            return "http://localhost:8081";
+            return "http://localhost:8888";
         }
         if ("WH02".equalsIgnoreCase(wh) || "WH2".equalsIgnoreCase(wh)) {
             return "http://localhost:8080";
@@ -934,48 +1057,313 @@
     }
 
     private List<Map<String, Object>> callMesInventoryApi(String baseUrl, String path, Map<String, Object> payload) throws IOException {
-        String json = JSON.toJSONString(payload == null ? new HashMap<>() : payload);
-        Map<String, Object> headers = new HashMap<>();
-        headers.put("appkey", "ea1f0459efc02a79f046f982767939ae");
+
+        String url = baseUrl + path;
+        String requestJson = JSON.toJSONString(payload == null ? new HashMap<>() : payload);
+
+        try {
+
+            Map<String, Object> headers = new HashMap<>();
+            headers.put("appkey", "ea1f0459efc02a79f046f982767939ae");
+
+            String response = new HttpHandler.Builder()
+                    .setHeaders(headers)
+                    .setUri(baseUrl)
+                    .setPath(path)
+                    .setJson(requestJson)
+                    .build()
+                    .doPost();
+
+            // ===== 鏃犲搷搴� =====
+            if (Cools.isEmpty(response)) {
+                callApiLogSave(null, url, "鎺ュ彛鏃犲搷搴�", false);
+                throw new CoolException("鎺ュ彛鏃犲搷搴�");
+            }
+
+            JSONObject jsonResponse = JSON.parseObject(response);
+            if (jsonResponse == null) {
+                callApiLogSave(null, url, "鎺ュ彛鍝嶅簲鏍煎紡閿欒", false);
+                throw new CoolException("鎺ュ彛鍝嶅簲鏍煎紡閿欒");
+            }
+
+            Integer code = jsonResponse.getInteger("code");
+
+            if (code != null && (code == 0 || code == 200)) {
+
+                // 鉁� 鎴愬姛鏃ュ織
+                callApiDetlLogSave("搴撳瓨鏄庣粏鏌ヨ", url, requestJson, response, true);                Object data = jsonResponse.get("data");
+
+                if (data == null) {
+                    return new ArrayList<>();
+                }
+
+                if (data instanceof List) {
+                    return JSON.parseObject(JSON.toJSONString(data), List.class);
+                }
+
+                List<Map<String, Object>> list = new ArrayList<>();
+                Map<String, Object> one = JSON.parseObject(JSON.toJSONString(data), Map.class);
+                if (one != null) {
+                    list.add(one);
+                }
+                return list;
+
+            } else {
+
+                String msg = jsonResponse.getString("msg");
+                String err = !Cools.isEmpty(msg) ? msg : "鏈煡閿欒锛宑ode=" + code;
+
+                // 鉂� 澶辫触鏃ュ織
+                callApiDetlLogSave("搴撳瓨鏄庣粏鏌ヨ", url, requestJson, response, false);
+                throw new CoolException(err);
+            }
+
+        } catch (Exception e) {
+
+            log.error("callMesInventoryApi error", e);
+
+            // 鉂� 寮傚父鏃ュ織
+            callApiDetlLogSave("搴撳瓨鏄庣粏鏌ヨ", url, requestJson, e.getMessage(), false);            throw e;
+        }
+    }
+
+    private String resolveMesWkBaseUrl(OrderReportParam param) {
+        String raw = param != null ? param.getWarehouseId() : null;
+        if (!Cools.isEmpty(raw)) {
+            String v = raw.trim();
+            if (v.startsWith("http://") || v.startsWith("https://")) {
+                return v;
+            }
+            if (v.matches("^\\d{1,3}(\\.\\d{1,3}){3}(:\\d+)?$")) {
+                return "http://" + v;
+            }
+        }
+
+        String wkType = param != null ? param.getWkType() : null;
+        String norm = wkType == null ? "" : wkType.trim().toLowerCase();
+        if (norm.contains("test") || norm.contains("41") || norm.contains("娴嬭瘯")) {
+            return normalizeHttpBaseUrl(mesWkBaseUrlTest);
+        }
+        return normalizeHttpBaseUrl(mesWkBaseUrlProd);
+    }
+
+    private String normalizeHttpBaseUrl(String baseUrl) {
+        if (Cools.isEmpty(baseUrl)) {
+            return null;
+        }
+        String v = baseUrl.trim();
+        if (v.startsWith("http://") || v.startsWith("https://")) {
+            return v;
+        }
+        return "http://" + v;
+    }
+
+    private MesWkBizType resolveMesWkBizType(String wkType) {
+        String v = wkType == null ? "" : wkType.trim().toLowerCase();
+        if (v.contains("purchase") || v.contains("purch") || v.contains("cg") || v.contains("閲囪喘") || v.equals("1")) {
+            return MesWkBizType.PURCHASE_IN_STOCK;
+        }
+        if (v.contains("issue") || v.contains("fl") || v.contains("鍙戞枡") || v.equals("2")) {
+            return MesWkBizType.PRODUCT_ISSUE;
+        }
+        if (v.contains("feed") || v.contains("bl") || v.contains("琛ユ枡") || v.equals("3")) {
+            return MesWkBizType.PRODUCT_FEED;
+        }
+        if (v.contains("return") || v.contains("tl") || v.contains("閫�鏂�") || v.equals("4")) {
+            return MesWkBizType.PRODUCT_RETURN;
+        }
+        throw new CoolException("鏃犳硶璇嗗埆wkType锛�" + wkType);
+    }
+
+    private synchronized String getMesWkToken(String baseUrl) throws IOException {
+        if (Cools.isEmpty(baseUrl)) {
+            throw new CoolException("鏈嶅姟鍣ㄥ湴鍧�鏈厤缃�");
+        }
+        long now = System.currentTimeMillis();
+        MesWkTokenInfo cached = mesWkTokenCache.get(baseUrl);
+        if (cached != null && !Cools.isEmpty(cached.token) && now < cached.expireAt) {
+            return cached.token;
+        }
+
+        String path = "/acco/login";
+        Map<String, Object> payload = new HashMap<>();
+        payload.put("entCode", mesWkEntCode);
+        payload.put("username", mesWkUsername);
+        payload.put("password", mesWkPasswordMd5);
+        String requestJson = JSON.toJSONString(payload);
+        String url = baseUrl + path;
+
         String response = new HttpHandler.Builder()
-                .setHeaders(headers)
                 .setUri(baseUrl)
                 .setPath(path)
-                .setJson(json)
+                .setJson(requestJson)
                 .build()
                 .doPost();
 
         if (Cools.isEmpty(response)) {
+            callApiDetlLogSave("绔嬪簱鎺ュ彛鐧诲綍", url, requestJson, "鎺ュ彛鏃犲搷搴�", false);
+            throw new CoolException("绔嬪簱鎺ュ彛鐧诲綍鏃犲搷搴�");
+        }
+
+        JSONObject json = JSON.parseObject(response);
+        if (json == null) {
+            callApiDetlLogSave("绔嬪簱鎺ュ彛鐧诲綍", url, requestJson, response, false);
+            throw new CoolException("绔嬪簱鎺ュ彛鐧诲綍鍝嶅簲鏍煎紡閿欒");
+        }
+
+        Integer code = json.getInteger("code");
+        if (code == null || (code != 200 && code != 0)) {
+            callApiDetlLogSave("绔嬪簱鎺ュ彛鐧诲綍", url, requestJson, response, false);
+            throw new CoolException("绔嬪簱鎺ュ彛鐧诲綍澶辫触锛�" + response);
+        }
+
+        String token = json.getString("data");
+        if (Cools.isEmpty(token)) {
+            callApiDetlLogSave("绔嬪簱鎺ュ彛鐧诲綍", url, requestJson, response, false);
+            throw new CoolException("绔嬪簱鎺ュ彛鐧诲綍鏈繑鍥瀟oken");
+        }
+
+        callApiDetlLogSave("绔嬪簱鎺ュ彛鐧诲綍", url, requestJson, response, true);
+        long expireAt = now + (mesWkTokenValidMinutes == null ? 30 : mesWkTokenValidMinutes) * 60L * 1000L;
+        mesWkTokenCache.put(baseUrl, new MesWkTokenInfo(token, expireAt));
+        return token;
+    }
+
+    private Map<String, Object> callMesWkApi(String baseUrl, String path, Map<String, Object> headers, Map<String, Object> payload, String bizDesc) throws IOException {
+        String url = baseUrl + path;
+        String requestJson = JSON.toJSONString(payload == null ? new HashMap<>() : payload);
+        String response;
+        try {
+            response = new HttpHandler.Builder()
+                    .setUri(baseUrl)
+                    .setPath(path)
+                    .setHeaders(headers)
+                    .setJson(requestJson)
+                    .build()
+                    .doPost();
+        } catch (Exception e) {
+            callApiDetlLogSave(bizDesc, url, requestJson, e.getMessage(), false);
+            throw e;
+        }
+
+        if (Cools.isEmpty(response)) {
+            callApiDetlLogSave(bizDesc, url, requestJson, "鎺ュ彛鏃犲搷搴�", false);
             throw new CoolException("鎺ュ彛鏃犲搷搴�");
         }
-        JSONObject jsonResponse = JSON.parseObject(response);
-        if (jsonResponse == null) {
+
+        JSONObject json = JSON.parseObject(response);
+        if (json == null) {
+            callApiDetlLogSave(bizDesc, url, requestJson, response, false);
             throw new CoolException("鎺ュ彛鍝嶅簲鏍煎紡閿欒");
         }
-        Integer code = jsonResponse.getInteger("code");
-        if (code != null && (code == 0 || code == 200)) {
-            Object data = jsonResponse.get("data");
-            if (data == null) {
-                return new ArrayList<>();
-            }
-            if (data instanceof List) {
-                return JSON.parseObject(JSON.toJSONString(data), List.class);
-            }
-            List<Map<String, Object>> list = new ArrayList<>();
-            Map<String, Object> one = JSON.parseObject(JSON.toJSONString(data), Map.class);
-            if (one != null) {
-                list.add(one);
-            }
-            return list;
+
+        Integer code = json.getInteger("code");
+        if (code != null && (code == 200 || code == 0)) {
+            callApiDetlLogSave(bizDesc, url, requestJson, response, true);
+            return JSON.parseObject(response, Map.class);
         }
-        String msg = jsonResponse.getString("msg");
-        throw new CoolException(!Cools.isEmpty(msg) ? msg : "鏈煡閿欒锛宑ode=" + code);
+
+        String err = json.getString("error");
+        String msg = json.getString("msg");
+        String text = !Cools.isEmpty(err) ? err : (!Cools.isEmpty(msg) ? msg : "鏈煡閿欒");
+        callApiDetlLogSave(bizDesc, url, requestJson, response, false);
+        if (text.toLowerCase().contains("token") || text.toLowerCase().contains("unauthor")) {
+            throw new MesWkAuthException(text);
+        }
+        throw new CoolException(text);
+    }
+
+    private Map<String, Object> buildPurchaseInStockPayload(List<OrderDetl> orderDetls) {
+        List<Map<String, Object>> dtls = new ArrayList<>();
+        for (OrderDetl d : orderDetls) {
+            if (d == null) {
+                continue;
+            }
+            if (Cools.isEmpty(d.getBatch())) {
+                throw new CoolException("orderDetls.batch涓嶈兘涓虹┖");
+            }
+            if (d.getAnfme() == null) {
+                throw new CoolException("orderDetls.anfme涓嶈兘涓虹┖");
+            }
+            Map<String, Object> one = new HashMap<>();
+            one.put("batchNum", d.getBatch());
+            one.put("quantity", d.getAnfme());
+            dtls.add(one);
+        }
+        Map<String, Object> payload = new HashMap<>();
+        payload.put("purchaseInStockDtls", dtls);
+        return payload;
+    }
+
+    private Map<String, Object> buildProductBizPayload(List<OrderDetl> orderDetls, String dtlsKey, String bomsKey) {
+        Map<String, List<OrderDetl>> bySku = new LinkedHashMap<>();
+        for (OrderDetl d : orderDetls) {
+            if (d == null) {
+                continue;
+            }
+            if (Cools.isEmpty(d.getSku())) {
+                throw new CoolException("orderDetls.sku涓嶈兘涓虹┖");
+            }
+            bySku.computeIfAbsent(d.getSku(), k -> new ArrayList<>()).add(d);
+        }
+
+        List<Map<String, Object>> dtls = new ArrayList<>();
+        for (Map.Entry<String, List<OrderDetl>> entry : bySku.entrySet()) {
+            String sku = entry.getKey();
+            List<OrderDetl> list = entry.getValue();
+
+            List<Map<String, Object>> boms = new ArrayList<>();
+            for (OrderDetl d : list) {
+                if (Cools.isEmpty(d.getBatch())) {
+                    throw new CoolException("orderDetls.batch涓嶈兘涓虹┖");
+                }
+                if (d.getAnfme() == null) {
+                    throw new CoolException("orderDetls.anfme涓嶈兘涓虹┖");
+                }
+                Map<String, Object> bom = new HashMap<>();
+                bom.put("batchNum", d.getBatch());
+                bom.put("quantity", d.getAnfme());
+                boms.add(bom);
+            }
+
+            Map<String, Object> one = new HashMap<>();
+            one.put("planSpNo", sku);
+            one.put(bomsKey, boms);
+            dtls.add(one);
+        }
+
+        Map<String, Object> payload = new HashMap<>();
+        payload.put(dtlsKey, dtls);
+        return payload;
+    }
+
+    private enum MesWkBizType {
+        PURCHASE_IN_STOCK,
+        PRODUCT_ISSUE,
+        PRODUCT_FEED,
+        PRODUCT_RETURN
+    }
+
+    private static class MesWkTokenInfo {
+        private final String token;
+        private final long expireAt;
+
+        private MesWkTokenInfo(String token, long expireAt) {
+            this.token = token;
+            this.expireAt = expireAt;
+        }
+    }
+
+    private static class MesWkAuthException extends RuntimeException {
+        private MesWkAuthException(String message) {
+            super(message);
+        }
     }
 
     // 妯℃嫙璋冪敤浠撳簱1鎺ュ彛
     private String syncOrderToWarehouse1(ErpOrder order, List<ErpOrderDetl> details, Integer orderType) {
         log.info("Calling Warehouse 1 API for order: {}", order.getOrderNo());
-        return callOrderSyncApi(order, details, orderType, "http://localhost:8081");
+        return callOrderSyncApi(order, details, orderType, "http://localhost:8888");
     }
 
     // 妯℃嫙璋冪敤浠撳簱2鎺ュ彛
@@ -991,66 +1379,66 @@
     }
 
     private String callOrderSyncApi(ErpOrder order, List<ErpOrderDetl> details, Integer orderType, String baseUrl) {
+
+        String path = null;
+        String json = null;
+        String url = null;
+
         try {
-            // 鏍规嵁 orderType 鍒ゆ柇鎺ュ彛璺緞
-            // 鍋囪 1=鍑哄簱锛�2=鍏ュ簱锛堣鏍规嵁瀹為檯涓氬姟璋冩暣锛岃繖閲屾寜鐢ㄦ埛鎻忚堪閫昏緫瀹炵幇锛�
-            // 鐢ㄦ埛鎻忚堪锛氳嫢鏄叆搴撳崟鍒欒皟鐢╫rder/pakin/default/v1锛岃嫢鏄嚭搴搊rder/pakout/default/v1
-            // 鍋囪 orderType 2 涓哄叆搴擄紝1 鎴� 3 涓哄嚭搴擄紙闇�纭 3 璋冩嫧鍗曞睘浜庡摢绫伙紝鏆傚綊涓哄嚭搴撴垨涓嶅鐞嗭級
-            
-            String path;
-            String json;
-            
+
+            // ===== 鏋勯�犺姹� =====
             if (orderType == 2) {
-                // 鍏ュ簱鍗�
                 path = "/lfdwms/open/asrs/order/pakin/default/v1";
+
                 OpenOrderPakinParam param = new OpenOrderPakinParam();
                 param.setOrderNo(order.getOrderNo());
-                // 杩欓噷鍙兘闇�瑕佹槧灏� wkType 鍒� orderType 瀛楃涓诧紝鎴栬�呯洿鎺ョ敤
-                param.setOrderType(order.getWkType()); 
+                param.setOrderType(order.getWkType());
                 param.setOrderTime(DateUtils.convert(new Date(order.getBusinessTime())));
-                
+
                 List<DetlDto> detlDtos = new ArrayList<>();
-                if (!Cools.isEmpty(details)) {
-                    for (ErpOrderDetl d : details) {
-                        DetlDto dto = new DetlDto();
-                        dto.setMatnr(d.getMatNr());
-                        // 濡傛灉鏈� batch 瀛楁鍒欒缃紝OpenOrderPakinParam 鐨� DetlDto 鍙兘闇�瑕佺‘璁ゅ瓧娈�
-                        dto.setBatch(d.getBatch());
-                        dto.setAnfme(d.getAnfme() != null ? d.getAnfme().doubleValue() : 0.0);
-                        // 鍏朵粬瀛楁鏄犲皠...
-                        detlDtos.add(dto);
-                    }
+                for (ErpOrderDetl d : details) {
+                    DetlDto dto = new DetlDto();
+                    dto.setMatnr(d.getMatNr());
+                    dto.setBatch(d.getBatch());
+                    dto.setAnfme(d.getAnfme() != null ? d.getAnfme().doubleValue() : 0.0);
+                    detlDtos.add(dto);
                 }
                 param.setOrderDetails(detlDtos);
+
                 json = JSON.toJSONString(param);
-                
+
             } else if (orderType == 1 || orderType == 3) {
-                // 鍑哄簱鍗�
+
                 path = "/lfdwms/open/asrs/order/pakout/default/v1";
+
                 OpenOrderPakoutParam param = new OpenOrderPakoutParam();
                 param.setOrderNo(order.getOrderNo());
                 param.setOrderType(order.getWkType());
                 param.setOrderTime(DateUtils.convert(new Date(order.getBusinessTime())));
-                param.setLgort("5006"); // 蹇呭~鏍¢獙瑕佹眰
-                
+                param.setLgort("5006");
+
                 List<DetlDto> detlDtos = new ArrayList<>();
-                if (!Cools.isEmpty(details)) {
-                    for (ErpOrderDetl d : details) {
-                        DetlDto dto = new DetlDto();
-                        dto.setMatnr(d.getMatNr());
-                        dto.setBatch(d.getBatch());
-                        dto.setAnfme(d.getAnfme() != null ? d.getAnfme().doubleValue() : 0.0);
-                        detlDtos.add(dto);
-                    }
+                for (ErpOrderDetl d : details) {
+                    DetlDto dto = new DetlDto();
+                    dto.setMatnr(d.getMatNr());
+                    dto.setBatch(d.getBatch());
+                    dto.setAnfme(d.getAnfme() != null ? d.getAnfme().doubleValue() : 0.0);
+                    detlDtos.add(dto);
                 }
                 param.setOrderDetails(detlDtos);
+
                 json = JSON.toJSONString(param);
+
             } else {
                 return "鏈煡鐨勮鍗曠被鍨嬶細" + orderType;
             }
 
+            url = baseUrl + path;
+
+            // ===== 璋冩帴鍙� =====
             Map<String, Object> headers = new HashMap<>();
             headers.put("appkey", "ea1f0459efc02a79f046f982767939ae");
+
             String response = new HttpHandler.Builder()
                     .setHeaders(headers)
                     .setUri(baseUrl)
@@ -1058,25 +1446,46 @@
                     .setJson(json)
                     .build()
                     .doPost();
-            
+
+            // ===== 鍒ょ┖ =====
             if (Cools.isEmpty(response)) {
+                callOrderLogSave(order.getOrderNo(), url, json, "鎺ュ彛鏃犲搷搴�", false);
                 return "鎺ュ彛鏃犲搷搴�";
             }
-            
+
             JSONObject jsonResponse = JSON.parseObject(response);
             if (jsonResponse == null) {
+                callOrderLogSave(order.getOrderNo(), url, json, "鍝嶅簲鏍煎紡閿欒", false);
                 return "鎺ュ彛鍝嶅簲鏍煎紡閿欒";
             }
-            
+
             Integer code = jsonResponse.getInteger("code");
+
             if (code != null && (code == 0 || code == 200)) {
+
+                // 鉁� 鎴愬姛鏃ュ織
+                callOrderLogSave(order.getOrderNo(), url, json, response, true);
+
                 return null;
+
             } else {
-                return jsonResponse.getString("msg") != null ? jsonResponse.getString("msg") : "鏈煡閿欒锛宑ode=" + code;
+
+                String msg = jsonResponse.getString("msg");
+                String err = msg != null ? msg : "鏈煡閿欒 code=" + code;
+
+                // 鉂� 澶辫触鏃ュ織
+                callOrderLogSave(order.getOrderNo(), url, json, response, false);
+
+                return err;
             }
 
         } catch (Exception e) {
+
             log.error("Call order sync api error", e);
+
+            // 鉂� 寮傚父鏃ュ織
+            callOrderLogSave(order.getOrderNo(), url, json, e.getMessage(), false);
+
             return "鎺ュ彛璋冪敤寮傚父锛�" + e.getMessage();
         }
     }
@@ -1092,4 +1501,27 @@
                 bool
         );
     }
+    public void callOrderLogSave(String orderNo, String url, String request, String response, Boolean success) {
+        apiLogService.save(
+                "璁㈠崟鏂板鎺ュ彛",
+                url,
+                request,
+                null,
+                "璁㈠崟鍙凤細" + orderNo,
+                response,
+                success
+        );
+    }
+    public void callApiDetlLogSave(String bizDesc, String url, String request, String response, Boolean success) {
+        apiLogService.save(
+                bizDesc,
+                url,
+                request,
+                null,
+                null,
+                response,
+                success
+        );
+    }
+
 }

--
Gitblit v1.9.1