diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/TencentDocController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/TencentDocController.java index dad5d11..5ef560e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/TencentDocController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/TencentDocController.java @@ -498,8 +498,8 @@ public class TencentDocController extends BaseController { return AjaxResult.error("物流链接不能为空"); } - // 2. 检查订单是否已推送(防止重复推送);单号与客户/第三方单号任一完全匹配 - JDOrder order = jdOrderService.selectJDOrderByOrderIdOrThirdPartyOrderNo(thirdPartyOrderNo); + // 2. 检查订单是否已推送(防止重复推送) + JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(thirdPartyOrderNo); if (order == null) { logOperation(null, null, null, "WRITE_SINGLE", thirdPartyOrderNo, null, logisticsLink, "FAILED", "订单不存在"); @@ -599,7 +599,8 @@ public class TencentDocController extends BaseController { if (cell.containsKey("cellValue")) { String cellText = cell.getJSONObject("cellValue").getString("text"); if (cellText != null) { - if (cellText.contains("单号")) { + // 「物流单号」也含「单号」,须排除,否则会误把物流列当成单号列 + if (cellText.contains("单号") && !cellText.contains("物流")) { orderNoColumn = i; } else if (cellText.contains("物流")) { logisticsColumn = i; @@ -611,7 +612,7 @@ public class TencentDocController extends BaseController { if (orderNoColumn == -1 || logisticsColumn == -1) { logOperation(null, fileId, sheetId, "WRITE_SINGLE", thirdPartyOrderNo, null, logisticsLink, "FAILED", "未找到'单号'或'物流'列"); - return AjaxResult.error("未找到'单号'或'物流'列,请检查表头配置"); + return AjaxResult.error("未找到「单号/客户单号/第三方单号」或「物流」列,请检查表头配置"); } log.info("表头解析完成 - 单号列: {}, 物流列: {}", orderNoColumn, logisticsColumn); @@ -645,7 +646,7 @@ public class TencentDocController extends BaseController { JSONObject orderNoCell = cells.getJSONObject(orderNoColumn); if (orderNoCell.containsKey("cellValue")) { String cellText = orderNoCell.getJSONObject("cellValue").getString("text"); - if (tencentSheetOrderNoMatches(order, thirdPartyOrderNo, cellText)) { + if (thirdPartyOrderNo.equals(cellText)) { targetRow = configStartRow + i; break; } @@ -696,9 +697,9 @@ public class TencentDocController extends BaseController { verifyOrderNo = verifyOrderNoCell.getJSONObject("cellValue").getString("text"); } - if (!tencentSheetOrderNoMatches(order, thirdPartyOrderNo, verifyOrderNo)) { + if (!thirdPartyOrderNo.equals(verifyOrderNo)) { logOperation(null, fileId, sheetId, "WRITE_SINGLE", thirdPartyOrderNo, targetRow, logisticsLink, - "SKIPPED", String.format("验证失败:单号不匹配,期望(单号/客户单号其一) %s,实际 %s", thirdPartyOrderNo, verifyOrderNo)); + "SKIPPED", String.format("验证失败:单号不匹配,期望 %s,实际 %s", thirdPartyOrderNo, verifyOrderNo)); return AjaxResult.error("验证失败:单号不匹配,行数据已变化"); } @@ -899,29 +900,6 @@ public class TencentDocController extends BaseController { return null; } - /** - * 腾讯文档「单号」列单元格是否与本地订单对应:与请求键、订单号、客户/第三方单号任一完全相同(去首尾空白) - */ - private static boolean tencentSheetOrderNoMatches(JDOrder order, String requestKey, String cellText) { - if (cellText == null) { - return false; - } - String c = cellText.trim(); - if (c.isEmpty()) { - return false; - } - if (requestKey != null && c.equals(requestKey.trim())) { - return true; - } - if (order == null) { - return false; - } - if (order.getOrderId() != null && c.equals(order.getOrderId().trim())) { - return true; - } - return order.getThirdPartyOrderNo() != null && c.equals(order.getThirdPartyOrderNo().trim()); - } - /** * 批量同步中出现报错时,将摘要推送到企业微信(wxSend 闲鱼应用通道) */ @@ -1133,7 +1111,7 @@ public class TencentDocController extends BaseController { return AjaxResult.error("无法识别表头,表头数据为空"); } - // 列名须与表格完全一致(仅忽略首尾空白、不间断空格等):备注、是否安排、物流单号、下单电话、标记、京东下单订单号;另需「单号」或「第三方单号」 + // 列名须与表格完全一致(仅忽略首尾空白、不间断空格等):备注、是否安排、物流单号、下单电话、标记、京东下单订单号;另需「单号」「客户单号」或「第三方单号」之一 log.info("开始识别表头列(完全匹配列名),共 {} 列", headerRowData.size()); for (int i = 0; i < headerRowData.size(); i++) { String cellValue = headerRowData.getString(i); @@ -1151,6 +1129,10 @@ public class TencentDocController extends BaseController { orderNoColumn = i; log.info("✓ 列名完全匹配「单号」:第 {} 列(索引{})", i + 1, i); } + if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "客户单号")) { + orderNoColumn = i; + log.info("\u2713 列名完全匹配「客户单号」:第 {} 列(索引{})", i + 1, i); + } if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "第三方单号")) { orderNoColumn = i; log.info("✓ 列名完全匹配「第三方单号」:第 {} 列(索引{})", i + 1, i); @@ -1184,7 +1166,7 @@ public class TencentDocController extends BaseController { // 检查必需的列是否都已识别 if (orderNoColumn == null) { - return AjaxResult.error("无法找到列名完全为「单号」或「第三方单号」的列(请与表格列名一致,勿加空格或后缀)"); + return AjaxResult.error("无法找到列名完全为「单号」「客户单号」或「第三方单号」的列(请与表格列名一致,勿加空格或后缀)"); } if (logisticsLinkColumn == null) { return AjaxResult.error("无法找到列名完全为「物流单号」的列(兼容「物流链接」);请与表格列名一致"); @@ -1380,7 +1362,7 @@ public class TencentDocController extends BaseController { if (!trimmedExistingLink.isEmpty()) { // 文档中已有物流链接,需要比对数据库中的物流链接 try { - JDOrder existingOrder = jdOrderService.selectJDOrderByOrderIdOrThirdPartyOrderNo(orderNo); + JDOrder existingOrder = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo); if (existingOrder != null) { String dbLogisticsLink = existingOrder.getLogisticsLink(); String trimmedDbLink = (dbLogisticsLink != null) ? dbLogisticsLink.trim() : ""; @@ -1477,8 +1459,8 @@ public class TencentDocController extends BaseController { } try { - // 表格单号列与本地订单号或客户/第三方单号完全匹配 - JDOrder order = jdOrderService.selectJDOrderByOrderIdOrThirdPartyOrderNo(orderNo); + // 根据第三方单号查询订单(与文档「单号/客户单号/第三方单号」列单元格一致) + JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo); if (order == null) { // 订单不存在,跳过但不统计为错误 @@ -1861,7 +1843,7 @@ public class TencentDocController extends BaseController { // 更新订单的推送状态(重新查询订单,避免使用旧对象) JDOrder orderToUpdate = null; try { - orderToUpdate = jdOrderService.selectJDOrderByOrderIdOrThirdPartyOrderNo(expectedOrderNo); + orderToUpdate = jdOrderService.selectJDOrderByThirdPartyOrderNo(expectedOrderNo); if (orderToUpdate != null) { orderToUpdate.setTencentDocPushed(1); orderToUpdate.setTencentDocPushTime(new java.util.Date()); @@ -2334,6 +2316,10 @@ public class TencentDocController extends BaseController { orderNoColumn = i; log.info("✓ 列名完全匹配「单号」:第 {} 列(索引{})", i + 1, i); } + if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "客户单号")) { + orderNoColumn = i; + log.info("\u2713 列名完全匹配「客户单号」:第 {} 列(索引{})", i + 1, i); + } if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "第三方单号")) { orderNoColumn = i; log.info("✓ 列名完全匹配「第三方单号」:第 {} 列(索引{})", i + 1, i); @@ -2349,7 +2335,7 @@ public class TencentDocController extends BaseController { } if (orderNoColumn == null || logisticsLinkColumn == null) { - return AjaxResult.error("无法识别表头列,请确保存在列名完全为「单号」或「第三方单号」,以及「物流单号」(或「物流链接」)"); + return AjaxResult.error("无法识别表头列,请确保存在列名完全为「单号」「客户单号」或「第三方单号」,以及「物流单号」(或「物流链接」)"); } // 统计结果 @@ -2638,6 +2624,10 @@ public class TencentDocController extends BaseController { orderNoColumn = i; log.info("✓ 列名完全匹配「单号」:第 {} 列(索引{})", i + 1, i); } + if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "客户单号")) { + orderNoColumn = i; + log.info("\u2713 列名完全匹配「客户单号」:第 {} 列(索引{})", i + 1, i); + } if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellValue, "第三方单号")) { orderNoColumn = i; log.info("✓ 列名完全匹配「第三方单号」:第 {} 列(索引{})", i + 1, i); @@ -2653,7 +2643,7 @@ public class TencentDocController extends BaseController { } if (orderNoColumn == null || logisticsLinkColumn == null) { - return AjaxResult.error("无法识别表头列,请确保存在列名完全为「单号」或「第三方单号」,以及「物流单号」(或「物流链接」)"); + return AjaxResult.error("无法识别表头列,请确保存在列名完全为「单号」「客户单号」或「第三方单号」,以及「物流单号」(或「物流链接」)"); } // 统计结果 @@ -2745,8 +2735,8 @@ public class TencentDocController extends BaseController { String cleanedLogisticsLink = cleanLogisticsLink(logisticsLinkFromDoc); try { - // 表格单号与订单号或客户/第三方单号完全匹配;否则再按内部单号(remark) - JDOrder order = jdOrderService.selectJDOrderByOrderIdOrThirdPartyOrderNo(orderNoFromDoc.trim()); + // 通过第三方单号查找本地订单;找不到再按内部单号(remark) + JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNoFromDoc.trim()); if (order == null) { order = jdOrderService.selectJDOrderByRemark(orderNoFromDoc.trim()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java index 45534ad..90d3ab0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java @@ -46,11 +46,6 @@ public interface JDOrderMapper { */ JDOrder selectJDOrderByThirdPartyOrderNo(String thirdPartyOrderNo); - /** - * 腾讯文档「单号」列:与订单号(order_id)或客户/第三方单号(third_party_order_no)任一完全相等则命中 - */ - JDOrder selectJDOrderByOrderIdOrThirdPartyOrderNo(String orderKey); - /** * 后返备注 JSON 中含指定 uploadRecordId 的订单主键(撤销导入时用) */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IJDOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IJDOrderService.java index 1657d75..030edc1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IJDOrderService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IJDOrderService.java @@ -43,11 +43,6 @@ public interface IJDOrderService { /** 根据第三方单号查询订单 */ JDOrder selectJDOrderByThirdPartyOrderNo(String thirdPartyOrderNo); - /** - * 按订单号或客户/第三方单号(与表 jd_order.order_id、third_party_order_no 完全匹配) - */ - JDOrder selectJDOrderByOrderIdOrThirdPartyOrderNo(String orderKey); - /** 批量删除(根据主键ID) */ int deleteJDOrderByIds(Long[] ids); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/JDOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/JDOrderServiceImpl.java index 23b9cbd..1f9756b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/JDOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/JDOrderServiceImpl.java @@ -69,14 +69,6 @@ public class JDOrderServiceImpl implements IJDOrderService { return jdOrderMapper.selectJDOrderByThirdPartyOrderNo(thirdPartyOrderNo); } - @Override - public JDOrder selectJDOrderByOrderIdOrThirdPartyOrderNo(String orderKey) { - if (orderKey == null || orderKey.trim().isEmpty()) { - return null; - } - return jdOrderMapper.selectJDOrderByOrderIdOrThirdPartyOrderNo(orderKey.trim()); - } - @Override public int deleteJDOrderByIds(Long[] ids) { if (ids == null || ids.length == 0) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java index d098886..8daf178 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java @@ -229,6 +229,8 @@ public class TencentDocServiceImpl implements ITencentDocService { companyColumn = i; } else if (TencentDocDataParser.headerEquals(cellText, "单号")) { orderNoColumn = i; + } else if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellText, "客户单号")) { + orderNoColumn = i; } else if (orderNoColumn == null && TencentDocDataParser.headerEquals(cellText, "第三方单号")) { orderNoColumn = i; } else if (cellText.contains("型号")) { @@ -255,7 +257,7 @@ public class TencentDocServiceImpl implements ITencentDocService { } if (orderNoColumn == null) { - throw new RuntimeException("未找到'单号'列,请检查表头配置"); + throw new RuntimeException("未找到「单号」「客户单号」或「第三方单号」列,请检查表头配置"); } log.info("表头识别完成 - 单号列: {}, 京东下单订单号列: {}, 物流列: {}", orderNoColumn, jdPlaceOrderNoColumn, logisticsColumn); diff --git a/ruoyi-system/src/main/resources/mapper/jarvis/JDOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/jarvis/JDOrderMapper.xml index 2266088..ded282a 100644 --- a/ruoyi-system/src/main/resources/mapper/jarvis/JDOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/jarvis/JDOrderMapper.xml @@ -262,13 +262,6 @@ limit 1 - -