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 992005ef..47cb4073 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 @@ -560,7 +560,7 @@ public class ErfApprovalReminderServiceImpl implements ErfApprovalReminderServic emailBody.append("").append(apply.getQuantityReq() != null ? apply.getQuantityReq() : "").append(""); emailBody.append("").append(apply.getRemark() != null ? apply.getRemark() : "").append(""); emailBody.append("").append(expectedFinishDateStr).append(""); - emailBody.append("").append(apply.getCreatorName() != null ? apply.getCreatorName() : "").append(""); + emailBody.append("").append(apply.getProjectLeader()!= null ? apply.getProjectLeader() : "").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 4ddc8fc1..569dddac 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 @@ -26,6 +26,7 @@ import com.xujie.sys.modules.erf.service.ErfTriConfirmService; import com.xujie.sys.modules.sys.dao.SysUserDao; import com.xujie.sys.modules.sys.dto.ManagerInfoDto; import com.xujie.sys.modules.sys.dto.UserRoleDto; +import com.xujie.sys.modules.sys.entity.SysUserEntity; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; @@ -38,6 +39,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import static com.xujie.sys.common.utils.ShiroUtils.getUserId; @@ -281,9 +284,22 @@ public class ErfExpApplyServiceImpl extends ServiceImpl plannerUserIds = extractPlannerIdsFromFlowRemark(data.getApplyNo()); + if (!plannerUserIds.isEmpty()) { + sendPlannerSubmitNotification(approvedEntity, plannerUserIds); + } else { + log.warn("流程 remark 中未解析到计划员ID,跳过计划员邮件: {}", data.getApplyNo()); + } + sendProjectLeaderApprovalPassedNotification(approvedEntity); + } + } } } else if ("驳回".equals(data.getAction())) { // 驳回:返回到指定节点或创建人 @@ -1312,6 +1328,49 @@ public class ErfExpApplyServiceImpl extends ServiceImpl extractPlannerIdsFromFlowRemark(String applyNo) { + QueryWrapper flowQuery = new QueryWrapper<>(); + flowQuery.eq("apply_no", applyNo); + ErfFlowInstance flowInstance = erfFlowInstanceMapper.selectOne(flowQuery); + if (flowInstance == null || flowInstance.getRemark() == null || flowInstance.getRemark().isEmpty()) { + return Collections.emptyList(); + } + String json = flowInstance.getRemark(); + try { + Pattern p = Pattern.compile("\"plannerIds\":\\[([0-9,]+)\\]"); + Matcher m = p.matcher(json); + if (m.find()) { + String idsStr = m.group(1); + return Arrays.stream(idsStr.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Long::valueOf) + .filter(id -> id > 0) + .collect(Collectors.toList()); + } + int idx = json.indexOf("\"plannerId\":"); + if (idx >= 0) { + String sub = json.substring(idx + 12).trim(); + int end = sub.indexOf(','); + if (end < 0) { + end = sub.indexOf('}'); + } + if (end > 0) { + long id = Long.parseLong(sub.substring(0, end).trim()); + if (id > 0) { + return Collections.singletonList(id); + } + } + } + } catch (Exception e) { + log.error("解析流程实例中的计划员ID失败 applyNo={}: {}", applyNo, e.getMessage()); + } + return Collections.emptyList(); + } + @Override public void cancelExpApply(String applyNo, Long userId) { log.info("=== 开始取消试验单 === 试验单号: {}, 操作人: {}", applyNo, userId); @@ -1531,6 +1590,86 @@ public class ErfExpApplyServiceImpl extends ServiceImpl尊敬的 " + leader.getUsername() + ":" + + "

您好!您作为试验负责人负责的工程实验试验单,经理层审批已全部通过,流程已进入计划员排产环节。

" + + "

请留意后续排产与执行安排。

" + + "
" + tableBody + + "

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

"; + + MailUtil.sendMail(subject, body, new String[]{email}, mailSendData); + log.info("已向试验负责人 {} ({}) 发送审批通过通知,试验单: {}", + leader.getUsername(), email, entity.getApplyNo()); + + SendMailRecord mailRecord = new SendMailRecord(); + mailRecord.setType("工程实验申请试验负责人审批通过通知"); + mailRecord.setDocumentNo(entity.getApplyNo()); + mailRecord.setRecipient(email); + mailRecord.setSendDate(new Date()); + qcMapper.saveSendMailRecord(mailRecord); + } catch (Exception e) { + log.error("发送试验负责人审批通过邮件失败,试验单: {}, 错误: {}", entity.getApplyNo(), e.getMessage(), e); + } + } + + /** + * 根据试验单上的试验负责人字段解析系统用户邮箱(优先用户名,其次用户显示名精确匹配) + */ + private UserEmailInfoDto resolveProjectLeaderEmailInfo(ErfExpApply entity) { + if (entity == null) { + return null; + } + if (StringUtils.isNotBlank(entity.getProjectLeaderName())) { + SysUserEntity u = sysUserDao.queryByUserName(entity.getProjectLeaderName()); + if (u != null) { + return sysUserDao.getUserEmailInfoById(u.getUserId()); + } + } + if (StringUtils.isNotBlank(entity.getProjectLeader())) { + SysUserEntity u = sysUserDao.selectOne(new QueryWrapper() + .eq("user_display", entity.getProjectLeader()) + .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + if (u != null) { + return sysUserDao.getUserEmailInfoById(u.getUserId()); + } + } + return null; + } + /** * 排产完成后向仓库角色用户发送邮件通知 * 邮件内容包含试验单信息表格和原材料清单 @@ -1653,7 +1792,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl" + (entity.getQuantityReq() != null ? entity.getQuantityReq() : "") + "" + "" + (entity.getRemark() != null ? entity.getRemark() : "") + "" + "" + expectedFinishDateStr + "" - + "" + (entity.getCreatorName() != null ? entity.getCreatorName() : "") + "" + + "" + (entity.getProjectLeader() != null ? entity.getProjectLeader() : "") + "" + ""; }