From f8c024b1c1de318a4de485e048d1044cd6dcaa53 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期六, 24 十月 2026 21:05:42 +0800
Subject: [PATCH] feat(search-new):  1.标准查新模块                    2.印章使用记录

---
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java |  237 ++++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 161 insertions(+), 76 deletions(-)

diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
index dcd6d1e..3dde4b3 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -359,13 +359,16 @@
                         "妯℃澘ID " + snapshot.getTemplateId());
                 if (snapshot.getDetectionTime() == null) {
                     collect.add("璇烽�夋嫨鈥�" + templateName + "鈥濈殑妫�娴嬫椂闂�");
+                } else if (snapshot.getDetectionEndTime() != null
+                        && snapshot.getDetectionEndTime().isBefore(snapshot.getDetectionTime())) {
+                    collect.add("鈥�" + templateName + "鈥濈殑妫�娴嬬粨鏉熸棩鏈熶笉鑳芥棭浜庡紑濮嬫棩鏈�");
                 }
                 if (StringUtils.isBlank(snapshot.getDetectionPlace())) {
                     collect.add("璇峰~鍐欌��" + templateName + "鈥濈殑妫�娴嬪湴鐐�");
                 }
             }
             map.put("errorMsg", collect);
-            map.put("missingExportItems", getMissingTemplateExportValues(orderId));
+            map.put("missingExportItems", getMissingTemplateExportValues(orderId, laboratory));
             map.put("unInsOrderCount", 0L);
             return map;
         }
@@ -602,11 +605,9 @@
         }
 
 
-        // 娣诲姞璁惧璁板綍
-        threadPoolTaskExecutor.execute(() -> {
-            // 娣诲姞璁惧浣跨敤璁板綍
-            addDeviceRecord(insSample, userId);
-        });
+        // 鍘熷璁板綍淇濆瓨鍚庯紝鎸夊綋鍓嶆ā鏉块�夌敤鐨勮澶囩敓鎴愪娇鐢ㄨ褰�
+        syncDeviceRecordsFromTemplate(saveInsContextDto.getOrderId(), saveInsContextDto.getSampleId(),
+                saveInsContextDto.getCurrentTable(), userId);
     }
 
     /**
@@ -649,10 +650,11 @@
 
         JSONObject values = JSON.parseObject(JSON.toJSONString(dto.getValues() == null
                 ? Collections.emptyMap() : dto.getValues()));
-        // 妫�楠屾湡闂撮〉闈㈠睍绀虹殑鏄爣鍑嗙淮鎶や腑鐨勬渶鏂版ā鏉匡紝淇濆瓨鏍¢獙蹇呴』浣跨敤鍚屼竴浠芥ā鏉匡紝
-        // 閬垮厤妯℃澘鏂板鈥滃鍑哄�尖�濇壒娉ㄥ悗浠嶆寜涓嬪崟鏃剁殑鏃у揩鐓ц鎶ユ湭閰嶇疆銆�
-        String currentTemplateThing = getCurrentTemplateThing(snapshot);
-        List<String> exportValueCoordinates = getExportValueCoordinates(currentTemplateThing).values().stream()
+        // 淇濆瓨鏃跺繀椤讳娇鐢ㄩ〉闈㈠綋鍓嶅睍绀虹殑妯℃澘锛氬緟妫�銆佸湪妫�闃舵灞曠ず鏍囧噯缁存姢涓殑瀹炴椂妯℃澘锛�
+        // 澶嶆牳銆侀┏鍥為樁娈靛睍绀鸿鍗曞揩鐓э紱鍚﹀垯妯℃澘鍦ㄦ楠岄�斾腑琚慨鏀瑰悗浼氬彇閿欏鍑哄�煎崟鍏冩牸銆�
+        boolean useSnapshot = useSnapshotTemplate(dto.getOrderId(), getCurrentUserLaboratory(dto.getOrderId()));
+        String pageTemplateThing = getPageTemplateThing(snapshot, useSnapshot);
+        List<String> exportValueCoordinates = getExportValueCoordinates(pageTemplateThing).values().stream()
                 .flatMap(Collection::stream)
                 .distinct()
                 .collect(Collectors.toList());
@@ -688,6 +690,9 @@
                 .and(w -> w.isNull(InsProduct::getLastValue).or().eq(InsProduct::getLastValue, "")));
         sample.setInsState(unfinished == 0 ? 2 : 1);
         insSampleMapper.updateById(sample);
+
+        // 鍘熷璁板綍淇濆瓨鍚庯紝鎸夊綋鍓嶆ā鏉块�夌敤鐨勮澶囩敓鎴愪娇鐢ㄨ褰�
+        syncDeviceRecordsFromTemplate(dto.getOrderId(), dto.getSampleId(), dto.getTemplateId(), userId);
     }
 
     /**
@@ -889,8 +894,8 @@
     }
 
     /**
-     * 妫�楠屼繚瀛樸�佹彁浜ゆ牎楠岃鍙栨爣鍑嗙淮鎶や腑鐨勫疄鏃舵ā鏉匡紱妯℃澘宸茶鍒犻櫎鎴栧唴瀹逛负绌烘椂鎵嶅洖閫�璁㈠崟蹇収銆�
-     * 妫�楠屽畬鎴愬悗鐨勫睍绀哄拰鎶ュ憡浠嶇敱璁㈠崟蹇収璐熻矗锛屼笉浼氶殢鏍囧噯妯℃澘鍚庣画淇敼鑰屽彉鍖栥��
+     * 璇诲彇鏍囧噯缁存姢涓殑瀹炴椂妯℃澘锛涙ā鏉垮凡琚垹闄ゆ垨鍐呭涓虹┖鏃舵墠鍥為��璁㈠崟蹇収銆�
+     * 浠呯敤浜庢楠屽浠嶅浜庡緟妫�銆佸湪妫�闃舵锛堥〉闈㈠睍绀哄疄鏃舵ā鏉匡級鐨勪繚瀛樹笌鏍¢獙銆�
      */
     private String getCurrentTemplateThing(InsOrderStandardTemplate snapshot) {
         if (snapshot != null && snapshot.getTemplateId() != null) {
@@ -903,9 +908,53 @@
     }
 
     /**
+     * 妫�楠屽崟椤甸潰鍦ㄦ楠屽杩涘叆澶嶆牳鍙婁箣鍚庣姸鎬佹椂灞曠ず璁㈠崟蹇収锛屽鍑哄�肩殑淇濆瓨鍜屾彁浜ゆ牎楠屽繀椤讳笌椤甸潰
+     * 浣跨敤鍚屼竴浠芥ā鏉匡紱鍚﹀垯鏍囧噯妯℃澘鍦ㄦ楠岄�斾腑琚慨鏀瑰悗锛屽巻鍙插崟鎹細鎸夋柊鍧愭爣璇诲彇蹇収鏁版嵁鑰岃鎶ヤ负绌恒��
+     */
+    private String getPageTemplateThing(InsOrderStandardTemplate snapshot, boolean useSnapshot) {
+        if (useSnapshot && snapshot != null && StrUtil.isNotBlank(snapshot.getThing())) {
+            return snapshot.getThing();
+        }
+        return getCurrentTemplateThing(snapshot);
+    }
+
+    /**
+     * 涓庢楠屽崟椤甸潰 getTemplateThing 鐨勫垽瀹氫繚鎸佷竴鑷达細妫�楠屽鐘舵�佽繘鍏ュ鏍革紙2锛夊強涔嬪悗鏃朵娇鐢ㄨ鍗曞揩鐓с��
+     * 鎸囨淳璁板綍閲岀殑瀹為獙瀹ゅ悕绉板彲鑳藉拰鐘舵�佽涓嶄竴鑷达紙濡傗�滃叏閮ㄢ�濓級锛屾鏃堕��鍥炴寜璁㈠崟鏁翠綋鐘舵�佸垽瀹氥��
+     */
+    private boolean useSnapshotTemplate(Integer orderId, String laboratory) {
+        if (StringUtils.isNotBlank(laboratory)) {
+            InsOrderState state = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery()
+                    .eq(InsOrderState::getInsOrderId, orderId)
+                    .eq(InsOrderState::getLaboratory, laboratory)
+                    .last("limit 1"));
+            if (state != null) {
+                return state.getInsState() != null && state.getInsState() >= 2;
+            }
+        }
+        return insOrderStateMapper.selectList(Wrappers.<InsOrderState>lambdaQuery()
+                        .eq(InsOrderState::getInsOrderId, orderId))
+                .stream()
+                .anyMatch(state -> state.getInsState() != null && state.getInsState() >= 2);
+    }
+
+    /**
+     * 鍙栧綋鍓嶇櫥褰曚汉鍦ㄨ璁㈠崟涓婃渶杩戜竴鏉℃寚娲捐褰曟墍灞炵殑妫�楠屽锛涙湭鎸囨淳璐﹀彿杩斿洖 null锛岀敱鐘舵�佸垽瀹氬厹搴曘��
+     */
+    private String getCurrentUserLaboratory(Integer orderId) {
+        Integer userId = SecurityUtils.getUserId().intValue();
+        InsSampleUser sampleUser = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
+                .eq(InsSampleUser::getInsSampleId, orderId)
+                .eq(InsSampleUser::getUserId, userId)
+                .orderByDesc(InsSampleUser::getId)
+                .last("limit 1"));
+        return sampleUser == null ? null : sampleUser.getSonLaboratory();
+    }
+
+    /**
      * 鐩寸粦妯℃澘璁㈠崟鍙牎楠屾瘡涓�滃鍑哄�尖�濇壒娉ㄦ墍鍦ㄥ尯鍩熷彸渚х揣閭诲崟鍏冩牸锛屼笉浣跨敤妫�楠岄」鐘舵�佹垨 last_value 鍒ゅ畾銆�
      */
-    private List<String> getMissingTemplateExportValues(Integer orderId) {
+    private List<String> getMissingTemplateExportValues(Integer orderId, String laboratory) {
         List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateService.list(
                 Wrappers.<InsOrderStandardTemplate>lambdaQuery()
                         .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
@@ -915,9 +964,10 @@
             missing.add("褰撳墠璁㈠崟鏈壘鍒板師濮嬭褰曟ā鏉垮揩鐓�");
             return missing;
         }
+        boolean useSnapshot = useSnapshotTemplate(orderId, laboratory);
         for (InsOrderStandardTemplate snapshot : snapshots) {
             Integer templateId = snapshot.getTemplateId();
-            List<String> coordinates = getExportValueCoordinates(getCurrentTemplateThing(snapshot)).values().stream()
+            List<String> coordinates = getExportValueCoordinates(getPageTemplateThing(snapshot, useSnapshot)).values().stream()
                     .flatMap(Collection::stream)
                     .distinct()
                     .collect(Collectors.toList());
@@ -982,60 +1032,52 @@
         }
     }
 
-    private synchronized void addDeviceRecord(InsSample insSample, Integer userId) {
-        InsOrder order = insOrderMapper.selectById(insSample.getInsOrderId());
+    /**
+     * 鍘熷璁板綍淇濆瓨鍚庯紝鎸夊綋鍓嶆ā鏉块�夌敤鐨勮澶囩敓鎴愬緟濉啓鐨勪娇鐢ㄨ褰曘��
+     * 鍚屼竴璁㈠崟銆佹牱鍝併�佽澶囧彧鐢熸垚涓�鏉★紱宸茬粡濉啓杩囩殑璁板綍涓嶄細琚鐩栥��
+     */
+    private synchronized void syncDeviceRecordsFromTemplate(Integer orderId, Integer sampleId,
+                                                            Integer templateId, Integer userId) {
+        if (orderId == null || sampleId == null || templateId == null) {
+            return;
+        }
+        InsOrder order = insOrderMapper.selectById(orderId);
+        InsSample sample = insSampleMapper.selectById(sampleId);
+        if (order == null || sample == null) {
+            return;
+        }
+        List<Integer> deviceIds = insOrderTemplateDeviceMapper
+                .selectDeviceIdsByOrderAndTemplate(orderId, templateId);
+        if (CollectionUtils.isEmpty(deviceIds)) {
+            return;
+        }
         User user = userMapper.selectById(userId);
-        // 鏌ヨ璁惧浣跨敤璁板綍鏌ヨ璇ヨ鍗曠殑浣跨敤璁板綍
-        List<InsOrderDeviceRecordDto> deviceRecordDtoList = insOrderDeviceRecordMapper.selectDeviceNumber(insSample.getInsOrderId());
-        Set<String> recordCodeset = deviceRecordDtoList.stream().map(InsOrderDeviceRecordDto::getManagementNumber).collect(Collectors.toSet());
-
-        // 鑾峰彇璁㈠崟璁惧缂栧彿
-        List<InsProductResult> resultList = insProductResultMapper.selectResultByOrderId(insSample.getInsOrderId());
-        Set<String> deviceCodeSet = new HashSet<>();
-        for (InsProductResult result : resultList) {
-            // 娣诲姞璁惧缂栧彿
-            List<JSONObject> jsonObjects = JSON.parseArray(result.getEquipValue(), JSONObject.class);
-            for (JSONObject jsonObject : jsonObjects) {
-                if (!"".equals(jsonObject.get("v") + "")) {
-                    List<String> v = StrUtil.split(jsonObject.get("v") + "", "锛�");
-                    deviceCodeSet.addAll(v);
-                }
+        String usePerson = user == null ? "" : user.getName();
+        String sampleCode = StringUtils.isNotBlank(sample.getSampleCode())
+                ? sample.getSampleCode() : order.getEntrustCode();
+        for (Integer deviceId : deviceIds) {
+            if (deviceId == null) {
+                continue;
             }
+            Long count = insOrderDeviceRecordMapper.selectCount(Wrappers.<InsOrderDeviceRecord>lambdaQuery()
+                    .eq(InsOrderDeviceRecord::getInsOrderId, orderId)
+                    .eq(InsOrderDeviceRecord::getDeviceId, deviceId)
+                    .eq(InsOrderDeviceRecord::getSampleCode, sampleCode));
+            if (count != null && count > 0) {
+                continue;
+            }
+            InsOrderDeviceRecord record = new InsOrderDeviceRecord();
+            record.setInsOrderId(orderId);
+            record.setDeviceId(deviceId);
+            record.setSampleCode(sampleCode);
+            record.setTemperature(order.getTemperature());
+            record.setHumidity(order.getHumidity());
+            record.setUseBefore(1);
+            record.setUseAfter(1);
+            record.setUsePersonId(userId);
+            record.setUsePerson(usePerson);
+            insOrderDeviceRecordMapper.insert(record);
         }
-        // 1.鍒ゆ柇鏄惁鏈夋病鏈夋坊鍔犵殑浣跨敤璁板綍
-        Set<String> orderDeviceNumbers = getDeviceDifference(deviceCodeSet, recordCodeset);
-        // 娣诲姞浣跨敤璁板綍, 鏍规嵁缂栧彿鏌ヨ璁惧id
-        if (CollectionUtils.isNotEmpty(orderDeviceNumbers)) {
-            List<Integer> orderDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(orderDeviceNumbers);
-            List<InsOrderDeviceRecord> collect = orderDeviceIds.stream().map(deviceId -> {
-                InsOrderDeviceRecord insOrderDeviceRecord = new InsOrderDeviceRecord();
-                insOrderDeviceRecord.setInsOrderId(insSample.getInsOrderId());
-                insOrderDeviceRecord.setDeviceId(deviceId);
-                insOrderDeviceRecord.setSampleCode(order.getEntrustCode());
-                insOrderDeviceRecord.setUseBefore(1);
-                insOrderDeviceRecord.setUseAfter(1);
-                insOrderDeviceRecord.setUsePerson(user.getName());
-                insOrderDeviceRecord.setUsePersonId(user.getId());
-                return insOrderDeviceRecord;
-            }).collect(Collectors.toList());
-
-            insOrderDeviceRecordService.saveBatch(collect);
-
-        }
-
-        // 2.鍒ゆ柇鏄惁鍙栨秷浜嗚澶囦娇鐢�
-        Set<String> repoprNumbers = getDeviceDifference(recordCodeset, deviceCodeSet);
-        if (CollectionUtils.isNotEmpty(repoprNumbers)) {
-            List<Integer> reportDeviceIds = insOrderDeviceRecordMapper.selectDeviceIdsByNumbers(repoprNumbers);
-            insOrderDeviceRecordMapper.delete(Wrappers.<InsOrderDeviceRecord>lambdaQuery()
-                    .in(InsOrderDeviceRecord::getDeviceId, reportDeviceIds)
-                    .eq(InsOrderDeviceRecord::getInsOrderId, insSample.getInsOrderId()));
-        }
-    }
-
-    private static Set<String> getDeviceDifference(Set<String> number1, Set<String> number2) {
-        return number1.stream().filter(s1 -> number2.stream().noneMatch(s2 -> s1.equals(s2)))
-                .collect(Collectors.toSet());
     }
 
 
@@ -1273,7 +1315,7 @@
         boolean directTemplateOrder = isDirectTemplateOrder(orderId);
         List<InsProduct> insProducts;
         if (directTemplateOrder) {
-            List<String> missingExportValues = getMissingTemplateExportValues(orderId);
+            List<String> missingExportValues = getMissingTemplateExportValues(orderId, laboratory);
             if (!missingExportValues.isEmpty()) {
                 throw new ErrorException("妯℃澘涓殑瀵煎嚭鍊间笉鑳戒负绌猴細\n" + String.join("\n", missingExportValues));
             }
@@ -1655,6 +1697,8 @@
             refreshed.setInsOrderId(orderId);
             refreshed.setTemplateId(templateId);
             refreshed.setNumber(standardTemplate == null ? oldSnapshot.getNumber() : standardTemplate.getNumber());
+            refreshed.setStandardRequirement(oldSnapshot == null
+                    ? standardTemplate.getStandardRequirement() : oldSnapshot.getStandardRequirement());
             refreshed.setName(standardTemplate == null ? oldSnapshot.getName() : standardTemplate.getName());
             refreshed.setRemark(standardTemplate == null ? oldSnapshot.getRemark() : standardTemplate.getRemark());
             refreshed.setThing(standardTemplate == null ? oldSnapshot.getThing() : standardTemplate.getThing());
@@ -1665,6 +1709,7 @@
             refreshed.setHumidity(templateHumidityMap.get(templateId));
             // 鍒锋柊妯℃澘缁撴瀯鏃跺繀椤讳繚鐣欐楠岄樁娈靛~鍐欑殑涓氬姟鏁版嵁锛岄伩鍏嶈繘鍏ュ鏍稿悗鍥炴樉涓虹┖銆�
             refreshed.setDetectionTime(oldSnapshot == null ? null : oldSnapshot.getDetectionTime());
+            refreshed.setDetectionEndTime(oldSnapshot == null ? null : oldSnapshot.getDetectionEndTime());
             refreshed.setDetectionPlace(oldSnapshot == null ? null : oldSnapshot.getDetectionPlace());
             refreshed.setInsResult(oldSnapshot == null ? null : oldSnapshot.getInsResult());
             Integer templateSort = templateSortMap.get(templateId);
@@ -1882,9 +1927,17 @@
 
 
         } else {
-            //澶嶆牳涓嶉�氳繃灏嗘妸澶嶆牳鐨勮礋璐d汉鍘绘帀
-            Integer id = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery().eq(InsSampleUser::getInsSampleId, orderId).orderByDesc(InsSampleUser::getId).last("limit 1")).getId();
-            insSampleUserMapper.deleteById(id);
+            // 澶嶆牳涓嶉�氳繃鍙幓鎺夋湰妫�楠屽鏈鎻愪氦鐨勫鏍歌礋璐d汉锛涙寜澶嶆牳浜虹姸鎬佸拰妫�楠屽瀹氫綅锛�
+            // 閬垮厤璇垹鍏朵粬妫�楠屽鐨勮褰曟垨妫�楠屼汉鍛樿褰曘��
+            InsSampleUser reviewerRow = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
+                    .eq(InsSampleUser::getInsSampleId, orderId)
+                    .eq(InsSampleUser::getState, 1)
+                    .eq(InsSampleUser::getSonLaboratory, laboratory)
+                    .orderByDesc(InsSampleUser::getId)
+                    .last("limit 1"));
+            if (reviewerRow != null) {
+                insSampleUserMapper.deleteById(reviewerRow.getId());
+            }
 
             // 褰撳墠瀹℃牳浜�
             Integer currentUserId = SecurityUtils.getUserId().intValue();
@@ -2004,7 +2057,8 @@
         if (Objects.equals(report.getIsRatify(), 1)) {
             throw new ErrorException("宸叉壒鍑嗘姤鍛婁笉鑳介噸鏂扮敓鎴�");
         }
-        if (StringUtils.isNotBlank(report.getUrlS())) {
+        // urlS 鍚屾椂鐢ㄤ簬浜哄伐涓婁紶鍜屽鏍搁〉闈繚瀛樼殑 Word锛涘彧鏈変汉宸ヤ笂浼犻渶瑕佸厛鎵嬪姩鍒囧洖绯荤粺鎶ュ憡銆�
+        if (StringUtils.isNotBlank(report.getUrlS()) && !isBrowserEditedReportUrl(report.getUrlS())) {
             throw new ErrorException("褰撳墠鎶ュ憡宸叉墜鍔ㄤ笂浼狅紝璇峰厛杩樺師涓虹郴缁熸姤鍛婂悗鍐嶉噸鏂扮敓鎴�");
         }
         if (report.getInsOrderId() == null) {
@@ -2048,7 +2102,12 @@
                 .eq(InsReport::getId, reportId)
                 .set(InsReport::getWriteTime, report.getWriteTime())
                 .set(InsReport::getIsPass, report.getIsPass())
+                .set(InsReport::getUrlS, null)
                 .set(InsReport::getTempUrlPdf, "/word/" + tempPdfName));
+    }
+
+    private static boolean isBrowserEditedReportUrl(String url) {
+        return url != null && url.matches("(?i)^/word/(?:edited|reviewed)-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\\.docx$");
     }
 
     private Map<String, Object> buildExistingReportMarks(InsReport report) {
@@ -3613,7 +3672,8 @@
                         .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
                         .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId));
         List<LocalDate> detectionDates = templateSnapshots.stream()
-                .map(InsOrderStandardTemplate::getDetectionTime)
+                .flatMap(snapshot -> java.util.stream.Stream.of(
+                        snapshot.getDetectionTime(), snapshot.getDetectionEndTime()))
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
         String insTime = formatReportTestDate(detectionDates);
@@ -3629,7 +3689,7 @@
         List<Map<String, String>> finalDeviceList = deviceList;
         String finalModelStr = modelStr;
 
-        // 鐩寸粦妯℃澘璁㈠崟娌℃湁 ins_product锛屾娴嬮」鐩�佸崟浣嶅拰缁撴灉鍧囦粠璁㈠崟妯℃澘蹇収涓幏鍙栥��
+        // 鐩寸粦妯℃澘璁㈠崟娌℃湁 ins_product锛屾娴嬮」鐩�佹爣鍑嗚姹傚�煎拰缁撴灉鍧囦粠璁㈠崟妯℃澘蹇収涓幏鍙栥��
         List<Map<String, String>> detectionResultRows = directTemplateOrder
                 ? buildTemplateDetectionResultRows(orderId)
                 : buildDetectionResultRows(samples);
@@ -3811,7 +3871,7 @@
     }
 
     /**
-     * 鏂扮増妫�娴嬫姤鍛婄殑缁撴灉琛ㄥ浐瀹氫负鍥涘垪锛氬簭鍙枫�佹娴嬮」鐩�佸崟浣嶃�佹娴嬬粨鏋溿��
+     * 鏂扮増妫�娴嬨�佹楠屾姤鍛婂叡鐢ㄧ粨鏋滄暟鎹紱鏍囧噯瑕佹眰鍊煎彇鑷師濮嬭褰曟ā鏉块厤缃��
      */
     private List<Map<String, String>> buildDetectionResultRows(List<SampleProductDto> samples) {
         List<Map<String, String>> rows = new ArrayList<>();
@@ -3820,6 +3880,7 @@
         }
 
         boolean multipleSamples = samples.size() > 1;
+        Map<Integer, String> requirementsByTemplate = new HashMap<>();
         int sequence = 1;
         for (SampleProductDto sample : samples) {
             if (CollectionUtils.isEmpty(sample.getInsProduct())) {
@@ -3840,8 +3901,15 @@
 
                 Map<String, String> row = new LinkedHashMap<>();
                 row.put("seq", String.valueOf(sequence++));
-                row.put("itemName", itemName);
+                row.put("itemName", formatReportItemWithUnit(itemName, product.getUnit()));
                 row.put("unit", defaultReportText(product.getUnit(), "/"));
+                String requirement = product.getTemplateId() == null ? null
+                        : requirementsByTemplate.computeIfAbsent(product.getTemplateId(), templateId -> {
+                            StandardTemplate sourceTemplate = standardTemplateService.getById(templateId);
+                            return defaultReportText(sourceTemplate == null ? null
+                                    : sourceTemplate.getStandardRequirement(), "/");
+                        });
+                row.put("standardRequirement", defaultReportText(requirement, "/"));
                 row.put("result", defaultReportText(product.getLastValue(), "/"));
                 row.put("inspectionConclusion", formatInspectionConclusion(product.getInsResult()));
                 rows.add(row);
@@ -3867,7 +3935,8 @@
                 Wrappers.<InsOrderStandardTemplate>lambdaQuery()
                         .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
                         .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId));
-        context.setDetectionDates(snapshots.stream().map(InsOrderStandardTemplate::getDetectionTime)
+        context.setDetectionDates(snapshots.stream().flatMap(snapshot -> java.util.stream.Stream.of(
+                        snapshot.getDetectionTime(), snapshot.getDetectionEndTime()))
                 .filter(Objects::nonNull).distinct().sorted().collect(Collectors.toList()));
         List<Integer> deviceIds = insOrderTemplateDeviceMapper.selectDeviceIdsByOrderId(orderId);
         if (CollectionUtils.isNotEmpty(deviceIds)) {
@@ -3895,6 +3964,12 @@
         List<Map<String, String>> rows = new ArrayList<>();
         int sequence = 1;
         for (InsOrderStandardTemplate snapshot : snapshots) {
+            String standardRequirement = snapshot.getStandardRequirement();
+            // 鍏煎鏂板璇ュ瓧娈靛墠涓嬪崟鐨勬棫璁板綍锛涙湁蹇収鏃跺缁堜互璁㈠崟淇濆瓨鐨勫�间负鍑嗐��
+            if (StringUtils.isBlank(standardRequirement) && snapshot.getTemplateId() != null) {
+                StandardTemplate sourceTemplate = standardTemplateService.getById(snapshot.getTemplateId());
+                standardRequirement = sourceTemplate == null ? null : sourceTemplate.getStandardRequirement();
+            }
             List<TemplateExportCell> exportCells = getTemplateExportCells(snapshot.getThing());
             JSONObject recordValues = StrUtil.isBlank(snapshot.getRecordValues())
                     ? new JSONObject() : JSON.parseObject(snapshot.getRecordValues());
@@ -3913,8 +3988,10 @@
                 row.put("seq", String.valueOf(sequence++));
                 String reportItemName = defaultReportText(itemName,
                         defaultReportText(snapshot.getName(), "妯℃澘ID " + snapshot.getTemplateId()));
-                row.put("itemName", formatExportItemName(reportItemName));
+                row.put("itemName", formatReportItemWithUnit(
+                        formatExportItemName(reportItemName), unit));
                 row.put("unit", defaultReportText(unit, "/"));
+                row.put("standardRequirement", defaultReportText(standardRequirement, "/"));
                 row.put("result", result);
                 row.put("inspectionConclusion", formatInspectionConclusion(snapshot.getInsResult()));
                 rows.add(row);
@@ -4090,6 +4167,14 @@
         return itemName.replaceAll("骞冲潎鍊糪\s*[锛�,]?\\s*", "");
     }
 
+    private static String formatReportItemWithUnit(String itemName, String unit) {
+        if (StringUtils.isBlank(unit) || "/".equals(unit.trim())
+                || itemName.contains(unit.trim())) {
+            return itemName;
+        }
+        return itemName + "锛�" + unit.trim();
+    }
+
     private static String getMapText(Map<String, String> map, String... keys) {
         if (map == null) {
             return null;

--
Gitblit v1.9.3