From 07b313d9e220c814ebd689ab1b970b73cedd19e8 Mon Sep 17 00:00:00 2001 From: 10001392 <1055202292@qq.com> Date: Tue, 26 Nov 2024 13:45:30 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=B7=A5=E8=89=BA=E8=B7=AF=E7=BA=BF?= =?UTF-8?q?=E3=80=91=E8=8E=B7=E5=8F=96PBOM=E6=89=80=E6=9C=89=E5=AD=90?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../technology/api/ProcessRouteTaskApi.java | 2 +- .../technology/job/PBomFormalTreeTask.java | 176 ++++++++ .../mapper/master/ProcessRouteTaskMapper.java | 12 + .../pojo/vo/BomNewPbomParentVO.java | 381 ++++++++++++++++++ .../service/ProcessRouteTaskService.java | 252 ++++++++++-- .../mapper/master/MaterialMainMapper.xml | 2 +- .../mapper/master/ProcessRouteTaskMapper.xml | 35 ++ 7 files changed, 814 insertions(+), 46 deletions(-) create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/job/PBomFormalTreeTask.java create mode 100644 nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomNewPbomParentVO.java diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/api/ProcessRouteTaskApi.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/api/ProcessRouteTaskApi.java index 06b8711e..a95aa02b 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/api/ProcessRouteTaskApi.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/api/ProcessRouteTaskApi.java @@ -65,7 +65,7 @@ public class ProcessRouteTaskApi extends BaseApi { * @param query * @return */ - @GetMapping("getPBomAllTree") + @PostMapping("getPBomAllTree") public ResultVO> getPBomAllTree(@RequestBody ProcessRouteTaskQuery query) { return ResultVO.success(processRouteTaskService.getPBomAllTree(query)); } diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/job/PBomFormalTreeTask.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/job/PBomFormalTreeTask.java new file mode 100644 index 00000000..6f759c68 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/job/PBomFormalTreeTask.java @@ -0,0 +1,176 @@ +package com.nflg.product.technology.job; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.nflg.product.technology.pojo.vo.BomNewPbomParentVO; +import com.nflg.product.technology.service.ProcessRouteTaskService; +import lombok.Getter; +import lombok.Setter; + +import java.util.*; +import java.util.concurrent.RecursiveTask; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + + +public class PBomFormalTreeTask extends RecursiveTask> { + + private List bomDetail; + + @Getter + @Setter + private int levelNum=2; + private AtomicInteger inCountNum; + private String facCode; + List result = new ArrayList<>(); + + + + + public PBomFormalTreeTask(List inBomDetail, + int inCountLevel , + AtomicInteger inCountNum, + String facCode) { + this. bomDetail = inBomDetail; + this.levelNum=inCountLevel; + this.inCountNum = inCountNum; + this.facCode=facCode; + + + } + + + + + + + /** + * 处理BOM明细中未选择Bom版本的明细;使用最新版 + */ + public void handlerChildBomVersionDetail() { + if (CollUtil.isEmpty(bomDetail)) { + return; + } + + + for (BomNewPbomParentVO vo : + bomDetail) { + vo.setLevelNum(levelNum); + vo.setOrderNumber(inCountNum.getAndIncrement() + ""); + } + + + + + List materialNos = bomDetail.stream().filter(u -> StrUtil.isNotBlank(u.getMaterialNo())).map(BomNewPbomParentVO::getMaterialNo).collect(Collectors.toList()); + + if (CollUtil.isNotEmpty(materialNos)) { + + List childBomlist = SpringUtil.getBean(ProcessRouteTaskService.class).selectPBomParentBatch(4, facCode, materialNos); + Map parentMap = childBomlist.stream() + .collect(Collectors.groupingBy( + BomNewPbomParentVO::getMaterialNo, + Collectors.collectingAndThen( + Collectors.maxBy(Comparator.comparing(BomNewPbomParentVO::getCurrentVersion)), + Optional::get + ) + )); + + for (BomNewPbomParentVO detailVO : bomDetail) { + if (parentMap.containsKey(detailVO.getMaterialNo())) { + BomNewPbomParentVO ebomParentEntity = parentMap.get(detailVO.getMaterialNo()); + detailVO.setBomRowId(ebomParentEntity.getRowId()); + detailVO.setSourceRowId(ebomParentEntity.getSourceRowId()); + detailVO.setCurrentVersion(ebomParentEntity.getCurrentVersion()); + + + detailVO.setStatus(ebomParentEntity.getStatus()); + detailVO.setEditStatus(ebomParentEntity.getEditStatus()); + detailVO.setDeviseName(ebomParentEntity.getDeviseName()); + detailVO.setDeviseUserCode(ebomParentEntity.getDeviseUserCode()); + + detailVO.setCreatedTime(ebomParentEntity.getCreatedTime()); + + detailVO.setExpireEndTime(ebomParentEntity.getExpireEndTime()); + // detailVO.setCreatedBy(ebomParentEntity.getCreatedBy()); + + detailVO.setDeptName(ebomParentEntity.getDeptName()); + detailVO.setDeptRowId(ebomParentEntity.getDeptRowId()); + detailVO.setChangeDesc(ebomParentEntity.getChangeDesc()); + detailVO.setOrderNo(ebomParentEntity.getOrderNo()); + + detailVO.setBomExist(ebomParentEntity.getBomExist()); + detailVO.setShouldBomExist(ebomParentEntity.getShouldBomExist()); + detailVO.setVirtualPackageIs(ebomParentEntity.getVirtualPackageIs()); + } else { + detailVO.setBomRowId(0L); + BomNewPbomParentVO parent = SpringUtil.getBean(ProcessRouteTaskService.class).selectPBomParentByRowId(detailVO.getParentRowId()); + if(Objects.nonNull(parent)) { + detailVO.setDeviseUserCode(parent.getDeviseUserCode()); + detailVO.setDeviseName(parent.getDeviseName()); + // detailVO.setCreatedBy(parent.getCreatedBy()); + detailVO.setDeptName(parent.getDeptName()); + detailVO.setDeptRowId(parent.getDeptRowId()); + detailVO.setStatus(parent.getStatus()); + detailVO.setEditStatus(parent.getEditStatus()); + detailVO.setVirtualPackageIs(parent.getVirtualPackageIs()); + detailVO.setExpireEndTime(parent.getExpireEndTime()); + detailVO.setCurrentVersion(parent.getCurrentVersion()); + } + + +// if (MaterialshouldBomExistUtil.checkShouldBomExist(detailVO)) { +// detailVO.setCurrentVersion(OriginalConstant.NO_BOM_VERSION); +// } else { +// detailVO.setCurrentVersion(OriginalConstant.DEFAULT_BOM_VERSION); +// } + + + } + + + } + + + } + + } + + /** + * 递归调用零部件BOM + * + * @return + */ + @Override + protected List compute() { + + handlerChildBomVersionDetail(); + // 最新 BOM 版本 + result.addAll(bomDetail); + + if (CollUtil.isNotEmpty(bomDetail)) { + levelNumAdd(); + List childBowIds = bomDetail.stream().map(BomNewPbomParentVO::getBomRowId).filter(bomRowId -> bomRowId > 0).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(childBowIds)) { + List bom = SpringUtil.getBean(ProcessRouteTaskService.class).selectPBomChildByParentRowId(childBowIds); + + PBomFormalTreeTask task = new PBomFormalTreeTask(bom, levelNum, inCountNum, facCode); + task.fork(); + bomDetail.addAll(task.join()); + return bomDetail; + } + + } + return result; + + + + + } + + public synchronized void levelNumAdd(){ + levelNum++; + } +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/ProcessRouteTaskMapper.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/ProcessRouteTaskMapper.java index 822891dc..2da67712 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/ProcessRouteTaskMapper.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/mapper/master/ProcessRouteTaskMapper.java @@ -5,9 +5,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.nflg.product.technology.pojo.entity.ProcessRouteTaskEntity; import com.nflg.product.technology.pojo.query.ProcessRouteTaskQuery; +import com.nflg.product.technology.pojo.vo.BomNewPbomParentVO; import com.nflg.product.technology.pojo.vo.ProcessRouteTaskVO; import org.apache.ibatis.annotations.Param; +import java.util.List; + /** *

* 工艺路线-任务清单(抬头) Mapper 接口 @@ -20,4 +23,13 @@ public interface ProcessRouteTaskMapper extends BaseMapper selectPageByCondition(Page page, @Param("query") ProcessRouteTaskQuery query); + BomNewPbomParentVO selectPBomParent(@Param("materialNo") String materialNo, @Param("status") Integer status, @Param("factory") String factory); + + List selectPBomParentChild(@Param("parentRowId") Long parentRowId); + + List selectPBomParentBatch(@Param("status") Integer status, @Param("factory") String factory, @Param("materialNoList") List materialNoList); + + BomNewPbomParentVO selectPBomParentByRowId(@Param("rowId") Long rowId); + + List selectPBomChildByParentRowId(@Param("parentRowIdList") List parentRowIdList); } diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomNewPbomParentVO.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomNewPbomParentVO.java new file mode 100644 index 00000000..f46680b8 --- /dev/null +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/pojo/vo/BomNewPbomParentVO.java @@ -0,0 +1,381 @@ +package com.nflg.product.technology.pojo.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * t_bom_new_pbom_parent + * @author makejava + * @since 2024-01-01 10:39:59 + */ +@Data +@Accessors(chain = true) +@ApiModel(value = "com-nflg-product-bomnew-pojo-new-vo-BomNewPbomParentEntityVO") +public class BomNewPbomParentVO extends BaseMaterialVO implements Serializable { + + /** + * 主键行ID-雪花 + */ + @ApiModelProperty(value = "主键行ID-雪花") + private Long rowId = 0L; + + + @ApiModelProperty("Bom行ID") + private Long bomRowId = 0L; + + + @ApiModelProperty("父级行id") + private Long parentRowId = 0L; + /** + * 批号-来自plm-临时 + */ + @ApiModelProperty(value = "批号-来自plm-临时") + private String batchNo; + + + /** + * 工厂编码 + */ + @ApiModelProperty(value = "工厂编码") + private String facCode; + + + /** + * 排序号 + */ + @ApiModelProperty(value = "排序号") + private String orderNumber; + + + /** + * 单重 + */ + @ApiModelProperty(value = "单重") + private BigDecimal unitWeight; + + /** + * 总重 + */ + @ApiModelProperty(value = "总重") + private BigDecimal totalWeight; + + /** + * 版本号 + */ + @ApiModelProperty(value = "版本号") + private String currentVersion; + + /** + * 数量 + */ + @ApiModelProperty(value = "数量") + private BigDecimal num; + + public BigDecimal getNum() { + return num==null?null:num.stripTrailingZeros(); + } + + /** + * 是否跟节点 0-否 1-是 + */ + @ApiModelProperty(value = "是否跟节点 0-否 1-是") + private Integer rootIs; + + /** + * 是否应该有BOM 0-否 1-是 + */ + @ApiModelProperty(value = "是否应该有BOM 0-否 1-是") + private Integer shouldBomExist; + + /** + * 超级物料 0-否 1-是 + */ + @ApiModelProperty(value = "超级物料 0-否 1-是") + private Integer superMaterialStatus; + + /** + * 是否有BOM: 0-否 1-是 + */ + @ApiModelProperty(value = "是否有BOM: 0-否 1-是") + private Integer bomExist = 0; + + /** + * 是否最新版:0-否 1-是 + */ + @ApiModelProperty(value = "是否最新版:0-否 1-是") + private Integer lastVersionIs; + + /** + * 1=待处理、2=暂存 3=已处理 + */ + @ApiModelProperty(value = "1=待处理、2=暂存 3=已处理") + private Integer editStatus; + + /** + * BOM状态:1=待发布 2=待分配工厂 3=已分配工厂 4=已发布 + */ + @ApiModelProperty(value = "BOM状态:1=待发布 2-借用件 4=已发布 8=待分配工厂 16=已分配工厂") + private Integer status; + + /** + * 是否用户跟节点 0-否 1-是 + */ + @ApiModelProperty(value = "是否用户跟节点 0-否 1-是") + private Integer userRootIs; + + /** + * 是否虚拟包 0-否 1-是 + */ + @ApiModelProperty(value = "是否虚拟包 0-否 1-是") + private Integer virtualPackageIs; + + /** + * 来源行ID(EBOM中的行ID) + */ + @ApiModelProperty(value = "来源行ID(EBOM中的行ID)") + private Long sourceRowId; + + /** + * 设计人员编码 + */ + @ApiModelProperty(value = "设计人员编码") + private String deviseUserCode; + + /** + * 设计人员名称 + */ + @ApiModelProperty(value = "设计人员名称") + private String deviseName; + + /** + * 工艺人员编码 + */ + @ApiModelProperty(value = "工艺人员编码") + private String technologyUserCode; + + + /** + * 工艺人员名称 + */ + @ApiModelProperty(value = "工艺人员名称") + private String technologyUserName; + + /** + * 创建人编码 + */ + @ApiModelProperty(value = "创建人编码") + private String createdBy; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private LocalDateTime createdTime; + + /** + * 创建人员所属岗位 0-设计人员 1-工艺人员 2-其他 + */ + @ApiModelProperty(value = "创建人员所属岗位 0-设计人员 1-工艺人员 2-其他") + private Integer createdJob; + + /** + * 发布时间 + */ + @ApiModelProperty(value = "发布时间") + private LocalDateTime releaseTime; + + /** + * 发布人 + */ + @ApiModelProperty(value = "发布人") + private String releaseUserName; + + /** + * 版本过期时间=下个版本的创建时间 + */ + @ApiModelProperty(value = "版本过期时间=下个版本的创建时间") + private LocalDateTime expireEndTime; + + public LocalDateTime getExpireEndTime() { + return expireEndTime == null ? LocalDateTime.of(9999, 12, 31, 23, 59, 59) : expireEndTime; + } + + /** + * 备注 + */ + @ApiModelProperty(value = "备注") + private String remark; + + /** + * 设计维护部门名称 + */ + @ApiModelProperty(value = "设计维护部门名称") + private String deptName; + + /** + * bom树的高度 + */ + @ApiModelProperty(value = "bom树的高度") + private Integer levelNum; + + /** + * 升版说明 + */ + @ApiModelProperty(value = "升版说明") + private String changeDesc; + + /** + * 通知单号 + */ + @ApiModelProperty(value = "通知单号") + private String noticeNums; + + /** + * 订单号 + */ + @ApiModelProperty(value = "订单号") + private String orderNo; + + /** + * 修改时间 + */ + @ApiModelProperty(value = "修改时间") + private LocalDateTime modifyTime; + + @ApiModelProperty("生产工厂") + private String productionFactoryCode; + + @ApiModelProperty("生产工厂设置方式 0-默认 1-规则匹配 2-手工") + private Integer productionFactoryCodeInputType; + + @ApiModelProperty("是否虚拟件 0-否 1-是") + private Integer virtualPartIs; + + @ApiModelProperty("虚拟件类型 0-非虚拟包 1-发货包 2-制作包 4-直发包 8-发货前装配包") + private Integer virtualPartType; + + @ApiModelProperty("层级数字") + private BigDecimal levelNumber; + + @ApiModelProperty(value = "导入SAP状态") + private Integer sapState; + + /** + * SAP排序字符串 + */ + @ApiModelProperty(value = "SAP排序字符串") + private String sapOrderNum = "0040"; + + /** + * 创建人所属部门rowId + */ + @ApiModelProperty(value = "创建人所属部门rowId") + private Long deptRowId; + + private String levelNo; + + + // @ApiModelProperty("物料一级分类编码") + // private String relCategoryCode; + + + @ApiModelProperty("子级") + List childNodes; + + @ApiModelProperty("所有父级的rowId") + private Set allParentRowIds = new HashSet<>(); + + @ApiModelProperty(value = "来源状态:1-EBOM导入、2-PBOM创建、3-E->P修改") + private Integer sourceStatus; + + @ApiModelProperty(value = "来源状态:1-EBOM导入、2-PBOM创建、3-E->P修改") + private String sourceStatusName; + + //PBOM发起变更时,漏掉该值 by luohj 240828 + @ApiModelProperty("来源行-父项物料编码") + private String sourceParentMaterialNo; + + @ApiModelProperty("原始物料编码") + private String originalMaterialNo; + + + @ApiModelProperty("原始数量") + private BigDecimal originalNum; + + public BigDecimal getOriginalNum() { + return originalNum==null?null:originalNum.stripTrailingZeros(); + } + + @ApiModelProperty("原始项目类别") + private String originalProjectType; + + @ApiModelProperty("生产仓储地点") + private String lgpro; + +// private String materialNoAndProjectType; +// +// private String materialNoAndNumAndProjectType; +// +// public String getMaterialNoAndProjectType() { +// return MyStrUtil.joinStr(getMaterialNo(),getProjectType()); +// } +// +// public String getMaterialNoAndNumAndProjectType() { +// return MyStrUtil.joinStr(StrUtil.isNotBlank(getOriginalMaterialNo())?getOriginalMaterialNo(): getMaterialNo(),Objects.nonNull(getOriginalNum())?getOriginalNum(): getNum(),StrUtil.isNotBlank(getOriginalProjectType())?getOriginalProjectType(): getProjectType()); +// } +// +// private String materialNoAndNum; +// +// public String getMaterialNoAndNum() { +// return MyStrUtil.joinStr(StrUtil.isNotBlank(getOriginalMaterialNo())?getOriginalMaterialNo(): getMaterialNo(),Objects.nonNull(getOriginalNum())?getOriginalNum(): getNum()); +// } + + //发布PBOM 时 ,对比Pbom已发布版是否一致,一致则不转PBOM正式,直接删除PBOM 草稿数据 + private Integer delIs=0; + + @ApiModelProperty(value = "ebom-发布后的版本") + private String ebomVersion; + + + @ApiModelProperty(value = "异常状态:1=正常、2=冻结/完全弃用异常、3=递归异常、4=数据不完整异常、5=超级物料异常、6=重复异常 7=物料主数据不存在 8=项目类别为空 9=项目赋值异常(父级物料的项目类型为Q时,子级中不能存在项目类别为Q的物料) 10=项目赋值异常(当父级物料的项目类型为F时,子级中不能存在项目类型为F的物料) 11=未填写变更原因和技术通知单 12=数量需要用户确认 13=项目类型需要用户确认") + private Integer exceptionStatus=1; + + + @ApiModelProperty(value = "是否锁定(1020),锁定时ebom转直接跳过") + private Integer lock1020State; + + + @ApiModelProperty(value = "锁定人") + private String lockUserName; + + @ApiModelProperty(value = "锁定时间") + private LocalDateTime lockTime; + + private static final long serialVersionUID = 1L; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + BomNewPbomParentVO that = (BomNewPbomParentVO) o; + return rowId.equals(that.rowId); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), rowId); + } + + +} diff --git a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/ProcessRouteTaskService.java b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/ProcessRouteTaskService.java index 8fc63d2d..a94af7e7 100644 --- a/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/ProcessRouteTaskService.java +++ b/nflg_project_dev/nflg-technology/src/main/java/com/nflg/product/technology/service/ProcessRouteTaskService.java @@ -1,7 +1,9 @@ package com.nflg.product.technology.service; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.TypeReference; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; @@ -11,6 +13,7 @@ import com.nflg.product.base.core.exception.NflgBusinessException; import com.nflg.product.base.core.vo.PageVO; import com.nflg.product.technology.constant.HandleStateEnum; import com.nflg.product.technology.constant.SapStateEnum; +import com.nflg.product.technology.job.PBomFormalTreeTask; import com.nflg.product.technology.mapper.master.ProcessRouteTaskAssemblyMapper; import com.nflg.product.technology.mapper.master.ProcessRouteTaskMapper; import com.nflg.product.technology.mapper.master.ProcessRouteTaskProcessesMapper; @@ -18,17 +21,17 @@ import com.nflg.product.technology.pojo.entity.ProcessRouteTaskAssemblyEntity; import com.nflg.product.technology.pojo.entity.ProcessRouteTaskEntity; import com.nflg.product.technology.pojo.entity.ProcessRouteTaskProcessesEntity; import com.nflg.product.technology.pojo.query.ProcessRouteTaskQuery; -import com.nflg.product.technology.pojo.vo.BomNewPBomVO; -import com.nflg.product.technology.pojo.vo.ProcessRouteTaskAssemblyVO; -import com.nflg.product.technology.pojo.vo.ProcessRouteTaskProcessesVO; -import com.nflg.product.technology.pojo.vo.ProcessRouteTaskVO; +import com.nflg.product.technology.pojo.vo.*; import nflg.product.common.constant.STATE; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; /** *

@@ -89,6 +92,20 @@ public class ProcessRouteTaskService extends ServiceImpl existsTaskList = this.lambdaQuery().eq(ProcessRouteTaskEntity::getFactory, processRouteTaskVO.getFactory()) + .eq(ProcessRouteTaskEntity::getMaterialNo, processRouteTaskVO.getMaterialNo()) + .list(); + if (CollUtil.isNotEmpty(existsTaskList)) { + // 已存在 + throw new NflgBusinessException(STATE.ParamErr, "工厂" + processRouteTaskVO.getFactory() + "物料号" + processRouteTaskVO.getMaterialNo() + "工艺路线已存在"); + } + ProcessRouteTaskEntity taskEntity = Convert.convert(ProcessRouteTaskEntity.class, processRouteTaskVO); // 新增 if (ObjectUtil.isEmpty(processRouteTaskVO.getRowId())) { @@ -138,46 +155,193 @@ public class ProcessRouteTaskService extends ServiceImpl nodesList=new ArrayList<>(); -// for ( BomNewPbomParentVO parentFormal: -// listParent ) { -// -// -// List bomList = bomDetailAndParent(parentFormal); -// -// if(CollUtil.isEmpty(bomList)){ -// continue; + if (ObjectUtil.isEmpty(query.getFactory())) { + return null; + } + // 最新版 + BomNewPbomParentVO rootParent = processRouteTaskMapper.selectPBomParent(query.getMaterialNo(), 4, query.getFactory()); + if (ObjectUtil.isEmpty(rootParent)) { + throw new NflgBusinessException(STATE.ParamErr, "物料号" + query.getMaterialNo() + "尚未发布PBOM"); + } + rootParent.setBomRowId(rootParent.getRowId()); + List nodesList = new ArrayList<>(); +// BomNewPBomVO rootNode = Convert.convert(BomNewPBomVO.class, rootParent); +// nodesList.add(rootNode); + + List bomList = bomDetailAndParent(rootParent); + materialMainService.intiMaterialInfo(bomList, ""); + List convertBomList = Convert.convert(new TypeReference>() { + }, bomList); + + sumLevel(convertBomList); + //转化为树结构 + List nodeList = showDataStyle(convertBomList, rootParent.getRowId()); + for (BomNewPBomVO vo: nodeList) { + vo.setBomVersion(rootParent.getCurrentVersion()); + // vo.setDeviseName(parentFormal.getDeviseName()); + // vo.setCreatedTime(parentFormal.getCreatedTime()); + // vo.setExpireEndTime(parentFormal.getReleaseTime()); + // 10、40、50、60、70大类以及200201小类这些不需要BOM的物料,版本号显示B00 by 10002327 241101 +// if(MaterialshouldBomExistUtil.checkNoNeedBom(vo) || Objects.equals("T",vo.getProjectType())){ +// vo.setCurrentVersion(OriginalConstant.NO_NEED_BOM); // } -// initMaterialInfo(bomList); -// List convertBomList = Convert.convert(new TypeReference>() { -// }, bomList); -// -// -// sumLevel(convertBomList); -// //转化为树结构 -// List nodeList = showDataStyle(convertBomList, parentFormal.getRowId()); -// -// -// for (ForwardReportVO vo : -// nodeList) { -// vo.setBomVersion(parentFormal.getCurrentVersion()); -// // vo.setDeviseName(parentFormal.getDeviseName()); -// // vo.setCreatedTime(parentFormal.getCreatedTime()); -// // vo.setExpireEndTime(parentFormal.getReleaseTime()); -// // 10、40、50、60、70大类以及200201小类这些不需要BOM的物料,版本号显示B00 by 10002327 241101 -// if(MaterialshouldBomExistUtil.checkNoNeedBom(vo) || Objects.equals("T",vo.getProjectType())){ -// vo.setCurrentVersion(OriginalConstant.NO_NEED_BOM); -// } + } + nodesList.addAll(nodeList); + return nodesList; + } + + /** + * 可参考 https://www.doc88.com/p-9002887925771.html?s=rel&id=7 + * 二叉树的前序遍历 + * @param bomList + * @param parentRowId + * @return + */ + protected List listToList(List bomList, Long parentRowId) { + + Map> listMap = bomList.stream().filter(item ->Objects.nonNull(item.getParentRowId())&&item.getParentRowId()>0).collect(Collectors.groupingBy(BomNewPBomVO::getParentRowId)); + //第一层数据 + List parentChildList = bomList.stream().filter(item -> Objects.equals(parentRowId, item.getRowId())).collect(Collectors.toList()); + //无bom数据直接展示 + List rootList = parentChildList.stream().filter(item -> Objects.isNull(item.getBomRowId()) || item.getBomRowId().longValue() == 0).collect(Collectors.toList()); + //第一层数据有bom + List moreBomList = parentChildList.stream().filter(item -> item.getBomRowId() != null && item.getBomRowId().longValue() > 0).collect(Collectors.toList()); + //采用前序遍历 前->左->右 输出 + Deque majorStack = new ArrayDeque(); + + //迭代第一层有Bom 前序遍历 + if (CollectionUtil.isNotEmpty(moreBomList)) { + AtomicInteger noCode = new AtomicInteger(); + //noCode.set(1); + for (BomNewPBomVO item : moreBomList) { + + majorStack.push(item); + + while (!majorStack.isEmpty()) { + + BomNewPBomVO pop = majorStack.poll(); + if (pop != null) { + pop.setOrderNumber(noCode.incrementAndGet() + ""); + rootList.add(pop); + List childNode = listMap.get(pop.getBomRowId()); + if (CollectionUtil.isNotEmpty(childNode)) { + for (int size = childNode.size() - 1, index = 0; size >= index; size--) { + majorStack.push(childNode.get(size)); + } + } + } + } + + } + } + + return rootList; + + } + + protected List showDataStyle(List bomList, Long parentRowId) { + List rootList = null; + //列表 + rootList = listToList(bomList, parentRowId); + Collections.sort(rootList, (option0, option1) -> Integer.parseInt(option0.getOrderNumber()) - Integer.parseInt(option1.getOrderNumber())); + return rootList; + } + + /** + * 各层汇总 + * 1.按层分组 和 parent分组 + * 2.下层数量=下层数量*上层数量 + * + * @param bomList + */ + protected void sumLevel(List bomList) { + if(CollUtil.isEmpty(bomList)){ + return; + } + //分层统计,避免使用遍历树统计 + Map> listMap = bomList.stream().collect(Collectors.groupingBy(BomNewPBomVO::getLevelNum)); + +// List>> sortList=new ArrayList<>(listMap.entrySet()); +// Collections.sort(sortList, new Comparator>>() { +// @Override +// public int compare(Map.Entry> o1, Map.Entry> o2) { +// return o1.getKey().compareTo(o2.getKey()); // } -// nodesList.addAll(nodeList); -// } -// -// ReportBomVO reportBomVO =buildReportBomVo(forwardReportVO,nodesList,query.getDataType()); -// reportBomVO.setBomNum(listParent.size()); -// return reportBomVO; +// }); + + //排序 层级升序 + Map> sortListMap= CollectionUtil.sort(listMap, new Comparator() { + @Override + public int compare( Integer o1, Integer o2) { + return o1.compareTo(o2 ); + } + }); + sortListMap.putAll(listMap); + + + + Map> bomParentMap = bomList.stream().filter(u->Objects.nonNull(u.getParentRowId())&&u.getParentRowId()>0).collect(Collectors.groupingBy(BomNewPBomVO::getParentRowId)); + sortListMap.forEach((key, value) -> { + value.forEach(parent -> { + List dataList = bomParentMap.get(parent.getBomRowId()); + if (CollectionUtil.isNotEmpty(dataList) ) { + if(Objects.nonNull(parent.getNum())) { + for (BomNewPBomVO data : + dataList) { + if(Objects.nonNull(data.getNum())) { + data.setNum(parent.getNum().multiply(data.getNum())); + } + + + } + } + } + + }); + }); + + } + + List bomDetailAndParent(BomNewPbomParentVO parentBomRow) { + List bomDetails =new ArrayList<>(); + List childs = bomDetailList(parentBomRow.getRowId(),parentBomRow.getFacCode()); + parentBomRow.setLevelNum(1); + parentBomRow.setOrderNumber("1"); + bomDetails.add(parentBomRow); + if(CollUtil.isNotEmpty(childs)){ + bomDetails.addAll(childs); + } + return bomDetails; + } + + /** + * bomid下所有数据 + * + * @return + */ + List bomDetailList(Long bomRowId,String facCode) { + List childList = processRouteTaskMapper.selectPBomParentChild(bomRowId); + if(CollUtil.isNotEmpty(childList)) { + int inCountLevel=2; + AtomicInteger inCountNum=new AtomicInteger(2); + PBomFormalTreeTask task = new PBomFormalTreeTask(childList,inCountLevel,inCountNum,facCode); + ForkJoinPool pool = new ForkJoinPool(); + ForkJoinTask> submit = pool.submit(task); + List bomList = submit.join(); + return bomList; + } return null; } + + public List selectPBomParentBatch(Integer status, String factory, List materialNoList) { + return processRouteTaskMapper.selectPBomParentBatch(status, factory, materialNoList); + } + + public BomNewPbomParentVO selectPBomParentByRowId(Long rowId) { + return processRouteTaskMapper.selectPBomParentByRowId(rowId); + } + + public List selectPBomChildByParentRowId(List parentRowIdList) { + return processRouteTaskMapper.selectPBomChildByParentRowId(parentRowIdList); + } } diff --git a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml index 6a12a312..989ddfa5 100644 --- a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml +++ b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/MaterialMainMapper.xml @@ -1,6 +1,6 @@ - + diff --git a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/ProcessRouteTaskMapper.xml b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/ProcessRouteTaskMapper.xml index 6c1cb3dc..64398f36 100644 --- a/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/ProcessRouteTaskMapper.xml +++ b/nflg_project_dev/nflg-technology/src/main/resources/mapper/master/ProcessRouteTaskMapper.xml @@ -53,4 +53,39 @@ + + + + + + + + +