From 2851c8a62b0adef99af453c7c74c538e4855c87f Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Thu, 9 Oct 2025 22:51:19 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A3=85=E7=AE=B1=E6=95=B0=E6=8D=AE=E5=B7=B2?= =?UTF-8?q?=E6=8A=A5=E5=85=B3=E7=8A=B6=E6=80=81=E4=B8=80=E9=94=AE=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=88=96=E6=89=8B=E5=8A=A8=E4=BF=AE=E6=94=B9=E4=B9=9F?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=8F=91=E9=80=81=E9=82=AE=E4=BB=B6=E6=8F=90?= =?UTF-8?q?=E9=86=92=E5=8D=95=E8=AF=81=E4=BA=BA=E5=91=98=EF=BC=8C=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E5=8F=91=E9=80=81=E9=80=BB=E8=BE=91=E8=BF=98=E6=98=AF?= =?UTF-8?q?=E4=B9=8B=E5=89=8D=E7=9A=84=EF=BC=8C=E8=B0=81=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E7=9A=84=E5=8F=91=E7=BB=99=E8=B0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ecss/service/impl/CoDelServiceImpl.java | 614 ++++++++++++++++++ .../resources/mapper/ecss/CoDelMapper.xml | 5 +- 2 files changed, 618 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java index 8fa780ef..27776a06 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java @@ -2655,6 +2655,23 @@ public class CoDelServiceImpl implements CoDelService { public void saveOneClickPacking(EcssCoDelPalletHeaderData inData) { // 发货通知单 EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(inData.getSite(), inData.getDelNo()); + + // 检查发货通知单状态是否为已报关 + boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); + + // 如果状态为已报关,保存计算前的装箱数据用于对比 + List oldBoxList = new ArrayList<>(); + List oldPalletDetailList = new ArrayList<>(); + if (isCustomsCleared) { + // 获取计算前的装箱数据 + oldBoxList = coDelMapper.selectBoxList(notifyHeader); + EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData(); + queryData.setSite(inData.getSite()); + queryData.setBuNo(inData.getBuNo()); + queryData.setDelNo(inData.getDelNo()); + oldPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData); + } + // 先删除已存在的装箱数据 clearPalletData(notifyHeader); SysUserEntity currentUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); @@ -2851,6 +2868,11 @@ public class CoDelServiceImpl implements CoDelService { //notifyHeader.setModifyFlag(false); coDelMapper.updateEcssDelHeaderForModify(notifyHeader); coDelMapper.updateEcssDelDetailForModify(notifyHeader); + + // 如果状态为已报关,发送邮件通知创建人 + if (isCustomsCleared) { + sendPackingChangeNotificationEmail(notifyHeader, oldBoxList, oldPalletDetailList, inData); + } } private void clearPalletData(EcssCoDelNotifyHeaderData inData) { @@ -3101,12 +3123,46 @@ public class CoDelServiceImpl implements CoDelService { @Override @Transactional public void updateBoxInfo(Map boxData) { + // 获取发货通知单信息 + String site = boxData.get("site").toString(); + String delNo = boxData.get("delNo").toString(); + EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(site, delNo); + + // 检查发货通知单状态是否为已报关 + boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); + + // 如果状态为已报关,保存修改前的装箱数据用于对比 + List oldBoxList = new ArrayList<>(); + if (isCustomsCleared) { + oldBoxList = coDelMapper.selectBoxList(notifyHeader); + } + + // 执行修改操作 coDelMapper.updateBoxInfo(boxData); + + // 如果状态为已报关,发送邮件通知创建人 + if (isCustomsCleared) { + sendBoxChangeNotificationEmail(notifyHeader, oldBoxList, "修改", boxData); + } } @Override @Transactional public void deleteBoxInfo(Map boxData) { + // 获取发货通知单信息 + String site = boxData.get("site").toString(); + String delNo = boxData.get("delNo").toString(); + EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(site, delNo); + + // 检查发货通知单状态是否为已报关 + boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); + + // 如果状态为已报关,保存删除前的装箱数据用于对比 + List oldBoxList = new ArrayList<>(); + if (isCustomsCleared) { + oldBoxList = coDelMapper.selectBoxList(notifyHeader); + } + // 获取该箱下的全部箱明细 EcssCoDelPalletHeaderData inData = new EcssCoDelPalletHeaderData(); inData.setSite(boxData.get("site").toString()); @@ -3141,11 +3197,32 @@ public class CoDelServiceImpl implements CoDelService { boxData.get("buNo").toString(), boxData.get("delNo").toString(), Integer.parseInt(boxData.get("item_no").toString()), null); coDelMapper.deleteBoxInfo(boxData); + + // 如果状态为已报关,发送邮件通知创建人 + if (isCustomsCleared) { + sendBoxChangeNotificationEmail(notifyHeader, oldBoxList, "删除", boxData); + } } @Override @Transactional public void updateDetailInfo(EcssCoDelPalletData detailData) { + // 获取发货通知单信息 + EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(detailData.getSite(), detailData.getDelNo()); + + // 检查发货通知单状态是否为已报关 + boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); + + // 如果状态为已报关,保存修改前的装箱数据用于对比 + List oldPalletDetailList = new ArrayList<>(); + if (isCustomsCleared) { + EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData(); + queryData.setSite(detailData.getSite()); + queryData.setBuNo(detailData.getBuNo()); + queryData.setDelNo(detailData.getDelNo()); + oldPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData); + } + Integer notifyDetailItemNo = detailData.getNotifyDetailItemNo(); BigDecimal qty = detailData.getQty(); BigDecimal oldQty = detailData.getOldQty(); @@ -3170,11 +3247,32 @@ public class CoDelServiceImpl implements CoDelService { coDelMapper.updateEcssCoDelNotifyDetailSurplus(notifyDetail); } } + + // 如果状态为已报关,发送邮件通知创建人 + if (isCustomsCleared) { + sendDetailChangeNotificationEmail(notifyHeader, oldPalletDetailList, "修改", detailData); + } } @Override @Transactional public void deleteDetailInfo(EcssCoDelPalletData detailData) { + // 获取发货通知单信息 + EcssCoDelNotifyHeaderData notifyHeader = coDelMapper.getEcssCoDelNotifyHeader(detailData.getSite(), detailData.getDelNo()); + + // 检查发货通知单状态是否为已报关 + boolean isCustomsCleared = "已报关".equals(notifyHeader.getNotifyStatus()); + + // 如果状态为已报关,保存删除前的装箱数据用于对比 + List oldPalletDetailList = new ArrayList<>(); + if (isCustomsCleared) { + EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData(); + queryData.setSite(detailData.getSite()); + queryData.setBuNo(detailData.getBuNo()); + queryData.setDelNo(detailData.getDelNo()); + oldPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData); + } + // 删除明细前,先获取被删除明细的数量和notifyDetailItemNo Integer notifyDetailItemNo = detailData.getNotifyDetailItemNo(); BigDecimal deletedQty = detailData.getQty(); @@ -3205,6 +3303,11 @@ public class CoDelServiceImpl implements CoDelService { coDelMapper.updateEcssCoDelNotifyDetailSurplus(notifyDetail); } } + + // 如果状态为已报关,发送邮件通知创建人 + if (isCustomsCleared) { + sendDetailChangeNotificationEmail(notifyHeader, oldPalletDetailList, "删除", detailData); + } } @Override @@ -3337,4 +3440,515 @@ public class CoDelServiceImpl implements CoDelService { } } + /** + * 发送装箱变更通知邮件 + * + * @param notifyHeader 发货通知单头数据 + * @param oldBoxList 计算前的箱子列表 + * @param oldPalletDetailList 计算前的装箱明细列表 + * @param inData 输入参数 + * @author AI Assistant + * @date 2024-10-09 + */ + private void sendPackingChangeNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader, + List oldBoxList, + List oldPalletDetailList, + EcssCoDelPalletHeaderData inData) { + try { + log.info("开始发送装箱变更通知邮件,发货通知单号:{}", notifyHeader.getDelNo()); + + // 获取计算后的装箱数据 + List newBoxList = coDelMapper.selectBoxList(notifyHeader); + EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData(); + queryData.setSite(inData.getSite()); + queryData.setBuNo(inData.getBuNo()); + queryData.setDelNo(inData.getDelNo()); + List newPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData); + + // 生成对比邮件内容 + String emailContent = generatePackingComparisonEmailContent(notifyHeader, oldBoxList, newBoxList, + oldPalletDetailList, newPalletDetailList); + + // 获取发货通知单创建人邮箱 + String creatorEmail = coDelMapper.queryByUserName(notifyHeader.getCreateBy()).getEmail(); + if (StringUtils.isBlank(creatorEmail)) { + log.warn("发货通知单创建人{}没有配置邮箱地址", notifyHeader.getCreateBy()); + return; + } + + // 发送邮件 + String subject = String.format("发货通知单%s【发票:%s】一键装箱数据变更通知", + notifyHeader.getDelNo(), notifyHeader.getCmcInvoice()); + String[] mailAddress = {creatorEmail}; + + sendMailUtil(subject, emailContent, mailAddress, notifyHeader); + + log.info("装箱变更通知邮件发送成功,收件人:{}", creatorEmail); + + } catch (Exception e) { + log.error("发送装箱变更通知邮件失败,发货通知单号:{}, 错误信息:{}", + notifyHeader.getDelNo(), e.getMessage(), e); + // 邮件发送失败不影响主流程,只记录日志 + } + } + + /** + * 生成装箱对比邮件内容 + * + * @param notifyHeader 发货通知单头数据 + * @param oldBoxList 计算前的箱子列表 + * @param newBoxList 计算后的箱子列表 + * @param oldPalletDetailList 计算前的装箱明细列表 + * @param newPalletDetailList 计算后的装箱明细列表 + * @return HTML格式的邮件内容 + * @author AI Assistant + * @date 2024-10-09 + */ + private String generatePackingComparisonEmailContent(EcssCoDelNotifyHeaderData notifyHeader, + List oldBoxList, + List newBoxList, + List oldPalletDetailList, + List newPalletDetailList) { + StringBuilder emailContent = new StringBuilder(); + + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + + // 邮件标题 + emailContent.append("

发货通知单一键装箱数据变更通知

"); + emailContent.append("

发货通知单号:").append(notifyHeader.getDelNo()).append("

"); + emailContent.append("

发票号:").append(notifyHeader.getCmcInvoice()).append("

"); + emailContent.append("

客户:").append(notifyHeader.getCustomerName()).append("

"); + emailContent.append("

操作时间:").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("

"); + emailContent.append("

操作类型:一键装箱重新计算

"); + + // 箱子信息对比 + emailContent.append("
箱子信息对比
"); + emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList)); + + // 装箱明细对比 + emailContent.append("
装箱明细对比
"); + emailContent.append(generatePalletDetailComparisonTable(oldPalletDetailList, newPalletDetailList)); + + emailContent.append(""); + emailContent.append(""); + + return emailContent.toString(); + } + + /** + * 生成箱子列表对比表格 + * + * @param oldBoxList 计算前的箱子列表 + * @param newBoxList 计算后的箱子列表 + * @return HTML表格内容 + */ + private String generateBoxListComparisonTable(List oldBoxList, List newBoxList) { + StringBuilder table = new StringBuilder(); + + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + + // 创建映射以便对比 + Map oldBoxMap = new HashMap<>(); + for (Map box : oldBoxList) { + Integer itemNo = (Integer) box.get("item_no"); + oldBoxMap.put(itemNo, box); + } + + Map newBoxMap = new HashMap<>(); + for (Map box : newBoxList) { + Integer itemNo = (Integer) box.get("item_no"); + newBoxMap.put(itemNo, box); + } + + // 获取所有序号 + Set allItemNos = new HashSet<>(); + allItemNos.addAll(oldBoxMap.keySet()); + allItemNos.addAll(newBoxMap.keySet()); + + List sortedItemNos = new ArrayList<>(allItemNos); + sortedItemNos.sort(Integer::compareTo); + + for (Integer itemNo : sortedItemNos) { + Map oldBox = oldBoxMap.get(itemNo); + Map newBox = newBoxMap.get(itemNo); + + table.append(""); + table.append(""); + + // 毛重对比 + BigDecimal oldGrossWeight = oldBox != null ? (BigDecimal) oldBox.get("gross_weight") : BigDecimal.ZERO; + BigDecimal newGrossWeight = newBox != null ? (BigDecimal) newBox.get("gross_weight") : BigDecimal.ZERO; + table.append(""); + if (oldGrossWeight.compareTo(newGrossWeight) != 0) { + table.append(""); + } else { + table.append(""); + } + + // 净重对比 + BigDecimal oldNetWeight = oldBox != null ? (BigDecimal) oldBox.get("net_weight") : BigDecimal.ZERO; + BigDecimal newNetWeight = newBox != null ? (BigDecimal) newBox.get("net_weight") : BigDecimal.ZERO; + table.append(""); + if (oldNetWeight.compareTo(newNetWeight) != 0) { + table.append(""); + } else { + table.append(""); + } + + // 箱数对比 + BigDecimal oldBoxQty = oldBox != null ? (BigDecimal) oldBox.get("box_qty") : BigDecimal.ZERO; + BigDecimal newBoxQty = newBox != null ? (BigDecimal) newBox.get("box_qty") : BigDecimal.ZERO; + table.append(""); + if (oldBoxQty.compareTo(newBoxQty) != 0) { + table.append(""); + } else { + table.append(""); + } + + table.append(""); + } + + table.append("
序号毛重(计算前)毛重(计算后)净重(计算前)净重(计算后)箱数(计算前)箱数(计算后)
").append(itemNo).append("").append(formatDecimal(oldGrossWeight)).append("").append(formatDecimal(newGrossWeight)).append("").append(formatDecimal(newGrossWeight)).append("").append(formatDecimal(oldNetWeight)).append("").append(formatDecimal(newNetWeight)).append("").append(formatDecimal(newNetWeight)).append("").append(formatDecimal(oldBoxQty)).append("").append(formatDecimal(newBoxQty)).append("").append(formatDecimal(newBoxQty)).append("
"); + return table.toString(); + } + + /** + * 生成装箱明细对比表格 + * + * @param oldPalletDetailList 计算前的装箱明细列表 + * @param newPalletDetailList 计算后的装箱明细列表 + * @return HTML表格内容 + */ + private String generatePalletDetailComparisonTable(List oldPalletDetailList, + List newPalletDetailList) { + StringBuilder table = new StringBuilder(); + + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + table.append(""); + + // 创建映射以便对比 - 使用序号+项次作为唯一标识 + Map oldDetailMap = new HashMap<>(); + for (EcssCoDelPalletDetailData detail : oldPalletDetailList) { + String key = detail.getSeqNo() + "_" + detail.getItemNo(); + oldDetailMap.put(key, detail); + } + + Map newDetailMap = new HashMap<>(); + for (EcssCoDelPalletDetailData detail : newPalletDetailList) { + String key = detail.getSeqNo() + "_" + detail.getItemNo(); + newDetailMap.put(key, detail); + } + + // 获取所有键值 + Set allKeys = new HashSet<>(); + allKeys.addAll(oldDetailMap.keySet()); + allKeys.addAll(newDetailMap.keySet()); + + List sortedKeys = new ArrayList<>(allKeys); + sortedKeys.sort((a, b) -> { + String[] aParts = a.split("_"); + String[] bParts = b.split("_"); + int seqCompare = Integer.compare(Integer.parseInt(aParts[0]), Integer.parseInt(bParts[0])); + if (seqCompare != 0) return seqCompare; + return Integer.compare(Integer.parseInt(aParts[1]), Integer.parseInt(bParts[1])); + }); + + for (String key : sortedKeys) { + EcssCoDelPalletDetailData oldDetail = oldDetailMap.get(key); + EcssCoDelPalletDetailData newDetail = newDetailMap.get(key); + + String[] keyParts = key.split("_"); + Integer seqNo = Integer.parseInt(keyParts[0]); + Integer itemNo = Integer.parseInt(keyParts[1]); + + table.append(""); + table.append(""); + table.append(""); + + // 物料号和PN(取新数据或旧数据) + EcssCoDelPalletDetailData referenceDetail = newDetail != null ? newDetail : oldDetail; + table.append(""); + table.append(""); + + // 数量对比 + BigDecimal oldQty = oldDetail != null ? oldDetail.getQty() : BigDecimal.ZERO; + BigDecimal newQty = newDetail != null ? newDetail.getQty() : BigDecimal.ZERO; + table.append(""); + if (oldQty.compareTo(newQty) != 0) { + table.append(""); + } else { + table.append(""); + } + + // 箱数对比 + BigDecimal oldBoxQty = oldDetail != null ? oldDetail.getBoxQty() : BigDecimal.ZERO; + BigDecimal newBoxQty = newDetail != null ? newDetail.getBoxQty() : BigDecimal.ZERO; + table.append(""); + if (oldBoxQty.compareTo(newBoxQty) != 0) { + table.append(""); + } else { + table.append(""); + } + + // 卷数对比 + BigDecimal oldRolls = oldDetail != null ? oldDetail.getRolls() : BigDecimal.ZERO; + BigDecimal newRolls = newDetail != null ? newDetail.getRolls() : BigDecimal.ZERO; + table.append(""); + if (oldRolls.compareTo(newRolls) != 0) { + table.append(""); + } else { + table.append(""); + } + + table.append(""); + } + + table.append("
序号项次物料号PN数量(计算前)数量(计算后)箱数(计算前)箱数(计算后)卷数(计算前)卷数(计算后)
").append(seqNo).append("").append(itemNo).append("").append(referenceDetail.getPartNo() != null ? referenceDetail.getPartNo() : "").append("").append(referenceDetail.getPn() != null ? referenceDetail.getPn() : "").append("").append(formatDecimal(oldQty)).append("").append(formatDecimal(newQty)).append("").append(formatDecimal(newQty)).append("").append(formatDecimal(oldBoxQty)).append("").append(formatDecimal(newBoxQty)).append("").append(formatDecimal(newBoxQty)).append("").append(formatDecimal(oldRolls)).append("").append(formatDecimal(newRolls)).append("").append(formatDecimal(newRolls)).append("
"); + return table.toString(); + } + + /** + * 格式化BigDecimal数值显示 + * + * @param value 数值 + * @return 格式化后的字符串 + */ + private String formatDecimal(BigDecimal value) { + if (value == null) { + return "0"; + } + return value.stripTrailingZeros().toPlainString(); + } + + /** + * 发送箱子变更通知邮件 + * + * @param notifyHeader 发货通知单头数据 + * @param oldBoxList 操作前的箱子列表 + * @param operation 操作类型(修改/删除) + * @param boxData 操作的箱子数据 + * @author AI Assistant + * @date 2024-10-09 + */ + private void sendBoxChangeNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader, + List oldBoxList, + String operation, + Map boxData) { + try { + log.info("开始发送箱子{}通知邮件,发货通知单号:{}", operation, notifyHeader.getDelNo()); + + // 获取操作后的装箱数据 + List newBoxList = coDelMapper.selectBoxList(notifyHeader); + + // 生成对比邮件内容 + String emailContent = generateBoxChangeEmailContent(notifyHeader, oldBoxList, newBoxList, operation, boxData); + + // 获取发货通知单创建人邮箱 + String creatorEmail = coDelMapper.queryByUserName(notifyHeader.getCreateBy()).getEmail(); + if (StringUtils.isBlank(creatorEmail)) { + log.warn("发货通知单创建人{}没有配置邮箱地址", notifyHeader.getCreateBy()); + return; + } + + // 发送邮件 + String subject = String.format("发货通知单%s【发票:%s】箱子%s通知", + notifyHeader.getDelNo(), notifyHeader.getCmcInvoice(), operation); + String[] mailAddress = {creatorEmail}; + + sendMailUtil(subject, emailContent, mailAddress, notifyHeader); + + log.info("箱子{}通知邮件发送成功,收件人:{}", operation, creatorEmail); + + } catch (Exception e) { + log.error("发送箱子{}通知邮件失败,发货通知单号:{}, 错误信息:{}", + operation, notifyHeader.getDelNo(), e.getMessage(), e); + // 邮件发送失败不影响主流程,只记录日志 + } + } + + /** + * 发送箱明细变更通知邮件 + * + * @param notifyHeader 发货通知单头数据 + * @param oldPalletDetailList 操作前的装箱明细列表 + * @param operation 操作类型(修改/删除) + * @param detailData 操作的明细数据 + * @author AI Assistant + * @date 2024-10-09 + */ + private void sendDetailChangeNotificationEmail(EcssCoDelNotifyHeaderData notifyHeader, + List oldPalletDetailList, + String operation, + EcssCoDelPalletData detailData) { + try { + log.info("开始发送箱明细{}通知邮件,发货通知单号:{}", operation, notifyHeader.getDelNo()); + + // 获取操作后的装箱数据 + EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData(); + queryData.setSite(detailData.getSite()); + queryData.setBuNo(detailData.getBuNo()); + queryData.setDelNo(detailData.getDelNo()); + List newPalletDetailList = coDelMapper.searchEcssCoDelPalletDetailData(queryData); + + // 生成对比邮件内容 + String emailContent = generateDetailChangeEmailContent(notifyHeader, oldPalletDetailList, newPalletDetailList, operation, detailData); + + // 获取发货通知单创建人邮箱 + String creatorEmail = coDelMapper.queryByUserName(notifyHeader.getCreateBy()).getEmail(); + if (StringUtils.isBlank(creatorEmail)) { + log.warn("发货通知单创建人{}没有配置邮箱地址", notifyHeader.getCreateBy()); + return; + } + + // 发送邮件 + String subject = String.format("发货通知单%s【发票:%s】箱明细%s通知", + notifyHeader.getDelNo(), notifyHeader.getCmcInvoice(), operation); + String[] mailAddress = {creatorEmail}; + + sendMailUtil(subject, emailContent, mailAddress, notifyHeader); + + log.info("箱明细{}通知邮件发送成功,收件人:{}", operation, creatorEmail); + + } catch (Exception e) { + log.error("发送箱明细{}通知邮件失败,发货通知单号:{}, 错误信息:{}", + operation, notifyHeader.getDelNo(), e.getMessage(), e); + // 邮件发送失败不影响主流程,只记录日志 + } + } + + /** + * 生成箱子变更邮件内容 + * + * @param notifyHeader 发货通知单头数据 + * @param oldBoxList 操作前的箱子列表 + * @param newBoxList 操作后的箱子列表 + * @param operation 操作类型 + * @param boxData 操作的箱子数据 + * @return HTML格式的邮件内容 + */ + private String generateBoxChangeEmailContent(EcssCoDelNotifyHeaderData notifyHeader, + List oldBoxList, + List newBoxList, + String operation, + Map boxData) { + StringBuilder emailContent = new StringBuilder(); + + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + + // 邮件标题 + emailContent.append("

发货通知单箱子").append(operation).append("通知

"); + emailContent.append("

发货通知单号:").append(notifyHeader.getDelNo()).append("

"); + emailContent.append("

发票号:").append(notifyHeader.getCmcInvoice()).append("

"); + emailContent.append("

客户:").append(notifyHeader.getCustomerName()).append("

"); + emailContent.append("

操作时间:").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("

"); + emailContent.append("

操作类型:").append(operation).append("箱子(序号:").append(boxData.get("item_no")).append(")

"); + + // 箱子信息对比 + emailContent.append("
箱子信息对比
"); + emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList)); + + emailContent.append(""); + emailContent.append(""); + + return emailContent.toString(); + } + + /** + * 生成箱明细变更邮件内容 + * + * @param notifyHeader 发货通知单头数据 + * @param oldPalletDetailList 操作前的装箱明细列表 + * @param newPalletDetailList 操作后的装箱明细列表 + * @param operation 操作类型 + * @param detailData 操作的明细数据 + * @return HTML格式的邮件内容 + */ + private String generateDetailChangeEmailContent(EcssCoDelNotifyHeaderData notifyHeader, + List oldPalletDetailList, + List newPalletDetailList, + String operation, + EcssCoDelPalletData detailData) { + StringBuilder emailContent = new StringBuilder(); + + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + emailContent.append(""); + + // 邮件标题 + emailContent.append("

发货通知单箱明细").append(operation).append("通知

"); + emailContent.append("

发货通知单号:").append(notifyHeader.getDelNo()).append("

"); + emailContent.append("

发票号:").append(notifyHeader.getCmcInvoice()).append("

"); + emailContent.append("

客户:").append(notifyHeader.getCustomerName()).append("

"); + emailContent.append("

操作时间:").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("

"); + emailContent.append("

操作类型:").append(operation).append("箱明细(序号:").append(detailData.getSeqNo()).append(",项次:").append(detailData.getItemNo()).append(")

"); + + // 装箱明细对比 + emailContent.append("
装箱明细对比
"); + emailContent.append(generatePalletDetailComparisonTable(oldPalletDetailList, newPalletDetailList)); + + emailContent.append(""); + emailContent.append(""); + + return emailContent.toString(); + } + } diff --git a/src/main/resources/mapper/ecss/CoDelMapper.xml b/src/main/resources/mapper/ecss/CoDelMapper.xml index 5cda50f3..53a26a12 100644 --- a/src/main/resources/mapper/ecss/CoDelMapper.xml +++ b/src/main/resources/mapper/ecss/CoDelMapper.xml @@ -475,7 +475,10 @@ create_by,create_date,update_by,update_date