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

import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.common.db.Pagination;
import net.northking.cctp.common.db.annotation.DatabaseReadOnly;
import net.northking.cctp.common.db.excel.AbstractExcelService;
import net.northking.cctp.common.db.excel.ExcelHeader;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.http.QueryByPage;
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.entity.AtuElementGroup;
import net.northking.cctp.scriptcase.db.entity.AtuElementInfo;
import net.northking.cctp.scriptcase.db.service.AtuElementGroupService;
import net.northking.cctp.scriptcase.db.service.AtuElementInfoService;
import net.northking.cctp.scriptcase.dto.elementLibrary.*;
import net.northking.cctp.scriptcase.enums.ElementLibraryError;
import net.northking.cctp.scriptcase.constants.ScriptConstant;
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;

/**
 * 元素目录管理服务实现类
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

@Service
@ConditionalOnMissingBean(name = "AtuElementGroupApiServiceImpl")
public class AtuElementGroupApiServiceImpl extends AbstractExcelService<AtuElementGroup> implements AtuElementGroupApiService
{
  /**
   * 日志
   */
  private final static Logger logger = LoggerFactory.getLogger(AtuElementGroupApiServiceImpl.class);

  @Autowired
  private AtuElementGroupService atuElementGroupService;
  @Autowired
  private AtuElementInfoService atuElementInfoService;
  @Autowired
  private AtuBusinessNoApiService atuBusinessNoApiService;
  @Autowired
  private EntityNameCache entityNameCache;

  //= Excel 导入导出相关代码 start ==================//
  @Override
  public BasicService<AtuElementGroup> getService()
  {
    return this.atuElementGroupService;
  }

  @Override
  public ExcelHeader[] excelHeaders()
  {
    ExcelHeader id = new ExcelHeader("目录ID", "id", String.class);
    ExcelHeader pid = new ExcelHeader("父目录ID", "pid", String.class);
    ExcelHeader groupName = new ExcelHeader("目录名称", "groupName", String.class);
    ExcelHeader description = new ExcelHeader("目录描述", "description", String.class);
    ExcelHeader levelNo = new ExcelHeader("目录层级", "levelNo", Integer.class);
    ExcelHeader seq = new ExcelHeader("目录顺序", "seq", Integer.class);
    ExcelHeader isLeaf = new ExcelHeader("是否为叶子节点", "isLeaf", String.class);
    ExcelHeader idPath = new ExcelHeader("ID路径", "idPath", String.class);
    ExcelHeader namePath = new ExcelHeader("名称路径", "namePath", String.class);
    ExcelHeader projectId = new ExcelHeader("系统ID", "projectId", String.class);
    ExcelHeader tenantId = new ExcelHeader("租户号", "tenantId", String.class);
    ExcelHeader createdBy = new ExcelHeader("创建人", "createdBy", String.class);
    ExcelHeader createdTime = new ExcelHeader("创建时间", "createdTime", Date.class);
    ExcelHeader updatedBy = new ExcelHeader("更新人", "updatedBy", String.class);
    ExcelHeader updatedTime = new ExcelHeader("更新时间", "updatedTime", Date.class);
    return new ExcelHeader[]{};
  }

  /**
   * Excel导入，入库之前的处理
   * @param records 从Excel读取到的记录
   * @return 待入库的记录
   */
  @Override
  protected List<AtuElementGroup> beforeInsertBatch(List<AtuElementGroup> records)
  {
    for (AtuElementGroup record : records)
    {
      record.setId(UUIDUtil.create32UUID());
    }
    return records;
  }

  /**
   * 写入Excel之前的处理<br>
   * 数据的特殊处理在此处加工处理
   *
   * @param record 来自数据库记录
   * @return 待写入Excel的记录
   */
  @Override
  protected AtuElementGroup beforeWriteExcel(AtuElementGroup record)
  {
    return record;
  }

  //= Excel 导入导出相关代码 end =======================//

  //= 增删改查 相关代码 start ==================//
  @Override
  @DatabaseReadOnly
  public Pagination<AtuElementGroupDetailDto> pagingQuery(QueryByPage<AtuElementGroupQueryDto> queryByPage)
  {
    return this.atuElementGroupService.pagingQuery(queryByPage);
  }

  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public String add(AtuElementGroupAddDto dto)
  {
    //判断名字是否包括/或者\
    if (dto.getGroupName().contains("/") || dto.getGroupName().contains("\\")) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NAME_VALID);
    }
    //设置根节点目录
    if (!StringUtils.hasText(dto.getPid())) {
      dto.setPid(ScriptConstant.STR_ZERO);
    }
    //获取父id,如果是根目录则父id为0
    String pid = dto.getPid();
    //查询父节点信息
    AtuElementGroup byPKParent = atuElementGroupService.findByPrimaryKey(pid);
    //设置根节点的父节点
    if (byPKParent == null) {
      byPKParent = new AtuElementGroup();
      byPKParent.setId(ScriptConstant.STR_ZERO);
      byPKParent.setGroupName("");
      byPKParent.setLevelNo(0);
      byPKParent.setIdPath(ScriptConstant.STR_ZERO);
      byPKParent.setNamePath("");
      byPKParent.setPid(ScriptConstant.STR_MINUS_ONE);
      byPKParent.setIsLeaf(ScriptConstant.STR_ZERO);
    }
    //非根目录创建
    //1.判断父节点是否存在元素
    if (!ScriptConstant.STR_ZERO.equals(pid)) {
      AtuElementInfo atuElementInfo = new AtuElementInfo();
      atuElementInfo.setGroupId(byPKParent.getId());
      atuElementInfo.setIsDeleted(ScriptConstant.STR_ZERO);
      List<AtuElementInfo> existElements = atuElementInfoService.query(atuElementInfo);
      if (!CollectionUtils.isEmpty(existElements)) {
        throw new PlatformRuntimeException(ElementLibraryError.TREE_ADD_DATA_EXISTS);
      }
    }
    //2.限制最多十级目录
    if (byPKParent.getLevelNo() - 10 >= 0) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_LEVEL_LIMIT);
    }
    //3.判断同级是否存在重名目录
    AtuElementGroup elementGroup = new AtuElementGroup();
    elementGroup.setPid(pid);
    elementGroup.setGroupName(dto.getGroupName());
    elementGroup.setProjectId(dto.getProjectId());
    List<AtuElementGroup> elementGroups = atuElementGroupService.query(elementGroup);
    if (!CollectionUtils.isEmpty(elementGroups)) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NAME_EXISTS);
    }
    //5.插入节点至数据库
    String uuid = UUIDUtil.create32UUID();
    AtuElementGroup newTree = new AtuElementGroup();
    BeanUtils.copyProperties(dto,newTree);
    newTree.setId(uuid);
    newTree.setIsLeaf(ScriptConstant.STR_ONE);
    newTree.setCreatedBy(NKSecurityContext.getUserId());
    newTree.setCreatedTime(new Date());
    newTree.setUpdatedBy(newTree.getCreatedBy());
    newTree.setUpdatedTime(newTree.getCreatedTime());
    //新增根节点目录
    if (ScriptConstant.STR_ZERO.equals(dto.getPid())) {
      newTree.setIdPath(uuid);
      newTree.setNamePath(dto.getGroupName());
      newTree.setLevelNo(1);
    } else { //新增非根节点目录
      newTree.setLevelNo(byPKParent.getLevelNo()+1);
      newTree.setIdPath(byPKParent.getIdPath() + "/" + uuid);
      newTree.setNamePath(byPKParent.getNamePath() + "/" + dto.getGroupName());
      //6.如果父节点是叶子节点更新父节点
      if (ScriptConstant.STR_ONE.equals(byPKParent.getIsLeaf())) {
        AtuElementGroup newParent = new AtuElementGroup();
        newParent.setId(dto.getPid());
        newParent.setIsLeaf(ScriptConstant.STR_ZERO);
        newParent.setUpdatedBy(NKSecurityContext.getUserId());
        newParent.setUpdatedTime(newTree.getCreatedTime());
        atuElementGroupService.updateByPrimaryKey(newParent);
      }
    }
    //获取排序值
    Integer seq = atuBusinessNoApiService.genBusinessNo(dto.getProjectId(), ScriptConstant.ATU_ELEMENT_TREE, 1L).get(0);
    newTree.setSeq(seq);
    newTree.setTenantId(NKSecurityContext.getTenantId());
    atuElementGroupService.insert(newTree);
    return uuid;
  }

  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer updateByPK(AtuElementGroupUpdateDto dto) throws IllegalAccessException
  {
    String newName = dto.getGroupName();
    //判断目录名是否包括/或者\
    if (newName.contains("/") || newName.contains("\\")) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NAME_VALID);
    }
    //获取待改目录节点信息
    AtuElementGroup byPrimaryKey = atuElementGroupService.findByPrimaryKey(dto.getId());
    if (null == byPrimaryKey) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NO_EXISTS);
    }
    //获取同级目录节点信息
    AtuElementGroup tree = new AtuElementGroup();
    tree.setPid(byPrimaryKey.getPid());
    tree.setGroupName(dto.getGroupName());
    tree.setProjectId(byPrimaryKey.getProjectId());
    List<AtuElementGroup> broNodes = atuElementGroupService.query(tree);
    if (!CollectionUtils.isEmpty(broNodes) && !broNodes.get(0).getId().equals(dto.getId())) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NAME_EXISTS);
    }
    //更新数据库数据
    AtuElementGroup tempTree = new AtuElementGroup();
    BeanUtils.copyProperties(dto,tempTree);
    tempTree.setUpdatedBy(NKSecurityContext.getUserId());
    tempTree.setUpdatedTime(new Date());
    //更新namePath
    String namePath = byPrimaryKey.getNamePath();
    StringBuilder namePathNew = new StringBuilder();
    AtuElementGroup childTrees = new AtuElementGroup();
    childTrees.setProjectId(byPrimaryKey.getProjectId());
    childTrees.setNamePath(namePath);
    //更新根节点名称路径
    if (ScriptConstant.STR_ZERO.equals(byPrimaryKey.getPid())) {
      namePathNew = new StringBuilder(dto.getGroupName());
    }else {
      //更新非根节点名称路径
      String[] nameArr = namePath.split("/");
      namePathNew = new StringBuilder(nameArr[0]);
      for (int i = 1; i < nameArr.length - 1; i++) {
        namePathNew.append("/").append(nameArr[i]);
      }
      namePathNew.append("/").append(dto.getGroupName());
    }
    tempTree.setNamePath(namePathNew.toString());
    int total = atuElementGroupService.updateByPrimaryKey(tempTree);
    //同步修改所有子级节点
    total+= atuElementGroupService.updateChildNamePath(childTrees, namePathNew.toString());
    return total;
  }

  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer deleteByPK(String uuid)
  {
    AtuElementGroup byPrimaryKey = atuElementGroupService.findByPrimaryKey(uuid);
    if (null == byPrimaryKey) {
      return 0;
    }
    //判断节点是否为叶子结点
    if (ScriptConstant.STR_ZERO.equals(byPrimaryKey.getIsLeaf())) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_DEL_DIR_EXISTS);
    }
    //判断所选目录是否有脚本
    AtuElementInfo tempElement = new AtuElementInfo();
    tempElement.setGroupId(uuid);
    tempElement.setIsDeleted(ScriptConstant.STR_ZERO);
    List<AtuElementInfo> elementInfos = atuElementInfoService.query(tempElement);
    if (!CollectionUtils.isEmpty(elementInfos)) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_DEL_DATA_EXISTS);
    }
    //删除数据库数据
    int res = atuElementGroupService.deleteByPrimaryKey(uuid);
    //查询父目录是否含有其他子目录
    AtuElementGroup childTree = new AtuElementGroup();
    childTree.setPid(byPrimaryKey.getPid());
    List<AtuElementGroup> childrenNodes = atuElementGroupService.query(childTree);
    //无子目录时需改为叶子结点
    if (CollectionUtils.isEmpty(childrenNodes)) {
      AtuElementGroup newParent = new AtuElementGroup();
      newParent.setId(byPrimaryKey.getPid());
      newParent.setIsLeaf(ScriptConstant.STR_ONE);
      newParent.setUpdatedBy(NKSecurityContext.getUserId());
      newParent.setUpdatedTime(new Date());
      atuElementGroupService.updateByPrimaryKey(newParent);
    }
    return res;
  }

  @Override
  @DatabaseReadOnly
  public List<AtuElementGroupDetailDto> queryElementTreeByParentId(AtuElementGroupQueryDto dto) {
    List<AtuElementGroupDetailDto> result = new ArrayList<>();
    //根据父节点查询所有子级节点
    if(!StringUtils.isEmpty(dto.getPid())){
      AtuElementGroupQueryDto elementGroupQueryDto = new AtuElementGroupQueryDto();
      elementGroupQueryDto.setProjectIds(dto.getProjectIds());
      elementGroupQueryDto.setPid(dto.getPid());
      //租户隔离
      elementGroupQueryDto.setTenantId(NKSecurityContext.getTenantId());
      result = atuElementGroupService.selectElementTree(elementGroupQueryDto);
      for (AtuElementGroupDetailDto detailDto : result) {
        detailDto.setIdx(detailDto.getSeq());
      }
    }else{
      //最外层为系统信息数组
      for (String projectId : dto.getProjectIds()) {
        AtuElementGroupDetailDto detailDto = new AtuElementGroupDetailDto();
        detailDto.setId(projectId);
        detailDto.setPid("");
        detailDto.setProjectId(projectId);
        detailDto.setGroupName(entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM.name(),projectId));
        detailDto.setIsLeaf(ScriptConstant.STR_ZERO);
        detailDto.setLevelNo(0);
        result.add(detailDto);
      }
    }
    return result;
  }

  @Override
  @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public Integer moveElementTree(AtuElementGroupMoveDto dto) {
    AtuElementGroup oldNode = atuElementGroupService.findByPrimaryKey(dto.getId());
    AtuElementGroup tempTree = new AtuElementGroup();
    if(ScriptConstant.STR_ZERO.equals(dto.getTargetId())) {
      tempTree.setId(ScriptConstant.STR_ZERO);
      tempTree.setLevelNo(0);
      tempTree.setIsLeaf(ScriptConstant.STR_ZERO);
      tempTree.setNamePath("");
    }else {
      tempTree = atuElementGroupService.findByPrimaryKey(dto.getTargetId());
    }
    //判断拖拽后是否层数超过10级
    Integer targetLevel = tempTree.getLevelNo();
    AtuElementGroup queryLevel = new AtuElementGroup();
    queryLevel.setId(oldNode.getId());
    queryLevel.setProjectId(oldNode.getProjectId());
    int maxLevel = atuElementGroupService.countMaxLevelNo(queryLevel);
    int myMaxLevel = maxLevel - oldNode.getLevelNo() + 1;
    if ((targetLevel + myMaxLevel) > 10) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_LEVEL_LIMIT);
    }
    int levelNo = tempTree.getLevelNo()-oldNode.getLevelNo()+1;
    if(dto.getOrderSeq()==null) {
      dto.setOrderSeq(0);
    }
    //校验是否同名
    AtuElementGroup check = new AtuElementGroup();
    check.setGroupName(oldNode.getGroupName());
    check.setPid(tempTree.getId());
    check.setProjectId(dto.getProjectId());
    List<AtuElementGroup> sameElements = atuElementGroupService.query(check);
    if(!CollectionUtils.isEmpty(sameElements) && !oldNode.getPid().equals(tempTree.getId())){
      throw new PlatformRuntimeException(ElementLibraryError.TREE_NAME_EXISTS);
    }
    //校验是否目标节点为非叶子节点并存在用例
    AtuElementInfo exitElement = new AtuElementInfo();
    exitElement.setProjectId(dto.getProjectId());
    exitElement.setGroupId(tempTree.getId());
    exitElement.setIsDeleted(ScriptConstant.STR_ZERO);
    if (ScriptConstant.STR_ONE.equals(tempTree.getIsLeaf()) && !CollectionUtils.isEmpty(atuElementInfoService.query(exitElement))) {
      throw new PlatformRuntimeException(ElementLibraryError.TREE_MOVE_DATA_EXISTS);
    }
    //更新节点以及子节点
    AtuElementGroup treeUp = new AtuElementGroup();
    treeUp.setId(oldNode.getId());
    treeUp.setPid(tempTree.getId());
    treeUp.setTenantId(oldNode.getTenantId());
    atuElementGroupService.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());
    //更改顺序号
    AtuElementGroupMoveDto childUp = new AtuElementGroupMoveDto();
    childUp.setOrderSeq(dto.getOrderSeq());
    childUp.setProjectId(dto.getProjectId());
    atuBusinessNoApiService.genBusinessNo(dto.getProjectId(),ScriptConstant.ATU_ELEMENT_TREE,1L);
    atuElementGroupService.updateSeqByMove(childUp);
    //替换移动节点的排序号
    AtuElementGroup treeUpOrder = new AtuElementGroup();
    treeUpOrder.setId(oldNode.getId());
    treeUpOrder.setSeq(dto.getOrderSeq()+1);
    treeUpOrder.setTenantId(oldNode.getTenantId());
    atuElementGroupService.updateByPrimaryKey(treeUpOrder);
    //子节点更改路径
    AtuElementGroup child = new AtuElementGroup();
    BeanUtils.copyProperties(childUp,child);
    child.setProjectId(oldNode.getProjectId());
    child.setNamePath(oldNode.getNamePath());
    child.setIdPath(oldNode.getIdPath());
    child.setLevelNo(levelNo);
    atuElementGroupService.updateChildNamePath(child,treeUp.getNamePath());
    atuElementGroupService.updateChildIdPath(child,treeUp.getIdPath());
    //修改原父节点以及现父节点的叶子节点标识
    if(ScriptConstant.STR_ONE.equals(tempTree.getIsLeaf())){
      AtuElementGroup itemTreeUp = new AtuElementGroup();
      itemTreeUp.setId(tempTree.getId());
      itemTreeUp.setIsLeaf(ScriptConstant.STR_ZERO);
      itemTreeUp.setTenantId(tempTree.getTenantId());
      atuElementGroupService.updateByPrimaryKey(itemTreeUp);
    }
    AtuElementGroup oldFaCount = new AtuElementGroup();
    oldFaCount.setPid(oldNode.getPid());
    if(CollectionUtils.isEmpty(atuElementGroupService.query(oldFaCount))){
      AtuElementGroup oldTreeUp = new AtuElementGroup();
      oldTreeUp.setId(oldNode.getPid());
      oldTreeUp.setIsLeaf(ScriptConstant.STR_ONE);
      atuElementGroupService.updateByPrimaryKey(oldTreeUp);
    }
    return 1;
  }

  @Override
  public List<AtuElementGroupDetailDto> queryElementTreeByName(AtuElementGroupQueryDto dto) {
    AtuElementGroupQueryDto queryDto = new AtuElementGroupQueryDto();
    queryDto.setGroupName(dto.getGroupName());
    queryDto.setProjectIds(dto.getProjectIds());
    queryDto.setTenantId(NKSecurityContext.getTenantId());
    List<AtuElementGroupDetailDto> elementTreeList = atuElementGroupService.selectElementTree(queryDto);
    if (elementTreeList.size()<1) {
      //无数据时多系统也需再包装一层系统级信息
      if(dto.isMoreProject()) {
        return setProjectTop(elementTreeList, dto.getProjectIds(), dto.getGroupName());
      }else {
        return elementTreeList;
      }
    }
    Map<String, AtuElementGroupDetailDto> treeMap = getTreeMap(elementTreeList);
    List<AtuElementGroupDetailDto> detailDtos = new ArrayList<>();
    for (String treeId : treeMap.keySet()) {
      detailDtos.add(treeMap.get(treeId));
    }
    List<AtuElementGroupDetailDto> treeList = getTreeList(detailDtos);
    List<AtuElementGroupDetailDto> resList = treeList.stream().sorted(Comparator.comparing(AtuElementGroupDetailDto::getSeq)).collect(Collectors.toList());
    //多系统包装最外层系统信息
    if(dto.isMoreProject()){
      return setProjectTop(resList,dto.getProjectIds(),dto.getGroupName());
    }
    return resList;
  }

  private Map<String, AtuElementGroupDetailDto> getTreeMap(List<AtuElementGroupDetailDto> allList) {
    Map<String, AtuElementGroupDetailDto> treeMap = new HashMap<>();
    List<String> list = new ArrayList<>();
    //查询包含的树节点id
    for (int i = 0; i < allList.size(); i++) {
      AtuElementGroupDetailDto 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<AtuElementGroup> treeList = atuElementGroupService.queryByIds(list);
    for (AtuElementGroup elementTree : treeList) {
      AtuElementGroupDetailDto detailDto = new AtuElementGroupDetailDto();
      BeanUtils.copyProperties(elementTree,detailDto);
      detailDto.setIdx(detailDto.getSeq());
      if (!treeMap.containsKey(elementTree.getId())) {
        treeMap.put(elementTree.getId(),detailDto);
      }
    }
    return treeMap;
  }

  private List<AtuElementGroupDetailDto> getTreeList(List<AtuElementGroupDetailDto> dtoList) {
    List<AtuElementGroupDetailDto> treeList = new ArrayList<>();
    for (int i = 0; i < dtoList.size(); i++) {
      AtuElementGroupDetailDto tree = dtoList.get(i);
      //根节点生成对应树列表
      if(ScriptConstant.STR_ZERO.equals(tree.getPid())){
        getSonTree(tree,dtoList);
        treeList.add(tree);
      }
    }
    return treeList;
  }

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

  private List<AtuElementGroupDetailDto> setProjectTop(List<AtuElementGroupDetailDto> reList,List<String> projectIds,String name){
    List<AtuElementGroupDetailDto> result = new ArrayList<>();
    Map<String,List<AtuElementGroupDetailDto>> tool = new HashMap<>();
    for (AtuElementGroupDetailDto oneTree : reList) {
      if (tool.containsKey(oneTree.getProjectId())){
        tool.get(oneTree.getProjectId()).add(oneTree);
      }else{
        List<AtuElementGroupDetailDto> 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(name)|| (StringUtils.hasText(name) && projectName.contains(name))){
        AtuElementGroupDetailDto one = new AtuElementGroupDetailDto();
        one.setId(projectId);
        one.setIsLeaf(ScriptConstant.STR_ZERO);
        one.setGroupName(projectName);
        one.setLevelNo(0);
        one.setPid("");
        one.setProjectId(projectId);
        one.setChildren(tool.get(projectId));
        //无子树则为叶子结点
        if (CollectionUtils.isEmpty(one.getChildren())) {
          one.setIsLeaf(ScriptConstant.STR_ONE);
        }
        result.add(one);
      }
    }
    return result;
  }
}
