新增webcad生产单导入:1、plan微服务补充superadmin-prod-org-ignore-enable配置;2、cad拆单导入orderitem、orderplate、orderpart新增线程池处理;3、cad拆单过程debug日志增加;

This commit is contained in:
gaoqr
2025-04-10 17:36:16 +08:00
parent 58616b1de0
commit c13e19bc60
5 changed files with 230 additions and 62 deletions
@@ -25,6 +25,21 @@ import lombok.ToString;
@AllArgsConstructor
public class OrderItemDO {
public OrderItemDO(OrderItemDO item) {
this.id = item.getId();
this.orderId = item.getOrderId();
this.type = item.getType();
this.roomId = item.getRoomId();
this.bodyId = item.getBodyId();
this.planId = item.getPlanId();
this.plateId = item.getPlateId();
this.packageId = item.getPackageId();
this.groupId = item.getGroupId();
this.partsId = item.getPartsId();
this.num = item.getNum();
this.organId = item.getOrganId();
}
/**
* 明细编号
*/
@@ -26,6 +26,35 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class OrderPartsDO extends BaseDO {
public OrderPartsDO(OrderPartsDO parts) {
this.id = parts.getId();
this.organId = parts.getOrganId();
this.orderId = parts.getOrderId();
this.goodsId = parts.getGoodsId();
this.name = parts.getName();
this.color = parts.getColor();
this.material = parts.getMaterial();
this.category = parts.getCategory();
this.type = parts.getType();
this.width = parts.getWidth();
this.length = parts.getLength();
this.thickness = parts.getThickness();
this.model = parts.getModel();
this.spec = parts.getSpec();
this.brand = parts.getBrand();
this.factory = parts.getFactory();
this.unit = parts.getUnit();
this.price = parts.getPrice();
this.isComposite = parts.getIsComposite();
this.subparts = parts.getSubparts();
this.remark = parts.getRemark();
this.deleted = parts.getDeleted();
this.setCreateTime(parts.getCreateTime());
this.setUpdateTime(parts.getUpdateTime());
this.setCreator(parts.getCreator());
this.setUpdater(parts.getUpdater());
}
/**
* 配件 ID
*/
@@ -30,6 +30,60 @@ import java.math.BigDecimal;
@AllArgsConstructor
public class PlateDO extends BaseDO {
public PlateDO(PlateDO plateDO) {
this.id = plateDO.getId();
this.organId = plateDO.getOrganId();
this.orderId = plateDO.getOrderId();
this.name = plateDO.getName();
this.plateNo = plateDO.getPlateNo();
this.type = plateDO.getType();
this.goodsId = plateDO.getGoodsId();
this.width = plateDO.getWidth();
this.height = plateDO.getHeight();
this.thickness = plateDO.getThickness();
this.splitWidth = plateDO.getSplitWidth();
this.splitHeight = plateDO.getSplitHeight();
this.splitThickness = plateDO.getSplitThickness();
this.sealLeft = plateDO.getSealLeft();
this.sealRight = plateDO.getSealRight();
this.sealUp = plateDO.getSealUp();
this.sealDown = plateDO.getSealDown();
this.area = plateDO.getArea();
this.texture = plateDO.getTexture();
this.holeFace = plateDO.getHoleFace();
this.holeArrange = plateDO.getHoleArrange();
this.unregularPointCount = plateDO.getUnregularPointCount();
this.frontHoleCount = plateDO.getFrontHoleCount();
this.backHoleCount = plateDO.getBackHoleCount();
this.sideHoleCount = plateDO.getSideHoleCount();
this.frontModelCount = plateDO.getFrontModelCount();
this.backModelCount = plateDO.getBackModelCount();
this.isDoor = plateDO.getIsDoor();
this.openDoorType = plateDO.getOpenDoorType();
this.offsetX = plateDO.getOffsetX();
this.offsetY = plateDO.getOffsetY();
this.isArcAcross = plateDO.getIsArcAcross();
this.moduleTypeId = plateDO.getModuleTypeId();
this.isSpecialShaped = plateDO.getIsSpecialShaped();
this.isSculpt = plateDO.getIsSculpt();
this.isRowHole = plateDO.getIsRowHole();
this.isOptimized = plateDO.getIsOptimized();
this.isCutted = plateDO.getIsCutted();
this.filterType = plateDO.getFilterType();
this.remark = plateDO.getRemark();
this.isCancel = plateDO.getIsCancel();
this.deleted = plateDO.getDeleted();
this.customPlateNo = plateDO.getCustomPlateNo();
this.roomName = plateDO.getRoomName();
this.bodyName = plateDO.getBodyName();
this.customPlateNoBuilder = plateDO.getCustomPlateNoBuilder();
this.setCreateTime(plateDO.getCreateTime());
this.setUpdateTime(plateDO.getUpdateTime());
this.setCreator(plateDO.getCreator());
this.setUpdater(plateDO.getUpdater());
this.setDeleted(plateDO.getDeleted());
}
/**
* 板件 ID
*/
@@ -10,12 +10,12 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.exception.ErrorCode;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
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.mybatis.core.generator.SnowFlakeGenerator;
import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
@@ -240,45 +240,47 @@ public class WebCadOrderImportFactory {
// 获取自定义板编号配置
plateNoGenerateConfigVO = customPlateNoGenerateService.getPlateNoGenerateConfig(orderId);
log.info("====================【cad拆单获取封边配置开始】====================");
log.debug("====================【cad拆单获取封边配置开始】====================");
// 获取系统配置-封边对应配置
getOrgSealEdgeConfig();
log.info("====================【cad拆单获取封边配置结束】====================");
log.debug("====================【cad拆单获取封边配置结束】====================");
log.info("====================【cad拆单解析生产单开始】====================");
log.debug("====================【cad拆单解析生产单开始】====================");
// 解析生产单信息
analyzeOrder(webCadDataReqVO.getOrders());
log.info("====================【cad拆单解析生产单结束】====================");
log.debug("====================【cad拆单解析生产单结束】====================");
log.info("====================【cad拆单解析板材开始】====================");
log.debug("====================【cad拆单解析板材开始】====================");
// 板材id对应板件
analyzeMaterials(webCadDataReqVO.getMaterials(), webCadDataReqVO.getBlocks());
log.info("====================【cad拆单解析板材结束】====================");
log.debug("====================【cad拆单解析板材结束】====================");
log.info("====================【cad拆单解析加工组开始】====================");
log.debug("====================【cad拆单解析加工组开始】====================");
// 解析加工组类型
analyzeGroups(webCadDataReqVO.getProcessGroup(), webCadDataReqVO.getBlocks(), webCadDataReqVO.getParts());
log.info("====================【cad拆单解析加工组结束】====================");
log.debug("====================【cad拆单解析加工组结束】====================");
log.info("====================【cad拆单解析成倍柜体开始】====================");
log.debug("====================【cad拆单解析成倍柜体开始】====================");
// 缓存柜体成倍信息
analyzeRoomBody(webCadDataReqVO.getDouleRoomTree());
log.info("====================【cad拆单解析成倍柜体结束】====================");
log.debug("====================【cad拆单解析成倍柜体结束】====================");
log.info("====================【cad拆单解析板件开始】====================");
log.debug("====================【cad拆单解析板件开始】====================");
// 解析板件列表
analyzeBlockList(webCadDataReqVO.getBlocks());
log.info("====================【cad拆单解析板件结束】====================");
log.debug("====================【cad拆单解析板件结束】====================");
log.info("====================【cad拆单解析配件开始】====================");
log.debug("====================【cad拆单解析配件开始】====================");
// 解析配件列表
analyzeParts(webCadDataReqVO.getParts());
log.info("====================【cad拆单解析配件结束】====================");
log.debug("====================【cad拆单解析配件结束】====================");
log.info("====================【cad拆单异步保存开始】====================");
orderItemBatchInsertWithinThreshold(orderItemDOS, true);
log.debug("====================【cad拆单异步保存开始】====================");
// 异步保存数据
saveDataAsync();
log.info("====================【cad拆单异步保存结束】====================");
log.debug("====================【cad拆单异步保存结束】====================");
} catch (Exception e) {
if (esInsert) {
@@ -338,7 +340,10 @@ public class WebCadOrderImportFactory {
private void analyzeOrder(WebCadDataOrderReqVO orderReqVO) {
// 查询生产单信息
String orderNo = orderReqVO.getOrderNo();
OrderDO orderDOFromOrderNo = orderMapper.selectById(NumberUtil.parseLong(orderNo));
OrderDO orderDOFromOrderNo = orderMapper.selectOne(new LambdaUpdateWrapper<OrderDO>()
.eq(OrderDO::getId, NumberUtil.parseLong(orderNo))
.eq(OrderDO::getOrganId, organId)
.eq(OrderDO::getDeleted, false));
if (ObjectUtil.isNull(orderDOFromOrderNo)) {
throw ServiceExceptionUtil.exception(WEBCAD_ORDER_NOT_EXISTS_ERROR, orderNo);
} else {
@@ -369,7 +374,10 @@ public class WebCadOrderImportFactory {
String plateGoodsId = materialReqVO.getId();
String plateGoodsGoodsId = materialReqVO.getGoodsId();
List<Integer> orginIds = materialReqVO.getOrginIds();
PlateGoodDO plateGoodDO = plateGoodMapper.selectById(plateGoodsId);
PlateGoodDO plateGoodDO = plateGoodMapper.selectOne(new LambdaQueryWrapper<PlateGoodDO>()
.eq(PlateGoodDO::getId, NumberUtil.parseLong(plateGoodsId))
.eq(PlateGoodDO::getOrganId, organId)
.eq(PlateGoodDO::getDeleted, false));
// 检查板材库
if (ObjectUtil.isNull(plateGoodDO)) {
throw ServiceExceptionUtil.exception(WEBCAD_ORDER_IMPORT_PLATE_NOT_EXIST_ERROR, plateGoodsId);
@@ -632,7 +640,7 @@ public class WebCadOrderImportFactory {
// 所有自定义板编号生成完成后更新配置到生产单
customPlateNoGenerateService.updateCustomPlateNoGenerateConfig(plateNoGenerateConfigVO, orderDO);
// 批量插入板件
orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, true);
orderPlateBatchInsertWithinThreshold(plateDOS, true);
// 批量插入造型数据
orderModelsBatchInsertWithinThreshold(true);
}
@@ -768,7 +776,7 @@ public class WebCadOrderImportFactory {
//批量保存板件
plateDOS.add(plateDO);
orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, false);
orderPlateBatchInsertWithinThreshold(plateDOS, false);
// 创建es造型数据
createModel(plateDO, block, blockInfo, plateRemark);
@@ -1254,6 +1262,7 @@ public class WebCadOrderImportFactory {
.organId(organId)
.build();
orderItemDOS.add(orderItemDO);
orderItemBatchInsertWithinThreshold(orderItemDOS, false);
}
} else {
// 没有归属的加工组,只创建一个orderItem
@@ -1272,6 +1281,7 @@ public class WebCadOrderImportFactory {
.organId(organId)
.build();
orderItemDOS.add(orderItemDO);
orderItemBatchInsertWithinThreshold(orderItemDOS, false);
}
}
@@ -1436,6 +1446,7 @@ public class WebCadOrderImportFactory {
.organId(organId)
.build();
orderItemDOS.add(orderItemDO);
orderItemBatchInsertWithinThreshold(orderItemDOS, false);
}
OrderItemDO orderItemDO = OrderItemDO
.builder()
@@ -1452,6 +1463,7 @@ public class WebCadOrderImportFactory {
.organId(organId)
.build();
orderItemDOS.add(orderItemDO);
orderItemBatchInsertWithinThreshold(orderItemDOS, false);
} else {
OrderItemDO orderItemDO = OrderItemDO
.builder()
@@ -1468,6 +1480,7 @@ public class WebCadOrderImportFactory {
.organId(organId)
.build();
orderItemDOS.add(orderItemDO);
orderItemBatchInsertWithinThreshold(orderItemDOS, false);
}
}
@@ -1544,13 +1557,15 @@ public class WebCadOrderImportFactory {
.organId(organId)
.deleted(false)
.build();
orderPartsDO.setCreator(operatorName);
orderPartsDO.setUpdater(operatorName);
orderPartsDO.setCreateTime(now);
orderPartsDO.setUpdateTime(now);
orderPartsDOS.add(orderPartsDO);
orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, false);
orderPartBatchInsertWithinThreshold(orderPartsDOS, false);
// 配件id回显到列表
partValue.forEach(p -> {
p.setImesPartsId(partId);
});
partValue.forEach(p -> p.setImesPartsId(partId));
});
// 组件不分组,每一个组件认为是一种组件
for (WebCadDataPartsReqVO.BlockObjectListDTO module : moduleCollect) {
@@ -1581,13 +1596,17 @@ public class WebCadOrderImportFactory {
.organId(organId)
.deleted(false)
.build();
orderPartsDO.setCreator(operatorName);
orderPartsDO.setUpdater(operatorName);
orderPartsDO.setCreateTime(now);
orderPartsDO.setUpdateTime(now);
orderPartsDOS.add(orderPartsDO);
orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, false);
orderPartBatchInsertWithinThreshold(orderPartsDOS, false);
// 配件id回显到列表
module.setImesPartsId(partId);
}
orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, true);
orderPartBatchInsertWithinThreshold(orderPartsDOS, true);
}
@@ -1714,6 +1733,90 @@ public class WebCadOrderImportFactory {
}
}
/**
* 每达到阈值就批量插入一次orderItem
*
* @param list
* @param isLast 是否最后一次插入,不是就需要清理list
*/
private void orderItemBatchInsertWithinThreshold(List<OrderItemDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
// 深拷贝list
List<OrderItemDO> deepCopyList = list.stream().map(item -> new OrderItemDO(item)).collect(Collectors.toList());
threadPoolTaskExecutor.submit(() -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderItemMapper.insertBatchSomeColumn(deepCopyList);
deepCopyList.clear();
} catch (Exception e) {
log.error("WEBCAD import saveItemAsync error", e);
}
});
if (!isLast) {
// 存储完成清理 list
list.clear();
}
}
}
/**
* 每达到阈值就批量插入一次orderPlate
*
* @param list
* @param isLast 是否最后一次插入,不是就需要清理list
*/
private void orderPlateBatchInsertWithinThreshold(List<PlateDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
// 深拷贝list
List<PlateDO> deepCopyList = list.stream().map(item -> new PlateDO(item)).collect(Collectors.toList());
threadPoolTaskExecutor.submit(() -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
plateMapper.insertBatchSomeColumn(deepCopyList);
deepCopyList.clear();
} catch (Exception e) {
log.error("WEBCAD import savePlateAsync error", e);
}
});
if (!isLast) {
// 存储完成清理 list
list.clear();
}
}
}
/**
* 每达到阈值就批量插入一次orderPart
*
* @param list
* @param isLast 是否最后一次插入,不是就需要清理list
*/
private void orderPartBatchInsertWithinThreshold(List<OrderPartsDO> list, boolean isLast) {
// 达到批量的阈值就做一次插入
if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
// 深拷贝list
List<OrderPartsDO> deepCopyList = list.stream().map(item -> new OrderPartsDO(item)).collect(Collectors.toList());
threadPoolTaskExecutor.submit(() -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderPartsMapper.insertBatchSomeColumn(deepCopyList);
deepCopyList.clear();
} catch (Exception e) {
log.error("WEBCAD import savePartAsync error", e);
}
});
if (!isLast) {
// 存储完成清理 list
list.clear();
}
}
}
/**
* 每达到阈值就批量插入一次生产单造型数据和压缩数据
*
@@ -1754,19 +1857,15 @@ public class WebCadOrderImportFactory {
private void saveDataAsync() {
TransactionStatus transactionStatus = transactionManager.getTransaction(TransactionDefinition.withDefaults());
AtomicBoolean hasError = new AtomicBoolean(false);
// 当前数据源data_code
String peek = DynamicDataSourceContextHolder.peek();
List<List<OrderBodyDO>> bodyList = batchProcess(bodyMap.values().stream().toList());
List<List<OrderGroupDO>> groupList = batchProcess(orderGroupDOS);
List<List<OrderItemDO>> itemList = batchProcess(orderItemDOS);
// 计数器
CountDownLatch latch = new CountDownLatch(bodyList.size() + groupList.size() + itemList.size());
CountDownLatch latch = new CountDownLatch(bodyList.size() + groupList.size());
// 保存
saveBodyAsync(bodyList, latch, hasError);
saveGroupAsync(groupList, latch, hasError);
saveItemAsync(itemList, latch, hasError);
try {
// 等待所有任务完成,30s没有完成就主动终止
@@ -1840,32 +1939,6 @@ public class WebCadOrderImportFactory {
}
}
/**
* 异步插入明细item
*
* @param latch
* @param hasError
*/
private void saveItemAsync(List<List<OrderItemDO>> itemList, CountDownLatch latch, AtomicBoolean hasError) {
for (List<OrderItemDO> itemDOS : itemList) {
threadPoolTaskExecutor.submit(() -> {
try {
// 子线程同步主线程的多数据源
DynamicDataSourceContextHolder.push(peek);
orderItemMapper.insertBatchSomeColumn(itemDOS);
} catch (Exception e) {
log.error("WEBCAD import saveItemAsync error", e);
boolean b = hasError.get();
if (!b) {
hasError.set(true);
}
} finally {
latch.countDown(); // 任务完成,计数器减1
}
});
}
}
/**
* 每batchSize条拆分dataList
*
@@ -1905,8 +1978,4 @@ public class WebCadOrderImportFactory {
processGroupMap.clear();
materialMap.clear();
}
public static void main(String[] args) {
System.out.println(Math.ceil(205 / 100));
}
}
@@ -166,6 +166,7 @@ chenfeng:
- com.cf.imes.module.plan.enums.ErrorCodeConstants
organ: # 多组织相关配置项
enable: true
superadmin-prod-org-ignore-enable: false
ignore-urls:
- /rpc-api/**
ignore-tables: