This commit is contained in:
dzc committed 2025-02-28 20:50:04 +08:00
commit 254f074c52
15 files changed
+1182 -15

No files matched your search

@@ -0,0 +1,71 @@
package com.bsd.pjcloud.supermarket.dto.erpspu;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class SmErpSpuImportDto {
@ExcelProperty("货号")
private String productCode; // 货号
@ExcelProperty("自编码/条码")
private String barCode; // 自编码/条码
@ExcelProperty("商品名称")
private String productName; // 商品名称
@ExcelProperty("单位")
private String unit; // 单位
@ExcelProperty("产地")
private String origin; // 产地
@ExcelProperty("规格")
private String spec; // 规格
@ExcelProperty("库存")
private Integer stock; // 库存
@ExcelProperty("品牌")
private String brand; // 品牌
@ExcelProperty("分类")
private String classification; // 分类
@ExcelProperty("装数")
private Integer packageNum; // 装数
@ExcelProperty("进价")
private Integer purchasePrice; // 进价
@ExcelProperty("零售价")
private Integer retailPrice; // 零售价
@ExcelProperty("货商")
private String supplier; // 货商
@ExcelProperty("促销价")
private Double promotionPrice; // 促销价
@ExcelProperty("商品性质")
private String commodityNature; // 商品性质
@ExcelProperty("成本单价")
private Integer costPrice; // 成本单价
@ExcelProperty("库存上限")
private int inventoryUpperLimit; // 库存上限
@ExcelProperty("库存下限")
private int inventoryLowerLimit; // 库存下限
@ExcelProperty("毛利率%")
private Double grossProfitRate; // 毛利率%
@ExcelProperty("辅助条码")
private String auxiliaryBarcode; // 辅助条码
@ExcelProperty("停销")
private Boolean discontinued; // 停销
}
@@ -33,7 +33,7 @@ public class SmErpSupplierImportDto {
@ExcelProperty("开户行及帐号")
private String bankAccount;
@ExcelProperty("货商类别")
@ExcelProperty("货商类")
private String supplierCategory;
@ExcelProperty("货商地区")
@@ -42,8 +42,8 @@ public class SmErpSupplierImportDto {
@ExcelProperty("建档人")
private String creator;
@ExcelProperty("状态")
private String status;
// @ExcelProperty("状态")
// private String status;
@ExcelProperty("期初应付款")
private Double initialPayable;
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.supermarket.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.bsd.pjcloud.common.core.util.TenantTable;
@@ -81,7 +81,7 @@ public class SmErpSupplierEntity extends Model<SmErpSupplierEntity> {
* 货商类别
*/
@Schema(description="货商类别")
private String supplierType;
private Long supplierType;
/**
* 货商地区
@@ -0,0 +1,21 @@
package com.bsd.pjcloud.supermarket.task;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
public class AsyncConfig {
@Bean("importExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("import-");
executor.initialize();
return executor;
}
}
@@ -0,0 +1,20 @@
package com.bsd.pjcloud.supermarket.task;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Data
public class ImportTask {
private String taskId;
private String status; // PENDING, PROCESSING, COMPLETED, FAILED
private LocalDateTime createTime;
private LocalDateTime finishTime;
private int total;
private int success;
private int error;
private List<Map<String, Object>> errors = new ArrayList<>();
}
@@ -0,0 +1,36 @@
package com.bsd.pjcloud.supermarket.task;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@Service
public class TaskStoreService {
private final Map<String, ImportTask> tasks = new ConcurrentHashMap<>();
public String createTask(int total) {
String taskId = "TASK-" + UUID.randomUUID().toString().substring(0, 8);
ImportTask task = new ImportTask();
task.setTaskId(taskId);
task.setStatus("PENDING");
task.setCreateTime(LocalDateTime.now());
task.setTotal(total);
tasks.put(taskId, task);
return taskId;
}
public void updateTask(String taskId, Consumer<ImportTask> updater) {
ImportTask task = tasks.get(taskId);
if (task != null) {
updater.accept(task);
}
}
public ImportTask getTask(String taskId) {
return tasks.get(taskId);
}
}
@@ -0,0 +1,45 @@
package com.bsd.pjcloud.supermarket.validarot;
import com.alibaba.excel.util.StringUtils;
import com.bsd.pjcloud.supermarket.dto.erpspu.SmErpSpuImportDto;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import java.util.ArrayList;
import java.util.List;
public class ErpSpuValidator {
public static List<String> validate(SmErpSpuImportDto entity, int rowIndex) {
List<String> errors = new ArrayList<>();
if (StringUtils.isEmpty(entity.getProductCode())) {
errors.add("第" + (rowIndex + 1) + "行: 货号不能为空");
}
if (StringUtils.isEmpty(entity.getProductName())) {
errors.add("第" + (rowIndex + 1) + "行: 商品名称不能为空");
}
if (StringUtils.isEmpty(entity.getUnit())) {
errors.add("第" + (rowIndex + 1) + "行: 单位不能为空");
}
if (StringUtils.isEmpty(entity.getSpec())) {
errors.add("第" + (rowIndex + 1) + "行: 规格不能为空");
}
if (StringUtils.isEmpty(entity.getClassification())) {
errors.add("第" + (rowIndex + 1) + "行: 分类不能为空");
}
if (StringUtils.isEmpty(entity.getCommodityNature())) {
errors.add("第" + (rowIndex + 1) + "行: 商品性质不能为空");
}
if (StringUtils.isEmpty(entity.getSupplier())) {
errors.add("第" + (rowIndex + 1) + "行: 货商不能为空");
}
if (null==entity.getPurchasePrice()) {
errors.add("第" + (rowIndex + 1) + "行: 进价不能为空");
}
if (null==entity.getRetailPrice()) {
errors.add("第" + (rowIndex + 1) + "行: 零售价不能为空");
}
return errors;
}
}
@@ -0,0 +1,22 @@
package com.bsd.pjcloud.supermarket.validarot;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
public class SupplierValidator {
public static List<String> validate(SmErpSupplierImportDto entity, int rowIndex) {
List<String> errors = new ArrayList<>();
if (entity.getSupplierName() == null || entity.getSupplierName().isEmpty()) {
errors.add("第" + (rowIndex + 1) + "行: 货商名称不能为空");
}
// if (entity.getPhone()== null || entity.getPhone().isEmpty()) {
// errors.add("第" + (rowIndex + 1) + "行: 电话不能为空");
// }
return errors;
}
}
@@ -1,31 +1,30 @@
package com.bsd.pjcloud.supermarket.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
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.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.excel.annotation.RequestExcel;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuAppQueryDTO;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuQueryDTO;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuUpdateStockReqDTO;
import com.bsd.pjcloud.supermarket.dto.erpspu.SmErpSpuImportDto;
import com.bsd.pjcloud.supermarket.entity.SmErpAuxiliaryCodeEntity;
import com.bsd.pjcloud.supermarket.entity.SmErpSpuEntity;
import com.bsd.pjcloud.supermarket.entity.SmErpStockEntity;
import com.bsd.pjcloud.supermarket.entity.SmErpUnitEntity;
import com.bsd.pjcloud.supermarket.service.*;
import com.bsd.pjcloud.supermarket.vo.app.SupermarketAppSpuVo;
import com.bsd.pjcloud.supermarket.task.TaskStoreService;
import com.bsd.pjcloud.supermarket.vo.erpspu.SmErpSpuSimpleVo;
import com.bsd.pjcloud.supermarket.vo.stockwarn.StockWarnVO;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import com.bsd.pjcloud.common.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -35,9 +34,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
* 商品spu
@@ -62,6 +66,12 @@ public class SmErpSpuController {
private final SmErpStockService smErpStockService;
private final TaskStoreService taskStoreService;
/**
* 分页查询
* @param page 分页对象
@@ -211,6 +221,27 @@ public class SmErpSpuController {
}
/**
* 导入
*
* @param
* @param bindingResult 错误信息列表
* @return R
*/
@PostMapping("/import")
@PreAuthorize("@pms.hasPermission('supermarket_supermarketSpu_export')" )
public R importErpSpu(@RequestExcel List<SmErpSpuImportDto> dtos, BindingResult bindingResult) {
List<SmErpSpuImportDto> collect = dtos.stream().filter(smErpSpuImportDto -> smErpSpuImportDto.getProductCode() == null).collect(Collectors.toList());
// String taskId = taskStoreService.createTask(dtos.size());
// smErpSpuService.asyncExecuteImport(taskId, collect);
// return R.ok(Collections.singletonMap("taskId", taskId));
System.out.println(collect);
List<SmErpSpuImportDto> collect1 = dtos.stream().filter(smErpSpuImportDto -> StringUtils.isBlank(smErpSpuImportDto.getClassification())).collect(Collectors.toList());
System.out.println(collect1);
return smErpSpuService.importErpSpu(dtos, bindingResult);
}
// --------APP-----------------
@@ -6,10 +6,14 @@ import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.vo.UserExcelVO;
import com.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.excel.annotation.RequestExcel;
import com.bsd.pjcloud.common.log.annotation.SysLog;
import com.bsd.pjcloud.common.security.annotation.HasPermission;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import com.bsd.pjcloud.supermarket.entity.SmErpSupplierEntity;
import com.bsd.pjcloud.supermarket.service.SmErpSupplierService;
import com.bsd.pjcloud.supermarket.vo.erp.SmErpSupplierSimpleVo;
@@ -21,6 +25,7 @@ import org.springframework.http.HttpHeaders;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -135,4 +140,17 @@ public class SmErpSupplierController {
List<SmErpSupplierSimpleVo> bean = BeanUtils.toBean(list, SmErpSupplierSimpleVo.class);
return R.ok(bean);
}
/**
* 导入
*
* @param smErpSupplierImportDtos 用户列表
* @param bindingResult 错误信息列表
* @return R
*/
@PostMapping("/import")
// @PreAuthorize("@pms.hasPermission('supermarketerp_smErpSupplier_import')" )
public R importUser(@RequestExcel List<SmErpSupplierImportDto> smErpSupplierImportDtos, BindingResult bindingResult) {
return smErpSupplierService.importSupplier(smErpSupplierImportDtos, bindingResult);
}
}
@@ -7,9 +7,11 @@ import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuQueryDTO;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuUpdateStockReqDTO;
import com.bsd.pjcloud.supermarket.dto.cgplan.ErpCgPlanDTO;
import com.bsd.pjcloud.supermarket.dto.erpspu.SmErpSpuImportDto;
import com.bsd.pjcloud.supermarket.entity.SmErpSpuEntity;
import com.bsd.pjcloud.supermarket.vo.cgplan.ErpSpuWithUnitPageVo;
import com.bsd.pjcloud.supermarket.vo.sm.smspu.SmErpPageScopeVo;
import org.springframework.validation.BindingResult;
import java.util.ArrayList;
import java.util.List;
@@ -85,4 +87,19 @@ public interface SmErpSpuService extends IService<SmErpSpuEntity> {
* @return
*/
List<SmErpSpuEntity> ListScope(LambdaQueryWrapper<SmErpSpuEntity> wrapper);
/**
* 导入
* @param smErpSupplierImportDtos
* @param bindingResult
* @return
*/
R importErpSpu(List<SmErpSpuImportDto> smErpSupplierImportDtos, BindingResult bindingResult);
void asyncExecuteImport(String taskId, List<SmErpSpuImportDto> dtos);
}
@@ -3,7 +3,10 @@ package com.bsd.pjcloud.supermarket.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import com.bsd.pjcloud.supermarket.entity.SmErpSupplierEntity;
import org.springframework.validation.BindingResult;
import java.util.List;
@@ -24,4 +27,13 @@ public interface SmErpSupplierService extends IService<SmErpSupplierEntity> {
* @return
*/
Object pageScope(Page page, LambdaQueryWrapper<SmErpSupplierEntity> wrapper);
/**
* 导入
* @param smErpSupplierImportDtos
* @param bindingResult
* @return
*/
R importSupplier(List<SmErpSupplierImportDto> smErpSupplierImportDtos, BindingResult bindingResult);
}
@@ -13,15 +13,18 @@ import com.bsd.pjcloud.supermarket.constant.OrderTypeEnum;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuQueryDTO;
import com.bsd.pjcloud.supermarket.dto.SupermarketSpuUpdateStockReqDTO;
import com.bsd.pjcloud.supermarket.dto.cgplan.ErpCgPlanDTO;
import com.bsd.pjcloud.supermarket.dto.erpspu.SmErpSpuImportDto;
import com.bsd.pjcloud.supermarket.dto.inventoryrecords.UpdateStockDTO;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import com.bsd.pjcloud.supermarket.entity.*;
import com.bsd.pjcloud.supermarket.mapper.SmErpCategoryMapper;
import com.bsd.pjcloud.supermarket.mapper.SmErpSpuMapper;
import com.bsd.pjcloud.supermarket.mapper.SmErpStockMapper;
import com.bsd.pjcloud.supermarket.mapper.SmSpuMapper;
import com.bsd.pjcloud.supermarket.service.SmErpAuxiliaryCodeService;
import com.bsd.pjcloud.supermarket.service.SmErpSpuService;
import com.bsd.pjcloud.supermarket.service.SmErpStockService;
import com.bsd.pjcloud.supermarket.service.SmErpUnitService;
import com.bsd.pjcloud.supermarket.service.*;
import com.bsd.pjcloud.supermarket.task.TaskStoreService;
import com.bsd.pjcloud.supermarket.validarot.ErpSpuValidator;
import com.bsd.pjcloud.supermarket.validarot.SupplierValidator;
import com.bsd.pjcloud.supermarket.vo.app.SupermarketAppSpuDetailsVo;
import com.bsd.pjcloud.supermarket.vo.app.SupermarketAppUnitVo;
import com.bsd.pjcloud.supermarket.vo.erp.SmErpAuxiliaryCodeVo;
@@ -34,11 +37,17 @@ import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
@@ -61,9 +70,21 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
private final SmErpStockService smErpStockService;
private final SmErpCategoryMapper smErpCategoryMapper;
private final SmErpCategoryService smCategoryService;
@Autowired
private Sequence sequence;
@Autowired
@Qualifier("importExecutor")
private Executor executor;
@Autowired
private TaskStoreService taskStoreService;
@Override
@Transactional
public R saveSpu(SmErpSpuEntity supermarketSpu) {
@@ -333,4 +354,646 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
List<SmErpSpuEntity> smErpSpuEntities = baseMapper.selectListByScope(wrapper, DataScope.of());
return smErpSpuEntities;
}
/* @Override
@Transactional
public R importErpSpu(List<SmErpSpuImportDto> smErpSpuImportDtos, BindingResult bindingResult) {
if (CollectionUtils.isEmpty(smErpSpuImportDtos)) {
return R.failed("导入数据不能为空");
}
List<Map<String, Object>> errorList = new ArrayList<>();
List<SmErpSupplierEntity> successList = new ArrayList<>();
for (int i = 0; i < smErpSpuImportDtos.size(); i++) {
int rowNumber = i + 1;
SmErpSpuImportDto dto = smErpSpuImportDtos.get(i);
List<String> errorReasons = new ArrayList<>();
// 数据校验阶段
List<String> validationErrors = ErpSpuValidator.validate(dto, rowNumber);
String productCode = dto.getProductCode();
if (!validationErrors.isEmpty()) {
errorList.add(createErrorInfo(rowNumber, productCode, validationErrors));
continue;
}
//新增商品
//1.先查询当前货号是否存在,存在即更新,不存在即新增
List<SmErpSpuEntity> smErpSpuEntities = baseMapper.selectListByScope(new LambdaQueryWrapper<SmErpSpuEntity>().
eq(SmErpSpuEntity::getProductCode, productCode), DataScope.of());
if (CollectionUtils.isEmpty(smErpSpuEntities)) {
//新增
SmErpSpuEntity smErpSpuEntity = BeanUtils.toBean(dto, SmErpSpuEntity.class);
if (dto.getCommodityNature().equals("电子称称重商品")){
smErpSpuEntity.setProductNature("2");
}else {
smErpSpuEntity.setProductNature("1");
}
//先查询分类是否有,没有自动新增
SmErpCategoryEntity smErpCategoryEntity = smErpCategoryMapper.selectOne
(new LambdaQueryWrapper<SmErpCategoryEntity>().eq(SmErpCategoryEntity::getName, dto.getClassification()));
if (smErpCategoryEntity == null) {
//新增分类
SmErpCategoryEntity smErpCategoryEntity1 = new SmErpCategoryEntity();
smErpCategoryEntity1.setName(dto.getClassification());
smErpCategoryEntity1.setStatus("0");
smErpCategoryMapper.insert(smErpCategoryEntity1);
smErpSpuEntity.setCategoryId(smErpCategoryEntity1.getId());
}else {
smErpSpuEntity.setCategoryId(smErpCategoryEntity.getId());
}
baseMapper.insert(smErpSpuEntity);
//新增包装单位
SmErpUnitEntity smErpUnitEntity = BeanUtils.toBean(dto, SmErpUnitEntity.class);
smErpUnitEntity.setIsBase(true);
smErpUnitEntity.setSpuId(smErpSpuEntity.getId());
smErpUnitService.save(smErpUnitEntity);
//新增库存
SmErpStockEntity smErpStockEntity = new SmErpStockEntity();
smErpStockEntity.setCurrentStock(dto.getStock());
smErpStockEntity.setBaseStock(dto.getStock());
smErpStockEntity.setInventoryLowerLimit(dto.getInventoryLowerLimit());
smErpStockEntity.setInventoryUpperLimit(dto.getInventoryUpperLimit());
smErpStockEntity.setErpSpuId(smErpSpuEntity.getId());
smErpStockMapper.insert(smErpStockEntity);
//新增辅助条码
SmErpAuxiliaryCodeEntity smErpAuxiliaryCodeEntity = new SmErpAuxiliaryCodeEntity();
smErpAuxiliaryCodeEntity.setBarCode(dto.getBarCode());
smErpAuxiliaryCodeEntity.setSpuId(smErpSpuEntity.getId());
smErpAuxiliaryCodeEntity.setUnitId(smErpUnitEntity.getId());
smErpAuxiliaryCodeService.save(smErpAuxiliaryCodeEntity);
}else {
//查到相同的货号,更新
}
}
return null;
}*/
/*
@Override
@Transactional
public R importErpSpu(List<SmErpSpuImportDto> smErpSpuImportDtos, BindingResult bindingResult) {
if (CollectionUtils.isEmpty(smErpSpuImportDtos)) {
return R.failed("导入数据不能为空");
}
List<Map<String, Object>> errorList = new ArrayList<>();
List<SmErpSpuEntity> successList = new ArrayList<>();
for (int i = 0; i < smErpSpuImportDtos.size(); i++) {
int rowNumber = i + 1;
SmErpSpuImportDto dto = smErpSpuImportDtos.get(i);
List<String> errorReasons = new ArrayList<>();
String productCode = dto.getProductCode();
try {
// 数据校验
List<String> validationErrors = ErpSpuValidator.validate(dto, rowNumber);
if (!validationErrors.isEmpty()) {
errorList.add(createErrorInfo(rowNumber, productCode, validationErrors));
continue;
}
// 解析商品分类
Long categoryId = resolveCategory(dto.getClassification(), errorReasons);
if (categoryId == null) {
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
continue;
}
// 查询现有商品
SmErpSpuEntity existingSpu = baseMapper.selectOne(new LambdaQueryWrapper<SmErpSpuEntity>()
.eq(SmErpSpuEntity::getProductCode, productCode));
if (existingSpu == null) {
// 新增逻辑
handleNewSpu(dto, categoryId, errorReasons, rowNumber, productCode, errorList);
} else {
// 更新逻辑
handleExistingSpu(existingSpu, dto, categoryId, errorReasons, rowNumber, productCode, errorList);
}
// 记录成功数据
if (errorReasons.isEmpty()) {
successList.add(baseMapper.selectById(existingSpu != null ? existingSpu.getId() : null));
}
} catch (Exception e) {
errorReasons.add("系统异常: " + e.getMessage());
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
}
}
return buildImportResult(smErpSpuImportDtos.size(), successList.size(), errorList);
}
// 处理分类(公共方法)
private Long resolveCategory(String categoryName, List<String> errorReasons) {
try {
SmErpCategoryEntity category = smErpCategoryMapper.selectOne(
new LambdaQueryWrapper<SmErpCategoryEntity>()
.eq(SmErpCategoryEntity::getName, categoryName)
);
if (category != null) return category.getId();
// 新建分类
SmErpCategoryEntity newCategory = new SmErpCategoryEntity();
newCategory.setName(categoryName);
newCategory.setStatus("0"); // 假设0为启用状态
if (smErpCategoryMapper.insert(newCategory) > 0) {
return newCategory.getId();
}
errorReasons.add("分类创建失败");
} catch (DuplicateKeyException e) {
// 处理并发创建场景
return smErpCategoryMapper.selectOne(
new LambdaQueryWrapper<SmErpCategoryEntity>()
.eq(SmErpCategoryEntity::getName, categoryName)
).getId();
}
return null;
}
// 处理新增商品
private void handleNewSpu(SmErpSpuImportDto dto, Long categoryId, List<String> errorReasons,
int rowNumber, String productCode, List<Map<String, Object>> errorList) {
try {
SmErpSpuEntity newSpu = BeanUtils.toBean(dto, SmErpSpuEntity.class);
newSpu.setProductNature(dto.getCommodityNature().equals("电子称称重商品") ? "2" : "1");
newSpu.setCategoryId(categoryId);
if (baseMapper.insert(newSpu) <= 0) {
errorReasons.add("商品创建失败");
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
return;
}
// 处理关联数据
handleRelatedData(newSpu, dto, errorReasons, rowNumber, productCode, errorList);
} catch (DuplicateKeyException e) {
errorReasons.add("货号已存在");
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
}
}
// 处理更新商品
private void handleExistingSpu(SmErpSpuEntity existingSpu, SmErpSpuImportDto dto, Long categoryId,
List<String> errorReasons, int rowNumber, String productCode,
List<Map<String, Object>> errorList) {
try {
// 更新主数据
org.springframework.beans.BeanUtils.copyProperties(dto, existingSpu);
existingSpu.setProductNature(dto.getCommodityNature().equals("电子称称重商品") ? "2" : "1");
existingSpu.setCategoryId(categoryId);
if (baseMapper.updateById(existingSpu) <= 0) {
errorReasons.add("商品更新失败");
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
return;
}
// 处理关联数据
handleRelatedData(existingSpu, dto, errorReasons, rowNumber, productCode, errorList);
} catch (Exception e) {
errorReasons.add("更新异常: " + e.getMessage());
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
}
}
// 处理关联数据(单位、库存、条码)
private void handleRelatedData(SmErpSpuEntity spu, SmErpSpuImportDto dto, List<String> errorReasons,
int rowNumber, String productCode, List<Map<String, Object>> errorList) {
// 处理包装单位
SmErpUnitEntity unit = smErpUnitService.getOne(
new LambdaQueryWrapper<SmErpUnitEntity>()
.eq(SmErpUnitEntity::getSpuId, spu.getId())
);
try {
if (unit != null) {
// 更新单位
org.springframework.beans.BeanUtils.copyProperties(dto, unit);
smErpUnitService.updateById(unit);
} else {
// 新增单位
unit = BeanUtils.toBean(dto, SmErpUnitEntity.class);
unit.setSpuId(spu.getId());
unit.setIsBase(true);
smErpUnitService.save(unit);
}
} catch (Exception e) {
errorReasons.add("包装单位处理失败: " + e.getMessage());
}
// 处理库存
SmErpStockEntity stock = smErpStockMapper.selectOne(
new LambdaQueryWrapper<SmErpStockEntity>()
.eq(SmErpStockEntity::getErpSpuId, spu.getId())
);
try {
if (stock != null) {
// 更新库存
stock.setCurrentStock(dto.getStock());
stock.setBaseStock(dto.getStock());
stock.setInventoryLowerLimit(dto.getInventoryLowerLimit());
stock.setInventoryUpperLimit(dto.getInventoryUpperLimit());
smErpStockMapper.updateById(stock);
} else {
// 新增库存
stock = BeanUtils.toBean(dto, SmErpStockEntity.class);
stock.setErpSpuId(spu.getId());
smErpStockMapper.insert(stock);
}
} catch (Exception e) {
errorReasons.add("库存处理失败: " + e.getMessage());
}
// 处理辅助条码
SmErpAuxiliaryCodeEntity code = smErpAuxiliaryCodeService.getOne(
new LambdaQueryWrapper<SmErpAuxiliaryCodeEntity>()
.eq(SmErpAuxiliaryCodeEntity::getSpuId, spu.getId())
);
try {
if (code != null) {
// 更新条码
code.setBarCode(dto.getBarCode());
code.setUnitId(unit.getId());
smErpAuxiliaryCodeService.updateById(code);
} else {
// 新增条码
code = new SmErpAuxiliaryCodeEntity();
code.setBarCode(dto.getBarCode());
code.setSpuId(spu.getId());
code.setUnitId(unit.getId());
smErpAuxiliaryCodeService.save(code);
}
} catch (Exception e) {
errorReasons.add("条码处理失败: " + e.getMessage());
}
// 记录错误
if (!errorReasons.isEmpty()) {
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
}
}
// 构建返回结果(与供应商导入保持一致)
private R buildImportResult(int total, int successCount, List<Map<String, Object>> errorList) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("total", total);
result.put("successCount", successCount);
result.put("errorCount", errorList.size());
if (!errorList.isEmpty()) {
result.put("errors", errorList);
return R.failed(result,"部分数据导入失败");
}
return R.ok( result,"成功导入所有" + successCount + "条数据");
}
// 错误信息构建方法
private Map<String, Object> createErrorInfo(int row, String name, List<String> reasons) {
return new HashMap<String, Object>() {{
put("row", row);
put("supplierName", name);
put("reasons", reasons);
}};
}
*/
private R buildImportResult(int total, int successCount, List<Map<String, Object>> errorList) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("total", total);
result.put("successCount", successCount);
result.put("errorCount", errorList.size());
if (!errorList.isEmpty()) {
result.put("errors", errorList);
return R.failed(result,"部分数据导入失败");
}
return R.ok( result,"成功导入所有" + successCount + "条数据");
}
// 错误信息构建方法
private Map<String, Object> createErrorInfo(int row, String name, List<String> reasons) {
return new HashMap<String, Object>() {{
put("row", row);
put("supplierName", name);
put("reasons", reasons);
}};
}
@Override
@Transactional(rollbackFor = Exception.class)
public R importErpSpu(List<SmErpSpuImportDto> smErpSpuImportDtos, BindingResult bindingResult) {
if (CollectionUtils.isEmpty(smErpSpuImportDtos)) {
return R.failed("导入数据不能为空");
}
List<Map<String, Object>> errorList = new ArrayList<>();
List<SmErpSpuEntity> successList = new ArrayList<>();
// 批量处理分类
Map<String, Long> categoryMap = resolveCategories(smErpSpuImportDtos, errorList);
// 批量处理商品
List<SmErpSpuEntity> spuBatch = new ArrayList<>();
List<SmErpUnitEntity> unitBatch = new ArrayList<>();
List<SmErpStockEntity> stockBatch = new ArrayList<>();
List<SmErpAuxiliaryCodeEntity> codeBatch = new ArrayList<>();
for (int i = 0; i < smErpSpuImportDtos.size(); i++) {
int rowNumber = i + 1;
SmErpSpuImportDto dto = smErpSpuImportDtos.get(i);
List<String> errorReasons = new ArrayList<>();
String productCode = dto.getProductCode();
try {
// 数据校验
List<String> validationErrors = ErpSpuValidator.validate(dto, rowNumber);
if (!validationErrors.isEmpty()) {
errorList.add(createErrorInfo(rowNumber, productCode, validationErrors));
continue;
}
// 获取分类ID
Long categoryId = categoryMap.get(dto.getClassification());
if (categoryId == null) {
errorReasons.add("分类不存在且创建失败");
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
continue;
}
// 构造商品实体
SmErpSpuEntity spu = BeanUtils.toBean(dto, SmErpSpuEntity.class);
spu.setProductNature("电子称称重商品".equals(dto.getCommodityNature()) ? "2" : "1");
spu.setCategoryId(categoryId);
spuBatch.add(spu);
// 构造关联数据
buildRelatedData(dto, spu, unitBatch, stockBatch, codeBatch);
successList.add(spu);
} catch (Exception e) {
errorReasons.add("系统异常: " + e.getMessage());
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
}
}
// 批量数据库操作
try {
// 批量插入/更新商品
if (!spuBatch.isEmpty()) {
saveOrUpdateBatchSpu(spuBatch);
}
// 批量处理关联数据
if (!unitBatch.isEmpty()) {
smErpUnitService.saveOrUpdateBatch(unitBatch);
}
if (!stockBatch.isEmpty()) {
smErpStockService.saveOrUpdateBatch(stockBatch);
}
if (!codeBatch.isEmpty()) {
smErpAuxiliaryCodeService.saveOrUpdateBatch(codeBatch);
}
} catch (Exception e) {
throw new RuntimeException("批量操作失败", e);
}
return buildImportResult(smErpSpuImportDtos.size(), successList.size(), errorList);
}
// 批量处理分类
private Map<String, Long> resolveCategories(List<SmErpSpuImportDto> dtos, List<Map<String, Object>> errorList) {
// 获取所有分类名称
Set<String> categoryNames = dtos.stream()
.map(SmErpSpuImportDto::getClassification)
.collect(Collectors.toSet());
// 批量查询已有分类
List<SmErpCategoryEntity> existCategories = smErpCategoryMapper.selectList(
new LambdaQueryWrapper<SmErpCategoryEntity>()
.in(SmErpCategoryEntity::getName, categoryNames));
Map<String, Long> categoryMap = existCategories.stream()
.collect(Collectors.toMap(SmErpCategoryEntity::getName, SmErpCategoryEntity::getId));
// 找出需要新增的分类
List<SmErpCategoryEntity> newCategories = categoryNames.stream()
.filter(name -> !categoryMap.containsKey(name))
.map(name -> {
SmErpCategoryEntity category = new SmErpCategoryEntity();
category.setName(name);
category.setStatus("0");
return category;
})
.collect(Collectors.toList());
// 批量插入新分类
if (!newCategories.isEmpty()) {
smCategoryService.saveBatch(newCategories);
newCategories.forEach(cat -> categoryMap.put(cat.getName(), cat.getId()));
}
return categoryMap;
}
// 批量保存或更新商品
private void saveOrUpdateBatchSpu(List<SmErpSpuEntity> spuList) {
// 按货号分组
Map<String, List<SmErpSpuEntity>> spuMap = spuList.stream()
.collect(Collectors.groupingBy(SmErpSpuEntity::getProductCode));
// 批量查询已存在的商品
List<SmErpSpuEntity> existSpus = baseMapper.selectList(
new LambdaQueryWrapper<SmErpSpuEntity>()
.in(SmErpSpuEntity::getProductCode, spuMap.keySet()));
// 分离新增和更新数据
List<SmErpSpuEntity> toInsert = new ArrayList<>();
List<SmErpSpuEntity> toUpdate = new ArrayList<>();
spuList.forEach(spu -> {
Optional<SmErpSpuEntity> exist = existSpus.stream()
.filter(e -> e.getProductCode().equals(spu.getProductCode()))
.findFirst();
if (exist.isPresent()) {
SmErpSpuEntity entity = exist.get();
org.springframework.beans.BeanUtils.copyProperties(spu, entity);
toUpdate.add(entity);
} else {
toInsert.add(spu);
}
});
// 批量操作
if (!toInsert.isEmpty()) {
this.saveBatch((toInsert));
}
if (!toUpdate.isEmpty()) {
this.updateBatchById(toUpdate);
}
}
// 构建关联数据
private void buildRelatedData(SmErpSpuImportDto dto, SmErpSpuEntity spu,
List<SmErpUnitEntity> unitBatch,
List<SmErpStockEntity> stockBatch,
List<SmErpAuxiliaryCodeEntity> codeBatch) {
// 包装单位
SmErpUnitEntity unit = BeanUtils.toBean(dto, SmErpUnitEntity.class);
unit.setSpuId(spu.getId());
unit.setIsBase(true);
unitBatch.add(unit);
// 库存
SmErpStockEntity stock = BeanUtils.toBean(dto, SmErpStockEntity.class);
stock.setErpSpuId(spu.getId());
stockBatch.add(stock);
// 辅助条码
SmErpAuxiliaryCodeEntity code = new SmErpAuxiliaryCodeEntity();
code.setBarCode(dto.getBarCode());
code.setSpuId(spu.getId());
code.setUnitId(unit.getId());
codeBatch.add(code);
}
public void asyncExecuteImport(String taskId, List<SmErpSpuImportDto> dtos) {
executor.execute(() -> {
List<Map<String, Object>> errors = new ArrayList<>();
// 使用线程安全的计数器
AtomicInteger successCount = new AtomicInteger(0);
try {
taskStoreService.updateTask(taskId, t -> t.setStatus("PROCESSING"));
for (int i = 0; i < dtos.size(); i++) {
try {
processSingleItem(dtos.get(i), i + 1);
successCount.incrementAndGet();
} catch (Exception e) {
errors.add(buildErrorInfo(i + 1, dtos.get(i).getProductCode(), e));
}
}
taskStoreService.updateTask(taskId, t -> {
t.setStatus("COMPLETED");
t.setSuccess(successCount.get());
t.setError(errors.size());
t.setErrors(errors);
t.setFinishTime(LocalDateTime.now());
});
} catch (Exception e) {
taskStoreService.updateTask(taskId, t -> {
t.setStatus("FAILED");
t.setError(dtos.size());
t.setErrors(Collections.singletonList(
buildErrorInfo(0, "SYSTEM", e)
));
});
}
});
}
private void processSingleItem(SmErpSpuImportDto dto, int row) throws Exception {
// 数据校验
List<String> validations = ErpSpuValidator.validate(dto, row);
if (!validations.isEmpty()) {
throw new RuntimeException(String.join(",", validations));
}
// 处理分类
Long categoryId = resolveCategory(dto.getClassification());
// 处理商品
SmErpSpuEntity spu = resolveSpu(dto, categoryId);
// 处理关联数据
handleRelatedData(spu, dto);
}
private Long resolveCategory(String name) {
SmErpCategoryEntity category = smErpCategoryMapper.selectOne(
new LambdaQueryWrapper<SmErpCategoryEntity>()
.eq(SmErpCategoryEntity::getName, name));
if (category != null) return category.getId();
SmErpCategoryEntity newCategory = new SmErpCategoryEntity();
newCategory.setName(name);
if (smErpCategoryMapper.insert(newCategory) > 0) {
return newCategory.getId();
}
throw new RuntimeException("分类创建失败");
}
private SmErpSpuEntity resolveSpu(SmErpSpuImportDto dto, Long categoryId) {
SmErpSpuEntity existing = baseMapper.selectOne(
new LambdaQueryWrapper<SmErpSpuEntity>()
.eq(SmErpSpuEntity::getProductCode, dto.getProductCode()));
SmErpSpuEntity spu = BeanUtils.toBean(dto, SmErpSpuEntity.class);
spu.setProductNature("电子称称重商品".equals(dto.getCommodityNature()) ? "2" : "1");
spu.setCategoryId(categoryId);
if (existing != null) {
spu.setId(existing.getId());
if (baseMapper.updateById(spu) <= 0) {
throw new RuntimeException("商品更新失败");
}
} else {
if (baseMapper.insert(spu) <= 0) {
throw new RuntimeException("商品创建失败");
}
}
return spu;
}
private void handleRelatedData(SmErpSpuEntity spu, SmErpSpuImportDto dto) {
// 处理单位
SmErpUnitEntity unit = Optional.ofNullable(smErpUnitService.getOne(
new LambdaQueryWrapper<SmErpUnitEntity>()
.eq(SmErpUnitEntity::getSpuId, spu.getId())))
.orElseGet(() -> new SmErpUnitEntity());
org.springframework.beans.BeanUtils.copyProperties(dto, unit);
unit.setSpuId(spu.getId());
unit.setIsBase(true);
smErpUnitService.saveOrUpdate(unit);
// 处理库存
SmErpStockEntity stock = Optional.ofNullable(smErpStockMapper.selectOne(
new LambdaQueryWrapper<SmErpStockEntity>()
.eq(SmErpStockEntity::getErpSpuId, spu.getId())))
.orElseGet(() -> new SmErpStockEntity());
org.springframework.beans.BeanUtils.copyProperties(dto, stock);
stock.setErpSpuId(spu.getId());
smErpStockMapper.insertOrUpdate(stock);
// 处理条码
SmErpAuxiliaryCodeEntity code = Optional.ofNullable(smErpAuxiliaryCodeService.getOne(
new LambdaQueryWrapper<SmErpAuxiliaryCodeEntity>()
.eq(SmErpAuxiliaryCodeEntity::getSpuId, spu.getId())))
.orElseGet(() -> new SmErpAuxiliaryCodeEntity());
code.setBarCode(dto.getBarCode());
code.setSpuId(spu.getId());
code.setUnitId(unit.getId());
smErpAuxiliaryCodeService.saveOrUpdate(code);
}
private Map<String, Object> buildErrorInfo(int row, String code, Exception e) {
return new HashMap<String, Object>() {{
put("row", row);
put("productCode", code);
put("reason", e.getMessage());
}};
}
}
@@ -1,15 +1,29 @@
package com.bsd.pjcloud.supermarket.service.impl;
import cn.hutool.core.lang.Assert;
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.bsd.pjcloud.common.core.util.BeanUtils;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.data.datascope.DataScope;
import com.bsd.pjcloud.common.security.util.SecurityUtils;
import com.bsd.pjcloud.supermarket.dto.supplier.SmErpSupplierImportDto;
import com.bsd.pjcloud.supermarket.entity.SmErpSupplierEntity;
import com.bsd.pjcloud.supermarket.entity.SmErpSupplierTypeEntity;
import com.bsd.pjcloud.supermarket.mapper.SmErpSupplierMapper;
import com.bsd.pjcloud.supermarket.mapper.SmErpSupplierTypeMapper;
import com.bsd.pjcloud.supermarket.service.SmErpSupplierService;
import com.bsd.pjcloud.supermarket.validarot.SupplierValidator;
import lombok.AllArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import java.util.List;
import java.util.*;
/**
* 货商管理
@@ -18,7 +32,10 @@ import java.util.List;
* @date 2024-12-20 12:07:42
*/
@Service
@AllArgsConstructor
public class SmErpSupplierServiceImpl extends ServiceImpl<SmErpSupplierMapper, SmErpSupplierEntity> implements SmErpSupplierService {
private final SmErpSupplierTypeMapper supplierTypeMapper;
@Override
public List<SmErpSupplierEntity> selectSimpleAllScope() {
return baseMapper.selectListByScope(new LambdaQueryWrapper<SmErpSupplierEntity>().eq(SmErpSupplierEntity::getStatus, "0"), DataScope.of());
@@ -28,4 +45,197 @@ public class SmErpSupplierServiceImpl extends ServiceImpl<SmErpSupplierMapper, S
public Object pageScope(Page page, LambdaQueryWrapper<SmErpSupplierEntity> wrapper) {
return baseMapper.selectPageByScope(page, wrapper, DataScope.of());
}
/* @Override
@Transactional
public R importSupplier(List<SmErpSupplierImportDto> smErpSupplierImportDtos, BindingResult bindingResult) {
if (smErpSupplierImportDtos.isEmpty()) {
return R.failed("导入内容为空");
}
List<R> result = new ArrayList<>();
for (int i = 0; i < smErpSupplierImportDtos.size(); i++) {
SmErpSupplierImportDto entity = smErpSupplierImportDtos.get(i);
List<String> errors = SupplierValidator.validate(entity, i);
if (!errors.isEmpty()) {
for (String error : errors) {
bindingResult.rejectValue("", "", error);
}
continue;
}
SmErpSupplierEntity supplier = BeanUtils.toBean(entity, SmErpSupplierEntity.class);
//查询货商
List<SmErpSupplierEntity> smErpSupplierEntities = baseMapper.selectListByScope(new LambdaQueryWrapper<>(SmErpSupplierEntity.class)
.eq(SmErpSupplierEntity::getSupplierName, supplier.getSupplierName()), DataScope.of());
//查询货商类型
String supplierCategory = entity.getSupplierCategory();
List<SmErpSupplierTypeEntity> smErpSupplierTypeEntities = supplierTypeMapper.selectListByScope(new LambdaQueryWrapper<>(SmErpSupplierTypeEntity.class)
.eq(SmErpSupplierTypeEntity::getTypeName, supplierCategory), DataScope.of());
Long supplierTypeId = determineSupplierTypeId(supplierCategory, smErpSupplierTypeEntities);
supplier.setSupplierId(supplierTypeId);
//如果有当前名称,则更新
if (CollectionUtils.isEmpty(smErpSupplierEntities)) {
boolean b = updateById(supplier);
if (b) {
result.add(R.ok("更新成功"));
} else {
result.add(R.failed("更新失败"));
}
} else {
boolean save = save(supplier);
if (save) {
result.add(R.ok("新增成功"));
} else {
result.add(R.ok("新增失败"));
}
}
}
return R.ok(result);
}
// 新增的公共方法
private Long determineSupplierTypeId(String category, List<SmErpSupplierTypeEntity> typeEntities) {
if (CollectionUtils.isEmpty(typeEntities)) {
SmErpSupplierTypeEntity newType = new SmErpSupplierTypeEntity();
newType.setTypeName(category);
supplierTypeMapper.insert(newType);
return newType.getId();
}
// 显式断言确保集合非空
Assert.notEmpty(typeEntities, "供应商类型查询结果不应为空");
return typeEntities.get(0).getId();
}
*/
@Override
@Transactional
public R importSupplier(List<SmErpSupplierImportDto> smErpSupplierImportDtos, BindingResult bindingResult) {
if (CollectionUtils.isEmpty(smErpSupplierImportDtos)) {
return R.failed("导入数据不能为空");
}
List<Map<String, Object>> errorList = new ArrayList<>();
List<SmErpSupplierEntity> successList = new ArrayList<>();
for (int i = 0; i < smErpSupplierImportDtos.size(); i++) {
int rowNumber = i + 1;
SmErpSupplierImportDto dto = smErpSupplierImportDtos.get(i);
List<String> errorReasons = new ArrayList<>();
// 数据校验阶段
List<String> validationErrors = SupplierValidator.validate(dto, rowNumber);
if (!validationErrors.isEmpty()) {
errorList.add(createErrorInfo(rowNumber, dto.getSupplierName(), validationErrors));
continue;
}
try {
// 处理供应商类型
SmErpSupplierTypeEntity typeEntity = resolveSupplierType(dto.getSupplierCategory());
if (typeEntity == null) {
errorReasons.add("供应商类型不存在且创建失败");
errorList.add(createErrorInfo(rowNumber, dto.getSupplierName(), errorReasons));
continue;
}
// 转换实体
SmErpSupplierEntity supplier = BeanUtils.toBean(dto, SmErpSupplierEntity.class);
supplier.setDeptId(SecurityUtils.getUser().getDeptId());
supplier.setSupplierType(typeEntity.getId());
// 根据名称检查存在性(需确保supplier_name有唯一约束)
SmErpSupplierEntity existing = getExistingSupplier(supplier.getSupplierName());
boolean operationResult;
if (existing != null) {
// 更新逻辑:保持原有ID
supplier.setSupplierId(existing.getSupplierId());
operationResult = updateById(supplier);
} else {
// 新增逻辑
operationResult = save(supplier);
}
if (operationResult) {
successList.add(supplier);
} else {
errorReasons.add(existing != null ? "更新失败" : "新增失败");
errorList.add(createErrorInfo(rowNumber, dto.getSupplierName(), errorReasons));
}
} catch (DuplicateKeyException e) {
errorReasons.add("供应商名称已存在");
errorList.add(createErrorInfo(rowNumber, dto.getSupplierName(), errorReasons));
} catch (Exception e) {
errorReasons.add("系统异常: " + e.getMessage());
errorList.add(createErrorInfo(rowNumber, dto.getSupplierName(), errorReasons));
}
}
return buildFinalResult(smErpSupplierImportDtos.size(), successList.size(), errorList);
}
// 辅助方法:获取已存在的供应商
private SmErpSupplierEntity getExistingSupplier(String supplierName) {
List<SmErpSupplierEntity> list = baseMapper.selectListByScope(
new LambdaQueryWrapper<SmErpSupplierEntity>()
.eq(SmErpSupplierEntity::getSupplierName, supplierName)
.last("LIMIT 1"),
DataScope.of()
);
return CollectionUtils.isEmpty(list) ? null : list.get(0);
}
// 构建最终返回结果
private R buildFinalResult(int total, int successCount, List<Map<String, Object>> errorList) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("total", total);
result.put("successCount", successCount);
result.put("errorCount", errorList.size());
if (!errorList.isEmpty()) {
result.put("errors", errorList);
return R.failed( result,"部分数据导入失败");
}
return R.ok( result,"成功导入所有" + successCount + "条数据");
}
// 类型解析方法(带事务传播调整)
@Transactional(propagation = Propagation.REQUIRES_NEW) // 新事务避免主事务回滚影响
public SmErpSupplierTypeEntity resolveSupplierType(String typeName) {
// 先尝试查询
SmErpSupplierTypeEntity type = supplierTypeMapper.selectOne(
new LambdaQueryWrapper<SmErpSupplierTypeEntity>()
.eq(SmErpSupplierTypeEntity::getTypeName, typeName)
);
if (type != null) return type;
// 不存在则尝试插入
try {
SmErpSupplierTypeEntity newType = new SmErpSupplierTypeEntity();
newType.setTypeName(typeName);
if (supplierTypeMapper.insert(newType) > 0) {
return newType;
}
} catch (DuplicateKeyException e) {
// 并发情况下其他事务已创建
return supplierTypeMapper.selectOne(
new LambdaQueryWrapper<SmErpSupplierTypeEntity>()
.eq(SmErpSupplierTypeEntity::getTypeName, typeName)
);
}
return null;
}
// 错误信息构建方法
private Map<String, Object> createErrorInfo(int row, String name, List<String> reasons) {
return new HashMap<String, Object>() {{
put("row", row);
put("supplierName", name);
put("reasons", reasons);
}};
}
}