创建排单批量操作优化

This commit is contained in:
gaoqr
2026-06-30 14:42:10 +08:00
parent 39b870a950
commit fe6202e6f6
9 changed files with 176 additions and 93 deletions
@@ -16,6 +16,16 @@ import java.math.BigDecimal;
@AllArgsConstructor
@NoArgsConstructor
public class OrderPlanPlateNumAndAreaRespVO {
/**
* 排单ID
*/
private Long planId;
/**
* 订单ID
*/
private Long orderId;
/**
* 已排板件数量
*/
@@ -208,6 +208,14 @@ public interface GoodsMapper extends BaseMapperX<GoodsDO> {
*/
OrderPlanPlateNumAndAreaRespVO selectPlannedPlateNumAndArea(@Param("orderGoodsId") Long orderGoodsId);
/**
* 批量统计已排单板件数量和面积
*
* @param orderGoodsIds 商品id列表
* @return 每个商品的已排板件数量和面积
*/
List<OrderGoodsPlateNumAndAreaDO> selectPlannedPlateNumAndAreaGroup(@Param("orderGoodsIds") Collection<Long> orderGoodsIds);
/**
* 查询订单材质下的板件数量和面积
*
@@ -398,6 +398,14 @@ public interface OrderMapper extends BaseMapperX<OrderDO> {
*/
OrderPlanPlateNumAndAreaRespVO selectPlannedPlateNumAndArea(@Param("orderId") Long orderId);
/**
* 批量统计已排单板件数量和面积
*
* @param orderIds 订单id列表
* @return 每个订单的已排板件数量和面积
*/
List<OrderPlanPlateNumAndAreaRespVO> selectPlannedPlateNumAndAreaGroup(@Param("orderIds") Collection<Long> orderIds);
/**
* 查询订单下板件数量和面积
*
@@ -114,4 +114,11 @@ public interface PlanItemMapper extends BaseMapperX<PlanItemDO> {
*/
OrderPlanPlateNumAndAreaRespVO selectPlanPlateNumAndArea(@Param("planId") Long planId);
/**
* 批量统计排单板件数量和面积
*
* @param planIds 排单id列表
* @return 每个排单的板件数量和面积
*/
List<OrderPlanPlateNumAndAreaRespVO> selectPlanPlateNumAndAreaGroup(@Param("planIds") List<Long> planIds);
}
@@ -32,6 +32,7 @@ import com.cf.imes.module.executor.controller.admin.plate.vo.OrderPlateIds;
import com.cf.imes.module.executor.controller.admin.plate.vo.OrderViewPlatePageRespVO;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.goods.OptimizeBoardModelDO;
import com.cf.imes.module.executor.dal.dataobject.goods.OrderGoodsPlateNumAndAreaDO;
import com.cf.imes.module.executor.dal.dataobject.goods.PlanActualGoodsModelDO;
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO;
@@ -191,17 +192,20 @@ public class PlanServiceImpl implements PlanService {
}
// 计算排单的数量和面积
if (CollUtil.isNotEmpty(planDOS)) {
List<Long> planIdList = planDOS.stream().map(PlanDO::getId).toList();
Map<Long, OrderPlanPlateNumAndAreaRespVO> planPlateNumAndAreaMap = planItemMapper.selectPlanPlateNumAndAreaGroup(planIdList)
.stream().collect(Collectors.toMap(OrderPlanPlateNumAndAreaRespVO::getPlanId, Function.identity()));
for (PlanDO planDO : planDOS) {
OrderPlanPlateNumAndAreaRespVO orderPlanPlateNumAndAreaRespVO = planItemMapper.selectPlanPlateNumAndArea(planDO.getId());
if (ObjectUtil.isNotNull(orderPlanPlateNumAndAreaRespVO)) {
planDO.setPlateNum(orderPlanPlateNumAndAreaRespVO.getNum());
planDO.setPlateArea(orderPlanPlateNumAndAreaRespVO.getArea());
}
OrderPlanPlateNumAndAreaRespVO vo = planPlateNumAndAreaMap.get(planDO.getId());
if (vo != null) {
planDO.setPlateNum(vo.getNum());
planDO.setPlateArea(vo.getArea());
}
}
// 增加排单
planMapper.insertBatch(planDOS);
}
}
@@ -1649,6 +1653,7 @@ public class PlanServiceImpl implements PlanService {
LoginUser loginUser) {
Set<Long> orderIdSet = new HashSet<>();
Set<Long> allGoodsIds = new HashSet<>();
long sort = System.currentTimeMillis();
@@ -1657,31 +1662,33 @@ public class PlanServiceImpl implements PlanService {
// 查找和大板分类ID相同的小板的数据
List<SavePlanPlateList.PlateItemList> plateList = plateItemList.stream().filter(p -> f.getIds().contains(p.getId())).toList();
// 累计排单板件数量
Integer planPlateNum = plateList.size();
Set<Long> planOrderIdSet = new HashSet<>();
Map<Long, List<Long>> goodsPlateIdMap = new HashMap<>();
for (SavePlanPlateList.PlateItemList savePlanPlate : plateList) {
Long orderId = savePlanPlate.getOrderId();
// 累计排单下的订单号
planOrderIdSet.add(orderId);
// 累计发生改变的订单号
orderIdSet.add(orderId);
// 累计商品id下的订单号
List<Long> goodsPlateIdList = goodsPlateIdMap.get(savePlanPlate.getId());
if (CollUtil.isEmpty(goodsPlateIdList)) {
goodsPlateIdList = new ArrayList<>();
goodsPlateIdList.add(savePlanPlate.getPlateId());
goodsPlateIdMap.put(savePlanPlate.getId(), goodsPlateIdList);
} else {
goodsPlateIdList.add(savePlanPlate.getPlateId());
}
}
// 排单ID
Long planId = (Long) identifierGenerator.nextId(null);
// 更新小板排单id
List<Long> plateIds = plateList.stream().map(SavePlanPlateList.PlateItemList::getPlateId).toList();
if (CollUtil.isNotEmpty(plateIds)) {
List<List<Long>> batchPlateIdList = batchProcess(plateIds);
for (List<Long> batchIds : batchPlateIdList) {
int updatePlateNum = plateMapper.update(new LambdaUpdateWrapper<PlateDO>()
.in(PlateDO::getId, batchIds)
.eq(PlateDO::getPlanId, 0)
.set(PlateDO::getPlanId, planId));
if (updatePlateNum != batchIds.size()) {
throw new ServiceException(CREAT_PLAN_PLATE_PART_PLANNED);
}
}
}
// 累计排单下的订单号 & 累计发生改变的订单号
Set<Long> planOrderIdSet = plateList.stream()
.map(SavePlanPlateList.PlateItemList::getOrderId)
.collect(Collectors.toSet());
orderIdSet.addAll(planOrderIdSet);
// 累计涉及的商品id
allGoodsIds.addAll(plateList.stream().map(SavePlanPlateList.PlateItemList::getId).toList());
// 大板商品id
String goodsId = f.getPlanActualGoodsModelDO().getGoodsId();
@@ -1698,14 +1705,13 @@ public class PlanServiceImpl implements PlanService {
.operator(loginUser.getNickname())
.planTime(LocalDateTime.now())
.goodsId(goodsId)
.plateNum(planPlateNum)
.plateNum(plateList.size())
.build();
// 更新板件排单id & 统计更新order_goods的数量和面积
computePlatePlanAndComputeOrderGoodsInfo(planId, goodsPlateIdMap);
planDOS.add(planDO);
}
// 统计更新order_goods的数量和面积
computePlatePlanAndComputeOrderGoodsInfo(allGoodsIds);
// 统计更新orders的小板数量和面积
computeOrderInfo(orderIdSet);
}
@@ -1724,6 +1730,7 @@ public class PlanServiceImpl implements PlanService {
long sort = System.currentTimeMillis();
Set<Long> orderIdSet = new HashSet<>();
Set<Long> allGoodsIds = new HashSet<>();
// 进行数据处理:value 里为 大板的分类ID
for (Map.Entry<String, List<Long>> entry : grouped.entrySet()) {
@@ -1732,31 +1739,33 @@ public class PlanServiceImpl implements PlanService {
// 查找和大板分类ID相同的小板的数据
List<SavePlanPlateList.PlateItemList> plateList = plateItemList.stream().filter(p -> value.contains(p.getId())).toList();
// 累计排单板件数
Integer planPlateNum = plateList.size();
Set<Long> planOrderIdSet = new HashSet<>();
Map<Long, List<Long>> goodsPlateIdMap = new HashMap<>();
for (SavePlanPlateList.PlateItemList savePlanPlate : plateList) {
Long orderId = savePlanPlate.getOrderId();
// 累计排单下的订单号
planOrderIdSet.add(orderId);
// 累计发生改变的订单号
orderIdSet.add(orderId);
// 累计商品id下的订单号
List<Long> goodsPlateIdList = goodsPlateIdMap.get(savePlanPlate.getId());
if(CollUtil.isEmpty(goodsPlateIdList)) {
goodsPlateIdList = new ArrayList<>();
goodsPlateIdList.add(savePlanPlate.getPlateId());
goodsPlateIdMap.put(savePlanPlate.getId(), goodsPlateIdList);
} else {
goodsPlateIdList.add(savePlanPlate.getPlateId());
}
}
// 排单ID
Long planId = (Long) identifierGenerator.nextId(null);
// 直接小板排单id
List<Long> plateIds = plateList.stream().map(SavePlanPlateList.PlateItemList::getPlateId).toList();
if (CollUtil.isNotEmpty(plateIds)) {
List<List<Long>> batchPlateIdList = batchProcess(plateIds);
for (List<Long> batchIds : batchPlateIdList) {
int updatePlateNum = plateMapper.update(new LambdaUpdateWrapper<PlateDO>()
.in(PlateDO::getId, batchIds)
.eq(PlateDO::getPlanId, 0)
.set(PlateDO::getPlanId, planId));
if (updatePlateNum != batchIds.size()) {
throw new ServiceException(CREAT_PLAN_PLATE_PART_PLANNED);
}
}
}
// 累计排单下的订单号 & 累计发生改变的订单号
Set<Long> planOrderIdSet = plateList.stream()
.map(SavePlanPlateList.PlateItemList::getOrderId)
.collect(Collectors.toSet());
orderIdSet.addAll(planOrderIdSet);
// 累计涉及的商品id
allGoodsIds.addAll(plateList.stream().map(SavePlanPlateList.PlateItemList::getId).toList());
// 创建排单
PlanDO planDO = PlanDO.builder()
.id(planId)
@@ -1769,52 +1778,40 @@ public class PlanServiceImpl implements PlanService {
.status(PlanStatusEnum.NOCUTTING.getStatus())
.operator(loginUser.getNickname())
.planTime(LocalDateTime.now())
.plateNum(planPlateNum)
.plateNum(plateList.size())
.build();
// 更新板件排单id & 统计更新order_goods的数量和面积
computePlatePlanAndComputeOrderGoodsInfo(planId, goodsPlateIdMap);
planDOS.add(planDO);
}
// 统计更新order_goods的数量和面积
computePlatePlanAndComputeOrderGoodsInfo(allGoodsIds);
// 统计更新orders的小板数量和面积
computeOrderInfo(orderIdSet);
}
/**
* 更新板件排单id & 统计更新order_goods的小板数量和面积
* 统计更新order_goods的小板数量和面积
*
* @param planId
* @param goodsPlateIdMap
* @param allGoodsIds
*/
public void computePlatePlanAndComputeOrderGoodsInfo(Long planId, Map<Long, List<Long>> goodsPlateIdMap) {
for (Map.Entry<Long, List<Long>> entry : goodsPlateIdMap.entrySet()) {
Long orderGoodsId = entry.getKey();
// 查询version
GoodsDO goodsDO = goodsMapper.selectById(orderGoodsId);
List<Long> groupedPlateIdList = entry.getValue();
// 排单id更新到小板信息中
List<List<Long>> batchPlanPlateIdList = batchProcess(groupedPlateIdList);
for (List<Long> plateIdList : batchPlanPlateIdList) {
int updatePlateNum = plateMapper.update(new LambdaUpdateWrapper<PlateDO>()
.in(PlateDO::getId, plateIdList)
.eq(PlateDO::getPlanId, 0)
.set(PlateDO::getPlanId, planId));
if (updatePlateNum != plateIdList.size()) {
throw new ServiceException(CREAT_PLAN_PLATE_PART_PLANNED);
}
}
public void computePlatePlanAndComputeOrderGoodsInfo(Set<Long> allGoodsIds) {
if (CollUtil.isNotEmpty(allGoodsIds)) {
List<GoodsDO> goodsDOList = goodsMapper.selectByIds(new ArrayList<>(allGoodsIds));
Map<Long, OrderGoodsPlateNumAndAreaDO> statsMap = goodsMapper.selectPlannedPlateNumAndAreaGroup(allGoodsIds)
.stream().collect(Collectors.toMap(OrderGoodsPlateNumAndAreaDO::getOrderGoodsId, Function.identity()));
for (GoodsDO goodsDO : goodsDOList) {
OrderGoodsPlateNumAndAreaDO stats = statsMap.getOrDefault(goodsDO.getId(),
OrderGoodsPlateNumAndAreaDO.builder().num(0).area(BigDecimal.ZERO).build());
int version = goodsDO.getVersion();
// 统计每个order_goods下的未排单面积,更新到order_goods中
OrderPlanPlateNumAndAreaRespVO goodsPlateNumAndAreaPlanInfo = goodsMapper.selectPlannedPlateNumAndArea(orderGoodsId);
int update = goodsMapper.update(new LambdaUpdateWrapper<GoodsDO>()
.eq(GoodsDO::getId, orderGoodsId)
.eq(GoodsDO::getId, goodsDO.getId())
.eq(GoodsDO::getVersion, version)
.set(GoodsDO::getPlannedPlateArea, goodsPlateNumAndAreaPlanInfo.getArea())
.set(GoodsDO::getPlannedPlateNum, goodsPlateNumAndAreaPlanInfo.getNum())
.set(GoodsDO::getPlannedPlateArea, stats.getArea())
.set(GoodsDO::getPlannedPlateNum, stats.getNum())
.set(GoodsDO::getVersion, version + 1));
if (update == 0) {
throw new ServiceException(ErrorCodeConstants.CREATE_PLAN_GOODS_UPDATE_CONCURRENCY_ERROR, orderGoodsId);
throw new ServiceException(ErrorCodeConstants.CREATE_PLAN_GOODS_UPDATE_CONCURRENCY_ERROR, goodsDO.getId());
}
}
}
}
@@ -1825,21 +1822,34 @@ public class PlanServiceImpl implements PlanService {
* @param orderIdSet
*/
public void computeOrderInfo(Set<Long> orderIdSet) {
if (CollUtil.isEmpty(orderIdSet)) {
return;
}
// 批量查询订单信息(获取version和status
Map<Long, OrderDO> orderMap = orderMapper.selectByIds(new ArrayList<>(orderIdSet)).stream()
.collect(Collectors.toMap(OrderDO::getId, Function.identity()));
// 批量统计已排板件数量和面积
Map<Long, OrderPlanPlateNumAndAreaRespVO> statsMap = orderMapper.selectPlannedPlateNumAndAreaGroup(orderIdSet).stream()
.collect(Collectors.toMap(OrderPlanPlateNumAndAreaRespVO::getOrderId, Function.identity()));
// 循环更新每个订单(需要version乐观锁校验 + 条件状态更新)
for (Long orderId : orderIdSet) {
// 统计每个orders下的未排单面积,更新到orders中
OrderDO orderDO = orderMapper.selectById(orderId);
OrderPlanPlateNumAndAreaRespVO orderPlateNumAndAreaPlanInfo = orderMapper.selectPlannedPlateNumAndArea(orderId);
// 当前订单下排单的板件数量
Integer num = orderPlateNumAndAreaPlanInfo.getNum();
OrderDO orderDO = orderMap.get(orderId);
OrderPlanPlateNumAndAreaRespVO stats = statsMap.getOrDefault(orderId,
OrderPlanPlateNumAndAreaRespVO.builder().num(0).area(BigDecimal.ZERO).build());
Integer num = stats.getNum();
int version = orderDO.getVersion();
LambdaUpdateWrapper<OrderDO> updateWrapper = new LambdaUpdateWrapper<OrderDO>()
.eq(OrderDO::getId, orderId)
.eq(OrderDO::getVersion, version)
.set(OrderDO::getPlannedPlateArea, orderPlateNumAndAreaPlanInfo.getArea())
.set(OrderDO::getPlannedPlateArea, stats.getArea())
.set(OrderDO::getPlannedPlateNum, num)
.set(OrderDO::getVersion, version + 1);
Integer orderDOStatus = orderDO.getStatus();
// 更新订单排单状态
if (ObjectUtil.equals(orderDOStatus, OrderStatusEnum.NEW_ORDER.getStatus())) {
@@ -1854,6 +1864,7 @@ public class PlanServiceImpl implements PlanService {
updateWrapper.set(OrderDO::getStatus, OrderStatusEnum.NEW_ORDER.getStatus());
}
}
int update = orderMapper.update(updateWrapper);
if (update == 0) {
throw new ServiceException(ErrorCodeConstants.CREATE_PLAN_ORDER_UPDATE_CONCURRENCY_ERROR, orderId);
@@ -646,12 +646,12 @@ public class PlateServiceImpl implements PlateService {
.build());
// 累加订单板数和面积
orderPlanPlateNumAndAreaRespVOMap.putIfAbsent(orderId, new OrderPlanPlateNumAndAreaRespVO(0, BigDecimal.ZERO));
orderPlanPlateNumAndAreaRespVOMap.putIfAbsent(orderId, new OrderPlanPlateNumAndAreaRespVO().setNum(0).setArea(BigDecimal.ZERO));
OrderPlanPlateNumAndAreaRespVO orderPlanPlateNumAndAreaRespVO = orderPlanPlateNumAndAreaRespVOMap.get(orderId);
orderPlanPlateNumAndAreaRespVO.setArea(orderPlanPlateNumAndAreaRespVO.getArea().add(area)).setNum(orderPlanPlateNumAndAreaRespVO.getNum() + 1);
// 累加订单材质板数和面积
orderGoodsPlanPlateNumAndAreaRespVOMap.putIfAbsent(orderId, new OrderPlanPlateNumAndAreaRespVO(0, BigDecimal.ZERO));
orderGoodsPlanPlateNumAndAreaRespVOMap.putIfAbsent(orderId, new OrderPlanPlateNumAndAreaRespVO().setNum(0).setArea(BigDecimal.ZERO));
OrderPlanPlateNumAndAreaRespVO orderGoodsPlanPlateNumAndAreaRespVO = orderGoodsPlanPlateNumAndAreaRespVOMap.get(orderId);
orderGoodsPlanPlateNumAndAreaRespVO.setArea(orderGoodsPlanPlateNumAndAreaRespVO.getArea().add(area)).setNum(orderGoodsPlanPlateNumAndAreaRespVO.getNum() + 1);
});
@@ -575,6 +575,20 @@
and og.deleted = false
</select>
<select id="selectPlannedPlateNumAndAreaGroup" resultType="com.cf.imes.module.executor.dal.dataobject.goods.OrderGoodsPlateNumAndAreaDO">
select op.goods_id as orderGoodsId, count(op.id) as num, IFNULL(sum(op.area), 0) as area
from order_goods og
join order_plate op on og.organ_id = op.organ_id and og.order_id = op.order_id and og.id = op.goods_id
where og.id in
<foreach collection="orderGoodsIds" item="orderGoodsId" open="(" separator="," close=")">
#{orderGoodsId}
</foreach>
and op.plan_id != 0
and op.deleted = false
and og.deleted = false
group by op.goods_id
</select>
<select id="selectPlateNumAndArea" resultType="com.cf.imes.module.executor.dal.dataobject.goods.OrderGoodsPlateNumAndAreaDO">
SELECT
op.goods_id as order_goods_id,
@@ -1000,6 +1000,20 @@
and o.deleted = false
</select>
<select id="selectPlannedPlateNumAndAreaGroup" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderPlanPlateNumAndAreaRespVO">
select o.id as orderId, count(op.id) as num, IFNULL(sum(op.area), 0) as area
from orders o
join order_plate op on o.organ_id = op.organ_id and o.id = op.order_id
where o.id in
<foreach collection="orderIds" item="orderId" open="(" separator="," close=")">
#{orderId}
</foreach>
and op.plan_id != 0
and op.deleted = false
and o.deleted = false
group by o.id
</select>
<select id="selectPlateNumAndArea" resultType="com.cf.imes.module.executor.dal.dataobject.order.OrderPlateNumAndAreaDO">
select count(op.id) as num, IFNULL(sum(op.area), 0) as area
from orders o
@@ -604,4 +604,15 @@
and op.deleted = false
</select>
<select id="selectPlanPlateNumAndAreaGroup" resultType="com.cf.imes.module.executor.controller.admin.order.vo.order.OrderPlanPlateNumAndAreaRespVO">
select op.plan_id as planId, count(op.id) as num, IFNULL(sum(op.area), 0) as area
from order_plate op
where op.plan_id in
<foreach collection="planIds" item="planId" open="(" separator="," close=")">
#{planId}
</foreach>
and op.deleted = false
group by op.plan_id
</select>
</mapper>