贴皮排单增加orderNos订单列表冗余

This commit is contained in:
gaoqr
2026-07-29 13:41:08 +08:00
parent a31286c1cd
commit 45ef5b9c6a
5 changed files with 104 additions and 0 deletions
@@ -1,10 +1,12 @@
package com.cf.imes.module.executor.controller.admin.veneer.vo;
import com.cf.imes.module.executor.controller.admin.plan.vo.PlanOrderRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* 已排贴皮排单分页响应参数。
@@ -28,6 +30,12 @@ public class VeneerPlanPageRespVO {
@Schema(description = "贴皮信息,格式为材质-颜色-厚度mm")
private String veneerInfo;
@Schema(description = "排单关联的订单主键ID集合,JSON数组格式")
private String orderNos;
@Schema(description = "排单关联的订单信息")
private List<PlanOrderRespVO> orderList;
@Schema(description = "排单状态:0-未开料/新单,1-已优化,2-开料中,3-已开料")
private Integer status;
@@ -76,6 +76,11 @@ public class OrderVeneerPlanDO extends BaseDO {
*/
private Long sourceVeneerId;
/**
* 排单关联的订单主键ID集合,使用 JSON 数组格式存储。
*/
private String orderNos;
/**
* 贴皮数量,A/B面分别计数。
*/
@@ -89,6 +89,14 @@ public interface VeneerPlanMapper extends BaseMapperX<OrderVeneerPlanDO> {
*/
VeneerPlanStatisticsDO selectPlanStatistics(@Param("planId") Long planId);
/**
* 查询指定排单当前关联的订单主键ID集合。
*
* @param planId 贴皮排单ID
* @return 去重并按订单ID升序排列的订单ID集合
*/
List<Long> selectPlanOrderIdList(@Param("planId") Long planId);
/**
* 按版本物理删除已无关联贴皮且未进入开料阶段的排单。
*
@@ -2,6 +2,7 @@ package com.cf.imes.module.executor.service.veneer;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
@@ -9,8 +10,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.security.core.LoginUser;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.executor.controller.admin.plan.vo.PlanOrderRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanAddPlateReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanCreateReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPlanGroupReqVO;
@@ -44,13 +47,16 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.GOODS_PLATE_UPDATE_CONCURRENCY_ERROR;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_PLATE_UPDATE_CONCURRENCY_ERROR;
@@ -208,6 +214,7 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
.sort(++sort)
.planTime(planTime)
.sourceVeneerId(sourceVeneerId)
.orderNos(buildOrderNos(group))
.veneerNum(group.size())
.veneerArea(calculateVeneerArea(group))
.operator(loginUser.getNickname())
@@ -391,6 +398,7 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
IPage<VeneerPlanPageRespVO> page = veneerPlanMapper.selectPlanPage(
new PageDTO<>(req.getPageNo(), req.getPageSize()),
req);
fillPlanOrderList(page.getRecords());
return new PageResult<>(page.getRecords(), page.getTotal());
}
@@ -592,6 +600,9 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
*/
private void updatePlanStatistics(
OrderVeneerPlanDO plan, VeneerPlanStatisticsDO statistics) {
// 订单集合是读取快照,以当前排单剩余贴皮为准重新生成,避免新增或移除后数据漂移。
String orderNos = JSON.toJSONString(
veneerPlanMapper.selectPlanOrderIdList(plan.getId()));
int version = plan.getVersion();
int updated = veneerPlanMapper.update(new LambdaUpdateWrapper<OrderVeneerPlanDO>()
.eq(OrderVeneerPlanDO::getId, plan.getId())
@@ -599,12 +610,75 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
.eq(OrderVeneerPlanDO::getVersion, version)
.set(OrderVeneerPlanDO::getVeneerNum, statistics.getVeneerNum())
.set(OrderVeneerPlanDO::getVeneerArea, statistics.getVeneerArea())
.set(OrderVeneerPlanDO::getOrderNos, orderNos)
.set(OrderVeneerPlanDO::getVersion, version + 1));
if (updated != 1) {
throw new ServiceException(VENEER_PLAN_PLATE_STATUS_CHANGED);
}
}
/**
* 从同一贴皮商品分组提取订单ID,生成稳定有序的 JSON 数组快照。
*
* @param veneers 当前贴皮排单包含的贴皮记录
* @return 去重、升序排列后的订单ID JSON数组
*/
private String buildOrderNos(List<OrderPlateVeneerDO> veneers) {
List<Long> orderIds = veneers.stream()
.map(OrderPlateVeneerDO::getOrderId)
.filter(Objects::nonNull)
.distinct()
.sorted()
.toList();
return JSON.toJSONString(orderIds);
}
/**
* 根据排单中冗余的订单ID快照,批量加载当前页全部订单并回填订单信息。
* 查询次数只与分页请求相关,不随贴皮明细数量增加。
*
* @param plans 当前页贴皮排单
*/
private void fillPlanOrderList(List<VeneerPlanPageRespVO> plans) {
if (CollUtil.isEmpty(plans)) {
return;
}
Set<Long> orderIds = plans.stream()
.map(VeneerPlanPageRespVO::getOrderNos)
.filter(StrUtil::isNotBlank)
.flatMap(orderNos -> parseOrderIds(orderNos).stream())
.collect(Collectors.toCollection(LinkedHashSet::new));
Map<Long, OrderDO> orderMap = new HashMap<>(orderIds.size());
if (CollUtil.isNotEmpty(orderIds)) {
for (OrderDO order : orderMapper.selectByIds(orderIds)) {
orderMap.put(order.getId(), order);
}
}
for (VeneerPlanPageRespVO plan : plans) {
List<PlanOrderRespVO> orderList = parseOrderIds(plan.getOrderNos()).stream()
.map(orderMap::get)
.filter(Objects::nonNull)
.sorted(Comparator.comparing(OrderDO::getId).reversed())
.map(order -> BeanUtils.toBean(order, PlanOrderRespVO.class))
.toList();
plan.setOrderList(orderList);
}
}
/**
* 解析贴皮排单中的订单ID JSON快照。
*
* @param orderNos 订单ID JSON数组
* @return 订单ID列表;快照为空时返回空列表
*/
private List<Long> parseOrderIds(String orderNos) {
if (StrUtil.isBlank(orderNos)) {
return List.of();
}
return JSON.parseArray(orderNos).toJavaList(Long.class);
}
/**
* 根据本次新增或移除贴皮的归属范围重新统计订单及订单材质数量。
*
@@ -10,6 +10,7 @@
ovp.process_name AS processName,
CONCAT_WS('-', NULLIF(v.material, ''), NULLIF(v.color, ''),
CONCAT(CAST(v.thickness AS CHAR), 'mm')) AS veneerInfo,
ovp.order_nos AS orderNos,
ovp.status,
ovp.is_scheduled AS isScheduled,
ovp.veneer_num AS veneerNum,
@@ -124,6 +125,14 @@
AND opv.plan_id = #{planId}
</select>
<select id="selectPlanOrderIdList" resultType="java.lang.Long">
SELECT DISTINCT opv.order_id
FROM order_plate_veneer opv
WHERE opv.deleted = false
AND opv.plan_id = #{planId}
ORDER BY opv.order_id
</select>
<delete id="physicalDeleteEmptyPlan">
DELETE FROM order_veneer_plan
WHERE deleted = false