| | |
| | | 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; |
| | |
| | | // 模拟调用仓库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接口 |
| | |
| | | return "接口调用异常:" + e.getMessage(); |
| | | } |
| | | } |
| | | @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) |
| | | public void processOneOrder(OrderDto dto) { |
| | | |
| | | @Override |
| | | public Map<String, Object> addErpOrder(List<OrderDto> orders) { |
| | | if (Cools.isEmpty(orders)) { |
| | | Map<String, Object> res = new HashMap<>(); |
| | | res.put("result", "FAIL"); |
| | | res.put("successOrders", new ArrayList<>()); |
| | | res.put("failOrders", new ArrayList<>()); |
| | | res.put("successCount", 0); |
| | | res.put("failCount", 0); |
| | | 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()); |
| | |
| | | |
| | | 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())) { |
| | | || 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(); |
| | |
| | | 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) { |
| | | if (detl == null || Cools.isEmpty(detl.getLineId()) |
| | | || Cools.isEmpty(detl.getMatNr()) |
| | | || detl.getAnfme() == null) { |
| | | throw new CoolException("明细参数不完整"); |
| | | } |
| | | |
| | | detl.setOrderId(order.getId()); |
| | | |
| | | if (!erpOrderDetlService.insert(detl)) { |
| | | throw new CoolException("订单明细插入失败"); |
| | | } |
| | | } |
| | | return null; |
| | | }); |
| | | } |
| | | @Override |
| | | public Map<String, Object> addErpOrder(List<OrderDto> orders) { |
| | | |
| | | if (Cools.isEmpty(orders)) { |
| | | Map<String, Object> res = new HashMap<>(); |
| | | res.put("result", "FAIL"); |
| | | res.put("successOrders", new ArrayList<>()); |
| | | res.put("failOrders", new ArrayList<>()); |
| | | res.put("successCount", 0); |
| | | res.put("failCount", 0); |
| | | return res; |
| | | } |
| | | |
| | | List<String> successOrders = new ArrayList<>(); |
| | | List<Map<String, Object>> failOrders = new ArrayList<>(); |
| | | |
| | | for (OrderDto dto : orders) { |
| | | String orderNo = dto != null ? dto.getOrderNo() : null; |
| | | try { |
| | | // ⭐ 调用独立事务方法 |
| | | processOneOrder(dto); |
| | | successOrders.add(orderNo); |
| | | } catch (Exception e) { |
| | | Map<String, Object> fail = new HashMap<>(); |
| | |
| | | res.put("successCount", successOrders.size()); |
| | | res.put("failCount", failOrders.size()); |
| | | res.put("result", failOrders.isEmpty() ? "SUCCESS" : (successOrders.isEmpty() ? "FAIL" : "PART_SUCCESS")); |
| | | |
| | | return res; |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | } |
| | | 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"; |
| | |
| | | } |
| | | |
| | | 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); |
| | | |
| | | 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(json) |
| | | .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)) { |
| | | Object data = jsonResponse.get("data"); |
| | | |
| | | // ✅ 成功日志 |
| | | 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"); |
| | | throw new CoolException(!Cools.isEmpty(msg) ? msg : "未知错误,code=" + code); |
| | | String err = !Cools.isEmpty(msg) ? msg : "未知错误,code=" + 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; |
| | | } |
| | | } |
| | | |
| | | // 模拟调用仓库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接口 |
| | |
| | | } |
| | | |
| | | 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=入库(请根据实际业务调整,这里按用户描述逻辑实现) |
| | | // 用户描述:若是入库单则调用order/pakin/default/v1,若是出库order/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.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); |
| | | } |
| | | } |
| | | 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.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) |
| | |
| | | .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") : "未知错误,code=" + 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(); |
| | | } |
| | | } |
| | |
| | | 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 |
| | | ); |
| | | } |
| | | |
| | | } |