From de775139ac660c9d2e38ae54364f25e6724ca668 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期五, 28 八月 2026 15:41:38 +0800
Subject: [PATCH] feat(device): 1.添加设备导入导出功能并优化数据库关联查询 2.计量溯源性-标准物质清单导入导出

---
 cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java |  137 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 137 insertions(+), 0 deletions(-)

diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
index 2dd1a9c..d4aac72 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
@@ -1,12 +1,33 @@
 package com.ruoyi.require.service.impl;
 
+import com.alibaba.excel.EasyExcel;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+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.framework.exception.ErrorException;
+import com.ruoyi.require.excel.FeStandardSubstanceImport;
 import com.ruoyi.require.mapper.FeStandardSubstanceMapper;
 import com.ruoyi.require.pojo.FeStandardSubstance;
 import com.ruoyi.require.service.FeStandardSubstanceService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -23,4 +44,120 @@
     public IPage<FeStandardSubstance> page(Page page, FeStandardSubstance feStandardSubstance) {
         return this.baseMapper.getPage(page,feStandardSubstance);
     }
+
+    @Override
+    public void downloadImportTemplate(HttpServletResponse response) {
+        response.reset();
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
+        try {
+            String fileName = URLEncoder.encode("鏍囧噯鐗╄川瀵煎叆妯℃澘.xlsx", "UTF-8");
+            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+            EasyExcel.write(response.getOutputStream(), FeStandardSubstanceImport.class)
+                    .sheet("鏍囧噯鐗╄川瀵煎叆妯℃澘")
+                    .doWrite(Collections.emptyList());
+        } catch (Exception e) {
+            throw new RuntimeException("鏍囧噯鐗╄川瀵煎叆妯℃澘涓嬭浇澶辫触", e);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int importStandardSubstance(MultipartFile file) {
+        if (file == null || file.isEmpty()) {
+            throw new ErrorException("璇烽�夋嫨闇�瑕佸鍏ョ殑Excel鏂囦欢");
+        }
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || !fileName.toLowerCase(Locale.ROOT).endsWith(".xlsx")) {
+            throw new ErrorException("浠呮敮鎸�.xlsx鏍煎紡鏂囦欢");
+        }
+
+        final List<FeStandardSubstanceImport> rows;
+        try {
+            rows = EasyExcel.read(file.getInputStream())
+                    .head(FeStandardSubstanceImport.class)
+                    .sheet()
+                    .doReadSync();
+        } catch (Exception e) {
+            throw new ErrorException("Excel瑙f瀽澶辫触锛岃浣跨敤涓嬭浇鐨勫鍏ユā鏉�");
+        }
+        if (CollectionUtils.isEmpty(rows)) {
+            throw new ErrorException("瀵煎叆鏂囦欢娌℃湁鏍囧噯鐗╄川鏁版嵁");
+        }
+
+        Set<String> manageNumbers = new HashSet<>();
+        for (int i = 0; i < rows.size(); i++) {
+            String manageNum = required(rows.get(i).getManageNum(), i + 2, "绠$悊缂栧彿");
+            if (!manageNumbers.add(manageNum)) {
+                throw new ErrorException("绗�" + (i + 2) + "琛岋細绠$悊缂栧彿" + manageNum + "鍦ㄦ枃浠朵腑閲嶅");
+            }
+        }
+        Set<String> existingNumbers = baseMapper.selectList(Wrappers.<FeStandardSubstance>lambdaQuery()
+                        .in(FeStandardSubstance::getManageNum, manageNumbers)
+                        .select(FeStandardSubstance::getManageNum))
+                .stream().map(FeStandardSubstance::getManageNum).collect(Collectors.toSet());
+
+        List<FeStandardSubstance> substances = new ArrayList<>();
+        for (int i = 0; i < rows.size(); i++) {
+            int rowNumber = i + 2;
+            FeStandardSubstanceImport row = rows.get(i);
+            String manageNum = required(row.getManageNum(), rowNumber, "绠$悊缂栧彿");
+            if (existingNumbers.contains(manageNum)) {
+                throw new ErrorException("绗�" + rowNumber + "琛岋細绠$悊缂栧彿" + manageNum + "宸插瓨鍦�");
+            }
+
+            FeStandardSubstance substance = new FeStandardSubstance();
+            substance.setName(required(row.getName(), rowNumber, "鏍囧噯鐗╄川鍚嶇О"));
+            substance.setModel(required(row.getModel(), rowNumber, "瑙勬牸鍨嬪彿"));
+            substance.setFactoryManufacturer(required(row.getFactoryManufacturer(), rowNumber, "鐢熶骇鍘傚"));
+            substance.setFactoryNum(required(row.getFactoryNum(), rowNumber, "鍑哄巶缂栧彿"));
+            substance.setManageNum(manageNum);
+            substance.setUncertainty(required(row.getUncertainty(), rowNumber, "涓嶇‘瀹氬害"));
+            substance.setQuantity(parseQuantity(row.getQuantity(), rowNumber));
+            substance.setAcquisitionDate(parseDate(row.getAcquisitionDate(), rowNumber, "璐疆鏃ユ湡"));
+            substance.setEffectiveDate(parseDate(row.getEffectiveDate(), rowNumber, "鏈夋晥鏈�"));
+            substance.setFileNum(required(row.getFileNum(), rowNumber, "妗f缂栧彿"));
+            substance.setPosition(required(row.getPosition(), rowNumber, "瀛樻斁浣嶇疆"));
+            substance.setRemark(trim(row.getRemark()));
+            substance.setState(0);
+            substances.add(substance);
+        }
+        saveBatch(substances);
+        return substances.size();
+    }
+
+    private Long parseQuantity(String input, int rowNumber) {
+        String value = required(input, rowNumber, "鏁伴噺");
+        try {
+            long quantity = Long.parseLong(value);
+            if (quantity <= 0) {
+                throw new NumberFormatException();
+            }
+            return quantity;
+        } catch (NumberFormatException e) {
+            throw new ErrorException("绗�" + rowNumber + "琛岋細鏁伴噺蹇呴』鏄ぇ浜�0鐨勬暣鏁�");
+        }
+    }
+
+    private LocalDateTime parseDate(String input, int rowNumber, String column) {
+        String value = required(input, rowNumber, column);
+        try {
+            return LocalDate.parse(value.substring(0, Math.min(value.length(), 10)).replace('/', '-'), DateTimeFormatter.ofPattern("yyyy-M-d"))
+                    .atStartOfDay();
+        } catch (Exception e) {
+            throw new ErrorException("绗�" + rowNumber + "琛岋細" + column + "鏍煎紡搴斾负yyyy-MM-dd");
+        }
+    }
+
+    private String required(String input, int rowNumber, String column) {
+        String value = trim(input);
+        if (StringUtils.isBlank(value)) {
+            throw new ErrorException("绗�" + rowNumber + "琛岋細" + column + "涓嶈兘涓虹┖");
+        }
+        return value;
+    }
+
+    private String trim(String value) {
+        return value == null ? null : value.trim();
+    }
 }

--
Gitblit v1.9.3