src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -12,6 +12,7 @@
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductModelService;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
@@ -31,6 +32,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@@ -129,46 +131,52 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean importProduct(MultipartFile file) {
    public void importProduct(MultipartFile file, HttpServletResponse response) {
        ExcelUtil<ProductModelExcelCopyDto> productModelExcelUtil = new ExcelUtil<>(ProductModelExcelCopyDto.class);
        List<ProductModelExcelCopyDto> productModelList = null;
        try {
            ExcelUtil<ProductModelExcelCopyDto> productModelExcelUtil = new ExcelUtil<>(ProductModelExcelCopyDto.class);
            List<ProductModelExcelCopyDto> productModelList = productModelExcelUtil.importExcel(file.getInputStream());
            if(CollectionUtils.isNotEmpty(productModelList)){
                // 2. 按产品名称,图纸编号分组
                Map<Map.Entry<String, String>, List<ProductModelExcelCopyDto>> groupedByProductNameAndDrawingNumber =
                        productModelList.stream()
                                .collect(Collectors.groupingBy(
                                        dto -> new AbstractMap.SimpleEntry<>(
                                                dto.getProductName(),
                                                dto.getModel()
                                        )
                                ));
                // 2. 遍历分组结果处理数据
                for (Map.Entry<Map.Entry<String, String>, List<ProductModelExcelCopyDto>> entry : groupedByProductNameAndDrawingNumber.entrySet()) {
                    Map.Entry<String, String> groupKey = entry.getKey();
                    String productName = groupKey.getKey(); // 产品名称
                    String drawingNumber = groupKey.getValue(); // 图纸编号
                    List<ProductModelExcelCopyDto> dtoList = entry.getValue();
                    // 空列表跳过,避免后续NPE
                    if (CollectionUtils.isEmpty(dtoList)) {
                        continue;
                    }
                    ProductModelExcelCopyDto firstDto = dtoList.get(0);
                    String model = firstDto.getModel();
                    // 3. 查询/新增产品(按产品名称+图纸编号,更精准)
                    Product product = getOrCreateProduct(productName, drawingNumber);
                    // 4. 批量处理产品型号(按图纸编号+型号)
                    processProductModel(dtoList, product.getId(), model, drawingNumber);
                }
            }
            return true;
            productModelList = productModelExcelUtil.importExcel(file.getInputStream());
        }catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("文件解析失败");
        }
        return false;
        if(CollectionUtils.isNotEmpty(productModelList)){
            // 2. 按产品名称,图纸编号分组
            Map<Map.Entry<String, String>, List<ProductModelExcelCopyDto>> groupedByProductNameAndDrawingNumber =
                    productModelList.stream()
                            .collect(Collectors.groupingBy(
                                    dto -> new AbstractMap.SimpleEntry<>(
                                            dto.getProductName(),
                                            dto.getModel()
                                    )
                            ));
            List<ProductModelExcelCopyErrorDto> errorList = new ArrayList<>();
            // 2. 遍历分组结果处理数据
            for (Map.Entry<Map.Entry<String, String>, List<ProductModelExcelCopyDto>> entry : groupedByProductNameAndDrawingNumber.entrySet()) {
                Map.Entry<String, String> groupKey = entry.getKey();
                String productName = groupKey.getKey(); // 产品名称
                String drawingNumber = groupKey.getValue(); // 图纸编号
                List<ProductModelExcelCopyDto> dtoList = entry.getValue();
                // 空列表跳过,避免后续NPE
                if (CollectionUtils.isEmpty(dtoList)) {
                    continue;
                }
                ProductModelExcelCopyDto firstDto = dtoList.get(0);
                String model = firstDto.getModel();
                // 3. 查询/新增产品(按产品名称+图纸编号,更精准)
                Product product = getOrCreateProduct(productName, drawingNumber);
                // 4. 批量处理产品型号(按图纸编号+型号)
                processProductModel(dtoList, product.getId(), model, drawingNumber,errorList);
            }
            if(CollectionUtils.isNotEmpty(errorList)){
                // 5. 批量处理错误数据
                ExcelUtil<ProductModelExcelCopyErrorDto> errorExcelUtil = new ExcelUtil<>(ProductModelExcelCopyErrorDto.class);
                errorExcelUtil.exportExcel(response,errorList, "错误数据");
            }
        }
    }
    /**
@@ -195,11 +203,14 @@
     * 抽取通用方法:处理产品型号(新增/更新)
     */
    private void processProductModel(List<ProductModelExcelCopyDto> dtoList,
                                     Long productId, String model, String drawingNumber) {
                                     Long productId,
                                     String model,
                                     String drawingNumber,
                                     List<ProductModelExcelCopyErrorDto> errorList) {
        // 查询所有工艺路线
        List<ProductProcess> productRoutes = productProcessMapper.selectList(new QueryWrapper<ProductProcess>());
        if(CollectionUtils.isEmpty(productRoutes)){
            throw new RuntimeException("请先创建产品工艺路线");
            productRoutes = new ArrayList<>();
        }
        for (ProductModelExcelCopyDto dto : dtoList) {
            // 查询条件:型号+图纸编号(更精准,符合分组逻辑)