|
|
|
|
@ -1,10 +1,15 @@
|
|
|
|
|
package cn.iocoder.yudao.module.erp.service.product;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductImportExcelVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductImportRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
|
|
|
|
|
@ -16,17 +21,23 @@ import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductCategoryMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import javax.validation.ConstraintViolationException;
|
|
|
|
|
import javax.validation.Valid;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
|
|
|
|
|
@ -178,11 +189,15 @@ public class ErpProductServiceImpl implements ErpProductService {
|
|
|
|
|
}
|
|
|
|
|
Map<Long, ErpProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap(
|
|
|
|
|
convertSet(list, ErpProductDO::getCategoryId));
|
|
|
|
|
Map<Long, ErpProductCategoryDO> subCategoryMap = productCategoryService.getProductCategoryMap(
|
|
|
|
|
convertSet(list, ErpProductDO::getSubCategoryId));
|
|
|
|
|
Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
|
|
|
|
|
convertSet(list, ErpProductDO::getUnitId));
|
|
|
|
|
return BeanUtils.toBean(list, ErpProductRespVO.class, product -> {
|
|
|
|
|
MapUtils.findAndThen(categoryMap, product.getCategoryId(),
|
|
|
|
|
category -> product.setCategoryName(category.getName()));
|
|
|
|
|
MapUtils.findAndThen(subCategoryMap, product.getSubCategoryId(),
|
|
|
|
|
subCategory -> product.setSubCategoryName(subCategory.getName()));
|
|
|
|
|
MapUtils.findAndThen(unitMap, product.getUnitId(),
|
|
|
|
|
unit -> product.setUnitName(unit.getName()));
|
|
|
|
|
});
|
|
|
|
|
@ -206,4 +221,126 @@ public class ErpProductServiceImpl implements ErpProductService {
|
|
|
|
|
List<ErpProductDO> selectByCategorys(List<Integer> categoryIds){
|
|
|
|
|
return productMapper.selectByCategorys(categoryIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public ErpProductImportRespVO importProductList(List<ErpProductImportExcelVO> importProducts, boolean isUpdateSupport) {
|
|
|
|
|
// 1. 参数校验
|
|
|
|
|
if (CollUtil.isEmpty(importProducts)) {
|
|
|
|
|
throw exception(PRODUCT_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. 初始化返回结果
|
|
|
|
|
ErpProductImportRespVO respVO = ErpProductImportRespVO.builder()
|
|
|
|
|
.createNames(new ArrayList<>())
|
|
|
|
|
.updateNames(new ArrayList<>())
|
|
|
|
|
.failureNames(new LinkedHashMap<>())
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
// 3. 检查Excel中是否有重复的产品名称
|
|
|
|
|
Set<String> excelNames = new HashSet<>();
|
|
|
|
|
Set<String> duplicateNamesInExcel = new HashSet<>();
|
|
|
|
|
for (ErpProductImportExcelVO importProduct : importProducts) {
|
|
|
|
|
if (!excelNames.add(importProduct.getName())) {
|
|
|
|
|
duplicateNamesInExcel.add(importProduct.getName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 记录Excel中重复的产品名称
|
|
|
|
|
for (String duplicateName : duplicateNamesInExcel) {
|
|
|
|
|
respVO.getFailureNames().put(duplicateName, "Excel中存在重复的产品名称: " + duplicateName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. 获取数据库中已存在的产品
|
|
|
|
|
Set<String> uniqueNamesToCheck = new HashSet<>(excelNames);
|
|
|
|
|
uniqueNamesToCheck.removeAll(duplicateNamesInExcel); // 排除Excel中的重复项
|
|
|
|
|
|
|
|
|
|
List<ErpProductDO> existingProducts = new ArrayList<>();
|
|
|
|
|
if (!uniqueNamesToCheck.isEmpty()) {
|
|
|
|
|
existingProducts = productMapper.selectListByNameIn(uniqueNamesToCheck);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, ErpProductDO> existingProductMap = existingProducts.stream()
|
|
|
|
|
.collect(Collectors.toMap(ErpProductDO::getName, item -> item));
|
|
|
|
|
|
|
|
|
|
// 5. 遍历导入数据
|
|
|
|
|
for (ErpProductImportExcelVO importProduct : importProducts) {
|
|
|
|
|
// 如果已在失败列表中,则跳过
|
|
|
|
|
if (respVO.getFailureNames().containsKey(importProduct.getName())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 5.1 先处理分类和单位ID,确保它们被设置
|
|
|
|
|
ErpProductDO productDOForConversion = convertToProductDO(importProduct);
|
|
|
|
|
|
|
|
|
|
// 5.2 转换为保存对象
|
|
|
|
|
ProductSaveReqVO saveReqVO = BeanUtils.toBean(importProduct, ProductSaveReqVO.class);
|
|
|
|
|
|
|
|
|
|
// 5.3 设置saveReqVO中的ID值,以通过验证
|
|
|
|
|
saveReqVO.setCategoryId(productDOForConversion.getCategoryId());
|
|
|
|
|
saveReqVO.setUnitId(productDOForConversion.getUnitId());
|
|
|
|
|
|
|
|
|
|
// 5.4 字段校验
|
|
|
|
|
ValidationUtils.validate(saveReqVO);
|
|
|
|
|
} catch (ConstraintViolationException ex) {
|
|
|
|
|
respVO.getFailureNames().put(importProduct.getName(), ex.getMessage());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 5.2 检查是否已存在
|
|
|
|
|
ErpProductDO existProduct = existingProductMap.get(importProduct.getName());
|
|
|
|
|
if (existProduct == null) {
|
|
|
|
|
try {
|
|
|
|
|
// 5.3 创建新记录
|
|
|
|
|
ErpProductDO newProduct = convertToProductDO(importProduct);
|
|
|
|
|
// 设置创建时间为当前时间
|
|
|
|
|
newProduct.setCreateTime(LocalDateTime.now());
|
|
|
|
|
productMapper.insert(newProduct);
|
|
|
|
|
respVO.getCreateNames().add(importProduct.getName());
|
|
|
|
|
} catch (DuplicateKeyException e) {
|
|
|
|
|
// 处理并发插入或其他原因导致的重复键异常
|
|
|
|
|
respVO.getFailureNames().put(importProduct.getName(), "该产品已存在");
|
|
|
|
|
}
|
|
|
|
|
} else if (isUpdateSupport) {
|
|
|
|
|
// 5.4 更新已有记录
|
|
|
|
|
ErpProductDO updateProduct = convertToProductDO(importProduct);
|
|
|
|
|
updateProduct.setId(existProduct.getId());
|
|
|
|
|
// 保持原有创建时间不变
|
|
|
|
|
updateProduct.setCreateTime(existProduct.getCreateTime());
|
|
|
|
|
productMapper.updateById(updateProduct);
|
|
|
|
|
respVO.getUpdateNames().add(importProduct.getName());
|
|
|
|
|
} else {
|
|
|
|
|
// 5.5 已存在且不支持更新
|
|
|
|
|
respVO.getFailureNames().put(importProduct.getName(), "该产品已存在");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpProductDO convertToProductDO(ErpProductImportExcelVO importProduct) {
|
|
|
|
|
ErpProductDO productDO = BeanUtils.toBean(importProduct, ErpProductDO.class);
|
|
|
|
|
|
|
|
|
|
// 直接设置分类ID为5
|
|
|
|
|
productDO.setCategoryId(5L);
|
|
|
|
|
|
|
|
|
|
// 设置固定子分类名称为"备件"
|
|
|
|
|
productDO.setSubCategoryName("备件");
|
|
|
|
|
// 查找对应的子分类ID
|
|
|
|
|
ErpProductCategoryDO subCategoryDO = productCategoryService.getProductCategoryByName("备件");
|
|
|
|
|
if (subCategoryDO != null) {
|
|
|
|
|
productDO.setSubCategoryId(subCategoryDO.getId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理单位名称
|
|
|
|
|
if (StrUtil.isNotBlank(importProduct.getUnitName())) {
|
|
|
|
|
ErpProductUnitDO unitDO = productUnitService.getProductUnitByName(importProduct.getUnitName());
|
|
|
|
|
if (unitDO != null) {
|
|
|
|
|
productDO.setUnitId(unitDO.getId());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return productDO;
|
|
|
|
|
}
|
|
|
|
|
}
|