master:入库单调优;

pull/1121/head
liujiang 2025-07-07 22:40:36 +08:00
parent 7416c6f50b
commit 54b4fa0e32
5 changed files with 115 additions and 63 deletions

View File

@ -2,9 +2,15 @@ package com.ruoyi.web.controller.xkt.vo.storeProd;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.web.controller.xkt.vo.storeColor.StoreColorVO;
import com.ruoyi.xkt.dto.storeProdColorSize.StoreProdColorSizeDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@ -54,6 +60,8 @@ public class StoreProdResVO {
private List<StoreColorVO> colorList;
@ApiModelProperty(value = "档口颜色价格列表")
private List<StoreProdColorPriceVO> priceList;
@ApiModelProperty(value = "档口商品尺码列表")
private List<StoreProdColorSizeVO> sizeList;
@ApiModelProperty(value = "档口服务承诺")
private StoreProdSvcVO svc;
@ApiModelProperty(value = "详情内容")
@ -61,6 +69,23 @@ public class StoreProdResVO {
@ApiModelProperty(value = "档口商品生产工艺")
private StoreProdProcessVO process;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Valid
public static class StoreProdColorSizeVO {
@ApiModelProperty(value = "档口颜色ID")
private Long storeColorId;
@NotBlank(message = "颜色名称不能为空!")
@ApiModelProperty(value = "颜色名称")
private String colorName;
@ApiModelProperty(value = "商品尺码", required = true)
@NotNull(message = "档口商品定价不能为空!")
private Integer size;
@NotNull(message = "是否是标准尺码不能为空!")
@ApiModelProperty(value = "是否是标准尺码", required = true)
private Integer standard;
}
@Data
public static class StoreProdFileVO {

View File

@ -24,7 +24,7 @@ public class StoreProdStorageVO {
@ApiModelProperty(value = "档口ID", required = true)
@NotNull(message = "档口ID不能为空!")
private Long storeId;
@NotBlank(message = "入库类型不能为空!")
@NotNull(message = "入库类型不能为空!")
@ApiModelProperty(value = "入库类型", required = true)
private Integer storageType;
@Valid
@ -41,6 +41,9 @@ public class StoreProdStorageVO {
@NotNull(message = "档口商品颜色ID不能为空!")
@ApiModelProperty(value = "档口商品颜色ID", required = true)
private Long storeProdColorId;
@NotNull(message = "档口颜色ID不能为空!")
@ApiModelProperty(value = "档口颜色ID", required = true)
private Long storeColorId;
@NotBlank(message = "颜色名称不能为空!")
@ApiModelProperty(value = "颜色名称", required = true)
private String colorName;

View File

@ -3,6 +3,7 @@ package com.ruoyi.web.controller.xkt.vo.storeProductDemand;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@ -18,6 +19,7 @@ public class StoreProdDemandVerifyVO {
@NotNull(message = "档口ID不能为空")
@ApiModelProperty(value = "档口ID", required = true)
private Long storeId;
@Valid
@NotNull(message = "需求列表不能为空")
@ApiModelProperty(value = "需求列表", required = true)
private List<DetailVO> detailList;

View File

@ -10,6 +10,7 @@ import com.ruoyi.common.core.page.Page;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.xkt.domain.*;
import com.ruoyi.xkt.dto.storeProductDemand.*;
import com.ruoyi.xkt.dto.storeProductStock.StoreProdStockDTO;
@ -248,9 +249,9 @@ public class StoreProductDemandServiceImpl implements IStoreProductDemandService
List<String> errorsMsgList = new ArrayList<>();
if (CollectionUtils.isEmpty(demandDetailList)) {
demandVerifyDTO.getDetailList().forEach(x -> {
List<String> errors = this.addErrorMsg(x);
if (CollectionUtils.isNotEmpty(errors)) {
errorsMsgList.addAll(errors);
String errors = this.addErrorMsg(x);
if (StringUtils.isNotEmpty(errors)) {
errorsMsgList.add(errors);
}
});
} else {
@ -309,56 +310,59 @@ public class StoreProductDemandServiceImpl implements IStoreProductDemandService
// 按照入库的数量依次进行对比,若需求单中不存在匹配信息,则直接返回错误信息
demandVerifyDTO.getDetailList().forEach(x -> {
Map<Integer, Integer> sizeQuantityMap = colorSizeQuantityMap.get(x.getStoreProdColorId());
final String prefix = x.getProdArtNum() + x.getColorName();
final String suffix = "码";
final String prefix = x.getProdArtNum() + x.getColorName() + ": ";
// 如果没有对应的需求单则直接返回错误信息
if (MapUtils.isEmpty(sizeQuantityMap)) {
List<String> errors = this.addErrorMsg(x);
if (CollectionUtils.isNotEmpty(errors)) {
errorsMsgList.addAll(errors);
String errors = this.addErrorMsg(x);
if (StringUtils.isNotEmpty(errors)) {
errorsMsgList.add(errors);
}
} else {
List<String> tempErrors = new ArrayList<>();
if (ObjectUtils.isNotEmpty(x.getSize30()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_30))) {
errorsMsgList.add(prefix + SIZE_30 + suffix);
tempErrors.add(SIZE_30.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize31()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_31))) {
errorsMsgList.add(prefix + SIZE_31 + suffix);
tempErrors.add(SIZE_31.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize32()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_32))) {
errorsMsgList.add(prefix + SIZE_32 + suffix);
tempErrors.add(SIZE_32.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize33()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_33))) {
errorsMsgList.add(prefix + SIZE_33 + suffix);
tempErrors.add(SIZE_33.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize34()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_34))) {
errorsMsgList.add(prefix + SIZE_34 + suffix);
tempErrors.add(SIZE_34.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize35()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_35))) {
errorsMsgList.add(prefix + SIZE_35 + suffix);
tempErrors.add(SIZE_35.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize36()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_36))) {
errorsMsgList.add(prefix + SIZE_36 + suffix);
tempErrors.add(SIZE_36.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize37()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_37))) {
errorsMsgList.add(prefix + SIZE_37 + suffix);
tempErrors.add(SIZE_37.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize38()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_38))) {
errorsMsgList.add(prefix + SIZE_38 + suffix);
tempErrors.add(SIZE_38.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize39()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_39))) {
errorsMsgList.add(prefix + SIZE_39 + suffix);
tempErrors.add(SIZE_39.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize40()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_40))) {
errorsMsgList.add(prefix + SIZE_40 + suffix);
tempErrors.add(SIZE_40.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize41()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_41))) {
errorsMsgList.add(prefix + SIZE_41 + suffix);
tempErrors.add(SIZE_41.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize42()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_42))) {
errorsMsgList.add(prefix + SIZE_42 + suffix);
tempErrors.add(SIZE_42.toString());
}
if (ObjectUtils.isNotEmpty(x.getSize43()) && ObjectUtils.isEmpty(sizeQuantityMap.get(SIZE_43))) {
errorsMsgList.add(prefix + SIZE_43 + suffix);
tempErrors.add(SIZE_43.toString());
}
if (CollectionUtils.isNotEmpty(tempErrors)) {
errorsMsgList.add(prefix + String.join(",", tempErrors));
}
}
});
@ -576,53 +580,52 @@ public class StoreProductDemandServiceImpl implements IStoreProductDemandService
* @param detailDTO
* @return
*/
private List<String> addErrorMsg(StoreProdDemandVerifyDTO.DetailDTO detailDTO) {
private String addErrorMsg(StoreProdDemandVerifyDTO.DetailDTO detailDTO) {
List<String> errorMsgList = new ArrayList<>();
final String prefix = detailDTO.getProdArtNum() + detailDTO.getColorName();
final String suffix = "码";
final String prefix = detailDTO.getProdArtNum() + detailDTO.getColorName() + ": ";
if (ObjectUtils.isNotEmpty(detailDTO.getSize30())) {
errorMsgList.add(prefix + SIZE_30 + suffix);
errorMsgList.add(SIZE_30.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize31())) {
errorMsgList.add(prefix + SIZE_31 + suffix);
errorMsgList.add(SIZE_31.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize32())) {
errorMsgList.add(prefix + SIZE_32 + suffix);
errorMsgList.add(SIZE_32.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize33())) {
errorMsgList.add(prefix + SIZE_33 + suffix);
errorMsgList.add(SIZE_33.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize34())) {
errorMsgList.add(prefix + SIZE_34 + suffix);
errorMsgList.add(SIZE_34.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize35())) {
errorMsgList.add(prefix + SIZE_35 + suffix);
errorMsgList.add(SIZE_35.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize36())) {
errorMsgList.add(prefix + SIZE_36 + suffix);
errorMsgList.add(SIZE_36.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize37())) {
errorMsgList.add(prefix + SIZE_37 + suffix);
errorMsgList.add(SIZE_37.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize38())) {
errorMsgList.add(prefix + SIZE_38 + suffix);
errorMsgList.add(SIZE_38.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize39())) {
errorMsgList.add(prefix + SIZE_39 + suffix);
errorMsgList.add(SIZE_39.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize40())) {
errorMsgList.add(prefix + SIZE_40 + suffix);
errorMsgList.add(SIZE_40.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize41())) {
errorMsgList.add(prefix + SIZE_41 + suffix);
errorMsgList.add(SIZE_41.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize42())) {
errorMsgList.add(prefix + SIZE_42 + suffix);
errorMsgList.add(SIZE_42.toString());
}
if (ObjectUtils.isNotEmpty(detailDTO.getSize43())) {
errorMsgList.add(prefix + SIZE_43 + suffix);
errorMsgList.add(SIZE_43.toString());
}
return errorMsgList;
return prefix + String.join(",", errorMsgList);
}

View File

@ -83,6 +83,7 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
@Override
@Transactional
public int create(StoreProdStorageDTO storeProdStorageDTO) {
long start = System.currentTimeMillis();
// 用户是否为档口管理者或子账户
if (!SecurityUtils.isAdmin() && !SecurityUtils.isStoreManagerOrSub(storeProdStorageDTO.getStoreId())) {
throw new ServiceException("当前用户非档口管理者或子账号,无权限操作!", HttpStatus.ERROR);
@ -106,10 +107,16 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
this.storageDetailMapper.insert(detailList);
// 构造增加库存的入参DTO
List<StoreProdStockDTO> increaseStockList = BeanUtil.copyToList(detailList, StoreProdStockDTO.class);
long second = System.currentTimeMillis();
System.err.println("入库耗时:" + (second - start));
// 增加档口商品的库存
this.stockService.increaseStock(storeProdStorageDTO.getStoreId(), increaseStockList);
long third = System.currentTimeMillis();
System.err.println("库存耗时:" + (third - second));
// 处理档口商品需求单的抵扣
this.handleStorageDemandDeduct(storeProdStorageDTO.getStoreId(), storeProdStorage.getCode(), detailList);
long last = System.currentTimeMillis();
System.err.println("处理需求耗时:" + (last - third));
return count;
}
@ -122,6 +129,7 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
* @param detailList
*/
private void handleStorageDemandDeduct(Long storeId, String storageCode, List<StoreProductStorageDetail> detailList) {
long fourth = System.currentTimeMillis();
// 根据明细列表找到所有提交的需求
List<StoreProductDemandDetail> demandDetailList = this.demandDetailMapper.selectList(new LambdaQueryWrapper<StoreProductDemandDetail>()
.eq(StoreProductDemandDetail::getStoreId, storeId).eq(StoreProductDemandDetail::getDelFlag, Constants.UNDELETED)
@ -134,24 +142,32 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
// 所有的需求单ID列表
final List<Long> demandIdList = demandDetailList.stream().map(StoreProductDemandDetail::getStoreProdDemandId).distinct().collect(Collectors.toList());
// 所有颜色尺码需要抵扣的需求数量
Map<Long, Map<Integer, Map<Long, Integer>>> unDeductMap = this.getUnDeductMap(demandDetailList, detailList);
Map<Long, Map<Integer, Map<Long, Integer>>> unDeductMap = this.getUnDeductMap(demandDetailList, detailList.stream()
.map(StoreProductStorageDetail::getStoreProdColorId).collect(Collectors.toList()));
long fifth = System.currentTimeMillis();
System.err.println("查询需求耗时:" + (fifth - fourth));
if (MapUtils.isEmpty(unDeductMap)) {
return;
}
// 按照入库明细列表依次进行需求数量扣减
Map<Long, Map<Long, Map<Integer, Integer>>> storageQuantityMap = this.getStorageQuantityMap(detailList);
if (MapUtils.isEmpty(storageQuantityMap)) {
return;
}
long sixth = System.currentTimeMillis();
System.err.println("库存转map耗时: " + (sixth - fifth));
// 按照入库的数量明细依次判断哪些需求订单明细还未抵扣完毕
Map<Long, Map<Long, Map<Integer, Map<Long, Integer>>>> totalMatchMap = this.getTotalMatchMap(storageQuantityMap, unDeductMap);
long seventh = System.currentTimeMillis();
System.err.println("处理需求抵扣明细耗时:" + (seventh - sixth));
if (MapUtils.isEmpty(totalMatchMap)) {
return;
}
// 新增入库与需求的抵扣关系
List<Long> updateDetailIdList = this.createDemandDeduct(storageCode, demandDetailList, totalMatchMap);
long eighth = System.currentTimeMillis();
System.err.println("新增入库需求抵扣明细耗时:" + (eighth - seventh));
// 根据最新的数据更新需求单的抵扣状态
this.updateLatestDemandStatus(updateDetailIdList, demandIdList, totalMatchMap);
long ninth = System.currentTimeMillis();
System.err.println("更新需求单状态耗时:" + (ninth - eighth));
}
/**
@ -372,8 +388,8 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
if (MapUtils.isEmpty(sizeRequireMap) || MapUtils.isEmpty(detailSizeStorageMap)) {
return;
}
Map<Long, Map<Integer, Map<Long, Integer>>> storageDetailIdSizeMatchMap = new LinkedHashMap<>();
// 匹配的尺码集合
Map<Long, Map<Integer, Map<Long, Integer>>> storageDetailIdSizeMatchMap = new LinkedHashMap<>();
detailSizeStorageMap.forEach((storageDetailId, sizeStorageMap) -> {
if (MapUtils.isEmpty(sizeStorageMap)) {
return;
@ -392,6 +408,8 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
// 尺码的入库数量 + 当前尺码的需求明细数量
final int tempCompareQuantity = storageQuantity + entry.getValue();
if (tempCompareQuantity == 0) {
// 数量刚好抵扣完毕
itemMatchMap.put(entry.getKey(), Math.abs(entry.getValue()));
continue;
}
if (tempCompareQuantity > 0) {
@ -476,10 +494,11 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
return storageQuantityMap;
}
private Map<Long, Map<Integer, Map<Long, Integer>>> getUnDeductMap(List<StoreProductDemandDetail> demandDetailList, List<StoreProductStorageDetail> detailList) {
private Map<Long, Map<Integer, Map<Long, Integer>>> getUnDeductMap(List<StoreProductDemandDetail> demandDetailList, List<Long> storeProdColorIdList) {
List<StoreProductStorageDemandDeduct> deductedList = this.deductMapper.selectList(new LambdaQueryWrapper<StoreProductStorageDemandDeduct>()
.in(StoreProductStorageDemandDeduct::getStoreProdColorId, detailList.stream().map(StoreProductStorageDetail::getStoreProdColorId).collect(Collectors.toList()))
.eq(StoreProductStorageDemandDeduct::getDelFlag, Constants.UNDELETED));
.in(StoreProductStorageDemandDeduct::getStoreProdColorId, storeProdColorIdList).eq(StoreProductStorageDemandDeduct::getDelFlag, Constants.UNDELETED)
// 根据需求明细ID去找否则 会把 所有的需求明细 对应的数据都找出来
.in(StoreProductStorageDemandDeduct::getStoreProdDemandDetailId, demandDetailList.stream().map(StoreProductDemandDetail::getId).collect(Collectors.toList())));
// 已存在的需求抵扣明细列表
Map<Long, Map<Integer, Integer>> deductedExistsMap = deductedList.stream().collect(Collectors.groupingBy(StoreProductStorageDemandDeduct::getStoreProdColorId,
Collectors.groupingBy(StoreProductStorageDemandDeduct::getSize, Collectors.summingInt(x -> ObjectUtils.defaultIfNull(x.getQuantity(), 0)))));
@ -495,20 +514,20 @@ public class StoreProductStorageServiceImpl implements IStoreProductStorageServi
// 已存在抵扣的数量
Map<Integer, Integer> sizeDeductedMap = ObjectUtils.defaultIfNull(deductedExistsMap.get(storeProdColorId), new LinkedHashMap<>());
// 尺码为30的已抵扣需求数量
Integer size30Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(30), 0);
Integer size31Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(31), 0);
Integer size32Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(32), 0);
Integer size33Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(33), 0);
Integer size34Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(34), 0);
Integer size35Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(35), 0);
Integer size36Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(36), 0);
Integer size37Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(37), 0);
Integer size38Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(38), 0);
Integer size39Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(39), 0);
Integer size40Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(40), 0);
Integer size41Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(41), 0);
Integer size42Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(42), 0);
Integer size43Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(43), 0);
Integer size30Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_30), 0);
Integer size31Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_31), 0);
Integer size32Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_32), 0);
Integer size33Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_33), 0);
Integer size34Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_34), 0);
Integer size35Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_35), 0);
Integer size36Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_36), 0);
Integer size37Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_37), 0);
Integer size38Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_38), 0);
Integer size39Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_39), 0);
Integer size40Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_40), 0);
Integer size41Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_41), 0);
Integer size42Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_42), 0);
Integer size43Deduct = ObjectUtils.defaultIfNull(sizeDeductedMap.get(SIZE_43), 0);
Map<Long, Integer> size30DemandMap = new LinkedHashMap<>();
Map<Long, Integer> size31DemandMap = new LinkedHashMap<>();
Map<Long, Integer> size32DemandMap = new LinkedHashMap<>();