| package com.matrix.system.common.service.impl; | 
|   | 
| import com.matrix.core.constance.MatrixConstance; | 
| import com.matrix.core.constance.SystemErrorCode; | 
| import com.matrix.core.exception.GlobleException; | 
| import com.matrix.core.pojo.PaginationVO; | 
| import com.matrix.core.tools.LogUtil; | 
| import com.matrix.core.tools.ModelUtils; | 
| import com.matrix.core.tools.WebUtil; | 
| import com.matrix.system.common.authority.DefaultAuthorityManager; | 
| import com.matrix.system.common.bean.SysFnBtnRel; | 
| import com.matrix.system.common.bean.SysFunction; | 
| import com.matrix.system.common.bean.SysUsers; | 
| import com.matrix.system.common.constance.AppConstance; | 
| import com.matrix.system.common.constance.AppMessageCode; | 
| import com.matrix.system.common.dao.SysFunctionDao; | 
| import com.matrix.system.common.service.SysFunctionService; | 
| import com.matrix.system.common.tools.ServiceUtil; | 
| import jodd.util.StringUtil; | 
| import org.apache.commons.collections.CollectionUtils; | 
| import org.apache.commons.lang.ArrayUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.transaction.annotation.Transactional; | 
|   | 
| import javax.annotation.Resource; | 
| import java.util.*; | 
|   | 
| /** | 
|  * 系统功能管理 | 
|  *  | 
|  * @author jiangyouyao | 
|  * @time 2016-11-18 | 
|  */ | 
| @Service | 
| public class SysFunctionServiceImpl implements SysFunctionService { | 
|   | 
|     private static final String FN_ID = "fn_id"; | 
|   | 
|     private static final String FN_CODE = "fn_code"; | 
|   | 
|     @Autowired | 
|     private SysFunctionDao sysFunctionDao; | 
|   | 
|     @Autowired | 
|     private ServiceUtil serviceUtil; | 
|   | 
|     @Resource | 
|     private DefaultAuthorityManager matrix; | 
|   | 
|     private String tableName = "sys_function"; | 
|   | 
|   | 
|     @Override | 
|     public int add(SysFunction sysFunction) { | 
|          | 
|         // 自己不能是自己的父节点 | 
|         if (sysFunction.getFnParentId() != null && sysFunction.getFnParentId().equals(sysFunction.getFnId())) { | 
|             throw new GlobleException(AppMessageCode.Function.PARENT_FUNCTION_CANNOT_BE_SELF); | 
|         } | 
|         // 功能code去重 | 
|         if (serviceUtil.addCheckRepeat(tableName, FN_CODE, sysFunction.getFnCode())) { | 
|             throw new GlobleException(SystemErrorCode.DATA_REPEAT, sysFunction.getFnCode()); | 
|         } | 
|         //设置默认父节点 | 
|         if(sysFunction.getFnParentId()==null){ | 
|             sysFunction.setFnParentId(0L); | 
|         } | 
|   | 
|         sysFunction.setFnId(null); | 
|         SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); | 
|         sysFunction.setCreateBy(user.getSuName()); | 
|         sysFunction.setUpdateBy(user.getSuName()); | 
|   | 
|         // 设置功能等级 | 
|         setFunctionGrade(sysFunction); | 
|         sysFunction.setFnIsDisable(AppConstance.IS_N); | 
|         int n = sysFunctionDao.insert(sysFunction); | 
|         // 添加功能所对应的按钮 | 
|         addFnBtnRel(sysFunction); | 
|   | 
|         return n; | 
|   | 
|     } | 
|   | 
|     /** | 
|      * 添加功能所对应的按钮 | 
|      *  | 
|      * @author JIANGYOUYAO | 
|      * @param fnId | 
|      * @email 935090232@qq.com | 
|      * @date 2017年12月4日 | 
|      * @param sysFunction | 
|      */ | 
|     private void addFnBtnRel(SysFunction function) { | 
|         List<SysFnBtnRel> rels = function.getSysFnBtnRel(); | 
|         List<SysFnBtnRel> newRels = new ArrayList<>(); | 
|         for (SysFnBtnRel sysFnBtnRel : rels) { | 
|             if (sysFnBtnRel.getBtnValue() == null) { | 
|                 continue; | 
|             } | 
|             sysFnBtnRel.setFnId(function.getFnId()); | 
|             sysFnBtnRel.setCreateBy(function.getCreateBy()); | 
|             sysFnBtnRel.setUpdateBy(function.getUpdateBy()); | 
|             newRels.add(sysFnBtnRel); | 
|         } | 
|         if (CollectionUtils.isNotEmpty(newRels)) { | 
|             sysFunctionDao.bathInsertFnButRel(newRels); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 删除功能所对应的按钮 | 
|      *  | 
|      * @author JIANGYOUYAO | 
|      * @email 935090232@qq.com | 
|      * @date 2017年12月4日 | 
|      * @param fnId | 
|      */ | 
|     private void removerFnBtnRel(Long fnId) { | 
|         sysFunctionDao.deleteFnBtnRel(fnId); | 
|     } | 
|   | 
|     /** | 
|      * 批量删除功能所对应的按钮 | 
|      *  | 
|      * @author JIANGYOUYAO | 
|      * @email 935090232@qq.com | 
|      * @date 2017年12月4日 | 
|      * @param fnId | 
|      */ | 
|     private void batchRemoverFnBtnRel(List<String> ids) { | 
|   | 
|         sysFunctionDao.deleteFnBtnRels(ids); | 
|     } | 
|   | 
|     /** | 
|      * 设置功能的等级 | 
|      *  | 
|      * @author JIANGYOUYAO | 
|      * @email 935090232@qq.com | 
|      * @date 2017年12月4日 | 
|      * @param sysFunction | 
|      */ | 
|     private void setFunctionGrade(SysFunction sysFunction) { | 
|         if (null==sysFunction.getFnParentId()||0==sysFunction.getFnParentId()) { | 
|             sysFunction.setFnGrade(AppConstance.FUNCTION_FIRST_LEVEL); | 
|         } else { | 
|             SysFunction parent = sysFunctionDao.selectById(sysFunction.getFnParentId()); | 
|             sysFunction.setFnGrade(parent.getFnGrade() + 1); | 
|         } | 
|     } | 
|   | 
|     @Override | 
|     public int batchAdd(List<SysFunction> sysFunctionList) { | 
|         return sysFunctionDao.batchInsert(sysFunctionList); | 
|     } | 
|   | 
|     @Transactional(rollbackFor = Exception.class) | 
|     @Override | 
|     public int modifyByMap(SysFunction oldSysFunction, SysFunction newSysFunction) { | 
|         // 自己不能是自己的父节点 | 
|         if (newSysFunction.getFnParentId() != null && newSysFunction.getFnParentId().equals(newSysFunction.getFnId())) { | 
|             throw new GlobleException("功能的父级不能是自己"); | 
|         } | 
|         // 功能code去重 | 
|         if (serviceUtil.updateCheckRepeat(tableName, FN_CODE, newSysFunction.getFnCode(), FN_ID, | 
|                 newSysFunction.getFnId())) { | 
|             throw new GlobleException("code已经存在!"); | 
|         } | 
|         // 设置功能等级 | 
|         setFunctionGrade(newSysFunction); | 
|         SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); | 
|         // 创建人的复制是为了按钮关系表能够赋值 | 
|         newSysFunction.setCreateBy(oldSysFunction.getCreateBy()); | 
|         newSysFunction.setUpdateBy(user.getSuName()); | 
|         Map<String, Object> modifyMap = null; | 
|         int dmlResult = 0; | 
|         try { | 
|             if (!ModelUtils.isModified(oldSysFunction, newSysFunction)) { | 
|                 return MatrixConstance.DML_SUCCESSS; | 
|             } | 
|             modifyMap = ModelUtils.comparePojo2Map(oldSysFunction, newSysFunction); | 
|         } catch (Exception e) { | 
|             throw new GlobleException(SystemErrorCode.DATA_UPDATE_FAIL, e, newSysFunction.getFnName()); | 
|         } | 
|         if (modifyMap.size() > 0) { | 
|             modifyMap.put("fnId", oldSysFunction.getFnId()); | 
|             dmlResult = sysFunctionDao.updateByMap(modifyMap); | 
|         } | 
|         removerFnBtnRel(oldSysFunction.getFnId()); | 
|         addFnBtnRel(newSysFunction); | 
|         return dmlResult; | 
|     } | 
|   | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public int modifyByModel(SysFunction sysFunction) { | 
|   | 
|         return sysFunctionDao.updateByModel(sysFunction); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public int remove(List<String> list) { | 
|         int count = 0; | 
|         for (String fnId : list) { | 
|             removeById(fnId); | 
|             count++; | 
|         } | 
|         return count; | 
|     } | 
|   | 
|     /** | 
|      * 删除功能和功能下的子功能 | 
|      *  | 
|      * @param fnId | 
|      * @return | 
|      */ | 
|     @Override | 
|     @Transactional(rollbackFor = Exception.class) | 
|     public int removeById(String fnId) { | 
|         if (fnId == null) { | 
|             return 0; | 
|         } | 
|         List<String> ids = getFunctionChirds(Long.valueOf(fnId), new ArrayList<String>()); | 
|         if (CollectionUtils.isNotEmpty(ids)) { | 
|             batchRemoverFnBtnRel(ids); | 
|         } | 
|         return sysFunctionDao.deleteByIds(ids); | 
|     } | 
|   | 
|     @Override | 
|     public int removeByModel(SysFunction sysFunction) { | 
|   | 
|         return sysFunctionDao.deleteByModel(sysFunction); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public List<SysFunction> findInPage(SysFunction sysFunction, PaginationVO pageVo) { | 
|   | 
|         return sysFunctionDao.selectInPage(sysFunction, pageVo); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public List<SysFunction> findByModel(SysFunction sysFunction) { | 
|   | 
|         return sysFunctionDao.selectByModel(sysFunction); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public int findTotal(SysFunction sysFunction) { | 
|   | 
|         return sysFunctionDao.selectTotalRecord(sysFunction); | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public SysFunction findById(String fnId) { | 
|   | 
|         return sysFunctionDao.selectById(Long.valueOf(fnId)); | 
|   | 
|     } | 
|   | 
|     /** | 
|      * 获取功能下的子功能id,包含功能自己的id | 
|      *  | 
|      * @param id | 
|      * @param ids | 
|      * @return | 
|      */ | 
|     private List<String> getFunctionChirds(Long id, List<String> ids) { | 
|         SysFunction fnquery = new SysFunction(); | 
|         fnquery.setFnParentId(id); | 
|         // 获取子节点 | 
|         List<SysFunction> list = sysFunctionDao.selectByModel(fnquery); | 
|         if (!list.isEmpty()) { | 
|             for (SysFunction function : list) { | 
|                 // 删除子节点 | 
|                 getFunctionChirds(function.getFnId(), ids); | 
|             } | 
|         } | 
|         ids.add(String.valueOf(id)); | 
|         return ids; | 
|     } | 
|   | 
|     @Override | 
|     public void setIsDisable(Long fnId, String status) { | 
|         SysFunction dbFunction = sysFunctionDao.selectById(fnId); | 
|         if (status.equals(AppConstance.IS_Y)) { | 
|             // 启用功能 | 
|             if (dbFunction.getFnIsDisable().equals(AppConstance.IS_Y)) { | 
|                 throw new GlobleException("功能已经是启用状态"); | 
|             } else { | 
|   | 
|                 List<String> list = getFunctionChirds(fnId, new ArrayList<String>()); | 
|                 sysFunctionDao.batchChangeStatu(AppConstance.IS_Y, list); | 
|             } | 
|         } else { | 
|             // 禁用功能 | 
|             if (dbFunction.getFnIsDisable().equals(AppConstance.IS_N)) { | 
|                 throw new GlobleException("功能已是禁用状态"); | 
|             } else { | 
|   | 
|                 // 启用子节点,和父节点,因为目前只考虑2级的情况先写死吧 | 
|                 List<String> ids = new ArrayList<String>(); | 
|                 if (dbFunction.getFnParentId() != null) { | 
|                     ids.add(String.valueOf(dbFunction.getFnParentId())); | 
|                 } | 
|                 sysFunctionDao.batchChangeStatu(AppConstance.IS_N, getFunctionChirds(fnId, ids)); | 
|   | 
|             } | 
|         } | 
|   | 
|     } | 
|   | 
|     @Override | 
|     public List<SysFunction> findCompanyFunction(Long companyId) { | 
|         return sysFunctionDao.selectCompanyFunction(companyId); | 
|     } | 
|   | 
|     @Override | 
|     public List<SysFunction> findFunctionByRoleIds(String roleIds) { | 
|         return sysFunctionDao.selectFunctionByRoleIds(roleIds); | 
|     } | 
|   | 
|     @Override | 
|     public List<SysFunction> findRoleFuntion(String roleId) { | 
|         // 获取所有的功能--》获取所有的按钮--》对于功能的按钮|构建功能的父子关系--》 | 
|         Map<String, SysFunction> roleFnMap = new HashMap<>(MatrixConstance.COLLECTION_SIZE); | 
|         // id为空则不需要查询选中项 | 
|         if (roleId != null) { | 
|             // 把角色所有的功能变成map | 
|             List<SysFunction> editorFunction = sysFunctionDao.selectFunctionByRoleIds(roleId); | 
|             for (SysFunction temp : editorFunction) { | 
|                 roleFnMap.put(String.valueOf(temp.getFnId()), temp); | 
|             } | 
|         } | 
|   | 
|         // 只查询出没有被禁用的 | 
|         SysUsers user = WebUtil.getSessionAttribute(MatrixConstance.LOGIN_KEY); | 
|         // 只能查本公司的 | 
|         List<SysFunction> allFunction = sysFunctionDao.selectCompanyFunction(user.getCompanyId()); | 
|         Map<String, SysFunction> allFnMap = new TreeMap<>(); | 
|         // 构建树形关系 | 
|         for (SysFunction sysFunction : allFunction) { | 
|             // 用一个map记录下每一个功能 | 
|             allFnMap.put(String.valueOf(sysFunction.getFnId()), sysFunction); | 
|         } | 
|   | 
|         List<SysFunction> treeFunction = new ArrayList<>(); | 
|         Set<String> keys = allFnMap.keySet(); | 
|         for (String currentFnId : keys) { | 
|   | 
|             SysFunction function = allFnMap.get(currentFnId); | 
|   | 
|             // 判断功能是否为当前角色拥有 | 
|             initHashPower(roleFnMap, currentFnId, function); | 
|   | 
|             // 如果是一级节点则直接存入菜单 | 
|             if (null==function.getFnParentId() || 0L==function.getFnParentId()) { | 
|                 treeFunction.add(function); | 
|             } else { | 
|                 // 非一级节点找到父节点后存入 | 
|                 SysFunction parentFn = allFnMap.get(String.valueOf(function.getFnParentId())); | 
|                 if(parentFn!=null){ | 
|                     List<SysFunction> childs = parentFn.getChilds(); | 
|                     if (childs == null) { | 
|                         parentFn.setChilds(new ArrayList<SysFunction>()); | 
|                     } | 
|                     parentFn.getChilds().add(function); | 
|                 } | 
|   | 
|             } | 
|   | 
|         } | 
|         return treeFunction; | 
|     } | 
|   | 
|     /** | 
|      * 给已经拥有的权限打上标记 | 
|      *  | 
|      * @author JIANGYOUYAO | 
|      * @email 935090232@qq.com | 
|      * @date 2017年12月6日 | 
|      * @param roleFnMap | 
|      * @param currentFnId | 
|      * @param function | 
|      */ | 
|     private void initHashPower(Map<String, SysFunction> roleFnMap, String currentFnId, SysFunction function) { | 
|         if (roleFnMap.containsKey(currentFnId)) { | 
|             // 功能是当前角色拥有的 | 
|             function.setHasThisFn(true); | 
|             // 判断按钮是否为当前角色拥有 | 
|             String rpfBns = roleFnMap.get(currentFnId).getRpfBns(); | 
|             String[] rpfBnsArray = rpfBns.split(","); | 
|   | 
|             List<SysFnBtnRel> fnBtnRelList = function.getSysFnBtnRel(); | 
|   | 
|             if (CollectionUtils.isNotEmpty(fnBtnRelList) && ArrayUtils.isNotEmpty(rpfBnsArray)) { | 
|   | 
|                 for (SysFnBtnRel fnBtnRel : fnBtnRelList) { | 
|                     for (String tempRpfBns : rpfBnsArray) { | 
|                         if (StringUtil.isNotBlank(fnBtnRel.getBtnValue()) &&fnBtnRel.getBtnValue().equals(tempRpfBns)) { | 
|                             fnBtnRel.setHasThisBtn(true); | 
|                             break; | 
|                         } | 
|                     } | 
|   | 
|                 } | 
|             } | 
|         } | 
|     } | 
|   | 
|   | 
| } |