新增webcad生产单导入:1、增加拆单日志输出;2、增加拆单入参片数、成倍数量大小限制;3、拆单已有房间查询优化;

This commit is contained in:
gaoqr
2025-04-09 18:47:12 +08:00
parent 7645ac2997
commit cc00e2ffa2
4 changed files with 55 additions and 21 deletions
@@ -4,6 +4,7 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
@@ -29,7 +30,8 @@ public class WebCadDataDoubleRoomTreeReqVO {
private String name; private String name;
@NotNull(message = "房间倍数不能为空") @NotNull(message = "拆单倍数不能为空")
@Max(value = 5000, message = "拆单倍数不能超过5000")
private Integer count; private Integer count;
} }
} }
@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.Size;
import java.util.List; import java.util.List;
/** /**
@@ -23,6 +24,7 @@ public class WebCadDataReqVO {
private List<WebCadDataMaterialReqVO> Materials; private List<WebCadDataMaterialReqVO> Materials;
@JsonProperty(value = "Blocks") @JsonProperty(value = "Blocks")
@Size(max = 20000, message = "拆单板件片数单次不能超过2万片")
private List<WebCadDataBlockReqVO> Blocks; private List<WebCadDataBlockReqVO> Blocks;
@JsonProperty(value = "Parts") @JsonProperty(value = "Parts")
@@ -18,7 +18,7 @@ public class PlanThreadPoolConfiguration {
public ThreadPoolTaskExecutor planThreadPoolTaskExecutor() { public ThreadPoolTaskExecutor planThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8); // 设置核心线程数 executor.setCorePoolSize(8); // 设置核心线程数
executor.setMaxPoolSize(8); // 设置最大线程数 executor.setMaxPoolSize(16); // 设置最大线程数
executor.setKeepAliveSeconds(60); // 设置空闲时间 executor.setKeepAliveSeconds(60); // 设置空闲时间
executor.setQueueCapacity(100); // 设置队列大小 executor.setQueueCapacity(100); // 设置队列大小
executor.setThreadNamePrefix("plan-import-Executor-"); // 配置线程池的前缀 executor.setThreadNamePrefix("plan-import-Executor-"); // 配置线程池的前缀
@@ -1,5 +1,6 @@
package com.cf.imes.module.plan.service.orderImport.factory; package com.cf.imes.module.plan.service.orderImport.factory;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
@@ -14,6 +15,7 @@ import com.cf.imes.framework.common.exception.ErrorCode;
import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator; import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper; import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
@@ -100,7 +102,7 @@ public class WebCadOrderImportFactory {
/** /**
* 批量操作阈值 * 批量操作阈值
*/ */
private static final int BATCH_THRESHOLD_NUMBER = 200; private static final int BATCH_THRESHOLD_NUMBER = 500;
private OrderMapper orderMapper; private OrderMapper orderMapper;
@@ -168,6 +170,9 @@ public class WebCadOrderImportFactory {
// 板材缓存:{商品编号:order_goods} // 板材缓存:{商品编号:order_goods}
private Map<String, GoodsDO> materialMap = new HashMap<>(); private Map<String, GoodsDO> materialMap = new HashMap<>();
// 已存在的房间缓存
private Map<String, Long> existRoomMap = new HashMap();
// 加工组缓存 // 加工组缓存
private Map<Integer, WebCadDataBlockReqVO.GroupInfo> processGroupMap = new HashMap<>(); private Map<Integer, WebCadDataBlockReqVO.GroupInfo> processGroupMap = new HashMap<>();
@@ -186,6 +191,9 @@ public class WebCadOrderImportFactory {
private static final String PART_CATEGORY_THREE = "组件"; private static final String PART_CATEGORY_THREE = "组件";
private static final String EMPTY_STRING = new String(); private static final String EMPTY_STRING = new String();
// 主线程的data_code
private String peek;
public WebCadOrderImportFactory(Long organId, public WebCadOrderImportFactory(Long organId,
OrderMapper orderMapper, OrderMapper orderMapper,
SnowFlakeGenerator snowFlakeGenerator, SnowFlakeGenerator snowFlakeGenerator,
@@ -224,6 +232,7 @@ public class WebCadOrderImportFactory {
now = LocalDateTime.now(); now = LocalDateTime.now();
batchId = (Long) snowFlakeGenerator.nextId(null); batchId = (Long) snowFlakeGenerator.nextId(null);
sealEdgeConfigList = new ArrayList<>(); sealEdgeConfigList = new ArrayList<>();
peek = DynamicDataSourceContextHolder.peek();
} }
public void analyzeTempData(WebCadDataReqVO webCadDataReqVO) { public void analyzeTempData(WebCadDataReqVO webCadDataReqVO) {
@@ -231,29 +240,45 @@ public class WebCadOrderImportFactory {
// 获取自定义板编号配置 // 获取自定义板编号配置
plateNoGenerateConfigVO = customPlateNoGenerateService.getPlateNoGenerateConfig(orderId); plateNoGenerateConfigVO = customPlateNoGenerateService.getPlateNoGenerateConfig(orderId);
log.info("====================【cad拆单获取封边配置开始】====================");
// 获取系统配置-封边对应配置 // 获取系统配置-封边对应配置
getOrgSealEdgeConfig(); getOrgSealEdgeConfig();
log.info("====================【cad拆单获取封边配置结束】====================");
log.info("====================【cad拆单解析生产单开始】====================");
// 解析生产单信息 // 解析生产单信息
analyzeOrder(webCadDataReqVO.getOrders()); analyzeOrder(webCadDataReqVO.getOrders());
log.info("====================【cad拆单解析生产单结束】====================");
log.info("====================【cad拆单解析板材开始】====================");
// 板材id对应板件 // 板材id对应板件
analyzeMaterials(webCadDataReqVO.getMaterials(), webCadDataReqVO.getBlocks()); analyzeMaterials(webCadDataReqVO.getMaterials(), webCadDataReqVO.getBlocks());
log.info("====================【cad拆单解析板材结束】====================");
log.info("====================【cad拆单解析加工组开始】====================");
// 解析加工组类型 // 解析加工组类型
analyzeGroups(webCadDataReqVO.getProcessGroup(), webCadDataReqVO.getBlocks(), webCadDataReqVO.getParts()); analyzeGroups(webCadDataReqVO.getProcessGroup(), webCadDataReqVO.getBlocks(), webCadDataReqVO.getParts());
log.info("====================【cad拆单解析加工组结束】====================");
log.info("====================【cad拆单解析成倍柜体开始】====================");
// 缓存柜体成倍信息 // 缓存柜体成倍信息
analyzeRoomBody(webCadDataReqVO.getDouleRoomTree()); analyzeRoomBody(webCadDataReqVO.getDouleRoomTree());
log.info("====================【cad拆单解析成倍柜体结束】====================");
log.info("====================【cad拆单解析板件开始】====================");
// 解析板件列表 // 解析板件列表
analyzeBlockList(webCadDataReqVO.getBlocks()); analyzeBlockList(webCadDataReqVO.getBlocks());
log.info("====================【cad拆单解析板件结束】====================");
log.info("====================【cad拆单解析配件开始】====================");
// 解析配件列表 // 解析配件列表
analyzeParts(webCadDataReqVO.getParts()); analyzeParts(webCadDataReqVO.getParts());
log.info("====================【cad拆单解析配件结束】====================");
log.info("====================【cad拆单异步保存开始】====================");
// 异步保存数据 // 异步保存数据
saveDataAsync(); saveDataAsync();
log.info("====================【cad拆单异步保存结束】====================");
} catch (Exception e) { } catch (Exception e) {
if (esInsert) { if (esInsert) {
@@ -547,16 +572,24 @@ public class WebCadOrderImportFactory {
String roomName = roomEntry.getKey(); String roomName = roomEntry.getKey();
List<WebCadDataBlockReqVO> listRoom = roomEntry.getValue(); List<WebCadDataBlockReqVO> listRoom = roomEntry.getValue();
Long roomId = (Long) snowFlakeGenerator.nextId(null); Long roomId;
// 检查当前单子中是否已有房间,是则使用相同房间id Long existRoomId = existRoomMap.get(roomName);
List<OrderBodyDO> existRoomNameBodys = orderBodyMapper.selectList(new LambdaUpdateWrapper<OrderBodyDO>() if (ObjectUtil.isNotNull(existRoomId)) {
.eq(OrderBodyDO::getOrderId, orderId) roomId = existRoomId;
.eq(OrderBodyDO::getRoomName, roomName) } else {
.eq(OrderBodyDO::getOrganId, organId) roomId = (Long) snowFlakeGenerator.nextId(null);
.eq(OrderBodyDO::getDeleted, false)); // 检查当前单子中是否已有房间,是则使用相同房间id
if (CollUtil.isNotEmpty(existRoomNameBodys)) { List<OrderBodyDO> existRoomNameBodys = orderBodyMapper.selectList(new LambdaUpdateWrapper<OrderBodyDO>()
roomId = existRoomNameBodys.get(0).getRoomId(); .eq(OrderBodyDO::getOrderId, orderId)
.eq(OrderBodyDO::getRoomName, roomName)
.eq(OrderBodyDO::getOrganId, organId)
.eq(OrderBodyDO::getDeleted, false));
if (CollUtil.isNotEmpty(existRoomNameBodys)) {
roomId = existRoomNameBodys.get(0).getRoomId();
existRoomMap.put(roomName, roomId);
}
} }
// 基于柜体名分组 // 基于柜体名分组
Map<String, List<WebCadDataBlockReqVO>> bodyCollect = listRoom.stream() Map<String, List<WebCadDataBlockReqVO>> bodyCollect = listRoom.stream()
.collect(Collectors.groupingBy(WebCadDataBlockReqVO::getCabinetName, Collectors.toList())); .collect(Collectors.groupingBy(WebCadDataBlockReqVO::getCabinetName, Collectors.toList()));
@@ -1731,9 +1764,9 @@ public class WebCadOrderImportFactory {
CountDownLatch latch = new CountDownLatch(bodyList.size() + groupList.size() + itemList.size()); CountDownLatch latch = new CountDownLatch(bodyList.size() + groupList.size() + itemList.size());
// 保存 // 保存
saveBodyAsync(bodyList, latch, hasError, peek); saveBodyAsync(bodyList, latch, hasError);
saveGroupAsync(groupList, latch, hasError, peek); saveGroupAsync(groupList, latch, hasError);
saveItemAsync(itemList, latch, hasError, peek); saveItemAsync(itemList, latch, hasError);
try { try {
// 等待所有任务完成,30s没有完成就主动终止 // 等待所有任务完成,30s没有完成就主动终止
@@ -1760,9 +1793,8 @@ public class WebCadOrderImportFactory {
* *
* @param latch * @param latch
* @param hasError * @param hasError
* @param peek
*/ */
private void saveBodyAsync(List<List<OrderBodyDO>> bodyList, CountDownLatch latch, AtomicBoolean hasError, String peek) { private void saveBodyAsync(List<List<OrderBodyDO>> bodyList, CountDownLatch latch, AtomicBoolean hasError) {
for (List<OrderBodyDO> bodyDOS : bodyList) { for (List<OrderBodyDO> bodyDOS : bodyList) {
threadPoolTaskExecutor.submit(() -> { threadPoolTaskExecutor.submit(() -> {
try { try {
@@ -1787,9 +1819,8 @@ public class WebCadOrderImportFactory {
* *
* @param latch * @param latch
* @param hasError * @param hasError
* @param peek
*/ */
private void saveGroupAsync(List<List<OrderGroupDO>> groupList, CountDownLatch latch, AtomicBoolean hasError, String peek) { private void saveGroupAsync(List<List<OrderGroupDO>> groupList, CountDownLatch latch, AtomicBoolean hasError) {
for (List<OrderGroupDO> orderGroupDOS : groupList) { for (List<OrderGroupDO> orderGroupDOS : groupList) {
threadPoolTaskExecutor.submit(() -> { threadPoolTaskExecutor.submit(() -> {
try { try {
@@ -1814,9 +1845,8 @@ public class WebCadOrderImportFactory {
* *
* @param latch * @param latch
* @param hasError * @param hasError
* @param peek
*/ */
private void saveItemAsync(List<List<OrderItemDO>> itemList, CountDownLatch latch, AtomicBoolean hasError, String peek) { private void saveItemAsync(List<List<OrderItemDO>> itemList, CountDownLatch latch, AtomicBoolean hasError) {
for (List<OrderItemDO> itemDOS : itemList) { for (List<OrderItemDO> itemDOS : itemList) {
threadPoolTaskExecutor.submit(() -> { threadPoolTaskExecutor.submit(() -> {
try { try {