库存商品上传修改,库存单位类型修改
This commit is contained in:
1 parent
593701cd83
commit
2b8591efab
5 files changed
+263
-29
No files matched your search
+14
-2
@@ -1,6 +1,10 @@
|
||||
package com.bsd.pjcloud.supermarket.dto.erpspu;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.bsd.pjcloud.common.core.util.MoneyDeserializer;
|
||||
import com.bsd.pjcloud.common.core.util.MoneySerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@@ -24,7 +28,7 @@ public class SmErpSpuImportDto {
|
||||
private String spec; // 规格
|
||||
|
||||
@ExcelProperty("库存")
|
||||
private Integer stock; // 库存
|
||||
private Double stock; // 库存
|
||||
|
||||
@ExcelProperty("品牌")
|
||||
private String brand; // 品牌
|
||||
@@ -36,21 +40,29 @@ public class SmErpSpuImportDto {
|
||||
private Integer packageNum; // 装数
|
||||
|
||||
@ExcelProperty("进价")
|
||||
@JsonSerialize(using = MoneySerializer.class) // 分 -> 元
|
||||
@JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分
|
||||
private Integer purchasePrice; // 进价
|
||||
|
||||
@ExcelProperty("零售价")
|
||||
@JsonSerialize(using = MoneySerializer.class) // 分 -> 元
|
||||
@JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分
|
||||
private Integer retailPrice; // 零售价
|
||||
|
||||
@ExcelProperty("货商")
|
||||
private String supplier; // 货商
|
||||
|
||||
@ExcelProperty("促销价")
|
||||
private Double promotionPrice; // 促销价
|
||||
@JsonSerialize(using = MoneySerializer.class) // 分 -> 元
|
||||
@JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分
|
||||
private Integer promotionPrice; // 促销价
|
||||
|
||||
@ExcelProperty("商品性质")
|
||||
private String commodityNature; // 商品性质
|
||||
|
||||
@ExcelProperty("成本单价")
|
||||
@JsonSerialize(using = MoneySerializer.class) // 分 -> 元
|
||||
@JsonDeserialize(using = MoneyDeserializer.class) // 元 -> 分
|
||||
private Integer costPrice; // 成本单价
|
||||
|
||||
@ExcelProperty("库存上限")
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ public class SmErpSpuEntity extends Model<SmErpSpuEntity> {
|
||||
*/
|
||||
@Schema(description="库存")
|
||||
@TableField(exist = false)
|
||||
private Integer stock;
|
||||
private Double stock;
|
||||
|
||||
/**
|
||||
* 赠送积分
|
||||
|
||||
+2
-2
@@ -33,7 +33,7 @@ public class SmErpStockEntity extends Model<SmErpStockEntity> {
|
||||
* 基础库存数量
|
||||
*/
|
||||
@Schema(description="基础库存数量")
|
||||
private Integer baseStock;
|
||||
private Double baseStock;
|
||||
|
||||
/**
|
||||
* 乐观锁版本号
|
||||
@@ -90,7 +90,7 @@ public class SmErpStockEntity extends Model<SmErpStockEntity> {
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description="当前库存")
|
||||
private Integer currentStock;
|
||||
private Double currentStock;
|
||||
|
||||
/**
|
||||
* 库存上限
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class SupermarketAppSpuDetailsVo {
|
||||
* 库存
|
||||
*/
|
||||
@Schema(description="剩余库存")
|
||||
private Integer stock;
|
||||
private Double stock;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+245
-23
@@ -124,14 +124,14 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
|
||||
public R updateSpuById(SmErpSpuEntity supermarketSpu) {
|
||||
|
||||
baseMapper.updateById(supermarketSpu);
|
||||
Integer stock = supermarketSpu.getStock();
|
||||
Double stock = supermarketSpu.getStock();
|
||||
|
||||
//如果更新商品的期初库存,就需要计算后期商品出入库单据进行了多少数据
|
||||
LambdaQueryWrapper<SmErpStockEntity> selectWStockWrapper = new LambdaQueryWrapper<>();
|
||||
selectWStockWrapper.eq(SmErpStockEntity::getErpSpuId, supermarketSpu.getId());
|
||||
SmErpStockEntity queryStock = smErpStockMapper.selectOne(selectWStockWrapper);
|
||||
//得到单据进出的库存数量
|
||||
int inventoryStockNum = queryStock.getCurrentStock() - queryStock.getBaseStock();
|
||||
Double inventoryStockNum = queryStock.getCurrentStock() - queryStock.getBaseStock();
|
||||
|
||||
LambdaQueryWrapper<SmErpStockEntity> smErpStockEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
smErpStockEntityLambdaQueryWrapper.eq(SmErpStockEntity::getErpSpuId, supermarketSpu.getId());
|
||||
@@ -668,27 +668,27 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
// 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)) {
|
||||
@@ -869,9 +869,231 @@ public class SmErpSpuServiceImpl extends ServiceImpl<SmErpSpuMapper, SmErpSpuEnt
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@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> spuBatch = new ArrayList<>();
|
||||
Map<String, SmErpSpuEntity> productCodeToSpuMap = new HashMap<>();
|
||||
|
||||
// 第一阶段:处理商品主数据
|
||||
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,
|
||||
rowNumber,
|
||||
productCode
|
||||
);
|
||||
if (categoryId == null) {
|
||||
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
|
||||
continue;
|
||||
}
|
||||
//todo 处理货商
|
||||
|
||||
// 构建商品实体
|
||||
SmErpSpuEntity spu = new SmErpSpuEntity();
|
||||
org.springframework.beans.BeanUtils.copyProperties(dto, spu);
|
||||
spu.setProductNature("电子称称重商品".equals(dto.getCommodityNature()) ? "2" : "1");
|
||||
spu.setCategoryId(categoryId);
|
||||
|
||||
spuBatch.add(spu);
|
||||
productCodeToSpuMap.put(productCode, spu);
|
||||
} catch (Exception e) {
|
||||
errorReasons.add("系统异常: " + e.getMessage());
|
||||
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
|
||||
}
|
||||
}
|
||||
|
||||
// 批量保存商品(生成ID)
|
||||
try {
|
||||
if (!spuBatch.isEmpty()) {
|
||||
this.saveBatch(spuBatch); // MyBatis-Plus批量插入
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("商品批量保存失败", e);
|
||||
}
|
||||
|
||||
// 第二阶段:处理关联数据
|
||||
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);
|
||||
String productCode = dto.getProductCode();
|
||||
List<String> errorReasons = new ArrayList<>();
|
||||
|
||||
try {
|
||||
// 跳过已记录错误的数据
|
||||
if (errorList.stream().anyMatch(e ->
|
||||
e.get("productCode").equals(productCode) &&
|
||||
(int)e.get("row") == rowNumber)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取已插入的商品
|
||||
SmErpSpuEntity spu = productCodeToSpuMap.get(productCode);
|
||||
if (spu == null || spu.getId() == null) {
|
||||
errorReasons.add("商品数据不存在或ID未生成");
|
||||
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理单位数据
|
||||
SmErpUnitEntity unit = new SmErpUnitEntity();
|
||||
org.springframework.beans.BeanUtils.copyProperties(dto, unit);
|
||||
unit.setSpuId(spu.getId());
|
||||
unit.setIsBase(true);
|
||||
unitBatch.add(unit);
|
||||
|
||||
// 处理库存数据
|
||||
SmErpStockEntity stock = new SmErpStockEntity();
|
||||
org.springframework.beans.BeanUtils.copyProperties(dto, stock);
|
||||
stock.setErpSpuId(spu.getId());
|
||||
stock.setCurrentStock(dto.getStock());
|
||||
stock.setBaseStock(dto.getStock());
|
||||
stockBatch.add(stock);
|
||||
} catch (Exception e) {
|
||||
errorReasons.add("关联数据处理失败: " + e.getMessage());
|
||||
errorList.add(createErrorInfo(rowNumber, productCode, errorReasons));
|
||||
}
|
||||
}
|
||||
|
||||
// 第三阶段:批量保存单位(生成单位ID)
|
||||
try {
|
||||
if (!unitBatch.isEmpty()) {
|
||||
smErpUnitService.saveBatch(unitBatch);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("单位批量保存失败", e);
|
||||
}
|
||||
|
||||
// 第四阶段:处理条码(需要单位ID)
|
||||
for (int i = 0; i < unitBatch.size(); i++) {
|
||||
SmErpUnitEntity unit = unitBatch.get(i);
|
||||
SmErpSpuImportDto dto = smErpSpuImportDtos.get(i);
|
||||
List<String> errorReasons = new ArrayList<>();
|
||||
|
||||
try {
|
||||
if (unit.getId() == null) {
|
||||
errorReasons.add("单位ID未生成");
|
||||
errorList.add(createErrorInfo(i + 1, dto.getProductCode(), errorReasons));
|
||||
continue;
|
||||
}
|
||||
|
||||
SmErpAuxiliaryCodeEntity code = new SmErpAuxiliaryCodeEntity();
|
||||
code.setBarCode(dto.getBarCode());
|
||||
code.setSpuId(unit.getSpuId());
|
||||
code.setUnitId(unit.getId());
|
||||
codeBatch.add(code);
|
||||
} catch (Exception e) {
|
||||
errorReasons.add("条码处理失败: " + e.getMessage());
|
||||
errorList.add(createErrorInfo(i + 1, dto.getProductCode(), errorReasons));
|
||||
}
|
||||
}
|
||||
|
||||
// 最终批量保存
|
||||
try {
|
||||
if (!stockBatch.isEmpty()) {
|
||||
smErpStockService.saveBatch(stockBatch);
|
||||
}
|
||||
if (!codeBatch.isEmpty()) {
|
||||
smErpAuxiliaryCodeService.saveBatch(codeBatch);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("最终数据保存失败", e);
|
||||
}
|
||||
|
||||
return buildImportResult(smErpSpuImportDtos.size(), productCodeToSpuMap.size(), errorList);
|
||||
}
|
||||
|
||||
// 分类处理(完整实现)
|
||||
private Long resolveCategory(String categoryName,
|
||||
List<String> errorReasons,
|
||||
int rowNumber,
|
||||
String productCode) {
|
||||
try {
|
||||
// 查询现有分类
|
||||
SmErpCategoryEntity existCategory = smErpCategoryMapper.selectOne(
|
||||
new LambdaQueryWrapper<SmErpCategoryEntity>()
|
||||
.eq(SmErpCategoryEntity::getName, categoryName)
|
||||
);
|
||||
|
||||
if (existCategory != null) {
|
||||
return existCategory.getId();
|
||||
}
|
||||
|
||||
// 创建新分类
|
||||
SmErpCategoryEntity newCategory = new SmErpCategoryEntity();
|
||||
newCategory.setName(categoryName);
|
||||
newCategory.setStatus("0");
|
||||
|
||||
int insertResult = smErpCategoryMapper.insert(newCategory);
|
||||
if (insertResult > 0) {
|
||||
return newCategory.getId();
|
||||
}
|
||||
|
||||
errorReasons.add("分类创建失败");
|
||||
return null;
|
||||
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 处理并发创建冲突
|
||||
SmErpCategoryEntity conflictCategory = smErpCategoryMapper.selectOne(
|
||||
new LambdaQueryWrapper<SmErpCategoryEntity>()
|
||||
.eq(SmErpCategoryEntity::getName, categoryName)
|
||||
);
|
||||
return conflictCategory != null ? conflictCategory.getId() : null;
|
||||
|
||||
} catch (Exception e) {
|
||||
errorReasons.add("分类处理异常: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 错误信息构建(完整实现)
|
||||
private Map<String, Object> createErrorInfo(int row, String productCode, List<String> reasons) {
|
||||
Map<String, Object> errorInfo = new LinkedHashMap<>();
|
||||
errorInfo.put("row", row);
|
||||
errorInfo.put("productCode", productCode);
|
||||
errorInfo.put("reasons", new ArrayList<>(reasons)); // 防止列表被修改
|
||||
return errorInfo;
|
||||
}
|
||||
|
||||
// 结果构建(完整实现)
|
||||
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 + "条数据");
|
||||
}
|
||||
|
||||
|
||||
public void asyncExecuteImport(String taskId, List<SmErpSpuImportDto> dtos) {
|
||||
|
||||
Reference in new issue
Block a user