|  |  |  | 
|---|
|  |  |  | package com.matrix.system.common.authority; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import cn.hutool.crypto.SecureUtil; | 
|---|
|  |  |  | import cn.hutool.json.JSONArray; | 
|---|
|  |  |  | import cn.hutool.json.JSONObject; | 
|---|
|  |  |  | import cn.hutool.json.JSONUtil; | 
|---|
|  |  |  | import com.matrix.component.redis.RedisClient; | 
|---|
|  |  |  | import com.matrix.core.constance.MatrixConstance; | 
|---|
|  |  |  | import com.matrix.core.pojo.AjaxResult; | 
|---|
|  |  |  | import com.matrix.core.tools.LogUtil; | 
|---|
|  |  |  | import com.matrix.core.tools.StringUtils; | 
|---|
|  |  |  | import com.matrix.core.tools.WebUtil; | 
|---|
|  |  |  | import com.matrix.system.common.authority.strategy.LoginStrategy; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.Map.Entry; | 
|---|
|  |  |  | import java.util.logging.Logger; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * DefaultAuthorityManager 实现了权限控制接口 | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private static final int DEFAULT_2 = 2; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static final String USER_POWER_REDISKEY = "USER_POWER_"; | 
|---|
|  |  |  | public static final String USER_POWER_REDISKEY_PC = "USER_POWER_PC"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | SysFunctionService sysFunctionService; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static final String USERFUNCTION = "userFunction"; | 
|---|
|  |  |  | public static final String MENUSFUNCTION = "menusFunction"; | 
|---|
|  |  |  | /** 用户所有路径权限的记录 **/ | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 用户所有路径权限的记录 | 
|---|
|  |  |  | **/ | 
|---|
|  |  |  | public static final String USER_URL_MAPPING = "userUrlMapping"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | RedisClient redisClient; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private DefaultAuthorityManager() { | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 判断用户是否具有功能权限 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 初始化用户权限 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param result | 
|---|
|  |  |  | * @author JIANGYOUYAO | 
|---|
|  |  |  | * @email 935090232@qq.com | 
|---|
|  |  |  | * @date 2017年12月5日 | 
|---|
|  |  |  | * @param result | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void initUserPower(AjaxResult result) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | // 用户的所有功能权限用id记录,方便后面查询菜单树形结构 | 
|---|
|  |  |  | Map<String, SysFunction> menuFunctionMap = new TreeMap<>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 获取用户所有权限 | 
|---|
|  |  |  | getUserFunction(userFunction, menuFunctionMap, userUrlMapping); | 
|---|
|  |  |  | SysUsers sysUser = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 组装菜单 | 
|---|
|  |  |  | assembleMenu(menuFunction, menuFunctionMap); | 
|---|
|  |  |  | String redisKey = USER_POWER_REDISKEY_PC + SecureUtil.md5(sysUser.getSuId()+""); | 
|---|
|  |  |  | String cachedValue = redisClient.getCachedValue(redisKey); | 
|---|
|  |  |  | if (StringUtils.isNotBlank(cachedValue)) { | 
|---|
|  |  |  | //从缓存中获取用户权限 | 
|---|
|  |  |  | JSONObject powerMap = JSONUtil.parseObj(cachedValue); | 
|---|
|  |  |  | String userFunctionMapStr = powerMap.get(USERFUNCTION).toString(); | 
|---|
|  |  |  | JSONObject userFunctionMap = JSONUtil.parseObj(userFunctionMapStr); | 
|---|
|  |  |  | Set<String> userFunctionMapKeys = userFunctionMap.keySet(); | 
|---|
|  |  |  | userFunctionMapKeys.forEach(key -> { | 
|---|
|  |  |  | userFunction.put(key, userFunctionMap.get(key, SysFunction.class)); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | String menusFunctionListStr = powerMap.get(MENUSFUNCTION).toString(); | 
|---|
|  |  |  | JSONArray menusFunctionArray = JSONUtil.parseArray(menusFunctionListStr); | 
|---|
|  |  |  | for (int i = 0; i < menusFunctionArray.size(); i++) { | 
|---|
|  |  |  | menuFunction.add(menusFunctionArray.get(i, SysFunction.class)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | String userUrlMappingListStr = powerMap.get(USER_URL_MAPPING).toString(); | 
|---|
|  |  |  | JSONArray userUrlMappingArray = JSONUtil.parseArray(userUrlMappingListStr); | 
|---|
|  |  |  | for (int i = 0; i < userUrlMappingArray.size(); i++) { | 
|---|
|  |  |  | userUrlMapping.add(userUrlMappingArray.get(i, String.class)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // 获取用户所有权限 | 
|---|
|  |  |  | getUserFunction(userFunction, menuFunctionMap, userUrlMapping); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 组装菜单 | 
|---|
|  |  |  | assembleMenu(menuFunction, menuFunctionMap); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Map<String ,Object> powerMap=new HashMap<>(); | 
|---|
|  |  |  | powerMap.put(USERFUNCTION, userFunction); | 
|---|
|  |  |  | powerMap.put(MENUSFUNCTION, menuFunction); | 
|---|
|  |  |  | powerMap.put(USER_URL_MAPPING, userUrlMapping); | 
|---|
|  |  |  | redisClient.saveValue(redisKey,JSONUtil.parseObj(powerMap,true)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 把用户菜单和用户的功能都存在session中。 | 
|---|
|  |  |  | WebUtil.setSessionAttribute(USERFUNCTION, userFunction); | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取用的功能,包括菜单功能和非菜单功能 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @author JIANGYOUYAO | 
|---|
|  |  |  | * @email 935090232@qq.com | 
|---|
|  |  |  | * @date 2017年12月5日 | 
|---|
|  |  |  | * @param userFunctionMap | 
|---|
|  |  |  | * @param menuFunctionMap | 
|---|
|  |  |  | * @param userUrlMapping | 
|---|
|  |  |  | * @author JIANGYOUYAO | 
|---|
|  |  |  | * @email 935090232@qq.com | 
|---|
|  |  |  | * @date 2017年12月5日 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private void getUserFunction(Map<String, SysFunction> userFunctionMap, Map<String, SysFunction> menuFunctionMap, | 
|---|
|  |  |  | List<String> userUrlMapping) { | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | userFunctionMap.put(sysFunction.getFnCode(), sysFunction); | 
|---|
|  |  |  | // 注册访问路径 | 
|---|
|  |  |  | registerUrlMapping(userUrlMapping, sysFunction,true); | 
|---|
|  |  |  | registerUrlMapping(userUrlMapping, sysFunction, true); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 如果是菜单功能单独记录 | 
|---|
|  |  |  | if (AppConstance.IS_Y.equals(sysFunction.getFnShowMenu())) { | 
|---|
|  |  |  | 
|---|
|  |  |  | List<SysFunction> userFunctionList = sysFunctionService.findFunctionByRoleIds(sysUser.getRoleIds()); | 
|---|
|  |  |  | for (SysFunction sysFunction : userFunctionList) { | 
|---|
|  |  |  | // TODO注册访问路径 | 
|---|
|  |  |  | registerUrlMapping(userUrlMapping, sysFunction,false); | 
|---|
|  |  |  | registerUrlMapping(userUrlMapping, sysFunction, false); | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (userFunctionMap.containsKey(sysFunction.getFnCode())) { | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 注册功能和按钮的访问路径 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param userUrlMapping | 
|---|
|  |  |  | * @param sysFunction | 
|---|
|  |  |  | * @author JIANGYOUYAO | 
|---|
|  |  |  | * @email 935090232@qq.com | 
|---|
|  |  |  | * @date 2017年12月8日 | 
|---|
|  |  |  | * @param userUrlMapping | 
|---|
|  |  |  | * @param sysFunction | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private void registerUrlMapping(List<String> userUrlMapping, SysFunction sysFunction, boolean isAdmin) { | 
|---|
|  |  |  | String path = sysFunction.getFnPath(); | 
|---|
|  |  |  | 
|---|
|  |  |  | if (CollectionUtils.isNotEmpty(btnRels)) { | 
|---|
|  |  |  | for (SysFnBtnRel sysFnBtnRel : btnRels) { | 
|---|
|  |  |  | //公司管理员可以添加所有按钮权限否则只能添加员工自己所有拥有的权限 | 
|---|
|  |  |  | if(isAdmin ||StringUtils.isContentSet(sysFnBtnRel.getBtnValue(),sysFunction.getRpfBns())){ | 
|---|
|  |  |  | if (isAdmin || StringUtils.isContentSet(sysFnBtnRel.getBtnValue(), sysFunction.getRpfBns())) { | 
|---|
|  |  |  | String btnPath = sysFnBtnRel.getFbPath(); | 
|---|
|  |  |  | if (StringUtils.isNotBlank(btnPath) && !userUrlMapping.contains(btnPath)) { | 
|---|
|  |  |  | userUrlMapping.add(btnPath); | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 把菜单组装成树形结构 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param menuFunction | 
|---|
|  |  |  | * @param menuFunctionMap | 
|---|
|  |  |  | * @author JIANGYOUYAO | 
|---|
|  |  |  | * @email 935090232@qq.com | 
|---|
|  |  |  | * @date 2017年12月5日 | 
|---|
|  |  |  | * @param menuFunction | 
|---|
|  |  |  | * @param menuFunctionMap | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private void assembleMenu(List<SysFunction> menuFunction, Map<String, SysFunction> menuFunctionMap) { | 
|---|
|  |  |  | // 将map.entrySet()转换成list,并按照功能的FnSequence倒序 | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // 非一级节点找到父节点后存入 | 
|---|
|  |  |  | SysFunction parentFn = menuFunctionMap.get(String.valueOf(function.getFnParentId())); | 
|---|
|  |  |  | if(parentFn!=null){ | 
|---|
|  |  |  | if (parentFn != null) { | 
|---|
|  |  |  | List<SysFunction> childs = parentFn.getChilds(); | 
|---|
|  |  |  | if (childs == null) { | 
|---|
|  |  |  | parentFn.setChilds(new ArrayList<SysFunction>()); | 
|---|