yangys
2025-09-18 79e81a02076cdd1e828eb06029cd51eb37522f42
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java
@@ -1,22 +1,23 @@
package org.springblade.mdm.program.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.vo.MachineVO;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.mapper.NcNodeMapper;
import org.springblade.mdm.program.vo.NcNodeProgramQueryVO;
import org.springblade.mdm.program.vo.NcNodeProgramVO;
import org.springblade.mdm.program.vo.NcNodeVO;
import org.springblade.mdm.program.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
 * 程序节点
@@ -28,6 +29,7 @@
@AllArgsConstructor
public class NcNodeService extends BizServiceImpl<NcNodeMapper, NcNode> {
   private final MachineService machineService;
   public void saveNcCode(NcNodeVO vo) {
      NcNode ncNode = new NcNode();
@@ -74,7 +76,7 @@
    * @return
    */
   public List<NcNodeVO> lazyList(Long parentId) {
// 判断点击搜索但是没有查询条件的情况
      // 判断点击搜索但是没有查询条件的情况
      if (Func.isEmpty(parentId)) {
         parentId = 0L;
      }
@@ -93,5 +95,382 @@
      return this.getBaseMapper().getLastProgramNode(name);
   }
   /**
    * 首页树查询
    * @param queryVO
    * @return
    */
   public List<NcNodeVO> searchList(NcNodeOldQueryVO queryVO) {
      //1.根据关进字和节点类型查询初始列表,查询的原始列表,需要hasChild字段,所以使用mapper.xml
      List<NcNodeVO> oriList = this.getBaseMapper().searchList(queryVO);
      if ("10".equals(queryVO.getNodeType())) {
         //搜索的根级别,直接返回
         return oriList;
      }
      List<NcNodeVO> allVos = new ArrayList<NcNodeVO>();//已经加入过的节点,用于去重
      List<NcNodeVO> rootVos = new ArrayList<NcNodeVO>();
      for(NcNodeVO vo : oriList){
         allVos.add(vo);
         //上级各级的节点
         List<NcNodeVO> parents = this.getBaseMapper().searchListInIds(Func.toLongList(vo.getParentIds()));
         for(NcNodeVO pvo : parents){
            if(pvo.getParentId() == 0L){
               rootVos.add(pvo);
            }
            allVos.add(pvo);
         }
      }
      for(NcNodeVO root : rootVos){
         addNodeChildren(root, allVos);
      }
      return rootVos;
   }
   /**
    * 首页搜索 新的
    * @param queryVO 查询参数
    * @return
    */
   public List<NcNodeVO> searchList2(NcNodeQueryVO queryVO) {
      //1.根据零组件号和创建时间查询初始列表,查询的原始列表,需要hasChild字段,所以使用mapper.xml
      if(queryVO.getCreateTimeEnd()!=null){
         queryVO.setCreateTimeEnd(queryVO.getCreateTimeEnd().plusDays(1));
      }
      List<NcNodeVO> oriList = this.getBaseMapper().searchList2(queryVO);
      List<NcNodeVO> allVos = new ArrayList<>();//已经加入过的节点,用于去重
      List<NcNodeVO> rootVos = new ArrayList<>();
      for(NcNodeVO vo : oriList){
         allVos.add(vo);
         //上级各级的节点
         List<NcNodeVO> parents = this.getBaseMapper().searchListInIds(Func.toLongList(vo.getParentIds()));
         for(NcNodeVO pvo : parents){
            if(pvo.getParentId() == 0L && !rootVos.contains(pvo)){
               rootVos.add(pvo);
            }
            if(!allVos.contains(pvo)){
               allVos.add(pvo);
            }
         }
      }
      for(NcNodeVO root : rootVos){
         addNodeChildren(root, allVos);
      }
      return rootVos;
   }
   void addNodeChildren(NcNodeVO node, List<NcNodeVO> allNodes) {
      for(NcNodeVO vo : allNodes){
         if(Objects.equals(vo.getParentId(), node.getId())){
            node.addChildren(vo);
         }
      }
      if(node.getChildren()!=null && !node.getChildren().isEmpty()){
         for(NcNodeVO child : node.getChildren()){
            addNodeChildren(child, allNodes);
         }
      }
   }
   /**
    * 获取“程序包名”试切的最新版本
    * @param name 节点名称
    * @return 最新版本程序报名节点
    */
   public NcNode getLastEditionTryingProgramPackage(String name){
      //.or(NcNode::getIsCured,0)
      List<NcNode> pkgList = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getName, name).and(i->{
            i.eq(NcNode::getIsCured, 0).or().isNull(NcNode::getIsCured);
         }).likeRight(NcNode::getParentIds,"0,1,")
         .eq(NcNode::getIsLastEdition,1).orderByDesc(NcNode::getCreateTime).list();//.eq(NcNode::getProcessEdition,processEdition)
      if(pkgList.isEmpty()){
         return null;
      }else{
         return pkgList.get(0);
      }
   }
   /**
    * 根据父节点和名称,查询文件界节点列表
    * @param name 节点/文件名称
    * @param parentId 父节点id
    */
    public NcNode getLastEditionProgramFile(String name,Long parentId) {
      List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_FILE)
         .eq(NcNode::getName, name).eq(NcNode::getParentId,parentId)
         .eq(NcNode::getIsLastEdition,1).list();
      if(nodes.isEmpty()){
         return null;
      }else {
         return nodes.get(0);
      }
   }
   /**
    * 获取试切节点node的历史列表(零组件号,工序号,工序版本,机床组)
    * @param pkgNode node
    * @return 历史列表,报错节点本身
    */
    public List<NcNode> getTryNodeHistory(NcNode pkgNode) {
      return this.lambdaQuery().eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
         .eq(NcNode::getProcessNo,pkgNode.getProcessNo())
         .eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
         .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode())
         .likeLeft(NcNode::getParentIds,"0,1,")
         .list();//.ne(NcNode::getId,pkgNode.getId())
      /*
      return this.lambdaQuery().eq(NcNode::getParentId,pkgNode.getParentId())
         .eq(NcNode::getName,pkgNode.getName()).list();//.ne(NcNode::getId,pkgNode.getId())
       */
    }
   /**
    * 计算历史序号,根据零组件号,工序号,工序版次,机床组查询,查询道则使用该历史编号,查询不到使用新生成的
    */
   public long calculateHistorySerial(NcNode pkgNode) {
      NcNode node = this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE).eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
         .eq(NcNode::getProcessNo,pkgNode.getProcessNo()).eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
         .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode()).last("limit 1").one();
      if(node != null && node.getHisSerial()!=null){
         return node.getHisSerial();
      }else{
         //以往没有,生成一个新的
         return System.currentTimeMillis();//使用当前毫秒数
      }
   }
   public int calculateVersionNumber(NcNode pkgNode) {
      NcNode node = this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE).eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
         .eq(NcNode::getProcessNo,pkgNode.getProcessNo()).eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
         .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode()).last("limit 1").one();
      if(node != null && node.getVersionNumber()!=null){
         return node.getVersionNumber()+1;
      }else{
         //以往没有,生成一个新的
         return 1;
      }
   }
   /**
    * 生成程序包名/程序名称
    * @param drawingNo 零组件号
    * @param processNo 工序版次
    * @return 程序包名/程序名称
    */
   public static String genProgramName(String drawingNo,String processNo,String processEdition){
      return drawingNo+"-"+processNo+"-"+processEdition;
   }
   /**
    * 获取最新版本的 已固化节点
    * @param programPkgName
    * @return
    */
   public NcNode getLastEditionCuredProgramPackage(String programPkgName) {
      List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getName, programPkgName).likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
         //.eq(NcNode::getProcessEdition, processEdition)
         .eq(NcNode::getIsLastEdition,1).list();
      if(nodes.isEmpty()){
         return null;
      }else {
         return nodes.get(0);
      }
   }
   /**
    * 获取最新版本的 已固化节点
    * @param programPkgName 程序包名
    * @param machineCode 机床编号
    * @return
    */
   public NcNode getCuredProgramPackage(String programPkgName,String processEdition,String machineCode) {
      Machine machine = machineService.getByCode(machineCode);
      List<Machine> sameGroupMachines = machineService.lambdaQuery().eq(Machine::getMachineGroupCode,machine.getMachineGroupCode()).list();
      List<String> machineCodesInGroup = sameGroupMachines.stream().map(Machine::getCode).toList();
      List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getName, programPkgName)
         .eq(NcNode::getProcessEdition,processEdition)
         .likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
         .in(!machineCodesInGroup.isEmpty(),NcNode::getMachineCode,machineCodesInGroup)
         .eq(NcNode::getIsLastEdition,1).list();
      if(nodes.isEmpty()){
         return null;
      }else {
         return nodes.get(0);
      }
   }
   /**
    * 获取最新的固化程序,不用工序版次匹配
    * @param drawingNo
    * @param processNo
    * @param machineCode
    * @return
    */
   public NcNode getLastCuredProgramWithoutProcessEdition(String drawingNo, String processNo, String machineCode) {
      Machine machine = machineService.getByCode(machineCode);
      List<Machine> sameGroupMachines = machineService.lambdaQuery().eq(Machine::getMachineGroupCode,machine.getMachineGroupCode()).list();
      List<String> machineCodesInGroup = sameGroupMachines.stream().map(Machine::getCode).toList();
      List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getDrawingNo, drawingNo).eq(NcNode::getProcessNo, processNo)
         .likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
         .in(!machineCodesInGroup.isEmpty(),NcNode::getMachineCode,machineCodesInGroup)
         .eq(NcNode::getIsLastEdition,1).orderByDesc(NcNode::getCreateTime).list();
      if(nodes.isEmpty()){
         return null;
      }else {
         return nodes.get(0);
      }
   }
   /**
    * 获取最新版本的 偏离节点
    * @param programPkgName 程序包名
    * @return 偏离的程序节点
    */
   public NcNode getLastEditionDeviationProgramPackage(String programPkgName) {//,String processEdition
      List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getName, programPkgName)
         //.eq(NcNode::getProcessEdition, processEdition)
         .likeRight(NcNode::getParentIds,"0,3,")
         .eq(NcNode::getIsLastEdition,1).list();
      if(nodes.isEmpty()){
         return null;
      }else {
         return nodes.get(0);
      }
   }
   /**
    * 根据流程实例id获取node节点,都是程序包节点
    * @param processInstanceId 流程实例id
    * @return 对应额系欸但那
    */
    public NcNode getByProcessInstanceId(String processInstanceId) {
      Optional<NcNode> nodeOpt = this.lambdaQuery().eq(NcNode::getProcessInstanceId,processInstanceId).oneOpt();
      return nodeOpt.orElse(null);
    }
   /**
    * 物理删除节点id下的子节点(性能考虑,否则数据太多)
    * @param nodeId 节点id
    */
   public void deleteSubNodes(Long nodeId) {
      this.baseMapper.deleteSubNodes(nodeId);
   }
   /**
    * 获取程序包下所有层序文件节点
    * @param packageNodeId 程序包名 节点id
    * @return 包下属的程序文件
    */
   public List<NcNode> getProgramFilesByPackageId(Long packageNodeId) {
      return this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_FILE)
         .eq(NcNode::getParentId,packageNodeId).eq(NcNode::getIsLastEdition,1).list();
   }
   /**
    * 升级版本号(+1)
    * @param nodeId 节点id
    */
   @Transactional
   public void upgradeVersionNumber(Long nodeId) {
      NcNode node = this.getById(nodeId);
      node.upgradeVersionNumber();
      this.updateById(node);
   }
   /**
    * 锁定节点
    * @param id 程序包节点id
    */
   @Transactional
    public void lock(Long id) {
      NcNode node = this.getById(id);
      node.lock();
      this.updateById(node);
    }
   @Transactional
   public void lock(Long id,String remark) {
      NcNode node = this.getById(id);
      node.lock(remark);
      this.updateById(node);
   }
   @Transactional
   public void unlock(Long id) {
      NcNode node = this.getById(id);
      node.unlock();
      this.updateById(node);
   }
   /**
    * 查询偏离单的序号
    * @param programPkgNode 偏离单的程序包名节点
    * @return 序号
    */
   /*
    public long getDeviationSerialForNode(NcNode programPkgNode) {
      return lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
         .eq(NcNode::getName,programPkgNode.getName())
         .eq(NcNode::getDrawingNo,programPkgNode.getDrawingNo())
         .eq(NcNode::getProcessNo,programPkgNode.getProcessNo())
         .eq(NcNode::getProcessEdition,programPkgNode.getProcessEdition())
         .isNotNull(NcNode::getDeviation)
         .le(NcNode::getCreateTime,programPkgNode.getCreateTime())  //时间小于等于当前节点
         .count();
    }
   */
   /**
    * 根据上级节点id,移动下面的加工机床节点
    * @param parentId 上级节点id
    */
   /*
   public void deleteMachineGroupNodeByParentId(Long parentId) {
      baseMapper.deleteMachineGroupNodeByParentId(parentId);
   }*/
   /**
    * 删除所偶非最新版本的数据(hodeHIs里面已经保存过)
    */
   public void deleteOldEditionNodeData() {
      baseMapper.deleteOldEditionNodeData();
   }
   /**
    * //更新已固化的,同名、不同机床组的程序为锁定状态
    * @param packageNode
    */
    public void lockSameNameOtherMachineGroupProgramPackage(NcNode packageNode) {
      lambdaUpdate().eq(NcNode::getDrawingNo,packageNode.getDrawingNo())
         .eq(NcNode::getProcessNo,packageNode.getProcessNo())
         .eq(NcNode::getName,packageNode.getName())
         .ne(NcNode::getMachineGroupCode,packageNode.getMachineGroupCode())
         .eq(NcNode::getIsCured,1)
         .eq(NcNode::getIsLastEdition,1)
         .set(NcNode::getIsLocked,NcNode.LOCKED)
         .set(NcNode::getRemark,"回传固化同名程序锁定")
         .update();
    }
}