package com.qmth.sop.business.cache.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.reflect.TypeToken;
import com.qmth.boot.core.cache.service.CacheService;
import com.qmth.sop.business.bean.auth.AuthBean;
import com.qmth.sop.business.bean.dto.MenuDto;
import com.qmth.sop.business.bean.dto.MenuPrivilegeDto;
import com.qmth.sop.business.bean.result.FormWidgetResult;
import com.qmth.sop.business.bean.result.MenuResult;
import com.qmth.sop.business.cache.CommonCacheService;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.service.*;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.ExceptionResultEnum;
import com.qmth.sop.common.enums.PrivilegeEnum;
import com.qmth.sop.common.enums.PrivilegePropertyEnum;
import com.qmth.sop.common.enums.RoleTypeEnum;
import com.qmth.sop.common.util.GsonUtil;
import com.qmth.sop.common.util.JacksonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 缓存操作serviceImpl 实现类
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/3/25
 */
@Service
public class CommonCacheServiceImpl implements CommonCacheService {
    private final static Logger log = LoggerFactory.getLogger(CommonCacheServiceImpl.class);

    @Resource
    SysUserService sysUserService;

    @Resource
    SysConfigService sysConfigService;

    @Resource
    CacheService cacheService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SysPrivilegeService sysPrivilegeService;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    SysRolePrivilegeService sysRolePrivilegeService;

    @Resource
    TDFormWidgetService tdFormWidgetService;

    @Resource
    TDTablePropService tdTablePropService;

    @Resource
    BasicSchoolService basicSchoolService;

    /**
     * 添加用户缓存
     *
     * @param userId
     * @return
     */
    @Override
//    @Cacheable(value = SystemConstant.USER_ACCOUNT_CACHE, key = "#p0", unless = "#result == null")
    public SysUser userCache(Long userId) {
        return userCacheCommon(userId);
    }

    /**
     * 修改用户缓存
     *
     * @param userId
     * @return
     */
    @Override
//    @CachePut(value = SystemConstant.USER_ACCOUNT_CACHE, key = "#p0", condition = "#result != null")
    public SysUser updateUserCache(Long userId) {
        cacheService.evict(SystemConstant.USER_ACCOUNT_CACHE, String.valueOf(userId));
        return userCacheCommon(userId);
    }

    /**
     * 用户缓存共用
     *
     * @param userId
     * @return
     */
    private SysUser userCacheCommon(Long userId) {
        SysUser sysUser = (SysUser) cacheService.get(SystemConstant.USER_ACCOUNT_CACHE, String.valueOf(userId));
        if (Objects.isNull(sysUser)) {
            sysUser = sysUserService.getById(userId);
            if (Objects.nonNull(sysUser)) {
                cacheService.put(SystemConstant.USER_ACCOUNT_CACHE, String.valueOf(userId), sysUser);
            } else {
                throw ExceptionResultEnum.ERROR.exception("userId[" + userId + "]用户不存在");
            }
        }
        return sysUser;
    }

    /**
     * 删除用户缓存
     *
     * @param userId
     */
    @Override
//    @CacheEvict(value = SystemConstant.USER_ACCOUNT_CACHE, key = "#p0")
    public void removeUserCache(Long userId) {
        cacheService.evict(SystemConstant.USER_ACCOUNT_CACHE, String.valueOf(userId));
    }

    /**
     * 系统参数key缓存共用
     *
     * @param key
     * @return
     */
    private SysConfig sysConfigCacheCommon(String key) {
        SysConfig sysConfig = (SysConfig) cacheService.get(SystemConstant.SYS_CONFIG_CACHE, key);
        if (Objects.isNull(sysConfig)) {
            sysConfig = sysConfigService.getOne(new QueryWrapper<SysConfig>().lambda().eq(SysConfig::getConfigKey, key));
            if (Objects.nonNull(sysConfig)) {
                cacheService.put(SystemConstant.SYS_CONFIG_CACHE, key, sysConfig);
            }
        }
        return sysConfig;
    }

    /**
     * 添加系统参数缓存
     *
     * @param key
     * @return
     */
    @Override
//    @Cacheable(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0", unless = "#result == null")
    public SysConfig addSysConfigCache(String key) {
        return sysConfigCacheCommon(key);
    }

    /**
     * 更新系统参数缓存
     *
     * @param key
     * @return
     */
    @Override
//    @CachePut(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0", condition = "#result != null")
    public SysConfig updateSysConfigCache(String key) {
        cacheService.evict(SystemConstant.SYS_CONFIG_CACHE, key);
        return sysConfigCacheCommon(key);
    }

    /**
     * 删除系统参数缓存
     *
     * @param key
     */
    @Override
//    @CacheEvict(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0")
    public void removeSysConfigCache(String key) {
        cacheService.evict(SystemConstant.SYS_CONFIG_CACHE, key);
    }

    /**
     * 更新系统参数缓存
     *
     * @param key
     * @return
     */
    @Override
    public void updateSysConfigCacheForDb(String key, SysConfig sysConfig) {
//        cacheManager.getCache(SystemConstant.SYS_CONFIG_CACHE).put(key, sysConfig);
        cacheService.put(SystemConstant.SYS_CONFIG_CACHE, key, sysConfig);
    }

    /**
     * 系统参数key缓存共用
     *
     * @param orgId
     * @param key
     * @return
     */
    private SysConfig sysConfigCacheCommon(Long orgId, String key) {
        SysConfig sysConfig = (SysConfig) cacheService.get(SystemConstant.SYS_CONFIG_CACHE, orgId + "_" + key);
        if (Objects.isNull(sysConfig)) {
            sysConfig = sysConfigService.getOne(new QueryWrapper<SysConfig>().lambda().eq(SysConfig::getOrgId, orgId).eq(SysConfig::getConfigKey, key));
            if (Objects.nonNull(sysConfig)) {
                cacheService.put(SystemConstant.SYS_CONFIG_CACHE, orgId + "_" + key, sysConfig);
            }
        }
        return sysConfig;
    }

    /**
     * 添加系统参数缓存
     *
     * @param orgId
     * @param key
     * @return
     */
    @Override
//    @Cacheable(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0 + '-' + #p1", unless = "#result == null")
    public SysConfig addSysConfigCache(Long orgId, String key) {
        return sysConfigCacheCommon(orgId, key);
    }

    /**
     * 更新系统参数缓存
     *
     * @param orgId
     * @param key
     * @return
     */
    @Override
//    @CachePut(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0 + '-' + #p1", condition = "#result != null")
    public SysConfig updateSysConfigCache(Long orgId, String key) {
        cacheService.evict(SystemConstant.SYS_CONFIG_CACHE, orgId + "_" + key);
        return sysConfigCacheCommon(orgId, key);
    }

    /**
     * 删除系统参数缓存
     *
     * @param orgId
     * @param key
     */
    @Override
//    @CacheEvict(value = SystemConstant.SYS_CONFIG_CACHE, key = "#p0 + '-' + #p1")
    public void removeSysConfigCache(Long orgId, String key) {
        cacheService.evict(SystemConstant.SYS_CONFIG_CACHE, orgId + "_" + key);
    }

    /**
     * 设置用户session
     *
     * @param sessionId
     * @param o
     */
    @Override
    public void setUserSession(String sessionId, Object o) {
        cacheService.put(SystemConstant.SESSION, sessionId, o);
    }

    /**
     * 获取用户session
     *
     * @param sessionId
     * @return
     */
    @Override
    public Object getUserSession(String sessionId) {
        return cacheService.get(SystemConstant.SESSION, sessionId);
    }

    /**
     * 删除用户session
     *
     * @param sessionId
     */
    @Override
    public void deleteUserSession(String sessionId) {
        cacheService.evict(SystemConstant.SESSION, sessionId);
    }

    /**
     * 添加户鉴权缓存
     *
     * @param userId
     * @return
     */
    @Override
    public AuthBean userAuthCache(Long userId) {
        AuthBean authBean = (AuthBean) cacheService.get(SystemConstant.USER_OAUTH_CACHE, String.valueOf(userId));
        if (Objects.isNull(authBean)) {
            try {
                SysUser user = this.userCache(userId);
                Optional.ofNullable(user).orElseThrow(() -> ExceptionResultEnum.USER_NO_DATA.exception());
                //查询用户角色和权限
                List<SysUserRole> sysUserRoleList = this.userRolePrivilegeCache(user.getId());
                if (Objects.nonNull(sysUserRoleList) && sysUserRoleList.size() > 0) {
                    Set<Long> roleIds = sysUserRoleList.stream().map(s -> s.getRoleId()).collect(Collectors.toSet());
                    List<SysRolePrivilege> sysRolePrivilegeList = new ArrayList<>();
                    for (Long l : roleIds) {
                        sysRolePrivilegeList.addAll(this.rolePrivilegeCache(l));
                    }
                    Set<Long> privilegeIds = sysRolePrivilegeList.stream().map(s -> s.getPrivilegeId()).collect(Collectors.toSet());
                    List<SysRole> sysRoleList = sysRoleService.list(new QueryWrapper<SysRole>().lambda().in(SysRole::getId, roleIds).eq(SysRole::getEnable, true));
                    int count = Objects.nonNull(sysRoleList) && sysRoleList.size() > 0 ? (int) sysRoleList.stream().filter(s -> Objects.equals(s.getName(), RoleTypeEnum.ADMIN.getDesc())).count() : 0;
                    QueryWrapper<SysPrivilege> sysPrivilegeQueryWrapper = new QueryWrapper<>();
                    if (count > 0) {//超级系统管理员
                        sysPrivilegeQueryWrapper.lambda().eq(SysPrivilege::getType, PrivilegeEnum.URL).eq(SysPrivilege::getProperty, PrivilegePropertyEnum.AUTH);
                        List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.list(sysPrivilegeQueryWrapper);
                        authBean = new AuthBean(sysRoleList, sysPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()));
                    } else {
                        SysOrg org = Objects.nonNull(user.getOrgId()) ? this.orgCache(user.getOrgId()) : null;
                        List<SysPrivilege> sysPrivilegeList = new ArrayList<>();
                        if (privilegeIds.size() > 0) {
                            sysPrivilegeQueryWrapper.lambda().in(SysPrivilege::getId, privilegeIds).eq(SysPrivilege::getType, PrivilegeEnum.URL).eq(SysPrivilege::getProperty, PrivilegePropertyEnum.AUTH);
                            sysPrivilegeList = sysPrivilegeService.list(sysPrivilegeQueryWrapper);
                        }
                        authBean = new AuthBean(sysRoleList, sysPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()), org);
                    }
                }
                if (Objects.nonNull(authBean)) {
                    cacheService.put(SystemConstant.USER_OAUTH_CACHE, String.valueOf(userId), authBean);
                }
            } catch (Exception e) {
                log.error(SystemConstant.LOG_ERROR, e);
                throw ExceptionResultEnum.ERROR.exception("添加用户鉴权缓存失败");
            }
        }
        return authBean;
    }

    /**
     * 更新用户鉴权缓存
     *
     * @param userId
     * @return
     */
    @Override
    public AuthBean updateUserAuthCache(Long userId) {
        cacheService.evict(SystemConstant.USER_OAUTH_CACHE, String.valueOf(userId));
        return userAuthCache(userId);
    }

    /**
     * 删除用户鉴权换成
     *
     * @param userId
     */
    @Override
    public void removeUserAuthCache(Long userId) {
        cacheService.evict(SystemConstant.USER_OAUTH_CACHE, String.valueOf(userId));
    }

    /**
     * 添加用户角色权限缓存
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysUserRole> userRolePrivilegeCache(Long userId) {
        return userRoleCacheCommon(userId);
    }

    /**
     * 更新用户角色权限缓存
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysUserRole> updateUserRolePrivilegeCache(Long userId) {
        cacheService.evict(SystemConstant.USER_ROLE_PRIVILEGE_CACHE, String.valueOf(userId));
        return userRoleCacheCommon(userId);
    }

    /**
     * 删除用户角色权限缓存
     *
     * @param userId
     */
    @Override
    public void removeUserRolePrivilegeCache(Long userId) {
        cacheService.evict(SystemConstant.USER_ROLE_PRIVILEGE_CACHE, String.valueOf(userId));
    }

    /**
     * 添加机构缓存
     *
     * @param orgId
     * @return
     */
    @Override
    public SysOrg orgCache(Long orgId) {
        return orgCacheCommon(orgId);
    }

    /**
     * 更新机构缓存
     *
     * @param orgId
     * @return
     */
    @Override
    public SysOrg updateOrgCache(Long orgId) {
        cacheService.evict(SystemConstant.ORG_CACHE, String.valueOf(orgId));
        return orgCacheCommon(orgId);
    }

    /**
     * 删除机构缓存
     *
     * @param orgId
     */
    @Override
    public void removeOrgCache(Long orgId) {
        cacheService.evict(SystemConstant.ORG_CACHE, String.valueOf(orgId));
    }

    /**
     * 添加角色权限缓存
     *
     * @param roleId
     * @return
     */
    @Override
    public List<SysRolePrivilege> rolePrivilegeCache(Long roleId) {
        return rolePrivilegeCacheCommon(roleId);
    }

    /**
     * 修改角色权限缓存
     *
     * @param roleId
     * @return
     */
    @Override
    public List<SysRolePrivilege> updateRolePrivilegeCache(Long roleId) {
        cacheService.evict(SystemConstant.ROLE_PRIVILEGE_CACHE, String.valueOf(roleId));
        return rolePrivilegeCacheCommon(roleId);
    }

    /**
     * 删除角色权限缓存
     *
     * @param roleId
     */
    @Override
    public void removeRolePrivilegeCache(Long roleId) {
        cacheService.evict(SystemConstant.ROLE_PRIVILEGE_CACHE, String.valueOf(roleId));
    }

    /**
     * 获取鉴权url
     *
     * @param privilegePropertyEnum
     * @return
     */
    @Override
    public Set<String> privilegeUrlCache(PrivilegePropertyEnum privilegePropertyEnum) {
        return privilegeUrlCacheCommon(privilegePropertyEnum);
    }

    /**
     * 更新鉴权url
     *
     * @param privilegePropertyEnum
     * @return
     */
    @Override
    public Set<String> updatePrivilegeUrlCache(PrivilegePropertyEnum privilegePropertyEnum) {
        cacheService.evict(SystemConstant.PRIVILEGE_URL_CACHE, privilegePropertyEnum.name());
        return privilegeUrlCacheCommon(privilegePropertyEnum);
    }

    /**
     * 删除鉴权url
     *
     * @param privilegePropertyEnum
     */
    @Override
    public void removePrivilegeUrlCache(PrivilegePropertyEnum privilegePropertyEnum) {
        cacheService.evict(SystemConstant.PRIVILEGE_URL_CACHE, privilegePropertyEnum.name());
    }

    /**
     * 添加控件缓存
     *
     * @return
     */
    @Override
    public List<FormWidgetResult> formWidgetCache() {
        return formWidgetCacheCommon();
    }

    /**
     * 修改控件缓存
     *
     * @return
     */
    @Override
    public List<FormWidgetResult> updateFormWidgetCache() {
        cacheService.evict(SystemConstant.FORM_WIDGET_CACHE, SystemConstant.FORM_WIDGET_CACHE);
        return formWidgetCacheCommon();
    }

    /**
     * 删除控件缓存
     */
    @Override
    public void removeFormWidgetCache() {
        cacheService.evict(SystemConstant.FORM_WIDGET_CACHE, SystemConstant.FORM_WIDGET_CACHE);
    }

    /**
     * 添加控件缓存
     *
     * @param id
     * @return
     */
    @Override
    public TDFormWidget formWidgetCache(Long id) {
        return formWidgetCacheCommon(id);
    }

    /**
     * 修改控件缓存
     *
     * @param id
     * @return
     */
    @Override
    public TDFormWidget updateFormWidgetCache(Long id) {
        cacheService.evict(SystemConstant.FORM_WIDGET_CACHE, String.valueOf(id));
        return formWidgetCacheCommon(id);
    }

    /**
     * 删除控件缓存
     *
     * @param id
     */
    @Override
    public void removeFormWidgetCache(Long id) {
        cacheService.evict(SystemConstant.FORM_WIDGET_CACHE, String.valueOf(id));
    }

    /**
     * 添加表格属性缓存
     *
     * @param widgetId
     * @return
     */
    @Override
    public List<TDTableProp> tablePropCache(Long widgetId) {
        return tablePropCacheCommon(widgetId);
    }

    /**
     * 修改表格属性缓存
     *
     * @param widgetId
     * @return
     */
    @Override
    public List<TDTableProp> updateTablePropCache(Long widgetId) {
        cacheService.evict(SystemConstant.TABLE_PROP_CACHE, String.valueOf(widgetId));
        return tablePropCacheCommon(widgetId);
    }

    /**
     * 删除表格属性缓存
     *
     * @param widgetId
     */
    @Override
    public void removeTablePropCache(Long widgetId) {
        cacheService.evict(SystemConstant.TABLE_PROP_CACHE, String.valueOf(widgetId));
    }

    /**
     * 添加用户菜单缓存
     *
     * @param userId
     * @return
     */
    @Override
    public MenuResult userMenuCache(Long userId) {
        return userMenuCommon(userId);
    }

    /**
     * 修改用户菜单缓存
     *
     * @param userId
     * @return
     */
    @Override
    public MenuResult updateUserMenuCache(Long userId) {
        cacheService.evict(SystemConstant.USER_MENU_CACHE, String.valueOf(userId));
        return userMenuCommon(userId);
    }

    /**
     * 删除用户菜单缓存
     *
     * @param userId
     */
    @Override
    public void removeUserMenuCache(Long userId) {
        cacheService.evict(SystemConstant.USER_MENU_CACHE, String.valueOf(userId));
    }

    /**
     * 添加角色缓存
     *
     * @param roleId
     * @return
     */
    @Override
    public SysRole roleCache(Long roleId) {
        return roleCacheCommon(roleId);
    }

    /**
     * 修改角色缓存
     *
     * @param roleId
     * @return
     */
    @Override
    public SysRole updateRoleCache(Long roleId) {
        cacheService.evict(SystemConstant.ROLE_CACHE, String.valueOf(roleId));
        return roleCacheCommon(roleId);
    }

    /**
     * 删除角色缓存
     *
     * @param roleId
     */
    @Override
    public void removeRoleCache(Long roleId) {
        cacheService.evict(SystemConstant.ROLE_CACHE, String.valueOf(roleId));
    }

    /**
     * 添加学校缓存
     *
     * @param schoolId
     * @return
     */
    @Override
    public BasicSchool schoolCache(Long schoolId) {
        return schoolCacheCommon(schoolId);
    }

    /**
     * 添加学校缓存
     *
     * @param code
     * @return
     */
    @Override
    public BasicSchool schoolCache(String code) {
        return schoolCacheCommon(code);
    }

    /**
     * 更新学校缓存
     *
     * @param schoolId
     * @return
     */
    @Override
    public BasicSchool updateSchoolCache(Long schoolId) {
        cacheService.evict(SystemConstant.SCHOOL_CACHE, String.valueOf(schoolId));
        return schoolCacheCommon(schoolId);
    }

    /**
     * 更新学校缓存
     *
     * @param code
     * @return
     */
    @Override
    public BasicSchool updateSchoolCache(String code) {
        cacheService.evict(SystemConstant.SCHOOL_CODE_CACHE, code);
        return schoolCacheCommon(code);
    }

    /**
     * 删除学校缓存
     *
     * @param schoolId
     */
    @Override
    public void removeSchoolCache(Long schoolId) {
        cacheService.evict(SystemConstant.SCHOOL_CACHE, String.valueOf(schoolId));
    }

    /**
     * 删除学校缓存
     *
     * @param code
     */
    @Override
    public void removeSchoolCache(String code) {
        cacheService.evict(SystemConstant.SCHOOL_CODE_CACHE, code);
    }

    /**
     * 删除学校缓存
     */
    @Override
    public void removeSchoolIdCache() {
        cacheService.clear(SystemConstant.SCHOOL_CACHE);
    }

    /**
     * 删除学校缓存
     */
    @Override
    public void removeSchoolCodeCache() {
        cacheService.clear(SystemConstant.SCHOOL_CODE_CACHE);
    }

    /**
     * 学校缓存共用
     *
     * @param schoolId
     * @return
     */
    protected BasicSchool schoolCacheCommon(Long schoolId) {
        BasicSchool basicSchool = (BasicSchool) cacheService.get(SystemConstant.SCHOOL_CACHE, String.valueOf(schoolId));
        if (Objects.isNull(basicSchool)) {
            basicSchool = basicSchoolService.getById(schoolId);
            if (Objects.nonNull(basicSchool)) {
                cacheService.put(SystemConstant.SCHOOL_CACHE, String.valueOf(schoolId), basicSchool);
            }
        }
        return basicSchool;
    }

    /**
     * 学校缓存共用
     *
     * @param code
     * @return
     */
    protected BasicSchool schoolCacheCommon(String code) {
        BasicSchool basicSchool = (BasicSchool) cacheService.get(SystemConstant.SCHOOL_CODE_CACHE, code);
        if (Objects.isNull(basicSchool)) {
            basicSchool = basicSchoolService.getOne(new QueryWrapper<BasicSchool>().lambda().eq(BasicSchool::getCode, code));
            if (Objects.nonNull(basicSchool)) {
                cacheService.put(SystemConstant.SCHOOL_CODE_CACHE, code, basicSchool);
            }
        }
        return basicSchool;
    }

    /**
     * 角色缓存共用
     *
     * @param roleId
     * @return
     */
    protected SysRole roleCacheCommon(Long roleId) {
        SysRole sysRole = (SysRole) cacheService.get(SystemConstant.ROLE_CACHE, String.valueOf(roleId));
        if (Objects.isNull(sysRole)) {
            sysRole = sysRoleService.getById(roleId);
            if (Objects.nonNull(sysRole)) {
                cacheService.put(SystemConstant.ROLE_CACHE, String.valueOf(roleId), sysRole);
            }
        }
        return sysRole;
    }

    /**
     * 获取用户菜单
     *
     * @param userId
     * @return
     */
    protected MenuResult userMenuCommon(Long userId) {
        MenuResult menuResult = (MenuResult) cacheService.get(SystemConstant.USER_MENU_CACHE, String.valueOf(userId));
        if (Objects.isNull(menuResult)) {
            List<SysUserRole> sysUserRoleList = this.userRolePrivilegeCache(userId);
            List<SysRolePrivilege> sysRolePrivilegeList = new ArrayList<>();
            for (SysUserRole s : sysUserRoleList) {
                SysRole sysRole = this.roleCache(s.getRoleId());
                if (Objects.nonNull(sysRole) && sysRole.getEnable()) {
                    sysRolePrivilegeList.addAll(this.rolePrivilegeCache(s.getRoleId()));
                }
            }
            Set<Long> privilegeIds = sysRolePrivilegeList.stream().map(s -> s.getPrivilegeId()).collect(Collectors.toSet());
            QueryWrapper<SysPrivilege> sysPrivilegeQueryWrapper = new QueryWrapper<>();
            sysPrivilegeQueryWrapper.lambda()
                    .eq(SysPrivilege::getEnable, true).eq(SysPrivilege::getFrontDisplay, true)
                    .orderByAsc(SysPrivilege::getSequence);

            if (!privilegeIds.isEmpty()) {
                sysPrivilegeQueryWrapper.lambda().in(SysPrivilege::getId, privilegeIds);
            }
            List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.list(sysPrivilegeQueryWrapper);
            List<MenuDto> menuDtoList = GsonUtil.fromJson(JacksonUtil.parseJson(sysPrivilegeList), new TypeToken<List<MenuDto>>() {
            }.getType());
            LinkedMultiValueMap<Long, MenuDto> linkedMultiValueMap = new LinkedMultiValueMap<>();
            List<MenuPrivilegeDto> menuPrivilegeDtoList = new ArrayList<>();
            for (MenuDto m : menuDtoList) {
                if (Objects.isNull(m.getParentId()) || m.getType() == PrivilegeEnum.MENU) {
                    menuPrivilegeDtoList.add(GsonUtil.fromJson(GsonUtil.toJson(m), MenuPrivilegeDto.class));
                } else {
                    if (!linkedMultiValueMap.containsKey(m.getParentId())) {
                        linkedMultiValueMap.add(m.getParentId(), m);
                    } else {
                        List<MenuDto> menuDtos = linkedMultiValueMap.get(m.getParentId());
                        menuDtos.add(m);
                        linkedMultiValueMap.put(m.getParentId(), menuDtos);
                    }
                }
            }
            for (MenuPrivilegeDto m : menuPrivilegeDtoList) {
                List<MenuDto> menuDtos = linkedMultiValueMap.get(m.getId());
                List<MenuDto> urls = null, buttons = null, links = null, lists = null, conditions = null;
                if (Objects.nonNull(menuDtos)) {
                    for (MenuDto menuDto : menuDtos) {
                        if (menuDto.getType() == PrivilegeEnum.BUTTON) {
                            buttons = Objects.isNull(buttons) ? new ArrayList<>() : buttons;
                            buttons.add(GsonUtil.fromJson(GsonUtil.toJson(menuDto), MenuPrivilegeDto.class));
                            m.setButtons(buttons);
                        } else if (menuDto.getType() == PrivilegeEnum.LINK) {
                            links = Objects.isNull(links) ? new ArrayList<>() : links;
                            links.add(GsonUtil.fromJson(GsonUtil.toJson(menuDto), MenuPrivilegeDto.class));
                            m.setLinks(links);
                        } else if (menuDto.getType() == PrivilegeEnum.URL) {
                            urls = Objects.isNull(urls) ? new ArrayList<>() : urls;
                            urls.add(GsonUtil.fromJson(GsonUtil.toJson(menuDto), MenuPrivilegeDto.class));
                            m.setUrls(urls);
                        } else if (menuDto.getType() == PrivilegeEnum.LIST) {
                            lists = Objects.isNull(lists) ? new ArrayList<>() : lists;
                            lists.add(GsonUtil.fromJson(GsonUtil.toJson(menuDto), MenuPrivilegeDto.class));
                            m.setLists(lists);
                        } else if (menuDto.getType() == PrivilegeEnum.CONDITION) {
                            conditions = Objects.isNull(conditions) ? new ArrayList<>() : conditions;
                            conditions.add(GsonUtil.fromJson(GsonUtil.toJson(menuDto), MenuPrivilegeDto.class));
                            m.setConditions(conditions);
                        }
                    }
                }
            }
            menuResult = new MenuResult(userId, menuPrivilegeDtoList);
            cacheService.put(SystemConstant.USER_MENU_CACHE, String.valueOf(userId), menuResult);
        }
        return menuResult;
    }

    /**
     * 控件缓存共用
     *
     * @return
     */
    protected List<TDTableProp> tablePropCacheCommon(Long widgetId) {
        List<TDTableProp> tablePropList = (List<TDTableProp>) cacheService.get(SystemConstant.TABLE_PROP_CACHE, String.valueOf(widgetId));
        if (CollectionUtils.isEmpty(tablePropList)) {
            tablePropList = tdTablePropService.list(new QueryWrapper<TDTableProp>().lambda().eq(TDTableProp::getWidgetId, widgetId));
            if (!CollectionUtils.isEmpty(tablePropList)) {
                cacheService.put(SystemConstant.TABLE_PROP_CACHE, String.valueOf(widgetId), tablePropList);
            }
        }
        return tablePropList;
    }

    /**
     * 控件缓存共用
     *
     * @param id
     * @return
     */
    protected TDFormWidget formWidgetCacheCommon(Long id) {
        TDFormWidget tdFormWidget = (TDFormWidget) cacheService.get(SystemConstant.FORM_WIDGET_CACHE, String.valueOf(id));
        if (Objects.isNull(tdFormWidget)) {
            tdFormWidget = tdFormWidgetService.getById(id);
            if (Objects.nonNull(tdFormWidget)) {
                cacheService.put(SystemConstant.FORM_WIDGET_CACHE, String.valueOf(id), tdFormWidget);
            }
        }
        return tdFormWidget;
    }

    /**
     * 控件缓存共用
     *
     * @return
     */
    protected List<FormWidgetResult> formWidgetCacheCommon() {
        List<FormWidgetResult> formWidgetResultList = (List<FormWidgetResult>) cacheService.get(SystemConstant.FORM_WIDGET_CACHE, SystemConstant.FORM_WIDGET_CACHE);
        if (CollectionUtils.isEmpty(formWidgetResultList)) {
            List<TDFormWidget> tdFormWidgetList = tdFormWidgetService.list(new QueryWrapper<TDFormWidget>().select(" DISTINCT code "));
            if (!CollectionUtils.isEmpty(tdFormWidgetList)) {
                formWidgetResultList = GsonUtil.fromJson(JacksonUtil.parseJson(tdFormWidgetList), new TypeToken<List<FormWidgetResult>>() {
                }.getType());
                cacheService.put(SystemConstant.FORM_WIDGET_CACHE, SystemConstant.FORM_WIDGET_CACHE, formWidgetResultList);
            }
        }
        return formWidgetResultList;
    }

    /**
     * 鉴权url缓存共用
     *
     * @param privilegePropertyEnum
     * @return
     */
    protected Set<String> privilegeUrlCacheCommon(PrivilegePropertyEnum privilegePropertyEnum) {
        Set<String> privilegeUrlSet = (Set<String>) cacheService.get(SystemConstant.PRIVILEGE_URL_CACHE, privilegePropertyEnum.name());
        if (CollectionUtils.isEmpty(privilegeUrlSet)) {
            List<SysPrivilege> sysPrivilegeList = sysPrivilegeService.list(new QueryWrapper<SysPrivilege>().lambda().eq(SysPrivilege::getType, PrivilegeEnum.URL).eq(SysPrivilege::getProperty, privilegePropertyEnum).eq(SysPrivilege::getEnable, true));
            if (!CollectionUtils.isEmpty(sysPrivilegeList)) {
                privilegeUrlSet = sysPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet());
                cacheService.put(SystemConstant.PRIVILEGE_URL_CACHE, privilegePropertyEnum.name(), privilegeUrlSet);
            }
        }
        return privilegeUrlSet;
    }

    /**
     * 机构缓存共用
     *
     * @param orgId
     * @return
     */
    protected SysOrg orgCacheCommon(Long orgId) {
        SysOrg sysOrg = (SysOrg) cacheService.get(SystemConstant.ORG_CACHE, String.valueOf(orgId));
        if (Objects.isNull(sysOrg)) {
            sysOrg = sysOrgService.getById(orgId);
            if (Objects.nonNull(sysOrg)) {
                cacheService.put(SystemConstant.ORG_CACHE, String.valueOf(orgId), sysOrg);
            }
        }
        return sysOrg;
    }

    /**
     * 用户角色缓存共用
     *
     * @param userId
     * @return
     */
    protected List<SysUserRole> userRoleCacheCommon(Long userId) {
        List<SysUserRole> sysUserRoleList = (List<SysUserRole>) cacheService.get(SystemConstant.USER_ROLE_PRIVILEGE_CACHE, String.valueOf(userId));
        if (CollectionUtils.isEmpty(sysUserRoleList)) {
            sysUserRoleList = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, userId).eq(SysUserRole::getEnable, true));
            if (!CollectionUtils.isEmpty(sysUserRoleList)) {
                cacheService.put(SystemConstant.USER_ROLE_PRIVILEGE_CACHE, String.valueOf(userId), sysUserRoleList);
            }
        }
        return sysUserRoleList;
    }

    /**
     * 角色权限缓存共用
     *
     * @param roleId
     * @return
     */
    protected List<SysRolePrivilege> rolePrivilegeCacheCommon(Long roleId) {
        List<SysRolePrivilege> sysRolePrivilegeList = (List<SysRolePrivilege>) cacheService.get(SystemConstant.ROLE_PRIVILEGE_CACHE, String.valueOf(roleId));
        if (CollectionUtils.isEmpty(sysRolePrivilegeList)) {
            sysRolePrivilegeList = sysRolePrivilegeService.list(new QueryWrapper<SysRolePrivilege>().lambda().eq(SysRolePrivilege::getRoleId, roleId));
            if (!CollectionUtils.isEmpty(sysRolePrivilegeList)) {
                cacheService.put(SystemConstant.ROLE_PRIVILEGE_CACHE, String.valueOf(roleId), sysRolePrivilegeList);
            }
        }
        return sysRolePrivilegeList;
    }
}
