diff --git a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalReminderServiceImpl.java b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalReminderServiceImpl.java index 20e675d0..f111dd07 100644 --- a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalReminderServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfApprovalReminderServiceImpl.java @@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @@ -528,32 +529,38 @@ public class ErfApprovalReminderServiceImpl implements ErfApprovalReminderServic emailBody.append("

尊敬的 ").append(plannerName).append(" 计划员:

"); emailBody.append("

您好!系统检测到您有 ").append(applyList.size()).append(" 个待排产的工程实验试验单,请及时安排排产。

"); emailBody.append("
"); - emailBody.append(""); - emailBody.append(""); + emailBody.append("
"); + emailBody.append(""); emailBody.append(""); emailBody.append(""); + emailBody.append(""); emailBody.append(""); - emailBody.append(""); - emailBody.append(""); - emailBody.append(""); - emailBody.append(""); - emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); emailBody.append(""); emailBody.append(""); emailBody.append(""); int index = 1; for (ErfExpApply apply : applyList) { + String expectedFinishDateStr = apply.getExpectedFinishDate() != null + ? DateTimeFormatter.ofPattern("yyyy-MM-dd") + .format(apply.getExpectedFinishDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime()) + : ""; emailBody.append(""); emailBody.append(""); - emailBody.append(""); - emailBody.append(""); + emailBody.append(""); + emailBody.append(""); emailBody.append(""); - emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); + emailBody.append(""); emailBody.append(""); - emailBody.append(""); emailBody.append(""); } diff --git a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java index 19835266..ceb986d1 100644 --- a/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java @@ -616,6 +616,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl warehouseUsers = sysUserDao.getUserEmailListByRoleNameAndRemark("仓库", "工程实验申请"); + if (warehouseUsers == null || warehouseUsers.isEmpty()) { + log.warn("未找到仓库角色(备注=工程实验申请)的用户,跳过发送邮件"); + return; + } + + String todayStr = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()); + String expectedFinishDateStr = entity.getExpectedFinishDate() != null + ? DateTimeFormatter.ofPattern("yyyy-MM-dd") + .format(entity.getExpectedFinishDate().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime()) + : ""; + + // 构建试验单信息表格 + String mainTable = buildPlannerNotificationTable(entity, todayStr, expectedFinishDateStr); + + // 构建原材料清单表格 + List rawMaterials = erfExpRawMaterialService.getRawMaterialListByApplyNo(entity.getApplyNo()); + String rawMaterialTable = buildRawMaterialTable(rawMaterials); + + String subject = String.format("【排产通知】%s - %s", + entity.getApplyNo(), entity.getTitle() != null ? entity.getTitle() : ""); + + List successEmails = new ArrayList<>(); + + for (UserEmailInfoDto warehouseUser : warehouseUsers) { + try { + String body = "" + + "

尊敬的 " + warehouseUser.getUsername() + ":

" + + "

您好!以下工程实验试验单已完成排产,请做好相应备料准备。

" + + "
" + mainTable + + "

原材料清单:

" + rawMaterialTable + + "

发送时间:" + + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "

"; + + MailUtil.sendMail(subject, body, new String[]{warehouseUser.getEmail()}, mailSendData); + successEmails.add(warehouseUser.getEmail()); + log.info("已向仓库用户 {} ({}) 发送排产通知邮件,试验单: {}", + warehouseUser.getUsername(), warehouseUser.getEmail(), entity.getApplyNo()); + } catch (Exception e) { + log.error("向仓库用户 {} 发送邮件失败: {}", warehouseUser.getEmail(), e.getMessage()); + } + } + + if (!successEmails.isEmpty()) { + SendMailRecord mailRecord = new SendMailRecord(); + mailRecord.setType("工程实验申请排产通知"); + mailRecord.setDocumentNo(entity.getApplyNo()); + mailRecord.setRecipient(String.join(";", successEmails)); + mailRecord.setSendDate(new Date()); + qcMapper.saveSendMailRecord(mailRecord); + } + + } catch (Exception e) { + log.error("发送仓库排产通知邮件失败,试验单: {}, 错误: {}", entity.getApplyNo(), e.getMessage(), e); + } + } + + /** + * 构建原材料清单 HTML 表格 + * + * @param rawMaterials 原材料清单列表 + * @return HTML 表格字符串 + */ + private String buildRawMaterialTable(List rawMaterials) { + StringBuilder sb = new StringBuilder(); + sb.append("
序号项目号试验单号事业部试验名称实验类型创建人创建时间项目名称安排生产工序数量备注需求日期工程师
").append(index++).append("").append(apply.getApplyNo()).append("").append(apply.getBuNo() != null ? apply.getBuNo() : "").append("").append(apply.getProjectNo() != null ? apply.getProjectNo() : "").append("").append(apply.getApplyNo() != null ? apply.getApplyNo() : "").append("").append(apply.getTitle() != null ? apply.getTitle() : "").append("").append(apply.getExperimentType() != null ? apply.getExperimentType() : "").append("").append(apply.getProcessRequirement() != null ? apply.getProcessRequirement() : "").append("").append(apply.getQuantityReq() != null ? apply.getQuantityReq() : "").append("").append(apply.getRemark() != null ? apply.getRemark() : "").append("").append(expectedFinishDateStr).append("").append(apply.getCreatorName() != null ? apply.getCreatorName() : "").append("").append(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") - .format(apply.getCreateTime().toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDateTime())) - .append("
") + .append("") + .append("") + .append(""); + + if (rawMaterials == null || rawMaterials.isEmpty()) { + sb.append(""); + } else { + int index = 1; + for (ErfExpRawMaterial rm : rawMaterials) { + sb.append("") + .append("") + .append("") + .append("") + .append("") + .append("") + .append("") + .append(""); + } + } + + sb.append("
序号物料编码物料描述数量计量单位备注
暂无原材料
").append(index++).append("").append(rm.getPartNo() != null ? rm.getPartNo() : "").append("").append(rm.getPartDesc() != null ? rm.getPartDesc() : "").append("").append(rm.getQuantity() != null ? rm.getQuantity().toPlainString() : "").append("").append(rm.getUmid() != null ? rm.getUmid() : "").append("").append(rm.getRemark() != null ? rm.getRemark() : "").append("
"); + return sb.toString(); + } + private String buildPlannerNotificationTable(ErfExpApply entity, String todayStr, String expectedFinishDateStr) { return "" diff --git a/src/main/java/com/xujie/sys/modules/sys/dao/SysUserDao.java b/src/main/java/com/xujie/sys/modules/sys/dao/SysUserDao.java index af33aa6d..0b355440 100644 --- a/src/main/java/com/xujie/sys/modules/sys/dao/SysUserDao.java +++ b/src/main/java/com/xujie/sys/modules/sys/dao/SysUserDao.java @@ -55,6 +55,15 @@ public interface SysUserDao extends BaseMapper { */ List getUserEmailListByRoleName(@Param("roleName") String roleName); + /** + * 根据角色名称和角色备注查询用户邮件信息 + * + * @param roleName 角色名称 + * @param roleRemark 角色备注 + * @return 用户邮件信息列表 + */ + List getUserEmailListByRoleNameAndRemark(@Param("roleName") String roleName, @Param("roleRemark") String roleRemark); + /** * 根据用户ID查询用户邮件信息 * diff --git a/src/main/resources/mapper/sys/SysUserDao.xml b/src/main/resources/mapper/sys/SysUserDao.xml index 86c3c105..f6439462 100644 --- a/src/main/resources/mapper/sys/SysUserDao.xml +++ b/src/main/resources/mapper/sys/SysUserDao.xml @@ -88,6 +88,18 @@ AND su.email != '' + + +