| | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.dto.ProductDto; |
| | | import com.ruoyi.basic.dto.ProductModelDto; |
| | | import com.ruoyi.basic.dto.*; |
| | | import com.ruoyi.basic.mapper.ProductMapper; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.basic.service.IProductModelService; |
| | | import com.ruoyi.common.utils.OrderUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.common.utils.uuid.IdUtils; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.AbstractMap; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | |
| | | @Override |
| | | public int addOrEditProductModel(ProductModelDto productModelDto) { |
| | | |
| | | if(StringUtils.isEmpty(productModelDto.getProductName())){ |
| | | throw new RuntimeException("产品名称不能为空"); |
| | | } |
| | | Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>() |
| | | // .eq(Product::getModel, productModelDto.getModel()) |
| | | .eq(Product::getProductName, productModelDto.getProductName())); |
| | | if (productModelDto.getId() == null) { |
| | | if(product == null){ |
| | | product = new Product(); |
| | | product.setProductName(productModelDto.getProductName()); |
| | | productMapper.insert(product); |
| | | } |
| | | ProductModel productModel = new ProductModel(); |
| | | BeanUtils.copyProperties(productModelDto,productModel); |
| | | productModel.setProductId(product.getId()); |
| | | return productModelMapper.insert(productModel); |
| | | } else { |
| | | Product product1 = productMapper.selectById(productModelDto.getProductId()); |
| | | if(product1 != null){ |
| | | product1.setProductName(productModelDto.getProductName()); |
| | | productMapper.updateById(product1); |
| | | } |
| | | |
| | | return productModelMapper.updateById(productModelDto); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public int delProductModel(Long[] ids) { |
| | |
| | | return productModelMapper.selectPage(page, queryWrapper); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean importProduct(MultipartFile file) { |
| | | try { |
| | | ExcelUtil<ProductModel> productModelExcelUtil = new ExcelUtil<>(ProductModel.class); |
| | | List<ProductModel> productModelList = productModelExcelUtil.importExcel(file.getInputStream()); |
| | | Map<String, List<ProductModel>> collect = productModelList.stream().collect(Collectors.groupingBy(ProductModel::getProductName)); |
| | | collect.forEach((k,v)->{ |
| | | Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>().eq(Product::getProductName, k).last("LIMIT 1")); |
| | | if (product != null) { |
| | | v.forEach(productModel -> { |
| | | productModel.setProductId(product.getId()); |
| | | }); |
| | | this.saveOrUpdateBatch(v); |
| | | ExcelUtil<ProductModelExcelCopyDto> productModelExcelUtil = new ExcelUtil<>(ProductModelExcelCopyDto.class); |
| | | List<ProductModelExcelCopyDto> productModelList = productModelExcelUtil.importExcel(file.getInputStream()); |
| | | // List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>() |
| | | // .isNull(Product::getParentId)); |
| | | // if(CollectionUtils.isEmpty(productList)) { |
| | | // throw new RuntimeException("请先添加父级产品"); |
| | | // } |
| | | 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; |
| | | }catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 抽取通用方法:查询或新增产品 |
| | | */ |
| | | private Product getOrCreateProduct(String productName, String model) { |
| | | // 精准查询:产品名称+型号(避免同名不同型号的问题) |
| | | Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>() |
| | | .eq(Product::getProductName, productName) |
| | | // .eq(Product::getModel, model) |
| | | .last("limit 1")); |
| | | |
| | | if (product == null) { |
| | | product = new Product(); |
| | | product.setProductName(productName); |
| | | // product.setModel(model); // 补充型号,字段更完整 |
| | | product.setParentId(null); |
| | | productMapper.insert(product); |
| | | } |
| | | return product; |
| | | } |
| | | |
| | | /** |
| | | * 抽取通用方法:处理产品型号(新增/更新) |
| | | */ |
| | | private void processProductModel(List<ProductModelExcelCopyDto> dtoList, |
| | | Long productId, String model, String drawingNumber) { |
| | | for (ProductModelExcelCopyDto dto : dtoList) { |
| | | // 查询条件:型号+图纸编号(更精准,符合分组逻辑) |
| | | ProductModel productModel = productModelMapper.selectOne(new LambdaQueryWrapper<ProductModel>() |
| | | .eq(ProductModel::getModel, model) |
| | | .last("limit 1")); |
| | | |
| | | if (productModel == null) { |
| | | productModel = new ProductModel(); |
| | | BeanUtils.copyProperties(dto, productModel); |
| | | // 兜底默认值,避免空值 |
| | | if (productModel.getProductType() == null) { |
| | | productModel.setProductType(1); |
| | | } |
| | | productModel.setProductId(productId); |
| | | productModelMapper.insert(productModel); |
| | | } else { |
| | | BeanUtils.copyProperties(dto, productModel); |
| | | productModel.setProductId(productId); |
| | | productModelMapper.updateById(productModel); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 递归导入树形产品数据 |
| | | * @param excelDto Excel解析后的树形节点 |
| | | * @param parentId 父节点ID(顶级节点传null/0) |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) // 事务保证,失败则回滚 |
| | | public void recursiveSaveProduct(ProductModelExcelDto excelDto, Long parentId) { |
| | | // 1. 构建当前节点的Product实体 |
| | | Product product = new Product(); |
| | | product.setProductName(excelDto.getProductName()); |
| | | product.setParentId(parentId); // 父节点ID |
| | | |
| | | // 2. 插入当前节点,MyBatis会自动回填product的id属性 |
| | | productMapper.insert(product); |
| | | Long currentId = product.getId(); // 获取当前节点主键 |
| | | |
| | | // 3. 递归处理子节点 |
| | | if (excelDto.getChildren() != null && !excelDto.getChildren().isEmpty()) { |
| | | for (ProductModelExcelDto childDto : excelDto.getChildren()) { |
| | | recursiveSaveProduct(childDto, currentId); // 父ID为当前节点ID |
| | | } |
| | | } |
| | | |
| | | // 4. (可选)处理items数据(如果需要插入到关联表) |
| | | if (excelDto.getItems() != null && !excelDto.getItems().isEmpty()) { |
| | | for (ProductModelExcelItemDto item : excelDto.getItems()) { |
| | | // 插入item关联数据,关联currentId |
| | | // 构建ProductModel实体 |
| | | ProductModel productModel = new ProductModel(); |
| | | productModel.setProductId(currentId); // 关联当前产品节点ID |
| | | productModel.setModel(item.getModel()); // 从ItemDTO获取型号 |
| | | productModel.setUnit(item.getUnit()); // 从ItemDTO获取单位 |
| | | productModel.setDrawingNumber(item.getDrawingNumber()); // 图纸编号 |
| | | productModel.setProductType(item.getProductType()); |
| | | // 插入product_model表 |
| | | productModelMapper.insert(productModel); |
| | | } |
| | | } |
| | | } |
| | | } |