package com.dxhy.admin.sys.service.impl;

import java.util.*;

import javax.annotation.Resource;

import com.dxhy.common.util.StringHelper;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxhy.admin.sys.config.AdminConfig;
import com.dxhy.admin.sys.config.SysConfig;
import com.dxhy.admin.sys.dao.SysUserDao;
import com.dxhy.admin.sys.entity.*;
import com.dxhy.admin.sys.model.*;
import com.dxhy.admin.sys.service.*;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.constant.RedisConstant;
import com.dxhy.common.constant.UserConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.util.redis.RedisUtils;
import com.dxhy.common.utils.Aops;
import com.dxhy.common.utils.Constant;
import com.dxhy.common.utils.PageUtils;
import com.dxhy.common.utils.Query;
import com.dxhy.common.vo.TaxOrgCode;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 系统用户
 *
 * @author jiaohongyang
 */
@SuppressWarnings({"AlibabaCollectionInitShouldAssignCapacity", "AlibabaUndefineMagicConstant"})
@Service("sysUserService")
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {

    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private SysMenuService sysMenuService;
    @Resource
    private SysUserOrgService sysUserOrgService;
    @Resource
    private SysUserBusinessService sysUserBusinessService;
    @Resource
    private SysTabulateDeptService sysTabulateDeptService;
    @Resource
    private LoginService loginService;
    @Resource
    private RedisUtils redisUtils;

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryAllMenuId(userId);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        String username = (String) params.get("username");
        String company = (String) params.get("company");
        String deptId = (String) params.get("deptId");
        String taxno = (String) params.get("taxno");
        Integer userType = (Integer) params.get("userType");
        IPage<SysUserEntity> page = this.page(new Query<SysUserEntity>().getPage(params),
                new QueryWrapper<SysUserEntity>().like(StringUtils.isNotBlank(username), "username", username)
                        .eq(StringUtils.isNotBlank(deptId), "dept_id", deptId)
                        .eq(StringUtils.isNotBlank(company), "company", company)
                        .eq(StringUtils.isNotBlank(taxno), "taxno", taxno)
                        .eq(StringUtils.isNotBlank(taxno), "user_type", userType)
                        .apply(params.get(Constant.SQL_FILTER) != null, (String) params.get(Constant.SQL_FILTER)));

        List<SysUserEntity> records = page.getRecords();
        if (records != null && records.size() > 0) {
            for (SysUserEntity sysUserEntity : records) {
                SysDeptEntity sysDeptEntity = sysDeptService.getById(sysUserEntity.getDeptId());
                if (sysDeptEntity != null) {
                    sysUserEntity.setDeptName(sysDeptEntity.getName());
                }
            }
        }

        return new PageUtils(page);
    }

    @Override
    public void saveUser(SysUserEntity user) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        user.setCreateTime(DateUtil.date());
        user.setUpdateTime(DateUtil.date());
        // 查询用户关联菜单信息
        Aops.getSelf(this).insertUser(user);
        this.insertRedis(user);
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        this.uploadUser(user);
    }

    @Transactional(rollbackFor = Exception.class)
    public void insertUser(SysUserEntity user) {
        user.setCreateTime(new Date());
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setSalt(salt);
        user.setScanType("5");
        user.setPlpassword(Base64.encode(user.getPassword()));
        user.setPassword(new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(user.getPassword()));
        this.saveOrUpdate(user);
        // 保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
        // 获取关联 数据权限
        sysUserOrgService.saveOrUpdate(user.getUserId(), user.getUserOrgEntities());
        // 保存用户与业务单元关系
        if (user.getBusinessList() != null && user.getBusinessList().size() > 0) {
            sysUserBusinessService.saveOrUpdate(user.getUserId(), user.getBusinessList());
        }

    }

    @Override
    public void update(SysUserEntity user) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        user.setUpdateTime(DateUtil.date());
        Aops.getSelf(this).updateUser(user);
        this.insertRedis(user);
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        this.uploadUser(user);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateUser(SysUserEntity user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            user.setPlpassword(Base64.encode(user.getPassword()));
            user.setPassword(new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(user.getPassword()));
        }
        this.saveOrUpdate(user);
        // 保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
        // 获取关联 数据权限
        sysUserOrgService.saveOrUpdate(user.getUserId(), user.getUserOrgEntities());
        // 保存用户与业务单元关系
        sysUserBusinessService.saveOrUpdate(user.getUserId(), user.getBusinessList());
    }

    @Override
    public boolean updatePassword(Long userId, String password, String newPassword) {
        SysUserEntity user = this.selectUserById(userId);
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        return Aops.getSelf(this).updateNewPassword(userId, password, newPassword, user);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateNewPassword(Long userId, String password, String newPassword, SysUserEntity user) {
        if (password.equals(user.getPlpassword()) || password.equals(Base64.decodeStr(user.getPlpassword()))) {
            user.setPassword(new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(newPassword));
            user.setPlpassword(Base64.encode(newPassword));
            return this.update(user, new QueryWrapper<SysUserEntity>().eq("user_id", userId));
        } else {
            return false;
        }
    }

    public SysUserEntity selectUserById(Long userId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.selectById(userId);
    }

    @Override
    public SysUserEntity queryUserName(String loginname, Long userId) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryUserName(loginname, userId);
    }

    @Override
    public User getUser(String loginname) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        User userInfo = null;
        try {
            userInfo = redisUtils.get(RedisConstant.KEY_USER_MENU + loginname, User.class, -1);
            if (userInfo != null) {
                // 存储数据字典
                return userInfo;
            } else {
                userInfo = new User();
                // 获取用户信息
                SysUserEntity userEntity = baseMapper.queryUserName(loginname, null);
                userInfo = this.getUserInfo(userEntity);
                redisUtils.set(RedisConstant.KEY_USER_MENU + loginname, userInfo, -1);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("返回用户信息：{}", JSON.toJSON(userInfo));
        return userInfo;
    }

    public User toUser(User user, SysUserEntity userEntity) {

        user.setUserId(userEntity.getUserId());
        user.setStatus(userEntity.getStatus());
        user.setCompany(userEntity.getCompany());
        user.setWebscoketUrl(AdminConfig.webscoketUrl);
        // 新增 供应商用到
        user.setUserType(userEntity.getUserType());
        user.setTaxno(userEntity.getTaxno());
        user.setUserCode(userEntity.getUserCode());
        user.setZpAmount(userEntity.getZpAmount());
        user.setPpAmount(userEntity.getPpAmount());
        user.setKpType(userEntity.getKpType());
        user.setKpUser(userEntity.getKpUser());
        user.setSkUser(userEntity.getSkUser());
        user.setFhUser(userEntity.getFhUser());
        user.setSpType(userEntity.getSpType());
        user.setSpCode(userEntity.getSpCode());
        user.setCertPassword(userEntity.getCertPassword());
        user.setTaxPassword(userEntity.getTaxPassword());
        return user;
    }

    @Override
    public User getUserInfo(SysUserEntity userEntity) {

        User user = new User();

        List<TaxOrgCode> orgCodeList = new ArrayList<>();
        List<SysUserOrgEntity> userOrgEntity = new ArrayList<>();

        try {
            // 获取用户信息
            long userId = userEntity.getUserId();

            // 获取用户关联业务单元信息
            List<SysUserBusinessEntity> businessList = sysUserBusinessService.queryUserId(userId);

            BeanUtil.copyProperties(userEntity, user);
            // 获取机构编码
            List<SysDeptEntity> queryDept;
            if (SysConfig.UserType.USET_TYPE_1.getCode().equals(user.getUserType())) {
                queryDept = sysUserOrgService.queryOrgCodes(userId);
            } else {
                queryDept = sysDeptService.queryDept(userEntity.getCompany(), SysConfig.OrgType.ORG_TYPE_5.getCode());
            }
            toDeptOrgCode(user, orgCodeList, queryDept);

            // 获取用户关联数据权限信息
            if (SysConfig.UserType.USET_TYPE_1.getCode().equals(userEntity.getUserType())) {
                List<SysUserOrgEntity> queryOrgList = sysUserOrgService.queryOrgIdList(userId);
                if (queryOrgList != null && queryOrgList.size() > 0) {
                    for (SysUserOrgEntity sysUserOrgEntity : queryOrgList) {
                        sysUserOrgEntity.setDeptId(null);
                        sysUserOrgEntity.setId(null);
                        sysUserOrgEntity.setUserid(null);
                        userOrgEntity.add(sysUserOrgEntity);
                    }
                }
            } else {
                if (queryDept.size() > 0) {
                    for (SysDeptEntity sysDeptEntity : queryDept) {
                        SysUserOrgEntity org = new SysUserOrgEntity();
                        org.setTaxno(sysDeptEntity.getTaxno());
                        org.setTaxname(sysDeptEntity.getTaxname());
                        org.setCompany(sysDeptEntity.getCompany());
                        userOrgEntity.add(org);
                    }
                }
            }
            //获取组织编码
            List<SysCompanyEntity> companyEntitys = sysUserOrgService.getOrgsByUserId(userEntity.getUserId());
            if (companyEntitys != null && companyEntitys.size() > 0) {
                for (SysCompanyEntity companyEntity : companyEntitys) {
                    if (companyEntity != null) {
                        if (StringHelper.isNotBlank(companyEntity.getCompanyCode()) && StringHelper.isNotBlank(companyEntity.getCompanyName())) {
                            String companyName = "(" + companyEntity.getCompanyCode() + ")" + companyEntity.getCompanyName();
                            companyEntity.setCompanyName(companyName);
                        }
                    }
                }
                SysCompanyEntity company = new SysCompanyEntity();
                company.setCompanyName("()暂无组织编码发票");
                company.setCompanyCode("88");
                companyEntitys.add(company);
            }

            user = this.toUser(user, userEntity);
            user.setPassword("");
            user.setUserOrg(userOrgEntity);
            user.setUserBusiness(businessList);
            user.setCompanyCodes(companyEntitys);

            user.setUserModels(this.getUserCompanyList(userEntity.getCompany()));
            // 刷新菜单缓存处理
            this.setMetnuRedis(userEntity.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return user;
    }

    private List<UserModel> getUserCompanyList(String company) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.getUserCompanyList(company);
    }

    private MenuModel setMetnuRedis(long userId) {
        MenuModel menuModel = new MenuModel();
        List<SysMenuEntity> userMenuList = sysMenuService.getUserMenuList(userId);
        List<SysMenuEntity> childPerms = this.getChildPerms(userMenuList, 0);
        List<RouterVo> routerVos = this.toRouter(childPerms);
        Map<String, SysMenuEntity> menuEntityMap = this.toMenuList(childPerms);
        menuModel.setMenuList(menuEntityMap);
        menuModel.setMenus(routerVos);
        redisUtils.set(RedisConstant.KEY_USER_MENU + userId, menuModel, -1);
        return menuModel;
    }

    /**
     * 保存字典缓存
     *
     * @return 返回字典信息
     */
    private Map<String, List<SysDictdetaEntity>> getDictMap() {
        Set<String> keys = redisUtils.keys(RedisConstant.KEY_DICT);
        Map<String, List<SysDictdetaEntity>> map = new HashMap<>(keys.size());
        for (String key : keys) {
            String dicts = redisUtils.get(key);
            if (StringUtils.isNotBlank(dicts)) {
                List<SysDictdetaEntity> dictList = JSONObject.parseArray(dicts, SysDictdetaEntity.class);
                if (dictList.size() > 0) {
                    key = key.replace(RedisConstant.KEY_DICT, "");
                    map.put(key, dictList);
                }
            }
        }
        return map;
    }

    /**
     * 菜单路由转换
     *
     * @param childPerms 树状菜单信息
     * @return 转换后路由信息
     */
    private List<RouterVo> toRouter(List<SysMenuEntity> childPerms) {
        String path;
        boolean flg = false;
        RouterVo router;
        List<RouterVo> routerVos;

        if (childPerms.size() == 1) {
            childPerms = childPerms.get(0).getChildren();
            routerVos = this.buildMenus(childPerms);
        } else {
            routerVos = this.buildMenusSystem(childPerms);
        }
        if (routerVos != null && routerVos.size() > 0) {
            for (RouterVo routerVo : routerVos) {
                if (routerVo.getMenuType() != SysConfig.TYPE_SYSTEM) {
                    flg = true;
                    break;
                }
            }
            if (flg) {
                RouterVo routerVo = routerVos.get(0);
                List<RouterVo> children = routerVo.getChildren();
                if (children != null && children.size() > 0) {
                    path = children.get(0).getPath();
                    routerVo.setRedirect(path);
                    routerVo.setPath("");
                } else {
                    path = routerVo.getPath();
                    routerVo.setRedirect(path);
                    routerVo.setPath("");
                    router = new RouterVo();
                    List<RouterVo> childrenList = new ArrayList<>();
                    SysMenuEntity sysMenuEntity = childPerms.get(0);
                    router.setComponent(sysMenuEntity.getComponent());
                    router.setPath(sysMenuEntity.getUrl());
                    router.setMeta(new MetaVo(sysMenuEntity.getName(), sysMenuEntity.getIcon(), null,
                            sysMenuEntity.isNoCache(), null));
                    router.setName(StringUtils.capitalize(sysMenuEntity.getUrl().replaceAll("/", "")));
                    router.setMenuId(String.valueOf(sysMenuEntity.getMenuId()));
                    childrenList.add(router);
                    routerVo.setChildren(childrenList);
                    routerVo.setAlwaysShow(false);
                }
            } else {
                router = new RouterVo();
                router.setPath("/");
                RouterVo routerVo = routerVos.get(0);
                List<RouterVo> children = routerVo.getChildren();
                RouterVo routerVoDir = children.get(0);
                List<RouterVo> childrenMenu = routerVoDir.getChildren();
                if (childrenMenu != null && childrenMenu.size() > 0) {
                    log.info("无首页，默认跳转第一个目录第一个菜单");
                    router.setRedirect(childrenMenu.get(0).getPath());
                } else {
                    log.info("有首页，默认跳转首页");
                    router.setRedirect(routerVoDir.getPath());
                }
                routerVos.add(router);
            }
        } else {
            // 没有分配菜单权限返回跳转到欢迎页
            routerVos = new ArrayList<>();
            routerVos.add(this.toRouter());
        }
        return routerVos;
    }

    /**
     * 无菜单信息返回固定首页到欢迎页
     *
     * @return 路由信息
     */
    public RouterVo toRouter() {
        RouterVo routerVoM = new RouterVo();
        List<RouterVo> childrenList = new ArrayList<>();
        routerVoM.setPath("");
        routerVoM.setName("");
        routerVoM.setRedirect("/home");
        routerVoM.setAlwaysShow(false);
        routerVoM.setComponent(SysConfig.LAYOUT);
        routerVoM.setMeta(new MetaVo("首页", "icon_index_good", null, false, null));
        RouterVo router = new RouterVo();
        router.setComponent("home/index");
        router.setMeta(new MetaVo("首页", "icon_index_good", null, false, null));
        router.setName("Home");
        router.setPath("/home");
        router.setMenuId("");
        childrenList.add(router);
        routerVoM.setChildren(childrenList);
        return routerVoM;
    }

    private void toDeptOrgCode(User user, List<TaxOrgCode> orgCodeList, List<SysDeptEntity> queryDept) {
        log.info("查询到的企业列表为:{}", queryDept);
        String qsStatus = "0";
        String productType = "0";
        if (queryDept.size() > 0) {
            List<TaxOrgCode> oldTaxOrgCode = new ArrayList<>();
            for (SysDeptEntity sysDeptEntity : queryDept) {
                String orgCode = sysDeptEntity.getOrgCode();
                if (StringUtils.isNotBlank(orgCode) && orgCode.contains("旧")) {
                    oldTaxOrgCode.add(toTaxOrgCode(sysDeptEntity));
                } else {
                    orgCodeList.add(toTaxOrgCode(sysDeptEntity));
                }
            }
            orgCodeList.addAll(oldTaxOrgCode);
            qsStatus = queryDept.get(0).getQsStatus();
            productType = queryDept.get(0).getProductType();
            log.info("orgCodeList:{}", orgCodeList);
            user.setOrgCodes(orgCodeList);
            user.setQsStatus(qsStatus);
            user.setProductType(productType);
        }
    }

    private TaxOrgCode toTaxOrgCode(SysDeptEntity sysDeptEntity) {
        TaxOrgCode orgCode = new TaxOrgCode();
        if (StringUtils.isNotEmpty(sysDeptEntity.getTaxno())) {
            orgCode.setTaxno(sysDeptEntity.getTaxno());
            orgCode.setTaxname(sysDeptEntity.getTaxname());
            orgCode.setOrgCode(sysDeptEntity.getOrgCode());
            orgCode.setCompany(sysDeptEntity.getCompany());
            orgCode.setAreaCode(sysDeptEntity.getAreaCode());
            orgCode.setIsPassword(sysDeptEntity.getIsPassword());
        }
        return orgCode;
    }

    @Override
    public SysUserEntity queryUserById(Long id) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        SysUserEntity sysUserEntity = baseMapper.selectById(id);
        String plpassword = sysUserEntity.getPlpassword();
        sysUserEntity.setPlpassword(Base64.decodeStr(plpassword));
        return sysUserEntity;
    }

    @Override
    public void deleteUser(Long id) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).deleteUserById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteUserById(Long id) {
        baseMapper.deleteById(id);
    }

    @Override
    public boolean queryUserMenu(Long menuId) {
        try {
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysUserEntity user = baseMapper.queryUserMenu(menuId);
            return this.insertRedis(user);
        } catch (Exception e) {
            log.debug(e.getMessage());
            return false;
        }

    }

    @Override
    public boolean queryUserRole(Long roleId) {
        try {
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysUserEntity user = baseMapper.queryUserRole(roleId);
            this.getUserInfo(user);
            return this.insertRedis(user);
        } catch (Exception e) {
            log.debug(e.getMessage());
            return false;
        }
    }

    @Override
    public boolean queryUserBussiness(Long businessId) {
        try {
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            SysUserEntity user = baseMapper.queryUserBussiness(businessId);
            return this.insertRedis(user);
        } catch (Exception e) {
            log.debug(e.getMessage());
            return false;
        }
    }

    public boolean insertRedis(SysUserEntity user) {
        try {
            if (user != null) {
                // 保存用户信息到redis
                redisUtils.set(RedisConstant.KEY_USER_MENU + user.getLoginname(), this.getUserInfo(user), -1);
            }
            return true;
        } catch (Exception e) {
            log.debug(e.getMessage());
            return false;
        }

    }

    public void uploadUser(SysUserEntity user) {
        if (SysConfig.ITAX_SWITCH.equals(AdminConfig.itaxSwitch)
                && SysConfig.UserType.USET_TYPE_2.getCode().equals(user.getUserType())) {
            // 获取部门信息
            SysDeptEntity sysDeptEntity = sysDeptService.getById(user.getDeptId());
            Map<String, Object> map = new HashMap<>(9);
            map.put("name", sysDeptEntity.getName());
            map.put("taxpayerAccount", sysDeptEntity.getAccount());
            map.put("taxpayerAddress", sysDeptEntity.getAddress());
            map.put("taxpayerBank", sysDeptEntity.getBank());
            map.put("taxpayerCode", sysDeptEntity.getTaxno());
            map.put("taxpayerPhone", sysDeptEntity.getPhone());
            map.put("parentId", AdminConfig.parentId);
            map.put("deptSname", sysDeptEntity.getName());
            map.put("deptId", sysDeptEntity.getDeptId());
            log.debug("推送部门入参" + map);
            HttpUtil.post(AdminConfig.itaxDept, map, 60000);
            map = new HashMap<>(6);
            map.put("username", user.getUsername());
            map.put("deptId", user.getDeptId());
            map.put("name", user.getUsername());
            map.put("mobile", user.getMobile());
            map.put("password", user.getPlpassword());
            map.put("roleIdList", user.getRoleIdList());
            log.debug("推送用户入参" + map);
            HttpUtil.post(AdminConfig.itaxUser, map, 60000);
        }
    }

    @Override
    public boolean refreshCache(boolean flg, String loginName) {

        log.debug("刷新缓存开始");
        try {
            List<SysUserEntity> userList = null;
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            if (StringUtils.isBlank(loginName)) {
                userList = baseMapper.selectList(null);
            } else {
                userList = baseMapper.selectList(new QueryWrapper<SysUserEntity>().eq("loginname", loginName));
            }

            log.debug("刷新缓存查询到用户信息：" + userList.size());
            if (userList.size() > 0) {
                for (SysUserEntity sysUserEntity : userList) {
                    // 保存用户信息到redis
                    redisUtils.set(RedisConstant.KEY_USER_MENU + sysUserEntity.getLoginname(),
                            this.getUserInfo(sysUserEntity), -1);
                    redisUtils.set(RedisConstant.KEY_USER_TOKEN + sysUserEntity.getLoginname(),
                            loginService.infoListRedis(sysUserEntity.getLoginname()), RedisUtils.NOT_EXPIRE);
                }
            }
            // 刷新显示列表缓存、只刷新中心企业
            if (flg) {
                sysTabulateDeptService.refreshCache(SysConfig.ZXQY);
            }
            return true;
        } catch (Exception e) {
            log.debug(e.getMessage());
            return false;
        }

    }

    @Override
    public String getDict() {
        return Base64.encode(redisUtils.get(RedisConstant.DICT));
    }

    @Override
    public String getMenu(long userId) {
        String menuString = redisUtils.get(RedisConstant.KEY_USER_MENU + userId);
        if (StringUtils.isNotBlank(menuString)) {
            return Base64.encode(menuString);
        } else {
            return Base64.encode(JSON.toJSONString(this.setMetnuRedis(userId)));
        }
    }

    @Override
    public void deleteUserBigb(Long id) {
        DynamicContextHolder.push(DbConstant.BASICS_WRITE);
        Aops.getSelf(this).deleteUserById(id);
        sysUserOrgService.delete(id);
    }

    /**
     * 构建前端路由所需要的菜单
     *
     * @param menus 菜单列表
     * @return 路由列表
     */
    public List<RouterVo> buildMenus(List<SysMenuEntity> menus) {
        List<RouterVo> routers = new LinkedList<>();
        for (SysMenuEntity menu : menus) {
            RouterVo router = new RouterVo();
            router.setMenuId(String.valueOf(menu.getMenuId()));

            if (menu.getType() == SysConfig.TYPE_MENU) {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            } else {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));

            }
            router.setPath(menu.getUrl());

            if (menu.getType() == SysConfig.TYPE_DIR) {
                router.setName("");
                router.setComponent(SysConfig.LAYOUT);
            } else {
                router.setComponent(menu.getComponent());
                router.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
            }
            router.setMenuType(menu.getType());
            router.setSystemCode(menu.getMenuCode());
            List<SysMenuEntity> cMenus = menu.getChildren();
            if (SysConfig.TYPE_DIR == menu.getType() && cMenus != null && cMenus.size() > 0) {
                router.setAlwaysShow(true);
                router.setRedirect(menu.getUrl() + "/index");
                router.setChildren(buildMenus(cMenus));
            } else if (isMeunFrame(menu)) {
                log.info("不是菜单并且不等于0");
                List<RouterVo> childrenList = new ArrayList<>();
                RouterVo children = new RouterVo();
                children.setPath(menu.getUrl());
                children.setComponent(menu.getComponent());
                children.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
                children.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
                childrenList.add(children);
                router.setChildren(childrenList);
            }
            routers.add(router);
        }
        return routers;
    }

    /**
     * 构建前端路由所需要的菜单
     *
     * @param menus 菜单列表
     * @return 路由列表
     */
    public List<RouterVo> buildMenusSystem(List<SysMenuEntity> menus) {
        List<RouterVo> routers = new LinkedList<>();
        for (SysMenuEntity menu : menus) {
            RouterVo router = new RouterVo();
            router.setMenuId(String.valueOf(menu.getMenuId()));
            if (menu.getType() == SysConfig.TYPE_SYSTEM) {
                router.setName("");
            } else {
                router.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
            }

            router.setPath(menu.getUrl());

            if (menu.getType() != SysConfig.TYPE_SYSTEM) {
                router.setComponent(menu.getComponent());
            } else {
                router.setComponent(SysConfig.LAYOUT);
            }
            if (menu.getType() == SysConfig.TYPE_MENU) {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            } else {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            }
            router.setMenuType(menu.getType());
            router.setSystemCode(menu.getMenuCode());
            List<SysMenuEntity> cMenus = menu.getChildren();
            boolean typeFlg = SysConfig.TYPE_SYSTEM == menu.getType() || SysConfig.TYPE_DIR == menu.getType();
            if (typeFlg && cMenus != null && cMenus.size() > 0) {
                router.setAlwaysShow(true);
                router.setRedirect("noRedirect");
                router.setChildren(buildMenusSystem(cMenus));
            } else if (isMeunFrame(menu)) {
                log.info("不是菜单并且不等于0");
                List<RouterVo> childrenList = new ArrayList<>();
                RouterVo children = new RouterVo();
                children.setPath(menu.getUrl());
                children.setComponent(menu.getComponent());
                children.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
                children.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
                childrenList.add(children);
                router.setChildren(childrenList);
            }
            routers.add(router);
        }
        return routers;
    }

    /**
     * 转换按钮信息
     *
     * @param sysMenuEntity 菜单信息
     * @return 按钮信息
     */
    public ButtonQueryVo toButtonQuery(SysMenuEntity sysMenuEntity) {
        ButtonQueryVo buttonQueryVo = new ButtonQueryVo();
        List<ButtonVo> buttonVoList = new ArrayList<>();
        List<QueryVo> queryVoList = new ArrayList<>();
        List<SysMenuEntity> children = sysMenuEntity.getChildren();
        if (children != null && children.size() > 0) {
            for (SysMenuEntity menuEntity : children) {
                if (3 == menuEntity.getType()) {
                    buttonVoList.add(new ButtonVo(menuEntity.getMenuCode(), menuEntity.getName(), menuEntity.getUrl()));
                }
                if (4 == menuEntity.getType()) {
                    queryVoList.add(new QueryVo(menuEntity.getMenuCode(), menuEntity.getName()));
                }
            }
        }
        buttonQueryVo.setButtonVos(buttonVoList);
        buttonQueryVo.setQueryVos(queryVoList);
        return buttonQueryVo;

    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
    @Override
    public List<SysMenuEntity> getChildPerms(List<SysMenuEntity> list, int parentId) {
        List<SysMenuEntity> returnList = new ArrayList<>();
        for (SysMenuEntity t : list) {
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {

                recursionFn(list, t);
                returnList.add(t);
            }
        }
        log.debug("树状结构：{}", JSON.toJSONString(returnList));
        return returnList;
    }

    @Override
    public SysUserEntity queryUserByEmail(String principal) {
        DynamicContextHolder.push(DbConstant.BASICS_READ);
        return baseMapper.queryUserByEmail(principal);
    }

    /**
     * 递归列表
     *
     * @param list 菜单列
     * @param t    菜单信息
     */
    private void recursionFn(List<SysMenuEntity> list, SysMenuEntity t) {
        // 得到子节点列表
        List<SysMenuEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenuEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysMenuEntity n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenuEntity> getChildList(List<SysMenuEntity> list, SysMenuEntity t) {
        List<SysMenuEntity> tlist = new ArrayList<>();
        for (SysMenuEntity n : list) {
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenuEntity> list, SysMenuEntity t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 是否为系统信息
     *
     * @param menu 菜单信息
     * @return 结果
     */
    public boolean isMeunFrame(SysMenuEntity menu) {
        return menu.getParentId().intValue() == 0 && SysConfig.TYPE_MENU == menu.getType();
    }

    /**
     * 菜单信息
     *
     * @param menuEntities 菜单信息
     * @return 菜单信息
     */
    public Map<String, SysMenuEntity> toMenuList(List<SysMenuEntity> menuEntities) {
        Map<String, SysMenuEntity> map = new HashMap<>();
        if (menuEntities.size() > 0) {
            for (SysMenuEntity sysMenuEntity : menuEntities) {
                if (0 == sysMenuEntity.getType()
                        && (sysMenuEntity.getChildren() != null && sysMenuEntity.getChildren().size() > 0)) {
                    List<SysMenuEntity> childrenDirList = sysMenuEntity.getChildren();
                    if (childrenDirList.size() > 0) {
                        for (SysMenuEntity childrenDir : childrenDirList) {
                            List<SysMenuEntity> childrenMenuList = childrenDir.getChildren();

                            if (1 == childrenDir.getType()
                                    && (childrenMenuList != null && childrenMenuList.size() > 0)) {
                                for (SysMenuEntity childrenMenu : childrenMenuList) {
                                    if (2 == childrenMenu.getType()) {
                                        ButtonQueryVo buttonQueryVo = this.toButtonQuery(childrenMenu);
                                        childrenMenu.setMeta(
                                                new MetaVo(childrenMenu.getName(), "", buttonQueryVo.getButtonVos(),
                                                        childrenMenu.isNoCache(), buttonQueryVo.getQueryVos()));
                                        map.put(childrenMenu.getUrl().replaceAll("/", ""), childrenMenu);
                                    }

                                }
                            }
                        }
                    }

                }
            }
        }
        return map;
    }
}
