package com.hdkj.lt.bf.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.exception.BusinessException;
import com.hdkj.lt.bf.entity.FeederBase;
import com.hdkj.lt.bf.entity.dto.*;
import com.hdkj.lt.bf.entity.vo.StruTreeVO;
import com.hdkj.lt.bf.mapper.FeederBaseMapper;
import com.hdkj.lt.bf.service.StruService;
import com.hdkj.lt.core.sys.dao.FhzgDistMappingFileMapper;
import com.hdkj.lt.core.sys.dao.SysStruMapper;
import com.hdkj.lt.core.sys.model.dto.FeederCacheDTO;
import com.hdkj.lt.core.sys.model.dto.FhzgDistMappingFileDTO;
import com.hdkj.lt.core.sys.model.dto.StruTreeCacheDTO;
import com.hdkj.lt.core.sys.model.po.SysStru;
import com.hdkj.lt.core.sys.service.DwdShbDsFeederBaseService;
import com.hdkj.lt.core.sys.service.ISysStruService;
import com.hdkj.lt.utils.cache.RedisRepository;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

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


/**
 * @author luorui
 * @date 2025/5/12 10:43
 */
@Service
@Slf4j
public class StruServiceImpl implements StruService {


    @Autowired
    FeederBaseMapper feederBaseMapper;

    @Autowired
    SysStruMapper sysStruMapper;

    @Autowired
    FhzgDistMappingFileMapper fhzgDistMappingFileMapper;

    @Autowired
    ISysStruService sysStruService;

    @Autowired
    RedisRepository redisRepository;
    @Autowired
    DwdShbDsFeederBaseService dwdShbDsFeederBaseService;

    private static final String PROVINCE = "1";//省
    private static final String CITY = "4";//市
    private static final String COUNTY = "5";//区县
    private static final String FEEDER = "0";//线路
    private static final String STATION = "10";//变电站

    private static final Long PROVINCE_STRU_ID = 14015L;

    /**
     * @author luorui
     * @date 2025/5/12 11:48
     * @discription 根据登录用户所属的组织机构，查询出对应的三级信息。根据用户所属单位类型返回结果集合不一致.
     * 示例：
     * 用户为“湖北”，返回 地市-区县-线路 n-n-n
     * 用户为“A地市”，返回 A地市-区县-线路 1-n-n
     * 用户为“A区县”，返回 A地市-A区县-线路 1-1-n
     * <p>
     * 1.根据用户登录信息中的所属组织机构，查询对应组织机构详细信息
     * 2.根据用户的所属组织机构信息类型判断，a:如果是省-则向下查询两级数据（地市，区县），b:如果是地市则根据地市id查询对应的下级区县，c:如果是区县，则向上查询出对应地市
     * 3.根据区县编码查询出所以线路
     * 4.查询线路对应的 线路图信息
     * 5.组装返回数据
     **/
    @Override
    @Cacheable(value = RedisKeyConstants.STRU_TREE_RESP_DTO, key = "#struId", sync = true)
    public StruTreeRespDTO getStruTree(Long struId) {
        Long currentStruId;
        if (Objects.isNull(struId)) {
            //todo 获取用户的组织机构编码
            LoginUser loginUser = SecurityUtils.getLoginUser();
            currentStruId = loginUser.getSysUser().getDeptId();
            log.info("获取用户所属组织,userId:{},departmentId:{}", SecurityUtils.getUserId(), currentStruId);
        } else {
            currentStruId = struId;
        }
        //1.查询当前所在组织机构
        SysStru currentStru = sysStruMapper.getStruById(currentStruId);
        if (Objects.isNull(currentStru)) {
            throw new BusinessException("当前用户组织信息为空！");
        }
        String currentType = currentStru.getStruType();
        List<StruDTO> departmentList = new ArrayList<>();//申明返回结果对象集合
        StruTreeRespDTO struTreeRespDTO = new StruTreeRespDTO();
        struTreeRespDTO.setDepartmentList(departmentList);
        switch (currentType) {
            case PROVINCE:
                // a:如果是省-则向下查询两级数据（地市，区县）
                //3.构建返回参数
                buildProvince(departmentList, currentStruId);
                break;
            case CITY:
                // b:如果是地市则根据地市id查询对应的下级区县
                //3.构建返回参数
                buildCity(departmentList, currentStru);
                break;
            case COUNTY:
                // c:如果是区县，则向上查询出对应地市
                //3.构建返回参数
                buildCounty(departmentList, currentStru);
                break;
            default:
                log.error("当前用户所属组织类型不正确!");
                throw new BusinessException("当前用户所属组织类型不正确！");
        }
        return struTreeRespDTO;
    }

    /**
     * @author luorui
     * @date 2025/6/25 17:01
     * @discription 从缓存中查询组织树
     * @discription 根据登录用户所属的组织机构，查询出对应的三级信息。根据用户所属单位类型返回结果集合不一致.
     * 示例：
     * 用户为“湖北”，返回 地市-区县-线路 n-n-n
     * 用户为“A地市”，返回 A地市-区县-线路 1-n-n
     * 用户为“A区县”，返回 A地市-A区县-线路 1-1-n
     * <p>
     **/
    @Override
    public StruTreeRespDTO getStruTreeFromCache(Long struId) {
        Long currentStruId;
        if (Objects.isNull(struId)) {
            //todo 获取用户的组织机构编码
            LoginUser loginUser = SecurityUtils.getLoginUser();
            currentStruId = loginUser.getSysUser().getDeptId();
            log.info("获取用户所属组织,userId:{},departmentId:{}", SecurityUtils.getUserId(), currentStruId);
        } else {
            currentStruId = struId;
        }
        //1.查询当前所在组织机构树
        StruTreeCacheDTO struTreeByCache = sysStruService.getStruTreeByCache(currentStruId);
        if (Objects.isNull(struTreeByCache)) {
            throw new BusinessException("组织树缓存查询为空！struId:" + struId);
        }
        //2.获取线路缓存
        Map<String, Object> cacheMap = dwdShbDsFeederBaseService.getAllFeederCache();
        if (CollUtil.isEmpty(cacheMap)) {
            throw new BusinessException("线路缓存信息为空！");
        }
        Map<String, FeederCacheDTO> resultMap = cacheMap.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> (FeederCacheDTO) e.getValue()));

        //K->区县的 ISC组织机构ID ,V->线路信息集合
        Map<String, List<FeederCacheDTO>> maintOrgFeederMap = resultMap.values().parallelStream().filter(e -> StrUtil.isNotBlank(e.getMaintOrg())).collect(Collectors.groupingByConcurrent((FeederCacheDTO::getMaintOrg)));

        //将线路信息再按照变压器分组，K->区县ISC组织机构ID,V->变电站信息集合，（变电站信息保护信息信息）
        Map<String, List<StationDTO>> stationFeedMap = maintOrgFeederMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
                entry -> {
                    //对同一个区县下的线路按 变电站分组, 过滤掉变电站信息为空的数据
                    Map<String, List<FeederCacheDTO>> stationMap = entry.getValue().stream().filter(e -> StrUtil.isNotBlank(e.getStartStation())).collect(Collectors.groupingBy(FeederCacheDTO::getStartStation));
                    //将数据构建成  变电站数据
                    return stationMap.entrySet().stream().map(e -> StationDTO.builder()
                            .station(e.getKey())
                            .name(e.getValue().get(0).getStartStationName())
                            .type(STATION)
                            .children(
                                    e.getValue().stream().map(f -> FeederDTO.builder()
                                            .type(FEEDER)
                                            .name(f.getName())
                                            .psrId(f.getPsrId())
                                            .fileList(f.getFileList())
                                            .build()).collect(Collectors.toList())
                            ).build()).collect(Collectors.toList());
                }
        ));
        String currentType = struTreeByCache.getStruType();
        List<StruDTO> departmentList = new ArrayList<>();//申明返回结果对象集合
        StruTreeRespDTO struTreeRespDTO = new StruTreeRespDTO();
        struTreeRespDTO.setDepartmentList(departmentList);
        switch (currentType) {
            case PROVINCE:
                // a:如果是省-则向下查询两级数据（地市，区县）
                //3.构建返回参数
                buildProvinceByCache(departmentList, struTreeByCache, stationFeedMap);
                break;
            case CITY:
                // b:如果是地市则根据地市id查询对应的下级区县
                //3.构建返回参数
                buildCityByCache(departmentList, struTreeByCache, stationFeedMap);
                break;
            case COUNTY:
                // c:如果是区县，则向上查询出对应地市
                //3.构建返回参数
                buildCountyByCache(departmentList, struTreeByCache, stationFeedMap);
                break;
            default:
                log.error("当前用户所属组织类型不正确!");
                throw new BusinessException("当前用户所属组织类型不正确！");
        }
        return struTreeRespDTO;
    }

    //省份的数据构建
    private void buildProvinceByCache(List<StruDTO> departmentList, StruTreeCacheDTO struTreeByCache, Map<String, List<StationDTO>> stationFeedMap) {
        StruDTO struDTO = cloneTree(struTreeByCache, stationFeedMap);
        //省份的话，取 市->区县->线路，去除根节点
        departmentList.addAll(struDTO.getChildren());
    }

    //市的数据构建
    private void buildCityByCache(List<StruDTO> departmentList, StruTreeCacheDTO struTreeByCache, Map<String, List<StationDTO>> stationFeedMap) {
        StruDTO struDTO = cloneTree(struTreeByCache, stationFeedMap);
        //市的话直接返回重构树
        departmentList.add(struDTO);
    }

    //区县的数据构建，向上找到他的父节点
    private void buildCountyByCache(List<StruDTO> departmentList, StruTreeCacheDTO struTreeByCache, Map<String, List<StationDTO>> stationFeedMap) {
        //构建子节点
        StruDTO childDTO = cloneTree(struTreeByCache, stationFeedMap);
        //构建父节点
        StruDTO parentDto = new StruDTO();
        Long parentId = struTreeByCache.getParentId();
        StruTreeCacheDTO parentStruTreeByCache;
        if (parentId != null) {
            parentStruTreeByCache = sysStruService.getStruTreeByCache(parentId);
            if (parentStruTreeByCache != null) {
                //构建父节点属性
                parentDto = convertNode(parentStruTreeByCache);
            }
        } else {
            log.info("区县的上级节点缓存为空");
        }
        List<StruDTO> children = new ArrayList<>();
        children.add(childDTO);
        parentDto.setChildren(children);
        departmentList.add(parentDto);
    }

    //复制树结构转换成目标结构类型，递归遍历每个节点，拷贝属性，如果是区县则添加上变电站、线路信息
    private StruDTO cloneTree(StruTreeCacheDTO originalRoot, Map<String, List<StationDTO>> stationFeedMap) {
        if (originalRoot == null) {
            return null;
        }
        //创建新的节点
        StruDTO nowRoot = convertNode(originalRoot);

        if (StrUtil.equals(originalRoot.getStruType(), COUNTY)) {
            //如果节点是区县的话，将线路节点添加到区县子节点中
            List<StationDTO> stationDTOS = stationFeedMap.get(originalRoot.getIscOrgId());
            nowRoot.setChildren(stationDTOS == null ? new ArrayList<>() : stationDTOS);
        } else {
            //如果节点是区县的话 递归复制子节点，如果节点是区县终止递归
            if (originalRoot.getChildren() != null) {
                for (StruTreeCacheDTO child : originalRoot.getChildren()) {
                    nowRoot.getChildren().add(cloneTree(child, stationFeedMap));
                }
            }
        }
        return nowRoot;
    }

    //复制节点属性
    private StruDTO convertNode(StruTreeCacheDTO originalRoot) {
        StruDTO<StruDTO> nowRoot = new StruDTO<>();
        nowRoot.setName(originalRoot.getName());
        nowRoot.setStruId(originalRoot.getStruId());
        nowRoot.setType(originalRoot.getStruType());
        nowRoot.setParentId(originalRoot.getParentId());
        nowRoot.setChildren(new ArrayList<>());
        return nowRoot;
    }


    /**
     * @author luorui
     * @date 2025/5/13 11:49
     * @discription 当前用户为省份用户时，组装查询数据逻辑
     **/
    private void buildProvince(List<StruDTO> departmentList, Long currentStruId) {
        List<Long> struIdListProvince = new ArrayList<>();
        struIdListProvince.add(currentStruId);
        List<SysStru> cityStruList = sysStruMapper.getStruByParentIds(struIdListProvince);//地市集合
        if (CollUtil.isNotEmpty(cityStruList)) {
            List<StruDTO> cityList = caseSturModule(cityStruList);
            departmentList.addAll(cityList);//第一层城市数据
            List<Long> struIdListCity = cityList.stream().map(StruDTO::getStruId).collect(Collectors.toList());
            List<SysStru> countyStruList = sysStruMapper.getStruByParentIds(struIdListCity);//查询区县集合
            if (CollUtil.isNotEmpty(countyStruList)) {
                List<StruDTO> countyList = caseSturModule(countyStruList);
                Map<Long, List<StruDTO>> struMapCounty = countyList.stream().collect(Collectors.groupingBy(StruDTO::getParentId));
                cityList.forEach(e -> {
                    e.setChildren(struMapCounty.get(e.getStruId())); //将区县数据根据parentId分组，赋值回地市的子节点
                });
                List<Long> struIdList_county = countyStruList.stream().map(SysStru::getStruId).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(struIdList_county)) {
                    List<FeederBase> feederBaseListResult = feederBaseMapper.getFeederBaseByStruId(struIdList_county);//查询区县下线路
                    //查询的线路数据模型转换成返回前段的数据模型
                    if (CollUtil.isNotEmpty(feederBaseListResult)) {
                        List<FeederDTO> feederList = caseFeederModule(feederBaseListResult);
                        Map<Long, List<FeederDTO>> struMap_feeder = feederList.stream().collect(Collectors.groupingBy(FeederDTO::getStruId));
                        countyList.forEach(e -> {
                            e.setChildren(struMap_feeder.get(e.getStruId()));//将线路按照struId分组赋值回,区县子节点
                        });
                    }
                }
            }
        }
    }

    /**
     * @author luorui
     * @date 2025/5/13 11:49
     * @discription 当前用户为地市用户时，组装查询数据逻辑
     **/
    private void buildCity(List<StruDTO> departmentList, SysStru currentStru) {
        StruDTO cityStruDTO = new StruDTO();
        departmentList.add(cityStruDTO);
        cityStruDTO.setType(currentStru.getStruType());
        cityStruDTO.setName(currentStru.getName());
        cityStruDTO.setStruId(currentStru.getStruId());
        //查询下级区县信息集合
        List<Long> struIdList_city = new ArrayList<>();
        struIdList_city.add(currentStru.getStruId());
        List<SysStru> countyStruList = sysStruMapper.getStruByParentIds(struIdList_city);//区县集合
        if (CollUtil.isNotEmpty(countyStruList)) {
            List<StruDTO> children_county = caseSturModule(countyStruList);
            cityStruDTO.setChildren(children_county);
            //查询 区县下线路集合
            List<FeederBase> feederBaseListResult = new ArrayList<>();
            List<Long> struIdList_county = countyStruList.stream().map(SysStru::getStruId).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(struIdList_county)) {
                feederBaseListResult = feederBaseMapper.getFeederBaseByStruId(struIdList_county);//查询区县下线路
            }
            List<FeederDTO> feederList = new ArrayList<>();
            //查询的线路数据模型转换成返回前段的数据模型
            if (CollUtil.isNotEmpty(feederBaseListResult)) {
                feederList = caseFeederModule(feederBaseListResult);
            }
            //将线路按照struId分组赋值回,区县子节点
            Map<Long, List<FeederDTO>> struMap = feederList.stream().collect(Collectors.groupingBy(FeederDTO::getStruId));
            children_county.forEach(e -> {
                e.setChildren(struMap.get(e.getStruId()));
            });
        }
    }


    /**
     * @author luorui
     * @date 2025/5/13 11:49
     * @discription 当前用户为区县用户时，组装查询数据逻辑
     **/
    private void buildCounty(List<StruDTO> departmentList, SysStru currentStru) {
        StruDTO cityStruDTO = new StruDTO();
        departmentList.add(cityStruDTO);
        //查询上级地市,赋值地市
        SysStru parentStru = sysStruMapper.getStruByChildId(currentStru.getStruId());
        cityStruDTO.setType(parentStru.getStruType());
        cityStruDTO.setName(parentStru.getName());
        cityStruDTO.setStruId(parentStru.getStruId());
        //赋值区县
        StruDTO countyStruDTO = new StruDTO();
        countyStruDTO.setType(currentStru.getStruType());
        countyStruDTO.setName(currentStru.getName());
        countyStruDTO.setStruId(currentStru.getStruId());
        List<StruDTO> countyList = new ArrayList<>();
        countyList.add(countyStruDTO);
        cityStruDTO.setChildren(countyList);
        //赋值区县下线路，区县数据只有一条
        List<Long> struIdList = new ArrayList<>();
        struIdList.add(currentStru.getStruId());
        List<FeederBase> feederBaseList = feederBaseMapper.getFeederBaseByStruId(struIdList);//查询区县下线路
        if (CollUtil.isNotEmpty(feederBaseList)) {
            List<FeederDTO> feederList = caseFeederModule(feederBaseList);
            countyStruDTO.setChildren(feederList);//设置线路
        }
    }

    /**
     * @author luorui
     * @date 2025/5/12 18:09
     * @discription 将查询的组织机构数据模型转换成，返回对象模型
     **/
    private List<StruDTO> caseSturModule(List<SysStru> countyStruList) {
        List<StruDTO> struDTOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(countyStruList)) {
            countyStruList.forEach(e -> {
                StruDTO struDTO = new StruDTO();
                struDTO.setName(e.getName());
                struDTO.setStruId(e.getStruId());
                struDTO.setType(e.getStruType());
                struDTO.setParentId(e.getParentId());
                struDTOList.add(struDTO);
            });
        }
        return struDTOList;
    }

    /**
     * @author luorui
     * @date 2025/5/12 18:09
     * @discription 将查询的线路数据模型转换成，返回对象模型
     **/
    private List<FeederDTO> caseFeederModule(List<FeederBase> feederBaseList) {
        List<String> psrIdList = feederBaseList.stream().map(FeederBase::getPsrId).collect(Collectors.toList());
        List<FhzgDistMappingFileDTO> fhzgDistMappingFileDTOList = fhzgDistMappingFileMapper.getMappingFileById(psrIdList);
        //K->psrId V->图形文件集合
        Map<String, List<FhzgDistMappingFileDTO>> psrIdMap = fhzgDistMappingFileDTOList.stream().collect(Collectors.groupingBy(FhzgDistMappingFileDTO::getLineId));
        List<FeederDTO> feederList = new ArrayList<>();
        if (CollUtil.isNotEmpty(feederBaseList)) {
            feederBaseList.forEach(e -> {
                FeederDTO feederStruDTO = new FeederDTO();
                feederStruDTO.setType(FEEDER);
                feederStruDTO.setStruId(e.getStruId());
                feederStruDTO.setPsrId(e.getPsrId());
                feederStruDTO.setName(e.getName());
                feederStruDTO.setFileList(psrIdMap.get(e.getPsrId()));
                feederList.add(feederStruDTO);
            });
        }
        return feederList;
    }


    /**
     * @author luorui
     * @date 2025/5/13 11:49
     * @discription 根据struId 查询地市列表
     **/
    @Override
    public List<CityDTO> getCityListId(Long struId) {
        Long currentStruId;
        if (Objects.isNull(struId)) {
            //todo 获取用户的组织机构编码
            LoginUser loginUser = SecurityUtils.getLoginUser();
            currentStruId = loginUser.getSysUser().getDeptId();
            log.info("获取用户所属组织,userId:{},departmentId:{}", SecurityUtils.getUserId(), currentStruId);
        } else {
            currentStruId = struId;
        }
        SysStru currentStru = sysStruMapper.getStruById(currentStruId);
        String currentType = currentStru.getStruType();
        List<CityDTO> cityDTOList = new ArrayList<>();
        switch (currentType) {
            case PROVINCE:
                //查询城市列表
                List<Long> struIdList = new ArrayList<>();
                struIdList.add(currentStruId);
                List<SysStru> countyStruList = sysStruMapper.getStruByParentIds(struIdList);//地市集合
                if (CollUtil.isNotEmpty(countyStruList)) {
                    countyStruList.forEach(e -> {
                        CityDTO cityDTO = new CityDTO();
                        cityDTO.setName(e.getName());
                        cityDTO.setStruId(e.getStruId());
                        cityDTOList.add(cityDTO);
                    });
                }
                break;
            case CITY:
                CityDTO cityDTO = new CityDTO();
                cityDTO.setName(currentStru.getName());
                cityDTO.setStruId(currentStru.getStruId());
                cityDTOList.add(cityDTO);
                break;
            case COUNTY:
                //如果是区县，则查询上级，城市
                SysStru parentStru = sysStruMapper.getStruByChildId(currentStruId);
                CityDTO parentCityDTO = new CityDTO();
                parentCityDTO.setName(parentStru.getName());
                parentCityDTO.setStruId(parentStru.getStruId());
                cityDTOList.add(parentCityDTO);
                break;
            default:
                log.error("当前用户所属组织类型不正确!");
                throw new BusinessException("当前用户所属组织类型不正确！");
        }
        return cityDTOList;
    }

    /**
     * 查询省，市，区县的组织树（根据用户所属组织机构，从缓存中取）
     *
     * @param
     * @return
     */
    @Override
    public List<StruTreeVO> getStruList() {
        Long currentStruId;
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (null != loginUser) {
            currentStruId = loginUser.getSysUser().getDeptId();
            Optional.ofNullable(currentStruId).orElseThrow(() -> new BusinessException("用户所属组织机构信息为空"));
        } else {
            throw new BusinessException("请先登录");
        }
        return getStruTreeById(currentStruId);
    }

    /**
     * @author luorui
     * @date 2025/7/17 15:44
     * @discription 根据struId获取其下级所有区县id
     **/
    @Override
    public List<Long> getCountyCodeListByStruId(Long struId) {
        List<Long> result = new ArrayList<>();
        if (Objects.isNull(struId)) {
            return result;
        }
        StruTreeCacheDTO struTreeCacheDTO = sysStruService.getStruTreeByCache(struId);
        if (Objects.isNull(struTreeCacheDTO)) {
            return result;
        }
        String struType = struTreeCacheDTO.getStruType();
        switch (struType) {
            case PROVINCE:
                // 1.用户如果是省公司，获取所有市所有区县
                List<StruTreeCacheDTO> children = struTreeCacheDTO.getChildren();
                Optional.ofNullable(children).ifPresent(child -> {
                    List<Long> childrenStruIdList = child.stream().filter(e -> e != null && CollUtil.isNotEmpty(e.getChildren()))
                            .flatMap(grand -> grand.getChildren().stream())
                            .filter(grand -> !Objects.isNull(grand.getStruId()))
                            .map(StruTreeCacheDTO::getStruId)
                            .distinct().collect(Collectors.toList());
                    Optional.ofNullable(childrenStruIdList).ifPresent(childList -> result.addAll(childList));
                });
                break;
            case CITY:
                // 2.用户如果是市公司，获取市下级所有区县
                Optional.ofNullable(struTreeCacheDTO.getChildren()).ifPresent(e -> {
                    List<Long> childrenStruIdList = e.stream().filter(child -> !Objects.isNull(child.getStruId())).map(StruTreeCacheDTO::getStruId)
                            .distinct().collect(Collectors.toList());
                    Optional.ofNullable(childrenStruIdList).ifPresent(childList -> result.addAll(childList));
                });
                break;
            case COUNTY:
                // 3.用户如果是区县 只查询当前区县
                result.add(struId);
                break;
            default:
                log.error("当前组织类型不正确!");
                throw new BusinessException("当前组织类型不正确！");
        }
        return result;
    }

    /**
     * @author luorui
     * @date 2025/7/17 15:01
     * @discription 根据StruId 查询市->区县两级结构
     * 1.用户如果是省公司，返回->市-区县,
     * 2.用户如果是市公司，返回->所属市->区县，
     * 3.用户如果是区县，返回上级市->当前区县。
     **/
    private List<StruTreeVO> getStruTreeById(Long struId) {
        //查询所属机构的组织结构
        StruTreeCacheDTO struTreeCacheDTO = sysStruService.getStruTreeByCache(struId);
        List<StruTreeVO> result = new ArrayList<>();
        if (!Objects.isNull(struTreeCacheDTO)) {
            StruTreeVO struTreeVO = new StruTreeVO();
            BeanUtil.copyProperties(struTreeCacheDTO, struTreeVO);
            String currentType = struTreeVO.getStruType();
            //将获取的数据加工成前端需要的形式
            switch (currentType) {
                case PROVINCE:
                    // 1.用户如果是省公司，返回->市-区县,
                    List<StruTreeVO> childrenList = struTreeVO.getChildren();
                    if (CollUtil.isNotEmpty(childrenList)) {
                        result.add(struTreeVO);
                    } else {
                        log.info("省份下城市信息为空:{}", struId); //返回空数据
                    }
                    break;
                case CITY:
                    // 2.用户如果是市公司，返回->所属市->区县，
                    result.add(struTreeVO);
                    break;
                case COUNTY:
                    // 3.用户如果是区县，返回上级市->当前区县。
                    Long parentId = struTreeVO.getParentId();
                    if (!Objects.isNull(parentId)) {
                        StruTreeCacheDTO parentCacheDTO = sysStruService.getStruTreeByCache(parentId);
                        if (!Objects.isNull(parentCacheDTO)) {
                            StruTreeVO parentStruTreeVO = new StruTreeVO();
                            BeanUtil.copyProperties(parentCacheDTO, parentStruTreeVO);
                            parentStruTreeVO.setChildren(Lists.newArrayList(struTreeVO));
                            result.add(parentStruTreeVO);
                        } else {
                            log.info("未查询到组织机构数据struId:{}", parentId); //返回空数据
                        }
                    } else {
                        log.info("当前区县数据parentId为空struId:{}", struId); //返回空数据
                    }
                    break;
                default:
                    log.error("当前用户所属组织类型不正确!");
                    throw new BusinessException("当前用户所属组织类型不正确！");
            }
        } else {
            log.info("查询组织机构信息不存在struId:{}", struId);//返回空数据
        }
        removeSecondChildNode(result);
        setEmptyArr(result);//将子节点为空的数据去掉
        return result;
    }

    //删除第二层后组织机构数据
    private void removeSecondChildNode(List<StruTreeVO> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        for (StruTreeVO parent : list) {
            if (COUNTY.equals(parent.getStruType()) && parent.getChildren() != null) {
                parent.getChildren().clear();
            } else {
                removeSecondChildNode(parent.getChildren());
            }
        }
    }

    private void setEmptyArr(List<StruTreeVO> struTreeVOList) {
        if (struTreeVOList == null || struTreeVOList.isEmpty()) {
            return;
        }
        struTreeVOList.forEach(e -> {
            List<StruTreeVO> children = e.getChildren();
            if (children == null) {
                e.setChildren(new ArrayList<>());
            } else {
                setEmptyArr(children);
            }
        });
    }
}
