package jnpf.limsService.impl; import jnpf.limsEntity.LimsJianyanXiangEntity; import jnpf.limsEntity.LimsMessageEvent; import jnpf.limsEntity.LimsMessageRequest; import jnpf.limsEntity.LimsMessageSendResult; import jnpf.limsEntity.LimsRecipientRef; import jnpf.limsMapper.LimsJianceTaskRemindMapper; import jnpf.limsService.LimsJianceTaskRemindService; import jnpf.limsService.LimsMessageService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Slf4j @Service @RequiredArgsConstructor public class LimsJianceTaskRemindServiceImpl implements LimsJianceTaskRemindService { private static final String DATE_PATTERN = "yyyy-MM-dd"; private final LimsJianceTaskRemindMapper remindMapper; private final LimsMessageService messageService; @Value("${lims.message.enabled:false}") private boolean messageEnabled; @Scheduled(cron = "${lims.remind.cron:0 0 8 * * ?}") public void cronTrigger() { if (!messageEnabled) { log.info("[lims-remind] skipped because lims.message.enabled=false"); return; } log.info("[lims-remind] cron triggered"); scanAndRemind(false); } @Override public Map> scanAndRemind(boolean dryRun) { Map> stats = new LinkedHashMap<>(); stats.put("D7", processDueIn(7, dryRun)); stats.put("D3", processDueIn(3, dryRun)); stats.put("D1", processDueIn(1, dryRun)); stats.put("EXPIRED", processExpired(dryRun)); log.info("[lims-remind] done, dryRun={}, stats={}", dryRun, stats); return stats; } private Map processDueIn(int days, boolean dryRun) { String stage = "D" + days; List rows = remindMapper.selectDueIn(days, stage); int sent = 0; for (LimsJianyanXiangEntity row : rows) { LimsMessageSendResult result = messageService.send(LimsMessageRequest.builder() .event(LimsMessageEvent.INSPECTION_TASK_DUE) .tenantId(row.getTenantId()) .bizId(row.getId()) .remindStage(stage) .occurrenceKey(occurrenceKey(LimsMessageEvent.INSPECTION_TASK_DUE, row, stage)) .recipients(Arrays.asList(LimsRecipientRef.user(row.getJianchaRen()))) .parameters(dueParameters(row, days)) .dryRun(dryRun) .build()); if (isComplete(result)) { sent++; appendLegacyFlag(row.getId(), stage, dryRun); } } return statRow(rows.size(), sent); } private Map processExpired(boolean dryRun) { List rows = remindMapper.selectExpired(); int sent = 0; for (LimsJianyanXiangEntity row : rows) { List recipients = new ArrayList<>(); recipients.add(LimsRecipientRef.user(row.getJianchaRen())); recipients.add(LimsRecipientRef.user(row.getRenwuFenpeiren())); LimsMessageSendResult result = messageService.send(LimsMessageRequest.builder() .event(LimsMessageEvent.INSPECTION_TASK_OVERDUE) .tenantId(row.getTenantId()) .bizId(row.getId()) .remindStage("OVERDUE") .occurrenceKey(occurrenceKey(LimsMessageEvent.INSPECTION_TASK_OVERDUE, row, "OVERDUE")) .recipients(recipients) .parameters(dueParameters(row, 0)) .dryRun(dryRun) .build()); if (isComplete(result)) { sent++; appendLegacyFlag(row.getId(), "EXPIRED", dryRun); } } return statRow(rows.size(), sent); } private Map dueParameters(LimsJianyanXiangEntity row, int remainingDays) { Map parameters = new HashMap<>(); parameters.put("bizId", row.getId()); parameters.put("remainingDays", remainingDays); parameters.put("dueDate", formatDate(row.getWanchengRiqi())); parameters.put("productName", value(row.getChanpinMingcheng())); parameters.put("batchNo", value(row.getPihao())); parameters.put("itemName", value(row.getJianyanXiangmuMingcheng())); return parameters; } private String occurrenceKey(LimsMessageEvent event, LimsJianyanXiangEntity row, String stage) { return event.getCode() + ":" + row.getId() + ":" + formatCompactDate(row.getWanchengRiqi()) + ":" + stage; } private void appendLegacyFlag(String rowId, String flag, boolean dryRun) { if (!dryRun) { remindMapper.appendFlag(rowId, flag); } } private String formatDate(Date date) { return date == null ? "" : new SimpleDateFormat(DATE_PATTERN).format(date); } private String formatCompactDate(Date date) { return date == null ? "NO_DATE" : new SimpleDateFormat("yyyyMMdd").format(date); } private String value(String value) { return value == null ? "" : value; } private Map statRow(int hit, int sent) { Map row = new HashMap<>(); row.put("hit", hit); row.put("sent", sent); row.put("skipped", hit - sent); return row; } private boolean isComplete(LimsMessageSendResult result) { return result.isAccepted() && result.getRecipientCount() > 0 && result.getSentCount() == result.getRecipientCount() && result.getFailedCount() == 0; } }