From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master

---
 jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsJianceTaskRemindServiceImpl.java |  153 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsJianceTaskRemindServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsJianceTaskRemindServiceImpl.java
new file mode 100644
index 0000000..18de70d
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsJianceTaskRemindServiceImpl.java
@@ -0,0 +1,153 @@
+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<String, Map<String, Integer>> scanAndRemind(boolean dryRun) {
+        Map<String, Map<String, Integer>> 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<String, Integer> processDueIn(int days, boolean dryRun) {
+        String stage = "D" + days;
+        List<LimsJianyanXiangEntity> 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<String, Integer> processExpired(boolean dryRun) {
+        List<LimsJianyanXiangEntity> rows = remindMapper.selectExpired();
+        int sent = 0;
+        for (LimsJianyanXiangEntity row : rows) {
+            List<LimsRecipientRef> 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<String, Object> dueParameters(LimsJianyanXiangEntity row, int remainingDays) {
+        Map<String, Object> 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<String, Integer> statRow(int hit, int sent) {
+        Map<String, Integer> 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;
+    }
+}

--
Gitblit v1.8.0