diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApproveRuleSyncMes.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApproveRuleSyncMes.java index 974bc82..1f6691f 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApproveRuleSyncMes.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApproveRuleSyncMes.java @@ -43,13 +43,14 @@ public class AfterApproveRuleSyncMes implements IRule { private static final String MES_PMO_SYNC_URL = "/GTHINKING/AjaxService/N_SCSJJSA/102525006.ashx/receive_woinfo_insert"; + private static final String PK_VIOLATION_ERROR_SUBSTRING = "违反了 PRIMARY KEY 约束“PK_WO”"; + @Override public void process(PMOAggVO[] pmoAggVOS) { if (ArrayUtil.isEmpty(pmoAggVOS)) { return; } try { - // 检查并筛选生产订单 List filteredOrders = checkAndFilterBillSrcOrg(pmoAggVOS); if (filteredOrders.isEmpty()) { obmlog.info("没有符合条件的生产订单需要同步到MES系统。"); @@ -68,17 +69,99 @@ public class AfterApproveRuleSyncMes implements IRule { } for (PMOItemVO item : bodys) { + if (item.getVparentbillid() == null || item.getVparentbillid().isBlank()) { + continue; + } syncOrderItemToMes(head, item); } } obmlog.info("生产订单同步到MES系统处理完成。"); + } catch (Exception e) { obmlog.error("同步生产订单到MES系统失败: " + e.getMessage(), e); ExceptionUtils.wrappException(e); } } + /** + * 调用MES接口并处理特定错误(如主键冲突) + * + * @param apiPath MES接口路径 + * @param requestPayload 请求体 + * @param orderNo 订单号 (用于日志) + * @param itemRow 行号 (用于日志) + * @throws BusinessException 如果发生非特定可忽略的错误 + */ + private void callMesWithCustomErrorHandling(String apiPath, JSONObject requestPayload, String orderNo, String itemRow) throws BusinessException { + String responseString = null; + try { + responseString = HTTP_POST_OTHER_SYS.callMes(apiPath, requestPayload); + obmlog.info("生产订单 " + orderNo + " 行 " + itemRow + " MES系统原始返回: " + responseString); + + if (responseString == null || responseString.trim().isEmpty()) { + obmlog.warn("生产订单 " + orderNo + " 行 " + itemRow + " MES系统返回为空。"); + // 根据业务需求,空响应可能也算一种错误 + // throw new BusinessException("MES系统返回为空。"); + return; // 或者认为空响应不是致命错误,继续执行 + } + + JSONObject jsonResponse = JSONObject.parseObject(responseString); + + // 检查是否存在 "Data" 数组 + if (jsonResponse.containsKey("Data") && jsonResponse.get("Data") instanceof JSONArray) { + JSONArray dataArray = jsonResponse.getJSONArray("Data"); + for (int i = 0; i < dataArray.size(); i++) { + JSONObject dataObject = dataArray.getJSONObject(i); + String successInData = dataObject.getString("Success"); + if ("false".equalsIgnoreCase(successInData)) { + String errorMessage = dataObject.getString("ErrorMessage"); + if (StringUtils.isEmpty(errorMessage)) { + errorMessage = dataObject.getString("Message"); + } + if (StringUtils.isEmpty(errorMessage)) { + errorMessage = "外部系统在Data数组中未提供明确错误消息,但Success为false。"; + } + + if (errorMessage.contains(PK_VIOLATION_ERROR_SUBSTRING)) { + obmlog.warn("生产订单 " + orderNo + " 行 " + itemRow + " MES返回主键冲突错误(Item " + i + "),视为可忽略: " + errorMessage); + // 特定错误,记录并继续 + } else { + throw new BusinessException("同步MES系统失败 (Item " + i + "), 错误消息:" + errorMessage); + } + } + } + } else { + // 处理顶层Success字段 + String success = jsonResponse.getString("Success"); + if ("false".equalsIgnoreCase(success)) { + String errorMessage = jsonResponse.getString("ErrorMessage"); + if (StringUtils.isEmpty(errorMessage)) { + errorMessage = jsonResponse.getString("Message"); + } + if (StringUtils.isEmpty(errorMessage)) { + errorMessage = "外部系统未提供明确错误消息,但顶层Success为false。"; + } + + if (errorMessage.contains(PK_VIOLATION_ERROR_SUBSTRING)) { + obmlog.warn("生产订单 " + orderNo + " 行 " + itemRow + " MES返回主键冲突错误,视为可忽略: " + errorMessage); + // 特定错误,记录并继续 + } else { + throw new BusinessException("同步MES系统失败, 错误消息:" + errorMessage); + } + } + } + // 如果所有检查通过或特定错误被忽略,则方法正常结束 + } catch (BusinessException e) { + // 直接抛出已捕获的业务异常 + throw e; + } catch (Exception e) { + // 捕获调用callMes或JSON解析等其他异常 + obmlog.error("生产订单 " + orderNo + " 行 " + itemRow + " 调用MES或处理响应时发生错误。原始响应: " + responseString + " 错误: " + e.getMessage(), e); + throw new BusinessException("调用MES或处理响应时发生错误:" + e.getMessage(), e); + } + } + /** * 检查并筛选需要同步的单据 */ @@ -87,6 +170,14 @@ public class AfterApproveRuleSyncMes implements IRule { for (PMOAggVO aggvo : pmoAggVOS) { String pkOrg = aggvo.getParentVO().getPk_org(); String orgCode = transferCodeByPk(FactoryVO.getDefaultTableName(), FactoryVO.CODE, FactoryVO.PK_FACTORY, pkOrg); +// // 防止mes传bip,bip再推送给mes +// String billmaker = aggvo.getParentVO().getBillmaker(); +// String userCode = transferCodeByPk("sm_user", UserVO.USER_CODE, UserVO.CUSERID, billmaker); +// +// if ("C034".equals(orgCode)&&(!"gaoning".equals(userCode))) { +// aggvoList.add(aggvo); +// } + if ("C034".equals(orgCode)) { aggvoList.add(aggvo); } @@ -236,12 +327,13 @@ public class AfterApproveRuleSyncMes implements IRule { obmlog.info("生产订单 " + vbillcode + " 行 " + itemRow + " 同步MES请求数据: " + requestPayload.toJSONString()); - // Send to MES - // Note: The actual endpoint URL might need to be configured or obtained from a central place. - HTTP_POST_OTHER_SYS.sendToExternalSystem(MES_PMO_SYNC_URL, requestPayload); - obmlog.info("生产订单 " + vbillcode + " 行 " + itemRow + " 已成功发送到MES系统。"); + // Send to MES using custom error handling + callMesWithCustomErrorHandling(MES_PMO_SYNC_URL, requestPayload, vbillcode, itemRow); + + obmlog.info("生产订单 " + vbillcode + " 行 " + itemRow + " 已成功发送到MES系统或特定错误已被记录。"); } + /** * 根据主键查询编码 */