From 5734b7e1c2fb6e64ddc5956b84c5a125a8c1ea0e Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期二, 20 十月 2026 14:34:03 +0800
Subject: [PATCH] feat(order): 增加直绑模板下单标准库绑定与设备初始化

---
 inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java            |    3 
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsProductServiceImpl.java       |    5 +
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java |   89 ++++++++++++++---
 basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java   |   32 ++++-
 inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java                            |    3 
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java         |  136 +++++++++++++++++++++++++++
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java     |    2 
 7 files changed, 243 insertions(+), 27 deletions(-)

diff --git a/basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java b/basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java
index fe80870..d13456b 100644
--- a/basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java
+++ b/basic-server/src/main/java/com/ruoyi/basic/utils/StandardTemplateInspectionItemParser.java
@@ -13,9 +13,10 @@
 import java.util.List;
 import java.util.Set;
 
-/** 瑙f瀽 Luckysheet 鍘熷璁板綍妯℃澘涓殑鈥滄楠岄」鈥濇爣璁般�� */
+/** 瑙f瀽 Luckysheet 鍘熷璁板綍妯℃澘涓殑鈥滄楠岄」鈥濓紱鏈爣璁版椂鍥為��鍒扳�滃鍑哄�尖�濊銆� */
 public final class StandardTemplateInspectionItemParser {
     private static final String INSPECTION_ITEM_MARK = "妫�楠岄」";
+    private static final String EXPORT_VALUE_MARK = "瀵煎嚭鍊�";
 
     private StandardTemplateInspectionItemParser() {
     }
@@ -34,11 +35,22 @@
         } catch (Exception e) {
             throw new BaseException("鍘熷璁板綍妯℃澘鏍煎紡閿欒");
         }
-        List<TemplateInspectionItemDto> result = new ArrayList<>();
-        Set<Integer> rows = new HashSet<>();
         if (sheets == null) {
             throw new BaseException("鍘熷璁板綍妯℃澘鏍煎紡閿欒");
         }
+        List<TemplateInspectionItemDto> result = parseMarkedCells(sheets, templateId, templateSort,
+                INSPECTION_ITEM_MARK);
+        if (result.isEmpty()) {
+            result = parseMarkedCells(sheets, templateId, templateSort, EXPORT_VALUE_MARK);
+        }
+        result.sort(Comparator.comparing(TemplateInspectionItemDto::getTemplateRowIndex));
+        return result;
+    }
+
+    private static List<TemplateInspectionItemDto> parseMarkedCells(JSONArray sheets, Integer templateId,
+                                                                     Integer templateSort, String mark) {
+        List<TemplateInspectionItemDto> result = new ArrayList<>();
+        Set<Integer> rows = new HashSet<>();
         for (Object sheetObject : sheets) {
             JSONObject sheet = (JSONObject) sheetObject;
             JSONArray cells = sheet.getJSONArray("celldata");
@@ -48,16 +60,19 @@
             for (Object cellObject : cells) {
                 JSONObject cell = (JSONObject) cellObject;
                 JSONObject value = cell.getJSONObject("v");
-                if (value == null || !isInspectionItem(value)) {
+                if (value == null || !hasMark(value, mark)) {
                     continue;
                 }
                 Integer row = cell.getInteger("r");
                 String item = getCellText(value);
                 if (row == null || !StringUtils.hasText(item)) {
-                    throw new BaseException("鈥滄楠岄」鈥濇爣璁版墍鍦ㄥ崟鍏冩牸蹇呴』濉啓妫�楠岄」鍚嶇О");
+                    throw new BaseException("鈥�" + mark + "鈥濇爣璁版墍鍦ㄥ崟鍏冩牸蹇呴』濉啓妫�楠岄」鍚嶇О");
                 }
                 if (!rows.add(row)) {
-                    throw new BaseException("鍚屼竴妯℃澘琛屽彧鑳介厤缃竴涓�滄楠岄」鈥濇爣璁�");
+                    if (EXPORT_VALUE_MARK.equals(mark)) {
+                        continue;
+                    }
+                    throw new BaseException("鍚屼竴妯℃澘琛屽彧鑳介厤缃竴涓��" + mark + "鈥濇爣璁�");
                 }
                 TemplateInspectionItemDto dto = new TemplateInspectionItemDto();
                 dto.setTemplateId(templateId);
@@ -67,7 +82,6 @@
                 result.add(dto);
             }
         }
-        result.sort(Comparator.comparing(TemplateInspectionItemDto::getTemplateRowIndex));
         return result;
     }
 
@@ -101,8 +115,8 @@
         return richText.toString();
     }
 
-    private static boolean isInspectionItem(JSONObject value) {
+    private static boolean hasMark(JSONObject value, String mark) {
         JSONObject ps = value.getJSONObject("ps");
-        return ps != null && INSPECTION_ITEM_MARK.equals(ps.getString("value"));
+        return ps != null && mark.equals(ps.getString("value"));
     }
 }
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
index 56cf817..a74b48b 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrder.java
@@ -42,6 +42,9 @@
     @Schema(description = "璐ㄩ噺鐩戞帶璁″垝鏄庣粏ID")
     private Integer qualityMonitorDetailsId;
 
+    @Schema(description = "鏂拌仛鐩寸粦妯℃澘涓嬪崟鏃堕�夋嫨鐨勬爣鍑嗗簱浜岀骇鑺傜偣ID")
+    private Integer standardTreeId;
+
     @Schema(description = "涓嬪崟瀹㈡埛")
     private String custom;
 
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java
index 395a0cc..cf12774 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java
@@ -64,6 +64,9 @@
     @Schema(description = "鍘熷璁板綍宸插~鍐欏崟鍏冩牸锛屾寜鍧愭爣淇濆瓨")
     private String recordValues;
 
+    @Schema(description = "榛樿璁惧鏄惁宸插湪棣栨杩涘叆妫�楠屼换鍔℃椂鍒濆鍖栵細0鍚︼紝1鏄�")
+    private Integer deviceDefaultsInitialized;
+
     @Schema(description = "璇ユā鏉挎楠屾椂鐨勬俯搴�")
     private String temperature;
 
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 9e811fd..40dcb48 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
@@ -1659,6 +1659,8 @@
             refreshed.setRemark(standardTemplate == null ? oldSnapshot.getRemark() : standardTemplate.getRemark());
             refreshed.setThing(standardTemplate == null ? oldSnapshot.getThing() : standardTemplate.getThing());
             refreshed.setRecordValues(templateRecordValuesMap.get(templateId));
+            refreshed.setDeviceDefaultsInitialized(oldSnapshot == null ? 1
+                    : oldSnapshot.getDeviceDefaultsInitialized());
             refreshed.setTemperature(templateTemperatureMap.get(templateId));
             refreshed.setHumidity(templateHumidityMap.get(templateId));
             // 鍒锋柊妯℃澘缁撴瀯鏃跺繀椤讳繚鐣欐楠岄樁娈靛~鍐欑殑涓氬姟鏁版嵁锛岄伩鍏嶈繘鍏ュ鏍稿悗鍥炴樉涓虹┖銆�
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
index a79bfcd..f4b1b84 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
@@ -581,6 +581,9 @@
                         .thenComparing(item -> item.getTemplateRowIndex() == null
                                 ? Integer.MAX_VALUE : item.getTemplateRowIndex()))
                 .collect(Collectors.toList());
+        if (templateItems.isEmpty()) {
+            throw new ErrorException("鎵�閫夊師濮嬭褰曟ā鏉挎湭閰嶇疆妫�楠岄」鎴栧鍑哄�硷紝涓嶈兘涓嬪崟");
+        }
 
         StandardMethod standardMethod = standardMethodService.getById(standard.getStandardMethodId());
         if (standardMethod == null || StringUtils.isBlank(standardMethod.getCode())) {
@@ -596,6 +599,7 @@
         order.setIsExemption(0);
         order.setFactory(null);
         order.setLaboratory(standard.getLaboratory());
+        order.setStandardTreeId(dto.getStandardTreeId());
         order.setSampleType(null);
         order.setSample(standardCode);
         order.setPrepareUserEn(null);
@@ -740,6 +744,9 @@
                 .sorted(Comparator.comparing((TemplateInspectionItemDto item) -> templateSortMap.get(item.getTemplateId()))
                         .thenComparing(item -> item.getTemplateRowIndex() == null ? Integer.MAX_VALUE : item.getTemplateRowIndex()))
                 .collect(Collectors.toList());
+        if (templateItems.isEmpty()) {
+            throw new ErrorException("鎵�閫夊師濮嬭褰曟ā鏉挎湭閰嶇疆妫�楠岄」鎴栧鍑哄�硷紝涓嶈兘涓嬪崟");
+        }
         StandardMethod standardMethod = standardMethodService.getById(standard.getStandardMethodId());
         if (standardMethod == null || StringUtils.isBlank(standardMethod.getCode())) {
             throw new ErrorException("鏍囧噯缂栧彿涓嶅瓨鍦�");
@@ -754,6 +761,7 @@
         order.setIsExemption(currentOrder.getIsExemption());
         order.setFactory(null);
         order.setLaboratory(standard.getLaboratory());
+        order.setStandardTreeId(dto.getStandardTreeId());
         order.setSampleType(null);
         order.setSample(standardCode);
         order.setPrepareUserEn(null);
@@ -839,6 +847,7 @@
             snapshot.setRemark(template.getRemark());
             snapshot.setThing(template.getThing());
             snapshot.setSort(selection.getSort());
+            snapshot.setDeviceDefaultsInitialized(0);
             insOrderStandardTemplateMapper.insert(snapshot);
 
             StandardTreeTemplateBindingVo binding = bindingMap.get(selection.getTemplateId());
@@ -929,7 +938,9 @@
                         .eq(StandardMethod::getCode, insOrder.getSample())
                         .select(StandardMethod::getId)).stream()
                 .map(StandardMethod::getId).collect(Collectors.toList());
-        if (!methodIds.isEmpty() && !orderTemplateIds.isEmpty()) {
+        if (insOrder.getStandardTreeId() != null) {
+            map.put("standardTreeId", insOrder.getStandardTreeId());
+        } else if (!methodIds.isEmpty() && !orderTemplateIds.isEmpty()) {
             List<StandardTree> candidates = standardTreeService.list(Wrappers.<StandardTree>lambdaQuery()
                     .in(StandardTree::getStandardMethodId, methodIds)
                     .isNull(StandardTree::getSampleType)
@@ -1053,8 +1064,10 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Map<String, Object> getInsOrderAndSample(Integer id, String laboratory) {
         Map<String, Object> map = new HashMap<>();
+        initializeTemplateDevicesOnFirstOpen(id);
 //        InsOrder insOrder = insOrderMapper.selectById(id);
         IfsOrderVO ifsOrderVO = insOrderMapper.selectOrderInfoById(id);
         Map<Integer, List<Integer>> templateDeviceIds = insOrderTemplateDeviceMapper.selectList(
@@ -1097,6 +1110,127 @@
         return map;
     }
 
+    /** 棣栨鎵撳紑妫�楠屼换鍔℃椂锛屽皢浠嶄负绌虹殑妯℃澘璁惧浠庡搴旀爣鍑嗚ˉ鍏ヨ鍗曘�� */
+    private void initializeTemplateDevicesOnFirstOpen(Integer orderId) {
+        InsOrder order = insOrderMapper.selectById(orderId);
+        if (order == null || !DIRECT_TEMPLATE_LABORATORY.equals(order.getLaboratory())
+                || !Objects.equals(order.getTypeSource(), -1)
+                || !Objects.equals(order.getState(), 1)
+                || "QUALITY_MONITOR".equals(order.getTaskSource())) {
+            return;
+        }
+        List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateMapper.selectList(
+                Wrappers.<InsOrderStandardTemplate>lambdaQuery()
+                        .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
+                        .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId)
+                        .last("FOR UPDATE"));
+        if (snapshots.isEmpty() || snapshots.stream().allMatch(
+                snapshot -> Objects.equals(snapshot.getDeviceDefaultsInitialized(), 1))) {
+            return;
+        }
+
+        Set<Integer> existingTemplateIds = insOrderTemplateDeviceMapper.selectList(
+                Wrappers.<InsOrderTemplateDevice>lambdaQuery()
+                        .eq(InsOrderTemplateDevice::getInsOrderId, orderId))
+                .stream().map(InsOrderTemplateDevice::getTemplateId)
+                .filter(Objects::nonNull).collect(Collectors.toSet());
+        boolean inspectionStarted = order.getFirstInspectDate() != null
+                || (order.getInsState() != null && order.getInsState() > 0)
+                || snapshots.stream().anyMatch(snapshot -> StringUtils.isNotBlank(snapshot.getRecordValues())
+                        || snapshot.getDetectionTime() != null || snapshot.getTemperature() != null
+                        || snapshot.getDetectionPlace() != null);
+        Map<Integer, List<Integer>> defaults = inspectionStarted ? Collections.emptyMap()
+                : findStandardDeviceDefaults(order, snapshots);
+
+        for (InsOrderStandardTemplate snapshot : snapshots) {
+            if (Objects.equals(snapshot.getDeviceDefaultsInitialized(), 1)) {
+                continue;
+            }
+            Integer templateId = snapshot.getTemplateId();
+            if (!inspectionStarted && !existingTemplateIds.contains(templateId)
+                    && defaults.containsKey(templateId)) {
+                List<Integer> deviceIds = defaults.get(templateId);
+                for (int index = 0; index < deviceIds.size(); index++) {
+                    InsOrderTemplateDevice relation = new InsOrderTemplateDevice();
+                    relation.setInsOrderId(orderId);
+                    relation.setTemplateId(templateId);
+                    relation.setDeviceId(deviceIds.get(index));
+                    relation.setSort(index);
+                    insOrderTemplateDeviceMapper.insert(relation);
+                }
+            }
+            // 鏃犳硶鍞竴纭畾鏉ユ簮鏃朵篃鍙皾璇曡繖涓�娆★紝閬垮厤浠ュ悗鏍囧噯搴撹皟鏁存椂鎰忓鏀瑰姩璁㈠崟銆�
+            insOrderStandardTemplateMapper.update(null,
+                    Wrappers.<InsOrderStandardTemplate>lambdaUpdate()
+                            .eq(InsOrderStandardTemplate::getId, snapshot.getId())
+                            .set(InsOrderStandardTemplate::getDeviceDefaultsInitialized, 1));
+        }
+    }
+
+    private Map<Integer, List<Integer>> findStandardDeviceDefaults(InsOrder order,
+            List<InsOrderStandardTemplate> snapshots) {
+        Set<Integer> templateIds = snapshots.stream().map(InsOrderStandardTemplate::getTemplateId)
+                .filter(Objects::nonNull).collect(Collectors.toSet());
+        Integer standardTreeId = order.getStandardTreeId();
+        if (standardTreeId == null && StringUtils.isNotBlank(order.getSample()) && !templateIds.isEmpty()) {
+            List<Integer> methodIds = standardMethodService.list(Wrappers.<StandardMethod>lambdaQuery()
+                            .eq(StandardMethod::getCode, order.getSample())
+                            .select(StandardMethod::getId)).stream()
+                    .map(StandardMethod::getId).collect(Collectors.toList());
+            if (!methodIds.isEmpty()) {
+                List<StandardTree> candidates = standardTreeService.list(Wrappers.<StandardTree>lambdaQuery()
+                        .in(StandardTree::getStandardMethodId, methodIds)
+                        .eq(StandardTree::getLaboratory, order.getLaboratory())
+                        .isNotNull(StandardTree::getSample)
+                        .isNull(StandardTree::getSampleType)
+                        .isNull(StandardTree::getModel));
+                List<StandardTree> matches = candidates.stream()
+                        .filter(tree -> StringUtils.isNotBlank(tree.getSample()))
+                        .filter(tree -> {
+                            Set<Integer> boundIds = standardTreeService.selectTemplateBindings(tree.getId()).stream()
+                                    .map(StandardTreeTemplateBindingVo::getTemplateId).collect(Collectors.toSet());
+                            return boundIds.containsAll(templateIds);
+                        }).collect(Collectors.toList());
+                if (matches.size() == 1) {
+                    standardTreeId = matches.get(0).getId();
+                } else {
+                    List<StandardTree> exact = matches.stream().filter(tree ->
+                            standardTreeService.selectTemplateBindings(tree.getId()).stream()
+                                    .map(StandardTreeTemplateBindingVo::getTemplateId)
+                                    .collect(Collectors.toSet()).equals(templateIds))
+                            .collect(Collectors.toList());
+                    if (exact.size() == 1) {
+                        standardTreeId = exact.get(0).getId();
+                    }
+                }
+            }
+        }
+        if (standardTreeId == null) {
+            return Collections.emptyMap();
+        }
+        StandardTree standard = standardTreeService.getById(standardTreeId);
+        if (standard == null || StringUtils.isBlank(standard.getSample())
+                || !Objects.equals(standard.getLaboratory(), order.getLaboratory())
+                || standard.getSampleType() != null || standard.getModel() != null) {
+            return Collections.emptyMap();
+        }
+        if (order.getStandardTreeId() == null) {
+            insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate()
+                    .eq(InsOrder::getId, order.getId())
+                    .isNull(InsOrder::getStandardTreeId)
+                    .set(InsOrder::getStandardTreeId, standardTreeId));
+        }
+        List<StandardTreeTemplateBindingVo> bindings = standardTreeService.selectTemplateBindings(standardTreeId);
+        Map<Integer, List<Integer>> defaults = new HashMap<>();
+        for (StandardTreeTemplateBindingVo binding : bindings) {
+            if (templateIds.contains(binding.getTemplateId())) {
+                defaults.put(binding.getTemplateId(), binding.getDeviceIds() == null
+                        ? Collections.emptyList() : binding.getDeviceIds());
+            }
+        }
+        return defaults;
+    }
+
     @Override
     public IPage<SampleProductDto2> selectSampleAndProductByOrderId(IPage<SampleProductDto2> page, SampleProductDto2 sampleProductDto) {
         IPage<SampleProductDto2> productDto2IPage = insOrderMapper.selectSampleAndProductByOrderId(page,
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsProductServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsProductServiceImpl.java
index 8f642dc..ed0e8e7 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsProductServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsProductServiceImpl.java
@@ -94,6 +94,11 @@
                                         InsOrderStandardTemplate::getInsResult, dto.getInsResult()));
             }
             if (dto.isDeviceIdsPresent()) {
+                // 鎵嬪姩閫夋嫨鎴栨竻绌洪兘瑙嗕负宸插垵濮嬪寲锛屽悗缁繘鍏ヤ换鍔′笉寰楀啀娆″鐢ㄦ爣鍑嗗簱榛樿鍊笺��
+                insOrderStandardTemplateMapper.update(null,
+                        Wrappers.<InsOrderStandardTemplate>lambdaUpdate()
+                                .eq(InsOrderStandardTemplate::getId, snapshot.getId())
+                                .set(InsOrderStandardTemplate::getDeviceDefaultsInitialized, 1));
                 insOrderTemplateDeviceMapper.delete(
                         Wrappers.<InsOrderTemplateDevice>lambdaQuery()
                                 .eq(InsOrderTemplateDevice::getInsOrderId, dto.getId())
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java
index 5337574..37b2953 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsSampleReceiptServiceImpl.java
@@ -4,46 +4,44 @@
 import com.alibaba.excel.ExcelWriter;
 import com.alibaba.excel.write.metadata.WriteSheet;
 import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.dto.TemplateInspectionItemDto;
+import com.ruoyi.basic.utils.StandardTemplateInspectionItemParser;
+import com.ruoyi.common.utils.GZipUtil;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.exception.ErrorException;
 import com.ruoyi.inspect.dto.SampleReceiptActionDto;
 import com.ruoyi.inspect.dto.SampleReceiptPageDto;
 import com.ruoyi.inspect.dto.SampleReceiptQueryDto;
-import com.ruoyi.inspect.mapper.InsOrderMapper;
-import com.ruoyi.inspect.mapper.InsOrderStandardTemplateMapper;
-import com.ruoyi.inspect.mapper.InsProductMapper;
-import com.ruoyi.inspect.mapper.InsSampleMapper;
-import com.ruoyi.inspect.mapper.InsSampleReceiptMapper;
-import com.ruoyi.inspect.mapper.InsSampleUserMapper;
-import com.ruoyi.inspect.pojo.InsOrder;
-import com.ruoyi.inspect.pojo.InsOrderStandardTemplate;
-import com.ruoyi.inspect.pojo.InsProduct;
-import com.ruoyi.inspect.pojo.InsSample;
-import com.ruoyi.inspect.pojo.InsSampleReceipt;
-import com.ruoyi.inspect.pojo.InsSampleUser;
+import com.ruoyi.inspect.mapper.*;
+import com.ruoyi.inspect.pojo.*;
 import com.ruoyi.inspect.service.InsOrderService;
 import com.ruoyi.inspect.service.InsOrderStateService;
 import com.ruoyi.inspect.service.InsSampleReceiptService;
 import com.ruoyi.system.mapper.UserMapper;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import jakarta.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.net.URLEncoder;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 @AllArgsConstructor
 public class InsSampleReceiptServiceImpl extends ServiceImpl<InsSampleReceiptMapper, InsSampleReceipt>
         implements InsSampleReceiptService {
+    private static final String DIRECT_TEMPLATE_LABORATORY = "鏂拌仛";
+
     private final InsSampleReceiptMapper receiptMapper;
     private final InsOrderMapper insOrderMapper;
     private final InsOrderStandardTemplateMapper insOrderStandardTemplateMapper;
@@ -55,13 +53,17 @@
     private final UserMapper userMapper;
 
     @Override
-    public com.baomidou.mybatisplus.core.metadata.IPage<SampleReceiptPageDto> page(Page<?> page, SampleReceiptQueryDto query) {
-        return receiptMapper.selectPage(page, query);
+    public IPage<SampleReceiptPageDto> page(Page<?> page, SampleReceiptQueryDto query) {
+        IPage<SampleReceiptPageDto> result = receiptMapper.selectPage(page, query);
+        result.getRecords().forEach(this::fillInspectionItemsFromSnapshots);
+        return result;
     }
 
     @Override
     public SampleReceiptPageDto detail(Integer id) {
-        return receiptMapper.selectDetail(id);
+        SampleReceiptPageDto detail = receiptMapper.selectDetail(id);
+        fillInspectionItemsFromSnapshots(detail);
+        return detail;
     }
 
     @Override
@@ -91,7 +93,26 @@
         Long productCount = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
                 .eq(InsProduct::getInsSampleId, sample.getId()).eq(InsProduct::getState, 1));
         if (productCount == 0) {
-            throw new ErrorException("璇ュ鎵樻湭缁戝畾妫�楠岄」鐩紝涓嶈兘鎻愪氦妫�楠�");
+            List<TemplateInspectionItemDto> items = getSnapshotInspectionItems(order.getId());
+            if (items.isEmpty()) {
+                throw new ErrorException("璁㈠崟鍘熷璁板綍妯℃澘鏈厤缃楠岄」鎴栧鍑哄�硷紝涓嶈兘鎻愪氦妫�楠�");
+            }
+            int sort = 0;
+            for (TemplateInspectionItemDto item : items) {
+                InsProduct product = new InsProduct();
+                product.setInsSampleId(sample.getId());
+                product.setInspectionItem(item.getInspectionItem());
+                product.setInspectionItemClass("");
+                product.setInspectionItemSubclass("");
+                product.setLaboratory(order.getLaboratory());
+                product.setSample(order.getSample());
+                product.setTemplateId(item.getTemplateId());
+                product.setTemplateRowIndex(item.getTemplateRowIndex());
+                product.setSonLaboratory(DIRECT_TEMPLATE_LABORATORY);
+                product.setState(1);
+                product.setSort(sort++);
+                insProductMapper.insert(product);
+            }
         }
         if (userMapper.selectById(dto.getMainInspectorId()) == null) {
             throw new ErrorException("涓绘楠屼汉涓嶅瓨鍦ㄦ垨宸插仠鐢�");
@@ -160,9 +181,43 @@
         }
     }
 
+    private List<TemplateInspectionItemDto> getSnapshotInspectionItems(Integer orderId) {
+        List<InsOrderStandardTemplate> snapshots = insOrderStandardTemplateMapper.selectList(
+                Wrappers.<InsOrderStandardTemplate>lambdaQuery()
+                        .eq(InsOrderStandardTemplate::getInsOrderId, orderId)
+                        .orderByAsc(InsOrderStandardTemplate::getSort, InsOrderStandardTemplate::getId));
+        List<TemplateInspectionItemDto> items = new ArrayList<>();
+        for (InsOrderStandardTemplate snapshot : snapshots) {
+            String thing = snapshot.getThing();
+            try {
+                thing = GZipUtil.uncompress(thing);
+            } catch (RuntimeException ignored) {
+                // 鍏煎鏈帇缂╃殑鍘嗗彶妯℃澘蹇収銆�
+            }
+            items.addAll(StandardTemplateInspectionItemParser.parse(
+                    snapshot.getTemplateId(), snapshot.getSort(), thing));
+        }
+        return items;
+    }
+
+    private void fillInspectionItemsFromSnapshots(SampleReceiptPageDto row) {
+        if (row == null || row.getOrderId() == null || StringUtils.isNotBlank(row.getInspectionItem())) {
+            return;
+        }
+        try {
+            String names = getSnapshotInspectionItems(row.getOrderId()).stream()
+                    .map(TemplateInspectionItemDto::getInspectionItem)
+                    .distinct().collect(Collectors.joining("\n"));
+            row.setInspectionItem(names);
+        } catch (RuntimeException ignored) {
+            // 鍒楄〃浠嶅彲鏌ョ湅锛涙彁浜ゆ楠屾椂浼氳繑鍥炲叿浣撶殑妯℃澘瑙f瀽閿欒銆�
+        }
+    }
+
     @Override
     public void export(SampleReceiptQueryDto query, HttpServletResponse response) {
         List<SampleReceiptPageDto> list = receiptMapper.selectExportList(query);
+        list.forEach(this::fillInspectionItemsFromSnapshots);
         response.setContentType("application/vnd.ms-excel");
         response.setCharacterEncoding("UTF-8");
         try {

--
Gitblit v1.9.3