package jnpf.limsService.impl; import jnpf.base.UserInfo; import jnpf.limsEntity.BaogaoShenheJibie; import jnpf.limsEntity.LimsJianyanAssignItem; import jnpf.limsEntity.LimsJianyanXiangEntity; import jnpf.limsEntity.LimsLiuyangJiluEntity; import jnpf.limsEntity.LimsMessageEvent; import jnpf.limsEntity.LimsMessageRequest; import jnpf.limsEntity.LimsQingyandanEntity; import jnpf.limsEntity.LimsRecipientRef; import jnpf.limsMapper.LimsMessageAudienceMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class LimsOperationalMessagePublisher { private static final String QC_SUPERVISOR = "ROLE.003"; private final LimsMessageAfterCommitPublisher publisher; private final LimsMessageAudienceMapper audienceMapper; public void taskAssigned(LimsJianyanXiangEntity existing, LimsJianyanAssignItem item, UserInfo operator, Date assignedAt) { boolean external = "yes".equalsIgnoreCase(existing.getShifouWaijian()); String oldAssignee = external ? existing.getWaijianLururen() : existing.getJianchaRen(); String newAssignee = external ? item.getWaijianLururen() : item.getJianchaRen(); if (!StringUtils.hasText(newAssignee) || newAssignee.equals(oldAssignee)) { return; } Map parameters = baseInspectionParameters(existing); parameters.put("assignmentType", StringUtils.hasText(oldAssignee) ? "REASSIGN" : "ASSIGN"); parameters.put("inspectionItemName", value(existing.getJianyanXiangmuMingcheng())); parameters.put("dueDate", date(item.getWanchengRiqi())); parameters.put("assignerName", userName(operator)); parameters.put("externalInspection", external); publish(LimsMessageEvent.INSPECTION_TASK_ASSIGNED, tenant(operator, existing.getTenantId()), existing.getId(), "ASSIGNED", LimsMessageEvent.INSPECTION_TASK_ASSIGNED.getCode() + ":" + existing.getId() + ":" + assignedAt.getTime() + ":" + newAssignee, Collections.singletonList(LimsRecipientRef.user(newAssignee)), parameters); } public void inspectionResultsPendingReview(List rows, UserInfo submitter, Date submittedAt) { Map> byReviewer = new LinkedHashMap<>(); for (LimsJianyanXiangEntity row : rows) { if (!StringUtils.hasText(row.getJianchaBanzu())) { continue; } List reviewers = audienceMapper.selectOrganizationRoleUsers( tenant(submitter, row.getTenantId()), row.getJianchaBanzu(), QC_SUPERVISOR); String submitterId = assignee(row); for (String reviewer : reviewers) { if (StringUtils.hasText(reviewer) && !reviewer.equals(submitterId)) { byReviewer.computeIfAbsent(reviewer, key -> new ArrayList<>()).add(row); } } } for (Map.Entry> entry : byReviewer.entrySet()) { List assigned = entry.getValue(); Map parameters = new LinkedHashMap<>(); parameters.put("reviewerUserId", entry.getKey()); parameters.put("inspectionCount", assigned.size()); parameters.put("inspectionNos", join(assigned, LimsJianyanXiangEntity::getJianyanLiushuihao)); parameters.put("inspectionItemNames", join(assigned, LimsJianyanXiangEntity::getJianyanXiangmuMingcheng)); parameters.put("submitterName", userName(submitter)); parameters.put("submittedAt", dateTime(submittedAt)); LimsJianyanXiangEntity first = assigned.get(0); publish(LimsMessageEvent.INSPECTION_RESULT_REVIEW_PENDING, tenant(submitter, first.getTenantId()), first.getId(), "PENDING_REVIEW", LimsMessageEvent.INSPECTION_RESULT_REVIEW_PENDING.getCode() + ":" + entry.getKey() + ":" + submittedAt.getTime(), Collections.singletonList(LimsRecipientRef.user(entry.getKey())), parameters); } } public void inspectionResultsRejected(List rows, String reason, UserInfo rejector, Date rejectedAt) { for (LimsJianyanXiangEntity row : rows) { String recipient = assignee(row); if (!StringUtils.hasText(recipient)) { continue; } Map parameters = baseInspectionParameters(row); parameters.put("inspectionNo", value(row.getJianyanLiushuihao())); parameters.put("inspectionItemName", value(row.getJianyanXiangmuMingcheng())); parameters.put("rejectReason", value(reason)); parameters.put("rejectorName", userName(rejector)); parameters.put("externalInspection", "yes".equalsIgnoreCase(row.getShifouWaijian())); long round = row.getJieguoLuruRiqi() == null ? rejectedAt.getTime() : row.getJieguoLuruRiqi().getTime(); publish(LimsMessageEvent.INSPECTION_RESULT_REJECTED, tenant(rejector, row.getTenantId()), row.getId(), "REJECTED", LimsMessageEvent.INSPECTION_RESULT_REJECTED.getCode() + ":" + row.getId() + ":" + round, Collections.singletonList(LimsRecipientRef.user(recipient)), parameters); } } public void reportPendingReview(LimsQingyandanEntity report, UserInfo compiler, Date submittedAt) { List recipients = authorized(report, BaogaoShenheJibie.SHENHE.getCode(), Collections.singleton(compiler.getUserId())); Map parameters = baseReportParameters(report); parameters.put("compilerName", userName(compiler)); parameters.put("submittedAt", dateTime(submittedAt)); publishUsers(LimsMessageEvent.REPORT_REVIEW_PENDING, report, submittedAt, "PENDING_REVIEW", recipients, parameters); } public void reportPendingApproval(LimsQingyandanEntity report, UserInfo reviewer, Date reviewedAt) { Set excluded = new LinkedHashSet<>(); excluded.add(report.getBaogaoRen()); excluded.add(reviewer.getUserId()); List recipients = authorized(report, BaogaoShenheJibie.QIANFA.getCode(), excluded); Map parameters = baseReportParameters(report); parameters.put("compilerName", value(audienceMapper.selectUserDisplayName( report.getTenantId(), report.getBaogaoRen()))); parameters.put("reviewerName", userName(reviewer)); parameters.put("reviewedAt", dateTime(reviewedAt)); publishUsers(LimsMessageEvent.REPORT_APPROVAL_PENDING, report, reviewedAt, "PENDING_APPROVAL", recipients, parameters); } public void reportRejected(LimsQingyandanEntity report, List items, String fromStatus, String reason, UserInfo rejector, Date rejectedAt) { Set userIds = new LinkedHashSet<>(); if (StringUtils.hasText(report.getBaogaoRen())) { userIds.add(report.getBaogaoRen()); } items.stream().map(this::assignee).filter(StringUtils::hasText).forEach(userIds::add); Map parameters = baseReportParameters(report); parameters.put("rejectReason", value(reason)); parameters.put("rejectorName", userName(rejector)); parameters.put("rejectedFromStatus", value(fromStatus)); publishUsers(LimsMessageEvent.REPORT_REJECTED, report, rejectedAt, "REJECTED", new ArrayList<>(userIds), parameters); } public void retainSamplePendingReceive(LimsLiuyangJiluEntity record, LimsQingyandanEntity request, UserInfo sampler) { Map parameters = new LinkedHashMap<>(); parameters.put("bizId", record.getId()); parameters.put("requestId", request.getId()); parameters.put("inspectionNo", value(request.getJianyanLiushuihao())); parameters.put("receiveNo", value(record.getJieshouBianhao())); parameters.put("sampleName", value(record.getYangpinMingcheng())); parameters.put("sampleCode", value(record.getYangpinBianma())); parameters.put("batchNo", value(record.getPihao())); parameters.put("retainQuantity", value(record.getLiuyangLiangShiji())); parameters.put("unit", value(record.getLiuyangDanwei())); parameters.put("samplerName", userName(sampler)); parameters.put("sampledAt", dateTime(request.getQuyangRiqi())); publish(LimsMessageEvent.RETAIN_SAMPLE_RECEIVE_PENDING, tenant(sampler, record.getTenantId()), record.getId(), "PENDING_RECEIVE", LimsMessageEvent.RETAIN_SAMPLE_RECEIVE_PENDING.getCode() + ":" + record.getId(), Collections.singletonList(LimsRecipientRef.roleEnCode("ROLE.005")), parameters); } private List authorized(LimsQingyandanEntity report, String level, Set excluded) { List users = audienceMapper.selectReportAuthorizedUsers( value(report.getTenantId()), level, report.getBizType()); return users.stream().filter(StringUtils::hasText).filter(id -> !excluded.contains(id)) .distinct().collect(Collectors.toList()); } private void publishUsers(LimsMessageEvent event, LimsQingyandanEntity report, Date actionTime, String stage, List users, Map parameters) { List refs = users.stream().map(LimsRecipientRef::user).collect(Collectors.toList()); publish(event, value(report.getTenantId()), report.getId(), stage, event.getCode() + ":" + report.getId() + ":" + actionTime.getTime(), refs, parameters); } private Map baseInspectionParameters(LimsJianyanXiangEntity row) { Map parameters = new LinkedHashMap<>(); parameters.put("bizId", row.getId()); parameters.put("productName", value(row.getChanpinMingcheng())); parameters.put("batchNo", value(row.getPihao())); return parameters; } private Map baseReportParameters(LimsQingyandanEntity report) { Map parameters = new LinkedHashMap<>(); parameters.put("bizId", report.getId()); parameters.put("inspectionNo", value(report.getJianyanLiushuihao())); parameters.put("reportNo", value(report.getBaogaoBianhao())); parameters.put("productName", value(report.getChanpinMingcheng())); parameters.put("batchNo", value(report.getPihao())); parameters.put("reportCategory", value(report.getBizType())); return parameters; } private void publish(LimsMessageEvent event, String tenantId, String bizId, String stage, String occurrenceKey, List recipients, Map parameters) { publisher.publish(LimsMessageRequest.builder().event(event).tenantId(tenantId).bizId(bizId) .remindStage(stage).occurrenceKey(occurrenceKey).recipients(recipients) .parameters(parameters).build()); } private String assignee(LimsJianyanXiangEntity row) { return "yes".equalsIgnoreCase(row.getShifouWaijian()) ? row.getWaijianLururen() : row.getJianchaRen(); } private String tenant(UserInfo user, String fallback) { return user != null && StringUtils.hasText(user.getTenantId()) ? user.getTenantId() : value(fallback); } private String userName(UserInfo user) { return user == null ? "" : value(user.getUserName()); } private String date(Date value) { return value == null ? "" : new SimpleDateFormat("yyyy-MM-dd").format(value); } private String dateTime(Date value) { return value == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value); } private String join(List rows, java.util.function.Function getter) { return rows.stream().map(getter).filter(StringUtils::hasText).distinct().collect(Collectors.joining("、")); } private String value(String value) { return value == null ? "" : value; } }