package com.ruoyi.basic.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
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.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.exception.ServiceException;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.bean.BeanUtils;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.framework.web.domain.AjaxResult;
|
import com.ruoyi.sales.dto.LossProductModelDto;
|
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
|
import com.ruoyi.sales.pojo.SalesLedgerProduct;
|
import com.ruoyi.technology.mapper.TechnologyBomMapper;
|
import com.ruoyi.technology.pojo.TechnologyBom;
|
import lombok.AllArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
/**
|
* 【请填写功能名称】Service业务层处理
|
*
|
* @author ruoyi
|
* @date 2025-05-19
|
*/
|
@Service
|
@AllArgsConstructor
|
public class ProductModelServiceImpl extends ServiceImpl<ProductModelMapper, ProductModel> implements IProductModelService {
|
|
private final ProductMapper productMapper;
|
private final SalesLedgerProductMapper salesLedgerProductMapper;
|
private final TechnologyBomMapper technologyBomMapper;
|
private ProductModelMapper productModelMapper;
|
|
@Override
|
public int addOrEditProductModel(ProductModelDto productModelDto) {
|
String model = StringUtils.trim(productModelDto.getModel());
|
String productCode = StringUtils.trim(productModelDto.getProductCode());
|
String barcode = StringUtils.trim(productModelDto.getBarcode());
|
productModelDto.setModel(model);
|
productModelDto.setProductCode(productCode);
|
productModelDto.setBarcode(barcode);
|
checkModelAndProductCodeUnique(model, productCode, productModelDto.getId());
|
checkBarcodeUnique(barcode, productModelDto.getId());
|
|
if (productModelDto.getId() == null) {
|
ProductModel productModel = new ProductModel();
|
BeanUtils.copyProperties(productModelDto, productModel);
|
return productModelMapper.insert(productModel);
|
} else {
|
return productModelMapper.updateById(productModelDto);
|
}
|
}
|
|
private void checkModelAndProductCodeUnique(String model, String productCode, Long currentId) {
|
if (StringUtils.isEmpty(model) || StringUtils.isEmpty(productCode)) {
|
return;
|
}
|
LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(ProductModel::getModel, model)
|
.eq(ProductModel::getProductCode, productCode)
|
.ne(currentId != null, ProductModel::getId, currentId)
|
.last("limit 1");
|
ProductModel duplicateProductModel = productModelMapper.selectOne(queryWrapper);
|
if (duplicateProductModel != null) {
|
throw new ServiceException("对应的型号" + model + "的产品编码" + productCode + "已经存在");
|
}
|
}
|
|
private void checkBarcodeUnique(String barcode, Long currentId) {
|
if (StringUtils.isEmpty(barcode)) {
|
return;
|
}
|
LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(ProductModel::getBarcode, barcode)
|
.ne(currentId != null, ProductModel::getId, currentId)
|
.last("limit 1");
|
if (productModelMapper.selectOne(queryWrapper) != null) {
|
throw new ServiceException("条形码" + barcode + "已经存在");
|
}
|
}
|
|
|
@Override
|
public int delProductModel(Long[] ids) {
|
List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new QueryWrapper<SalesLedgerProduct>()
|
.lambda().in(SalesLedgerProduct::getProductModelId, ids));
|
if (salesLedgerProducts != null && salesLedgerProducts.size() > 0) {
|
|
throw new RuntimeException("已经存在该产品的销售台账和采购台账");
|
}
|
|
// 是否存在BOM
|
List<TechnologyBom> technologyBoms = technologyBomMapper.selectList(new QueryWrapper<TechnologyBom>()
|
.lambda().in(TechnologyBom::getProductModelId, ids));
|
if (CollectionUtils.isNotEmpty(technologyBoms)) {
|
throw new RuntimeException("已经存在该产品的BOM数据");
|
}
|
|
return productModelMapper.deleteBatchIds(Arrays.asList(ids));
|
}
|
|
@Override
|
public List<ProductModel> selectModelList(ProductDto productDto) {
|
LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(ProductModel::getProductId, productDto.getId());
|
return productModelMapper.selectList(queryWrapper);
|
}
|
|
/**
|
* 根据id查询产品规格分页查询
|
*
|
* @param page
|
* @param productDto
|
* @return
|
*/
|
@Override
|
public IPage<ProductModel> modelListPage(Page page, ProductDto productDto) {
|
LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(ProductModel::getProductId, productDto.getId());
|
return productModelMapper.selectPage(page, queryWrapper);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public AjaxResult importProductModel(MultipartFile file, Integer productId) {
|
if (productId == null) {
|
return AjaxResult.error("请先选择产品再导入规格型号");
|
}
|
|
Product product = productMapper.selectById(productId);
|
if (product == null) {
|
return AjaxResult.error("选择的产品不存在");
|
}
|
|
try {
|
ExcelUtil<ProductModel> productModelExcelUtil = new ExcelUtil<>(ProductModel.class);
|
List<ProductModel> productModelList = productModelExcelUtil.importExcel(file.getInputStream());
|
|
if (CollectionUtils.isEmpty(productModelList)) {
|
return AjaxResult.error("导入数据不能为空");
|
}
|
|
// 获取当前产品下所有的规格型号名
|
List<ProductModel> existingModels = list(new LambdaQueryWrapper<ProductModel>().eq(ProductModel::getProductId, productId));
|
Set<String> existingModelNames = existingModels.stream().map(ProductModel::getModel).collect(Collectors.toSet());
|
|
// 已存在于数据库中的条码(全局查重)
|
List<String> importBarcodes = productModelList.stream()
|
.map(item -> StringUtils.trim(item.getBarcode()))
|
.filter(StringUtils::isNotEmpty)
|
.distinct()
|
.collect(Collectors.toList());
|
Set<String> dbBarcodeSet = importBarcodes.isEmpty() ? new HashSet<>()
|
: list(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getBarcode, importBarcodes))
|
.stream().map(ProductModel::getBarcode).collect(Collectors.toSet());
|
Set<String> fileBarcodes = new HashSet<>();
|
|
List<ProductModel> waitToSaveList = new ArrayList<>();
|
int skipCount = 0;
|
|
for (int i = 0; i < productModelList.size(); i++) {
|
ProductModel item = productModelList.get(i);
|
int rowNum = i + 2;
|
|
if (StringUtils.isEmpty(item.getProductCode())) {
|
return AjaxResult.error("第 " + rowNum + " 行导入失败: [产品编码] 不能为空");
|
}
|
if (StringUtils.isEmpty(item.getModel())) {
|
return AjaxResult.error("第 " + rowNum + " 行导入失败: [规格型号] 不能为空");
|
}
|
if (StringUtils.isEmpty(item.getUnit())) {
|
return AjaxResult.error("第 " + rowNum + " 行导入失败: [单位] 不能为空");
|
}
|
|
item.setBarcode(StringUtils.trim(item.getBarcode()));
|
if (StringUtils.isNotEmpty(item.getBarcode())) {
|
if (!fileBarcodes.add(item.getBarcode())) {
|
return AjaxResult.error("第 " + rowNum + " 行导入失败: 条形码 " + item.getBarcode() + " 在文件中重复");
|
}
|
if (dbBarcodeSet.contains(item.getBarcode())) {
|
return AjaxResult.error("第 " + rowNum + " 行导入失败: 条形码 " + item.getBarcode() + " 已存在");
|
}
|
}
|
|
// 去重,如果已包含该型号,则跳过
|
if (existingModelNames.contains(item.getModel())) {
|
skipCount++;
|
continue;
|
}
|
|
item.setProductId(product.getId());
|
waitToSaveList.add(item);
|
|
existingModelNames.add(item.getModel());
|
}
|
|
if (!waitToSaveList.isEmpty()) {
|
saveBatch(waitToSaveList);
|
}
|
|
if (skipCount == 0) {
|
return AjaxResult.success(String.format("成功导入 %d 条数据", waitToSaveList.size()));
|
} else {
|
return AjaxResult.success(String.format("成功导入 %d 条,跳过已存在数据 %d 条", waitToSaveList.size(), skipCount));
|
}
|
} catch (Exception e) {
|
log.error("导入产品规格异常", e);
|
throw new ServiceException("导入失败");
|
}
|
}
|
|
@Override
|
public ProductModel selectByBarcode(String barcode) {
|
if (StringUtils.isEmpty(barcode)) {
|
return null;
|
}
|
LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(ProductModel::getBarcode, StringUtils.trim(barcode))
|
.last("limit 1");
|
ProductModel productModel = productModelMapper.selectOne(queryWrapper);
|
if (productModel != null && productModel.getProductId() != null) {
|
Product product = productMapper.selectById(productModel.getProductId());
|
if (product != null) {
|
productModel.setProductName(product.getProductName());
|
}
|
}
|
return productModel;
|
}
|
}
|