Browse Source

装箱数据已报关状态一键计算或手动修改也需要发送邮件提醒单证人员,邮件发送逻辑还是之前的,谁导入的发给谁

java8
han\hanst 3 months ago
parent
commit
2851c8a62b
  1. 614
      src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelServiceImpl.java
  2. 5
      src/main/resources/mapper/ecss/CoDelMapper.xml

614
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<Map> oldBoxList = new ArrayList<>();
List<EcssCoDelPalletDetailData> 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<String, Object> 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<Map> oldBoxList = new ArrayList<>();
if (isCustomsCleared) {
oldBoxList = coDelMapper.selectBoxList(notifyHeader);
}
// 执行修改操作
coDelMapper.updateBoxInfo(boxData);
// 如果状态为已报关发送邮件通知创建人
if (isCustomsCleared) {
sendBoxChangeNotificationEmail(notifyHeader, oldBoxList, "修改", boxData);
}
}
@Override
@Transactional
public void deleteBoxInfo(Map<String, Object> 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<Map> 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<EcssCoDelPalletDetailData> 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<EcssCoDelPalletDetailData> 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<Map> oldBoxList,
List<EcssCoDelPalletDetailData> oldPalletDetailList,
EcssCoDelPalletHeaderData inData) {
try {
log.info("开始发送装箱变更通知邮件,发货通知单号:{}", notifyHeader.getDelNo());
// 获取计算后的装箱数据
List<Map> newBoxList = coDelMapper.selectBoxList(notifyHeader);
EcssCoDelPalletHeaderData queryData = new EcssCoDelPalletHeaderData();
queryData.setSite(inData.getSite());
queryData.setBuNo(inData.getBuNo());
queryData.setDelNo(inData.getDelNo());
List<EcssCoDelPalletDetailData> 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<Map> oldBoxList,
List<Map> newBoxList,
List<EcssCoDelPalletDetailData> oldPalletDetailList,
List<EcssCoDelPalletDetailData> newPalletDetailList) {
StringBuilder emailContent = new StringBuilder();
emailContent.append("<!DOCTYPE html>");
emailContent.append("<html>");
emailContent.append("<head>");
emailContent.append("<meta charset='UTF-8'>");
emailContent.append("<style>");
emailContent.append("body { font-family: Arial, sans-serif; margin: 20px; }");
emailContent.append("table { border-collapse: collapse; width: 100%; margin: 10px 0; }");
emailContent.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }");
emailContent.append("th { background-color: #f2f2f2; font-weight: bold; }");
emailContent.append(".changed { color: red; font-weight: bold; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单一键装箱数据变更通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='changed'>一键装箱重新计算</span></p>");
// 箱子信息对比
emailContent.append("<div class='section-title'>箱子信息对比</div>");
emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList));
// 装箱明细对比
emailContent.append("<div class='section-title'>装箱明细对比</div>");
emailContent.append(generatePalletDetailComparisonTable(oldPalletDetailList, newPalletDetailList));
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
/**
* 生成箱子列表对比表格
*
* @param oldBoxList 计算前的箱子列表
* @param newBoxList 计算后的箱子列表
* @return HTML表格内容
*/
private String generateBoxListComparisonTable(List<Map> oldBoxList, List<Map> newBoxList) {
StringBuilder table = new StringBuilder();
table.append("<table>");
table.append("<tr>");
table.append("<th>序号</th>");
table.append("<th>毛重(计算前)</th>");
table.append("<th>毛重(计算后)</th>");
table.append("<th>净重(计算前)</th>");
table.append("<th>净重(计算后)</th>");
table.append("<th>箱数(计算前)</th>");
table.append("<th>箱数(计算后)</th>");
table.append("</tr>");
// 创建映射以便对比
Map<Integer, Map> oldBoxMap = new HashMap<>();
for (Map box : oldBoxList) {
Integer itemNo = (Integer) box.get("item_no");
oldBoxMap.put(itemNo, box);
}
Map<Integer, Map> newBoxMap = new HashMap<>();
for (Map box : newBoxList) {
Integer itemNo = (Integer) box.get("item_no");
newBoxMap.put(itemNo, box);
}
// 获取所有序号
Set<Integer> allItemNos = new HashSet<>();
allItemNos.addAll(oldBoxMap.keySet());
allItemNos.addAll(newBoxMap.keySet());
List<Integer> sortedItemNos = new ArrayList<>(allItemNos);
sortedItemNos.sort(Integer::compareTo);
for (Integer itemNo : sortedItemNos) {
Map oldBox = oldBoxMap.get(itemNo);
Map newBox = newBoxMap.get(itemNo);
table.append("<tr>");
table.append("<td>").append(itemNo).append("</td>");
// 毛重对比
BigDecimal oldGrossWeight = oldBox != null ? (BigDecimal) oldBox.get("gross_weight") : BigDecimal.ZERO;
BigDecimal newGrossWeight = newBox != null ? (BigDecimal) newBox.get("gross_weight") : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldGrossWeight)).append("</td>");
if (oldGrossWeight.compareTo(newGrossWeight) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newGrossWeight)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newGrossWeight)).append("</td>");
}
// 净重对比
BigDecimal oldNetWeight = oldBox != null ? (BigDecimal) oldBox.get("net_weight") : BigDecimal.ZERO;
BigDecimal newNetWeight = newBox != null ? (BigDecimal) newBox.get("net_weight") : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldNetWeight)).append("</td>");
if (oldNetWeight.compareTo(newNetWeight) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newNetWeight)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newNetWeight)).append("</td>");
}
// 箱数对比
BigDecimal oldBoxQty = oldBox != null ? (BigDecimal) oldBox.get("box_qty") : BigDecimal.ZERO;
BigDecimal newBoxQty = newBox != null ? (BigDecimal) newBox.get("box_qty") : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldBoxQty)).append("</td>");
if (oldBoxQty.compareTo(newBoxQty) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newBoxQty)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newBoxQty)).append("</td>");
}
table.append("</tr>");
}
table.append("</table>");
return table.toString();
}
/**
* 生成装箱明细对比表格
*
* @param oldPalletDetailList 计算前的装箱明细列表
* @param newPalletDetailList 计算后的装箱明细列表
* @return HTML表格内容
*/
private String generatePalletDetailComparisonTable(List<EcssCoDelPalletDetailData> oldPalletDetailList,
List<EcssCoDelPalletDetailData> newPalletDetailList) {
StringBuilder table = new StringBuilder();
table.append("<table>");
table.append("<tr>");
table.append("<th>序号</th>");
table.append("<th>项次</th>");
table.append("<th>物料号</th>");
table.append("<th>PN</th>");
table.append("<th>数量(计算前)</th>");
table.append("<th>数量(计算后)</th>");
table.append("<th>箱数(计算前)</th>");
table.append("<th>箱数(计算后)</th>");
table.append("<th>卷数(计算前)</th>");
table.append("<th>卷数(计算后)</th>");
table.append("</tr>");
// 创建映射以便对比 - 使用序号+项次作为唯一标识
Map<String, EcssCoDelPalletDetailData> oldDetailMap = new HashMap<>();
for (EcssCoDelPalletDetailData detail : oldPalletDetailList) {
String key = detail.getSeqNo() + "_" + detail.getItemNo();
oldDetailMap.put(key, detail);
}
Map<String, EcssCoDelPalletDetailData> newDetailMap = new HashMap<>();
for (EcssCoDelPalletDetailData detail : newPalletDetailList) {
String key = detail.getSeqNo() + "_" + detail.getItemNo();
newDetailMap.put(key, detail);
}
// 获取所有键值
Set<String> allKeys = new HashSet<>();
allKeys.addAll(oldDetailMap.keySet());
allKeys.addAll(newDetailMap.keySet());
List<String> 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("<tr>");
table.append("<td>").append(seqNo).append("</td>");
table.append("<td>").append(itemNo).append("</td>");
// 物料号和PN取新数据或旧数据
EcssCoDelPalletDetailData referenceDetail = newDetail != null ? newDetail : oldDetail;
table.append("<td>").append(referenceDetail.getPartNo() != null ? referenceDetail.getPartNo() : "").append("</td>");
table.append("<td>").append(referenceDetail.getPn() != null ? referenceDetail.getPn() : "").append("</td>");
// 数量对比
BigDecimal oldQty = oldDetail != null ? oldDetail.getQty() : BigDecimal.ZERO;
BigDecimal newQty = newDetail != null ? newDetail.getQty() : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldQty)).append("</td>");
if (oldQty.compareTo(newQty) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newQty)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newQty)).append("</td>");
}
// 箱数对比
BigDecimal oldBoxQty = oldDetail != null ? oldDetail.getBoxQty() : BigDecimal.ZERO;
BigDecimal newBoxQty = newDetail != null ? newDetail.getBoxQty() : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldBoxQty)).append("</td>");
if (oldBoxQty.compareTo(newBoxQty) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newBoxQty)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newBoxQty)).append("</td>");
}
// 卷数对比
BigDecimal oldRolls = oldDetail != null ? oldDetail.getRolls() : BigDecimal.ZERO;
BigDecimal newRolls = newDetail != null ? newDetail.getRolls() : BigDecimal.ZERO;
table.append("<td>").append(formatDecimal(oldRolls)).append("</td>");
if (oldRolls.compareTo(newRolls) != 0) {
table.append("<td class='changed'>").append(formatDecimal(newRolls)).append("</td>");
} else {
table.append("<td>").append(formatDecimal(newRolls)).append("</td>");
}
table.append("</tr>");
}
table.append("</table>");
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<Map> oldBoxList,
String operation,
Map<String, Object> boxData) {
try {
log.info("开始发送箱子{}通知邮件,发货通知单号:{}", operation, notifyHeader.getDelNo());
// 获取操作后的装箱数据
List<Map> 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<EcssCoDelPalletDetailData> 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<EcssCoDelPalletDetailData> 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<Map> oldBoxList,
List<Map> newBoxList,
String operation,
Map<String, Object> boxData) {
StringBuilder emailContent = new StringBuilder();
emailContent.append("<!DOCTYPE html>");
emailContent.append("<html>");
emailContent.append("<head>");
emailContent.append("<meta charset='UTF-8'>");
emailContent.append("<style>");
emailContent.append("body { font-family: Arial, sans-serif; margin: 20px; }");
emailContent.append("table { border-collapse: collapse; width: 100%; margin: 10px 0; }");
emailContent.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }");
emailContent.append("th { background-color: #f2f2f2; font-weight: bold; }");
emailContent.append(".changed { color: red; font-weight: bold; }");
emailContent.append(".deleted { color: red; text-decoration: line-through; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单箱子").append(operation).append("通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='changed'>").append(operation).append("箱子(序号:").append(boxData.get("item_no")).append(")</span></p>");
// 箱子信息对比
emailContent.append("<div class='section-title'>箱子信息对比</div>");
emailContent.append(generateBoxListComparisonTable(oldBoxList, newBoxList));
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
/**
* 生成箱明细变更邮件内容
*
* @param notifyHeader 发货通知单头数据
* @param oldPalletDetailList 操作前的装箱明细列表
* @param newPalletDetailList 操作后的装箱明细列表
* @param operation 操作类型
* @param detailData 操作的明细数据
* @return HTML格式的邮件内容
*/
private String generateDetailChangeEmailContent(EcssCoDelNotifyHeaderData notifyHeader,
List<EcssCoDelPalletDetailData> oldPalletDetailList,
List<EcssCoDelPalletDetailData> newPalletDetailList,
String operation,
EcssCoDelPalletData detailData) {
StringBuilder emailContent = new StringBuilder();
emailContent.append("<!DOCTYPE html>");
emailContent.append("<html>");
emailContent.append("<head>");
emailContent.append("<meta charset='UTF-8'>");
emailContent.append("<style>");
emailContent.append("body { font-family: Arial, sans-serif; margin: 20px; }");
emailContent.append("table { border-collapse: collapse; width: 100%; margin: 10px 0; }");
emailContent.append("th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }");
emailContent.append("th { background-color: #f2f2f2; font-weight: bold; }");
emailContent.append(".changed { color: red; font-weight: bold; }");
emailContent.append(".deleted { color: red; text-decoration: line-through; }");
emailContent.append(".section-title { color: #333; font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }");
emailContent.append("</style>");
emailContent.append("</head>");
emailContent.append("<body>");
// 邮件标题
emailContent.append("<h2>发货通知单箱明细").append(operation).append("通知</h2>");
emailContent.append("<p><strong>发货通知单号:</strong>").append(notifyHeader.getDelNo()).append("</p>");
emailContent.append("<p><strong>发票号:</strong>").append(notifyHeader.getCmcInvoice()).append("</p>");
emailContent.append("<p><strong>客户:</strong>").append(notifyHeader.getCustomerName()).append("</p>");
emailContent.append("<p><strong>操作时间:</strong>").append(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
emailContent.append("<p><strong>操作类型:</strong><span class='changed'>").append(operation).append("箱明细(序号:").append(detailData.getSeqNo()).append(",项次:").append(detailData.getItemNo()).append(")</span></p>");
// 装箱明细对比
emailContent.append("<div class='section-title'>装箱明细对比</div>");
emailContent.append(generatePalletDetailComparisonTable(oldPalletDetailList, newPalletDetailList));
emailContent.append("</body>");
emailContent.append("</html>");
return emailContent.toString();
}
}

5
src/main/resources/mapper/ecss/CoDelMapper.xml

@ -475,7 +475,10 @@ create_by,create_date,update_by,update_date
<select id="searchEcssCoDelPalletDetailData" resultType="EcssCoDelPalletDetailData">
select site,bu_no,delNo,seq_no,item_no,part_no,qty,po_no,box_qty,create_by,create_date,update_by,update_date,rolls,pn,notify_detail_item_no as notifyDetailItemNo
from ecss_CoDelPalletDetail
where site =#{site} and bu_no=#{buNo} and delNo=#{delNo} and seq_no=#{seqNo}
where site =#{site} and bu_no=#{buNo} and delNo=#{delNo}
<if test="seqNo != null and seqNo != ''">
and seq_no=#{seqNo}
</if>
</select>
<select id="getCoDelPalletHeaderSeqNo" resultType="int">

Loading…
Cancel
Save