Browse Source

QC生产车间负责人

master
han\hanst 2 weeks ago
parent
commit
b965c9d9c1
  1. 6
      src/main/java/com/xujie/sys/modules/erf/controller/ErfExpApplyController.java
  2. 10
      src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java
  3. 10
      src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java
  4. 2
      src/main/java/com/xujie/sys/modules/erf/service/ErfExpApplyService.java
  5. 190
      src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java
  6. 8
      src/main/resources/mapper/erf/ErfExpApplyMapper.xml

6
src/main/java/com/xujie/sys/modules/erf/controller/ErfExpApplyController.java

@ -160,7 +160,7 @@ public class ErfExpApplyController extends AbstractController {
}
/**
* 获取负责人列表PJM负责人 + 生产车间负责人
* 获取负责人列表PJM负责人 + 生产车间负责人 + QC车间负责人
*
* @param data 包含buNo
* @return 负责人列表
@ -173,10 +173,12 @@ public class ErfExpApplyController extends AbstractController {
Map<String, List<Map<String, Object>>> leaderMap = erfExpApplyService.getPjmLeaderList(buNo);
List<Map<String, Object>> pjmLeaderList = leaderMap.getOrDefault("pjmLeaderList", Collections.emptyList());
List<Map<String, Object>> workshopLeaderList = leaderMap.getOrDefault("workshopLeaderList", Collections.emptyList());
List<Map<String, Object>> qcWorkshopLeaderList = leaderMap.getOrDefault("qcWorkshopLeaderList", Collections.emptyList());
return R.ok()
.put("list", pjmLeaderList)
.put("pjmLeaderList", pjmLeaderList)
.put("workshopLeaderList", workshopLeaderList);
.put("workshopLeaderList", workshopLeaderList)
.put("qcWorkshopLeaderList", qcWorkshopLeaderList);
} catch (Exception e) {
log.error("获取负责人列表失败: " + e.getMessage(), e);
return R.error("获取负责人列表失败: " + e.getMessage());

10
src/main/java/com/xujie/sys/modules/erf/data/ErfExpApplyData.java

@ -230,6 +230,16 @@ public class ErfExpApplyData implements Serializable {
*/
private String workshopLeaderName;
/**
* QC车间负责人用户ID支持多选英文逗号分隔
*/
private String qcWorkshopLeaderUserId;
/**
* QC车间负责人姓名
*/
private String qcWorkshopLeaderName;
/**
* 联系方式
*/

10
src/main/java/com/xujie/sys/modules/erf/entity/ErfExpApply.java

@ -115,6 +115,16 @@ public class ErfExpApply implements Serializable {
*/
private String workshopLeaderName;
/**
* QC车间负责人用户ID支持多选英文逗号分隔
*/
private String qcWorkshopLeaderUserId;
/**
* QC车间负责人姓名
*/
private String qcWorkshopLeaderName;
/**
* 联系方式
*/

2
src/main/java/com/xujie/sys/modules/erf/service/ErfExpApplyService.java

@ -61,7 +61,7 @@ public interface ErfExpApplyService extends IService<ErfExpApply> {
Map<String, Object> getSubmitApprovers(Long userId, String buNo);
/**
* 获取负责人列表PJM负责人 + 生产车间负责人
* 获取负责人列表PJM负责人 + 生产车间负责人 + QC车间负责人
*
* @param buNo 事业部编码可为空为空时不按BU过滤
* @return 负责人列表映射

190
src/main/java/com/xujie/sys/modules/erf/service/impl/ErfExpApplyServiceImpl.java

@ -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语法
*/

8
src/main/resources/mapper/erf/ErfExpApplyMapper.xml

@ -23,6 +23,8 @@
<result column="pjm_leader_name" property="pjmLeaderName"/>
<result column="workshop_leader_user_id" property="workshopLeaderUserId"/>
<result column="workshop_leader_name" property="workshopLeaderName"/>
<result column="qc_workshop_leader_user_id" property="qcWorkshopLeaderUserId"/>
<result column="qc_workshop_leader_name" property="qcWorkshopLeaderName"/>
<result column="contact_method" property="contactMethod"/>
<result column="process_requirement" property="processRequirement"/>
<result column="actual_finish_date" property="actualFinishDate"/>
@ -65,6 +67,8 @@
pjm_leader_name,
workshop_leader_user_id,
workshop_leader_name,
qc_workshop_leader_user_id,
qc_workshop_leader_name,
contact_method,
process_requirement,
actual_finish_date,
@ -155,6 +159,8 @@
pjm_leader_name,
workshop_leader_user_id,
workshop_leader_name,
qc_workshop_leader_user_id,
qc_workshop_leader_name,
contact_method,
process_requirement,
actual_finish_date,
@ -198,6 +204,8 @@
a.pjm_leader_name,
a.workshop_leader_user_id,
a.workshop_leader_name,
a.qc_workshop_leader_user_id,
a.qc_workshop_leader_name,
a.contact_method,
a.process_requirement,
a.actual_finish_date,

Loading…
Cancel
Save