|
|
|
@ -64,6 +64,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
private static final String APPROVAL_PAGE_URL = "http://172.26.68.20:9001/#/erf-expApplyApproval"; |
|
|
|
private static final String PLANNER_PAGE_URL = "http://172.26.68.20:9001/#/erf-plannerSchedule"; |
|
|
|
private static final String TRI_CONFIRM_PAGE_URL = "http://172.26.68.20:9001/#/erf-triConfirm"; |
|
|
|
private static final String ROLE_PJM_LEADER = "产品文档收集 - PjM"; |
|
|
|
private static final String ROLE_WORKSHOP_LEADER = "生产车间负责人"; |
|
|
|
private static final String ROLE_QC_WORKSHOP_LEADER = "QC车间负责人"; |
|
|
|
private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); |
|
|
|
|
|
|
|
@Autowired |
|
|
|
@ -128,6 +131,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
|
|
|
|
validatePjmLeader(data); |
|
|
|
validateWorkshopLeader(data); |
|
|
|
validateQcWorkshopLeader(data); |
|
|
|
fillProjectLeaderId(data); |
|
|
|
|
|
|
|
ErfExpApply entity = new ErfExpApply(); |
|
|
|
@ -235,6 +239,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
if (!"草稿".equals(entity.getStatus()) && !"已驳回".equals(entity.getStatus())) { |
|
|
|
throw new XJException("只有草稿或已驳回状态的试验单才能下达"); |
|
|
|
} |
|
|
|
if (StringUtils.isBlank(entity.getWorkshopLeaderUserId())) { |
|
|
|
throw new XJException("请先维护生产车间负责人后再下达"); |
|
|
|
} |
|
|
|
|
|
|
|
// 验证审批人信息 |
|
|
|
if (data.getTechManagerId() == null) { |
|
|
|
@ -385,6 +392,7 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
sendProjectLeaderApprovalPassedNotification(approvedEntity); |
|
|
|
sendPjmLeaderApprovalPassedNotification(approvedEntity); |
|
|
|
sendWorkshopLeaderApprovalPassedNotification(approvedEntity); |
|
|
|
sendQcWorkshopLeaderApprovalPassedNotification(approvedEntity); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1302,8 +1310,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
public Map<String, List<Map<String, Object>>> getPjmLeaderList(String buNo) { |
|
|
|
log.info("获取负责人列表: buNo={}", buNo); |
|
|
|
Map<String, List<Map<String, Object>>> result = new HashMap<>(); |
|
|
|
result.put("pjmLeaderList", convertManagerList(sysUserDao.getManagerListByRoleNameAndBu("产品文档收集 - PjM", buNo))); |
|
|
|
result.put("workshopLeaderList", convertManagerList(sysUserDao.getManagerListByRoleNameAndBu("生产车间负责人", buNo))); |
|
|
|
result.put("pjmLeaderList", convertManagerList(sysUserDao.getManagerListByRoleNameAndBu(ROLE_PJM_LEADER, buNo))); |
|
|
|
result.put("workshopLeaderList", convertManagerList(sysUserDao.getManagerListByRoleNameAndBu(ROLE_WORKSHOP_LEADER, buNo))); |
|
|
|
result.put("qcWorkshopLeaderList", convertManagerList(sysUserDao.getManagerListByRoleNameAndBu(ROLE_QC_WORKSHOP_LEADER, buNo))); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1328,9 +1337,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
return; |
|
|
|
} |
|
|
|
List<UserRoleDto> roles = sysUserDao.getUserRolesByRoleNames( |
|
|
|
data.getPjmLeaderUserId(), List.of("产品文档收集 - PjM")); |
|
|
|
data.getPjmLeaderUserId(), List.of(ROLE_PJM_LEADER)); |
|
|
|
if (roles == null || roles.isEmpty()) { |
|
|
|
throw new XJException("PJM负责人必须是【产品文档收集 - PjM】角色用户"); |
|
|
|
throw new XJException("PJM负责人必须是【" + ROLE_PJM_LEADER + "】角色用户"); |
|
|
|
} |
|
|
|
if (StringUtils.isBlank(data.getPjmLeaderName())) { |
|
|
|
String pjmDisplay = sysUserDao.getUserDisplayById(data.getPjmLeaderUserId()); |
|
|
|
@ -1344,19 +1353,16 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
* 校验生产车间负责人是否为生产车间负责人角色用户 |
|
|
|
*/ |
|
|
|
private void validateWorkshopLeader(ErfExpApplyData data) { |
|
|
|
if (data == null || StringUtils.isBlank(data.getWorkshopLeaderUserId())) { |
|
|
|
if (data != null) { |
|
|
|
data.setWorkshopLeaderUserId(""); |
|
|
|
data.setWorkshopLeaderName(""); |
|
|
|
} |
|
|
|
if (data == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (StringUtils.isBlank(data.getWorkshopLeaderUserId())) { |
|
|
|
throw new XJException("请选择生产车间负责人"); |
|
|
|
} |
|
|
|
|
|
|
|
List<Long> workshopLeaderIds = parseUserIdCsv(data.getWorkshopLeaderUserId(), "生产车间负责人", true); |
|
|
|
if (workshopLeaderIds.isEmpty()) { |
|
|
|
data.setWorkshopLeaderUserId(""); |
|
|
|
data.setWorkshopLeaderName(""); |
|
|
|
return; |
|
|
|
throw new XJException("请选择生产车间负责人"); |
|
|
|
} |
|
|
|
|
|
|
|
List<String> inputNameList = parseNameCsv(data.getWorkshopLeaderName()); |
|
|
|
@ -1365,9 +1371,9 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
for (int i = 0; i < workshopLeaderIds.size(); i++) { |
|
|
|
Long workshopLeaderId = workshopLeaderIds.get(i); |
|
|
|
List<UserRoleDto> roles = sysUserDao.getUserRolesByRoleNames( |
|
|
|
workshopLeaderId, List.of("生产车间负责人")); |
|
|
|
workshopLeaderId, List.of(ROLE_WORKSHOP_LEADER)); |
|
|
|
if (roles == null || roles.isEmpty()) { |
|
|
|
throw new XJException("生产车间负责人必须是【生产车间负责人】角色用户"); |
|
|
|
throw new XJException("生产车间负责人必须是【" + ROLE_WORKSHOP_LEADER + "】角色用户"); |
|
|
|
} |
|
|
|
|
|
|
|
String workshopDisplay = sysUserDao.getUserDisplayById(workshopLeaderId); |
|
|
|
@ -1386,6 +1392,52 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
data.setWorkshopLeaderName(String.join(",", resolvedNameList)); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 校验QC车间负责人是否为QC车间负责人角色用户(非必填) |
|
|
|
*/ |
|
|
|
private void validateQcWorkshopLeader(ErfExpApplyData data) { |
|
|
|
if (data == null || StringUtils.isBlank(data.getQcWorkshopLeaderUserId())) { |
|
|
|
if (data != null) { |
|
|
|
data.setQcWorkshopLeaderUserId(""); |
|
|
|
data.setQcWorkshopLeaderName(""); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
List<Long> qcWorkshopLeaderIds = parseUserIdCsv(data.getQcWorkshopLeaderUserId(), "QC车间负责人", true); |
|
|
|
if (qcWorkshopLeaderIds.isEmpty()) { |
|
|
|
data.setQcWorkshopLeaderUserId(""); |
|
|
|
data.setQcWorkshopLeaderName(""); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
List<String> inputNameList = parseNameCsv(data.getQcWorkshopLeaderName()); |
|
|
|
List<String> resolvedNameList = new ArrayList<>(); |
|
|
|
|
|
|
|
for (int i = 0; i < qcWorkshopLeaderIds.size(); i++) { |
|
|
|
Long qcWorkshopLeaderId = qcWorkshopLeaderIds.get(i); |
|
|
|
List<UserRoleDto> roles = sysUserDao.getUserRolesByRoleNames( |
|
|
|
qcWorkshopLeaderId, List.of(ROLE_QC_WORKSHOP_LEADER)); |
|
|
|
if (roles == null || roles.isEmpty()) { |
|
|
|
throw new XJException("QC车间负责人必须是【" + ROLE_QC_WORKSHOP_LEADER + "】角色用户"); |
|
|
|
} |
|
|
|
|
|
|
|
String qcWorkshopDisplay = sysUserDao.getUserDisplayById(qcWorkshopLeaderId); |
|
|
|
if (StringUtils.isBlank(qcWorkshopDisplay) && i < inputNameList.size()) { |
|
|
|
qcWorkshopDisplay = inputNameList.get(i); |
|
|
|
} |
|
|
|
if (StringUtils.isBlank(qcWorkshopDisplay)) { |
|
|
|
qcWorkshopDisplay = String.valueOf(qcWorkshopLeaderId); |
|
|
|
} |
|
|
|
resolvedNameList.add(qcWorkshopDisplay); |
|
|
|
} |
|
|
|
|
|
|
|
data.setQcWorkshopLeaderUserId(qcWorkshopLeaderIds.stream() |
|
|
|
.map(String::valueOf) |
|
|
|
.collect(Collectors.joining(","))); |
|
|
|
data.setQcWorkshopLeaderName(String.join(",", resolvedNameList)); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 解析逗号分隔用户ID串 |
|
|
|
*/ |
|
|
|
@ -2782,6 +2834,74 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 经理层审批全部通过后(进入计划员排产节点时)通知QC车间负责人 |
|
|
|
*/ |
|
|
|
private void sendQcWorkshopLeaderApprovalPassedNotification(ErfExpApply entity) { |
|
|
|
try { |
|
|
|
List<UserEmailInfoDto> qcWorkshopLeaderList = resolveQcWorkshopLeaderEmailInfos(entity); |
|
|
|
if (qcWorkshopLeaderList.isEmpty()) { |
|
|
|
log.info("未维护QC车间负责人或无法解析邮箱,跳过审批通过通知: applyNo={}", entity.getApplyNo()); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
MailSendAddressData mailSendData = qcMapper.getSendMailFromAddress(); |
|
|
|
if (mailSendData == null) { |
|
|
|
log.error("邮件发送配置未设置,无法发送QC车间负责人审批通过通知"); |
|
|
|
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()) |
|
|
|
: todayStr; |
|
|
|
|
|
|
|
String subject = String.format("【工程试验申请审批通过】%s - %s", |
|
|
|
entity.getApplyNo(), entity.getTitle() != null ? entity.getTitle() : ""); |
|
|
|
String tableBody = buildPlannerNotificationTable(entity, todayStr, expectedFinishDateStr); |
|
|
|
List<MailUtil.MailAttachment> attachments = collectErfApplyMailAttachments(entity.getApplyNo()); |
|
|
|
|
|
|
|
List<String> successEmailList = new ArrayList<>(); |
|
|
|
for (UserEmailInfoDto qcWorkshopLeader : qcWorkshopLeaderList) { |
|
|
|
String email = qcWorkshopLeader.getEmail(); |
|
|
|
if (StringUtils.isBlank(email)) { |
|
|
|
log.warn("QC车间负责人 {} 未配置邮箱,跳过审批通过通知", qcWorkshopLeader.getUsername()); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
String displayName = StringUtils.isNotBlank(qcWorkshopLeader.getUsername()) |
|
|
|
? qcWorkshopLeader.getUsername() |
|
|
|
: String.valueOf(qcWorkshopLeader.getUserId()); |
|
|
|
|
|
|
|
String body = "<html><body>" |
|
|
|
+ "<h3>尊敬的 " + displayName + ":</h3>" |
|
|
|
+ "<p>您好!以下工程试验单的三类经理审批已全部完成,您作为QC车间负责人请知悉并关注后续排产执行。</p>" |
|
|
|
+ "<p>当前流程已进入<strong>计划员排产</strong>环节。</p>" |
|
|
|
+ "<hr/>" + tableBody |
|
|
|
+ "<br/><p style='color:#888;'>发送时间:" |
|
|
|
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) |
|
|
|
+ "</p></body></html>"; |
|
|
|
|
|
|
|
MailUtil.sendMail(subject, body, new String[]{email}, mailSendData, attachments); |
|
|
|
successEmailList.add(email); |
|
|
|
log.info("已向QC车间负责人 {} ({}) 发送审批通过通知,试验单: {}", |
|
|
|
displayName, email, entity.getApplyNo()); |
|
|
|
} |
|
|
|
|
|
|
|
if (!successEmailList.isEmpty()) { |
|
|
|
SendMailRecord mailRecord = new SendMailRecord(); |
|
|
|
mailRecord.setType("工程试验申请QC车间负责人审批通过通知"); |
|
|
|
mailRecord.setDocumentNo(entity.getApplyNo()); |
|
|
|
mailRecord.setRecipient(String.join(";", successEmailList)); |
|
|
|
mailRecord.setSendDate(new Date()); |
|
|
|
qcMapper.saveSendMailRecord(mailRecord); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("发送QC车间负责人审批通过邮件失败,试验单: {}, 错误: {}", entity.getApplyNo(), e.getMessage(), e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 查询并构建工程试验单附件(sys_oss: order_ref1=ERF, order_ref2=applyNo, order_ref6=EXP_APPLY) |
|
|
|
*/ |
|
|
|
@ -2935,6 +3055,48 @@ public class ErfExpApplyServiceImpl extends ServiceImpl<ErfExpApplyMapper, ErfEx |
|
|
|
return workshopLeaderList; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 根据试验单上的QC车间负责人字段解析系统用户邮箱 |
|
|
|
*/ |
|
|
|
private List<UserEmailInfoDto> resolveQcWorkshopLeaderEmailInfos(ErfExpApply entity) { |
|
|
|
if (entity == null) { |
|
|
|
return Collections.emptyList(); |
|
|
|
} |
|
|
|
|
|
|
|
List<UserEmailInfoDto> qcWorkshopLeaderList = new ArrayList<>(); |
|
|
|
Set<Long> userIdSet = new LinkedHashSet<>(); |
|
|
|
|
|
|
|
List<Long> qcWorkshopLeaderIds = parseUserIdCsv(entity.getQcWorkshopLeaderUserId(), "QC车间负责人", false); |
|
|
|
for (Long qcWorkshopLeaderId : qcWorkshopLeaderIds) { |
|
|
|
UserEmailInfoDto qcWorkshopLeader = sysUserDao.getUserEmailInfoById(qcWorkshopLeaderId); |
|
|
|
if (qcWorkshopLeader != null && userIdSet.add(qcWorkshopLeader.getUserId())) { |
|
|
|
qcWorkshopLeaderList.add(qcWorkshopLeader); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (String qcWorkshopLeaderName : parseNameCsv(entity.getQcWorkshopLeaderName())) { |
|
|
|
SysUserEntity userByName = sysUserDao.queryByUserName(qcWorkshopLeaderName); |
|
|
|
if (userByName == null) { |
|
|
|
userByName = getFirstUserByDisplay(qcWorkshopLeaderName); |
|
|
|
} |
|
|
|
if (userByName == null || !userIdSet.add(userByName.getUserId())) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
UserEmailInfoDto qcWorkshopLeader = sysUserDao.getUserEmailInfoById(userByName.getUserId()); |
|
|
|
if (qcWorkshopLeader != null) { |
|
|
|
qcWorkshopLeaderList.add(qcWorkshopLeader); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (qcWorkshopLeaderList.isEmpty() && StringUtils.isNotBlank(entity.getQcWorkshopLeaderUserId())) { |
|
|
|
log.warn("QC车间负责人字段无法解析有效用户,applyNo={}, qcWorkshopLeaderUserId={}, qcWorkshopLeaderName={}", |
|
|
|
entity.getApplyNo(), entity.getQcWorkshopLeaderUserId(), entity.getQcWorkshopLeaderName()); |
|
|
|
} |
|
|
|
|
|
|
|
return qcWorkshopLeaderList; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 按显示名查询首个用户(按user_id升序),避免使用OFFSET语法 |
|
|
|
*/ |
|
|
|
|