liding
2025-04-01 8bf9254ba43e744517d4de2516121da2979fd057
1.检验项目参数导入 2.对象导入
已修改11个文件
已添加2个文件
1089 ■■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/controller/CapacityScopeController.java 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/excel/ExcelMultiSheetImporter.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/excel/MultiSheetImportListener.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/mapper/ProductMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/mapper/StructureTestObjectMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/pojo/StructureItemParameter.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/CapacityScopeServiceImpl.java 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/StandardMethodServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PersonDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PersonnelHeaderApi.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/controller/CapacityScopeController.java
@@ -1,22 +1,18 @@
package com.ruoyi.basic.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.ProductDto;
import com.ruoyi.basic.dto.StructureTestObjectDto;
import com.ruoyi.basic.excel.ExcelMultiSheetImporter;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.basic.dto.PageTestObjectDto;
import com.ruoyi.basic.dto.ProductDTO1;
import com.ruoyi.basic.excel.StructureTestObjectData;
import com.ruoyi.basic.excel.StructureTestObjectListener;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.StandardTemplate;
import com.ruoyi.basic.pojo.StructureItemParameter;
import com.ruoyi.basic.pojo.StructureTestObject;
import com.ruoyi.basic.service.CapacityScopeService;
@@ -27,18 +23,13 @@
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
 * æ£€éªŒé¡¹ç›®å‚æ•°(StructureItemParameter)表控制层
@@ -152,240 +143,16 @@
        return Result.success(capacityScopeService.getItemTree());
    }
    @ApiOperation(value = "装备导入检验项目")
    @PostMapping("/importEquipData")
    @Transactional
    public Result importEquipData(@RequestParam("file") MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        List<StructureItemParameter> lists = new ArrayList<>();
        AtomicReference<String> sample = new AtomicReference<>();
        ExcelUtil.readBySax(inputStream, -1, (i, l, list1) -> {
            if (l == 1) {
                sample.set(list1.get(1) + "");
            }
            if (l >= 1) {
                StructureItemParameter str = new StructureItemParameter();
                // æµ‹è¯•对象
                if (list1.get(1) == null) {
                    str.setSample(null);
                } else {
                    String brand = (String) list1.get(1);
                    StringBuilder builder = new StringBuilder();
                    builder.append("[");
                    // äº§å“
                    if (ObjectUtil.isNotEmpty(list1.get(2))) {
                        String production = (String) list1.get(2);
                        if (!production.contains(";")) {
                            builder.append(String.format("[\"%s\",\"%s\"]", brand, production));
                        } else {
                            Arrays.stream(production.split(";")).forEach(item -> {
                                builder.append(String.format("[\"%s\",\"%s\"],", brand, item));
                            });
                            builder.deleteCharAt(builder.length() - 1);
                        }
                    } else {
                        builder.append("[");
                        builder.append(String.format("\"%s\"", brand));
                        builder.append("]");
                    }
                    builder.append("]");
                    str.setSample(builder.toString());
                }
                // æ£€éªŒé¡¹
                str.setInspectionItem(list1.get(4).toString().trim());
                // æ£€éªŒé¡¹è‹±æ–‡
                if (list1.get(5) != null) {
                    str.setInspectionItemEn(list1.get(5).toString());
                }
                // æ£€éªŒå­é¡¹
                if (list1.get(6) == null) {
                    str.setInspectionItemSubclass(null);
                } else {
                    str.setInspectionItemSubclass(list1.get(6).toString().trim());
                }
                // æ£€éªŒå­é¡¹è‹±æ–‡
                if (list1.get(7) == null) {
                    str.setInspectionItemSubclassEn(null);
                } else {
                    str.setInspectionItemSubclassEn(String.valueOf(list1.get(7).toString()));
                }
                // æ£€éªŒé¡¹åˆ†ç±»
                if (list1.get(22) != null && list1.get(22) != "") {
                    str.setInspectionItemClass(list1.get(22).toString().trim());
                } else {
                    str.setInspectionItemClass(null);
                }
                // æ£€éªŒé¡¹åˆ†ç±»è‹±æ–‡
                if (list1.get(23) != null && list1.get(23) != "") {
                    str.setInspectionItemClassEn(list1.get(23) + "");
                } else {
                    str.setInspectionItemClassEn(null);
                }
                LambdaQueryWrapper<StructureItemParameter> wrapper = Wrappers.lambdaQuery(StructureItemParameter.class)
                        .eq(StructureItemParameter::getInspectionItem, str.getInspectionItem())
                        .eq(StructureItemParameter::getSample, str.getSample())
                        .last("limit 1");
                // åˆ¤æ–­æ˜¯å¦æœ‰æ£€éªŒé¡¹ç±»åž‹
                if (ObjectUtils.isNotEmpty(str.getInspectionItemClass())) {
                    wrapper.eq(StructureItemParameter::getInspectionItemClass, str.getInspectionItemClass());
                }
                // åˆ¤æ–­æ˜¯å¦æœ‰æ£€éªŒå­é¡¹
                if (ObjectUtils.isNotEmpty(str.getInspectionItemSubclass())) {
                    wrapper.eq(StructureItemParameter::getInspectionItemSubclass, str.getInspectionItemSubclass());
                }
                StructureItemParameter db_str = structureItemParameterService.getOne(wrapper);
                if (ObjectUtils.isNotEmpty(db_str)) {
                    str.setId(db_str.getId());
                }
                // æ–¹æ³•名称
                if (list1.get(8) == null) {
                    str.setMethod(null);
                } else {
                    StringBuffer buffer = new StringBuffer();
                    String input = list1.get(8).toString();
                    buffer.append("[");
                    String[] values = input.split(";");
                    for (String value : values) {
                        buffer.append("\"").append(value.trim()).append("\",");
                    }
                    buffer.deleteCharAt(buffer.length() - 1);
                    buffer.append("]");
                    str.setMethod(buffer.toString());
                }
                // è¯•验室
                if (list1.get(9) == null) {
                    str.setSonLaboratory(null);
                } else {
                    str.setSonLaboratory(list1.get(9).toString());
                }
                // è®¡é‡å•位
                if (list1.get(10) == null) {
                    str.setUnit(null);
                } else {
                    str.setUnit(list1.get(10).toString());
                }
                // è¦æ±‚值
                if (list1.get(11) == null) {
                    str.setAskTell(null);
                } else {
                    str.setAskTell(list1.get(11).toString());
                }
                // è¦æ±‚描述
                if (list1.get(12) == null) {
                    str.setAsk(null);
                } else {
                    str.setAsk(list1.get(12).toString());
                }
                // å•ä»·
                if (list1.get(13) == null) {
                    str.setPrice(null);
                } else {
                    str.setPrice(list1.get(13) + "");
                }
                // å·¥æ—¶ç³»æ•°
                if (list1.get(14) == null) {
                    str.setManHour(null);
                } else {
                    str.setManHour(Double.valueOf(list1.get(14).toString()));
                }
                // å·¥æ—¶åˆ†ç»„
                if (list1.get(15) == null) {
                    str.setManHourGroup(null);
                } else {
                    str.setManHourGroup(list1.get(15).toString());
                }
                // é¢„计完成时间
                if (list1.get(16) == null) {
                    str.setManDay(null);
                } else {
                    str.setManDay(Integer.valueOf(list1.get(16).toString()));
                }
                // æ•°æ®ç±»åž‹
                String jy;
                if (list1.get(17).toString().equals("非采集类型")) {
                    jy = "0";
                } else {
                    jy = "1";
                }
                str.setInspectionItemType(jy);
                // æ£€éªŒé¡¹ç±»åž‹
                String validateValueType = list1.get(18).toString();
                if (ObjectUtils.isNotEmpty(validateValueType)) {
                    List<SysDictData> enums = dictTypeService.selectDictDataByName("检验值类型")
                            .stream().filter(sysDictData -> sysDictData.getDictLabel().equals(validateValueType)).collect(Collectors.toList());
                    str.setInspectionValueType(enums.get(0).getDictValue());
                }
                int bsm;
                //特殊标识
                if (list1.get(19).toString().equals("否")) {
                    bsm = 0;
                } else {
                    bsm = 1;
                }
                str.setBsm(bsm + "");
                // æ•°å­—å­—å…¸
                if (list1.get(20) != null) {
                    str.setDic(list1.get(20) + "");
                } else {
                    str.setDic(null);
                }
                // åŽŸå§‹è®°å½•æ¨¡æ¿
                StandardTemplate standTempIdByName = standardTemplateService.getStandTempIdByName(String.valueOf(list1.get(21)));
                if (standTempIdByName != null) {
                    str.setTemplateId(standTempIdByName.getId());
                } else {
                    str.setTemplateId(null);
                }
                try {
                    if (list1.get(24) != null) {
                        str.setLaboratory(list1.get(24) + "");
                    }
                } catch (Exception e) {
                }
                // æ¡ä»¶
                if (list1.get(25) == null) {
                    str.setRadiusList(null);
                } else {
                    StringBuffer buffer = new StringBuffer();
                    String input = list1.get(25).toString();
                    buffer.append("[");
                    String[] values = input.split(";");
                    for (String value : values) {
                        buffer.append("\"").append(value.trim()).append("\",");
                    }
                    buffer.deleteCharAt(buffer.length() - 1);
                    buffer.append("]");
                    str.setRadiusList(buffer.toString());
                }
                //收费标准
                if (list1.get(26) == null) {
                    str.setRates(null);
                } else {
                    str.setRates(list1.get(26) + "");
                }
                lists.add(str);
            }
        });
//        structureItemParameterService.removeNoSample(sample.get());
        // å¦‚果数据库里面的数据存在那么就执行更新拷贝操作
        try {
            structureItemParameterService.saveOrUpdateBatch(lists);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("服务端报错");
        }
        return Result.success();
    public Result importData(@RequestParam("file") MultipartFile file) {
        // è°ƒç”¨å¯¼å…¥å·¥å…·
        String result = ExcelMultiSheetImporter.importExcel(file, structureItemParameterService, standardTemplateService, dictTypeService);
        return Result.success(result);
    }
    @ApiOperation(value = "导入检验对象")
    @PostMapping("/importExcel")
    public Result importExcel(@RequestParam("file") MultipartFile file){
    public Result importExcel(@RequestParam("file") MultipartFile file) {
        List<String> processedFiles = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream()) {
            String fileHash = DigestUtils.md5Hex(inputStream);
basic-server/src/main/java/com/ruoyi/basic/excel/ExcelMultiSheetImporter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.basic.excel;
import com.alibaba.excel.EasyExcel;
import com.ruoyi.basic.pojo.StructureItemParameter;
import com.ruoyi.basic.service.StandardTemplateService;
import com.ruoyi.basic.service.StructureItemParameterService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
public class ExcelMultiSheetImporter {
    public static String importExcel(MultipartFile file, StructureItemParameterService service, StandardTemplateService standardTemplateService,
                                     ISysDictTypeService dictTypeService) {
        try {
            // è¯»å–所有Sheet(通过监听器处理每个Sheet)
            EasyExcel.read(file.getInputStream())
                    .head(StructureItemParameter.class)
                    // æ³¨å†Œç›‘听器(每个Sheet共用同一个监听器)
                    .registerReadListener(new MultiSheetImportListener(service, standardTemplateService, dictTypeService))
                    // è‡ªåŠ¨è¯†åˆ«æ‰€æœ‰Sheet并遍历读取
                    .doReadAll();
            return "导入成功";
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return "导入失败:" + StringUtils.substring(e.getMessage(), 0, 100);
        }
    }
}
basic-server/src/main/java/com/ruoyi/basic/excel/MultiSheetImportListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,224 @@
package com.ruoyi.basic.excel;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.basic.pojo.StandardTemplate;
import com.ruoyi.basic.pojo.StructureItemParameter;
import com.ruoyi.basic.service.StandardTemplateService;
import com.ruoyi.basic.service.StructureItemParameterService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@AllArgsConstructor
public class MultiSheetImportListener implements ReadListener<StructureItemParameter> {
    // æ¯æ‰¹å¤„理1000条数据
    private static final int BATCH_COUNT = 1000;
    private List<StructureItemParameter> cachedList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    private final StructureItemParameterService parameterService;
    private String currentSheetName;
    private final ISysDictTypeService dictTypeService;
    private final StandardTemplateService standardTemplateService;
    public MultiSheetImportListener(StructureItemParameterService parameterService, StandardTemplateService standardTemplateService,
                                    ISysDictTypeService dictTypeService) {
        this.parameterService = parameterService;
        this.standardTemplateService = standardTemplateService;
        this.dictTypeService = dictTypeService;
    }
    @Override
    public void invoke(StructureItemParameter data, AnalysisContext context) {
        data.setId(null);
        // æµ‹è¯•对象
        if (data.getSample() == null) {
            data.setSample(null);
        } else {
            String brand = data.getSample();
            StringBuilder builder = new StringBuilder();
            builder.append("[");
            // äº§å“
            if (ObjectUtil.isNotEmpty(data.getProduct())) {
                String production = data.getProduct();
                if (!production.contains(";")) {
                    builder.append(String.format("[\"%s\",\"%s\"]", brand, production));
                } else {
                    Arrays.stream(production.split(";")).forEach(item -> {
                        builder.append(String.format("[\"%s\",\"%s\"],", brand, item));
                    });
                    builder.deleteCharAt(builder.length() - 1);
                }
            } else {
                builder.append("[");
                builder.append(String.format("\"%s\"", brand));
                builder.append("]");
            }
            builder.append("]");
            data.setSample(builder.toString());
        }
        // æŸ¥è¯¢æ•°æ®åº“中是否存在相同记录
        LambdaQueryWrapper<StructureItemParameter> wrapper = Wrappers.lambdaQuery(StructureItemParameter.class)
                .eq(StructureItemParameter::getInspectionItem, data.getInspectionItem())
                .eq(StructureItemParameter::getSample, data.getSample())
                .last("limit 1");
        // åˆ¤æ–­æ˜¯å¦æœ‰æ£€éªŒé¡¹ç±»åž‹
        if (ObjectUtils.isNotEmpty(data.getInspectionItemClass())) {
            wrapper.eq(StructureItemParameter::getInspectionItemClass, data.getInspectionItemClass());
        }
        // åˆ¤æ–­æ˜¯å¦æœ‰æ£€éªŒå­é¡¹
        if (ObjectUtils.isNotEmpty(data.getInspectionItemSubclass())) {
            wrapper.eq(StructureItemParameter::getInspectionItemSubclass, data.getInspectionItemSubclass());
        }
        StructureItemParameter db_str = parameterService.getOne(wrapper);
        if (db_str != null) {
            // è‹¥éœ€æ›´æ–°ï¼Œè®¾ç½® id
            data.setId(db_str.getId());
        }
        // åŽŸå§‹è®°å½•æ¨¡æ¿
        StandardTemplate standTempIdByName = standardTemplateService.getStandTempIdByName(String.valueOf(data.getTemplateName()));
        if (standTempIdByName != null) {
            data.setTemplateId(standTempIdByName.getId());
        } else {
            data.setTemplateId(null);
        }
        // æ•°æ®ç±»åž‹
        String jy;
        String inspectionType = data.getInspectionItemType() != null ?
                data.getInspectionItemType().toString() : "";
        if ("非采集类型".equals(inspectionType)) {
            jy = "0";
        } else {
            jy = "1";
        }
        data.setInspectionItemType(jy);
        // æ–¹æ³•名称
        if (data.getMethod() == null) {
            data.setMethod(null);
        } else {
            StringBuffer buffer = new StringBuffer();
            String input = data.getMethod().toString();
            buffer.append("[");
            String[] values = input.split(";");
            for (String value : values) {
                buffer.append("\"").append(value.trim()).append("\",");
            }
            buffer.deleteCharAt(buffer.length() - 1);
            buffer.append("]");
            data.setMethod(buffer.toString());
        }
        // ç‰¹æ®Šæ ‡è¯†
        String bs;
        String bsmValue = data.getBsm() == null ? "" : data.getBsm().trim();
        if ("否".equals(bsmValue)) {
            bs = "0";
        } else {
            bs = "1";
        }
        data.setBsm(bs);
        //检验项类型
        String validateValueType = data.getInspectionValueType().toString();
        if (ObjectUtils.isNotEmpty(validateValueType)) {
            List<SysDictData> enums = dictTypeService.selectDictDataByName("检验值类型")
                    .stream().filter(sysDictData -> sysDictData.getDictLabel().equals(validateValueType)).collect(Collectors.toList());
            data.setInspectionValueType(enums.get(0).getDictValue());
        }
        // æ¡ä»¶
        if (data.getRadiusList() == null) {
            data.setRadiusList(null);
        } else {
            StringBuffer buffer = new StringBuffer();
            String input = data.getRadiusList();
            buffer.append("[");
            String[] values = input.split(";");
            for (String value : values) {
                buffer.append("\"").append(value.trim()).append("\",");
            }
            buffer.deleteCharAt(buffer.length() - 1);
            buffer.append("]");
            data.setRadiusList(buffer.toString());
        }
        if (data.getManDay() == null) {
            data.setManDay(null);
        }
        // è®¾ç½®å½“前Sheet名为分类标识
        data.setInspectionItemClass(currentSheetName);
        // æ·»åŠ åˆ°ç¼“å­˜åˆ—è¡¨
        cachedList.add(data);
        // è¾¾åˆ°æ‰¹æ¬¡å¤„理阈值时入库
        if (cachedList.size() >= BATCH_COUNT) {
            saveData();
            cachedList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // æœ€åŽä¸€æ‰¹æ•°æ®å¤„理
        if (!cachedList.isEmpty()) {
            saveData();
        }
        log.info("Sheet [{}] å¯¼å…¥å®Œæˆ", currentSheetName);
    }
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        this.currentSheetName = context.readSheetHolder().getSheetName();
    }
    private void saveData() {
        // æ‰¹é‡æ’入(使用若依Service层方法)
        parameterService.saveOrUpdateBatch(cachedList);
    }
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        String sheetName = context.readSheetHolder().getSheetName();
        int rowIndex = context.readRowHolder().getRowIndex() + 1;
        int columnIndex = -1;
        String errorMsg = exception.getMessage();
        // é’ˆå¯¹ ExcelDataConvertException æå–列号
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException ex = (ExcelDataConvertException) exception;
            columnIndex = ex.getColumnIndex() + 1;
            errorMsg = String.format("列[%s]数据格式错误: %s",
                    ex.getCellData().getStringValue(),
                    errorMsg
            );
        }
        // æ‰“印完整错误堆栈(调试时开启)
        log.error("Sheet[{}] ç¬¬{}行第{}列解析失败: {}", sheetName, rowIndex, columnIndex, errorMsg);
    }
}
basic-server/src/main/java/com/ruoyi/basic/mapper/ProductMapper.java
@@ -1,11 +1,11 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.ProductDTO1;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.framework.mybatis_config.MyBaseMapper;
import org.apache.ibatis.annotations.Param;
/**
@@ -14,7 +14,7 @@
* @createDate 2024-04-26 01:11:02
* @Entity com.ruoyi.basic.pojo.Product
*/
public interface ProductMapper extends BaseMapper<Product> {
public interface ProductMapper extends MyBaseMapper<Product> {
    IPage<Product> selectProductListByObjectId(Page page, @Param("ew") QueryWrapper<ProductDTO1> ew, @Param("partNo") String partNo);
}
basic-server/src/main/java/com/ruoyi/basic/mapper/StructureTestObjectMapper.java
@@ -1,12 +1,14 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.PageTestObjectDto;
import com.ruoyi.basic.pojo.StructureTestObject;
import com.ruoyi.framework.mybatis_config.MyBaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * æ£€æµ‹å¯¹è±¡(StructureTestObject)表数据库访问层
@@ -14,7 +16,7 @@
 * @author makejava
 * @since 2024-02-26 17:36:41
 */
public interface StructureTestObjectMapper extends BaseMapper<StructureTestObject> {
public interface StructureTestObjectMapper extends MyBaseMapper<StructureTestObject> {
    IPage<PageTestObjectDto> selectTestObjectList(Page page, @Param("ew") QueryWrapper<PageTestObjectDto> ew, @Param("specimenName") String specimenName);
basic-server/src/main/java/com/ruoyi/basic/pojo/StructureItemParameter.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.io.Serializable;
@@ -14,108 +15,235 @@
 * @author makejava
 * @since 2024-02-26 16:21:17
 */
@TableName(value ="structure_item_parameter")
@TableName(value = "structure_item_parameter")
@Data
public class StructureItemParameter implements Serializable {
    /**
     * ä¸»é”®
     */
    @ApiModelProperty(value = "主键")
    @TableId(type = IdType.AUTO)
    private Integer id;
    /**
     * æ£€éªŒé¡¹
     */
    @ApiModelProperty(value = "检验项")
    @ExcelProperty(value = "检测参数名称",index = 4)
    private String inspectionItem;
    /**
     * æ£€éªŒé¡¹EN
     */
    @ApiModelProperty(value = "检验项EN")
    @ExcelProperty(value = "检测参数名称(EN)",index = 5)
    private String inspectionItemEn;
    /**
     * æ£€éªŒå­é¡¹
     */
    @ApiModelProperty(value = "检验子项")
    @ExcelProperty(value = "检测子项",index = 6)
    private String inspectionItemSubclass;
    /**
     * æ£€éªŒå­é¡¹EN
     */
    @ApiModelProperty(value = "检验子项EN")
    @ExcelProperty(value = "检测子项(EN)",index = 7)
    private String inspectionItemSubclassEn;
    /**
     * æ£€éªŒå¯¹è±¡
     */
    @ApiModelProperty(value = "检验对象")
    @ExcelProperty(value = "测试对象",index = 1)
    private String sample;
    /**
     * å•ä»·(元)
     */
    @ApiModelProperty(value = "单价(元)")
    @ExcelProperty(value = "单价",index = 13)
    private String price;
    /**
     * åœºæ‰€
     */
    @ApiModelProperty(value = "场所")
    @ExcelProperty(value = "场所",index = 24)
    private String laboratory;
    /**
     * è¯•验室
     */
    @ApiModelProperty(value = "试验室")
    @ExcelProperty(value = "试验室",index = 9)
    private String sonLaboratory;
    /**
     * è¦æ±‚描述
     */
    @ApiModelProperty(value = "要求描述")
    @ExcelProperty(value = "标准显示",index = 11)
    private String askTell;
    /**
     * è¦æ±‚值
     */
    @ApiModelProperty(value = "要求值")
    @ExcelProperty(value = "判断要求",index = 12)
    private String ask;
    /**
     * è®¡é‡å•位
     */
    @ApiModelProperty(value = "计量单位")
    @ExcelProperty(value = "计量单位",index = 10)
    private String unit;
    /**
     * è¯•验方法
     */
    @ApiModelProperty(value = "试验方法")
    @ExcelProperty(value = "方法名称",index = 8)
    private String method;
    /**
     * å·¥æ—¶(H)
     */
    @ApiModelProperty(value = "工时(H)")
    @ExcelProperty(value = "工时系数",index = 14)
    private Double manHour;
    /**
     * é¢„计时间(H)
     */
    @ApiModelProperty(value = "预计时间(H)")
    @ExcelProperty(value = "预计完成时间",index = 16)
    private Integer manDay;
    /**
     * å·¥æ—¶åˆ†ç»„
     */
    @ApiModelProperty(value = "工时分组")
    @ExcelProperty(value = "工时分组",index = 15)
    private String manHourGroup;
    /**
     * æ£€éªŒé¡¹ç±»åž‹
     */
    @ApiModelProperty(value = "检验项类型")
    @ExcelProperty(value = "数据类型",index = 17)
    private String inspectionItemType;
    /**
     * æ£€éªŒå€¼ç±»åž‹
     */
    @ApiModelProperty(value = "检验值类型")
    @ExcelProperty(value = "检验值类型",index = 18)
    private String inspectionValueType;
    /**
     * æ£€éªŒæ¬¡æ•°
     */
    @ApiModelProperty(value = "检验次数")
    private Integer checkoutNumber;
    /**
     * åŒºé—´
     */
    @ApiModelProperty(value = "区间")
    private String section;
    /**
     * ç‰¹æ®Šæ ‡è¯†
     */
    @ApiModelProperty(value = "特殊标识")
    @ExcelProperty(value = "特殊标识",index = 19)
    private String bsm;
    /**
     * åŽŸå§‹è®°å½•æ¨¡æ¿
     */
    @ApiModelProperty(value = "原始记录模板")
    private Integer templateId;
    @TableField(exist = false)
    @ExcelProperty(value = "原始记录模板",index = 21)
    private String templateName;
    /**
     * åˆ›å»ºäººid
     */
    @ApiModelProperty(value = "创建人id")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * ä¿®æ”¹äººid
     */
    @ApiModelProperty(value = "修改人id")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    /**
     * å­—典类型
     */
    @ApiModelProperty(value = "字典类型")
    @ExcelProperty(value = "数据字典",index = 20)
    private String dic;
    /**
     * æ£€éªŒé¡¹åˆ†ç±»
     */
    @ApiModelProperty(value = "检验项分类")
    @ExcelProperty(value = "检验项分类",index = 22)
    private String inspectionItemClass;
    /**
     * æ£€éªŒé¡¹åˆ†ç±»EN
     */
    @ApiModelProperty(value = "检验项分类EN")
    @ExcelProperty(value = "检验项分类",index = 23)
    private String inspectionItemClassEn;
    /**
     * æ¡ä»¶
     */
    @ApiModelProperty(value = "条件")
    @ExcelProperty(value = "试验条件",index = 25)
    private String radiusList;
    /**
     * æ”¶è´¹æ ‡å‡†(元/次)
     */
    @ApiModelProperty(value = "收费标准(元/次)")
    @ExcelProperty(value = "收费标准",index = 26)
    private String rates;
}
    @TableField(exist = false)
    @ExcelProperty(value = "产品",index = 2)
    private String product;
    @ExcelProperty(value = "检测参数编号",index = 3)
    @TableField(exist = false)
    private String parameterNumber;
}
basic-server/src/main/java/com/ruoyi/basic/service/impl/CapacityScopeServiceImpl.java
@@ -2,10 +2,8 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -22,11 +20,10 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
 * æ£€éªŒé¡¹ç›®å‚æ•°(StructureItemParameter)表服务实现类
@@ -192,132 +189,228 @@
    public List<TestItemDto> getItemTree() {
        return structureItemParameterMapper.getItemTree();
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importPartExcel(List<StructureTestObjectData> list) {
        // æ‰¹é‡æŸ¥è¯¢ StructureTestObject
        Map<String, StructureTestObject> structureTestObjectMap = getStructureTestObjectMap(list);
        // æ‰¹é‡æŸ¥è¯¢ WorkShop
        Map<String, WorkShop> workShopMap = getWorkShopMap(list);
        // é˜¶æ®µ1: æ•°æ®é¢„处理
        // æ”¶é›†æ‰€æœ‰éœ€è¦æŸ¥è¯¢çš„æ ‡æœ¬ä¿¡æ¯
        Set<String> specimenKeys = list.stream()
                .map(i -> i.getSpecimenName() + "|" + i.getSpecimenNameEn())
                .collect(Collectors.toSet());
        List<StructureTestObject> insertStructureTestObjects = new ArrayList<>();
        List<StructureTestObject> updateStructureTestObjects = new ArrayList<>();
        List<Product> insertProducts = new ArrayList<>();
        List<Product> updateProducts = new ArrayList<>();
        // é˜¶æ®µ2: æ‰¹é‡æŸ¥è¯¢çŽ°æœ‰ç»“æž„æµ‹è¯•å¯¹è±¡
        Map<String, StructureTestObject> existStructureTestObjects = structureTestObjectMapper.selectList(
                Wrappers.<StructureTestObject>lambdaQuery()
                        .in(StructureTestObject::getSpecimenName, list.stream().map(StructureTestObjectData::getSpecimenName).collect(Collectors.toSet()))
                        .in(StructureTestObject::getSpecimenNameEn, list.stream().map(StructureTestObjectData::getSpecimenNameEn).collect(Collectors.toSet()))
        ).stream().collect(Collectors.toMap(
                obj -> obj.getSpecimenName() + "|" + obj.getSpecimenNameEn(),
                Function.identity(),
                (existing, replacement) -> existing  // å¤„理重复键
        ));
        for (StructureTestObjectData data : list) {
            String key = data.getSpecimenName() + "_" + data.getSpecimenNameEn();
            StructureTestObject structureTestObject = structureTestObjectMap.get(key);
            if (ObjectUtils.isEmpty(structureTestObject)) {
                structureTestObject = createStructureTestObject(data);
                insertStructureTestObjects.add(structureTestObject);
            } else {
                updateStructureTestObject(structureTestObject, data);
                updateStructureTestObjects.add(structureTestObject);
            }
            String productKey = data.getName() + "_" + data.getNameEn();
            Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>()
                    .eq(Product::getName, data.getName())
                    .eq(Product::getNameEn, data.getNameEn()));
            if (ObjectUtils.isEmpty(product)) {
                product = createProduct(data, structureTestObject.getId(), workShopMap);
                insertProducts.add(product);
            } else {
                updateProduct(product, data, structureTestObject.getId(), workShopMap);
                updateProducts.add(product);
            }
        }
        // æ‰¹é‡æ’入和更新
        if (!insertStructureTestObjects.isEmpty()) {
            structureTestObjectService.saveOrUpdateBatch(insertStructureTestObjects);
        }
        if (!updateStructureTestObjects.isEmpty()) {
            structureTestObjectService.updateBatchById(updateStructureTestObjects);
        }
        if (!insertProducts.isEmpty()) {
            productService.saveOrUpdateBatch(insertProducts);
        }
        if (!updateProducts.isEmpty()) {
            productService.updateBatchById(updateProducts);
        }
    }
    private Map<String, StructureTestObject> getStructureTestObjectMap(List<StructureTestObjectData> list) {
        List<String> specimenNames = list.stream().map(StructureTestObjectData::getSpecimenName).collect(Collectors.toList());
        List<String> specimenNamesEn = list.stream().map(StructureTestObjectData::getSpecimenNameEn).collect(Collectors.toList());
        List<StructureTestObject> structureTestObjects = structureTestObjectMapper.selectList(new LambdaQueryWrapper<StructureTestObject>()
                .in(StructureTestObject::getSpecimenName, specimenNames)
                .in(StructureTestObject::getSpecimenNameEn, specimenNamesEn));
        Map<String, StructureTestObject> map = new HashMap<>();
        for (StructureTestObject obj : structureTestObjects) {
            map.put(obj.getSpecimenName() + "_" + obj.getSpecimenNameEn(), obj);
        }
        return map;
    }
    private Map<String, WorkShop> getWorkShopMap(List<StructureTestObjectData> list) {
        List<String> workShopNames = list.stream()
        // é˜¶æ®µ3: é¢„处理车间信息
        Set<String> workShopNames = list.stream()
                .map(StructureTestObjectData::getWorkShopName)
                .filter(StringUtils::isNotEmpty)
                .distinct()
                .collect(Collectors.toList());
        List<WorkShop> workShops = workShopMapper.selectList(new LambdaQueryWrapper<WorkShop>()
                .in(WorkShop::getName, workShopNames));
        Map<String, WorkShop> map = new HashMap<>();
        for (WorkShop workShop : workShops) {
            map.put(workShop.getName(), workShop);
        }
        return map;
    }
                .collect(Collectors.toSet());
    private StructureTestObject createStructureTestObject(StructureTestObjectData data) {
        StructureTestObject structureTestObject = new StructureTestObject();
        structureTestObject.setLaboratoryId(9);
        structureTestObject.setSpecimenName(data.getSpecimenName());
        structureTestObject.setSpecimenNameEn(data.getSpecimenNameEn());
        structureTestObject.setCode(data.getCode());
        structureTestObject.setWorkShopName("");
        return structureTestObject;
    }
        Map<String, WorkShop> workShopCache = workShopNames.isEmpty() ?
                Collections.emptyMap() :
                workShopMapper.selectList(Wrappers.<WorkShop>lambdaQuery()
                                .in(WorkShop::getName, workShopNames))
                        .stream()
                        .collect(Collectors.toMap(WorkShop::getName, Function.identity()));
    private void updateStructureTestObject(StructureTestObject structureTestObject, StructureTestObjectData data) {
        structureTestObject.setCode(data.getCode());
        structureTestObject.setLaboratoryId(9);
    }
        // é˜¶æ®µ4: å‡†å¤‡æ‰¹é‡æ“ä½œæ•°æ®
        List<StructureTestObject> structureTestObjectsToInsert = new ArrayList<>();
        List<StructureTestObject> structureTestObjectsToUpdate = new ArrayList<>();
        List<Product> productsToInsert = new ArrayList<>();
        List<Product> productsToUpdate = new ArrayList<>();
    private Product createProduct(StructureTestObjectData data, Integer objectId, Map<String, WorkShop> workShopMap) {
        Product product = new Product();
        product.setName(data.getName());
        product.setNameEn(data.getNameEn());
        if (StringUtils.isNotEmpty(data.getWorkShopName())) {
            WorkShop workShop = workShopMap.get(data.getWorkShopName());
            if (workShop == null) {
                throw new BaseException("请先维护车间信息");
        // é˜¶æ®µ5: ä¸»å¤„理逻辑(仅处理结构测试对象)
        List<StructureTestObjectData> pendingProducts = new ArrayList<>(); // æ–°å¢žï¼šæš‚存待处理的产品数据
        for (StructureTestObjectData i : list) {
            // å¤„理结构测试对象(逻辑不变)
            String specimenKey = i.getSpecimenName() + "|" + i.getSpecimenNameEn();
            StructureTestObject structureTestObject = existStructureTestObjects.get(specimenKey);
            if (structureTestObject == null) {
                StructureTestObject newObj = createNewStructureTestObject(i, workShopCache); // ä¿®æ”¹ï¼šä¼ å…¥è½¦é—´ç¼“å­˜
                structureTestObjectsToInsert.add(newObj);
                existStructureTestObjects.put(specimenKey, newObj);
            } else {
                updateExistingStructureTestObject(structureTestObject, i);
                structureTestObjectsToUpdate.add(structureTestObject);
            }
            product.setWorkShopId(workShop.getId());
            // æš‚存产品处理数据(新增)
            pendingProducts.add(i);
        }
        product.setWorkShopName(data.getWorkShopName());
        product.setObjectId(objectId);
        return product;
        // é˜¶æ®µ6: å…ˆå¤„理结构测试对象批量操作
        executeStructureTestObjectBatch(structureTestObjectsToInsert, structureTestObjectsToUpdate);
        // é˜¶æ®µ7: æ›´æ–°ç¼“存中的ID(关键新增步骤)
        refreshStructureTestObjectIds(existStructureTestObjects, structureTestObjectsToInsert);
        // é˜¶æ®µ8: å¤„理产品数据
        processProducts(pendingProducts, existStructureTestObjects, workShopCache,
                productsToInsert, productsToUpdate);
        // é˜¶æ®µ9: æ‰§è¡Œäº§å“æ‰¹é‡æ“ä½œ
        executeProductBatch(productsToInsert, productsToUpdate);
    }
    private void updateProduct(Product product, StructureTestObjectData data, Integer objectId, Map<String, WorkShop> workShopMap) {
        if (StringUtils.isNotEmpty(data.getWorkShopName())) {
            WorkShop workShop = workShopMap.get(data.getWorkShopName());
            if (workShop == null) {
                throw new BaseException("请先维护车间信息");
            }
            product.setWorkShopId(workShop.getId());
    // æ›´æ–°çŽ°æœ‰ç»“æž„æµ‹è¯•å¯¹è±¡
    private void updateExistingStructureTestObject(StructureTestObject obj, StructureTestObjectData data) {
        obj.setCode(data.getCode());
        obj.setLaboratoryId(9);
    }
    // å¤„理产品数据
    private void processProductData(StructureTestObjectData data,
                                    Integer objectId,
                                    Map<String, WorkShop> workShopCache,
                                    List<Product> insertList,
                                    List<Product> updateList) {
        // æž„建产品唯一标识
        String productKey = data.getName() + "|" + data.getNameEn();
        // æ£€æŸ¥å†…存中是否已处理过该产品
        Optional<Product> existingProduct = findProductInBatchLists(productKey, insertList, updateList);
        // å¦‚果内存中不存在,查询数据库
        if (!existingProduct.isPresent()) {
            Product dbProduct = productMapper.selectOne(Wrappers.<Product>lambdaQuery()
                    .eq(Product::getName, data.getName())
                    .eq(Product::getNameEn, data.getNameEn())
                    .last("limit 1"));
            existingProduct = Optional.ofNullable(dbProduct);
        }
        product.setWorkShopName(data.getWorkShopName());
        // åˆ›å»ºæˆ–更新产品
        Product product = existingProduct.orElseGet(Product::new);
        boolean isNew = product.getId() == null;
        // è®¾ç½®äº§å“å±žæ€§
        setupProduct(product, data, objectId, workShopCache);
        // åŠ å…¥å¯¹åº”åˆ—è¡¨
        if (isNew) {
            insertList.add(product);
        } else {
            updateList.add(product);
        }
    }
    // åœ¨äº§å“æ‰¹é‡åˆ—表中查找
    private Optional<Product> findProductInBatchLists(String productKey,
                                                      List<Product> insertList,
                                                      List<Product> updateList) {
        return Stream.concat(insertList.stream(), updateList.stream())
                .filter(p -> (p.getName() + "|" + p.getNameEn()).equals(productKey))
                .findFirst();
    }
    // è®¾ç½®äº§å“ä¿¡æ¯
    private void setupProduct(Product product,
                              StructureTestObjectData data,
                              Integer objectId,
                              Map<String, WorkShop> workShopCache) {
        product.setName(data.getName());
        product.setNameEn(data.getNameEn());
        product.setObjectId(objectId);
        // å¤„理车间信息
        if (StringUtils.isNotEmpty(data.getWorkShopName())) {
            WorkShop workShop = workShopCache.get(data.getWorkShopName());
            if (workShop == null) {
                throw new BaseException("车间信息未维护: " + data.getWorkShopName());
            }
            product.setWorkShopId(workShop.getId());
            product.setWorkShopName(data.getWorkShopName());
        }
    }
    // åˆ›å»ºç»“构测试对象(使用缓存车间信息)
    private StructureTestObject createNewStructureTestObject(StructureTestObjectData data,
                                                             Map<String, WorkShop> workShopCache) {
        StructureTestObject obj = new StructureTestObject();
        obj.setLaboratoryId(9);
        obj.setSpecimenName(data.getSpecimenName());
        obj.setSpecimenNameEn(data.getSpecimenNameEn());
        obj.setCode(data.getCode());
        obj.setObjectType(data.getObjectType());
        // ä½¿ç”¨ç¼“存获取车间信息
        if (StringUtils.isNotEmpty(data.getWorkShopName())) {
            WorkShop workShop = workShopCache.get(data.getWorkShopName());
            if (workShop == null) {
                throw new BaseException("车间信息未维护: " + data.getWorkShopName());
            }
            obj.setWorkShopId(workShop.getId());
            obj.setWorkShopName(data.getWorkShopName());
        } else {
            obj.setWorkShopName("");
        }
        return obj;
    }
    // åˆ·æ–°ç»“构测试对象ID(关键方法)
    private void refreshStructureTestObjectIds(
            Map<String, StructureTestObject> existStructureTestObjects,
            List<StructureTestObject> insertedObjects) {
        insertedObjects.forEach(obj -> {
            String key = obj.getSpecimenName() + "|" + obj.getSpecimenNameEn();
            existStructureTestObjects.get(key).setId(obj.getId()); // æ›´æ–°ç¼“存中的ID
        });
    }
    // å¤„理产品数据(独立方法)
    private void processProducts(List<StructureTestObjectData> pendingProducts,
                                 Map<String, StructureTestObject> structureTestObjectCache,
                                 Map<String, WorkShop> workShopCache,
                                 List<Product> insertList,
                                 List<Product> updateList) {
        // é˜¶æ®µ5原有产品处理逻辑迁移至此
        pendingProducts.forEach(i -> {
            String specimenKey = i.getSpecimenName() + "|" + i.getSpecimenNameEn();
            StructureTestObject sto = structureTestObjectCache.get(specimenKey);
            processProductData(
                    i,
                    sto.getId(), // æ­¤æ—¶ID已正确设置
                    workShopCache,
                    insertList,
                    updateList
            );
        });
    }
    // åˆ†æ‹†æ‰¹é‡æ“ä½œæ–¹æ³•
    private void executeStructureTestObjectBatch(List<StructureTestObject> toInsert,
                                                 List<StructureTestObject> toUpdate) {
        if (!toInsert.isEmpty()) {
            structureTestObjectMapper.insertBatchSomeColumn(toInsert);
        }
        if (!toUpdate.isEmpty()) {
            structureTestObjectService.updateBatchById(toUpdate);
        }
    }
    private void executeProductBatch(List<Product> toInsert,
                                     List<Product> toUpdate) {
        if (!toInsert.isEmpty()) {
            productMapper.insertBatchSomeColumn(toInsert);
        }
        if (!toUpdate.isEmpty()) {
            productService.updateBatchById(toUpdate);
        }
    }
}
basic-server/src/main/java/com/ruoyi/basic/service/impl/StandardMethodServiceImpl.java
@@ -171,58 +171,76 @@
    }
    public void addStructureTest(List<Object> structureTestObjectIdList, List<StandardMethod> standardMethodList) {
        // ç”¨äºŽå­˜å‚¨æ–°å¢žã€æ›´æ–°å’Œåˆ é™¤çš„æ•°æ®
        List<StandardMethod> updateList = new ArrayList<>();
        List<Integer> deleteListId = new ArrayList<>();
        List<StandardMethod> addList = new ArrayList<>();
        // å…ˆå°† Excel æ•°æ®æŒ‰ key åˆ†ç»„
        // å…ˆå°† Excel æ•°æ®æŒ‰ code åˆ†ç»„,并合并 field
        Map<String, StandardMethod> excelDataMap = new HashMap<>();
        for (StandardMethod excelMethod : standardMethodList) {
            String key = generateKey(excelMethod);
            excelDataMap.put(key, excelMethod);
            if (excelDataMap.containsKey(key)) {
                // å¦‚果已存在相同的 code,则合并 field
                StandardMethod existingMethod = excelDataMap.get(key);
                String mergedField = mergeFields(existingMethod.getField(), excelMethod.getField());
                existingMethod.setField(mergedField);
            } else {
                // å¦åˆ™ç›´æŽ¥æ·»åŠ åˆ° map ä¸­
                excelDataMap.put(key, excelMethod);
            }
        }
//        if (!structureTestObjectIdList.isEmpty()) {
            // ä»¥ excel ä¸­çš„组名查询数据库中的分组
            List<StandardMethod> allDbMethods = new ArrayList<>();
            for (Object j : structureTestObjectIdList) {
                List<StandardMethod> standardMethods = baseMapper.selectList(new LambdaQueryWrapper<StandardMethod>()
                        .like(StandardMethod::getStructureTestObjectId, "\"" + j + "\""));
                allDbMethods.addAll(standardMethods);
            }
        // æŸ¥è¯¢æ•°æ®åº“中的分组数据
        List<StandardMethod> allDbMethods = new ArrayList<>();
        for (Object j : structureTestObjectIdList) {
            List<StandardMethod> standardMethods = baseMapper.selectList(
                    new LambdaQueryWrapper<StandardMethod>()
                            .apply("JSON_CONTAINS(structure_test_object_id, {0})", j) // MySQL JSON æŸ¥è¯¢
            );
            allDbMethods.addAll(standardMethods);
        }
            // å°†æ•°æ®åº“数据按 key åˆ†ç»„
            Map<String, StandardMethod> dbDataMap = new HashMap<>();
            for (StandardMethod dbMethod : allDbMethods) {
                String key = generateKey(dbMethod);
        // å°†æ•°æ®åº“数据按 code åˆ†ç»„,并合并 field
        Map<String, StandardMethod> dbDataMap = new HashMap<>();
        for (StandardMethod dbMethod : allDbMethods) {
            String key = generateKey(dbMethod);
            if (dbDataMap.containsKey(key)) {
                // å¦‚果已存在相同的 code,则合并 field
                StandardMethod existingMethod = dbDataMap.get(key);
                String mergedField = mergeFields(existingMethod.getField(), dbMethod.getField());
                existingMethod.setField(mergedField);
            } else {
                // å¦åˆ™ç›´æŽ¥æ·»åŠ åˆ° map ä¸­
                dbDataMap.put(key, dbMethod);
            }
        }
            // å¤„理更新和新增
            for (Map.Entry<String, StandardMethod> entry : excelDataMap.entrySet()) {
                String key = entry.getKey();
                StandardMethod excelMethod = entry.getValue();
                StandardMethod dbMethod = dbDataMap.get(key);
                if (dbMethod != null) {
                    // æ›´æ–°
                    excelMethod.setId(dbMethod.getId());
                    updateList.add(excelMethod);
                } else {
                    // æ–°å¢ž
                    addList.add(excelMethod);
                }
        // å¤„理更新和新增
        for (Map.Entry<String, StandardMethod> entry : excelDataMap.entrySet()) {
            String key = entry.getKey();
            StandardMethod excelMethod = entry.getValue();
            StandardMethod dbMethod = dbDataMap.get(key);
            if (dbMethod != null) {
                // æ›´æ–°
                excelMethod.setId(dbMethod.getId());
                updateList.add(excelMethod);
            } else {
                // æ–°å¢ž
                addList.add(excelMethod);
            }
        }
            // å¤„理删除
            for (Map.Entry<String, StandardMethod> entry : dbDataMap.entrySet()) {
                String key = entry.getKey();
                if (!excelDataMap.containsKey(key)) {
                    StandardMethod dbMethod = entry.getValue();
                    deleteListId.add(dbMethod.getId());
                }
        // å¤„理删除
        for (Map.Entry<String, StandardMethod> entry : dbDataMap.entrySet()) {
            String key = entry.getKey();
            if (!excelDataMap.containsKey(key)) {
                StandardMethod dbMethod = entry.getValue();
                deleteListId.add(dbMethod.getId());
            }
        }
            // æ‰§è¡Œæ‰¹é‡æ“ä½œ
        if (!addList.isEmpty()) {
            // æ–°å¢ž
            baseMapper.insertBatchSomeColumn(addList);
@@ -241,8 +259,26 @@
        }
    }
    private String mergeFields(String field1, String field2) {
        if (field1 == null || field1.isEmpty()) {
            return field2;
        }
        if (field2 == null || field2.isEmpty()) {
            return field1;
        }
        // ä½¿ç”¨ Set åŽ»é‡
        String[] fields1 = field1.split(",");
        String[] fields2 = field2.split(",");
        Set<String> uniqueFields = new HashSet<>(Arrays.asList(fields1));
        uniqueFields.addAll(Arrays.asList(fields2));
        // è¿”回逗号拼接的结果
        return String.join(",", uniqueFields);
    }
    private String generateKey(StandardMethod method) {
        return method.getStructureTestObjectId() + "-" + method.getCode() + "-" + method.getField();
        return method.getCode();
    }
    // æ ¼å¼åŒ–数据
cnas-device/src/main/java/com/ruoyi/device/mapper/DeviceMapper.java
@@ -1,11 +1,11 @@
package com.ruoyi.device.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.device.dto.DeviceDto;
import com.ruoyi.device.pojo.Device;
import com.ruoyi.framework.mybatis_config.MyBaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -15,7 +15,7 @@
/**
 * è®¾å¤‡(Device)表数据库访问层
 */
public interface DeviceMapper extends BaseMapper<Device> {
public interface DeviceMapper extends MyBaseMapper<Device> {
    IPage<Device> selectDeviceParameter(Page page, QueryWrapper<Device> ew);
    List<Device> selectEquipmentOverview(Page page, QueryWrapper<Device> ew);
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceServiceImpl.java
@@ -607,12 +607,12 @@
            }
        }
        // æ‰¹é‡æ’入(使用MyBatis-Plus的insertBatch,默认batchSize=1000)
        // æ‰¹é‡æ’å…¥
        if (CollUtil.isNotEmpty(toInsert)) {
            saveOrUpdateBatch(toInsert);
            baseMapper.insertBatchSomeColumn(toInsert);
        }
        // æ‰¹é‡æ›´æ–°ï¼ˆä½¿ç”¨MyBatis-Plus的updateBatchById,默认batchSize=1000)
        // æ‰¹é‡æ›´æ–°
        if (CollUtil.isNotEmpty(toUpdate)) {
            updateBatchById(toUpdate);
        }
pom.xml
@@ -44,7 +44,7 @@
        <minio.version>8.4.3</minio.version>
        <okhttp.version>4.9.0</okhttp.version>
        <hutool.version>5.8.18</hutool.version>
        <easyexcel.version>3.3.2</easyexcel.version>
        <easyexcel.version>3.3.3</easyexcel.version>
        <poi.tl.version>1.12.2</poi.tl.version>
    </properties>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PersonDto.java
@@ -17,4 +17,6 @@
    private Integer roleId;
    private Integer deptId;
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PersonnelHeaderApi.java
@@ -183,6 +183,7 @@
                user.setIsCustom(0);
                user.setPassword(SecurityUtils.encryptPassword("zttZTT123!"));
                user.setCompany(BeanUtil.isNotEmpty(custom) ? (custom.getId() + "") : companyName);
                user.setDeptId(personDto.getDeptId());
                userMapper.insert(user);
            } else {
                user.setName(person.getName());
@@ -190,6 +191,7 @@
                user.setEmail(person.getCompanyEmail());
                user.setIsCustom(0);
                user.setCompany(BeanUtil.isNotEmpty(custom) ? (custom.getId() + "") : companyName);
                user.setDeptId(personDto.getDeptId());
                userMapper.updateById(user);
            }
        });