/*
* Copyright (c) 京北方信息技术股份有限公司 Corporation 2022 . All rights reserved.
*
*/
package net.northking.cctp.scriptcase.db.impl;

import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.BasicDao;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.saas.db.TenantEntityService;
import net.northking.cctp.common.security.authentication.NKSecurityContext;
import net.northking.cctp.common.util.UUIDUtil;
import net.northking.cctp.scriptcase.api.component.service.AtuBusinessNoApiService;
import net.northking.cctp.scriptcase.db.dao.AtuScriptGroupDao;
import net.northking.cctp.scriptcase.db.dao.AtuScriptInfoDao;
import net.northking.cctp.scriptcase.db.entity.AtuScriptGroup;
import net.northking.cctp.scriptcase.db.entity.AtuScriptInfo;
import net.northking.cctp.scriptcase.db.service.AtuScriptGroupService;
import net.northking.cctp.scriptcase.dto.atuScript.atuScriptGroup.*;
import net.northking.cctp.scriptcase.enums.ErrorMessage;
import net.northking.cctp.scriptcase.enums.ScriptCaseAppError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 脚本分组表
 *
 * <p>文件内容由代码生成器产生，请不要手动修改！ <br>
 * createdate:  2022-10-18 17:29:31  <br>
 * @author:  maven-cctp-plugin  <br>
 * @since:  1.0 <br>
 */
@Service
@ConditionalOnMissingBean(name = "AtuScriptGroupServiceImpl")
public class AtuScriptGroupServiceImpl extends TenantEntityService<AtuScriptGroup> implements AtuScriptGroupService
{
private static final Logger logger = LoggerFactory.getLogger(AtuScriptGroupServiceImpl.class);

  @Autowired
  private AtuScriptInfoDao atuScriptInfoDao;

  @Autowired
  private EntityNameCache entityNameCache;

  @Autowired
  private AtuBusinessNoApiService atuBusinessNoApiService;

  private final AtuScriptGroupDao atuScriptGroupDao;

  public AtuScriptGroupServiceImpl(AtuScriptGroupDao atuScriptGroupDao) {this.atuScriptGroupDao = atuScriptGroupDao;}

  public BasicDao<AtuScriptGroup> getDao() {return atuScriptGroupDao;}

  public AtuScriptGroup createEntity() { return new AtuScriptGroup();}





  /**
   * 新增脚本目录
   * @param dto
   * @return
   */
  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public String addScriptTree(AtuScriptGroupAddDto dto) {
    //判断名字是否包括/或者\
    if (dto.getGroupName().contains("/") || dto.getGroupName().contains("\\")) {
      throw new PlatformRuntimeException(new ErrorMessage("目录名称不可包含【/】或者【\\】"));
    }
    //设置根节点目录
    if (!StringUtils.hasText(dto.getPid())) {
      dto.setPid("0");
    }
    //获取父id,如果是根目录则父id为0
    String pid = dto.getPid();
    //查询父节点信息
    AtuScriptGroup atuScriptGroup = new AtuScriptGroup();
    atuScriptGroup.setId(pid);
    AtuScriptGroup byPKParent = atuScriptGroupDao.findByPrimaryKey(atuScriptGroup);
    //设置根节点的父节点
    if (byPKParent == null) {
      byPKParent = new AtuScriptGroup();
      byPKParent.setId("0");
      byPKParent.setGroupName("");
      byPKParent.setLevelNo(0);
      byPKParent.setIdPath("0");
      byPKParent.setNamePath("");
      byPKParent.setPid("-1");
      byPKParent.setIsLeaf("1");
    }
    //非根目录创建
    //1.判断父节点是否存在脚本
    if (!"0".equals(pid)) {
      AtuScriptInfo tempScript = new AtuScriptInfo();
      tempScript.setGroupId(byPKParent.getId());
      tempScript.setIsDeleted("0");
      List<AtuScriptInfo> existScripts = atuScriptInfoDao.query(tempScript);
      if (!CollectionUtils.isEmpty(existScripts)) {
        throw new PlatformRuntimeException(new ErrorMessage("所选目录下已存在脚本，不允许新增目录"));
      }
    }
    //2.限制最多十级目录
    if (byPKParent.getLevelNo() - 10 >= 0) {
      throw new PlatformRuntimeException(new ErrorMessage("目录不能超过10级"));
    }
    //3.判断同级是否存在重名目录
    AtuScriptGroup scriptGroup = new AtuScriptGroup();
    scriptGroup.setPid(pid);
    scriptGroup.setGroupName(dto.getGroupName());
    scriptGroup.setProjectId(dto.getProjectId());
    List<AtuScriptGroup> scriptGroups = atuScriptGroupDao.query(scriptGroup);
    if (!CollectionUtils.isEmpty(scriptGroups)) {
          throw new PlatformRuntimeException(new ErrorMessage("该脚本目录下已存在重名脚本目录，不允许新增目录"));
    }
    //5.插入节点至数据库
    String uuid = UUIDUtil.create32UUID();
    AtuScriptGroup newGroup = new AtuScriptGroup();
    BeanUtils.copyProperties(dto,newGroup);
    newGroup.setId(uuid);
    newGroup.setIsLeaf("1");
    newGroup.setCreatedBy(NKSecurityContext.getUserId());
    newGroup.setCreatedTime(new Date());
    newGroup.setUpdatedBy(newGroup.getCreatedBy());
    newGroup.setUpdatedTime(newGroup.getCreatedTime());
    //新增根节点目录
    if ("0".equals(dto.getPid())) {
      newGroup.setIdPath(uuid);
      newGroup.setNamePath(dto.getGroupName());
      newGroup.setLevelNo(1);
    } else { //新增非根节点目录
      newGroup.setLevelNo(byPKParent.getLevelNo()+1);
      newGroup.setIdPath(byPKParent.getIdPath() + "/" + uuid);
      newGroup.setNamePath(byPKParent.getNamePath() + "/" + dto.getGroupName());
      //6.如果父节点是叶子节点更新父节点
      if ("1".equals(byPKParent.getIsLeaf())) {
        AtuScriptGroup newParent = new AtuScriptGroup();
        newParent.setId(dto.getPid());
        newParent.setIsLeaf("0");
        newParent.setUpdatedBy(NKSecurityContext.getUserId());
        newParent.setUpdatedTime(newGroup.getCreatedTime());
        newParent.setTenantId(byPKParent.getTenantId());
        atuScriptGroupDao.updateByPrimaryKey(newParent);
      }
    }
    //获取排序值
    Integer seq = atuBusinessNoApiService.genBusinessNo(dto.getProjectId(), "ATU_SCRIPT_TREE", 1L).get(0);
    newGroup.setSeq(String.valueOf(seq));
    newGroup.setTenantId(NKSecurityContext.getTenantId());
    atuScriptGroupDao.insert(newGroup);
    return uuid;
  }

  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer moveScriptTree(AtuScriptGroupMoveDto dto) {
    AtuScriptGroup oldNode = atuScriptGroupDao.findByPrimaryKey(dto.getId());
    AtuScriptGroup tempTree = new AtuScriptGroup();
    if("0".equals(dto.getTargetId())) {
      tempTree.setId("0");
      tempTree.setLevelNo(0);
      tempTree.setIsLeaf("0");
      tempTree.setNamePath("");
    }else {
      tempTree = atuScriptGroupDao.findByPrimaryKey(dto.getTargetId());
    }
    //判断拖拽后是否层数超过10级
    Integer targetLevel = tempTree.getLevelNo();
    AtuScriptGroup queryLevel = new AtuScriptGroup();
    queryLevel.setId(oldNode.getId());
    queryLevel.setProjectId(oldNode.getProjectId());
    int maxLevel = atuScriptGroupDao.countMaxLevelNo(queryLevel);
    int myMaxLevel = maxLevel - oldNode.getLevelNo() + 1;
    if ((targetLevel + myMaxLevel) > 10) {
      throw new PlatformRuntimeException(ScriptCaseAppError.TREE_LEVEL_LIMIT);
    }
    int levelNo = tempTree.getLevelNo()-oldNode.getLevelNo()+1;
    if(dto.getOrderSeq()==null) {
      dto.setOrderSeq(0);
    }
    //校验是否同名
    AtuScriptGroup check = new AtuScriptGroup();
    check.setGroupName(oldNode.getGroupName());
    check.setPid(tempTree.getId());
    check.setProjectId(dto.getProjectId());
    if(!CollectionUtils.isEmpty(atuScriptGroupDao.query(check)) && !oldNode.getPid().equals(tempTree.getId())){
      throw new PlatformRuntimeException(ScriptCaseAppError.TREE_NAME_EXISTS);
    }
    //校验是否目标节点为非叶子节点并存在用例
    AtuScriptInfo exitScript = new AtuScriptInfo();
    exitScript.setProjectId(dto.getProjectId());
    exitScript.setGroupId(tempTree.getId());
    exitScript.setIsDeleted("0");
    if ("1".equals(tempTree.getIsLeaf()) && !CollectionUtils.isEmpty(atuScriptInfoDao.query(exitScript))) {
      throw new PlatformRuntimeException(new ErrorMessage("目标目录存在脚本数据，不能生成目录"));
    }
    //更新节点以及子节点
    AtuScriptGroup treeUp = new AtuScriptGroup();
    treeUp.setId(oldNode.getId());
    treeUp.setPid(tempTree.getId());
    treeUp.setTenantId(oldNode.getTenantId());
    atuScriptGroupDao.updateByPrimaryKey(treeUp);
    String targetIdPath = StringUtils.hasText(tempTree.getIdPath()) ? (tempTree.getIdPath()+"/") : "";
    String targetNamePath = StringUtils.hasText(tempTree.getNamePath()) ? (tempTree.getNamePath()+"/") : "";
    treeUp.setIdPath(targetIdPath+oldNode.getId());
    treeUp.setNamePath(targetNamePath+oldNode.getGroupName());
    //更改顺序号
    AtuScriptGroupMoveDto childUp = new AtuScriptGroupMoveDto();
    childUp.setOrderSeq(dto.getOrderSeq());
    childUp.setProjectId(dto.getProjectId());
    atuBusinessNoApiService.genBusinessNo(dto.getProjectId(),"ATU_SCRIPT_TREE",1L);
    atuScriptGroupDao.updateSeqByMove(childUp);
    //替换移动节点的排序号
    AtuScriptGroup treeUpOrder = new AtuScriptGroup();
    treeUpOrder.setId(oldNode.getId());
    treeUpOrder.setSeq(dto.getOrderSeq()+1+"");
    treeUpOrder.setTenantId(oldNode.getTenantId());
    atuScriptGroupDao.updateByPrimaryKey(treeUpOrder);
    //子节点更改路径
    AtuScriptGroup child = new AtuScriptGroup();
    BeanUtils.copyProperties(childUp,child);
    child.setProjectId(oldNode.getProjectId());
    child.setNamePath(oldNode.getNamePath());
    child.setIdPath(oldNode.getIdPath());
    child.setLevelNo(levelNo);
    atuScriptGroupDao.updateChildNamePath(child,treeUp.getNamePath());
    atuScriptGroupDao.updateChildIdPath(child,treeUp.getIdPath());
    //修改原父节点以及现父节点的叶子节点标识
    if("1".equals(tempTree.getIsLeaf())){
      AtuScriptGroup itemTreeUp = new AtuScriptGroup();
      itemTreeUp.setId(tempTree.getId());
      itemTreeUp.setIsLeaf("0");
      itemTreeUp.setTenantId(tempTree.getTenantId());
      atuScriptGroupDao.updateByPrimaryKey(itemTreeUp);
    }
    AtuScriptGroup oldFaCount = new AtuScriptGroup();
    oldFaCount.setPid(oldNode.getPid());
    if(CollectionUtils.isEmpty(atuScriptGroupDao.query(oldFaCount))){
      AtuScriptGroup oldTreeUp = new AtuScriptGroup();
      oldTreeUp.setId(oldNode.getPid());
      oldTreeUp.setIsLeaf("1");
      oldTreeUp.setTenantId(oldNode.getTenantId());
      atuScriptGroupDao.updateByPrimaryKey(oldTreeUp);
    }
    return 1;
  }

  @Override
  public List<AtuScriptGroup> queryChildrenTreeList(String groupId) {
    return atuScriptGroupDao.queryChildrenTreeList(groupId);
  }

  @Override
  public List<AtuScriptGroup> queryByIds(List<String> groupIdList) {
    return atuScriptGroupDao.queryByIds(groupIdList);
  }

  @Override
  public List<String> getAllIdPath(PublishScriptQueryDto dto) {
    return atuScriptGroupDao.getAllIdPath(dto);
  }

  @Override
  public List<AtuScriptGroup> findTreeListLike(PublishScriptQueryDto dto) {
    return atuScriptGroupDao.findTreeListLike(dto);
  }

  /**
   * 获取子目录列表
   * @param dto
   * @return
   */
  @Override
  public List<AtuScriptGroupDetailDto> queryChildrenTree(AtuScriptGroupQueryDto dto) {
    if (CollectionUtils.isEmpty(dto.getProjectIds())) {
      if (StringUtils.hasText(dto.getProjectId())) {
        List<String> proIds = new ArrayList<>();
        proIds.add(dto.getProjectId());
        dto.setProjectIds(proIds);
      }
    }
    List<AtuScriptGroupDetailDto> result = new ArrayList<>();
    //根据父节点查询所有子级节点
    if(!StringUtils.isEmpty(dto.getPid())){
      AtuScriptGroupQueryDto atuScriptGroup = new AtuScriptGroupQueryDto();
      atuScriptGroup.setProjectId(dto.getProjectId());
      atuScriptGroup.setProjectIds(dto.getProjectIds());
      atuScriptGroup.setPid(dto.getPid());
      result = atuScriptGroupDao.selectScriptTree(atuScriptGroup);
      for (AtuScriptGroupDetailDto detailDto : result) {
        detailDto.setNodeType("g");
        detailDto.setIdx(Integer.parseInt(detailDto.getSeq()));
      }
    }else{
      //最外层为系统信息数组
      for (String projectId : dto.getProjectIds()) {
        AtuScriptGroupDetailDto detailDto = new AtuScriptGroupDetailDto();
        detailDto.setId(projectId);
        detailDto.setPid("");
        detailDto.setProjectId(projectId);
        detailDto.setGroupName(entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM.name(),projectId));
        detailDto.setIsLeaf("0");
        detailDto.setLevelNo(0);
        detailDto.setNodeType("p");
        result.add(detailDto);
      }
    }
    return result;
  }

  /**
   * 条件查询脚本目录树
   * @param dto
   * @return
   */
  @Override
  public List<AtuScriptGroupDetailDto> queryScriptTree(AtuScriptGroupQueryDto dto) {
    if(dto.isMoreProject() && CollectionUtils.isEmpty(dto.getProjectIds())){
      if (StringUtils.hasText(dto.getProjectId())) {
        List<String> list = new ArrayList<>();
        list.add(dto.getProjectId());
        dto.setProjectIds(list);
      }
    }
    AtuScriptGroupQueryDto queryDto = new AtuScriptGroupQueryDto();
    queryDto.setGroupName(dto.getGroupName());
    queryDto.setProjectId(dto.getProjectId());
    queryDto.setProjectIds(dto.getProjectIds());
    queryDto.setTenantId(NKSecurityContext.getTenantId());
    List<AtuScriptGroupDetailDto> scriptTreeList = atuScriptGroupDao.selectScriptTree(queryDto);
    if (scriptTreeList.size()<1) {
      //无数据时多系统也需再包装一层系统级信息
      if(dto.isMoreProject()) {
        return setProjectTop(scriptTreeList, dto.getProjectIds(), dto.getGroupName());
      }else {
        return scriptTreeList;
      }
    }
    Map<String, AtuScriptGroupDetailDto> treeMap = getTreeMap(scriptTreeList);
    List<AtuScriptGroupDetailDto> detailDtos = new ArrayList<>();
    for (String treeId : treeMap.keySet()) {
      detailDtos.add(treeMap.get(treeId));
    }
    List<AtuScriptGroupDetailDto> treeList = getTreeList(detailDtos);
    List<AtuScriptGroupDetailDto> resList = treeList.stream().sorted(Comparator.comparing(AtuScriptGroupDetailDto::getSeq)).collect(Collectors.toList());
    //多系统包装最外层系统信息
    if(dto.isMoreProject()){
      return setProjectTop(resList,dto.getProjectIds(),dto.getGroupName());
    }
    return resList;
  }

  /**
   * 编辑脚本目录
   * @param dto
   * @return
   */
  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer updateScriptTree(AtuScriptGroupUpdateDto dto) {
    String newName = dto.getGroupName();
    //判断目录名是否包括/或者\
    if (newName.contains("/") || newName.contains("\\")) {
      throw new PlatformRuntimeException(new ErrorMessage("目录名称不可包含【/】或者【\\】"));
    }
    //获取待改目录节点信息
    AtuScriptGroup byPrimaryKey = atuScriptGroupDao.findByPrimaryKey(dto.getId());
    if (null == byPrimaryKey) {
      throw new PlatformRuntimeException(new ErrorMessage("该目录不存在，请刷新目录列表"));
    }
    //获取同级目录节点信息
    AtuScriptGroup group = new AtuScriptGroup();
    group.setPid(byPrimaryKey.getPid());
    group.setGroupName(dto.getGroupName());
    group.setProjectId(byPrimaryKey.getProjectId());
    List<AtuScriptGroup> broNodes = atuScriptGroupDao.query(group);
    if (!CollectionUtils.isEmpty(broNodes) && !broNodes.get(0).getId().equals(dto.getId())) {
      throw new PlatformRuntimeException(new ErrorMessage("同级目录下该名称已存在，修改失败"));
    }
    //更新数据库数据
    AtuScriptGroup tempScriptGroup = new AtuScriptGroup();
    BeanUtils.copyProperties(dto,tempScriptGroup);
    tempScriptGroup.setUpdatedBy(NKSecurityContext.getUserId());
    tempScriptGroup.setUpdatedTime(new Date());
    //更新namePath
    String namePath = byPrimaryKey.getNamePath();
    String namePathNew = "";
    AtuScriptGroup childScriptGroup = new AtuScriptGroup();
    childScriptGroup.setProjectId(byPrimaryKey.getProjectId());
    childScriptGroup.setNamePath(namePath);
    //更新根节点名称路径
    if ("0".equals(byPrimaryKey.getPid())) {
      namePathNew = dto.getGroupName();
    }else {
      //更新非根节点名称路径
      String[] nameArr = namePath.split("/");
      namePathNew = nameArr[0];
      for (int i = 1; i < nameArr.length - 1; i++) {
        namePathNew = namePathNew + "/" + nameArr[i];
      }
      namePathNew = namePathNew + "/" + dto.getGroupName();
    }
    tempScriptGroup.setNamePath(namePathNew);
    tempScriptGroup.setTenantId(byPrimaryKey.getTenantId());
    int total = atuScriptGroupDao.updateByPrimaryKey(tempScriptGroup);
    //同步修改所有子级节点
    total+= atuScriptGroupDao.updateChildNamePath(childScriptGroup,namePathNew);
    return total;
  }

  /**
   * 删除脚本目录
   * @param id
   * @return
   */
  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer deleteScriptTree(String id) {
    AtuScriptGroup byPrimaryKey = atuScriptGroupDao.findByPrimaryKey(id);
    if (null == byPrimaryKey) {
      return 0;
    }
    //判断节点是否为叶子结点
    if ("0".equals(byPrimaryKey.getIsLeaf())) {
      throw new PlatformRuntimeException(new ErrorMessage("该目录下有子目录，不可删除"));
    }
    //判断所选目录是否有脚本
    AtuScriptInfo tempScript = new AtuScriptInfo();
    tempScript.setGroupId(id);
    tempScript.setIsDeleted("0");
    List<AtuScriptInfo> scripts = atuScriptInfoDao.query(tempScript);
    if (!CollectionUtils.isEmpty(scripts)) {
      throw new PlatformRuntimeException(new ErrorMessage("该目录下存在数据，不可删除"));
    }
    //删除数据库数据
    int res = atuScriptGroupDao.deleteByPrimaryKey(id);
    //查询父目录是否含有其他子目录
    AtuScriptGroup scriptGroup = new AtuScriptGroup();
    scriptGroup.setPid(byPrimaryKey.getPid());
    List<AtuScriptGroup> childrenNodes = atuScriptGroupDao.query(scriptGroup);
    //无子目录时需改为叶子结点
    if (CollectionUtils.isEmpty(childrenNodes)) {
      AtuScriptGroup newParent = new AtuScriptGroup();
      newParent.setId(byPrimaryKey.getPid());
      newParent.setIsLeaf("1");
      newParent.setUpdatedBy(NKSecurityContext.getUserId());
      newParent.setUpdatedTime(new Date());
      newParent.setTenantId(byPrimaryKey.getTenantId());
      atuScriptGroupDao.updateByPrimaryKey(newParent);
    }
    return res;
  }

  private Map<String, AtuScriptGroupDetailDto> getTreeMap(List<AtuScriptGroupDetailDto> allList) {
    Map<String, AtuScriptGroupDetailDto> treeMap = new HashMap<>();
    List<String> list = new ArrayList<>();
    //查询包含的树节点id
    for (int i = 0; i < allList.size(); i++) {
      AtuScriptGroupDetailDto detailDto = allList.get(i);
      String[] paths = detailDto.getIdPath().split("/");
      List<String> ids = new ArrayList<>(Arrays.asList(paths));
      list.addAll(ids);
    }
    list = list.stream().distinct().collect(Collectors.toList());
    List<AtuScriptGroup> treeList = atuScriptGroupDao.queryByIds(list);
    for (AtuScriptGroup atuScriptGroup : treeList) {
      AtuScriptGroupDetailDto detailDto = new AtuScriptGroupDetailDto();
      BeanUtils.copyProperties(atuScriptGroup,detailDto);
      detailDto.setIdx(Integer.parseInt(detailDto.getSeq()));
      detailDto.setNodeType("g");
      if (!treeMap.containsKey(atuScriptGroup.getId())) {
        treeMap.put(atuScriptGroup.getId(),detailDto);
      }
    }
    return treeMap;
  }

  private List<AtuScriptGroupDetailDto> getTreeList(List<AtuScriptGroupDetailDto> dtoList) {
    List<AtuScriptGroupDetailDto> treeList = new ArrayList<>();
    for (int i = 0; i < dtoList.size(); i++) {
      AtuScriptGroupDetailDto tree = dtoList.get(i);
      if("0".equals(tree.getPid())){
        getSonTree(tree,dtoList);
        treeList.add(tree);
      }
    }
    return treeList;
  }

  private void getSonTree(AtuScriptGroupDetailDto tree, List<AtuScriptGroupDetailDto> dtoList) {
    List<AtuScriptGroupDetailDto> sonList = new ArrayList<>();
    for (AtuScriptGroupDetailDto dto : dtoList) {
      if(tree.getId().equals(dto.getPid())){
        getSonTree(dto,dtoList);
        sonList.add(dto);
      }
    }
    List<AtuScriptGroupDetailDto> reSonList = sonList.stream().sorted(Comparator.comparing(AtuScriptGroupDetailDto::getSeq)).collect(Collectors.toList());
    tree.setChildren(reSonList);
  }

  private List<AtuScriptGroupDetailDto> setProjectTop(List<AtuScriptGroupDetailDto> reList,List<String> projectIds,String groupName){
    List<AtuScriptGroupDetailDto> result = new ArrayList<>();
    Map<String,List<AtuScriptGroupDetailDto>> tool = new HashMap<>();
    for (AtuScriptGroupDetailDto oneTree : reList) {
      if (tool.containsKey(oneTree.getProjectId())){
        tool.get(oneTree.getProjectId()).add(oneTree);
      }else{
        List<AtuScriptGroupDetailDto> list = new ArrayList<>();
        list.add(oneTree);
        tool.put(oneTree.getProjectId(),list);
      }
    }
    //无系统查全部
    if (CollectionUtils.isEmpty(projectIds)) {
      projectIds = new ArrayList<>();
      projectIds.addAll(tool.keySet());
    }
    for (String projectId : projectIds) {
      String projectName = entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM.name(), projectId);
      if(tool.containsKey(projectId) || !StringUtils.hasText(groupName)|| (StringUtils.hasText(groupName) && projectName.contains(groupName))){
        AtuScriptGroupDetailDto one = new AtuScriptGroupDetailDto();
        one.setId(projectId);
        one.setNodeType("p");
        one.setIsLeaf("0");
        one.setGroupName(projectName);
        one.setLevelNo(0);
        one.setPid("");
        one.setProjectId(projectId);
        one.setChildren(tool.get(projectId));
        //无子树则为叶子结点
        if (CollectionUtils.isEmpty(one.getChildren())) {
          one.setIsLeaf("1");
        }
        result.add(one);
      }
    }
    return result;
  }
}

