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-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java | 186 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 186 insertions(+), 0 deletions(-)
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
index c743869..570a0f8 100644
--- a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
@@ -2,6 +2,7 @@
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
+import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -15,9 +16,12 @@
import com.ruoyi.basic.mapper.StructureItemParameterMapper;
import com.ruoyi.basic.pojo.StructureItemParameter;
import com.ruoyi.common.core.domain.Result;
+import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.device.dto.*;
+import com.ruoyi.device.excel.upload.DeviceImport;
import com.ruoyi.device.mapper.CollectBridgeMapper;
import com.ruoyi.device.mapper.DeviceMaintenanceMapper;
import com.ruoyi.device.mapper.DeviceMapper;
@@ -31,6 +35,8 @@
import com.ruoyi.inspect.mapper.InsSampleMapper;
import com.ruoyi.inspect.pojo.InsProduct;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
+import com.ruoyi.system.mapper.SysDictDataMapper;
+import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.UserMapper;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
@@ -42,6 +48,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
+import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
@@ -60,6 +67,10 @@
private DeviceMapper deviceMapper;
private UserMapper userMapper;
+
+ private SysDeptMapper sysDeptMapper;
+
+ private SysDictDataMapper sysDictDataMapper;
private StructureItemParameterMapper structureItemParameterMapper;
@@ -495,4 +506,179 @@
throw new RuntimeException("瀵煎嚭澶辫触");
}
}
+
+ @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(), DeviceImport.class)
+ .sheet("璁惧瀵煎叆妯℃澘")
+ .doWrite(Collections.emptyList());
+ } catch (Exception e) {
+ throw new RuntimeException("璁惧瀵煎叆妯℃澘涓嬭浇澶辫触", e);
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public int importDevice(org.springframework.web.multipart.MultipartFile file) {
+ if (file == null || file.isEmpty()) {
+ throw new RuntimeException("璇烽�夋嫨闇�瑕佸鍏ョ殑Excel鏂囦欢");
+ }
+ String fileName = file.getOriginalFilename();
+ if (fileName == null || !fileName.toLowerCase(Locale.ROOT).endsWith(".xlsx")) {
+ throw new RuntimeException("浠呮敮鎸�.xlsx鏍煎紡鏂囦欢");
+ }
+
+ final List<DeviceImport> rows;
+ try {
+ rows = EasyExcel.read(file.getInputStream())
+ .head(DeviceImport.class)
+ .sheet()
+ .doReadSync();
+ } catch (Exception e) {
+ throw new RuntimeException("Excel瑙f瀽澶辫触锛岃浣跨敤涓嬭浇鐨勫鍏ユā鏉�", e);
+ }
+ if (CollectionUtils.isEmpty(rows)) {
+ throw new RuntimeException("瀵煎叆鏂囦欢娌℃湁璁惧鏁版嵁");
+ }
+
+ Set<String> managementNumbers = new HashSet<>();
+ for (int i = 0; i < rows.size(); i++) {
+ String managementNumber = required(rows.get(i).getManagementNumber(), i + 2, "绠$悊缂栧彿");
+ if (!managementNumbers.add(managementNumber)) {
+ throw new RuntimeException("绗�" + (i + 2) + "琛岋細绠$悊缂栧彿" + managementNumber + "鍦ㄦ枃浠朵腑閲嶅");
+ }
+ }
+ Set<String> existingNumbers = baseMapper.selectList(Wrappers.<Device>lambdaQuery()
+ .in(Device::getManagementNumber, managementNumbers)
+ .select(Device::getManagementNumber))
+ .stream().map(Device::getManagementNumber).collect(Collectors.toSet());
+
+ Map<String, List<SysDept>> departmentMap = sysDeptMapper.selectDeptList(new SysDept()).stream()
+ .filter(item -> StringUtils.isNotBlank(item.getDeptName()))
+ .collect(Collectors.groupingBy(item -> item.getDeptName().trim()));
+ Map<String, List<User>> userMap = userMapper.selectList(Wrappers.<User>lambdaQuery()
+ .isNotNull(User::getName).select(User::getId, User::getName))
+ .stream().collect(Collectors.groupingBy(item -> item.getName().trim()));
+ Map<String, String> statusMap = dictMap("device_status");
+ Map<String, String> typeMap = dictMap("device_type");
+
+ List<Device> devices = new ArrayList<>();
+ for (int i = 0; i < rows.size(); i++) {
+ int rowNumber = i + 2;
+ DeviceImport row = rows.get(i);
+ String managementNumber = required(row.getManagementNumber(), rowNumber, "绠$悊缂栧彿");
+ if (existingNumbers.contains(managementNumber)) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細绠$悊缂栧彿" + managementNumber + "宸插瓨鍦�");
+ }
+
+ String laboratoryName = required(row.getLaboratoryName(), rowNumber, "鎵�灞為儴闂�");
+ List<SysDept> departments = departmentMap.get(laboratoryName);
+ if (CollectionUtils.isEmpty(departments) || departments.size() > 1) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細鎵�灞為儴闂ㄢ��" + laboratoryName + "鈥濅笉瀛樺湪鎴栦笉鍞竴");
+ }
+
+ Device device = new Device();
+ device.setDeviceName(required(row.getDeviceName(), rowNumber, "浠櫒鍚嶇О"));
+ device.setSpecificationModel(required(row.getSpecificationModel(), rowNumber, "瑙勬牸鍨嬪彿"));
+ device.setManagementNumber(managementNumber);
+ device.setActivationDate(parseDate(row.getActivationDate(), rowNumber, "鏍″噯鏈夋晥鏈�", true));
+ device.setSubordinateDepartmentsId(departments.get(0).getDeptId().intValue());
+ device.setDeviceStatus(Integer.valueOf(dictValue(statusMap, row.getDeviceStatus(), rowNumber, "褰撳墠鐘舵��", true)));
+ device.setCalibrationDate(required(row.getCalibrationDate(), rowNumber, "鏍″噯鍛ㄦ湡(鏈�)"));
+ device.setEnDeviceName(trim(row.getEnDeviceName()));
+ device.setManufacturer(trim(row.getManufacturer()));
+ device.setFactoryNo(trim(row.getFactoryNo()));
+ device.setAssetCode(trim(row.getAssetCode()));
+ device.setOrigin(trim(row.getOrigin()));
+ device.setAcquisitionDate(parseDate(row.getAcquisitionDate(), rowNumber, "璐疆鏃ユ湡", false));
+ device.setStoragePoint(trim(row.getStoragePoint()));
+ device.setTechnicalIndicators(trim(row.getTechnicalIndicators()));
+ device.setCalibrationServices(trim(row.getCalibrationServices()));
+ device.setLastCalibrationDate(parseDate(row.getLastCalibrationDate(), rowNumber, "鏈�杩戞牎鍑嗘棩鏈�", false));
+ device.setNextCalibrationDate(parseDate(row.getNextCalibrationDate(), rowNumber, "涓嬫鏍″噯鏃ユ湡", false));
+ device.setLargeCategory(dictValue(typeMap, row.getLargeCategory(), rowNumber, "璁惧绫诲瀷", false));
+ device.setUnitPrice(parseDecimal(row.getUnitPrice(), rowNumber, "鍗曚环(涓囧厓)"));
+
+ String managerName = trim(row.getEquipmentManagerName());
+ if (StringUtils.isNotBlank(managerName)) {
+ List<User> users = userMap.get(managerName);
+ if (CollectionUtils.isEmpty(users) || users.size() > 1) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細璐熻矗浜衡��" + managerName + "鈥濅笉瀛樺湪鎴栦笉鍞竴");
+ }
+ device.setEquipmentManager(users.get(0).getId());
+ }
+ devices.add(device);
+ }
+ saveBatch(devices);
+ return devices.size();
+ }
+
+ private Map<String, String> dictMap(String dictType) {
+ return sysDictDataMapper.selectDictDataByType(dictType).stream()
+ .collect(Collectors.toMap(item -> item.getDictLabel().trim(), SysDictData::getDictValue, (first, second) -> first));
+ }
+
+ private String dictValue(Map<String, String> values, String input, int rowNumber, String column, boolean required) {
+ String text = trim(input);
+ if (StringUtils.isBlank(text)) {
+ if (required) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "涓嶈兘涓虹┖");
+ }
+ return null;
+ }
+ String value = values.get(text);
+ if (value == null && values.containsValue(text)) {
+ value = text;
+ }
+ if (value == null) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "鈥�" + text + "鈥濅笉鍦ㄧ郴缁熷瓧鍏镐腑");
+ }
+ return value;
+ }
+
+ private LocalDateTime parseDate(String input, int rowNumber, String column, boolean required) {
+ String text = trim(input);
+ if (StringUtils.isBlank(text)) {
+ if (required) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "涓嶈兘涓虹┖");
+ }
+ return null;
+ }
+ try {
+ return LocalDate.parse(text.substring(0, Math.min(text.length(), 10)).replace('/', '-'), DateTimeFormatter.ofPattern("yyyy-M-d"))
+ .atStartOfDay();
+ } catch (Exception e) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "鏍煎紡搴斾负yyyy-MM-dd", e);
+ }
+ }
+
+ private BigDecimal parseDecimal(String input, int rowNumber, String column) {
+ String text = trim(input);
+ if (StringUtils.isBlank(text)) {
+ return null;
+ }
+ try {
+ return new BigDecimal(text);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "蹇呴』鏄暟瀛�", e);
+ }
+ }
+
+ private String required(String input, int rowNumber, String column) {
+ String value = trim(input);
+ if (StringUtils.isBlank(value)) {
+ throw new RuntimeException("绗�" + rowNumber + "琛岋細" + column + "涓嶈兘涓虹┖");
+ }
+ return value;
+ }
+
+ private String trim(String value) {
+ return value == null ? null : value.trim();
+ }
}
--
Gitblit v1.9.3