From 51786b723d0a91d11476776d9ce50af7994dc4bd Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期三, 23 九月 2026 15:58:53 +0800
Subject: [PATCH] feat(inspect): 完善检验订单状态管理和样品接收流程

---
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java |  169 ++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 133 insertions(+), 36 deletions(-)

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 d7c0021..e1bc8a1 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
@@ -57,6 +57,7 @@
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
@@ -107,6 +108,8 @@
     private StandardTemplateService standardTemplateService;
     private InsOrderStandardTemplateMapper insOrderStandardTemplateMapper;
     private InsOrderTemplateDeviceMapper insOrderTemplateDeviceMapper;
+    private InsSampleReceiptMapper insSampleReceiptMapper;
+    private ApplicationEventPublisher applicationEventPublisher;
 
 
 
@@ -120,7 +123,10 @@
             isOrderAll = "1";
             sampleOrderDto.setState(null);
         }
-        return insOrderMapper.selectInsOrderPage(page, QueryWrappers.queryWrappers(sampleOrderDto), laboratory, isOrderAll);
+        // 妫�楠屼腑锛氭柊鑱氫笅鍗曞厤瀹℃牳鍗冲彈鐞嗭紝闇�鏍峰搧鎺ユ敹鎻愪氦鍚庯紙ins_sample_receipt.status=1锛夋墠灞曠ず
+        String receiptSubmitted = sampleOrderDto.getState() != null && sampleOrderDto.getState() == 1 ? "1" : null;
+        return insOrderMapper.selectInsOrderPage(page, QueryWrappers.queryWrappers(sampleOrderDto), laboratory,
+                isOrderAll, receiptSubmitted);
     }
 
 
@@ -175,13 +181,17 @@
         }
 
         if (userId != null) {
-            InsSampleUser insSampleUser = new InsSampleUser();
-            insSampleUser.setState(0);
-            insSampleUser.setUserId(userId);
-            insSampleUser.setInsSampleId(orderId);
-            insSampleUser.setSonLaboratory(directTemplateOrder
-                    ? DIRECT_TEMPLATE_LABORATORY : sonLaboratory);
-            insSampleUserMapper.insert(insSampleUser);
+            Set<String> assignedLaboratories = StringUtils.isBlank(sonLaboratory)
+                    ? taskLaboratories
+                    : Collections.singleton(sonLaboratory);
+            for (String laboratory : assignedLaboratories) {
+                InsSampleUser insSampleUser = new InsSampleUser();
+                insSampleUser.setState(0);
+                insSampleUser.setUserId(userId);
+                insSampleUser.setInsSampleId(orderId);
+                insSampleUser.setSonLaboratory(laboratory);
+                insSampleUserMapper.insert(insSampleUser);
+            }
         }
 
         // 鍒ゆ柇璁㈠崟鏈夋病鏈夌粦瀹氭娊鏍疯鍒�
@@ -364,6 +374,15 @@
                 }
             }
         });
+        // 涓嬪崟鏃剁敓鎴愬鎵樼紪鍙峰苟鏍¢獙鍞竴鎬э紱瀛e害妫�楠屽鐢ㄨ繘鍘傛楠岀紪鍙凤紝鐣欏緟瀹℃牳澶勭悊銆�
+        if (!InsOrderTypeConstants.QUARTERLY_TEST.equals(insOrder.getOrderType())) {
+            String entrustCode = buildEntrustCode(insOrder, Collections.emptyList());
+            assertEntrustCodeUnique(entrustCode, insOrder.getId());
+            insOrder.setEntrustCode(entrustCode);
+            insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate()
+                    .eq(InsOrder::getId, insOrder.getId())
+                    .set(InsOrder::getEntrustCode, entrustCode));
+        }
         //鍘熸潗鏂欎笅鍗曟垨澶栬喘鎴愬搧涓嬪崟
         if (Objects.nonNull(insOrder.getTypeSource())&&Objects.nonNull(insOrder.getIfsInventoryId())) {
             // 濮旀墭浜哄氨鏄姤妫�浜�, 鐢熶骇鍗曚綅灏辨槸渚涘簲鍟嗗崟浣�
@@ -403,9 +422,7 @@
             // 瀹℃牳妫�楠屽崟
             upInsOrderOfState(insOrder);
 
-            // 鍒嗛厤妫�楠屼汉
-            String sonLaboratory = insOrder.getTypeSource().equals(1)?"鍘熸潗鏂�":"鎴愬搧瀹為獙瀹�";
-            upInsOrder(insOrder.getId(), null, appointed != null ? appointed.toString() : null, SecurityUtils.getUserId().intValue(), sonLaboratory);
+            // 瀹℃牳閫氳繃鍚庝粎杩涘叆鏍峰搧鎺ユ敹锛涚敱鏍峰搧鎺ユ敹椤甸潰閫夋嫨涓绘楠屼汉鍚庡啀鍒涘缓妫�楠屼换鍔°��
 
             //鏄惁涓哄師鏉愭枡涓嬪崟
             if(insOrder.getTypeSource().equals(1)){
@@ -468,6 +485,24 @@
         if (StringUtils.isBlank(sampleCode) || sampleCode.length() < 2) {
             throw new ErrorException("鏍峰搧缂栧彿涓嶈兘涓虹┖涓斾笉鑳藉皯浜�2浣�");
         }
+        // 濮旀墭瑕佹眰瀛楁鏍¢獙锛氬洓缁勫崟閫夊繀閫夛紝鍒嗗寘/蹇�掕仈鍔ㄥ繀濉�
+        InsOrder reqOrder = dto.getInsOrder();
+        if (reqOrder.getSubcontractType() == null || reqOrder.getSampleDisposal() == null
+                || reqOrder.getResultEvaluation() == null || reqOrder.getReportDelivery() == null) {
+            throw new ErrorException("璇烽�夋嫨鍒嗗寘鍐呭銆佹牱鍝佸缃�佸缁撴灉璇勪环鍜屾姤鍛婁氦浠樻柟寮�");
+        }
+        if (Integer.valueOf(1).equals(reqOrder.getSubcontractType())
+                && StringUtils.isBlank(reqOrder.getSubcontractCompany())) {
+            throw new ErrorException("鍒嗗寘鍐呭涓烘湁鏃讹紝鍒嗗寘鍗曚綅淇℃伅涓嶈兘涓虹┖");
+        }
+        if (Integer.valueOf(2).equals(reqOrder.getReportDelivery())) {
+            if (StringUtils.isBlank(reqOrder.getReportAddress())) {
+                throw new ErrorException("鎶ュ憡浜や粯鏂瑰紡涓哄揩閫掓椂锛屾姤鍛婂瘎閫佸湴鍧�涓嶈兘涓虹┖");
+            }
+            if (StringUtils.isBlank(reqOrder.getReportReceiver())) {
+                throw new ErrorException("鎶ュ憡浜や粯鏂瑰紡涓哄揩閫掓椂锛屾敹浠朵汉鍙婄數璇濅笉鑳戒负绌�");
+            }
+        }
         StandardTree standard = standardTreeService.getById(dto.getStandardTreeId());
         if (standard == null || StringUtils.isBlank(standard.getSample())
                 || standard.getSampleType() != null || standard.getModel() != null) {
@@ -528,7 +563,9 @@
 
         InsOrder order = dto.getInsOrder();
         order.setId(null);
-        order.setState(0);
+        // 鏂拌仛涓嬪崟鍏嶅鏍革細鐩存帴鍙楃悊锛屼笅鍗曞嵆娴佽浆鍒版牱鍝佹帴鏀�
+        order.setState(1);
+        order.setExamineTime(LocalDateTime.now());
         order.setIsExemption(0);
         order.setFactory(null);
         order.setLaboratory(standard.getLaboratory());
@@ -540,6 +577,14 @@
         // 鏂拌仛璁㈠崟鐨勭幆澧冩潯浠剁敱妫�楠屼换鍔″~鍐欙紝閬垮厤涓嬪崟妯℃澘鎴栨祻瑙堝櫒缂撳瓨甯﹀叆鏃у�笺��
         order.setTemperature(null);
         order.setHumidity(null);
+        // 鏈懡涓仈鍔ㄦ潯浠舵椂娓呯┖瀵瑰簲鏂囨湰瀛楁锛岄伩鍏嶆ā鏉垮揩鐓ф垨娴忚鍣ㄧ紦瀛樺甫鍏ユ棫鍊笺��
+        if (!Integer.valueOf(1).equals(order.getSubcontractType())) {
+            order.setSubcontractCompany(null);
+        }
+        if (!Integer.valueOf(2).equals(order.getReportDelivery())) {
+            order.setReportAddress(null);
+            order.setReportReceiver(null);
+        }
         insOrderMapper.insert(order);
 
         InsSample sample = new InsSample();
@@ -573,11 +618,23 @@
             product.setSort(productSort++);
             insProductMapper.insert(product);
         }
-        saveTemplateSnapshots(order.getId(), selections);
+        saveTemplateSnapshots(order.getId(), selections, bindingMap);
+
+        // 涓嬪崟鏃剁敓鎴愬鎵樼紪鍙峰苟鏍¢獙鍞竴鎬э紝閲嶅鍒欐彁绀猴紝閬垮厤鐣欏埌瀹℃牳鎵嶆姤閿欍��
+        String entrustCode = buildEntrustCode(order, Collections.singletonList(sample));
+        assertEntrustCodeUnique(entrustCode, order.getId());
+        insOrderMapper.update(null, Wrappers.<InsOrder>lambdaUpdate()
+                .eq(InsOrder::getId, order.getId())
+                .set(InsOrder::getEntrustCode, entrustCode));
+        // 鍏嶅鏍稿悗鐢变笅鍗曠敓鎴愬緟鎺ユ敹鐨勬牱鍝佹帴鏀惰褰曪紝涓绘楠屼汉浠嶅湪鏍峰搧鎺ユ敹椤甸潰閫夋嫨鍚庢墠鍒涘缓妫�楠屼换鍔�
+        insSampleReceiptMapper.insertIgnore(order.getId(), sample.getId());
+        // 鍚屼簨鍔″唴鍙戝竷涓嬪崟浜嬩欢锛岀敱 cnas-process 鑷姩鐢熸垚妫�楠屽鎵樺崟锛涚洃鍚櫒寮傚父浼氳繛甯︿笅鍗曞洖婊�
+        applicationEventPublisher.publishEvent(new com.ruoyi.inspect.event.NewJuOrderPlacedEvent(order.getId()));
         return order.getId();
     }
 
-    private void saveTemplateSnapshots(Integer orderId, List<OrderTemplateSelectionDto> selections) {
+    private void saveTemplateSnapshots(Integer orderId, List<OrderTemplateSelectionDto> selections,
+                                       Map<Integer, StandardTreeTemplateBindingVo> bindingMap) {
         for (OrderTemplateSelectionDto selection : selections) {
             StandardTemplate template = standardTemplateService.getById(selection.getTemplateId());
             if (template == null) {
@@ -592,6 +649,18 @@
             snapshot.setThing(template.getThing());
             snapshot.setSort(selection.getSort());
             insOrderStandardTemplateMapper.insert(snapshot);
+
+            StandardTreeTemplateBindingVo binding = bindingMap.get(selection.getTemplateId());
+            List<Integer> deviceIds = binding == null || binding.getDeviceIds() == null
+                    ? Collections.emptyList() : binding.getDeviceIds();
+            for (int index = 0; index < deviceIds.size(); index++) {
+                InsOrderTemplateDevice relation = new InsOrderTemplateDevice();
+                relation.setInsOrderId(orderId);
+                relation.setTemplateId(selection.getTemplateId());
+                relation.setDeviceId(deviceIds.get(index));
+                relation.setSort(index);
+                insOrderTemplateDeviceMapper.insert(relation);
+            }
         }
     }
 
@@ -672,33 +741,16 @@
      * @return
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int upInsOrderOfState(InsOrder insOrder) {
         insOrder.setExamineTime(LocalDateTime.now());
         if (insOrder.getState() == 1) {
-            //瀹℃牳閫氳繃鎵嶄細鐢熸垚濮旀墭缂栧彿
+            //濮旀墭缂栧彿宸插湪涓嬪崟鏃剁敓鎴愬苟鏍¢獙鍞竴鎬э紝瀹℃牳鏃跺鐢紱鍘嗗彶/瀛e害妫�楠岃鍗曞厹搴曠敓鎴愩��
             InsOrder order = this.getById(insOrder.getId());
             List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery()
                     .eq(InsSample::getInsOrderId, insOrder.getId())
                     .orderByAsc(InsSample::getId));
-            // 濮旀墭缂栧彿鎸夐�佹牱鏃ユ湡鐢熸垚锛涙柊鑱氬崟鏍峰搧璁㈠崟鐨勬湯涓や綅鍙栨牱鍝佺紪鍙锋湯涓や綅銆�
-            // 鍘嗗彶/澶栭儴璁㈠崟鏈~鍐欓�佹牱鏃ユ湡鏃跺洖閫�鍒板綋澶╋紝閬垮厤褰卞搷鍘熸湁娴佺▼銆�
-            LocalDate entrustDate = order.getSampleDate() == null ? LocalDate.now() : order.getSampleDate();
-            String entrustCodePrefix = "LMSY-"
-                    + entrustDate.format(DateTimeFormatter.BASIC_ISO_DATE)
-                    + "-";
-            String no;
-            if (isDirectTemplateOrder(order, insSamples)) {
-                String sampleCode = insSamples.get(0).getSampleCode();
-                if (StringUtils.isBlank(sampleCode) || sampleCode.trim().length() < 2) {
-                    throw new ErrorException("鏍峰搧缂栧彿涓嶈兘涓虹┖涓斾笉鑳藉皯浜�2浣�");
-                }
-                sampleCode = sampleCode.trim();
-                no = entrustCodePrefix + sampleCode.substring(sampleCode.length() - 2);
-            } else {
-                no = numberGenerator.generateNumberWithPrefix(2,
-                        entrustCodePrefix,
-                        InsOrder::getEntrustCode);
-            }
+            String no = order.getEntrustCode();
             // 鍒ゆ柇鏄惁鏄搴︽楠�, 鏄搴︽楠屽彇娑堝師鏉愭枡瀛e害妫�楠屼笅鍗�
             if (InsOrderTypeConstants.QUARTERLY_TEST.equals(order.getOrderType())) {
                 ifsInventoryQuantityMapper.update(null,  Wrappers.<IfsInventoryQuantity>lambdaUpdate()
@@ -714,6 +766,10 @@
                   no = order1.getEntrustCode();
                 }
             }
+            if (StringUtils.isBlank(no)) {
+                no = buildEntrustCode(order, insSamples);
+            }
+            assertEntrustCodeUnique(no, order.getId());
 
             int count = 1;
             for (InsSample insSample : insSamples) {
@@ -731,7 +787,48 @@
 
             insOrder.setEntrustCode(no);
         }
-        return insOrderMapper.updateById(insOrder);
+        int updated = insOrderMapper.updateById(insOrder);
+        if (updated > 0 && Integer.valueOf(1).equals(insOrder.getState())) {
+            List<InsSample> samples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery()
+                    .eq(InsSample::getInsOrderId, insOrder.getId())
+                    .orderByAsc(InsSample::getId));
+            if (samples.size() != 1) {
+                throw new ErrorException("濮旀墭鍗曞繀椤讳笖鍙兘鍖呭惈涓�涓牱鍝侊紝涓嶈兘杩涘叆鏍峰搧鎺ユ敹娴佺▼");
+            }
+            insSampleReceiptMapper.insertIgnore(insOrder.getId(), samples.get(0).getId());
+        }
+        return updated;
+    }
+
+    /**
+     * 濮旀墭缂栧彿鍏ㄥ眬鍞竴锛岀敓鎴愮紪鍙峰拰鍚庣画鎻愪氦鍓嶅潎闇�鎺掗櫎褰撳墠璁㈠崟鍚庢牎楠屻��
+     */
+    private void assertEntrustCodeUnique(String entrustCode, Integer currentOrderId) {
+        Long count = insOrderMapper.selectCount(Wrappers.<InsOrder>lambdaQuery()
+                .eq(InsOrder::getEntrustCode, entrustCode)
+                .ne(currentOrderId != null, InsOrder::getId, currentOrderId));
+        if (count > 0) {
+            throw new ErrorException("鏍峰搧/濮旀墭鍗曞凡瀛樺湪锛岃纭鏍峰搧缂栧彿");
+        }
+    }
+
+    /**
+     * 鐢熸垚濮旀墭缂栧彿锛氭柊鑱氱洿缁戞ā鏉胯鍗曟湯涓や綅鍙栨牱鍝佺紪鍙锋湯涓や綅锛屽叾浣欐寜閫佹牱鏃ユ湡鐢熸垚搴忓彿銆�
+     */
+    private String buildEntrustCode(InsOrder order, List<InsSample> insSamples) {
+        LocalDate entrustDate = order.getSampleDate() == null ? LocalDate.now() : order.getSampleDate();
+        String entrustCodePrefix = "LMSY-"
+                + entrustDate.format(DateTimeFormatter.BASIC_ISO_DATE)
+                + "-";
+        if (isDirectTemplateOrder(order, insSamples)) {
+            String sampleCode = insSamples.get(0).getSampleCode();
+            if (StringUtils.isBlank(sampleCode) || sampleCode.trim().length() < 2) {
+                throw new ErrorException("鏍峰搧缂栧彿涓嶈兘涓虹┖涓斾笉鑳藉皯浜�2浣�");
+            }
+            sampleCode = sampleCode.trim();
+            return entrustCodePrefix + sampleCode.substring(sampleCode.length() - 2);
+        }
+        return numberGenerator.generateNumberWithPrefix(2, entrustCodePrefix, InsOrder::getEntrustCode);
     }
 
     @Override
@@ -1058,7 +1155,7 @@
         insOrder.setState(1);
 
         upInsOrderOfState(insOrder);
-        upInsOrder(insOrder.getId(), null, appointed != null ? appointed.toString() : null, SecurityUtils.getUserId().intValue(), "鍘熸潗鏂�");
+        // 瀹℃牳閫氳繃鍚庝粎杩涘叆鏍峰搧鎺ユ敹锛涚敱鏍峰搧鎺ユ敹椤甸潰閫夋嫨涓绘楠屼汉鍚庡啀鍒涘缓妫�楠屼换鍔°��
 
         return insOrder.getId();
     }

--
Gitblit v1.9.3