package com.ho.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import com.ho.business.entity.Station;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.util.CodeUtil;
import com.ho.common.tools.util.PageResult;
import com.ho.user.api.entity.SysDept;
import com.ho.user.api.entity.SysUser;
import com.ho.user.api.vo.req.DeptManagerReq;
import com.ho.user.api.vo.req.QueryDeptReqVO;
import com.ho.user.entity.IdControl;
import com.ho.user.feignclient.BusinessFeignClient;
import com.ho.user.feignclient.FlowFeignClient;
import com.ho.user.mapper.SysDeptMapper;
import com.ho.user.service.DeptService;
import com.ho.user.service.IdControlService;
import com.ho.user.service.PermissionService;
import com.ho.user.service.UserService;
import com.ho.user.vo.req.DeptAddReqVO;
import com.ho.user.vo.req.DeptQuery;
import com.ho.user.vo.req.DeptUpdateReqVO;
import com.ho.user.vo.req.UserPageUserByDeptReqVO;
import com.ho.user.vo.resp.DeptRespNodeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

/**
 * 机构部门服务类
 */
@Service
@Slf4j
public class DeptServiceImpl implements DeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private UserService userService;

    @Autowired
    Snowflake snowflake;

    @Autowired
    PermissionService permissionService;

    @Autowired
    private IdControlService idControlService;

    @Autowired
    private BusinessFeignClient businessFeignClient;

    @Autowired
    FlowFeignClient flowFeignClient;

    @Override
    @Transactional
    public SysDept addDept(DeptAddReqVO vo) {
        IdControl idControl = idControlService.selectCurrentVal(CommonConstant.DEPT_KEY);
        IdControl control = null;
        Integer currentVal = null;
        if (idControl == null) {
            control = new IdControl();
            control.setType(CommonConstant.DEPT_KEY);
            control.setCurrentVal(0);
            Integer insert = idControlService.insert(control);
            currentVal = control.getCurrentVal();
        } else {
            currentVal = idControl.getCurrentVal();
        }
        Integer result = ++currentVal;
        String deptCode = CodeUtil.getCode(CodeUtil.DEPT_PREFIX, String.valueOf(result), 6, "0");

        //同级部门不能重名 根据pid和name进行查询
        List<SysDept> dept = sysDeptMapper.selectByPidAndName(vo.getPid(), vo.getName(), null);
        if (!dept.isEmpty()) {
            throw new BusinessException(BaseResponseCode.PEER_EXISTENCE_SAME_NAME);
        }
        SysDept sysDept = new SysDept();
        BeanUtils.copyProperties(vo, sysDept);
        sysDept.setCreateTime(new Date());
        sysDept.setDeptNo(deptCode);
        int count = sysDeptMapper.insertSelective(sysDept);
        if (count != 1) {
            throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
        }
        //如果是顶级部门,还需要部署工作流
        if (CommonConstant.TOP_PARENT_ID.equals(sysDept.getPid())) {
            Integer groupId = sysDept.getId();
            DataResult deploymentResult = flowFeignClient.deploymentWorkflow(groupId);
            //判断服务是否成功
            boolean flag = deploymentResult.isSuccess();
            if (!flag) {
                throw new BusinessException(BaseResponseCode.PLAT_USER_DEPLOYMENT_ERROR);
            }
        }
        SysDept updateDept = new SysDept();
        updateDept.setId(sysDept.getId());
        if (CommonConstant.ZERO.equals(vo.getPid())) {
            updateDept.setGroupId(sysDept.getId());
        } else {
            SysDept topDept = getTopDept(sysDept.getId());
            updateDept.setGroupId(topDept.getId());
        }
        int i = sysDeptMapper.updateByPrimaryKeySelective(updateDept);
        if (i != 1) {
            throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
        }
        idControlService.updateCurrentVal(CommonConstant.DEPT_KEY, currentVal);

        return sysDept;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDept(DeptUpdateReqVO vo) {

        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(vo.getId());
        SysDept pidDept = sysDeptMapper.selectByPrimaryKey(vo.getPid());
        if (null == sysDept) {
            log.error("传入 的 id:{}不合法", vo.getId());
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        //同级部门不能重名 根据pid和name进行查询 在修改加id判断不是自己的那条数据
        List<SysDept> dept = sysDeptMapper.selectByPidAndName(vo.getPid(), vo.getName(), vo.getId());
        if (!dept.isEmpty()) {
            throw new BusinessException(BaseResponseCode.PEER_EXISTENCE_SAME_NAME);
        }
        if (!CommonConstant.ZERO.equals(vo.getPid()) || pidDept != null) {
            //判断是否为同一集团
            if (!sysDept.getGroupId().equals(pidDept.getGroupId())) {
                throw new BusinessException(BaseResponseCode.UPDATE_BELONGS_DEPT_NOT_SAME_GROUP);
            }
            //判断所修改的数据是否为顶级部门
            if (vo.getPid() != null) {
                if (CommonConstant.ZERO.equals(sysDept.getPid())) {
                    throw new BusinessException(BaseResponseCode.TOP_LEVEL_DEPARTMENTS_CANNOT_CHANGE_DEPARTMENTS);
                }
            }


            //根据id的pid往上面找
            List<SysDept> aboveDept = getAllToTop(sysDept, new ArrayList<>());
            aboveDept.removeIf(s -> {
                return s.getId().equals(sysDept.getId());
            });
            Map<Integer, List<SysDept>> collect = aboveDept.stream().collect(Collectors.groupingBy(SysDept::getId));

            if (collect.containsKey(vo.getPid())) {
                //说明是下改上
                SysDept update = new SysDept();
                BeanUtils.copyProperties(vo, update);
                update.setUpdateTime(new Date());
                update.setPid(vo.getPid());
                int count = sysDeptMapper.updateByPrimaryKeySelective(update);
                if (count != 1) {
                    throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
                }
            } else {
                //包含上改下，同系的上改下是改两个，旁系的上改下只需要呼唤
                //判断是否是旁系
                //判断这两个要修改的节点是否属于同一个分支，如果不是同一个分支下的，只修改一个即可.
                boolean pang = false;
                List<SysDept> deptParents = getParents(sysDept);
                List<SysDept> targetParents = getParents(pidDept);
                //两个集合倒序遍历，最后面的节点是顶级节点,如果有一个不相同，那么就是旁系
                //使用双指针遍历两个集合
                int deptIdx = deptParents.size() - 1;
                int targetIdx = targetParents.size() - 1;
                //遍历两个
                while (deptIdx >= 0 && targetIdx >= 0) {
                    //如果两个节点不一样说明是旁系
                    if (!deptParents.get(deptIdx).getId().equals(targetParents.get(targetIdx).getId())) {
                        pang = true;
                        break;
                    }
                    deptIdx--;
                    targetIdx--;
                }
                log.info("旁系:" + pang);

                // sourceFather和targetFather 相同时则修改两个 ，在加一个条件（判断同时修改的数据是否为上下相互紧邻着）
                //不同 时则修改一个
                //if (sourceFather.equals(targetFather) || sysDept.getId().equals(pidDept.getPid())) {
                //改为如下的判断
                if (!pang) {
                    SysDept paterUpdate = new SysDept();
                    BeanUtils.copyProperties(pidDept, paterUpdate);
                    paterUpdate.setUpdateTime(new Date());
                    if (CommonConstant.ZERO.equals(pidDept.getPid())) {
                        //出现问题：将更改的数据变换父级id时，由于父级的pid 为0，所以沿用自身的pid
                        paterUpdate.setPid(pidDept.getPid());
                    } else {
                        paterUpdate.setPid(sysDept.getPid());
                    }
                    sysDeptMapper.updateByPrimaryKeySelective(paterUpdate);
                    SysDept update = new SysDept();
                    BeanUtils.copyProperties(vo, update);
                    update.setUpdateTime(new Date());
                    update.setPid(vo.getPid());
                    int count = sysDeptMapper.updateByPrimaryKeySelective(update);
                    if (count != 1) {
                        throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
                    }
                } else {
                    SysDept update = new SysDept();
                    BeanUtils.copyProperties(vo, update);
                    update.setUpdateTime(new Date());
                    update.setPid(vo.getPid());
                    int count = sysDeptMapper.updateByPrimaryKeySelective(update);
                    if (count != 1) {
                        throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
                    }
                }

            }
        } else {
            SysDept update = new SysDept();
            BeanUtils.copyProperties(vo, update);
            update.setUpdateTime(new Date());
            update.setPid(vo.getPid());
            int count = sysDeptMapper.updateByPrimaryKeySelective(update);
            if (count != 1) {
                throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
            }
        }


        /**
         * 如果是修改禁用或者启用需要判断下级及其上级的状态
         */
        if (vo.getStatus() != null) {
            Integer status = vo.getStatus();
            //查询到父级部门
            SysDept pSysDept = sysDeptMapper.selectByPrimaryKey(sysDept.getPid());
            //启用
            if (status == 1) {
                //如果是顶级部门，就不需要进行判断父级状态
                if (!CommonConstant.TOP_PARENT_ID.equals(vo.getPid())) {
                    //判断父级部门的状态
                    if (pSysDept.getStatus() != 1) {
                        throw new BusinessException(BaseResponseCode.PARENT_DEPT_IS_DISABLE);
                    }
                }
            }
            //禁用
            else {
                //禁用部门就修改禁用该部门及以下子部门
                List<Integer> childIds = new ArrayList<>();
                List<SysDept> depts = new ArrayList<>();
                depts.add(sysDept);
                List<SysDept> subsidiaryDepts = getSubsidiaryDepts(depts, CommonConstant.DEPT_KEY);
                for (SysDept subsidiaryDept : subsidiaryDepts) {
                    childIds.add(subsidiaryDept.getId());
                }
                //在禁用前判断是否有人在该部门下，如果有无论用户为启用或禁用，部门都不能被禁用
                List<SysUser> list = userService.getUserListByDeptIds(childIds);
                if (!list.isEmpty()) {
                    throw new BusinessException(BaseResponseCode.NOT_PERMISSION_STATUS_DEPT);
                }
                childIds.stream().map(s -> {
                            SysDept childDept = new SysDept();
                            childDept.setId(s);
                            childDept.setStatus(0);
                            return childDept;
                        }
                ).forEach(s -> {
                    sysDeptMapper.updateByPrimaryKeySelective(s);
                });
            }
        }
        /**
         * 说明层级发生了变化
         */
/*        if (!StringUtils.isEmpty(vo.getPid()) && !vo.getPid().equals(sysDept.getPid())) {
            SysDept parent = sysDeptMapper.selectByPrimaryKey(vo.getPid());
            if (!vo.getPid().equals(CommonConstant.TOP_PARENT_ID) && null == parent) {
                log.error("传入 的 pid:{}不合法", vo.getId());
                throw new BusinessException(BaseResponseCode.DATA_ERROR);
            }
            SysDept oldParent = sysDeptMapper.selectByPrimaryKey(sysDept.getPid());
            String oldRelationCode;
            String newRelationCode;
            *//**
         * 根目录降到其他目录
         *//*
            if (sysDept.getPid().equals(CommonConstant.TOP_PARENT_ID)) {
                oldRelationCode = sysDept.getDeptNo();
                newRelationCode = parent.getRelationCode() + sysDept.getDeptNo();
            } else if (vo.getPid().equals(CommonConstant.TOP_PARENT_ID)) {//其他目录升级到跟目录
                oldRelationCode = sysDept.getRelationCode();
                newRelationCode = sysDept.getDeptNo();
            } else {
                oldRelationCode = oldParent.getRelationCode();
                newRelationCode = parent.getRelationCode();
            }
            sysDeptMapper.updateRelationCode(oldRelationCode, newRelationCode, sysDept.getRelationCode());
        }*/
    }

    //按从父级到子级的顺序返回节点集合
    private List<SysDept> getParents(SysDept sysDept) {
        List<SysDept> depts = new ArrayList<>();
        while (!CommonConstant.ZERO.equals(sysDept.getPid())) {
            depts.add(sysDept);
            sysDept = sysDeptMapper.selectByPrimaryKey(sysDept.getPid());
        }
        //执行到这肯定是顶级节点了
        depts.add(sysDept);
        //因为增加时是从子节点先增加的，所以返回的是一个倒序的集合
        return depts;
    }


    public List<SysDept> getAboveDept(SysDept sysDept) {
        List<SysDept> list = new ArrayList<>();
        SysDept dept = sysDeptMapper.selectByPrimaryKey(sysDept.getPid());
        list.add(dept);
        //查到顶级数据 ,返回
        if (CommonConstant.TOP_PARENT_ID.equals(dept.getPid())) {
            return list;
        }
        //递归查询pid那条数据
        return getAboveDept(dept);
    }

    @Override
    public SysDept detailInfo(Integer id) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(id);
        return sysDept;
    }

    @Override
    public void deleted(Integer id) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(id);
        //判断所删除的状态是否未启用状态，如果未启用状态则不能删除
        if (sysDept.getStatus().equals(CommonConstant.ONE)) {
            throw new BusinessException(BaseResponseCode.DEPT_CANNOT_NOT_STATE_DELETE);
        }
        //调用校验方法
        deleteCheck(id, sysDept);
        sysDept.setDeleted(0);
        sysDept.setUpdateTime(new Date());
        int count = sysDeptMapper.updateByPrimaryKeySelective(sysDept);
        if (count != 1) {
            throw new BusinessException(BaseResponseCode.OPERATION_ERRO);
        }
    }

    //删除校验
    private void deleteCheck(Integer id, SysDept sysDept) {
        if (null == sysDept) {
            log.error("传入 的 id:{}不合法", id);
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        List<Integer> deptIds = new ArrayList<>();
        List<SysDept> depts = new ArrayList<>();
        depts.add(sysDept);
        List<SysDept> subsidiaryDepts = getSubsidiaryDepts(depts, null);
        for (SysDept subsidiaryDept : subsidiaryDepts) {
            deptIds.add(subsidiaryDept.getId());
        }
        //List<Integer> deptIds = sysDeptMapper.selectChildIds(sysDept.getRelationCode());
        //        1.如果不是最末级部门(即:有子部门),提示'不是最末级部门,无法删除'
        if (deptIds.size() != 1) {
            throw new BusinessException(BaseResponseCode.NOT_LAST_DEPARTMENT);
        }
        QueryDeptReqVO vo = new QueryDeptReqVO();
        vo.setDeptId(id);
        DataResult<List<Station>> listDataResult = businessFeignClient.selectByDeptId(vo);

//        2.是最末级部门,如果有关联电站,提示'已有关联电站,无法删除'
        if (!listDataResult.getData().isEmpty() || !CommonConstant.ZERO.equals(listDataResult.getData().size())) {
            throw new BusinessException(BaseResponseCode.STATION_CANNOT_NOTDELE);
        }
//        3.是最末级部门,如果有关联人员(部门人员是非删除状态), 提示'已有关联人员,无法删除'
        List<SysUser> list = userService.getUserListByDeptIds(deptIds);
        if (!list.isEmpty()) {
            throw new BusinessException(BaseResponseCode.NOT_PERMISSION_DELETED_DEPT);
        }
    }


    @Override
    public List<DeptRespNodeVO> deptTreeList(DeptQuery query, String enableStatus) {
        if (query == null) {
            query = new DeptQuery();
        }
        //不是超级管理员,只能查到自己部门下的组织信息
        SimpleUser currentSimpleUser = permissionService.getCurrentSimpleUser();
        List<SysDept> list;
        SysDept sysDept;
        if (StringUtils.isEmpty(query.getDeptId())) {
            //超级管理员可以查看所有部门
            if (currentSimpleUser.getPlatSuper()) {
                list = sysDeptMapper.selectAll(query, enableStatus);
                //拿到每条数据的pidName
                for (SysDept dept : list) {
                    if (dept.getPid().equals(CommonConstant.TOP_PARENT_ID)) {
                        dept.setPidName(null);
                    } else {
                        SysDept pidNameDept = sysDeptMapper.selectByPid(dept.getPid());
                        dept.setPidName(pidNameDept.getName());
                    }

                }
                List<DeptRespNodeVO> treeForSuper = new ArrayList<>();
                //判断数据中有子级的数据的pid是否全为0
                //找到所有有孩子的数据，在判断这些数据pid是否全为0
                List<SysDept> fatherList = new ArrayList<>();
                //是儿子的数据集
                Map<Integer, SysDept> sunMap = new HashMap<>();

                for (SysDept dept : list) {
                    for (SysDept father : list) {
                        if (dept.getPid().equals(father.getId())) {
                            sunMap.put(dept.getId(), dept);
                            break;
                        }
                    }
                }
                //不是儿子的就是祖宗（查到的数据的最顶级）
                for (SysDept dept : list) {
                    if (!sunMap.containsKey(dept.getId())) {
                        fatherList.add(dept);
                    }
                }
                //判断fatherList中的pid是否全部等于0
                boolean isTopId = true;
                for (SysDept dept : fatherList) {
                    if (!CommonConstant.TOP_PARENT_ID.equals(dept.getPid())) {
                        isTopId = false;
                        break;
                    }
                }

                if (isTopId) {
                    treeForSuper = getTreeForSuper(list);
                } else {
                    treeForSuper = getTreeSuperDisable(list);
                }
                List<Integer> tree = new ArrayList<>();
                for (int i = 0; i < treeForSuper.size(); i++) {
                    DeptRespNodeVO deptRespNodeVO = treeForSuper.get(i);
                    for (DeptRespNodeVO vo : treeForSuper) {
                        if (deptRespNodeVO.getPid().equals(vo.getId())) {
                            tree.add(vo.getId());
                            break;
                        }
                    }
                }
                List<Integer> treeCollect = tree.stream().distinct().collect(Collectors.toList());
                List<DeptRespNodeVO> deptTree = new ArrayList<>();
                List<DeptRespNodeVO> sunList = new ArrayList<>();
                if (treeCollect.isEmpty() || CommonConstant.ZERO.equals(treeCollect.size())) {
                    deptTree = treeForSuper;
                } else {
                    //去除有父节点的数据
                    for (DeptRespNodeVO deptNode : treeForSuper) {
                        //找到不要的数据（父亲在的）
                        for (DeptRespNodeVO deptRespNodeVO : treeForSuper) {
                            if (deptNode.getId().equals(deptRespNodeVO.getPid())) {
                                sunList.add(deptRespNodeVO);
                            }
                        }
                    }
                    for (DeptRespNodeVO parent : treeForSuper) {
                        boolean needDelete = false;
                        for (DeptRespNodeVO sun : sunList) {
                            if (parent.getId().equals(sun.getId())) {
                                needDelete = true;
                                continue;
                            }
                        }
                        if (!needDelete) {
                            deptTree.add(parent);
                        }
                    }
                }
                return deptTree;
            } else {
                sysDept = sysDeptMapper.selectByPrimaryKey(currentSimpleUser.getDeptId());
                if (sysDept == null) {
                    throw new BusinessException(BaseResponseCode.DATA_ERROR);
                }
                //List<Integer> childIds = sysDeptMapper.selectChildIds(sysDept.getRelationCode());
                List<Integer> childIds = new ArrayList<>();
                List<SysDept> depts = new ArrayList<>();
                depts.add(sysDept);
                List<SysDept> subsidiaryDepts = getSubsidiaryDepts(depts, null);
                for (SysDept subsidiaryDept : subsidiaryDepts) {
                    childIds.add(subsidiaryDept.getId());
                }
                list = sysDeptMapper.selectChildByIds(childIds, query, enableStatus);
            }
        } else {
            sysDept = sysDeptMapper.selectByPrimaryKey(query.getDeptId());
            if (sysDept == null) {
                throw new BusinessException(BaseResponseCode.DATA_ERROR);
            }
            List<Integer> childIds = new ArrayList<>();
            List<SysDept> depts = new ArrayList<>();
            depts.add(sysDept);
            List<SysDept> subsidiaryDepts = getSubsidiaryDepts(depts, null);
            for (SysDept subsidiaryDept : subsidiaryDepts) {
                childIds.add(subsidiaryDept.getId());
            }
            //List<Integer> childIds = sysDeptMapper.selectChildIds(sysDept.getRelationCode());
            list = sysDeptMapper.selectAllByNotContainChild(childIds, query, enableStatus);
        }
        //拿到每条数据的pidName
        for (SysDept dept : list) {
            if (dept.getPid().equals(CommonConstant.TOP_PARENT_ID)) {
                dept.setPidName(null);
            } else {
                SysDept pidNameDept = sysDeptMapper.selectByPid(dept.getPid());
                dept.setPidName(pidNameDept.getName());
            }

        }

        //默认加一个顶级方便新增顶级部门
        /*DeptRespNodeVO respNodeVO = new DeptRespNodeVO();
        respNodeVO.setTitle("默认顶级部门");
        respNodeVO.setId("0");
        respNodeVO.setSpread(true);
        respNodeVO.setChildren(getTree(list));
        List<DeptRespNodeVO> result = new ArrayList<>();
        result.add(respNodeVO);*/
        //去除顶级机构
        List<DeptRespNodeVO> result = getTree(list);
        return result;
    }

    /**
     * 组织机构list 根据deptId
     *
     * @param deptId
     * @return
     */
    @Override
    public List<SysDept> depListByDeptId(Integer deptId) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        if (sysDept == null) {
            return new ArrayList<>();
        }
        //如果是子公司数据,需要再查询一下父公司,以便给pidName赋值
        String thePidName = "";
        Integer theId = null;
        if (!CommonConstant.TOP_PARENT_ID.equals(sysDept.getPid())) {
            SysDept theSysDept = sysDeptMapper.selectByPrimaryKey(sysDept.getPid());
            theId = sysDept.getId();
            thePidName = theSysDept.getName();
        }
        //子公司ids
        List<Integer> childIds = new ArrayList<>();
        List<SysDept> depts = new ArrayList<>();
        depts.add(sysDept);
        List<SysDept> subsidiaryDepts = getSubsidiaryDepts(depts, CommonConstant.DEPT_KEY);
        for (SysDept subsidiaryDept : subsidiaryDepts) {
            childIds.add(subsidiaryDept.getId());
        }
        //List<Integer> childIds = sysDeptMapper.selectChildIds(sysDept.getRelationCode());
        if (childIds.isEmpty()) {
            return new ArrayList<>();
        }
        //根据这个id查到所有机构
        DeptQuery query = new DeptQuery();
        String enableStatus = "enableStatus";
        List<SysDept> deptList = sysDeptMapper.selectChildByIds(childIds, query, enableStatus);
        dealPidName(deptList, theId, thePidName);
        return deptList;
    }

    //在集合中找到上级pidName
    private void dealPidName(List<SysDept> deptList, Integer theId, String thePidName) {
        for (SysDept dept : deptList) {
            //最顶层的部门无需赋值pidName
            if (CommonConstant.TOP_PARENT_ID.equals(dept.getPid())) {
                continue;
            }
            //那条记录自身赋值pidName
            if (dept.getId().equals(theId)) {
                dept.setPidName(thePidName);
            }
            //否则从集合中找到pid的那个名字
            for (SysDept innerDept : deptList) {
                if (dept.getPid().equals(innerDept.getId())) {
                    dept.setPidName(innerDept.getName());
                    break;
                }
            }
        }
    }


    //超级管理员的组织结构树
    private List<DeptRespNodeVO> getTreeForSuper(List<SysDept> all) {
        List<DeptRespNodeVO> list = new ArrayList<>();
        for (SysDept sysDept : all) {
            //
            if (CommonConstant.TOP_PARENT_ID.equals(sysDept.getPid())) {
                DeptRespNodeVO deptTree = new DeptRespNodeVO();
                BeanUtils.copyProperties(sysDept, deptTree);
                deptTree.setTitle(sysDept.getName());
                deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                deptTree.setSpread(true);
                deptTree.setChildren(getChild(sysDept.getId(), all));
                list.add(deptTree);
            }
        }
        return list;
    }

    //超级管理员的组织结构树(状态为禁用的)
    private List<DeptRespNodeVO> getTreeSuperDisable(List<SysDept> all) {
        List<DeptRespNodeVO> list = new ArrayList<>();
        for (SysDept sysDept : all) {
            //
            if (CommonConstant.TOP_PARENT_ID.equals(sysDept.getPid())) {
                DeptRespNodeVO deptTree = new DeptRespNodeVO();
                BeanUtils.copyProperties(sysDept, deptTree);
                deptTree.setTitle(sysDept.getName());
                deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                deptTree.setSpread(true);
                deptTree.setChildren(getChild(sysDept.getId(), all));
                list.add(deptTree);
            } else {
                DeptRespNodeVO deptTree = new DeptRespNodeVO();
                BeanUtils.copyProperties(sysDept, deptTree);
                deptTree.setTitle(sysDept.getName());
                deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                deptTree.setSpread(true);
                deptTree.setChildren(getChild(sysDept.getId(), all));
                list.add(deptTree);
            }
        }
        return list;
    }


    private List<DeptRespNodeVO> getTree(List<SysDept> all) {
        List<DeptRespNodeVO> list = new ArrayList<>();
        //找到根部门,根据部门id 分组
        Map<Integer, List<SysDept>> deptMap = all.stream().collect(Collectors.groupingBy(SysDept::getId));
        //设定一个顶级部门id
        final Integer[] topDeptId = new Integer[1];
        //如果Integer中key有0的,那么这个就是根
        if (deptMap.containsKey(CommonConstant.TOP_PARENT_ID)) {
            log.info("这个就是根部门");
            for (SysDept sysDept : all) {
                //
                if (sysDept.getPid().equals(0)) {
                    DeptRespNodeVO deptTree = new DeptRespNodeVO();
                    BeanUtils.copyProperties(sysDept, deptTree);
                    deptTree.setTitle(sysDept.getName());
                    deptTree.setPhone(sysDept.getPhone());
                    deptTree.setManagerName(sysDept.getManagerName());
                    deptTree.setSpread(true);
                    deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                    deptTree.setPidName(sysDept.getPidName());
                    deptTree.setChildren(getChild(sysDept.getId(), all));
                    list.add(deptTree);
                }
            }
            return list;
        } else {
            //遍历每个数组时,如果数组中的pid在map中没有,那么这个就是顶级部门
            deptMap.forEach((k, v) -> {
                for (SysDept sysDept : v) {
                    Integer pid = sysDept.getPid();
                    //如果list中有父id,继续
                    if (deptMap.containsKey(pid)) {
                        break;
                    }
                    if (!deptMap.containsKey(pid)) {
                        topDeptId[0] = pid;
                        break;
                    }
                }
            });
            //根据找到的topDeptId
            for (SysDept sysDept : all) {
                //
                if (sysDept.getPid().equals(topDeptId[0])) {
                    DeptRespNodeVO deptTree = new DeptRespNodeVO();
                    BeanUtils.copyProperties(sysDept, deptTree);
                    deptTree.setTitle(sysDept.getName());
                    deptTree.setPhone(sysDept.getPhone());
                    deptTree.setManagerName(sysDept.getManagerName());
                    deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                    deptTree.setPidName(sysDept.getPidName());
                    deptTree.setSpread(true);
                    deptTree.setChildren(getChild(sysDept.getId(), all));
                    list.add(deptTree);
                } else {
                    DeptRespNodeVO deptTree = new DeptRespNodeVO();
                    BeanUtils.copyProperties(sysDept, deptTree);
                    deptTree.setTitle(sysDept.getName());
                    deptTree.setPhone(sysDept.getPhone());
                    deptTree.setManagerName(sysDept.getManagerName());
                    deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                    deptTree.setPidName(sysDept.getPidName());
                    deptTree.setSpread(true);
                    deptTree.setChildren(getChild(sysDept.getId(), all));
                    if (!deptMap.containsKey(sysDept.getPid())) {
                        list.add(deptTree);
                    }
                }
            }
        }
        return list;
    }

    private List<DeptRespNodeVO> getChild(Integer id, List<SysDept> all) {
        List<DeptRespNodeVO> list = new ArrayList<>();
        for (SysDept sysDept : all) {
            if (sysDept.getPid().equals(id)) {
                DeptRespNodeVO deptTree = new DeptRespNodeVO();
                BeanUtils.copyProperties(sysDept, deptTree);
                deptTree.setTitle(sysDept.getName());
                deptTree.setPhone(sysDept.getPhone());
                deptTree.setManagerName(sysDept.getManagerName());
                deptTree.setCreateTime(DateUtil.format(sysDept.getCreateTime(), CommonConstant.DATE));
                deptTree.setPidName(sysDept.getPidName());
                deptTree.setChildren(getChild(sysDept.getId(), all));
                list.add(deptTree);
            }
        }
        return list;
    }

    @Override
    public PageResult<SysUser> pageDeptUserInfo(UserPageUserByDeptReqVO vo) {
        //如果是平台超管用户,查询的是这个部门下的所有用户
        SimpleUser currentSimpleUser = permissionService.getCurrentSimpleUser();
        log.info("user:{}, platSuper: {}", currentSimpleUser.getUserId(), currentSimpleUser.getPlatSuper());
        List<SysDept> depts = new ArrayList<>();
        if (currentSimpleUser.getPlatSuper()) {
            //这个deptId是要查的部门id,不是当前用户的部门id
            Integer deptId = vo.getDeptId();
            SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
            //加一个条件，获取当前用户的启用部门
            //String enableStatus = "enableStatus";
            List<SysDept> sysDepts = new ArrayList<>();
            sysDepts.add(sysDept);
            depts = getSubsidiaryDepts(sysDepts, null);
            //depts = sysDeptMapper.selectEnableByRelationCode(sysDept.getRelationCode(), enableStatus);
            return userService.selectUserInfoByDeptIds(vo.getPageNum(), vo.getPageSize(), depts, vo);
        }
        //非平台超管
        //当前用户所有的部门
        depts = getUserDepts();
        //判断当前人是否有该部门人员查询的权限
       /* if (!checkUserHasDeptPower(vo.getDeptId(), depts)) {
            log.info("have no dept search power ");
            return PageUtils.getPageResult(new PageInfo<>(new ArrayList<>()));
        }*/
        //当前传入部门及所有子部门
        List<SysDept> depListByDeptId = depListByDeptId(vo.getDeptId());
        //有权限,返回的是当前用户部门下的人员数据
        return userService.selectUserInfoByDeptIds(vo.getPageNum(), vo.getPageSize(), depListByDeptId, vo);
    }

    //当前用户所有的部门
    @Override
    public List<SysDept> getUserDepts() {
        SimpleUser currentSimpleUser = permissionService.getCurrentSimpleUser();
        List<Integer> childIds = currentSimpleUser.getDepts();
        DeptQuery query = new DeptQuery();
        //加一个条件，获取当前用户的启用部门
        String enableStatus = "enableStatus";
        List<SysDept> deptList = sysDeptMapper.selectChildByIds(childIds, query, enableStatus);
        return deptList;
    }

    @Override
    public Boolean checkUserHasDeptPower(Integer deptId, List<SysDept> userDepts) {
        //当前部门对象
        SysDept dept = sysDeptMapper.selectByPrimaryKey(deptId);
        if (dept == null) {
            return false;
        }
        //如果用户包含当前部门,就有权限,否则就没有
        if (!userDepts.isEmpty()) {
            for (SysDept userDept : userDepts) {
                if (userDept.getId().equals(dept.getId())) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 获取顶级Dept
     *
     * @param deptId
     * @return
     */
    @Override
    public SysDept getTopDept(Integer deptId) {
        //todo 先从缓存中查询是否有这个
        //redisService.get()
        //查询这个部门
        SysDept deptRecord = sysDeptMapper.selectByPrimaryKey(deptId);
        //没查到返回
        if (deptRecord == null) {
            return null;
        }
        //查到顶级数据 ,返回
        if (CommonConstant.TOP_PARENT_ID.equals(deptRecord.getPid())) {
            //todo 放置到缓存
            return deptRecord;
        }
        //递归查询pid那条数据
        return getTopDept(deptRecord.getPid());
    }

    @Override
    public List<SysDept> selectByIds(List<Integer> ids) {
        DeptQuery query = new DeptQuery();
        String enableStatus = null;
        List<SysDept> sysDepts = sysDeptMapper.selectChildByIds(ids, query, enableStatus);
        return sysDepts;
    }

    @Override
    public SysDept selectByPrimaryKey(Integer deptId) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        return sysDept;
    }

    //
/*   @Override
    public List<SysDept> selectEnableByRelationCode(String relationCode, String enable) {
        return sysDeptMapper.selectEnableByRelationCode(relationCode, enable);
    }*/

/*   @Override
    public List<SysDept> selectAllByRelationCode(String relationCode) {
        List<SysDept> sysDept = sysDeptMapper.selectAllByIds(relationCode);
        return sysDept;
    }*/

@Override
    public List<SysDept> getSubsidiaryDepts(List<SysDept> sysDepts, String status) {
        //去重
        Set<SysDept> deptSet = new HashSet<>();
        //获取部门id集合
        List<Integer> deptIds = sysDepts.stream().map(SysDept::getId).collect(Collectors.toList());
        //pid查询到子部门
        List<SysDept> deptList = sysDeptMapper.selectDeptsByPid(deptIds, status);
        deptSet.addAll(deptList);
        deptSet.addAll(sysDepts);
        if (deptList != null && !deptList.isEmpty()) {
            List<SysDept> subsidiaryDepts = getSubsidiaryDepts(deptList, status);
            deptSet.addAll(subsidiaryDepts);
        }
        return deptSet.stream().collect(Collectors.toList());
    }

@Override
    public List<SysDept> getAllToTop(SysDept dept, List<SysDept> all) {
        Set<SysDept> depts = new HashSet<>();
        depts.addAll(all);
        depts.add(dept);
        if (dept.getPid() != 0) {
            SysDept dept1 = sysDeptMapper.selectByPid(dept.getPid());
            depts.add(dept1);
            return getAllToTop(dept1, depts.stream().collect(Collectors.toList()));

        }
        return depts.stream().collect(Collectors.toList());
    }

    @Override
    public List<SysDept> selectByGroupId(Integer groupId) {
        List<SysDept> depts = sysDeptMapper.selectByGroup(groupId);
        return depts;
    }

    @Override
    public int getHierarchy(Map<Integer, SysDept> map, SysDept dept, Integer count) {
        Integer myCount = count;
        if (map.get(dept.getPid()) != null) {
            myCount++;
            SysDept sysDept = map.get(dept.getPid());
            if (dept.getPid() != 0) {
                return getHierarchy(map, sysDept, myCount);
            } else {
                return myCount;
            }
        } else {
            return myCount;
        }
    }

    @Override
    public PageResult<SysUser> getUserInfosPage(UserPageUserByDeptReqVO vo) {
        SimpleUser currentSimpleUser = permissionService.getCurrentSimpleUser();
        List<SysDept> depListByDeptId = depListByDeptId(currentSimpleUser.getDeptId());
        PageResult<SysUser> sysUserPageResult = userService.selectUserInfoByDeptIds(vo.getPageNum(), vo.getPageSize(), depListByDeptId, vo);
        List<SysUser> resultList = sysUserPageResult.getList().stream().filter(i -> i.getDeptId().equals(currentSimpleUser.getDeptId()) || i.getDeptId().equals(vo.getDeptId())).collect(Collectors.toList());
        sysUserPageResult.setList(resultList);
        return sysUserPageResult;
    }

    @Override
    public List<SysUser> getDeptUser(DeptManagerReq deptManagerReq) {
        //本级加上级
        SysDept dept = sysDeptMapper.selectByIdAndStatus(deptManagerReq.getDeptId());
        if (dept != null) {
            List<SysUser> sysUserList = new ArrayList<>();
            if (CommonConstant.ZERO.equals(dept.getPid())) {
                sysUserList = userService.selectByDeptId(dept.getId());
                for (SysUser sysUser : sysUserList) {
                    sysUser.setDeptName(dept.getName());
                }
            } else {
                List<SysDept> depts = selectByGroupId(dept.getGroupId());
                Map<Integer, SysDept> map = new HashMap<>();
                for (SysDept sysDept : depts) {
                    map.put(sysDept.getId(), sysDept);
                }
                //设置一个层级变量
                int count = 0;
                for (SysDept sysDept : depts) {
                    int hierarchy = getHierarchy(map, sysDept, 1);
                    sysDept.setHierarchy(hierarchy);
                    if (dept.getId().equals(sysDept.getId())) {
                        count = sysDept.getHierarchy();
                    }
                }
                int finalCount = count;
                List<SysDept> sysDepts = depts.stream().filter(sysDept -> {
                    return sysDept.getHierarchy() <= finalCount;
                }).collect(Collectors.toList());

                List<Integer> deptIds = sysDepts.stream().map(sysDept -> {
                    return sysDept.getId();
                }).collect(Collectors.toList());
                sysUserList = userService.selectByDeptIds(deptIds);
                for (SysUser user : sysUserList) {
                    for (SysDept sysDept : sysDepts) {
                        if (user.getDeptId().equals(sysDept.getId())) {
                            user.setDeptName(sysDept.getName());
                        }
                    }
                }
            }
            //排序
            List<SysUser> collect = sysUserList.stream().sorted(Comparator.comparing(SysUser::getDeptId,
                    Comparator.nullsFirst(Integer::compareTo)))
                    .collect(Collectors.toList());

            return collect;
        } else {
            return new ArrayList<>();
        }
    }


    public SysDept getTop(Integer deptId) {
        //todo 先从缓存中查询是否有这个
        //redisService.get()
        //查询这个部门
        SysDept deptRecord = sysDeptMapper.selectByPrimaryKey(deptId);
        //没查到返回
        if (deptRecord == null) {
            return null;
        }
        //查到顶级数据 ,返回
        if (CommonConstant.TOP_PARENT_ID.equals(deptRecord.getPid())) {
            //todo 放置到缓存
            return deptRecord;
        }
        //递归查询pid那条数据
        SysDept sysDept = sysDeptMapper.selectByPid(deptRecord.getPid());
        return getTopDept(sysDept.getPid());
    }

/*        //有deptId时就用deptId ,没有deptId时用 deptPid
        Integer deptId = deptManagerReq.getDeptId() == null ? deptManagerReq.getDeptPid() : deptManagerReq.getDeptId();
        log.info("getDeptUser deptId: {}", deptId);
        List<Integer> deptIds = new ArrayList<>();
        SysDept sysDept = new SysDept();
        //根据deptId拿到 pid 一直查到pid=0
        //查数据本身
        sysDept = sysDeptMapper.selectByPid(deptId);
        if (sysDept == null) {
            return new ArrayList<>();
        }

        int level = 1;
        //递归往上查,一直查到pid=0
        while (!CommonConstant.TOP_PARENT_ID.equals(sysDept.getPid())) {
            //循环内容
            sysDept = sysDeptMapper.selectByPid(sysDept.getPid());
            level++;
        }
        //顶级的那个部门
        deptIds.add(sysDept.getId());
        List<Integer> queryIds = new ArrayList<>();
        queryIds.add(sysDept.getId());
        for (int i = 0; i < level; i++) {
            //部门如果被禁用，下面的人则不能查到
            String status = "status";
            List<SysDept> sysDepts = sysDeptMapper.selectDeptsByPid(queryIds, status);
            //重新赋值 pid
            queryIds = new ArrayList<>();
            for (SysDept dept : sysDepts) {
                if(!dept.getId().equals(deptId)){
                    queryIds.add(dept.getId());
                }
                deptIds.add(dept.getId());
            }
        }
        //再根据deptIds进行人员查询
        UserPageUserByDeptReqVO userQuery = new UserPageUserByDeptReqVO();
        //set 状态为可用的状态
        userQuery.setStatus(CommonConstant.STATUS_FLAG);
        List<SysUser> SysUsers = userService.getUserListByDeptIdsAndUserIds(deptIds, userQuery, sysDept.getId());
        List<SysUser> SysUserList = new ArrayList<>();
        for (Integer id : deptIds) {
            SysDept dept = sysDeptMapper.selectByPid(id);
            for (SysUser sysUser : SysUsers) {
                if (dept.getId().equals(sysUser.getDeptId())) {
                    sysUser.setDeptName(dept.getName());
                    SysUserList.add(sysUser);
                }
            }
        }
        return SysUserList.stream().distinct().collect(Collectors.toList());
    }*/


}
