From dfa4f366b0d8dde01222c7ca1e6b1806a74893da Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Wed, 27 May 2026 16:18:38 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E4=BA=A7=E8=BD=A6=E9=97=B4=E8=B4=9F?= =?UTF-8?q?=E8=B4=A3=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sys/modules/erf/data/ErfExpApplyData.java | 4 +- .../sys/modules/erf/entity/ErfExpApply.java | 4 +- .../service/impl/ErfExpApplyServiceImpl.java | 223 +++++++++++++----- 3 files changed, 167 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java index 5c6d2730..ca3080c5 100644 --- a/src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java +++ b/src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java @@ -221,9 +221,9 @@ public class ErfExpApplyData implements Serializable { private String pjmLeaderName; /** - * 生产车间负责人用户ID + * 生产车间负责人用户ID(支持多选,英文逗号分隔) */ - private Long workshopLeaderUserId; + private String workshopLeaderUserId; /** * 生产车间负责人姓名 diff --git a/src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java b/src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java index d65ffa0c..09ba99b7 100644 --- a/src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java +++ b/src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java @@ -106,9 +106,9 @@ public class ErfExpApply implements Serializable { private String pjmLeaderName; /** - * 生产车间负责人用户ID + * 生产车间负责人用户ID(支持多选,英文逗号分隔) */ - private Long workshopLeaderUserId; + private String workshopLeaderUserId; /** * 生产车间负责人姓名 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 85632436..71fa5d26 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 @@ -217,9 +217,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl() - .eq("user_display", data.getProjectLeader().trim()) - .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + SysUserEntity userByDisplay = getFirstUserByDisplay(data.getProjectLeader().trim()); if (userByDisplay != null) { data.setProjectLeaderId(userByDisplay.getUserId()); } @@ -1346,20 +1344,85 @@ public class ErfExpApplyServiceImpl extends ServiceImpl roles = sysUserDao.getUserRolesByRoleNames( - data.getWorkshopLeaderUserId(), List.of("生产车间负责人")); - if (roles == null || roles.isEmpty()) { - throw new XJException("生产车间负责人必须是【生产车间负责人】角色用户"); + + List workshopLeaderIds = parseUserIdCsv(data.getWorkshopLeaderUserId(), "生产车间负责人", true); + if (workshopLeaderIds.isEmpty()) { + data.setWorkshopLeaderUserId(""); + data.setWorkshopLeaderName(""); + return; } - if (StringUtils.isBlank(data.getWorkshopLeaderName())) { - String workshopDisplay = sysUserDao.getUserDisplayById(data.getWorkshopLeaderUserId()); - if (StringUtils.isNotBlank(workshopDisplay)) { - data.setWorkshopLeaderName(workshopDisplay); + + List inputNameList = parseNameCsv(data.getWorkshopLeaderName()); + List resolvedNameList = new ArrayList<>(); + + for (int i = 0; i < workshopLeaderIds.size(); i++) { + Long workshopLeaderId = workshopLeaderIds.get(i); + List roles = sysUserDao.getUserRolesByRoleNames( + workshopLeaderId, List.of("生产车间负责人")); + if (roles == null || roles.isEmpty()) { + throw new XJException("生产车间负责人必须是【生产车间负责人】角色用户"); + } + + String workshopDisplay = sysUserDao.getUserDisplayById(workshopLeaderId); + if (StringUtils.isBlank(workshopDisplay) && i < inputNameList.size()) { + workshopDisplay = inputNameList.get(i); } + if (StringUtils.isBlank(workshopDisplay)) { + workshopDisplay = String.valueOf(workshopLeaderId); + } + resolvedNameList.add(workshopDisplay); } + + data.setWorkshopLeaderUserId(workshopLeaderIds.stream() + .map(String::valueOf) + .collect(Collectors.joining(","))); + data.setWorkshopLeaderName(String.join(",", resolvedNameList)); + } + + /** + * 解析逗号分隔用户ID串 + */ + private List parseUserIdCsv(String userIdCsv, String fieldLabel, boolean strict) { + if (StringUtils.isBlank(userIdCsv)) { + return Collections.emptyList(); + } + LinkedHashSet userIdSet = new LinkedHashSet<>(); + String[] parts = userIdCsv.split(","); + for (String part : parts) { + String trimmed = part == null ? "" : part.trim(); + if (trimmed.isEmpty()) { + continue; + } + try { + userIdSet.add(Long.valueOf(trimmed)); + } catch (NumberFormatException ex) { + if (strict) { + throw new XJException(fieldLabel + "格式不正确"); + } + log.warn("{}存在无法解析的用户ID: {}", fieldLabel, trimmed); + } + } + return new ArrayList<>(userIdSet); + } + + /** + * 解析逗号分隔姓名串 + */ + private List parseNameCsv(String nameCsv) { + if (StringUtils.isBlank(nameCsv)) { + return Collections.emptyList(); + } + return Arrays.stream(nameCsv.split(",")) + .map(String::trim) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); } /** @@ -1848,9 +1911,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl workshopLeaders = resolveWorkshopLeaderEmailInfos(entity); + for (UserEmailInfoDto workshopLeader : workshopLeaders) { addRecipientRole(recipientRoleMap, workshopLeader.getUserId(), "生产车间负责人"); } @@ -2656,16 +2719,11 @@ public class ErfExpApplyServiceImpl extends ServiceImpl workshopLeaderList = resolveWorkshopLeaderEmailInfos(entity); + if (workshopLeaderList.isEmpty()) { log.info("未维护生产车间负责人或无法解析邮箱,跳过审批通过通知: applyNo={}", entity.getApplyNo()); return; } - String email = workshopLeader.getEmail(); - if (email == null || email.trim().isEmpty()) { - log.warn("生产车间负责人 {} 未配置邮箱,跳过审批通过通知", workshopLeader.getUsername()); - return; - } MailSendAddressData mailSendData = qcMapper.getSendMailFromAddress(); if (mailSendData == null) { @@ -2682,27 +2740,43 @@ public class ErfExpApplyServiceImpl extends ServiceImpl attachments = collectErfApplyMailAttachments(entity.getApplyNo()); - String body = "" - + "

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

" - + "

您好!以下工程试验单的三类经理审批已全部完成,您作为生产车间负责人请知悉并关注后续排产执行。

" - + "

当前流程已进入计划员排产环节。

" - + "
" + tableBody - + "

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

"; + List successEmailList = new ArrayList<>(); + for (UserEmailInfoDto workshopLeader : workshopLeaderList) { + String email = workshopLeader.getEmail(); + if (StringUtils.isBlank(email)) { + log.warn("生产车间负责人 {} 未配置邮箱,跳过审批通过通知", workshopLeader.getUsername()); + continue; + } - List attachments = collectErfApplyMailAttachments(entity.getApplyNo()); - MailUtil.sendMail(subject, body, new String[]{email}, mailSendData, attachments); - log.info("已向生产车间负责人 {} ({}) 发送审批通过通知,试验单: {}", - workshopLeader.getUsername(), email, entity.getApplyNo()); + String displayName = StringUtils.isNotBlank(workshopLeader.getUsername()) + ? workshopLeader.getUsername() + : String.valueOf(workshopLeader.getUserId()); - SendMailRecord mailRecord = new SendMailRecord(); - mailRecord.setType("工程试验申请生产车间负责人审批通过通知"); - mailRecord.setDocumentNo(entity.getApplyNo()); - mailRecord.setRecipient(email); - mailRecord.setSendDate(new Date()); - qcMapper.saveSendMailRecord(mailRecord); + String body = "" + + "

尊敬的 " + displayName + ":

" + + "

您好!以下工程试验单的三类经理审批已全部完成,您作为生产车间负责人请知悉并关注后续排产执行。

" + + "

当前流程已进入计划员排产环节。

" + + "
" + tableBody + + "

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

"; + + MailUtil.sendMail(subject, body, new String[]{email}, mailSendData, attachments); + successEmailList.add(email); + log.info("已向生产车间负责人 {} ({}) 发送审批通过通知,试验单: {}", + displayName, email, entity.getApplyNo()); + } + + if (!successEmailList.isEmpty()) { + SendMailRecord mailRecord = new SendMailRecord(); + mailRecord.setType("工程试验申请生产车间负责人审批通过通知"); + mailRecord.setDocumentNo(entity.getApplyNo()); + mailRecord.setRecipient(String.join(";", successEmailList)); + mailRecord.setSendDate(new Date()); + qcMapper.saveSendMailRecord(mailRecord); + } } catch (Exception e) { log.error("发送生产车间负责人审批通过邮件失败,试验单: {}, 错误: {}", entity.getApplyNo(), e.getMessage(), e); } @@ -2788,9 +2862,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl() - .eq("user_display", entity.getProjectLeader()) - .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + SysUserEntity u = getFirstUserByDisplay(entity.getProjectLeader()); if (u != null) { return sysUserDao.getUserEmailInfoById(u.getUserId()); } @@ -2813,9 +2885,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl() - .eq("user_display", entity.getPjmLeaderName()) - .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); + SysUserEntity userByDisplay = getFirstUserByDisplay(entity.getPjmLeaderName()); if (userByDisplay != null) { return sysUserDao.getUserEmailInfoById(userByDisplay.getUserId()); } @@ -2826,26 +2896,59 @@ public class ErfExpApplyServiceImpl extends ServiceImpl resolveWorkshopLeaderEmailInfos(ErfExpApply entity) { if (entity == null) { - return null; + return Collections.emptyList(); } - if (entity.getWorkshopLeaderUserId() != null) { - return sysUserDao.getUserEmailInfoById(entity.getWorkshopLeaderUserId()); + + List workshopLeaderList = new ArrayList<>(); + Set userIdSet = new LinkedHashSet<>(); + + List workshopLeaderIds = parseUserIdCsv(entity.getWorkshopLeaderUserId(), "生产车间负责人", false); + for (Long workshopLeaderId : workshopLeaderIds) { + UserEmailInfoDto workshopLeader = sysUserDao.getUserEmailInfoById(workshopLeaderId); + if (workshopLeader != null && userIdSet.add(workshopLeader.getUserId())) { + workshopLeaderList.add(workshopLeader); + } } - if (StringUtils.isNotBlank(entity.getWorkshopLeaderName())) { - SysUserEntity userByName = sysUserDao.queryByUserName(entity.getWorkshopLeaderName()); - if (userByName != null) { - return sysUserDao.getUserEmailInfoById(userByName.getUserId()); + + for (String workshopLeaderName : parseNameCsv(entity.getWorkshopLeaderName())) { + SysUserEntity userByName = sysUserDao.queryByUserName(workshopLeaderName); + if (userByName == null) { + userByName = getFirstUserByDisplay(workshopLeaderName); } - SysUserEntity userByDisplay = sysUserDao.selectOne(new QueryWrapper() - .eq("user_display", entity.getWorkshopLeaderName()) - .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); - if (userByDisplay != null) { - return sysUserDao.getUserEmailInfoById(userByDisplay.getUserId()); + if (userByName == null || !userIdSet.add(userByName.getUserId())) { + continue; + } + + UserEmailInfoDto workshopLeader = sysUserDao.getUserEmailInfoById(userByName.getUserId()); + if (workshopLeader != null) { + workshopLeaderList.add(workshopLeader); } } - return null; + + if (workshopLeaderList.isEmpty() && StringUtils.isNotBlank(entity.getWorkshopLeaderUserId())) { + log.warn("生产车间负责人字段无法解析有效用户,applyNo={}, workshopLeaderUserId={}, workshopLeaderName={}", + entity.getApplyNo(), entity.getWorkshopLeaderUserId(), entity.getWorkshopLeaderName()); + } + + return workshopLeaderList; + } + + /** + * 按显示名查询首个用户(按user_id升序),避免使用OFFSET语法 + */ + private SysUserEntity getFirstUserByDisplay(String userDisplay) { + if (StringUtils.isBlank(userDisplay)) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_display", userDisplay).orderByAsc("user_id"); + List userList = sysUserDao.selectList(queryWrapper); + if (userList == null || userList.isEmpty()) { + return null; + } + return userList.get(0); } /**