package com.njcn.utils;

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

import javax.annotation.Resource;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.njcn.pojo.configuration.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.njcn.enums.ProjectEnum;
import com.njcn.mapper.configuration.DeviceMapper;
import com.njcn.mapper.configuration.DicDataMapper;
import com.njcn.mapper.configuration.GDInforMapper;
import com.njcn.mapper.configuration.LineMapper;
import com.njcn.mapper.configuration.SubStationMapper;
import com.njcn.mapper.data.IntegrityMapper;
import com.njcn.mapper.data.LimitRateMapper;
import com.njcn.mapper.user.DeptsLineMapper;
import com.njcn.mapper.user.DeptsMapper;
import com.njcn.mapper.user.FunctionMapper;
import com.njcn.mapper.user.RoleFunctionMapper;
import com.njcn.mapper.user.RoleGPAssMapper;
import com.njcn.mapper.user.RoleGroupMapper;
import com.njcn.mapper.user.RoleMapper;
import com.njcn.mapper.user.UserMapper;
import com.njcn.mapper.user.UserSetMapper;
import com.njcn.pojo.commons.AreaGeneralData;
import com.njcn.pojo.commons.CompanyValue;
import com.njcn.pojo.commons.DeviceType;
import com.njcn.pojo.commons.LoadTypeValue;
import com.njcn.pojo.commons.SimpleValue;
import com.njcn.pojo.commons.VoltageData;
import com.njcn.pojo.data.IndexsCount;
import com.njcn.pojo.user.Depts;
import com.njcn.pojo.user.Permission;
import com.njcn.pojo.user.Role;
import com.njcn.pojo.user.RoleFunction;
import com.njcn.pojo.user.RoleGPAss;
import com.njcn.pojo.user.RoleGroup;
import com.njcn.pojo.user.UserSet;
import com.njcn.shiro.token.TokenManager;
import com.njcn.sso.pojo.user.User;
import com.njcn.utils.redis.RedisCacheUtil;

@Service("userUtil")
public class UserUtil {

    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(UserUtil.class);

    @Autowired
    private SubStationMapper subStationMapper;

    @Autowired
    private DeptsMapper deptsMapper;

    @Autowired
    private LineMapper lineMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private LimitRateMapper limitRateMapper;

    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Autowired
    private UserSetMapper userSetMapper;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private RoleGPAssMapper roleGPAssMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleFunctionMapper roleFunctionMapper;

    @Autowired
    private FunctionMapper functionMapper;

    @Autowired
    private IntegrityMapper integrityMapper;

    @Autowired
    private RoleGroupMapper roleGroupMapper;

    @Autowired
    private DicDataMapper dicDataMapper;

    @Resource
    private DeptsLineMapper deptsLineMapper;

    @Resource
    private GDInforMapper gdInforMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据用户索引获取该用户的配置信息
     *
     * @param userIndex 用户索引
     */
    public UserSet getUserSet(String userIndex) {
        UserSet userSet = new UserSet();
        userSet.setUserIndex(userIndex);
        try {
            userSet = userSetMapper.selectOne(userSet);
        } catch (Exception e) {
            logger.error("根据用户索引获取配置信息失败，用户索引：" + userIndex + ",异常为：" + e.toString());
            userSet = null;
        }
        return userSet;
    }


    /**
     * 获取用户配置信息 根据用户索引、用户所属指定系统
     *
     * @return userSet
     */
    public UserSet getUserSet() {
        return getUserSet(TokenManager.getUserId());
    }

    /**
     * 根据用户，获取用户的角色组索引
     *
     * @param userIndex 用户索引
     */
    public String getRoleGpIndex(String userIndex) {
        String roleGpIndex;
        try {
            roleGpIndex = getUserSet(userIndex).getRoleGpIndex();
        } catch (Exception e) {
            logger.error("根据用户索引获取角色组失败，用户索引：" + userIndex + ",异常为：" + e.toString());
            roleGpIndex = null;
        }
        return roleGpIndex;
    }

    /**
     * 根据用户索引获取其角色组
     */
    public RoleGroup getRoleGroupByUserIndex(String userIndex) {
        String roleGpIndex = getRoleGpIndex(userIndex);
        if (StringUtils.isBlank(roleGpIndex)) {
            return null;
        }
        RoleGroup roleGroup = new RoleGroup();
        roleGroup.setRoleGpIndex(roleGpIndex);
        try {
            roleGroup = roleGroupMapper.selectOne(roleGroup);
        } catch (Exception e) {
            logger.error("根据用户索引获取角色组失败，用户索引：" + userIndex + ",异常为：" + e.toString());
            roleGroup = null;
        }
        return roleGroupMapper.selectOne(roleGroup);
    }


    /**
     * 根据用户索引获取其拥有的角色(超级管理员)
     */
    public List<Role> getRoles(String userIndex) {
        List<Role> roles = new ArrayList<>();
        RoleGroup roleGroup = getRoleGroupByUserIndex(userIndex);
        if (null == roleGroup) {
            return roles;
        }
        RoleGPAss roleGPAss = new RoleGPAss();
        roleGPAss.setRoleGpIndex(roleGroup.getRoleGpIndex());
        roleGPAss.setSysType(appConfig.getSysType());
        List<RoleGPAss> roleGPAsses = roleGPAssMapper.select(roleGPAss);
        if (!CollectionUtils.isEmpty(roleGPAsses)) {
            for (RoleGPAss roleGPass : roleGPAsses) {
                Role role = new Role();
                role.setRoleIndex(roleGPass.getRoleIndex());
                try {
                    role = roleMapper.selectOne(role);
                } catch (Exception e) {
                    logger.error("根据用户索引获取角色失败，用户索引：" + userIndex + ",异常为：" + e.toString());
                    role = null;
                }
                if (null != role) {
                    roles.add(role);
                }
            }
        }
        return roles;
    }

    /**
     * 根据用户索引获取其拥有的角色(超级管理员)
     */
    public RoleGroup getRolesSys(String userIndex) {
        RoleGroup roleGroup = new RoleGroup();
        try {
            roleGroup = getRoleGroupByUserIndex(userIndex);
        } catch (Exception e) {
            return roleGroup;
        }
        return roleGroup;
    }


    /**
     * 获取当前用户的所有权限
     */
    public List<Permission> getPermissions(List<Role> roles) {
        List<Permission> permissions = new ArrayList<>();
        if (CollectionUtils.isEmpty(roles)) {
            return null;
        } else {
            for (Role role : roles) {
                RoleFunction roleFunction = new RoleFunction();
                roleFunction.setRoleIndex(role.getRoleIndex());
                List<RoleFunction> roleFunctions = roleFunctionMapper.select(roleFunction);
                if (CollectionUtils.isEmpty(roleFunctions)) {
                    return null;
                } else {
                    for (RoleFunction roleFunction1 : roleFunctions) {
                        Permission permission = new Permission();
                        permission.setFunctionIndex(roleFunction1.getFunctionIndex());
                        permissions.add(functionMapper.selectOne(permission));
                    }
                }
            }
        }
        return permissions;
    }

    /**
     * 根据用户，获取用户的部门索引
     *
     * @param userIndex 用户索引
     */
    public String getDeptsIndex(String userIndex) {
        String deptsIndex;
        try {
            deptsIndex = getUserSet(userIndex).getDeptsIndex();
        } catch (Exception e) {
            logger.error("根据用户索引获取部门索引失败，用户索引：" + userIndex + ",异常为：" + e.toString());
            deptsIndex = null;
        }
        return deptsIndex;
    }

    public String getappDeptsIndex(String userIndex) {
        String deptsIndex;
        try {
            User user = userMapper.getAppBaseUser(userIndex);
            userIndex = user == null ? userIndex : user.getUserIndex();
            deptsIndex = getUserSet(userIndex).getDeptsIndex();
        } catch (Exception e) {
            logger.error("根据用户索引获取部门索引失败，用户索引：" + userIndex + ",异常为：" + e.toString());
            deptsIndex = null;
        }
        return deptsIndex;
    }

    /**
     * 根据用户索引获取对应部门
     */
    private Depts getDeptByUserIndex(String userIndex) {
        Depts depts = null;
        String deptsIndex = getDeptsIndex(userIndex);
        if (StringUtils.isNotBlank(deptsIndex)) {
            try {
                depts = deptsMapper.selectDeptsByDeptsIndex(deptsIndex);
            } catch (Exception e) {
                logger.error("根据用户索引获取部门失败，用户索引：" + userIndex + ",异常为：" + e.toString());
                depts = null;
            }
        }
        return depts;
    }


    /**
     * 根据用户获取所属部门
     */
    public Depts getCurrentDept() {
        return getDeptByUserIndex(TokenManager.getUserId());
    }


    /**
     * 根据用户获取所属部门
     */
    public Depts getDeptsByUser(User user) {
        return getDeptByUserIndex(user.getUserIndex());
    }


    /**
     * 根据部门索引获取部门
     */
    public Depts getDeptsByIndex(String deptIndex) {
        Depts dep;
        try {
            dep = deptsMapper.selectDeptsByDeptsIndex(deptIndex);
        } catch (Exception e) {
            logger.error("根据部门索引获取部门失败，部门索引：" + deptIndex + ",异常为：" + e.toString());
            dep = null;
        }
        return dep;
    }

    /**
     * 根据节点获取所有子孙部门。
     *
     * @param node 省级部门的node
     */
    public List<Depts> getDeptsByNode(String node) {
        return deptsMapper.getDeptsByNode(node);
    }

    /**
     * 根据部门索引向上递归获取所有部门
     *
     * @param deptsIndex 部门索引
     */
    public List<Depts> getDeptsByNodeUp(String deptsIndex) {
        return deptsMapper.getDeptsByNodeUp(deptsIndex);
    }

    /**
     * 根据父节点获取其直接子部门
     */
    public List<Depts> getDirectDeptsByNode(String node) {
        return deptsMapper.getDirectDeptsByNode(node);
    }

    public List<Depts> getNoDirectDeptsByNode(String node) {
        return deptsMapper.getNoDirectDeptsByNode(node);
    }

    /**
     * 获取当前系统类型
     */
    public String getSysType() {
        try {
            if (StringUtils.isBlank(TokenManager.getSysType())) {
                return appConfig.getSysType();
            }
            return TokenManager.getSysType();
        } catch (Exception e) {
            return appConfig.getSysType();
        }
    }


    /***************************根据当前用户获取区域信息***************************************************/

    /**
     * 根据用户身份以及传入的区域获取查询的区域信息
     * deptsIndex区域部门索引
     * 实际运行设备的数据
     */
    public List<AreaGeneralData> getAreaDataByInfo(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        return ag;
    }

    /**
     * 实际运行设备且处于投运状态且状态为在线
     * */
    public List<AreaGeneralData> getAreaDataByInfoRun(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType, 0);
        return ag;
    }

    /**
     * 获取非自定义的部门
     * 实际运行设备且处于投运状态
     * */
    public List<AreaGeneralData> getAreaDeptsDataByInfoRun(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getDeptsDatas(depts, deviceType, 0);
        return ag;
    }

    /**
     * 获取当前系统所有部门
     * 实际运行设备且处于投运状态
     * */
    public List<AreaGeneralData> getAllDeptDataById(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getDeptsDatas(depts, deviceType, 0);
        return ag;
    }


    /**
     * 短信功能专用
     * @param deptsIndex
     * @return
     */
    public List<AreaGeneralData> getAreaDataByMsg(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatasForMsg(depts, deviceType, 0);
        return ag;
    }

    /**
     * 实际运行设备且处于投运状态且需要统计的监测点
     * 9900pqs_linedetail字段statflag = 1时的监测点
     * 筛选监测点是非自定义部门下的
     * */
    public List<AreaGeneralData> getAreaDataByStatFlag(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDataStat(depts, deviceType, 0,1);
        return ag;
    }
    public List<AreaGeneralData> getAreaDataByStatFlagAll(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDataStat(depts, deviceType, 0,2);
        return ag;
    }

    /**
     * 根据用户身份以及传入的区域获取查询的区域信息
     * deptsIndex区域部门索引
     * 离线设备的数据
     */
    public List<AreaGeneralData> getAreaDataByInfoOffLine(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOffLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        return ag;
    }


    /**
     * 需求： 实际运行设备的数据
     * 根据用户返回地级市集合，内容包括
     * 1：地市名称 2：监测点数 3 每个地市下的所有监测点索引 4每个地市下的所有终端索引 5每个地市下的所有变电站索引 6每个地市下的所有供电公司索引
     */
    public List<AreaGeneralData> getAreaGeneral() {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByUser(TokenManager.getToken());
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        return ag;
    }

    /**
     * 需求： 实际运行设备的数据
     * 根据用户返回地级市集合，内容包括
     * 1：地市名称 2：监测点数 3 每个地市下的所有监测点索引 4每个地市下的所有终端索引 5每个地市下的所有变电站索引 6每个地市下的所有供电公司索引
     */
    public List<AreaGeneralData> getAreaPlateGeneral() {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByUser(TokenManager.getToken());
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaPlateDatas(depts, deviceType);
        return ag;
    }

    public List<AreaGeneralData> getAreaGeneralRun() {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByUser(TokenManager.getToken());
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType, 0);
        return ag;
    }

    public List<AreaGeneralData> getAreaGeneralRun(Integer devFlag,String deptId,Integer powerId) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptId);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaPowerIdData(depts, deviceType, devFlag,powerId);
        return ag;
    }


    public List<AreaGeneralData> getappAreaGeneral(User... userId) {
        List<AreaGeneralData> ag;
        Depts depts = userId.length > 0 ? getDeptsByUser(userId[0]) : getDeptsByUser(TokenManager.getToken());
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        return ag;
    }

    /**
     * 需求： 离线设备的数据
     * 根据用户返回地级市集合，内容包括
     * 1：地市名称 2：监测点数 3 每个地市下的所有监测点索引 4每个地市下的所有终端索引 5每个地市下的所有变电站索引 6每个地市下的所有供电公司索引
     */
    public List<AreaGeneralData> getAreaGeneralOffLine() {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByUser(TokenManager.getToken());

        DeviceType deviceType = getOffLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        return ag;
    }


    /**
     * @param dept 部门 只统计在线装置
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     */
    private List<AreaGeneralData> getAreaDatas(Depts dept, DeviceType deviceType) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaData(dept, deviceType));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaData(deptsTemp, deviceType));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }

    /**
     * @param dept 部门 只统计在线装置(电度)
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     */
    private List<AreaGeneralData> getAreaPlateDatas(Depts dept, DeviceType deviceType) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaPlateData(dept, deviceType));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaPlateData(deptsTemp, deviceType));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }


    /**
     * @param dept 部门 只统计在线装置 且投运状态
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     */
    private List<AreaGeneralData> getAreaDatas(Depts dept, DeviceType deviceType, Integer devFlag) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaData(dept, deviceType, devFlag));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaData(deptsTemp, deviceType, devFlag));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }

    /**
     * @param dept 部门 只统计在线装置 且投运状态
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     */
    private List<AreaGeneralData> getAreaPowerIdData(Depts dept, DeviceType deviceType, Integer devFlag,Integer powerId) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaPowerIdDept(dept, deviceType, devFlag,powerId));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaPowerIdDept(deptsTemp, deviceType, devFlag,powerId));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }
    /**
     * 获取部门下详细信息(监测点性质)
     *
     * @param dept 部门
     */
    private AreaGeneralData getAreaPowerIdDept(Depts dept, DeviceType deviceType, Integer devicdStatus,Integer powerId) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsPowerIdByDeptRun(Arrays.asList(dept.getDeptsIndex()), sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null,powerId);
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<String> deptIds = depts.stream().map(Depts::getDeptsIndex).collect(Collectors.toList());
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsPowerIdByDeptRun(deptIds, sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null,powerId);
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }
    private List<AreaGeneralData> getDeptsDatas(Depts dept, DeviceType deviceType, Integer devStatus) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getNoDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaData(dept, deviceType, devStatus));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaData(deptsTemp, deviceType, devStatus));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }

    /**
     * @param dept 部门 只统计在线装置 且投运状态
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     */
    private List<AreaGeneralData> getAreaDatasForMsg(Depts dept, DeviceType deviceType, Integer devStatus) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts = getDirectDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaDataForMsg(dept, deviceType, devStatus));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaDataForMsg(deptsTemp, deviceType, devStatus));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }

    /**
     * @param dept 部门 只统计在线装置 且投运状态
     *             1：判断该部门有没有直接子部门
     *             2：根据有效部门获取部门对应的各项信息
     *             针对原来方法没有关联line_detail表，此方法复制原生方法用于拓展查询
     *             type 1.非自定义部门 2.非自定义部门和自定义部门
     */
    private List<AreaGeneralData> getAreaDataStat(Depts dept, DeviceType deviceType, Integer devStatus,Integer type) {
        List<AreaGeneralData> ag = new ArrayList<>();
        try {
            List<Depts> depts;
            if(type == 1) {
                depts = getNoDirectDeptsByNode(dept.getDeptsIndex());
            }else {
                depts = getDirectDeptsByNode(dept.getDeptsIndex());
            }
            if (CollectionUtils.isEmpty(depts)) {
                //则只获取当前部门下的所有信息
                ag.add(getAreaDataStatFlag(dept, deviceType, devStatus));
            } else {
                //返回当前用户下所有子部门的信息
                for (Depts deptsTemp : depts) {
                    ag.add(getAreaDataStatFlag(deptsTemp, deviceType, devStatus));
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return ag;
    }

    /**
     * 获取部门下详细信息
     *
     * @param dept 部门
     */
    private AreaGeneralData getAreaData(Depts dept, DeviceType deviceType) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        if (sysType != null && sysType.equals(ProjectEnum.PQS9300.getKey())) {
            //9300系统使用的监测点是9000的
            sysType = ProjectEnum.PQS9000.getKey();
        }
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsByDept(dept.getDeptsIndex(), sysType, deviceType.getDevModel(), deviceType.getDataType());
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsByDepts(depts, sysType, deviceType.getDevModel(), deviceType.getDataType());
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }

    /**
     * 获取部门下详细信息(电度)
     *
     * @param dept 部门
     */
    private AreaGeneralData getAreaPlateData(Depts dept, DeviceType deviceType) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        if (sysType != null && sysType.equals(ProjectEnum.PQS9300.getKey())) {
            //9300系统使用的监测点是9000的
            sysType = ProjectEnum.PQS9000.getKey();
        }
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsByDeptPlate(dept.getDeptsIndex(), sysType, deviceType.getDevModel(), deviceType.getDataType());
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsByDeptsPlate(depts, sysType, deviceType.getDevModel(), deviceType.getDataType());
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }

    /**
     * 获取部门下详细信息
     *
     * @param dept 部门
     */
    private AreaGeneralData getAreaData(Depts dept, DeviceType deviceType, Integer devicdStatus) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsByDeptRun(dept.getDeptsIndex(), sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsByDeptsRun(depts, sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }

    /**
     * 获取部门下详细信息
     *
     * @param dept 部门
     */
    private AreaGeneralData getAreaDataStatFlag(Depts dept, DeviceType deviceType, Integer devicdStatus) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsByDeptRunForStatFlag(dept.getDeptsIndex(), sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsByDeptsRunForStatFlag(depts, sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }

    /**
     * 获取部门下详细信息
     * 短信功能
     * @param dept 部门
     */
    private AreaGeneralData getAreaDataForMsg(Depts dept, DeviceType deviceType, Integer devicdStatus) {
        AreaGeneralData areaGeneralData = new AreaGeneralData();
        if (dept.getCustomDept() == 0) {
            areaGeneralData.setName(dept.getArea());
        } else {
            areaGeneralData.setName(dept.getDeptsName());
        }
        areaGeneralData.setDeptIndex(dept.getDeptsIndex());
        String sysType = getSysType().equals(ProjectEnum.APP.getKey()) ? null : getSysType();
        if (sysType != null && sysType.equals(ProjectEnum.PQS9900.getKey())) {
            //9900系统使用的监测点是9200的
            sysType = ProjectEnum.PQS9200.getKey();
        }
        List<IndexsCount> indexsCountsByDept = deptsLineMapper.selectIndexsByDeptRun(dept.getDeptsIndex(), sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
        if (CollectionUtils.isEmpty(indexsCountsByDept)) {
            //如果该部门没有任何的监测点关联，有可能是因为其是父节点（程序默认，当存在子节点时，当前部门节点不可绑定监测点）
            List<Depts> depts = getDeptsByNode(dept.getDeptsIndex());
            if (CollectionUtils.isEmpty(depts)) {
                areaGeneralData.setMonitors(0);
            } else {
                List<IndexsCount> indexsCountsByDepts = deptsLineMapper.selectIndexsByDeptsRun(depts, sysType, deviceType.getDevModel(), deviceType.getDataType(), devicdStatus,null);
                if (CollectionUtils.isEmpty(indexsCountsByDepts)) {
                    areaGeneralData.setMonitors(0);
                } else {
                    areaGeneralData = filtIndexData(indexsCountsByDepts, areaGeneralData);
                }
            }
        } else {
            areaGeneralData = filtIndexData(indexsCountsByDept, areaGeneralData);
        }
        return areaGeneralData;
    }

    /**
     * 筛选索引数据
     *
     * @param indexsCountsByDepts 所有所有数据
     * @param areaGeneralData     返回数据体
     */
    private AreaGeneralData filtIndexData(List<IndexsCount> indexsCountsByDepts, AreaGeneralData areaGeneralData) {
        List<Integer> lineIndex = new ArrayList<>();
        List<Integer> subIndex = new ArrayList<>();
        List<Integer> devIndex = new ArrayList<>();
        List<Integer> gdIndex = new ArrayList<>();
        for (IndexsCount indexCount : indexsCountsByDepts) {
            if (!lineIndex.contains(indexCount.getLineIndex())) {
                lineIndex.add(indexCount.getLineIndex());
            }
            if (!subIndex.contains(indexCount.getSubIndex())) {
                subIndex.add(indexCount.getSubIndex());
            }
            if (!devIndex.contains(indexCount.getDevIndex())) {
                devIndex.add(indexCount.getDevIndex());
            }
            if (!gdIndex.contains(indexCount.getGdIndex())) {
                gdIndex.add(indexCount.getGdIndex());
            }
        }
        areaGeneralData.setMonitors(lineIndex.size());
        areaGeneralData.setDeviceIndexs(devIndex);
        areaGeneralData.setGdIndexs(gdIndex);
        areaGeneralData.setLineIndexs(lineIndex);
        areaGeneralData.setSubIndexs(subIndex);
        return areaGeneralData;
    }


    /**
     * 根据终端索引获取终端信息（只需要运行状态字段）
     *
     * @param devIndex 终端索引
     */
    public List<Device> getDevicesByDevIndexs(List<Integer> devIndex) {
        if (CollectionUtils.isEmpty(devIndex)) {
            return new ArrayList<>();
        }
        List<Device> tempDevice = new ArrayList<>();
        List<Integer> lineIndexTemp = new ArrayList<>(devIndex);
        try {
            //分片1000个终端
            int length = lineIndexTemp.size();
            if (length > 1000) {
                //需要循环的次数
                int times = length / 1000 + 1;
                for (int i = 1; i <= times; i++) {
                    if (length > 1000) {
                        List<Integer> temp = lineIndexTemp.subList(0, 1000);
                        List<Device> devices = deviceMapper.getDevicesByDevIndexs(temp);
                        if (!CollectionUtils.isEmpty(devices)) {
                            tempDevice.addAll(devices);
                        }
                        temp.clear();
                        length = length - 1000;
                    } else {
                        List<Device> devices = deviceMapper.getDevicesByDevIndexs(lineIndexTemp);
                        if (!CollectionUtils.isEmpty(devices)) {
                            tempDevice.addAll(devices);
                        }
                    }
                }
            } else {
                tempDevice = deviceMapper.getDevicesByDevIndexs(lineIndexTemp);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return tempDevice;
    }


    /**
     * 需求：
     * 需要根据终端索引然后根据终端厂家获取数据
     * 包括：厂家名称、终端索引、监测点数、监测点索引
     */
    public List<CompanyValue> getCompanyData(List<Integer> devIndexs) {
        if (CollectionUtils.isEmpty(devIndexs)) {
            return new ArrayList<>();
        }
        List<CompanyValue> companyValues = new ArrayList<>();
        try {
            List<DicData> dicCom = redisCacheUtil.getDeviceCompanyData();
            if (CollectionUtils.isEmpty(dicCom)) {
                return new ArrayList<>();
            }
            for (DicData dicData : dicCom) {
                CompanyValue companyValue = new CompanyValue();
                companyValue.setCompanyName(dicData.getDicName());
                List<Integer> devices = getDevIndexByDevIndexsAndCompany(devIndexs, dicData.getDicIndex());
                if (CollectionUtils.isEmpty(devices)) {
                    companyValue.setMonitors(0);
                } else {
                    companyValue.setDeviceIndexs(devices);
                    List<Integer> lineIndexs = getLineIndexsByDeviceIndexs(devices);
                    if (CollectionUtils.isEmpty(lineIndexs)) {
                        companyValue.setMonitors(0);
                    } else {
                        companyValue.setLineIndexs(lineIndexs);
                        companyValue.setMonitors(lineIndexs.size());
                    }
                }
                companyValues.add(companyValue);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return companyValues;
    }

    /**
     * 根据终端索引获取监测点索引
     *
     * @param devices 终端索引
     */
    public List<Integer> getLineIndexsByDeviceIndexs(List<Integer> devices) {
        List<Integer> lineIndexs = new ArrayList<>();
        List<Integer> devIndexTemp = new ArrayList<>(devices);
        if (devIndexTemp.size() > 1000) {
            int size = devIndexTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexTemp.size() > 1000) {
                    List<Integer> tempDevIndex = devIndexTemp.subList(0, 1000);
                    List<Integer> temp = lineMapper.getLineIndex(tempDevIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                    tempDevIndex.clear();
                } else {
                    List<Integer> temp = lineMapper.getLineIndex(devIndexTemp);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = lineMapper.getLineIndex(devIndexTemp);
            if (!CollectionUtils.isEmpty(temp)) {
                lineIndexs.addAll(temp);
            }
        }
        return lineIndexs;
    }


    /**
     * 根据已知的终端，按终端厂家获取那些终端索引属于该终端厂家
     *
     * @param devIndexs 终端索引
     * @param dicIndex  终端厂家
     */
    private List<Integer> getDevIndexByDevIndexsAndCompany(List<Integer> devIndexs, String dicIndex) {
        DeviceType deviceType = getOnLineDeviceType();
        List<Integer> devIndex = new ArrayList<>();
        List<Integer> devIndexTemp = new ArrayList<>(devIndexs);
        if (devIndexTemp.size() > 1000) {
            int size = devIndexTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexTemp.size() > 1000) {
                    List<Integer> devTemp = devIndexTemp.subList(0, 1000);
                    List<Integer> temp = deviceMapper.getDeviceIndexsByCompanyName(dicIndex, deviceType.getDevModel(), deviceType.getDataType(), devTemp);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                    devTemp.clear();
                } else {
                    List<Integer> temp = deviceMapper.getDeviceIndexsByCompanyName(dicIndex, deviceType.getDevModel(), deviceType.getDataType(), devIndexTemp);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = deviceMapper.getDeviceIndexsByCompanyName(dicIndex, deviceType.getDevModel(), deviceType.getDataType(), devIndexTemp);
            if (!CollectionUtils.isEmpty(temp)) {
                devIndex.addAll(temp);
            }
        }
        return devIndex;
    }


    /**
     * 需求：
     * 按电压等级返回集合，内容包括：
     * 1：电压等级 2：监测点索引 3:终端索引
     */
    public List<VoltageData> getVoltageData(List<Integer> devIndexs) {
        List<VoltageData> vol = new ArrayList<>();
        if (CollectionUtils.isEmpty(devIndexs)) {
            return vol;
        }
        try {
            List<DicData> dics = redisCacheUtil.getVoltageData();
            if (!CollectionUtils.isEmpty(dics)) {
                for (DicData dicData : dics) {
                    VoltageData temp = new VoltageData();
                    //电压等级
                    temp.setVol(dicData.getDicName());
                    //监测点的索引*******************跟用户有关系且与电压等级有关，需要用户下的供电公司的索引
                    List<Integer> lineIndex = getByDevIndexsAndVoltage(devIndexs, dicData.getDicIndex());
                    temp.setLineIndexs(lineIndex);
                    //终端索引**********************跟用户有关、跟电压等级有关
                    List<Integer> deviceIndexs = getDeviceIndexsByDevIndexsAndVoltage(devIndexs, dicData.getDicIndex());
                    temp.setDeviceIndexs(deviceIndexs);
                    vol.add(temp);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return vol;
    }


    /**
     * 根据终端索引和电压等级获取监测点索引 需要分片1000
     *
     * @param devIndexs 终端索引
     * @param dicIndex  电压等级
     */
    private List<Integer> getByDevIndexsAndVoltage(List<Integer> devIndexs, String dicIndex) {
        List<Integer> lineIndexs = new ArrayList<>();
        List<Integer> devIndexsTemp = new ArrayList<>(devIndexs);
        if (devIndexsTemp.size() > 1000) {
            //需要做分片处理
            int size = devIndexsTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexsTemp.size() > 1000) {
                    List<Integer> tempIndexs = devIndexsTemp.subList(0, 1000);
                    List<Integer> temp = lineMapper.getLineIndexs(tempIndexs, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                    tempIndexs.clear();
                } else {
                    List<Integer> temp = lineMapper.getLineIndexs(devIndexsTemp, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = lineMapper.getLineIndexs(devIndexsTemp, dicIndex);
            if (!CollectionUtils.isEmpty(temp)) {
                lineIndexs.addAll(temp);
            }
        }
        return lineIndexs;
    }

    /**
     * 根据终端索引和电压等级获取终端索引 需要分片1000
     *
     * @param devIndexs 终端索引
     * @param dicIndex  电压等级
     */
    private List<Integer> getDeviceIndexsByDevIndexsAndVoltage(List<Integer> devIndexs, String dicIndex) {
        List<Integer> devIndex = new ArrayList<>();
        List<Integer> devIndexTemp = new ArrayList<>(devIndexs);
        if (devIndexTemp.size() > 1000) {
            //需要分片
            int size = devIndexTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexTemp.size() > 1000) {
                    List<Integer> tempDev = devIndexTemp.subList(0, 1000);
                    List<Integer> temp = lineMapper.getDeviceIndexs(tempDev, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                    tempDev.clear();
                } else {
                    List<Integer> temp = lineMapper.getDeviceIndexs(devIndexTemp, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = lineMapper.getDeviceIndexs(devIndexTemp, dicIndex);
            if (!CollectionUtils.isEmpty(temp)) {
                devIndex.addAll(temp);
            }
        }
        return devIndex;
    }


    /**
     * 需求：
     * 按监测点的干扰源类型终返回集合，内容包括：
     * 1：干扰源类型终 2：监测点索引 3：终端索引  4：监测点数量
     */
    public List<LoadTypeValue> getLoadTypeValue(List<Integer> devIndexs) {
        List<LoadTypeValue> loadTypeValues = new ArrayList<>();
        if (CollectionUtils.isEmpty(devIndexs)) {
            return loadTypeValues;
        }
        try {
            List<DicData> dics = redisCacheUtil.getLoadType();
            if (!CollectionUtils.isEmpty(dics)) {
                for (DicData dicData : dics) {
                    LoadTypeValue temp = new LoadTypeValue();
                    //干扰源类型终
                    temp.setType(dicData.getDicName());
                    //监测点的索引*******************跟用户有关系且与电压等级有关，需要用户下合理的终端索引
                    List<Integer> lineIndex=new ArrayList<>();
                    if(devIndexs.size()>1000){
                        int count = devIndexs.size()/1000+1;
                        for(int i=0;i<count;i++){
                            List<Integer> temList = null;
                            if(devIndexs.size()>1000){
                                List<Integer> tem = devIndexs.subList(0,1000);
                                temList=getLineIndexsByDeviceIndexsLoadType(tem, dicData.getDicIndex());
                                tem.clear();
                            }else {
                                temList=getLineIndexsByDeviceIndexsLoadType(devIndexs, dicData.getDicIndex());
                            }
                            if(CollectionUtil.isNotEmpty(temList)){
                                lineIndex.addAll(temList);
                            }
                        }
                    }else {
                        lineIndex = getLineIndexsByDeviceIndexsLoadType(devIndexs, dicData.getDicIndex());
                    }

                    temp.setLineIndexs(lineIndex);
                    //终端索引**********************跟用户有关、跟电压等级有关
                    List<Integer> deviceIndexs = getDeviceIndexsByLoadType(devIndexs, dicData.getDicIndex());
                    temp.setDevIndexs(deviceIndexs);
                    loadTypeValues.add(temp);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return loadTypeValues;
    }

    /**
     * 根据终端索引、干扰源类型终获取范围内终端索引
     *
     * @param devIndexs 终端索引
     * @param dicIndex  干扰源类型终
     */
    private List<Integer> getDeviceIndexsByLoadType(List<Integer> devIndexs, String dicIndex) {
        List<Integer> devIndex = new ArrayList<>();
        List<Integer> devIndexTemp = new ArrayList<>(devIndexs);
        if (devIndexTemp.size() > 1000) {
            //需要分片
            int size = devIndexTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexTemp.size() > 1000) {
                    List<Integer> tempDev = devIndexTemp.subList(0, 1000);
                    List<Integer> temp = lineMapper.getDeviceIndexsByLoadType(tempDev, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                    tempDev.clear();
                } else {
                    List<Integer> temp = lineMapper.getDeviceIndexsByLoadType(devIndexTemp, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        devIndex.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = lineMapper.getDeviceIndexsByLoadType(devIndexTemp, dicIndex);
            if (!CollectionUtils.isEmpty(temp)) {
                devIndex.addAll(temp);
            }
        }
        return devIndex;
    }

    /**
     * 根据干扰源类型以及终端索引获取所有的监测点索引
     *
     * @param devIndexs 终端索引
     * @param dicIndex  监测点索引
     */
    private List<Integer> getLineIndexsByDeviceIndexsLoadType(List<Integer> devIndexs, String dicIndex) {
        List<Integer> lineIndexs = new ArrayList<>();
        List<Integer> devIndexsTemp = new ArrayList<>(devIndexs);
        if (devIndexsTemp.size() > 1000) {
            //需要做分片处理
            int size = devIndexsTemp.size() / 1000 + 1;
            for (int i = 0; i < size; i++) {
                if (devIndexsTemp.size() > 1000) {
                    List<Integer> tempIndexs = devIndexsTemp.subList(0, 1000);
                    List<Integer> temp = lineMapper.getLineIndexsByLoadType(devIndexs, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                    tempIndexs.clear();
                } else {
                    List<Integer> temp = lineMapper.getLineIndexsByLoadType(devIndexsTemp, dicIndex);
                    if (!CollectionUtils.isEmpty(temp)) {
                        lineIndexs.addAll(temp);
                    }
                }
            }
        } else {
            List<Integer> temp = lineMapper.getLineIndexsByLoadType(devIndexsTemp, dicIndex);
            if (!CollectionUtils.isEmpty(temp)) {
                lineIndexs.addAll(temp);
            }
        }
        return lineIndexs;
    }


    /**
     * 合并两个simvalue的值
     *
     * @param sim     原始sim
     * @param simTemp 查询出来的新sim
     */
    public SimpleValue mergeSim(SimpleValue sim, SimpleValue simTemp) {
        SimpleValue simpleValue = new SimpleValue();
        if (sim.getCountAll() == null || sim.getCountAll() == 0) {
            if (null != simTemp && simTemp.getCountAll() != null) {
                simpleValue.setCountOnline(simTemp.getCountOnline());
                simpleValue.setCountAll(simTemp.getCountAll());
            }
        } else {
            if (null != simTemp && simTemp.getCountAll() != null) {
                simpleValue.setCountOnline(sim.getCountOnline() + simTemp.getCountOnline());
                simpleValue.setCountAll(sim.getCountAll() + simTemp.getCountAll());
            }
        }
        return simpleValue;
    }


    /**
     * 根据监测点索引获取数据完整性
     *
     * @param lineIndexs 监测点索引
     * @param startTime  起始时间
     * @param endTime    截止时间
     */
    public SimpleValue selectIntegralityByLineIndexAndTime(List<Integer> lineIndexs, Date startTime, Date endTime) {
        SimpleValue sim = new SimpleValue();
        if (CollectionUtils.isEmpty(lineIndexs)) {
            return null;
        }
        try {
            List<Integer> lineIndexTemp = new ArrayList<>(lineIndexs);
            int length = lineIndexTemp.size();
            if (length > 1000) {
                //需要循环的次数
                int times = length / 1000 + 1;
                for (int i = 1; i <= times; i++) {
                    if (length > 1000) {
                        List<Integer> temp = lineIndexTemp.subList(0, 1000);
                        SimpleValue simTemp = integrityMapper.selectIntegralityByLineIndexAndTime(temp, startTime, endTime);
                        if (simTemp != null) {
                            sim = mergeSim(sim, simTemp);
                        }
                        temp.clear();
                        length = length - 1000;
                    } else {
                        SimpleValue simTemp = integrityMapper.selectIntegralityByLineIndexAndTime(lineIndexTemp, startTime, endTime);
                        if (simTemp != null) {
                            sim.setCountOnline(sim.getCountOnline() + simTemp.getCountOnline());
                            sim.setCountAll(sim.getCountAll() + simTemp.getCountAll());
                        }
                    }
                }
            } else {
                sim = integrityMapper.selectIntegralityByLineIndexAndTime(lineIndexTemp, startTime, endTime);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return sim;
    }

    /**
     * 根据监测点索引获取数据完整性(国网)
     *
     * @param lineIndexs 监测点索引
     * @param startTime  起始时间
     * @param endTime    截止时间
     */
    public SimpleValue selectGwIntegralityByLineIndexAndTime(List<Integer> lineIndexs, Date startTime, Date endTime) {
        SimpleValue sim = new SimpleValue();
        if (CollectionUtils.isEmpty(lineIndexs)) {
            return null;
        }
        try {
            List<Integer> lineIndexTemp = new ArrayList<>(lineIndexs);
            int length = lineIndexTemp.size();
            if (length > 1000) {
                //需要循环的次数
                int times = length / 1000 + 1;
                for (int i = 1; i <= times; i++) {
                    if (length > 1000) {
                        List<Integer> temp = lineIndexTemp.subList(0, 1000);
                        SimpleValue simTemp = integrityMapper.selectGwIntegralityByLineIndexAndTime(temp, startTime, endTime);
                        if (simTemp != null) {
                            sim = mergeSim(sim, simTemp);
                        }
                        temp.clear();
                        length = length - 1000;
                    } else {
                        SimpleValue simTemp = integrityMapper.selectGwIntegralityByLineIndexAndTime(lineIndexTemp, startTime, endTime);
                        if (simTemp != null) {
                            sim.setCountOnline(sim.getCountOnline() + simTemp.getCountOnline());
                            sim.setCountAll(sim.getCountAll() + simTemp.getCountAll());
                        }
                    }
                }
            } else {
                sim = integrityMapper.selectGwIntegralityByLineIndexAndTime(lineIndexTemp, startTime, endTime);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return sim;
    }


    /**
     * 判断当前系统下需要查询终端的条件 devmodel 1为实际设备
     */
    public DeviceType getOnLineDeviceType() {
        DeviceType deviceType = new DeviceType();
        deviceType.setDevModel(1);
        return getDataType(deviceType);
    }


    /**
     * 判断当前系统下需要查询终端的条件,获取离线的终端 devmodel 2为离线设备
     */
    public DeviceType getOffLineDeviceType() {
        DeviceType deviceType = new DeviceType();
        deviceType.setDevModel(2);
        return getDataType(deviceType);
    }

    /**
     * 获取装置的数据类型，是稳态还是暂态的
     */
    private DeviceType getDataType(DeviceType deviceType) {
        List<Integer> dataType = new ArrayList<>();
        dataType.add(2);
        String sysType = getSysType();
        if (sysType.equalsIgnoreCase(ProjectEnum.PQS9000.getKey())) {
            dataType.add(1);
        } else if (sysType.equalsIgnoreCase(ProjectEnum.PQS9200.getKey())) {
            dataType.add(0);
        } else if (sysType.equalsIgnoreCase(ProjectEnum.PQS9300.getKey())) {
            dataType.add(1);
        }
        deviceType.setDataType(dataType);
        return deviceType;
    }


    /**
     * 根据当前用户获取所有的供电公司ID
     */
    public List<Integer> listGD() {
        List<Integer> listGD = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAreaGeneral();
        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listGD;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listGD.addAll(areaGeneralData.getGdIndexs());
        }
        return listGD;
    }

    /**
     * 查询所有的供电公司索引
     */
    public List<Integer> allGD() {
        List<Integer> allGd = new ArrayList<>();
        List<GDInformation> gdInformations = gdInforMapper.selectAll();
        if (!CollectionUtils.isEmpty(gdInformations)) {
            for (GDInformation gdInformation : gdInformations) {
                allGd.add(gdInformation.getGdIndex().intValue());
            }
        }
        return allGd;
    }

    /**
     * 查询所有的变电站索引
     */
    public List<Integer> listSu() {
        List<Integer> listSu = new ArrayList<>();
        List<SubStation> su = subStationMapper.selectAll();
        if (!CollectionUtils.isEmpty(su)) {
            for (SubStation subStation : su) {
                listSu.add(subStation.getSubIndex().intValue());
            }
        }
        return listSu;
    }

    /**
     * 根据当前用户获取所有的在线监测点ID
     */
    public List<Integer> listLine() {
        List<Integer> listLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAreaGeneral();
        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listLine;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listLine;
    }

    /**
     * 根据当前用户获取所有的在线监测点ID(具有电度的终端)
     */
    public List<Integer> listPlateLine() {
        List<Integer> listLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAreaPlateGeneral();
        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listLine;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listLine;
    }

    /**
     * 根据当前用户获取所有的在线监测点ID
     */
    public List<Integer> listLineRun() {
        List<Integer> listLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAreaGeneralRun();
        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listLine;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }
        listLine = listLine.stream().distinct().collect(Collectors.toList());
        return listLine;
    }

    /**
     * 获取当前系统的国网监测点索引
     */
    public List<Integer> getGWLine() {
        DeviceType deviceType = getOnLineDeviceType();
        List<Integer> gwLineIndexs = lineMapper.getGwLinesByDeviceType(deviceType.getDataType());
        return gwLineIndexs;
    }

    /**
     * 获取当前系统的国网监测点索引(电度)
     */
    public List<Integer> getGWPlateLine() {
        DeviceType deviceType = getOnLineDeviceType();
        List<Integer> gwLineIndexs = lineMapper.getGwLinesByDevicePlateType(deviceType.getDataType());
        return gwLineIndexs;
    }

    /**
     * 根据当前用户获取所有的离线监测点ID
     */
    public List<Integer> listOffLine() {
        List<Integer> listOffLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAreaGeneralOffLine();
        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listOffLine;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listOffLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listOffLine;
    }

    /**
     * 根据当前用户获取所有的在线监测点ID
     */
    public List<Integer> listLineDepts(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        List<Integer> listLine = new ArrayList<>();
        if (CollectionUtils.isEmpty(ag)) {
            return listLine;
        }
        for (AreaGeneralData areaGeneralData : ag) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listLine;
    }

    /**
     * 获取当前区域下的所有供电公司id
     */

    /**
     * 根据当前用户获取所有的在线监测点ID
     */
    public List<Integer> listGdIndex(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        List<Integer> listGd = new ArrayList<>();
        if (CollectionUtils.isEmpty(ag)) {
            return listGd;
        }
        for (AreaGeneralData areaGeneralData : ag) {
            listGd.addAll(areaGeneralData.getGdIndexs());
        }
        return listGd;
    }

    /**
     * 根据当前用户获取所有的离线监测点ID
     */
    public List<Integer> listOffLineDepts(String deptsIndex) {
        List<AreaGeneralData> ag;
        Depts depts = getDeptsByIndex(deptsIndex);
        DeviceType deviceType = getOffLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        ag = getAreaDatas(depts, deviceType);
        List<Integer> listOffLine = new ArrayList<>();
        if (CollectionUtils.isEmpty(ag)) {
            return listOffLine;
        }
        for (AreaGeneralData areaGeneralData : ag) {
            listOffLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listOffLine;
    }


    /**
     * 根据系统获取所有的部门信息
     * 部门没有系统区分
     */
    public List<Depts> getDepts() {
        Depts dept = new Depts();
        dept.setState(1);
        List<Depts> depts = deptsMapper.select(dept);
        if (CollectionUtils.isEmpty(depts)) {
            return new ArrayList<>();
        }
        return depts;
    }


    /**
     * @return 返回合乎用户的所有离线监测点索引
     */
    public List<Integer> getAllOffLineIndexs(String deptsIndex) {
        List<AreaGeneralData> areaGeneralOffDatas = getAreaDataByInfoOffLine(deptsIndex);
        List<Integer> offLineIndex = new ArrayList<>();
        if (!CollectionUtils.isEmpty(areaGeneralOffDatas)) {
            for (AreaGeneralData areaGeneralData : areaGeneralOffDatas) {
                offLineIndex.addAll(areaGeneralData.getLineIndexs());
            }
        }
        return offLineIndex;
    }


    /**
     * @return 返回合乎用户的所有监测点索引
     */
    public List<Integer> getAllLineIndexs(String deptsIndex) {
        List<AreaGeneralData> areaGeneralDatas = getAreaDataByInfoRun(deptsIndex);
        List<Integer> linesIndex = new ArrayList<>();
        if (!CollectionUtils.isEmpty(areaGeneralDatas)) {
            for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
                linesIndex.addAll(areaGeneralData.getLineIndexs());
            }
        }
        return linesIndex;
    }


    /**
     * @return 返回合乎用户的所有装置索引
     */
    public Map<Integer, List<Integer>> getDeviceAndLineIndexs(String deptsIndex) {
        Map<Integer, List<Integer>> data = new HashMap<>();
        List<Integer> deviceIndex = new ArrayList<>();
        List<Integer> lineIndex = new ArrayList<>();
        List<AreaGeneralData> areaGeneralDatas = getAreaDataByInfo(deptsIndex);
        if (!CollectionUtils.isEmpty(areaGeneralDatas)) {
            for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
                deviceIndex.addAll(areaGeneralData.getDeviceIndexs());
                lineIndex.addAll(areaGeneralData.getLineIndexs());
            }
        }
        //没有任何装置
        if (CollectionUtils.isEmpty(deviceIndex)) {
            return data;
        }
        //否则挨个遍历出当前装置下有哪些监测点索引
        for (Integer index : deviceIndex) {
            List<Integer> linexIndexTemp = lineMapper.getLineIndexSingle(index, lineIndex);
            if (!CollectionUtils.isEmpty(linexIndexTemp)) {
                data.put(index, linexIndexTemp);
            }
        }
        return data;
    }


    /**
     * 获取服务器的前置类型、系统类型
     */
    public DicData getPreSysType(String ServerIndex) {
        DicData dicData = new DicData();
        try {
            dicData.setDicIndex(ServerIndex);
        } catch (Exception e) {
            logger.error("获取类型异常，异常是" + toString());
        }
        return dicDataMapper.selectOne(dicData);
    }

    /**
     * 随机生成token保存进session
     * 为了避免CSRF攻击，前台敏感操作需要校验token
     */
    public void saveRandomToken() {
        Session session = TokenManager.getSession();
        session.setAttribute("token", UUID.randomUUID().toString());
        session.setAttribute("username", TokenManager.getToken().getLoginName());
    }

    /*
     * 根据字典索引获取字典名称
     */
    public String getDicnameByIndex(String dicIndex) {
        DicData dicData = new DicData();
        try {
            dicData.setDicIndex(dicIndex);
        } catch (Exception e) {
            logger.error("获取类型异常，异常是" + toString());
        }
        dicData = dicDataMapper.selectOne(dicData);

        return dicData.getDicName();
    }

    /**
     * 根据部门索引判断是认为高级用户
     */
    public String getPro(String deptsIndex) {
        List<Depts> depts = getDeptsByNode(deptsIndex);
        //只要含有子孙节点则就是高级部门
        if (CollectionUtils.isEmpty(depts)) {
            return "normal";
        } else {
            return "senior";
        }
    }

    /**
     * 区域概览单独使用的，控制返回上一级按钮显示
     */
    public String getRoot(String deptsIndex) {
        Depts dept = getDeptsByIndex(deptsIndex);
        Depts parentDepts = getDeptsByIndex(dept.getParentNodeId());
        //没有父节点
        if (null == parentDepts) {
            return "root";
        }
        Depts currentDept = getCurrentDept();
        //四川省虽然有子部门，且有父级部门，如果用户当前的部门绑定的是四川，同样不可以查看全国
        if (dept.getDeptsIndex().equalsIgnoreCase(currentDept.getDeptsIndex())) {
            return "root";
        }
        return "unroot";
    }


    /**
     * 需求： 实际运行设备的数据
     * 根据用户返回地级市集合，内容包括
     * 1：地市名称 2：监测点数 3 每个地市下的所有监测点索引 4每个地市下的所有终端索引 5每个地市下的所有变电站索引 6每个地市下的所有供电公司索引
     */
    public List<AreaGeneralData> getAppAreaGeneral(String user_id) {
        List<AreaGeneralData> ag;

        User user = userMapper.getAppBaseUser(user_id);

        if (null == user) {
            return new ArrayList<>();
        }

        Depts depts = getDeptsByUser(user);
        DeviceType deviceType = getOnLineDeviceType();

        if (null == depts) {
            return new ArrayList<>();
        }

        ag = getAreaDatas(depts, deviceType);
        return ag;
    }

    /**
     * 根据当前用户获取所有的在线监测点ID
     */
    public List<Integer> ApplistLine(String user_id) {
        List<Integer> listLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = getAppAreaGeneral(user_id);

        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }

        return listLine;
    }

    /***
     * 根据当前用户获取下面的终端
     */
    public List<Integer> ApplistDev(String user_id) {
        List<Integer> listLine = ApplistLine(user_id);
        List<Integer> listDev = new ArrayList<>();
        if (!listLine.isEmpty()) {
            listDev = deviceMapper.getDeviceIndex(listLine);
        }
        //查询终端
        return listDev;
    }

    /**
     * 获取所有需要发送邮件的用户
     */
    public List<User> listMailUser() {
        List<User> users = new ArrayList<>();
        users = userMapper.getMailUsers();

        return users;
    }

    /**
     * 根据用户ID获取对应权限的监测点
     */
    public List<Integer> listLineByUserId(String userId) {
        List<Integer> listLine = new ArrayList<>();
        List<AreaGeneralData> listAreaGeneralData = new ArrayList<>();

        User usr = new User();
        usr.setUserIndex(userId);
        Depts depts = getDeptsByUser(usr);

        DeviceType deviceType = getOnLineDeviceType();
        if (null == depts) {
            return new ArrayList<>();
        }
        listAreaGeneralData = getAreaDatas(depts, deviceType);

        if (CollectionUtils.isEmpty(listAreaGeneralData)) {
            return listLine;
        }
        for (AreaGeneralData areaGeneralData : listAreaGeneralData) {
            listLine.addAll(areaGeneralData.getLineIndexs());
        }
        return listLine;
    }

    public boolean judgeLimit(Integer index, Long timeId) {
        Long num = limitRateMapper.sumlimitRate(index, new Date(timeId));

        if (num != null && num > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据电压等级、干扰源类型、终端厂家筛选
     */
    public List<AreaGeneralData> siftAreaGeneralData(List<AreaGeneralData> areaGeneralDatas, String scale, String manc, String loadType, String devLocation) {
        List<AreaGeneralData> result = new ArrayList<>();

        for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
            AreaGeneralData areaGeneralDataTmp = new AreaGeneralData();
            List<Integer> lineIndexs = areaGeneralData.getLineIndexs();
            if (CollectionUtils.isEmpty(lineIndexs)) {
                continue;
            }
            List<IndexsCount> indexs = lineMapper.siftAllIndexs(lineIndexs, scale, manc, loadType, devLocation);
            if (CollectionUtils.isEmpty(indexs)) {
                areaGeneralDataTmp.setMonitors(0);
            } else {
                areaGeneralDataTmp = filtIndexData(indexs, areaGeneralData);
                result.add(areaGeneralDataTmp);
            }
        }
        return result;
    }

    public List<Integer> getDevIndex (){
        String sysType = getSysType();
        List<Integer> dataType = new ArrayList<>();
        if (sysType.equalsIgnoreCase(ProjectEnum.PQS9000.getKey())) {
            dataType.add(1);
        } else if (sysType.equalsIgnoreCase(ProjectEnum.PQS9200.getKey())) {
            dataType.add(0);
        }
        dataType.add(2);
        return deviceMapper.getDevIndex(dataType);
    }

    /**
     * 根据电压等级、干扰源类型、终端厂家筛选
     */
    public List<AreaGeneralData> siftAreaGeneralDataByLineGrade(List<AreaGeneralData> areaGeneralDatas, String scale, String manc, String loadType,Integer lineGrade) {
        List<AreaGeneralData> result = new ArrayList<>();

        for (AreaGeneralData areaGeneralData : areaGeneralDatas) {
            AreaGeneralData areaGeneralDataTmp = new AreaGeneralData();
            List<Integer> lineIndexs = areaGeneralData.getLineIndexs();
            if (CollectionUtils.isEmpty(lineIndexs)) {
                continue;
            }
            List<IndexsCount> indexs = lineMapper.siftAllIndexsByLineGrade(lineIndexs, scale, manc, loadType,lineGrade);
            if (CollectionUtils.isEmpty(indexs)) {
                areaGeneralDataTmp.setMonitors(0);
            } else {
                areaGeneralDataTmp = filtIndexData(indexs, areaGeneralData);
                result.add(areaGeneralDataTmp);
            }
        }
        return result;
    }

}
