mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 12:52:07 +08:00
1、新增cad拆单支持部件不加工状态判定;2、加工/恢复部件顶级部分加工状态判定处理;
This commit is contained in:
+5
@@ -108,4 +108,9 @@ public class OrderComponentDO extends BaseDO {
|
||||
* 加工状态
|
||||
*/
|
||||
private Integer processStatus;
|
||||
|
||||
/**
|
||||
* 附加加工状态:不加工/部分加工(只有顶级)
|
||||
*/
|
||||
private Integer extraProcessStatus;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package com.cf.imes.module.plan.framework.rpc.config;
|
||||
|
||||
import com.cf.imes.module.infra.api.file.FileApi;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
|
||||
import com.cf.imes.module.system.api.customplateno.CustomPlateNoSeqApi;
|
||||
import com.cf.imes.module.system.api.dict.DictDataApi;
|
||||
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
|
||||
@@ -12,6 +13,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
* @author there
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableFeignClients(clients = {AdminUserApi.class, DictDataApi.class, SystemConfigApi.class, CustomPlateNoSeqApi.class, FileApi.class})
|
||||
@EnableFeignClients(clients = {AdminUserApi.class, DictDataApi.class, SystemConfigApi.class, CustomPlateNoSeqApi.class, FileApi.class, AssemblyConfigApi.class})
|
||||
public class RpcConfiguration {
|
||||
}
|
||||
|
||||
+5
-1
@@ -35,6 +35,7 @@ import com.cf.imes.module.plan.enums.ErrorCodeConstants;
|
||||
import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService;
|
||||
import com.cf.imes.module.plan.service.orderImport.factory.WebCadOrderImportFactory;
|
||||
import com.cf.imes.module.plan.service.orderImport.property.WebCadImportProperties;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
|
||||
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
@@ -118,6 +119,9 @@ public class WebCadOrderImportServiceImpl implements WebCadOrderImportService {
|
||||
@Resource
|
||||
private WebCadImportProperties webCadImportProperties;
|
||||
|
||||
@Resource
|
||||
private AssemblyConfigApi assemblyConfigApi;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean webCadOrderImport(MultipartFile file) {
|
||||
@@ -161,7 +165,7 @@ public class WebCadOrderImportServiceImpl implements WebCadOrderImportService {
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
WebCadDataReqVO webCadDataReqVO = mapper.readValue(parser, WebCadDataReqVO.class);
|
||||
WebCadOrderImportFactory webCadOrderImportFactory = new WebCadOrderImportFactory(organId, orderDO, snowFlakeGenerator, orderMapper, orderBodyMapper, plateMapper,
|
||||
idWorker, goodsMapper, customPlateNoGenerateService, systemConfigApi, webCadImportProperties.getCadImportPlateNumThreshold(), jdbcTemplate);
|
||||
idWorker, goodsMapper, customPlateNoGenerateService, systemConfigApi, assemblyConfigApi, webCadImportProperties.getCadImportPlateNumThreshold(), jdbcTemplate);
|
||||
|
||||
// cad图纸文件id
|
||||
cadViewFileId = webCadDataReqVO.getCadViewFileId();
|
||||
|
||||
+5
-1
@@ -20,6 +20,7 @@ import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateServic
|
||||
import com.cf.imes.module.plan.service.orderImport.OrderImportTaskService;
|
||||
import com.cf.imes.module.plan.service.orderImport.factory.WebCadOrderImportAsyncFactory;
|
||||
import com.cf.imes.module.plan.service.orderImport.property.WebCadImportProperties;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
|
||||
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -76,6 +77,9 @@ public class WebCadOrderImportConsumer {
|
||||
@Resource
|
||||
private SystemConfigApi systemConfigApi;
|
||||
|
||||
@Resource
|
||||
private AssemblyConfigApi assemblyConfigApi;
|
||||
|
||||
@Value("${chenfeng.plan.webcad.import.cadImportPlateNumThreshold:10000}")
|
||||
private int cadImportPlateNumThreshold;
|
||||
|
||||
@@ -138,7 +142,7 @@ public class WebCadOrderImportConsumer {
|
||||
log.info("====================【webcad异步拆单处理临时数据开始】====================");
|
||||
WebCadOrderImportAsyncFactory webCadOrderImportAsyncFactory =
|
||||
new WebCadOrderImportAsyncFactory(organId, orderMapper, snowFlakeGenerator, orderBodyMapper, plateMapper, idWorker,
|
||||
orderImportTaskMapper, goodsMapper, customPlateNoGenerateService, systemConfigApi, orderImportTaskDO.getCreator(),
|
||||
orderImportTaskMapper, goodsMapper, customPlateNoGenerateService, systemConfigApi, assemblyConfigApi, orderImportTaskDO.getCreator(),
|
||||
cadImportPlateNumThreshold, jdbcTemplate);
|
||||
webCadOrderImportAsyncFactory.analyzeTempData(taskId, webCadImportProperties.getTempFilePath());
|
||||
log.info("====================【webcad异步拆单处理临时数据结束】====================");
|
||||
|
||||
+306
-48
@@ -5,6 +5,8 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.util.ListUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
@@ -61,6 +63,9 @@ import com.cf.imes.module.plan.enums.ErrorCodeConstants;
|
||||
import com.cf.imes.module.plan.enums.ordercomponent.OrderComponentProcessStatusEnum;
|
||||
import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService;
|
||||
import com.cf.imes.module.plan.service.customplateno.vo.CustomPlateNoGenerateConfigVO;
|
||||
import com.cf.imes.module.plan.service.orderImport.vo.OrderComponentTreeCompareVO;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.dto.AssemblyConfigRespDTO;
|
||||
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
|
||||
import com.cf.imes.module.system.api.systemconfig.dto.SystemConfigRespDTO;
|
||||
import com.cf.imes.module.system.api.systemconfig.dto.SystemConfigSealEdgeRespDTO;
|
||||
@@ -83,10 +88,14 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_GET_ORG_SEALEDGE_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORDER_PLATENUM_CHECK_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORG_SEALEDGE_ANALYZE_ERROR;
|
||||
@@ -119,6 +128,8 @@ public class WebCadOrderImportAsyncFactory {
|
||||
|
||||
private SystemConfigApi systemConfigApi;
|
||||
|
||||
private AssemblyConfigApi assemblyConfigApi;
|
||||
|
||||
private GoodsMapper goodsMapper;
|
||||
|
||||
private CustomPlateNoGenerateService customPlateNoGenerateService;
|
||||
@@ -207,6 +218,7 @@ public class WebCadOrderImportAsyncFactory {
|
||||
GoodsMapper goodsMapper,
|
||||
CustomPlateNoGenerateService customPlateNoGenerateService,
|
||||
SystemConfigApi systemConfigApi,
|
||||
AssemblyConfigApi assemblyConfigApi,
|
||||
String operatorName,
|
||||
int cadImportPlateNumThreshold,
|
||||
JdbcTemplate jdbcTemplate) {
|
||||
@@ -220,6 +232,7 @@ public class WebCadOrderImportAsyncFactory {
|
||||
this.goodsMapper = goodsMapper;
|
||||
this.customPlateNoGenerateService = customPlateNoGenerateService;
|
||||
this.systemConfigApi = systemConfigApi;
|
||||
this.assemblyConfigApi = assemblyConfigApi;
|
||||
this.operatorName = operatorName;
|
||||
now = LocalDateTime.now();
|
||||
batchId = (Long) snowFlakeGenerator.nextId(null);
|
||||
@@ -1764,91 +1777,336 @@ public class WebCadOrderImportAsyncFactory {
|
||||
* @param reader
|
||||
*/
|
||||
private void processComponentList(JSONReader reader) {
|
||||
reader.startArray();
|
||||
while (reader.hasNext()) {
|
||||
processComponent(reader, null, null, 0);
|
||||
// 1. 构建树
|
||||
List<OrderComponentTreeCompareVO> roots = buildTree(reader);
|
||||
|
||||
if (CollUtil.isEmpty(roots)) {
|
||||
return;
|
||||
}
|
||||
reader.endArray();
|
||||
orderComponentBatchInsertWithinThreshold(orderComponentDOS, true);
|
||||
|
||||
// 2. 查询配置
|
||||
List<String> names = roots.stream()
|
||||
.map(OrderComponentTreeCompareVO::getName)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
CommonResult<List<AssemblyConfigRespDTO>> result =
|
||||
assemblyConfigApi.getNotProcessAssemblyConfigByPartNameList(names);
|
||||
|
||||
if (result.isError()) {
|
||||
throw new ServiceException(ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR);
|
||||
}
|
||||
|
||||
List<AssemblyConfigRespDTO> configList = result.getData();
|
||||
|
||||
// 3. hash计算
|
||||
for (OrderComponentTreeCompareVO root : roots) {
|
||||
computeHashRecursively(root);
|
||||
}
|
||||
|
||||
// 4. 状态刷新
|
||||
refreshComponentStatus(roots, configList);
|
||||
|
||||
// 5. 入库
|
||||
List<OrderComponentDO> buffer = new ArrayList<>();
|
||||
for (OrderComponentTreeCompareVO root : roots) {
|
||||
createAndCacheComponent(root, null, null, 0);
|
||||
}
|
||||
|
||||
orderComponentBatchInsertWithinThreshold(buffer, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析单个部件
|
||||
* 创建部件并缓存
|
||||
*
|
||||
* @param reader
|
||||
* @param componentGroupReqVO cad部件数据
|
||||
* @param parentId 父级部件id
|
||||
* @param topId 顶级部件id
|
||||
* @param level 层级从0开始计算
|
||||
*/
|
||||
private void processComponent(JSONReader reader, Long parentId, Long topId, int level) {
|
||||
if (parentId == null) {
|
||||
private void createAndCacheComponent(OrderComponentTreeCompareVO componentGroupReqVO, Long parentId, Long topId, int level) {
|
||||
if (ObjectUtil.isNull(parentId)) {
|
||||
parentId = OrderComponentDO.PARENT_ID_ROOT;
|
||||
}
|
||||
Integer cadGroupId = componentGroupReqVO.getId();
|
||||
Long componentId = (Long) snowFlakeGenerator.nextId(null);
|
||||
// 顶级节点创建过一次后后续继续使用
|
||||
if (ObjectUtil.isNull(topId)) {
|
||||
topId = componentId;
|
||||
}
|
||||
OrderComponentDO componentDO = OrderComponentDO.builder()
|
||||
.id(componentId)
|
||||
.organId(organId)
|
||||
.orderId(orderId)
|
||||
.pid(parentId)
|
||||
.topId(topId)
|
||||
.name(componentGroupReqVO.getName())
|
||||
.width(componentGroupReqVO.getWidth())
|
||||
.height(componentGroupReqVO.getHeight())
|
||||
.depth(componentGroupReqVO.getDepth())
|
||||
.cadViewFileId(cadViewFileId)
|
||||
.processStatus(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus())
|
||||
.extraProcessStatus(componentGroupReqVO.getProcessStatus())
|
||||
.level(level)
|
||||
.build();
|
||||
componentDO.setCreateTime(now);
|
||||
componentDO.setUpdateTime(now);
|
||||
componentDO.setCreator(operatorName);
|
||||
componentDO.setUpdater(operatorName);
|
||||
componentDO.setDeleted(false);
|
||||
|
||||
Integer cadGroupId = null;
|
||||
// 缓存部件
|
||||
componentGroupMap.put(cadGroupId, componentId);
|
||||
// 部件入库
|
||||
orderComponentDOS.add(componentDO);
|
||||
orderComponentBatchInsertWithinThreshold(orderComponentDOS, false);
|
||||
// 继续处理下级
|
||||
if (CollUtil.isNotEmpty(componentGroupReqVO.getChildren())) {
|
||||
for (OrderComponentTreeCompareVO children : componentGroupReqVO.getChildren()) {
|
||||
createAndCacheComponent(children, componentId, topId, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取全部部件树
|
||||
*
|
||||
* @param reader
|
||||
* @return
|
||||
*/
|
||||
private List<OrderComponentTreeCompareVO> buildTree(JSONReader reader) {
|
||||
|
||||
List<OrderComponentTreeCompareVO> roots = new ArrayList<>();
|
||||
|
||||
reader.startArray();
|
||||
|
||||
while (reader.hasNext()) {
|
||||
roots.add(readNode(reader));
|
||||
}
|
||||
|
||||
reader.endArray();
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个部件节点读取
|
||||
*
|
||||
* @param reader
|
||||
* @return
|
||||
*/
|
||||
private OrderComponentTreeCompareVO readNode(JSONReader reader) {
|
||||
|
||||
Integer groupId = null;
|
||||
String name = null;
|
||||
WebCadDataComponentGroupReqVO.BoxSizeDTO boxSize = null;
|
||||
|
||||
List<OrderComponentTreeCompareVO> children = new ArrayList<>();
|
||||
|
||||
reader.startObject();
|
||||
List<JSONReader> childrenReaders = new ArrayList<>();
|
||||
|
||||
while (reader.hasNext()) {
|
||||
|
||||
String key = reader.readString();
|
||||
|
||||
switch (key) {
|
||||
|
||||
case "groupID":
|
||||
cadGroupId = reader.readInteger();
|
||||
groupId = reader.readInteger();
|
||||
break;
|
||||
|
||||
case "name":
|
||||
name = reader.readString();
|
||||
break;
|
||||
|
||||
case "boxSize":
|
||||
boxSize = reader.readObject(WebCadDataComponentGroupReqVO.BoxSizeDTO.class);
|
||||
break;
|
||||
|
||||
case "children":
|
||||
// 当前节点生成 OrderComponentDO
|
||||
Long componentId = (Long) snowFlakeGenerator.nextId(null);
|
||||
if (topId == null) {
|
||||
topId = componentId;
|
||||
}
|
||||
|
||||
OrderComponentDO componentDO = OrderComponentDO.builder()
|
||||
.id(componentId)
|
||||
.organId(organId)
|
||||
.orderId(orderId)
|
||||
.pid(parentId)
|
||||
.topId(topId)
|
||||
.name(name)
|
||||
.width(boxSize != null ? boxSize.getWidth() : null)
|
||||
.height(boxSize != null ? boxSize.getHeight() : null)
|
||||
.depth(boxSize != null ? boxSize.getDepth() : null)
|
||||
.cadViewFileId(cadViewFileId)
|
||||
.processStatus(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus())
|
||||
.level(level)
|
||||
.build();
|
||||
|
||||
componentDO.setCreateTime(now);
|
||||
componentDO.setUpdateTime(now);
|
||||
componentDO.setCreator(operatorName);
|
||||
componentDO.setUpdater(operatorName);
|
||||
componentDO.setDeleted(false);
|
||||
|
||||
// 缓存组件id
|
||||
componentGroupMap.put(cadGroupId, componentId);
|
||||
|
||||
// 逐条加入批量入库
|
||||
orderComponentDOS.add(componentDO);
|
||||
orderComponentBatchInsertWithinThreshold(orderComponentDOS, false);
|
||||
|
||||
reader.startArray();
|
||||
|
||||
while (reader.hasNext()) {
|
||||
// 递归子节点
|
||||
processComponent(reader, componentId, topId, level + 1); // 子节点在递归中生成组件DO
|
||||
children.add(readNode(reader));
|
||||
}
|
||||
|
||||
reader.endArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
// 其他字段直接跳过
|
||||
reader.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
|
||||
OrderComponentTreeCompareVO node = new OrderComponentTreeCompareVO();
|
||||
node.setId(groupId == null ? null : groupId);
|
||||
node.setName(name);
|
||||
node.setChildren(children);
|
||||
node.setProcessStatus(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus());
|
||||
|
||||
if (boxSize != null) {
|
||||
node.setWidth(boxSize.getWidth());
|
||||
node.setHeight(boxSize.getHeight());
|
||||
node.setDepth(boxSize.getDepth());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归生成 structureHash
|
||||
*
|
||||
* @return 当前节点结构字符串
|
||||
*/
|
||||
private void computeHashRecursively(OrderComponentTreeCompareVO node) {
|
||||
|
||||
List<OrderComponentTreeCompareVO> children = node.getChildren();
|
||||
|
||||
if (CollUtil.isNotEmpty(children)) {
|
||||
|
||||
children.sort(Comparator.comparing(OrderComponentTreeCompareVO::getName));
|
||||
|
||||
for (OrderComponentTreeCompareVO child : children) {
|
||||
computeHashRecursively(child);
|
||||
}
|
||||
}
|
||||
|
||||
node.setStructureHash(
|
||||
DigestUtil.sha256Hex(buildStructureString(node))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private String buildStructureString(OrderComponentTreeCompareVO node) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(node.getName());
|
||||
|
||||
List<OrderComponentTreeCompareVO> children = node.getChildren();
|
||||
|
||||
if (CollUtil.isNotEmpty(children)) {
|
||||
|
||||
sb.append("(");
|
||||
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
sb.append(buildStructureString(children.get(i)));
|
||||
}
|
||||
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新组件树状态
|
||||
*
|
||||
* 规则:
|
||||
* 1、当前节点配置 process=false => 不加工
|
||||
* 2、任意直接子节点为“不加工” => 当前节点部分加工
|
||||
* 3、否则 => 未加工
|
||||
*/
|
||||
private void refreshComponentStatus(
|
||||
List<OrderComponentTreeCompareVO> roots,
|
||||
List<AssemblyConfigRespDTO> configList) {
|
||||
|
||||
if (CollUtil.isEmpty(roots) || CollUtil.isEmpty(configList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, AssemblyConfigRespDTO> configMap =
|
||||
configList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
item -> buildKey(item.getComponentName(), item.getStructureHash()),
|
||||
Function.identity(),
|
||||
(a, b) -> a
|
||||
));
|
||||
|
||||
for (OrderComponentTreeCompareVO root : roots) {
|
||||
|
||||
String key = buildKey(root.getName(), root.getStructureHash());
|
||||
|
||||
AssemblyConfigRespDTO config = configMap.get(key);
|
||||
|
||||
if (config == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(config.getNotProcess())) {
|
||||
root.setProcessStatus(OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus());
|
||||
}
|
||||
|
||||
// 反序列化配置树
|
||||
OrderComponentTreeCompareVO configTree =
|
||||
JSONUtil.toBean(
|
||||
JsonUtils.unzipString(
|
||||
config.getStructureJson()
|
||||
),
|
||||
OrderComponentTreeCompareVO.class
|
||||
);
|
||||
|
||||
// 递归同步状态
|
||||
refreshStatus(root, configTree);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归同步不加工状态
|
||||
*/
|
||||
private void refreshStatus(
|
||||
OrderComponentTreeCompareVO actualNode,
|
||||
OrderComponentTreeCompareVO configNode) {
|
||||
|
||||
List<OrderComponentTreeCompareVO> actualChildren =
|
||||
actualNode.getChildren();
|
||||
|
||||
List<OrderComponentTreeCompareVO> configChildren =
|
||||
configNode.getChildren();
|
||||
|
||||
if (CollUtil.isEmpty(actualChildren)
|
||||
|| CollUtil.isEmpty(configChildren)) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int size = Math.min(
|
||||
actualChildren.size(),
|
||||
configChildren.size()
|
||||
);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
OrderComponentTreeCompareVO actualChild =
|
||||
actualChildren.get(i);
|
||||
|
||||
OrderComponentTreeCompareVO configChild =
|
||||
configChildren.get(i);
|
||||
|
||||
// 子节点不加工
|
||||
if (!configChild.isProcess()) {
|
||||
|
||||
actualChild.setProcessStatus(
|
||||
OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus()
|
||||
);
|
||||
}
|
||||
|
||||
refreshStatus(actualChild, configChild);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建key
|
||||
*/
|
||||
private String buildKey(String name, String hash) {
|
||||
return name + "#" + hash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+297
-10
@@ -5,6 +5,8 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.util.ListUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
@@ -55,6 +57,9 @@ import com.cf.imes.module.plan.enums.ErrorCodeConstants;
|
||||
import com.cf.imes.module.plan.enums.ordercomponent.OrderComponentProcessStatusEnum;
|
||||
import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService;
|
||||
import com.cf.imes.module.plan.service.customplateno.vo.CustomPlateNoGenerateConfigVO;
|
||||
import com.cf.imes.module.plan.service.orderImport.vo.OrderComponentTreeCompareVO;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.AssemblyConfigApi;
|
||||
import com.cf.imes.module.system.api.assemblyconfig.dto.AssemblyConfigRespDTO;
|
||||
import com.cf.imes.module.system.api.systemconfig.SystemConfigApi;
|
||||
import com.cf.imes.module.system.api.systemconfig.dto.SystemConfigRespDTO;
|
||||
import com.cf.imes.module.system.api.systemconfig.dto.SystemConfigSealEdgeRespDTO;
|
||||
@@ -71,11 +76,15 @@ import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_GET_ORG_SEALEDGE_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORDER_PLATENUM_CHECK_ERROR;
|
||||
import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORDER_PLATENUM_REACH_THRESHOLD_ERROR;
|
||||
@@ -106,6 +115,8 @@ public class WebCadOrderImportFactory {
|
||||
|
||||
private SystemConfigApi systemConfigApi;
|
||||
|
||||
private AssemblyConfigApi assemblyConfigApi;
|
||||
|
||||
private GoodsMapper goodsMapper;
|
||||
|
||||
private CustomPlateNoGenerateService customPlateNoGenerateService;
|
||||
@@ -195,6 +206,7 @@ public class WebCadOrderImportFactory {
|
||||
GoodsMapper goodsMapper,
|
||||
CustomPlateNoGenerateService customPlateNoGenerateService,
|
||||
SystemConfigApi systemConfigApi,
|
||||
AssemblyConfigApi assemblyConfigApi,
|
||||
int cadImportPlateNumThreshold,
|
||||
JdbcTemplate jdbcTemplate) {
|
||||
this.organId = organId;
|
||||
@@ -208,6 +220,7 @@ public class WebCadOrderImportFactory {
|
||||
this.goodsMapper = goodsMapper;
|
||||
this.customPlateNoGenerateService = customPlateNoGenerateService;
|
||||
this.systemConfigApi = systemConfigApi;
|
||||
this.assemblyConfigApi = assemblyConfigApi;
|
||||
operatorName = SecurityFrameworkUtils.getLoginUser().getNickname();
|
||||
now = LocalDateTime.now();
|
||||
sealEdgeConfigList = new ArrayList<>();
|
||||
@@ -487,13 +500,284 @@ public class WebCadOrderImportFactory {
|
||||
if (CollUtil.isEmpty(componentGroupReqVOS)) {
|
||||
return;
|
||||
}
|
||||
for (WebCadDataComponentGroupReqVO componentGroupReqVO : componentGroupReqVOS) {
|
||||
createAndCacheComponent(componentGroupReqVO, null, null, 0);
|
||||
// 1、构建树 + 生成结构hash
|
||||
List<OrderComponentTreeCompareVO> roots =
|
||||
buildTree(componentGroupReqVOS);
|
||||
|
||||
// 2、查询装配配置
|
||||
List<String> names = roots.stream()
|
||||
.map(OrderComponentTreeCompareVO::getName)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
|
||||
CommonResult<List<AssemblyConfigRespDTO>> configResult =
|
||||
assemblyConfigApi.getNotProcessAssemblyConfigByPartNameList(names);
|
||||
|
||||
if (configResult.isError()) {
|
||||
throw new ServiceException(
|
||||
ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// 3、刷新组件状态
|
||||
refreshComponentStatus(roots, configResult.getData());
|
||||
|
||||
for (OrderComponentTreeCompareVO root : roots) {
|
||||
createAndCacheComponent(root, null, null, 0);
|
||||
}
|
||||
// 部件入库
|
||||
orderComponentBatchInsertWithinThreshold(orderComponentDOS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建运行时树
|
||||
*
|
||||
* 功能:
|
||||
* 1、递归转换树结构
|
||||
* 2、生成 structureHash
|
||||
* 3、初始化默认状态
|
||||
*/
|
||||
private List<OrderComponentTreeCompareVO> buildTree(
|
||||
List<WebCadDataComponentGroupReqVO> list) {
|
||||
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<OrderComponentTreeCompareVO> roots = new ArrayList<>();
|
||||
|
||||
for (WebCadDataComponentGroupReqVO node : list) {
|
||||
|
||||
// 递归转换
|
||||
OrderComponentTreeCompareVO root =
|
||||
convertNode(node);
|
||||
|
||||
// 递归生成 hash
|
||||
computeHashRecursively(root);
|
||||
|
||||
roots.add(root);
|
||||
}
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归转换节点
|
||||
*/
|
||||
private OrderComponentTreeCompareVO convertNode(
|
||||
WebCadDataComponentGroupReqVO node) {
|
||||
|
||||
OrderComponentTreeCompareVO vo =
|
||||
new OrderComponentTreeCompareVO();
|
||||
|
||||
vo.setId(node.getGroupId() == null
|
||||
? null
|
||||
: node.getGroupId());
|
||||
|
||||
vo.setName(node.getName());
|
||||
|
||||
// 尺寸
|
||||
if (ObjectUtil.isNotNull(node.getBoxSize())) {
|
||||
|
||||
vo.setWidth(node.getBoxSize().getWidth());
|
||||
|
||||
vo.setHeight(node.getBoxSize().getHeight());
|
||||
|
||||
vo.setDepth(node.getBoxSize().getDepth());
|
||||
}
|
||||
|
||||
// 默认未加工
|
||||
vo.setProcessStatus(
|
||||
OrderComponentProcessStatusEnum.UNPROCESSED.getStatus()
|
||||
);
|
||||
|
||||
List<OrderComponentTreeCompareVO> children =
|
||||
new ArrayList<>();
|
||||
|
||||
if (CollUtil.isNotEmpty(node.getChildren())) {
|
||||
|
||||
for (WebCadDataComponentGroupReqVO child :
|
||||
node.getChildren()) {
|
||||
|
||||
children.add(convertNode(child));
|
||||
}
|
||||
}
|
||||
|
||||
vo.setChildren(children);
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归生成 structureHash
|
||||
*
|
||||
* @return 当前节点结构字符串
|
||||
*/
|
||||
private String computeHashRecursively(
|
||||
OrderComponentTreeCompareVO node) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(node.getName());
|
||||
|
||||
List<OrderComponentTreeCompareVO> children =
|
||||
node.getChildren();
|
||||
|
||||
if (CollUtil.isNotEmpty(children)) {
|
||||
|
||||
// 排序保证 hash 稳定
|
||||
children.sort(
|
||||
Comparator.comparing(
|
||||
OrderComponentTreeCompareVO::getName
|
||||
)
|
||||
);
|
||||
|
||||
sb.append("(");
|
||||
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
|
||||
// 递归子节点
|
||||
sb.append(
|
||||
computeHashRecursively(
|
||||
children.get(i)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
String structureStr = sb.toString();
|
||||
|
||||
// 当前节点 hash
|
||||
node.setStructureHash(
|
||||
DigestUtil.sha256Hex(structureStr)
|
||||
);
|
||||
|
||||
return structureStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新组件树状态
|
||||
*
|
||||
* 规则:
|
||||
* 1、当前节点配置 process=false => 不加工
|
||||
* 2、任意直接子节点为“不加工” => 当前节点部分加工
|
||||
* 3、否则 => 未加工
|
||||
*/
|
||||
private void refreshComponentStatus(
|
||||
List<OrderComponentTreeCompareVO> roots,
|
||||
List<AssemblyConfigRespDTO> configList) {
|
||||
|
||||
if (CollUtil.isEmpty(roots)
|
||||
|| CollUtil.isEmpty(configList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 顶级配置索引
|
||||
Map<String, AssemblyConfigRespDTO> configMap =
|
||||
configList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
item -> buildKey(
|
||||
item.getComponentName(),
|
||||
item.getStructureHash()
|
||||
),
|
||||
Function.identity(),
|
||||
(a, b) -> a
|
||||
));
|
||||
|
||||
for (OrderComponentTreeCompareVO root : roots) {
|
||||
|
||||
String rootKey = buildKey(
|
||||
root.getName(),
|
||||
root.getStructureHash()
|
||||
);
|
||||
|
||||
AssemblyConfigRespDTO config = configMap.get(rootKey);
|
||||
|
||||
// 没有配置,默认整棵树未加工
|
||||
if (config == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 顶级是否不加工
|
||||
if (Boolean.TRUE.equals(config.getNotProcess())) {
|
||||
|
||||
root.setProcessStatus(
|
||||
OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus()
|
||||
);
|
||||
}
|
||||
|
||||
// 反序列化配置树
|
||||
OrderComponentTreeCompareVO configTree =
|
||||
JSONUtil.toBean(
|
||||
JsonUtils.unzipString(
|
||||
config.getStructureJson()
|
||||
),
|
||||
OrderComponentTreeCompareVO.class
|
||||
);
|
||||
|
||||
// 递归同步状态
|
||||
refreshStatus(root, configTree);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归同步不加工状态
|
||||
*/
|
||||
private void refreshStatus(
|
||||
OrderComponentTreeCompareVO actualNode,
|
||||
OrderComponentTreeCompareVO configNode) {
|
||||
|
||||
List<OrderComponentTreeCompareVO> actualChildren =
|
||||
actualNode.getChildren();
|
||||
|
||||
List<OrderComponentTreeCompareVO> configChildren =
|
||||
configNode.getChildren();
|
||||
|
||||
if (CollUtil.isEmpty(actualChildren)
|
||||
|| CollUtil.isEmpty(configChildren)) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int size = Math.min(
|
||||
actualChildren.size(),
|
||||
configChildren.size()
|
||||
);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
OrderComponentTreeCompareVO actualChild =
|
||||
actualChildren.get(i);
|
||||
|
||||
OrderComponentTreeCompareVO configChild =
|
||||
configChildren.get(i);
|
||||
|
||||
// 子节点不加工
|
||||
if (!configChild.isProcess()) {
|
||||
|
||||
actualChild.setProcessStatus(
|
||||
OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus()
|
||||
);
|
||||
}
|
||||
|
||||
refreshStatus(actualChild, configChild);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建key
|
||||
*/
|
||||
private String buildKey(String name, String hash) {
|
||||
return name + "#" + hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建部件并缓存
|
||||
*
|
||||
@@ -502,11 +786,11 @@ public class WebCadOrderImportFactory {
|
||||
* @param topId 顶级部件id
|
||||
* @param level 层级从0开始计算
|
||||
*/
|
||||
private void createAndCacheComponent(WebCadDataComponentGroupReqVO componentGroupReqVO, Long parentId, Long topId, int level) {
|
||||
private void createAndCacheComponent(OrderComponentTreeCompareVO componentGroupReqVO, Long parentId, Long topId, int level) {
|
||||
if (ObjectUtil.isNull(parentId)) {
|
||||
parentId = OrderComponentDO.PARENT_ID_ROOT;
|
||||
}
|
||||
Integer cadGroupId = componentGroupReqVO.getGroupId();
|
||||
Integer cadGroupId = componentGroupReqVO.getId();
|
||||
Long componentId = (Long) snowFlakeGenerator.nextId(null);
|
||||
// 顶级节点创建过一次后后续继续使用
|
||||
if (ObjectUtil.isNull(topId)) {
|
||||
@@ -519,11 +803,12 @@ public class WebCadOrderImportFactory {
|
||||
.pid(parentId)
|
||||
.topId(topId)
|
||||
.name(componentGroupReqVO.getName())
|
||||
.width(componentGroupReqVO.getBoxSize().getWidth())
|
||||
.height(componentGroupReqVO.getBoxSize().getHeight())
|
||||
.depth(componentGroupReqVO.getBoxSize().getDepth())
|
||||
.width(componentGroupReqVO.getWidth())
|
||||
.height(componentGroupReqVO.getHeight())
|
||||
.depth(componentGroupReqVO.getDepth())
|
||||
.cadViewFileId(cadViewFileId)
|
||||
.processStatus(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus())
|
||||
.extraProcessStatus(componentGroupReqVO.getProcessStatus())
|
||||
.level(level)
|
||||
.build();
|
||||
componentDO.setCreateTime(now);
|
||||
@@ -539,7 +824,7 @@ public class WebCadOrderImportFactory {
|
||||
orderComponentBatchInsertWithinThreshold(orderComponentDOS, false);
|
||||
// 继续处理下级
|
||||
if (CollUtil.isNotEmpty(componentGroupReqVO.getChildren())) {
|
||||
for (WebCadDataComponentGroupReqVO children : componentGroupReqVO.getChildren()) {
|
||||
for (OrderComponentTreeCompareVO children : componentGroupReqVO.getChildren()) {
|
||||
createAndCacheComponent(children, componentId, topId, level + 1);
|
||||
}
|
||||
}
|
||||
@@ -2052,13 +2337,14 @@ public class WebCadOrderImportFactory {
|
||||
updater,
|
||||
update_time,
|
||||
deleted,
|
||||
level
|
||||
level,
|
||||
extra_process_status
|
||||
) VALUES (
|
||||
?,?,?,?,?,?,
|
||||
?,?,?,?,
|
||||
?,?,?,?,
|
||||
?,?,?,
|
||||
?,?
|
||||
?,?,?
|
||||
)
|
||||
""";
|
||||
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
|
||||
@@ -2097,6 +2383,7 @@ public class WebCadOrderImportFactory {
|
||||
ps.setTimestamp(17, Timestamp.valueOf(item.getUpdateTime()));
|
||||
ps.setBoolean(18, item.getDeleted());
|
||||
ps.setInt(19, item.getLevel());
|
||||
ps.setInt(20, item.getExtraProcessStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.cf.imes.module.plan.service.orderImport.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2026/2/28 16:13
|
||||
*/
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class OrderComponentTreeCompareVO {
|
||||
/**
|
||||
* 部件id
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 父级id
|
||||
*/
|
||||
private Long pid;
|
||||
|
||||
/**
|
||||
* 部件名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 子部件
|
||||
*/
|
||||
private List<OrderComponentTreeCompareVO> children;
|
||||
|
||||
/**
|
||||
* 是否加工
|
||||
*/
|
||||
private boolean process;
|
||||
|
||||
/**
|
||||
* 加工状态
|
||||
*/
|
||||
private Integer processStatus;
|
||||
|
||||
/**
|
||||
* 结构哈希
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String structureHash;
|
||||
|
||||
/**
|
||||
* 部件级别
|
||||
*/
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
private Double width;
|
||||
|
||||
/**
|
||||
* 高度
|
||||
*/
|
||||
private Double height;
|
||||
|
||||
/**
|
||||
* 厚度
|
||||
*/
|
||||
private Double depth;
|
||||
}
|
||||
Reference in New Issue
Block a user