diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java index 6d8b3d9f8..b6e90df78 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java @@ -193,4 +193,5 @@ public class ErrorCodeConstants { public static final ErrorCode ORDER_COMPONENT_PROCESSED_REPEAT = new ErrorCode(1_003_010_004, "order.component.processed.repeat"); public static final ErrorCode ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR = new ErrorCode(1_003_010_005, "order.component.assembly.config.query.error"); public static final ErrorCode ORDER_COMPONENT_NOT_PROCESS = new ErrorCode(1_003_010_006, "order.component.not.process"); + public static final ErrorCode ORDER_COMPONENT_RESTORE_REPEAT = new ErrorCode(1_003_010_007, "order.component.restore.repeat"); } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/assemblylist/AssemblyListController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/assemblylist/AssemblyListController.java index 9773a4f66..e78c00bb5 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/assemblylist/AssemblyListController.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/assemblylist/AssemblyListController.java @@ -61,4 +61,12 @@ public class AssemblyListController { assemblyListService.processComponent(id); return CommonResult.success(true); } + + @PostMapping("/restore/{id}") + @Operation(summary = "装配清单-恢复未加工") + @Parameter(name = "id", description = "部件编号", required = true, example = "1024") + public CommonResult restoreComponent(@PathVariable Long id) { + assemblyListService.restoreComponent(id); + return CommonResult.success(true); + } } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/OrderComponentController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/OrderComponentController.java index a88f0a204..e7aeab5f3 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/OrderComponentController.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/OrderComponentController.java @@ -7,6 +7,7 @@ import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderDetai import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderDetailComponentPageReqVO; import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrdersTopComponentListReqVO; import com.cf.imes.module.executor.controller.admin.plate.vo.OrderViewPlatePageRespVO; +import com.cf.imes.module.executor.service.assemblylist.AssemblyListService; import com.cf.imes.module.executor.service.ordercomponent.OrderComponentService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -41,6 +42,9 @@ public class OrderComponentController { @Resource private OrderComponentService orderComponentService; + @Resource + private AssemblyListService assemblyListService; + @PostMapping("/detail/list") @Operation(summary = "查询订单详情部件列表") public CommonResult> getOrderComponentList(@Valid @RequestBody OrderDetailComponentListReqVO reqVO) { @@ -50,7 +54,7 @@ public class OrderComponentController { @PostMapping("/top/list") @Operation(summary = "查询订单顶级部件列表") public CommonResult> getOrderTopComponentList(@Valid @RequestBody OrdersTopComponentListReqVO reqVO) { - return success(orderComponentService.getOrderTopComponentList(reqVO)); + return success(assemblyListService.getOrderTopComponentList(reqVO)); } @PostMapping("/view/list") diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/vo/OrdersTopComponentListReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/vo/OrdersTopComponentListReqVO.java index 9bebf7b0a..1abd647db 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/vo/OrdersTopComponentListReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/ordercomponent/vo/OrdersTopComponentListReqVO.java @@ -1,5 +1,7 @@ package com.cf.imes.module.executor.controller.admin.ordercomponent.vo; +import com.cf.imes.framework.common.validation.InEnum; +import com.cf.imes.module.executor.enums.ordercomponent.OrderComponentProcessStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -33,4 +35,7 @@ public class OrdersTopComponentListReqVO { @Length(max = 64, message = "{order.component.assemble.req.name.max}") private String name; + @Schema(description = "加工状态:0不加工、1未加工、2已加工、3部分加工", example = "1") + @InEnum(OrderComponentProcessStatusEnum.class) + private List processStatus; } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/enums/ordercomponent/OrderComponentProcessStatusEnum.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/enums/ordercomponent/OrderComponentProcessStatusEnum.java index e0dc810b4..2f6091998 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/enums/ordercomponent/OrderComponentProcessStatusEnum.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/enums/ordercomponent/OrderComponentProcessStatusEnum.java @@ -28,7 +28,12 @@ public enum OrderComponentProcessStatusEnum implements IntArrayValuable { /** * 已加工 */ - PROCESSED(2); + PROCESSED(2), + + /** + * 部分加工 + */ + PART_PROCESSED(3); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(OrderComponentProcessStatusEnum::getStatus).toArray(); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListService.java index fbfd82b69..0f2d95c4f 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListService.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListService.java @@ -3,6 +3,7 @@ package com.cf.imes.module.executor.service.assemblylist; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyListComponentPageReqVO; import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderComponentRespVO; +import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrdersTopComponentListReqVO; import com.cf.imes.module.executor.controller.admin.plate.vo.OrderViewPlatePageRespVO; import java.util.List; @@ -42,4 +43,18 @@ public interface AssemblyListService { * @param id */ void processComponent(Long id); + + /** + * 恢复部件未加工状态 + * @param id + */ + void restoreComponent(Long id); + + /** + * 查询订单顶级部件列表 + * + * @param reqVO + * @return + */ + List getOrderTopComponentList(OrdersTopComponentListReqVO reqVO); } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListServiceImpl.java index f1ce8a1d8..054fe96f3 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/assemblylist/AssemblyListServiceImpl.java @@ -18,9 +18,11 @@ import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyListComponentPageReqVO; import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderComponentRespVO; import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderComponentTreeCompareVO; +import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrdersTopComponentListReqVO; import com.cf.imes.module.executor.controller.admin.plate.vo.OrderViewPlatePageRespVO; import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderBodyViewPlatesPageDO; import com.cf.imes.module.executor.dal.dataobject.ordercomponent.OrderComponentDO; @@ -43,6 +45,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -50,6 +53,7 @@ import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONE import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_NOT_EXIST; import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_NOT_PROCESS; import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_PROCESSED_REPEAT; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_RESTORE_REPEAT; /** * 装配清单 ServiceImpl 实现类 @@ -74,6 +78,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { @Override public List getComponentList(AssemblyListComponentPageReqVO reqVO) { Set componentIds = reqVO.getComponentIds(); + List orderIds = reqVO.getOrderIds(); if (CollUtil.isEmpty(componentIds)) { return Collections.emptyList(); } @@ -81,7 +86,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { // 查询入参部件 List componentDOS = orderComponentMapper.selectList(new LambdaUpdateWrapper() .in(OrderComponentDO::getId, componentIds) - .in(OrderComponentDO::getOrderId, reqVO.getOrderIds())); + .in(OrderComponentDO::getOrderId, orderIds)); if (CollUtil.isEmpty(componentDOS) || componentDOS.size() != componentIds.size()) { throw new ServiceException(ORDER_COMPONENT_NOT_EXIST); } @@ -91,19 +96,21 @@ public class AssemblyListServiceImpl implements AssemblyListService { .map(OrderComponentDO::getTopId) .toList(); - OrderComponentProcessStatusEnum orderComponentProcessStatusEnum = OrderComponentProcessStatusEnum.fromValue(reqVO.getProcessStatus()); - if (OrderComponentProcessStatusEnum.NOT_PROCESS.equals(orderComponentProcessStatusEnum)) { - // 不加工 - return getNotProcessComponentList(reqVO, topIds); - } else if (OrderComponentProcessStatusEnum.UNPROCESSED.equals(orderComponentProcessStatusEnum)) { - // 未加工 - return getUnProcessedComponentList(reqVO, topIds, false); - } else if (OrderComponentProcessStatusEnum.PROCESSED.equals(orderComponentProcessStatusEnum)) { - // 已加工 - return getProcessedComponentList(reqVO, topIds); - } else { - return getUnProcessedComponentList(reqVO, topIds, true); + // 根据部件的topid查询树上所有已加工节点 + List topUnProcessedComponentList = orderComponentMapper.selectList(new LambdaQueryWrapperX() + .in(OrderComponentDO::getTopId, topIds) + .in(OrderComponentDO::getOrderId, orderIds) + .select(OrderComponentDO::getId, OrderComponentDO::getPid, OrderComponentDO::getName, OrderComponentDO::getProcessStatus)); + + // 计算部件状态 + List treeCompareVOS = calculateProcessingStatusAccordingToAssemblyConfig(topUnProcessedComponentList); + + List result = new ArrayList<>(); + // 树形扁平化 + for (OrderComponentTreeCompareVO vo : treeCompareVOS) { + flatTree(vo, result); } + return result; } /** @@ -123,7 +130,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { return orderComponentTreeRespVOS; } CommonResult> assemblyConfigByComponentNameListResult = assemblyConfigApi.getAssemblyConfigByPartNameList(topComponentNames); - if(assemblyConfigByComponentNameListResult.isError()) { + if (assemblyConfigByComponentNameListResult.isError()) { throw new ServiceException(ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR); } List assemblyConfigByComponentNameList = assemblyConfigByComponentNameListResult.getData(); @@ -136,7 +143,6 @@ public class AssemblyListServiceImpl implements AssemblyListService { (v1, v2) -> v1 // 如果重复保留第一个 )); - // 从当前树的顶级中匹配name+hash,匹配上的存id:json用于解析加工状态 Map result = orderComponentTreeRespVOS.stream() .map(vo -> { @@ -168,77 +174,6 @@ public class AssemblyListServiceImpl implements AssemblyListService { return orderComponentTreeRespVOS; } - /** - * 查询已配置的部件列表 - * - * @return - */ - private List getProcessedComponentList(AssemblyListComponentPageReqVO reqVO, List topIds) { - // 根据部件的topid查询树上所有已加工节点 - List topProcessedComponentList = orderComponentMapper.selectList(new LambdaQueryWrapperX() - .in(OrderComponentDO::getTopId, topIds) - .in(OrderComponentDO::getOrderId, reqVO.getOrderIds()) - .likeIfPresent(OrderComponentDO::getName, reqVO.getName()) - .eqIfPresent(OrderComponentDO::getProcessStatus, OrderComponentProcessStatusEnum.PROCESSED.getStatus()) - .select(OrderComponentDO::getId, OrderComponentDO::getPid, OrderComponentDO::getName, OrderComponentDO::getProcessStatus)); - return BeanUtil.copyToList(topProcessedComponentList, OrderComponentRespVO.class); - } - - /** - * 查询未加工的部件列表 - * - * @param topIds - * @param reqVO - * @return - */ - private List getUnProcessedComponentList(AssemblyListComponentPageReqVO reqVO, List topIds, boolean showAll) { - // 根据部件的topid查询树上所有已加工节点 - List topUnProcessedComponentList = orderComponentMapper.selectList(new LambdaQueryWrapperX() - .in(OrderComponentDO::getTopId, topIds) - .in(OrderComponentDO::getOrderId, reqVO.getOrderIds()) - .likeIfPresent(OrderComponentDO::getName, reqVO.getName()) - .neIfPresent(OrderComponentDO::getProcessStatus, showAll ? null : OrderComponentProcessStatusEnum.PROCESSED.getStatus()) - .select(OrderComponentDO::getId, OrderComponentDO::getPid, OrderComponentDO::getName, OrderComponentDO::getProcessStatus)); - - // 计算部件状态 - List treeCompareVOS = calculateProcessingStatusAccordingToAssemblyConfig(topUnProcessedComponentList); - - List result = new ArrayList<>(); - // 树形扁平化 - for (OrderComponentTreeCompareVO vo : treeCompareVOS) { - flatTree(vo, result); - } - return result; - } - - /** - * 查询不加工的部件列表 - * - * @param topIds - * @param reqVO - * @return - */ - private List getNotProcessComponentList(AssemblyListComponentPageReqVO reqVO, List topIds) { - // 根据部件的topid查询树上所有节点 - List topComponentList = orderComponentMapper.selectList(new LambdaQueryWrapperX() - .in(OrderComponentDO::getTopId, topIds) - .in(OrderComponentDO::getOrderId, reqVO.getOrderIds()) - .likeIfPresent(OrderComponentDO::getName, reqVO.getName()) - .select(OrderComponentDO::getId, OrderComponentDO::getPid, OrderComponentDO::getName, OrderComponentDO::getProcessStatus)); - - // 计算部件状态 - List treeCompareVOS = calculateProcessingStatusAccordingToAssemblyConfig(topComponentList); - - List result = new ArrayList<>(); - // 树形扁平化 - for (OrderComponentTreeCompareVO vo : treeCompareVOS) { - flatTree(vo, result); - } - - return result.stream().filter(o -> ObjectUtil.equals(o.getProcessStatus(), OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus())).toList(); - - } - /** * 构建树 * @@ -375,7 +310,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { * @param result */ private void flatTree(OrderComponentTreeCompareVO node, - List result) { + List result) { if (node == null) { return; @@ -402,12 +337,35 @@ public class AssemblyListServiceImpl implements AssemblyListService { @Override public void processComponent(Long id) { + // 未加工 -> 加工 + handleComponentProcessStatus(id, OrderComponentProcessStatusEnum.UNPROCESSED.getStatus(), OrderComponentProcessStatusEnum.PROCESSED.getStatus()); + } + + @Override + public void restoreComponent(Long id) { + // 加工 -> 未加工 + handleComponentProcessStatus(id, OrderComponentProcessStatusEnum.PROCESSED.getStatus(), OrderComponentProcessStatusEnum.UNPROCESSED.getStatus()); + } + + /** + * 处理部件加工状态 + * + * @param id + * @param sourceProcessStatus 来源加工状态 + * @param targetProcessStatus 目标加工状态 + */ + private void handleComponentProcessStatus(Long id, Integer sourceProcessStatus, Integer targetProcessStatus) { // 查询和校验部件 OrderComponentDO componentDO = orderComponentMapper.selectById(id); AssertUtils.notEmpty(componentDO, ORDER_COMPONENT_NOT_EXIST); - AssertUtils.equals(componentDO.getProcessStatus(), OrderComponentProcessStatusEnum.PROCESSED.getStatus(), ORDER_COMPONENT_PROCESSED_REPEAT); + if (ObjectUtil.equals(OrderComponentProcessStatusEnum.PROCESSED.getStatus(), sourceProcessStatus)) { + AssertUtils.equals(componentDO.getProcessStatus(), OrderComponentProcessStatusEnum.UNPROCESSED.getStatus(), ORDER_COMPONENT_RESTORE_REPEAT); + } + + if (ObjectUtil.equals(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus(), sourceProcessStatus)) { + AssertUtils.equals(componentDO.getProcessStatus(), OrderComponentProcessStatusEnum.PROCESSED.getStatus(), ORDER_COMPONENT_PROCESSED_REPEAT); + } - int level = componentDO.getLevel(); Long organId = componentDO.getOrganId(); Long orderId = componentDO.getOrderId(); @@ -449,38 +407,30 @@ public class AssemblyListServiceImpl implements AssemblyListService { OrderComponentTreeCompareVO structure = JSON.parseObject(JsonUtils.unzipString(structureJson), OrderComponentTreeCompareVO.class); // 筛选出需要加工的部件id列表 - List needProcessComponentIds = getNeedProcessIdsByAssemblyConfig(currentTreeCompareVO, structure, id); - if (CollUtil.isEmpty(needProcessComponentIds)) { + Long needProcessComponentId = getNeedProcessIdsByAssemblyConfig(currentTreeCompareVO, structure, id); + if (ObjectUtil.isNull(needProcessComponentId)) { return; } // 更新加工状态 orderComponentMapper.update(new LambdaUpdateWrapper() - .in(OrderComponentDO::getId, needProcessComponentIds) + .eq(OrderComponentDO::getId, needProcessComponentId) .eq(OrderComponentDO::getOrderId, orderId) .eq(OrderComponentDO::getOrganId, organId) - .ge(OrderComponentDO::getLevel, level) - .eq(OrderComponentDO::getProcessStatus, OrderComponentProcessStatusEnum.UNPROCESSED.getStatus()) + .eq(OrderComponentDO::getProcessStatus, sourceProcessStatus) .eq(OrderComponentDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus()) - .set(OrderComponentDO::getProcessStatus, OrderComponentProcessStatusEnum.PROCESSED.getStatus()) + .set(OrderComponentDO::getProcessStatus, targetProcessStatus) ); } } else { - // 没有对应的装配设置,更新未加工的本身和下级 - List needProcessComponentIds = topProcessedComponentList.stream().filter(o -> - ObjectUtil.notEqual(OrderComponentProcessStatusEnum.PROCESSED.getStatus(), o.getProcessStatus()) && o.getLevel() >= level).map(OrderComponentDO::getId).toList(); - if (CollUtil.isEmpty(needProcessComponentIds)) { - return; - } orderComponentMapper.update(new LambdaUpdateWrapper() - .in(OrderComponentDO::getId, needProcessComponentIds) + .eq(OrderComponentDO::getId, id) .eq(OrderComponentDO::getOrderId, orderId) .eq(OrderComponentDO::getOrganId, organId) - .ge(OrderComponentDO::getLevel, level) - .eq(OrderComponentDO::getProcessStatus, OrderComponentProcessStatusEnum.UNPROCESSED.getStatus()) + .eq(OrderComponentDO::getProcessStatus, sourceProcessStatus) .eq(OrderComponentDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus()) - .set(OrderComponentDO::getProcessStatus, OrderComponentProcessStatusEnum.PROCESSED.getStatus()) + .set(OrderComponentDO::getProcessStatus, targetProcessStatus) ); } } @@ -488,10 +438,10 @@ public class AssemblyListServiceImpl implements AssemblyListService { /** * 点击加工入口方法 */ - public static List getNeedProcessIdsByAssemblyConfig(OrderComponentTreeCompareVO aRoot, OrderComponentTreeCompareVO bRoot, Long currentComponentId) { + public static Long getNeedProcessIdsByAssemblyConfig(OrderComponentTreeCompareVO aRoot, OrderComponentTreeCompareVO bRoot, Long currentComponentId) { if (aRoot == null || bRoot == null || currentComponentId == null) { - return Collections.emptyList(); + return null; } // 1. 构建 B 的 processMap @@ -500,7 +450,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { // 2. 找到 A 中点击的节点 OrderComponentTreeCompareVO startNode = findNodeById(aRoot, currentComponentId); if (startNode == null) { - return Collections.emptyList(); + return null; } // 判断当前节点是否允许加工 @@ -511,8 +461,8 @@ public class AssemblyListServiceImpl implements AssemblyListService { throw new ServiceException(ORDER_COMPONENT_NOT_PROCESS); } - // 3. 过滤需要加工的节点 - return collectNeedProcessNodes(startNode, processMap); + // 3. 本身没有不加工,返回id + return currentComponentId; } /** @@ -568,44 +518,6 @@ public class AssemblyListServiceImpl implements AssemblyListService { return map; } - /** - * 收集需要加工的节点 - */ - private static List collectNeedProcessNodes( - OrderComponentTreeCompareVO startNode, - Map processMap) { - - List result = new ArrayList<>(); - - Deque stack = new ArrayDeque<>(); - stack.push(startNode); - - while (!stack.isEmpty()) { - OrderComponentTreeCompareVO node = stack.pop(); - - String key = buildKey(node.getName(), node.getLevel()); - Boolean configProcess = processMap.get(key); - - boolean allowProcess = !Boolean.FALSE.equals(configProcess); - boolean alreadyProcessed = OrderComponentProcessStatusEnum.PROCESSED.getStatus().equals(node.getProcessStatus()); - - // 规则 1:B 中配置为 false → 不加入 - // 规则 2:已经加工过 → 不加入 - if (allowProcess && !alreadyProcessed) { - result.add(node.getId()); - } - - if (node.getChildren() != null) { - for (OrderComponentTreeCompareVO child : node.getChildren()) { - stack.push(child); - } - } - } - - return result; - } - - /** * 构建匹配 key */ @@ -675,7 +587,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { List records = pageRes.getRecords(); List resultList = new ArrayList<>(); - if(total > 0) { + if (total > 0) { resultList = records.stream().map(item -> { OrderViewPlatePageRespVO vo = new OrderViewPlatePageRespVO(); BeanUtil.copyProperties(item, vo); @@ -736,7 +648,7 @@ public class AssemblyListServiceImpl implements AssemblyListService { List records = viewPlatesPage.getRecords(); List resultList = new ArrayList<>(); - if(CollUtil.isNotEmpty(records)) { + if (CollUtil.isNotEmpty(records)) { resultList = records.stream().map(item -> { OrderViewPlatePageRespVO vo = new OrderViewPlatePageRespVO(); BeanUtil.copyProperties(item, vo); @@ -788,4 +700,209 @@ public class AssemblyListServiceImpl implements AssemblyListService { } return needDeleteIds; } + + @Override + public List getOrderTopComponentList(OrdersTopComponentListReqVO reqVO) { + /** + * 规则: + * 部件装配的状态: + * 1、已加工:部件根节点已加工 + * 2、未加工:部件根节点未加工,且子节点均为未加工状态 + * 3、部份加工:部件根节点未加工,且子节点至少有一个已加工 + * 4、不加工: 部件装配设置中至少有一个节点标记为不加工 + */ + if (CollUtil.isEmpty(reqVO.getOrderIds())) { + return Collections.emptyList(); + } + + List states = buildTopComponentStates(reqVO); + + if (CollUtil.isEmpty(states)) { + return Collections.emptyList(); + } + + Set statusSet = + Optional.ofNullable(reqVO.getProcessStatus()) + .orElse(Collections.emptyList()) + .stream() + .map(OrderComponentProcessStatusEnum::fromValue) + .collect(Collectors.toSet()); + + List result = states.stream() + .filter(state -> matchAnyStatus(state, statusSet)) + .map(state -> state.node) + .toList(); + + return BeanUtil.copyToList(result, OrderComponentRespVO.class); + } + + + private List buildTopComponentStates(OrdersTopComponentListReqVO reqVO) { + + List topComponents = orderComponentMapper.selectList( + new LambdaQueryWrapperX() + .in(OrderComponentDO::getOrderId, reqVO.getOrderIds()) + .eq(OrderComponentDO::getPid, OrderComponentDO.PARENT_ID_ROOT) + .likeIfPresent(OrderComponentDO::getName, reqVO.getName()) + ); + + if (CollUtil.isEmpty(topComponents)) { + return Collections.emptyList(); + } + + List names = topComponents.stream() + .map(OrderComponentDO::getName) + .distinct() + .toList(); + + List topIds = topComponents.stream() + .map(OrderComponentDO::getId) + .toList(); + + // 查询不加工配置 + CommonResult> configResult = + assemblyConfigApi.getNotProcessAssemblyConfigByPartNameList(names); + + if (configResult.isError()) { + throw new ServiceException(ORDER_COMPONENT_ASSEMBLY_CONFIG_QUERY_ERROR); + } + + Set configSet = configResult.getData().stream() + .map(dto -> dto.getComponentName() + "#" + dto.getStructureHash()) + .collect(Collectors.toSet()); + + // 查询整棵树 + List allNodes = orderComponentMapper.selectList( + new LambdaQueryWrapperX() + .in(OrderComponentDO::getTopId, topIds) + .in(OrderComponentDO::getOrderId, reqVO.getOrderIds()) + .select(OrderComponentDO::getId, + OrderComponentDO::getPid, + OrderComponentDO::getName, + OrderComponentDO::getProcessStatus) + ); + + List tree = buildTree(allNodes); + + List result = new ArrayList<>(); + + for (OrderComponentTreeCompareVO root : tree) { + + ProcessStats stats = analyzeTree(root); + + TopComponentState state = new TopComponentState(); + + state.node = root; + state.rootProcessed = ObjectUtil.equals(root.getProcessStatus(), OrderComponentProcessStatusEnum.PROCESSED.getStatus()); + state.allUnprocessed = stats.allUnprocessed; + state.anyChildProcessed = stats.anyChildProcessed; + state.notProcessConfig = + configSet.contains(root.getName() + "#" + root.getStructureHash()); + + result.add(state); + } + + return result; + } + + private ProcessStats analyzeTree(OrderComponentTreeCompareVO node) { + + ProcessStats stats = new ProcessStats(); + + // 默认认为全未加工 + stats.allUnprocessed = + ObjectUtil.equals(OrderComponentProcessStatusEnum.UNPROCESSED.getStatus(), + node.getProcessStatus()); + + stats.anyChildProcessed = false; + + List children = node.getChildren(); + + if (CollUtil.isNotEmpty(children)) { + + for (OrderComponentTreeCompareVO child : children) { + + ProcessStats childStats = analyzeTree(child); + + // 只要有一个不是未加工 + if (!childStats.allUnprocessed) { + stats.allUnprocessed = false; + } + + // 子树存在已加工 + if (childStats.anyChildProcessed || + ObjectUtil.equals(OrderComponentProcessStatusEnum.PROCESSED.getStatus(), + child.getProcessStatus())) { + + stats.anyChildProcessed = true; + } + } + } + + return stats; + } + + private boolean matchAnyStatus(TopComponentState state, + Set statusSet) { + + if (CollUtil.isEmpty(statusSet)) { + return true; + } + + for (OrderComponentProcessStatusEnum status : statusSet) { + + switch (status) { + + case PROCESSED: + if (state.rootProcessed) { + return true; + } + break; + + case UNPROCESSED: + if (!state.rootProcessed + && state.allUnprocessed + && !state.notProcessConfig) { + return true; + } + break; + + case PART_PROCESSED: + if (!state.rootProcessed + && state.anyChildProcessed + && !state.notProcessConfig) { + return true; + } + break; + + case NOT_PROCESS: + if (state.notProcessConfig) { + return true; + } + break; + } + } + + return false; + } + + class ProcessStats { + + boolean allUnprocessed = true; + + boolean anyChildProcessed = false; + } + + class TopComponentState { + + OrderComponentTreeCompareVO node; + + boolean rootProcessed; + + boolean allUnprocessed; + + boolean anyChildProcessed; + + boolean notProcessConfig; + } } \ No newline at end of file diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode.properties index 7d361441a..b84db99da 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode.properties @@ -32,4 +32,5 @@ order.component.restore.parent.is.deleted=该部件上级已被删除,请先 order.component.no.need.to.restore=该部件未删除,无需恢复 order.component.processed.repeat=该部件已加工勿重复操作,请刷新列表后检查状态 order.component.assembly.config.query.error=装配设置查询失败,请检查服务状态 -order.component.not.process=当前部件无需加工,请刷新列表后检查状态 \ No newline at end of file +order.component.not.process=当前部件无需加工,请刷新列表后检查状态 +order.component.restore.repeat=该部件已恢复勿重复操作,请刷新列表后检查状态 \ No newline at end of file diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties index 422bff8a3..69126ae0d 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties @@ -32,4 +32,5 @@ order.component.restore.parent.is.deleted=該部件上級已被删除,請先 order.component.no.need.to.restore=該部件未删除,無需恢復 order.component.processed.repeat=該部件已加工勿重複操作,請重繪清單後檢查狀態 order.component.assembly.config.query.error=裝配設定査詢失敗,請檢查服務狀態 -order.component.not.process=當前部件無需加工,請重繪清單後檢查狀態 \ No newline at end of file +order.component.not.process=當前部件無需加工,請重繪清單後檢查狀態 +order.component.restore.repeat=該部件已恢復勿重複操作,請重繪清單後檢查狀態 \ No newline at end of file diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties index cd509a956..dd6da7a99 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties @@ -32,4 +32,5 @@ order.component.restore.parent.is.deleted=The upper level of this component has order.component.no.need.to.restore=This component has not been deleted and does not need to be restored order.component.processed.repeat=This component has been processed and should not be operated repeatedly. Please refresh the list and check the status order.component.assembly.config.query.error=Assembly settings query failed, please check service status -order.component.not.process=The current component does not require processing. Please refresh the list and check the status \ No newline at end of file +order.component.not.process=The current component does not require processing. Please refresh the list and check the status +order.component.restore.repeat=The component has been restored. Do not repeat the operation. Please refresh the list and check the status \ No newline at end of file diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApi.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApi.java index d9fb6e508..0cd59470b 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApi.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApi.java @@ -26,4 +26,8 @@ public interface AssemblyConfigApi { @PostMapping("/getOrgAssemblySettingByComponentNames") @Operation(summary = "根据部件名称列表查询组织下对应的装配设置") CommonResult> getAssemblyConfigByPartNameList(@RequestBody List componentNameList); + + @PostMapping("/getOrgNotProcessAssemblySettingByComponentNames") + @Operation(summary = "根据部件名称列表查询组织下对应不加工的装配设置") + CommonResult> getNotProcessAssemblyConfigByPartNameList(@RequestBody List componentNameList); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApiImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApiImpl.java index 85f0a398c..f2f55a40b 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApiImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/api/assemblyconfig/AssemblyConfigApiImpl.java @@ -28,4 +28,10 @@ public class AssemblyConfigApiImpl implements AssemblyConfigApi { List assemblyConfigByComponentNameList = assemblyConfigService.getAssemblyConfigByComponentNameList(componentNameList); return CommonResult.success(BeanUtil.copyToList(assemblyConfigByComponentNameList, AssemblyConfigRespDTO.class)); } + + @Override + public CommonResult> getNotProcessAssemblyConfigByPartNameList(List componentNameList) { + List assemblyConfigByComponentNameList = assemblyConfigService.getNotProcessAssemblyConfigByComponentNameList(componentNameList); + return CommonResult.success(BeanUtil.copyToList(assemblyConfigByComponentNameList, AssemblyConfigRespDTO.class)); + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/assemblyconfig/vo/AssemblyConfigSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/assemblyconfig/vo/AssemblyConfigSaveReqVO.java index c62aabc57..39b427c9f 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/assemblyconfig/vo/AssemblyConfigSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/assemblyconfig/vo/AssemblyConfigSaveReqVO.java @@ -19,5 +19,5 @@ public class AssemblyConfigSaveReqVO { @Schema(description = "装备设置树形结构", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "{assembly.config.save.structure.config.notNull}") - private AssemblyConfigSaveStructureVO config; + private AssemblyConfigStructureVO config; } \ No newline at end of file diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/assemblyconfig/AssemblyConfigDO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/assemblyconfig/AssemblyConfigDO.java index ef5b1e3e2..5424b643a 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/assemblyconfig/AssemblyConfigDO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/assemblyconfig/AssemblyConfigDO.java @@ -65,4 +65,9 @@ public class AssemblyConfigDO extends BaseDO { * 状态 */ private Integer status; + + /** + * 不加工 + */ + private Boolean notProcess; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigService.java index 55798fd7c..4418ce35d 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigService.java @@ -71,4 +71,12 @@ public interface AssemblyConfigService { * @return */ List getAssemblyConfigByComponentNameList(List componentNameList); + + /** + * 根据部件名称获取组织不加工的装配设置 + * + * @param componentNameList + * @return + */ + List getNotProcessAssemblyConfigByComponentNameList(List componentNameList); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigServiceImpl.java index 395b97e12..d05edc094 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/assemblyconfig/AssemblyConfigServiceImpl.java @@ -21,7 +21,6 @@ import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConf import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigListRespVO; import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigRespVO; import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigSaveReqVO; -import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigSaveStructureVO; import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigStructureVO; import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigDO; import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigNameSeqDO; @@ -422,8 +421,7 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService { AssemblyConfigDO assemblyConfigDO = getById(reqVO.getId(), organId); - AssemblyConfigSaveStructureVO config = reqVO.getConfig(); - AssemblyConfigStructureVO structureVO = BeanUtil.toBean(config, AssemblyConfigStructureVO.class); + AssemblyConfigStructureVO structureVO = reqVO.getConfig(); String newTopName = structureVO.getName(); // 2、如果顶级的名称发生改变,需要校验是否重复,并且同步给name String needChangeName = null; @@ -440,7 +438,8 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService { } // 3、更新hash和json - computeHashRecursively(structureVO); + // 生成hash并检查是不是全部不加工 + boolean allNotProcess = computeHashAndCheckProcess(structureVO); String structureHash = structureVO.getStructureHash(); assemblyConfigMapper.update(new LambdaUpdateWrapperX() @@ -450,10 +449,43 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService { .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus()) .setIfPresent(AssemblyConfigDO::getComponentName, needChangeName) .set(AssemblyConfigDO::getStructureHash, structureHash) - .set(AssemblyConfigDO::getStructureJson, JsonUtils.zipString(JsonUtils.toJsonString(config))) + .set(AssemblyConfigDO::getStructureJson, JsonUtils.zipString(JsonUtils.toJsonString(structureVO))) + .set(AssemblyConfigDO::getNotProcess, allNotProcess) ); } + /** + * 生成结构hash、逐级检查是否全部不加工 + * + * @param node + * @return true 表示全部不加工 + */ + private boolean computeHashAndCheckProcess(AssemblyConfigStructureVO node) { + + // 当前节点是否不加工 + boolean hasProcessFalse = !node.isProcess(); + + List children = node.getChildren(); + if (children != null && !children.isEmpty()) { + + // 1. 按 name 排序保证 hash 稳定 + children.sort(Comparator.comparing(AssemblyConfigStructureVO::getName)); + + // 2. 递归子节点 + for (AssemblyConfigStructureVO child : children) { + if (computeHashAndCheckProcess(child)) { + hasProcessFalse = true; + } + } + } + + // 3. 生成结构字符串并 hash + String structureStr = buildStructureString(node); + node.setStructureHash(DigestUtil.sha256Hex(structureStr)); + + return hasProcessFalse; + } + @Override public List getAssemblyConfigByComponentNameList(List componentNameList) { Long organId = SecurityFrameworkUtils.getUserOrganId(); @@ -468,4 +500,20 @@ public class AssemblyConfigServiceImpl implements AssemblyConfigService { return BeanUtil.copyToList(assemblyConfigDOS, AssemblyConfigRespVO.class); } + + @Override + public List getNotProcessAssemblyConfigByComponentNameList(List componentNameList) { + Long organId = SecurityFrameworkUtils.getUserOrganId(); + + List assemblyConfigDOS = assemblyConfigMapper.selectList(new LambdaQueryWrapper() + .eq(AssemblyConfigDO::getOrganId, organId) + .in(AssemblyConfigDO::getComponentName, componentNameList) + .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus()) + .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus()) + .eq(AssemblyConfigDO::getNotProcess, true) + .select(AssemblyConfigDO::getComponentName, AssemblyConfigDO::getStructureHash, AssemblyConfigDO::getStructureJson) + ); + + return BeanUtil.copyToList(assemblyConfigDOS, AssemblyConfigRespVO.class); + } } \ No newline at end of file