mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-15 06:02:06 +08:00
1、订单新增加工状态字段;2、拆单、删除部件、部件加工增加订单加工状态计算能力;
This commit is contained in:
+3
@@ -246,6 +246,9 @@ public class ErrorCodeConstants {
|
||||
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");
|
||||
public static final ErrorCode ORDER_COMPONENT_PROCESS_STATUS_INVALID = new ErrorCode(1_003_010_008, "order.component.process.status.invalid");
|
||||
public static final ErrorCode ORDER_COMPONENT_PROCESSED_CAN_NOT_DELETE = new ErrorCode(1_003_010_009, "order.component.processed.can.not.delete");
|
||||
public static final ErrorCode ORDER_ASSEMBLY_STATUS_UPDATE_CONCURRENCY_ERROR = new ErrorCode(1_003_010_010, "order.assembly.status.update.concurrency.error");
|
||||
|
||||
//=========== 分堆打包 1-003-011-000 ============
|
||||
public static final ErrorCode PARTS_PACK_NUM_NOT_ENOUGH = new ErrorCode(1_003_010_000, "parts.pack.num.not.enough");
|
||||
|
||||
+4
-3
@@ -7,8 +7,8 @@ import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyListComponentPageReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyListComponentFlatReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyListComponentFlatRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.assemblylist.vo.AssemblyOrderRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderPageReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrdersViewCadViewInfoRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.AssemblyComponentChildPrintReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.AssemblyComponentChildPrintRespVO;
|
||||
@@ -56,8 +56,9 @@ public class AssemblyListController {
|
||||
@GetMapping("/order/page")
|
||||
@Operation(summary = "获得装配清单订单分页")
|
||||
@PreAuthorize("@ss.hasPermission('productManager:List')")
|
||||
public CommonResult<PageResult<OrderRespVO>> getMainOrderPage(@Valid OrderPageReqVO pageReqVO) {
|
||||
return success(BeanUtils.toBean(assemblyListService.getMainOrderPage(pageReqVO), OrderRespVO.class));
|
||||
public CommonResult<PageResult<AssemblyOrderRespVO>> getMainOrderPage(@Valid OrderPageReqVO pageReqVO) {
|
||||
return success(BeanUtils.toBean(
|
||||
assemblyListService.getMainOrderPage(pageReqVO), AssemblyOrderRespVO.class));
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
|
||||
+7
@@ -82,6 +82,13 @@ public class OrderDO extends BaseDO {
|
||||
* 订单状态,0空订单1新单2已排单3生产中4生产完成
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 订单装配加工状态:0不加工、1未加工、2已加工、3部分加工。
|
||||
*
|
||||
* <p>订单没有有效部件时保持为空。</p>
|
||||
*/
|
||||
private Integer assemblyProcessStatus;
|
||||
/**
|
||||
* 打包状态:0未打包1打包中2已打包
|
||||
*/
|
||||
|
||||
+29
@@ -5,9 +5,12 @@ import com.cf.imes.module.executor.controller.admin.ordercomponent.vo.OrderDetai
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.OrderComponentDO;
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentPrintDataDO;
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentPrintQuantityDO;
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentProcessStatisticsDO;
|
||||
import com.cf.imes.module.executor.enums.ordercomponent.OrderComponentProcessStatusEnum;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -19,6 +22,32 @@ import java.util.Set;
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderComponentMapper extends BaseMapperX<OrderComponentDO> {
|
||||
/**
|
||||
* 汇总订单下全部未删除部件的加工状态。
|
||||
*
|
||||
* @param organId 组织 ID,用于分片路由和数据隔离
|
||||
* @param orderId 订单 ID
|
||||
* @return 状态聚合结果
|
||||
*/
|
||||
ComponentProcessStatisticsDO selectProcessStatistics(@Param("organId") Long organId,
|
||||
@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 判断待删除子树中是否存在已加工部件。
|
||||
*/
|
||||
default boolean existsProcessedComponent(Long organId, Long orderId,
|
||||
Collection<Long> componentIds) {
|
||||
if (componentIds == null || componentIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return selectCount(new com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getOrganId, organId)
|
||||
.eq(OrderComponentDO::getOrderId, orderId)
|
||||
.in(OrderComponentDO::getId, componentIds)
|
||||
.eq(OrderComponentDO::getDeleted, false)
|
||||
.eq(OrderComponentDO::getProcessStatus,
|
||||
OrderComponentProcessStatusEnum.PROCESSED.getStatus())) > 0;
|
||||
}
|
||||
/**
|
||||
* 查询部件标签打印数据,包括当前部件、直接父级、层级及同树同名数量。
|
||||
*
|
||||
|
||||
+12
-74
@@ -44,6 +44,7 @@ import com.cf.imes.module.system.api.assemblyconfig.dto.AssemblyConfigRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayDeque;
|
||||
@@ -90,6 +91,9 @@ public class AssemblyListServiceImpl implements AssemblyListService {
|
||||
@Resource
|
||||
private OrderItemMapper orderItemMapper;
|
||||
|
||||
@Resource
|
||||
private OrderAssemblyProcessStatusService orderAssemblyProcessStatusService;
|
||||
|
||||
@Override
|
||||
public PageResult<OrderDO> getMainOrderPage(OrderPageReqVO pageReqVO) {
|
||||
pageReqVO.setAssembly(true);
|
||||
@@ -771,12 +775,14 @@ public class AssemblyListServiceImpl implements AssemblyListService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void processComponent(Long id) {
|
||||
// 未加工 -> 加工
|
||||
handleComponentProcessStatus(id, OrderComponentProcessStatusEnum.UNPROCESSED.getStatus(), OrderComponentProcessStatusEnum.PROCESSED.getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void restoreComponent(Long id) {
|
||||
// 加工 -> 未加工
|
||||
handleComponentProcessStatus(id, OrderComponentProcessStatusEnum.PROCESSED.getStatus(), OrderComponentProcessStatusEnum.UNPROCESSED.getStatus());
|
||||
@@ -894,81 +900,13 @@ public class AssemblyListServiceImpl implements AssemblyListService {
|
||||
return;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 5、重新查询整棵树(拿最新状态)
|
||||
// =========================
|
||||
List<OrderComponentDO> topComponentList =
|
||||
orderComponentMapper.selectList(
|
||||
new LambdaQueryWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getTopId, topId)
|
||||
.eq(OrderComponentDO::getDeleted,
|
||||
DeletedCodeEnum.NOT_DELETED.getStatus())
|
||||
.select(
|
||||
OrderComponentDO::getId,
|
||||
OrderComponentDO::getTopId,
|
||||
OrderComponentDO::getLevel,
|
||||
OrderComponentDO::getProcessStatus
|
||||
)
|
||||
);
|
||||
// 完整沿用原有规则重新计算顶级部件状态,不改变顶级节点判定口径。
|
||||
orderAssemblyProcessStatusService.refreshTopComponentProcessStatus(
|
||||
organId, orderId, topId);
|
||||
|
||||
if (CollUtil.isEmpty(topComponentList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 6、统计:
|
||||
// 是否存在已加工子级
|
||||
// =========================
|
||||
boolean hasProcessedChild =
|
||||
topComponentList.stream()
|
||||
// 排除顶级自己
|
||||
.filter(item ->
|
||||
!Objects.equals(
|
||||
item.getId(),
|
||||
topId
|
||||
))
|
||||
.anyMatch(item ->
|
||||
Objects.equals(
|
||||
item.getProcessStatus(),
|
||||
OrderComponentProcessStatusEnum.PROCESSED.getStatus()
|
||||
));
|
||||
|
||||
// =========================
|
||||
// 7、计算顶级 extra 状态
|
||||
// =========================
|
||||
Integer extraProcessStatus = null;
|
||||
|
||||
// 顶级自身未加工
|
||||
boolean topUnProcessed =
|
||||
Objects.equals(
|
||||
topComponentDO.getProcessStatus(),
|
||||
OrderComponentProcessStatusEnum.UNPROCESSED.getStatus()
|
||||
);
|
||||
|
||||
// 只要:
|
||||
// 顶级未加工
|
||||
// 且存在已加工子级
|
||||
// => 部分加工
|
||||
if (topUnProcessed && hasProcessedChild) {
|
||||
|
||||
extraProcessStatus =
|
||||
OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus();
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 8、更新顶级 extra 状态
|
||||
// =========================
|
||||
orderComponentMapper.update(
|
||||
null,
|
||||
new LambdaUpdateWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getId, topId)
|
||||
.eq(OrderComponentDO::getOrderId, orderId)
|
||||
.eq(OrderComponentDO::getOrganId, organId)
|
||||
.eq(OrderComponentDO::getDeleted,
|
||||
DeletedCodeEnum.NOT_DELETED.getStatus())
|
||||
.set(OrderComponentDO::getExtraProcessStatus,
|
||||
extraProcessStatus)
|
||||
);
|
||||
// 订单状态是新增的独立聚合结果,按订单下全部未删除部件重新计算。
|
||||
orderAssemblyProcessStatusService.refreshOrderAssemblyProcessStatus(
|
||||
organId, orderId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.cf.imes.module.executor.service.assemblylist;
|
||||
|
||||
/**
|
||||
* 订单装配加工状态服务。
|
||||
*
|
||||
* <p>顶级部件状态继续沿用原规则;订单状态在此基础上独立聚合。</p>
|
||||
*/
|
||||
public interface OrderAssemblyProcessStatusService {
|
||||
|
||||
/**
|
||||
* 按现有顶级部件规则重新计算 extraProcessStatus。
|
||||
*/
|
||||
void refreshTopComponentProcessStatus(Long organId, Long orderId, Long topId);
|
||||
|
||||
/**
|
||||
* 计算订单下全部未删除部件对应的订单装配加工状态。
|
||||
*/
|
||||
Integer calculateOrderAssemblyProcessStatus(Long organId, Long orderId);
|
||||
|
||||
/**
|
||||
* 计算并通过 orders.version 乐观锁更新订单装配加工状态。
|
||||
*/
|
||||
void refreshOrderAssemblyProcessStatus(Long organId, Long orderId);
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
package com.cf.imes.module.executor.service.assemblylist;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
|
||||
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentProcessStatisticsDO;
|
||||
import com.cf.imes.module.executor.dal.dataobject.ordercomponent.OrderComponentDO;
|
||||
import com.cf.imes.module.executor.dal.mysql.order.OrderMapper;
|
||||
import com.cf.imes.module.executor.dal.mysql.ordercomponent.OrderComponentMapper;
|
||||
import com.cf.imes.module.executor.enums.ordercomponent.OrderComponentProcessStatusEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_ASSEMBLY_STATUS_UPDATE_CONCURRENCY_ERROR;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_PROCESS_STATUS_INVALID;
|
||||
|
||||
/**
|
||||
* 订单装配加工状态服务实现。
|
||||
*/
|
||||
@Service
|
||||
public class OrderAssemblyProcessStatusServiceImpl implements OrderAssemblyProcessStatusService {
|
||||
|
||||
@Resource
|
||||
private OrderComponentMapper orderComponentMapper;
|
||||
|
||||
@Resource
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
@Override
|
||||
public void refreshTopComponentProcessStatus(Long organId, Long orderId, Long topId) {
|
||||
OrderComponentDO topComponent = orderComponentMapper.selectOne(
|
||||
new LambdaQueryWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getId, topId)
|
||||
.eq(OrderComponentDO::getOrderId, orderId)
|
||||
.eq(OrderComponentDO::getOrganId, organId)
|
||||
.eq(OrderComponentDO::getDeleted, false));
|
||||
|
||||
// 删除整个顶级部件时,该顶级节点已不再参与任何状态计算。
|
||||
if (topComponent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<OrderComponentDO> topComponentList = orderComponentMapper.selectList(
|
||||
new LambdaQueryWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getTopId, topId)
|
||||
.eq(OrderComponentDO::getOrderId, orderId)
|
||||
.eq(OrderComponentDO::getOrganId, organId)
|
||||
.eq(OrderComponentDO::getDeleted, false)
|
||||
.select(OrderComponentDO::getId,
|
||||
OrderComponentDO::getProcessStatus));
|
||||
if (CollUtil.isEmpty(topComponentList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 以下判断完整沿用原有顶级部件规则:
|
||||
* 顶级自身未加工,并且任一子级已加工时,顶级才标记为部分加工;
|
||||
* 其他情况清空附加状态,不新增或改变顶级部件业务规则。
|
||||
*/
|
||||
boolean hasProcessedChild = topComponentList.stream()
|
||||
.filter(item -> !Objects.equals(item.getId(), topId))
|
||||
.anyMatch(item -> Objects.equals(item.getProcessStatus(),
|
||||
OrderComponentProcessStatusEnum.PROCESSED.getStatus()));
|
||||
boolean topUnprocessed = Objects.equals(topComponent.getProcessStatus(),
|
||||
OrderComponentProcessStatusEnum.UNPROCESSED.getStatus());
|
||||
Integer extraProcessStatus = topUnprocessed && hasProcessedChild
|
||||
? OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus()
|
||||
: null;
|
||||
|
||||
orderComponentMapper.update(null,
|
||||
new LambdaUpdateWrapperX<OrderComponentDO>()
|
||||
.eq(OrderComponentDO::getId, topId)
|
||||
.eq(OrderComponentDO::getOrderId, orderId)
|
||||
.eq(OrderComponentDO::getOrganId, organId)
|
||||
.eq(OrderComponentDO::getDeleted, false)
|
||||
.set(OrderComponentDO::getExtraProcessStatus, extraProcessStatus));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer calculateOrderAssemblyProcessStatus(Long organId, Long orderId) {
|
||||
ComponentProcessStatisticsDO stats =
|
||||
orderComponentMapper.selectProcessStatistics(organId, orderId);
|
||||
if (stats == null || value(stats.getTotalCount()) == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 状态字段出现空值或非法值时终止事务,不能静默归类为未加工。
|
||||
if (value(stats.getInvalidProcessStatusCount()) > 0
|
||||
|| value(stats.getInvalidExtraProcessStatusCount()) > 0) {
|
||||
throw new ServiceException(ORDER_COMPONENT_PROCESS_STATUS_INVALID);
|
||||
}
|
||||
|
||||
// 部分加工只由顶级部件产生;任一顶级为部分加工,订单即为部分加工。
|
||||
if (value(stats.getPartProcessedCount()) > 0) {
|
||||
return OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus();
|
||||
}
|
||||
|
||||
// 不加工只排除节点自身,不排除该节点下仍需加工的子部件。
|
||||
long processableCount = value(stats.getTotalCount())
|
||||
- value(stats.getNotProcessCount());
|
||||
if (processableCount == 0) {
|
||||
return OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus();
|
||||
}
|
||||
if (value(stats.getProcessedCount()) == 0) {
|
||||
return OrderComponentProcessStatusEnum.UNPROCESSED.getStatus();
|
||||
}
|
||||
if (value(stats.getUnprocessedCount()) == 0) {
|
||||
return OrderComponentProcessStatusEnum.PROCESSED.getStatus();
|
||||
}
|
||||
return OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshOrderAssemblyProcessStatus(Long organId, Long orderId) {
|
||||
OrderDO order = orderMapper.selectOrderOne(orderId, organId);
|
||||
if (order == null) {
|
||||
return;
|
||||
}
|
||||
Integer status = calculateOrderAssemblyProcessStatus(organId, orderId);
|
||||
int version = order.getVersion();
|
||||
int updated = orderMapper.update(null,
|
||||
new LambdaUpdateWrapperX<OrderDO>()
|
||||
.eq(OrderDO::getId, orderId)
|
||||
.eq(OrderDO::getOrganId, organId)
|
||||
.eq(OrderDO::getVersion, version)
|
||||
.set(OrderDO::getAssemblyProcessStatus, status)
|
||||
.set(OrderDO::getVersion, version + 1));
|
||||
if (updated != 1) {
|
||||
throw new ServiceException(ORDER_ASSEMBLY_STATUS_UPDATE_CONCURRENCY_ERROR, orderId);
|
||||
}
|
||||
}
|
||||
|
||||
private long value(Long count) {
|
||||
return count == null ? 0L : count;
|
||||
}
|
||||
}
|
||||
+8
@@ -20,6 +20,14 @@ public interface OrderInfoVersionControlService {
|
||||
*/
|
||||
void updateOrderPlateNumAndArea(OrderDO orderDO, Boolean delete);
|
||||
|
||||
/**
|
||||
* 在同一次订单乐观锁更新中写入板件统计和装配加工状态。
|
||||
*
|
||||
* <p>部件删除、恢复会同时影响两类数据,合并更新可避免使用已经过期的 version。</p>
|
||||
*/
|
||||
void updateOrderPlateNumAreaAndAssemblyStatus(OrderDO orderDO, Boolean delete,
|
||||
Integer assemblyProcessStatus);
|
||||
|
||||
/**
|
||||
* 更新订单柜体板件数量
|
||||
*
|
||||
|
||||
+16
@@ -47,6 +47,18 @@ public class OrderInfoVersionControlServiceImpl implements OrderInfoVersionContr
|
||||
|
||||
@Override
|
||||
public void updateOrderPlateNumAndArea(OrderDO orderDO, Boolean delete) {
|
||||
updateOrderPlateNumAndArea(orderDO, delete, null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrderPlateNumAreaAndAssemblyStatus(OrderDO orderDO, Boolean delete,
|
||||
Integer assemblyProcessStatus) {
|
||||
updateOrderPlateNumAndArea(orderDO, delete, assemblyProcessStatus, true);
|
||||
}
|
||||
|
||||
private void updateOrderPlateNumAndArea(OrderDO orderDO, Boolean delete,
|
||||
Integer assemblyProcessStatus,
|
||||
boolean updateAssemblyProcessStatus) {
|
||||
Long orderId = orderDO.getId();
|
||||
// 重新计算订单数量
|
||||
// 统计每个orders下的板件数量和面积,更新到orders中
|
||||
@@ -63,6 +75,10 @@ public class OrderInfoVersionControlServiceImpl implements OrderInfoVersionContr
|
||||
.set(OrderDO::getArea, orderPlateNumAndAreaDO.getArea())
|
||||
.set(OrderDO::getPlateNum, num)
|
||||
.set(OrderDO::getVersion, version + 1);
|
||||
if (updateAssemblyProcessStatus) {
|
||||
// 删除或恢复部件后,订单装配状态与板件统计使用同一个 version 提交。
|
||||
updateWrapper.set(OrderDO::getAssemblyProcessStatus, assemblyProcessStatus);
|
||||
}
|
||||
int update = orderMapper.update(updateWrapper);
|
||||
if (update == 0) {
|
||||
throw new ServiceException(com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_PLATE_UPDATE_CONCURRENCY_ERROR, orderId);
|
||||
|
||||
+31
-4
@@ -52,6 +52,7 @@ import com.cf.imes.module.executor.dal.mysql.orderItem.OrderItemTempMapper;
|
||||
import com.cf.imes.module.executor.dal.mysql.ordercomponent.OrderComponentMapper;
|
||||
import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper;
|
||||
import com.cf.imes.module.executor.service.manage.pack.PackService;
|
||||
import com.cf.imes.module.executor.service.assemblylist.OrderAssemblyProcessStatusService;
|
||||
import com.cf.imes.module.executor.service.order.OrderInfoVersionControlService;
|
||||
import com.cf.imes.module.executor.service.order.OrderService;
|
||||
import com.cf.imes.module.infra.api.file.FileApi;
|
||||
@@ -82,6 +83,7 @@ import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_BODY_NO
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_DELETE_PLATE_IN_PLAN;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_NOT_EXIST;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_NO_NEED_TO_RESTORE;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_PROCESSED_CAN_NOT_DELETE;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_RESTORE_PARENT_IS_DELETED;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_NOT_EXISTS;
|
||||
|
||||
@@ -129,6 +131,9 @@ public class OrderComponentServiceImpl implements OrderComponentService {
|
||||
@Resource
|
||||
private OrderInfoVersionControlService orderInfoVersionControlService;
|
||||
|
||||
@Resource
|
||||
private OrderAssemblyProcessStatusService orderAssemblyProcessStatusService;
|
||||
|
||||
@Resource
|
||||
private PackService packService;
|
||||
|
||||
@@ -600,6 +605,14 @@ public class OrderComponentServiceImpl implements OrderComponentService {
|
||||
// 整理出所属的下级,整理成id集合
|
||||
Set<Long> deleteIds = getChildrenIds(componentDO, componentOnTop);
|
||||
|
||||
/*
|
||||
* 删除会作用于目标节点的整棵子树。只要其中任一有效部件已经加工,
|
||||
* 就必须拒绝整个删除操作,避免删除已经产生加工进度的业务数据。
|
||||
*/
|
||||
if (orderComponentMapper.existsProcessedComponent(organId, orderId, deleteIds)) {
|
||||
throw new ServiceException(ORDER_COMPONENT_PROCESSED_CAN_NOT_DELETE);
|
||||
}
|
||||
|
||||
// 板件id Set
|
||||
Set<Long> plateIdSet = new HashSet<>();
|
||||
// 需要重新累计数量的order_goods id
|
||||
@@ -668,8 +681,15 @@ public class OrderComponentServiceImpl implements OrderComponentService {
|
||||
if (CollUtil.isNotEmpty(deleteGoodsIds)) {
|
||||
orderInfoVersionControlService.updateOrderGoodsPlateNumAndArea(deleteGoodsIds, true);
|
||||
}
|
||||
// 更新订单的板件数量和面积
|
||||
orderInfoVersionControlService.updateOrderPlateNumAndArea(orderDO, true);
|
||||
// 子树删除后先沿用原规则刷新仍然存在的顶级部件,再聚合订单状态。
|
||||
orderAssemblyProcessStatusService.refreshTopComponentProcessStatus(
|
||||
organId, orderId, componentDO.getTopId());
|
||||
Integer assemblyProcessStatus = orderAssemblyProcessStatusService
|
||||
.calculateOrderAssemblyProcessStatus(organId, orderId);
|
||||
|
||||
// 板件统计和订单装配状态在同一次 version 乐观锁更新中提交。
|
||||
orderInfoVersionControlService.updateOrderPlateNumAreaAndAssemblyStatus(
|
||||
orderDO, true, assemblyProcessStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -825,8 +845,15 @@ public class OrderComponentServiceImpl implements OrderComponentService {
|
||||
if (CollUtil.isNotEmpty(restoreGoodsIds)) {
|
||||
orderInfoVersionControlService.updateOrderGoodsPlateNumAndArea(restoreGoodsIds, false);
|
||||
}
|
||||
// 更新订单
|
||||
orderInfoVersionControlService.updateOrderPlateNumAndArea(orderDO, false);
|
||||
// 子树恢复后先沿用原规则刷新顶级部件,再聚合订单状态。
|
||||
orderAssemblyProcessStatusService.refreshTopComponentProcessStatus(
|
||||
organId, orderId, componentDO.getTopId());
|
||||
Integer assemblyProcessStatus = orderAssemblyProcessStatusService
|
||||
.calculateOrderAssemblyProcessStatus(organId, orderId);
|
||||
|
||||
// 板件统计和订单装配状态在同一次 version 乐观锁更新中提交。
|
||||
orderInfoVersionControlService.updateOrderPlateNumAreaAndAssemblyStatus(
|
||||
orderDO, false, assemblyProcessStatus);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+33
-2
@@ -34,7 +34,19 @@
|
||||
t.root_id
|
||||
|
||||
FROM orders t
|
||||
<if test="reqVO.assembly or reqVO.processStatus != null">
|
||||
<!--
|
||||
装配清单沿用原关联方式,只用于保证订单存在有效顶级部件;
|
||||
加工状态不再通过 order_component 过滤。
|
||||
-->
|
||||
<if test="reqVO.assembly">
|
||||
JOIN order_component assembly_oc
|
||||
ON assembly_oc.organ_id = t.organ_id
|
||||
AND assembly_oc.order_id = t.id
|
||||
AND assembly_oc.deleted = 0
|
||||
AND assembly_oc.pid = 0
|
||||
</if>
|
||||
<!-- 非装配接口继续保留原部件状态关联逻辑。 -->
|
||||
<if test="!reqVO.assembly and reqVO.processStatus != null">
|
||||
JOIN order_component oc
|
||||
ON oc.organ_id = t.organ_id
|
||||
AND oc.order_id = t.id
|
||||
@@ -60,6 +72,11 @@
|
||||
</if>
|
||||
where 1=1
|
||||
|
||||
<!-- 装配加工状态直接过滤订单冗余字段,不再依赖部件状态计算。 -->
|
||||
<if test="reqVO.assembly and reqVO.processStatus != null">
|
||||
AND t.assembly_process_status = #{reqVO.processStatus}
|
||||
</if>
|
||||
|
||||
<if test="reqVO.id != null and reqVO.id != ''">
|
||||
AND CAST(t.id AS CHAR) LIKE CONCAT('%', #{reqVO.id}, '%')
|
||||
</if>
|
||||
@@ -174,7 +191,16 @@
|
||||
SELECT DISTINCT
|
||||
t.id
|
||||
FROM orders t
|
||||
<if test="reqVO.assembly or reqVO.processStatus != null">
|
||||
<!-- 子订单同样只用原关联方式保证存在有效顶级部件。 -->
|
||||
<if test="reqVO.assembly">
|
||||
JOIN order_component assembly_oc
|
||||
ON assembly_oc.organ_id = t.organ_id
|
||||
AND assembly_oc.order_id = t.id
|
||||
AND assembly_oc.deleted = 0
|
||||
AND assembly_oc.pid = 0
|
||||
</if>
|
||||
<!-- 非装配接口继续保留原部件状态关联逻辑。 -->
|
||||
<if test="!reqVO.assembly and reqVO.processStatus != null">
|
||||
JOIN order_component oc
|
||||
ON oc.organ_id = t.organ_id
|
||||
AND oc.order_id = t.id
|
||||
@@ -208,6 +234,11 @@
|
||||
#{parentId}
|
||||
</foreach>
|
||||
|
||||
<!-- 子订单同样按自身的订单装配状态过滤。 -->
|
||||
<if test="reqVO.assembly and reqVO.processStatus != null">
|
||||
AND t.assembly_process_status = #{reqVO.processStatus}
|
||||
</if>
|
||||
|
||||
<if test="reqVO.id != null and reqVO.id != ''">
|
||||
AND CAST(t.id AS CHAR) LIKE CONCAT('%', #{reqVO.id}, '%')
|
||||
</if>
|
||||
|
||||
+30
@@ -1,6 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.cf.imes.module.executor.dal.mysql.ordercomponent.OrderComponentMapper">
|
||||
|
||||
<!--
|
||||
订单装配状态使用单行聚合结果,避免部件状态变化时加载整棵树。
|
||||
extra_process_status = 0 只排除当前节点,不会排除该节点的子级。
|
||||
-->
|
||||
<select id="selectProcessStatistics"
|
||||
resultType="com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentProcessStatisticsDO">
|
||||
SELECT COUNT(*) AS totalCount,
|
||||
COALESCE(SUM(CASE
|
||||
WHEN process_status IS NULL OR process_status NOT IN (1, 2)
|
||||
THEN 1 ELSE 0 END), 0) AS invalidProcessStatusCount,
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NOT NULL
|
||||
AND extra_process_status NOT IN (0, 3)
|
||||
THEN 1 ELSE 0 END), 0) AS invalidExtraProcessStatusCount,
|
||||
COALESCE(SUM(CASE WHEN extra_process_status = 0 THEN 1 ELSE 0 END), 0)
|
||||
AS notProcessCount,
|
||||
COALESCE(SUM(CASE WHEN extra_process_status = 3 THEN 1 ELSE 0 END), 0)
|
||||
AS partProcessedCount,
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NULL AND process_status = 1
|
||||
THEN 1 ELSE 0 END), 0) AS unprocessedCount,
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NULL AND process_status = 2
|
||||
THEN 1 ELSE 0 END), 0) AS processedCount
|
||||
FROM order_component
|
||||
WHERE organ_id = #{organId}
|
||||
AND order_id = #{orderId}
|
||||
AND deleted = 0
|
||||
</select>
|
||||
<select id="selectComponentPrintData"
|
||||
resultType="com.cf.imes.module.executor.dal.dataobject.ordercomponent.ComponentPrintDataDO">
|
||||
SELECT oc.order_id AS orderId,
|
||||
|
||||
+3
@@ -150,6 +150,9 @@ order.component.processed.repeat=該部件已加工勿重複操作,請重繪
|
||||
order.component.assembly.config.query.error=裝配設定査詢失敗,請檢查服務狀態
|
||||
order.component.not.process=當前部件無需加工,請重繪清單後檢查狀態
|
||||
order.component.restore.repeat=該部件已恢復勿重複操作,請重繪清單後檢查狀態
|
||||
order.component.process.status.invalid=部件加工狀態異常,請檢查資料後重試
|
||||
order.component.processed.can.not.delete=已加工部件不能刪除,請先恢復為未加工狀態
|
||||
order.assembly.status.update.concurrency.error=訂單裝配狀態已發生變化,請重新整理後重試,訂單號:{0}
|
||||
|
||||
heap.split.task.not.exist=分堆任務不存在
|
||||
heap.split.task.name.exist=分堆任務名已存在,請重新命名
|
||||
|
||||
+3
@@ -150,6 +150,9 @@ order.component.processed.repeat=This component has been processed and should no
|
||||
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
|
||||
order.component.restore.repeat=The component has been restored. Do not repeat the operation. Please refresh the list and check the status
|
||||
order.component.process.status.invalid=The component processing status is invalid. Check the data and try again
|
||||
order.component.processed.can.not.delete=Processed components cannot be deleted. Restore them to unprocessed first
|
||||
order.assembly.status.update.concurrency.error=The order assembly status has changed. Refresh and try again. Order ID: {0}
|
||||
|
||||
heap.split.task.not.exist=The heap split task does not exist
|
||||
heap.split.task.name.exist=The task name for heap splitting already exists, please rename it
|
||||
|
||||
+3
@@ -150,6 +150,9 @@ order.component.processed.repeat=该部件已加工勿重复操作,请刷新
|
||||
order.component.assembly.config.query.error=装配设置查询失败,请检查服务状态
|
||||
order.component.not.process=当前部件无需加工,请刷新列表后检查状态
|
||||
order.component.restore.repeat=该部件已恢复勿重复操作,请刷新列表后检查状态
|
||||
order.component.process.status.invalid=部件加工状态异常,请检查数据后重试
|
||||
order.component.processed.can.not.delete=已加工部件不能删除,请先恢复为未加工状态
|
||||
order.assembly.status.update.concurrency.error=订单装配状态已发生变化,请刷新后重试,订单号:{0}
|
||||
|
||||
heap.split.task.not.exist=分堆任务不存在
|
||||
heap.split.task.name.exist=分堆任务名已存在,请重新命名
|
||||
|
||||
+7
@@ -93,6 +93,13 @@ public class OrderDO extends BaseDO {
|
||||
* 订单状态,0空订单1新单2已排单3生产中4生产完成
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 订单装配加工状态:0不加工、1未加工、2已加工、3部分加工。
|
||||
*
|
||||
* <p>订单没有有效部件时保持为空。</p>
|
||||
*/
|
||||
private Integer assemblyProcessStatus;
|
||||
/**
|
||||
* 打包状态:0未打包1打包中2已打包
|
||||
*/
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@ import java.util.Arrays;
|
||||
public enum OrderComponentProcessStatusEnum implements IntArrayValuable {
|
||||
NOT_PROCESS(0),
|
||||
UNPROCESSED(1),
|
||||
PROCESSED(2);
|
||||
PROCESSED(2),
|
||||
PART_PROCESSED(3);
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(OrderComponentProcessStatusEnum::getStatus).toArray();
|
||||
|
||||
|
||||
+66
-1
@@ -88,6 +88,7 @@ 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.executor.enums.ErrorCodeConstants.ORDER_COMPONENT_PROCESS_STATUS_INVALID;
|
||||
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;
|
||||
@@ -3119,23 +3120,87 @@ public class ProducingOrderImportFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单的板件总数
|
||||
* 更新订单板件统计和装配加工状态。
|
||||
*
|
||||
* <p>组件生产单允许向已有订单重复导入,因此装配状态必须查询数据库中的
|
||||
* 全部未删除部件,不能只计算本次导入缓存中的部件。</p>
|
||||
*/
|
||||
private void updateOrderPlateNum() {
|
||||
int version = orderDO.getVersion();
|
||||
Long orderId = orderDO.getId();
|
||||
Integer assemblyProcessStatus = calculateOrderAssemblyProcessStatus();
|
||||
int updated = orderMapper.update(new LambdaUpdateWrapper<OrderDO>()
|
||||
.eq(OrderDO::getId, orderId)
|
||||
.eq(OrderDO::getOrganId, organId)
|
||||
.eq(OrderDO::getVersion, version)
|
||||
.set(OrderDO::getPlateNum, currentPlateNum)
|
||||
.set(OrderDO::getArea, currentPlateArea)
|
||||
.set(OrderDO::getAssemblyProcessStatus, assemblyProcessStatus)
|
||||
.set(OrderDO::getVersion, version + 1));
|
||||
if (updated == 0) {
|
||||
throw new ServiceException(ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORDER_UPDATE_CONCURRENCY_ERROR, orderId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单下全部未删除部件计算订单装配加工状态。
|
||||
*
|
||||
* <p>不加工状态只排除节点自身,不排除该节点的子树;出现空值或非法状态时
|
||||
* 直接终止导入事务,避免将未知数据归类为未加工。</p>
|
||||
*/
|
||||
private Integer calculateOrderAssemblyProcessStatus() {
|
||||
String sql = """
|
||||
SELECT COUNT(*),
|
||||
COALESCE(SUM(CASE
|
||||
WHEN process_status IS NULL OR process_status NOT IN (1, 2)
|
||||
THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NOT NULL
|
||||
AND extra_process_status NOT IN (0, 3)
|
||||
THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN extra_process_status = 0 THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE WHEN extra_process_status = 3 THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NULL AND process_status = 1
|
||||
THEN 1 ELSE 0 END), 0),
|
||||
COALESCE(SUM(CASE
|
||||
WHEN extra_process_status IS NULL AND process_status = 2
|
||||
THEN 1 ELSE 0 END), 0)
|
||||
FROM order_component
|
||||
WHERE organ_id = ?
|
||||
AND order_id = ?
|
||||
AND deleted = 0
|
||||
""";
|
||||
|
||||
long[] stats = jdbcTemplate.queryForObject(sql, (rs, rowNum) -> new long[]{
|
||||
rs.getLong(1), rs.getLong(2), rs.getLong(3), rs.getLong(4),
|
||||
rs.getLong(5), rs.getLong(6), rs.getLong(7)
|
||||
}, organId, orderId);
|
||||
if (stats == null || stats[0] == 0) {
|
||||
return null;
|
||||
}
|
||||
if (stats[1] > 0 || stats[2] > 0) {
|
||||
throw new ServiceException(ORDER_COMPONENT_PROCESS_STATUS_INVALID);
|
||||
}
|
||||
|
||||
// 任一顶级部件为部分加工,订单直接为部分加工。
|
||||
if (stats[4] > 0) {
|
||||
return OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus();
|
||||
}
|
||||
|
||||
long processableCount = stats[0] - stats[3];
|
||||
if (processableCount == 0) {
|
||||
return OrderComponentProcessStatusEnum.NOT_PROCESS.getStatus();
|
||||
}
|
||||
if (stats[6] == 0) {
|
||||
return OrderComponentProcessStatusEnum.UNPROCESSED.getStatus();
|
||||
}
|
||||
if (stats[5] == 0) {
|
||||
return OrderComponentProcessStatusEnum.PROCESSED.getStatus();
|
||||
}
|
||||
return OrderComponentProcessStatusEnum.PART_PROCESSED.getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增order_goods/更新已有order_goods的板件总数
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user