| | |
| | | package com.ruoyi.production.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.production.dto.ProductMaterialSkuDto; |
| | | import com.ruoyi.production.mapper.ProductMaterialMapper; |
| | | import com.ruoyi.production.mapper.ProductMaterialSkuMapper; |
| | | import com.ruoyi.production.pojo.ProductMaterial; |
| | | import com.ruoyi.production.pojo.ProductMaterialSku; |
| | | import com.ruoyi.production.dto.ProductMaterialSkuImportDto; |
| | | import com.ruoyi.production.service.ProductMaterialSkuService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <br> |
| | |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class ProductMaterialSkuServiceImpl |
| | | extends ServiceImpl<ProductMaterialSkuMapper, ProductMaterialSku> |
| | | implements ProductMaterialSkuService { |
| | | public class ProductMaterialSkuServiceImpl extends ServiceImpl<ProductMaterialSkuMapper, ProductMaterialSku> implements ProductMaterialSkuService { |
| | | |
| | | @Autowired |
| | | private ProductMaterialMapper productMaterialMapper; |
| | |
| | | * 查询物料规格列表 |
| | | */ |
| | | @Override |
| | | public List<ProductMaterialSkuDto> productMaterialSkuList(Long materialId) { |
| | | |
| | | if (materialId == null) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | LambdaQueryWrapper<ProductMaterialSku> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(ProductMaterialSku::getMaterialId, materialId) |
| | | .orderByAsc(ProductMaterialSku::getId); |
| | | List<ProductMaterialSku> skuList = this.list(queryWrapper); |
| | | if (skuList == null || skuList.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 查询物料信息 |
| | | ProductMaterial material = productMaterialMapper.selectById(materialId); |
| | | |
| | | String materialName = material != null ? material.getMaterialName() : null; |
| | | String baseUnit = material != null ? material.getBaseUnit() : null; |
| | | List<ProductMaterialSkuDto> result = new ArrayList<>(skuList.size()); |
| | | for (ProductMaterialSku sku : skuList) { |
| | | ProductMaterialSkuDto dto = new ProductMaterialSkuDto(); |
| | | dto.setMaterialId(materialId); |
| | | dto.setMaterialName(materialName); |
| | | dto.setBaseUnit(baseUnit); |
| | | dto.setSkuId(sku.getId()); |
| | | dto.setSpecification(sku.getSpecification()); |
| | | dto.setSupplyType(sku.getSupplyType()); |
| | | result.add(dto); |
| | | } |
| | | |
| | | return result; |
| | | public Page<ProductMaterialSkuDto> productMaterialSkuList(Page<ProductMaterialSkuDto> page, ProductMaterialSkuDto dto, Integer type) { |
| | | return baseMapper.selectSkuWithMaterialPage(page, dto, type); |
| | | } |
| | | |
| | | /** |
| | |
| | | public void addProductMaterialSku(ProductMaterialSku sku) { |
| | | validateProductMaterialSku(sku, false); |
| | | // 校验物料是否存在 |
| | | ProductMaterial material = productMaterialMapper.selectById(sku.getMaterialId()); |
| | | ProductMaterial material = productMaterialMapper.selectById(sku.getProductId()); |
| | | if (material == null) { |
| | | throw new ServiceException("物料不存在"); |
| | | } |
| | | // 校验规格是否重复 |
| | | if (existsSameSpecification(sku.getMaterialId(), sku.getSpecification(), null)) { |
| | | if (existsSameSpecification(sku.getProductId(), sku.getModel(), null)) { |
| | | throw new ServiceException("该物料已存在相同规格"); |
| | | } |
| | | LocalDateTime now = LocalDateTime.now(); |
| | |
| | | if (!this.save(sku)) { |
| | | throw new ServiceException("新增物料规格失败"); |
| | | } |
| | | log.info("新增物料规格成功 materialId={}, specification={}", sku.getMaterialId(), sku.getSpecification()); |
| | | log.info("新增物料规格成功 materialId={}, specification={}", sku.getProductId(), sku.getModel()); |
| | | } |
| | | |
| | | /** |
| | |
| | | public void updateProductMaterialSku(ProductMaterialSku sku) { |
| | | validateProductMaterialSku(sku, true); |
| | | // 校验规格是否重复 |
| | | if (existsSameSpecification(sku.getMaterialId(), sku.getSpecification(), sku.getId())) { |
| | | if (existsSameSpecification(sku.getProductId(), sku.getModel(), sku.getId())) { |
| | | throw new ServiceException("该物料已存在相同规格"); |
| | | } |
| | | sku.setUpdateTime(LocalDateTime.now()); |
| | |
| | | if (requireId && sku.getId() == null) { |
| | | throw new ServiceException("主键ID不能为空"); |
| | | } |
| | | if (sku.getMaterialId() == null) { |
| | | if (sku.getProductId() == null) { |
| | | throw new ServiceException("物料ID不能为空"); |
| | | } |
| | | if (StringUtils.isEmpty(sku.getSpecification())) { |
| | | if (StringUtils.isEmpty(sku.getModel())) { |
| | | throw new ServiceException("规格不能为空"); |
| | | } |
| | | } |
| | |
| | | */ |
| | | private boolean existsSameSpecification(Long materialId, String specification, Long excludeId) { |
| | | LambdaQueryWrapper<ProductMaterialSku> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(ProductMaterialSku::getMaterialId, materialId) |
| | | .eq(ProductMaterialSku::getSpecification, specification); |
| | | queryWrapper.eq(ProductMaterialSku::getProductId, materialId) |
| | | .eq(ProductMaterialSku::getModel, specification); |
| | | if (excludeId != null) { |
| | | queryWrapper.ne(ProductMaterialSku::getId, excludeId); |
| | | } |
| | | |
| | | return this.count(queryWrapper) > 0; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void importProdData(MultipartFile file, Long materialId) { |
| | | if (materialId == null) { |
| | | throw new ServiceException("物料ID不能为空"); |
| | | } |
| | | if (file == null || file.isEmpty()) { |
| | | throw new ServiceException("导入文件不能为空"); |
| | | } |
| | | |
| | | ProductMaterial material = productMaterialMapper.selectById(materialId); |
| | | if (material == null) { |
| | | throw new ServiceException("物料不存在"); |
| | | } |
| | | |
| | | ExcelUtil<ProductMaterialSkuImportDto> excelUtil = new ExcelUtil<>(ProductMaterialSkuImportDto.class); |
| | | List<ProductMaterialSkuImportDto> importList; |
| | | try { |
| | | importList = excelUtil.importExcel(file.getInputStream()); |
| | | } catch (Exception e) { |
| | | log.error("导入物料规格Excel解析失败", e); |
| | | throw new ServiceException("Excel解析失败"); |
| | | } |
| | | |
| | | if (importList == null || importList.isEmpty()) { |
| | | throw new ServiceException("Excel没有数据"); |
| | | } |
| | | |
| | | Map<String, ProductMaterialSkuImportDto> specMap = new LinkedHashMap<>(); |
| | | for (ProductMaterialSkuImportDto dto : importList) { |
| | | if (dto == null || StringUtils.isEmpty(dto.getModel())) { |
| | | continue; |
| | | } |
| | | String specification = dto.getModel().trim(); |
| | | if (specification.isEmpty()) { |
| | | continue; |
| | | } |
| | | specMap.putIfAbsent(specification, dto); |
| | | } |
| | | |
| | | if (specMap.isEmpty()) { |
| | | throw new ServiceException("Excel没有有效的规格数据"); |
| | | } |
| | | |
| | | Set<String> specifications = specMap.keySet(); |
| | | |
| | | List<ProductMaterialSku> existList = this.list(new LambdaQueryWrapper<ProductMaterialSku>() |
| | | .eq(ProductMaterialSku::getProductId, materialId) |
| | | .in(ProductMaterialSku::getModel, specifications)); |
| | | Map<String, ProductMaterialSku> existMap = existList.stream() |
| | | .collect(Collectors.toMap(ProductMaterialSku::getModel, sku -> sku, (a, b) -> a)); |
| | | |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | List<ProductMaterialSku> saveList = new ArrayList<>(); |
| | | List<ProductMaterialSku> updateList = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<String, ProductMaterialSkuImportDto> entry : specMap.entrySet()) { |
| | | String specification = entry.getKey(); |
| | | ProductMaterialSkuImportDto dto = entry.getValue(); |
| | | String supplyType = StringUtils.isNotEmpty(dto.getSupplyType()) ? dto.getSupplyType().trim() : null; |
| | | |
| | | ProductMaterialSku exist = existMap.get(specification); |
| | | if (exist == null) { |
| | | ProductMaterialSku sku = new ProductMaterialSku(); |
| | | sku.setProductId(materialId); |
| | | sku.setModel(specification); |
| | | sku.setSupplyType(supplyType); |
| | | sku.setCreateTime(now); |
| | | sku.setUpdateTime(now); |
| | | saveList.add(sku); |
| | | } else { |
| | | boolean needUpdate = false; |
| | | if (supplyType != null && !supplyType.equals(exist.getSupplyType())) { |
| | | exist.setSupplyType(supplyType); |
| | | needUpdate = true; |
| | | } |
| | | if (needUpdate) { |
| | | exist.setUpdateTime(now); |
| | | updateList.add(exist); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (saveList.isEmpty() && updateList.isEmpty()) { |
| | | throw new ServiceException("Excel与现有数据一致,无需导入"); |
| | | } |
| | | |
| | | if (!saveList.isEmpty()) { |
| | | this.saveBatch(saveList); |
| | | } |
| | | if (!updateList.isEmpty()) { |
| | | this.updateBatchById(updateList); |
| | | } |
| | | |
| | | log.info("物料规格导入完成 materialId={}, 新增{}条,更新{}条", materialId, saveList.size(), updateList.size()); |
| | | } |
| | | } |