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/LimsWendingxingWanchengServiceImpl.java |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingWanchengServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingWanchengServiceImpl.java
new file mode 100644
index 0000000..8dfb82f
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingWanchengServiceImpl.java
@@ -0,0 +1,156 @@
+package jnpf.limsService.impl;
+
+import jnpf.limsEntity.LimsWendingxingJianyanCountRow;
+import jnpf.limsEntity.LimsWendingxingJihuaZhixingCountRow;
+import jnpf.limsEntity.LimsMessageEvent;
+import jnpf.limsEntity.LimsMessageRequest;
+import jnpf.limsEntity.LimsRecipientRef;
+import jnpf.limsEntity.LimsStabilityCompletionRow;
+import jnpf.limsMapper.LimsWendingxingWanchengMapper;
+import jnpf.limsService.LimsMessageService;
+import jnpf.limsService.LimsWendingxingWanchengService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * 绋冲畾鎬ц�冨療璁″垝鑷姩瀹屾垚瀹氭椂浠诲姟銆�
+ */
+@Slf4j
+@Service
+public class LimsWendingxingWanchengServiceImpl implements LimsWendingxingWanchengService {
+
+    private final AtomicBoolean running = new AtomicBoolean(false);
+
+    @Autowired
+    private LimsWendingxingWanchengMapper limsWendingxingWanchengMapper;
+
+    @Autowired
+    private LimsMessageService messageService;
+
+    @Value("${lims.wendingxing.wancheng.page-size:200}")
+    private int pageSize;
+
+    @Value("${lims.message.enabled:false}")
+    private boolean messageEnabled;
+
+    @Scheduled(cron = "${lims.wendingxing.wancheng.cron:0 */10 * * * ?}")
+    public void cronTrigger() {
+        if (!running.compareAndSet(false, true)) {
+            log.warn("[wendingxing-wancheng] previous scan is still running, skip this trigger");
+            return;
+        }
+        try {
+            log.info("[wendingxing-wancheng] cron triggered");
+            scanAndComplete();
+        } catch (Exception e) {
+            log.error("[wendingxing-wancheng] scan failed: {}", e.getMessage(), e);
+        } finally {
+            running.set(false);
+        }
+    }
+
+    @Override
+    public Map<String, Integer> scanAndComplete() {
+        int actualPageSize = pageSize > 0 ? pageSize : 200;
+        int scanned = 0;
+        int cycleCompleted = 0;
+        int resultCompleted = 0;
+        int updated = 0;
+        String lastJihuaId = null;
+
+        while (true) {
+            List<LimsWendingxingJihuaZhixingCountRow> page =
+                    limsWendingxingWanchengMapper.selectJihuaZhixingPage(lastJihuaId, actualPageSize);
+            if (page.isEmpty()) {
+                break;
+            }
+
+            scanned += page.size();
+            lastJihuaId = page.get(page.size() - 1).getKaocaJihuaId();
+
+            List<String> allCyclesCompletedIds = new ArrayList<>();
+            for (LimsWendingxingJihuaZhixingCountRow row : page) {
+                if (row.getTotalCount() == row.getYizhixingCount()) {
+                    allCyclesCompletedIds.add(row.getKaocaJihuaId());
+                }
+            }
+            cycleCompleted += allCyclesCompletedIds.size();
+            if (allCyclesCompletedIds.isEmpty()) {
+                continue;
+            }
+
+            List<LimsWendingxingJianyanCountRow> counts =
+                    limsWendingxingWanchengMapper.selectJianyanCounts(allCyclesCompletedIds);
+            List<String> allResultsCompletedIds = new ArrayList<>();
+            for (LimsWendingxingJianyanCountRow row : counts) {
+                if (row.getJianyanXiangCount() != row.getJianyanJieguoLuruCount()) {
+                    continue;
+                }
+                allResultsCompletedIds.add(row.getWendingxingJiluId());
+            }
+            resultCompleted += allResultsCompletedIds.size();
+            if (!allResultsCompletedIds.isEmpty()) {
+                List<String> updatedIds = limsWendingxingWanchengMapper
+                        .updateJihuaYiwanchengReturning(allResultsCompletedIds);
+                updated += updatedIds.size();
+                notifyCompletedPlans(updatedIds);
+            }
+        }
+
+        Map<String, Integer> stats = new LinkedHashMap<>();
+        stats.put("scanned", scanned);
+        stats.put("cycleCompleted", cycleCompleted);
+        stats.put("resultCompleted", resultCompleted);
+        stats.put("updated", updated);
+        log.info("[wendingxing-wancheng] done, stats={}", stats);
+        return stats;
+    }
+
+    private void notifyCompletedPlans(List<String> updatedIds) {
+        if (!messageEnabled || updatedIds.isEmpty()) {
+            return;
+        }
+        Date completedAt = new Date();
+        for (LimsStabilityCompletionRow row
+                : limsWendingxingWanchengMapper.selectCompletionDetails(updatedIds)) {
+            List<LimsRecipientRef> recipients = new ArrayList<>();
+            if (row.getCreatorUserId() != null && !row.getCreatorUserId().trim().isEmpty()) {
+                recipients.add(LimsRecipientRef.user(row.getCreatorUserId()));
+            }
+            recipients.add(LimsRecipientRef.roleEnCode("ROLE.002"));
+            Map<String, Object> parameters = new LinkedHashMap<>();
+            parameters.put("bizId", row.getId());
+            parameters.put("planCode", value(row.getPlanCode()));
+            parameters.put("planName", value(row.getPlanName()));
+            parameters.put("sampleName", value(row.getSampleName()));
+            parameters.put("batchNo", value(row.getBatchNo()));
+            parameters.put("stabilityType", value(row.getStabilityType()));
+            parameters.put("cycleCount", row.getCycleCount());
+            parameters.put("completedAt", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+                    .format(completedAt));
+            messageService.send(LimsMessageRequest.builder()
+                    .event(LimsMessageEvent.STABILITY_PLAN_COMPLETED)
+                    .tenantId(value(row.getTenantId()))
+                    .bizId(row.getId())
+                    .remindStage("COMPLETED")
+                    .occurrenceKey(LimsMessageEvent.STABILITY_PLAN_COMPLETED.getCode() + ":" + row.getId())
+                    .recipients(recipients)
+                    .parameters(parameters)
+                    .build());
+        }
+    }
+
+    private String value(String value) {
+        return value == null ? "" : value;
+    }
+}

--
Gitblit v1.8.0