From 70dd9d0211e3686545b0f70e343109e17b8329be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Wed, 8 May 2024 15:35:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20ebom=E4=BB=8Eexcel=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/master/BomNewEbomChildMapper.java | 2 + .../product/bomnew/pojo/dto/EbomExcelDTO.java | 73 +++++ .../bomnew/service/EBomImportService.java | 286 ++++++++++++++++++ .../mapper/master/BomNewEbomChildMapper.xml | 12 + 4 files changed, 373 insertions(+) create mode 100644 nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/dto/EbomExcelDTO.java create mode 100644 nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/mapper/master/BomNewEbomChildMapper.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/mapper/master/BomNewEbomChildMapper.java index a723b7d6..fca209eb 100644 --- a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/mapper/master/BomNewEbomChildMapper.java +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/mapper/master/BomNewEbomChildMapper.java @@ -24,4 +24,6 @@ public interface BomNewEbomChildMapper extends BaseMapper void updateEBomMaterialUse(); List getChildMaxExceptionState(@Param("bomRowIds") List bomRowIds); + + Integer shouldSetRootIs(String materialNo); } diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/dto/EbomExcelDTO.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/dto/EbomExcelDTO.java new file mode 100644 index 00000000..35eb6479 --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/pojo/dto/EbomExcelDTO.java @@ -0,0 +1,73 @@ +package com.nflg.product.bomnew.pojo.dto; + +import lombok.Data; +import org.ttzero.excel.annotation.ExcelColumn; + +import java.math.BigDecimal; + +/** + * @author 曹鹏飞 + * @date 2024/5/8 09:07:23 + */ +@Data +public class EbomExcelDTO extends BaseImportExcelDTO { + + /** + * 父级物料编号 + */ + @ExcelColumn("抬头物料") + private String parentMaterialNo; + + /** + * 父级物料描述 + */ + @ExcelColumn("物料描述") + private String parentMaterialDesc; + + /** + * 项目类别 + */ + @ExcelColumn("项目类别") + private String projectType; + + /** + * 物料编号 + */ + @ExcelColumn("项目物料") + private String materialNo; + + /** + * 物料描述 + */ + @ExcelColumn("项目物料描述") + private String materialDesc; + + /** + * 数量 + */ + @ExcelColumn("数量") + private BigDecimal num; + + /** + * 物料单位 + */ + @ExcelColumn("单位") + private String unit; + + /** + * 排序顺序 + */ + @ExcelColumn("排序顺序") + private String orderNum; + + /** + * 备注 + */ + @ExcelColumn("备注") + private String remark; + + /** + * 图号 + */ + private String drawingNo; +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java new file mode 100644 index 00000000..7d56ecaf --- /dev/null +++ b/nflg_project_dev/nflg-bom-new/src/main/java/com/nflg/product/bomnew/service/EBomImportService.java @@ -0,0 +1,286 @@ +package com.nflg.product.bomnew.service; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.nflg.product.base.core.conmon.util.SessionUtil; +import com.nflg.product.bomnew.constant.*; +import com.nflg.product.bomnew.pojo.dto.BaseImportExcelDTO; +import com.nflg.product.bomnew.pojo.dto.EbomExcelDTO; +import com.nflg.product.bomnew.pojo.entity.BomNewEbomChildEntity; +import com.nflg.product.bomnew.pojo.entity.BomNewEbomParentEntity; +import com.nflg.product.bomnew.pojo.vo.BaseMaterialVO; +import com.nflg.product.bomnew.pojo.vo.OperationErrorMsgVO; +import com.nflg.product.bomnew.util.BomUtil; +import com.nflg.product.bomnew.util.EecExcelUtil; +import com.nflg.product.bomnew.util.StringUtil; +import com.nflg.product.bomnew.util.VUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author 曹鹏飞 + * @date 2024/5/8 09:02:12 + */ +@Service +@Slf4j +public class EBomImportService { + + public static final ThreadLocal rowNum = new ThreadLocal<>(); + + public static final ThreadLocal> excelContextTL = new ThreadLocal<>(); + + @Resource + private MaterialMainService materialMainService; + + @Resource + private UserRoleService userRoleService; + + @Resource + private BomNewEbomParentService bomNewEbomParentService; + + @Resource + private BomNewEbomChildService bomNewEbomChildService; + + public List importBom(MultipartFile file) throws IOException { + try { + rowNum.set(1); + excelContextTL.set(new ArrayList<>()); + EecExcelUtil.handlerExcel(file.getInputStream(), EbomExcelDTO.class, this::handlerExcelRow); + + List datas = excelContextTL.get(); + + List errorMsg = checkExcel(datas); + if (!errorMsg.isEmpty()) { + return errorMsg; + } + + Pair, List> pcs = convertToBom(datas); + VUtils.isTure(pcs.getLeft().stream().filter(p -> p.getRootIs() == 1).count() > 1) + .throwMessage("文件中存在多个根节点"); + //VUtils.isTure(checkInconsistentData(pcs.getLeft().get(0), pcs.getLeft(), pcs.getRight())) + // .throwMessage("导入的数据已存在,请勿重复导入"); + + //save(pcs.getLeft(), pcs.getRight()); + + return Collections.emptyList(); + } finally { + excelContextTL.remove(); + } + } + + private void handlerExcelRow(EbomExcelDTO dQbomExcelVO) { + rowNum.set(rowNum.get() + 1); + log.debug("ebom导入excel,第{}行,处理前:{}", rowNum.get(), JSON.toJSONString(dQbomExcelVO)); + + dQbomExcelVO.setRowNum(rowNum.get()); + + excelContextTL.get().add(dQbomExcelVO); + } + + private List checkExcel(List datas) { + List errorMsg = new ArrayList<>(); + + List numError = datas.stream().filter(u -> StrUtil.isBlank(u.getParentMaterialNo())) + .map(BaseImportExcelDTO::getRowNum) + .collect(Collectors.toList()); + if (!numError.isEmpty()) { + errorMsg.addAll(numError.stream().map(n -> OperationErrorMsgVO.create("第" + n + "行", "抬头物料为空")) + .collect(Collectors.toList()) + ); + } + + numError = datas.stream().filter(u -> StrUtil.isBlank(u.getMaterialNo())) + .map(BaseImportExcelDTO::getRowNum) + .collect(Collectors.toList()); + if (!numError.isEmpty()) { + errorMsg.addAll(numError.stream().map(n -> OperationErrorMsgVO.create("第" + n + "行", "项目物料为空")) + .collect(Collectors.toList()) + ); + } + + numError = datas.stream().filter(u -> Objects.isNull(u.getNum()) || BigDecimal.ZERO.compareTo(u.getNum()) >= 0) + .map(BaseImportExcelDTO::getRowNum) + .collect(Collectors.toList()); + + if (!numError.isEmpty()) { + errorMsg.addAll(numError.stream().map(n -> OperationErrorMsgVO.create("第" + n + "行", "数量不正确")) + .collect(Collectors.toList()) + ); + } + + numError = datas.stream().filter(u -> StringUtil.CountForMysql(u.getRemark()) > 200) + .map(BaseImportExcelDTO::getRowNum) + .collect(Collectors.toList()); + if (!numError.isEmpty()) { + errorMsg.addAll(numError.stream().map(n -> OperationErrorMsgVO.create("第" + n + "行", "备注超出200字")) + .collect(Collectors.toList()) + ); + } + + return errorMsg; + } + + private Pair, List> convertToBom(List datas) { + List parents = new ArrayList<>(); + List children = new ArrayList<>(); + + List materialNos = datas.stream().map(EbomExcelDTO::getMaterialNo).collect(Collectors.toList()); + materialNos.addAll(datas.stream().map(EbomExcelDTO::getParentMaterialNo).collect(Collectors.toList())); + materialNos = materialNos.stream().distinct().collect(Collectors.toList()); + List materialBaseInfos = materialMainService.getMaterialBaseInfo(materialNos); + + BomNewEbomParentEntity parent; + for (EbomExcelDTO data : datas) { + parent = parents.stream().filter(p -> p.getMaterialNo().equals(data.getParentMaterialNo())) + .findFirst() + .orElse(null); + if (Objects.isNull(parent)) { + parents.add(buildRoot(materialBaseInfos, data.getParentMaterialNo(), data.getParentMaterialDesc())); + } + + parent = parents.stream().filter(p -> p.getMaterialNo().equals(data.getMaterialNo())) + .findFirst() + .orElse(null); + if (Objects.isNull(parent)) { + parent = buildParent(materialBaseInfos, data); + children.add(buildChild(materialBaseInfos, parent, data.getProjectType())); + parents.add(parent); + } + } + return Pair.of(parents, children); + } + + private BomNewEbomChildEntity buildChild(List materialBaseInfos, BomNewEbomParentEntity parent, String projectType) { + BomNewEbomChildEntity child = Convert.convert(BomNewEbomChildEntity.class, parent); + parent.setOrderNumber(""); + child.setRowId(IdWorker.getId()); + child.setParentRowId(parent.getRowId()); + child.setProjectType(projectType); + child.setProjectTypeInputType(ProjectTypeInputTypeEnum.MANUAL_INPUT.getValue()); + child.setIdentityNo(child.getParentRowId() + "_" + child.getRowId()); + BaseMaterialVO vo = materialBaseInfos.stream() + .filter(m -> m.getMaterialNo().equals(child.getMaterialNo())) + .findFirst() + .orElse(null); + if (!Objects.isNull(vo)) { + child.setMaterialCategoryCode(vo.getMaterialCategoryCode()); + } + return child; + } + + private BomNewEbomParentEntity buildParent(List materialBaseInfos, EbomExcelDTO data) { + BomNewEbomParentEntity parent = new BomNewEbomParentEntity(); + parent.setRowId(IdWorker.getId()); + + BaseMaterialVO vo = materialBaseInfos.stream() + .filter(m -> m.getMaterialNo().equals(data.getMaterialNo())) + .findFirst() + .orElse(null); + if (!Objects.isNull(vo)) { + parent.setDrawingNo(vo.getDrawingNo()); + parent.setUnitWeight(vo.getMaterialWeight()); + } + + parent.setMaterialNo(data.getMaterialNo()); + parent.setMaterialDesc(data.getMaterialDesc()); + parent.setMaterialTexture(""); + parent.setMaterialUnit(data.getUnit()); + parent.setNum(data.getNum()); + parent.setTotalWeight(BomUtil.calculateTotalWeight(parent.getNum(), parent.getUnitWeight())); + //parent.setCurrentVersion(OriginalConstant.DEFAULT_BOM_VERSION); + parent.setUserRootIs(0); + parent.setRootIs(0); + if (userRoleService.technician()) { + //工艺人员 + parent.setStatus(EBomStatusEnum.CHECKED.getValue()); + parent.setCreatedJob(UserJobEnum.ENGINEER.getValue()); + parent.setAuditUserName(SessionUtil.getUserCode()); + parent.setAuditTime(LocalDateTime.now()); + } else { + //设计人员 + parent.setStatus(EBomStatusEnum.WAIT_CHECK.getValue()); + parent.setCreatedJob(UserJobEnum.DESIGNER.getValue()); + parent.setRootIsForWaitReview(1); + } + parent.setDeviseName(SessionUtil.getRealName()); + parent.setDeviseUserCode(SessionUtil.getUserCode()); + parent.setLastVersionIs(1); + parent.setEditStatus(EbomEditStatusEnum.HANDLER_CREATED.getValue()); + parent.setExceptionStatus(EBomExceptionStatusEnum.INIT.getValue()); + parent.setCreatedBy(SessionUtil.getUserCode()); + parent.setRemark(data.getRemark()); + parent.setOrderNumber(data.getOrderNum()); + parent.setDeptName(SessionUtil.getDepartName()); + parent.setSource(EBomSourceEnum.FROM_EXCE.getValue()); + return parent; + } + + /** + * 构建顶级 + * @param materialBaseInfos 主物料数据 + * @param materialNo 物料编号 + * @param materialDesc 物料描述 + * @return 父级 + */ + private BomNewEbomParentEntity buildRoot(List materialBaseInfos, String materialNo, String materialDesc) { + BomNewEbomParentEntity parent = new BomNewEbomParentEntity(); + parent.setRowId(IdWorker.getId()); + + BaseMaterialVO vo = materialBaseInfos.stream() + .filter(m -> m.getMaterialNo().equals(materialNo)) + .findFirst() + .orElse(null); + if (!Objects.isNull(vo)) { + parent.setDrawingNo(vo.getDrawingNo()); + parent.setUnitWeight(vo.getMaterialWeight()); + } + + parent.setMaterialNo(materialNo); + parent.setMaterialDesc(materialDesc); + parent.setMaterialTexture(""); + parent.setMaterialUnit("PC"); + //parent.setUnitWeight(BigDecimal.ZERO); + parent.setNum(BigDecimal.ONE); + //parent.setTotalWeight(BomUtil.calculateTotalWeight(data.getNum(), data.getUnitWeight())); + //parent.setCurrentVersion(OriginalConstant.DEFAULT_BOM_VERSION); + parent.setUserRootIs(1); + if (userRoleService.technician()) { + //工艺人员 + parent.setStatus(EBomStatusEnum.CHECKED.getValue()); + parent.setCreatedJob(UserJobEnum.ENGINEER.getValue()); + parent.setAuditUserName(SessionUtil.getUserCode()); + parent.setAuditTime(LocalDateTime.now()); + parent.setRootIs(bomNewEbomChildService.getBaseMapper().shouldSetRootIs(materialNo)); + } else { + //设计人员 + parent.setRootIs(1); + parent.setStatus(EBomStatusEnum.WAIT_CHECK.getValue()); + parent.setCreatedJob(UserJobEnum.DESIGNER.getValue()); + parent.setRootIsForWaitReview(1); + } + parent.setDeviseName(SessionUtil.getRealName()); + parent.setDeviseUserCode(SessionUtil.getUserCode()); + parent.setLastVersionIs(1); + parent.setEditStatus(EbomEditStatusEnum.HANDLER_CREATED.getValue()); + parent.setExceptionStatus(EBomExceptionStatusEnum.INIT.getValue()); + parent.setCreatedBy(SessionUtil.getUserCode()); + parent.setRemark(""); + parent.setDeptName(SessionUtil.getDepartName()); + parent.setSource(EBomSourceEnum.FROM_EXCE.getValue()); + return parent; + } +} diff --git a/nflg_project_dev/nflg-bom-new/src/main/resources/mapper/master/BomNewEbomChildMapper.xml b/nflg_project_dev/nflg-bom-new/src/main/resources/mapper/master/BomNewEbomChildMapper.xml index 65e5b549..df5dd0ec 100644 --- a/nflg_project_dev/nflg-bom-new/src/main/resources/mapper/master/BomNewEbomChildMapper.xml +++ b/nflg_project_dev/nflg-bom-new/src/main/resources/mapper/master/BomNewEbomChildMapper.xml @@ -73,4 +73,16 @@ group by parent_row_id + +