懒羊羊
2024-01-31 e57a8990ae56f657a59c435a0613c5f7a8728003
提交 | 用户 | 时间
e57a89 1 package com.jcdm.system.service.impl;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashSet;
6 import java.util.Iterator;
7 import java.util.LinkedList;
8 import java.util.List;
9 import java.util.Set;
10 import java.util.stream.Collectors;
11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.stereotype.Service;
13 import com.jcdm.common.constant.Constants;
14 import com.jcdm.common.constant.UserConstants;
15 import com.jcdm.common.core.domain.TreeSelect;
16 import com.jcdm.common.core.domain.entity.SysMenu;
17 import com.jcdm.common.core.domain.entity.SysRole;
18 import com.jcdm.common.core.domain.entity.SysUser;
19 import com.jcdm.common.utils.SecurityUtils;
20 import com.jcdm.common.utils.StringUtils;
21 import com.jcdm.system.domain.vo.MetaVo;
22 import com.jcdm.system.domain.vo.RouterVo;
23 import com.jcdm.system.mapper.SysMenuMapper;
24 import com.jcdm.system.mapper.SysRoleMapper;
25 import com.jcdm.system.mapper.SysRoleMenuMapper;
26 import com.jcdm.system.service.ISysMenuService;
27
28 /**
29  * 菜单 业务层处理
30  * 
31  * @author jc
32  */
33 @Service
34 public class SysMenuServiceImpl implements ISysMenuService
35 {
36     public static final String PREMISSION_STRING = "perms[\"{0}\"]";
37
38     @Autowired
39     private SysMenuMapper menuMapper;
40
41     @Autowired
42     private SysRoleMapper roleMapper;
43
44     @Autowired
45     private SysRoleMenuMapper roleMenuMapper;
46
47     /**
48      * 根据用户查询系统菜单列表
49      * 
50      * @param userId 用户ID
51      * @return 菜单列表
52      */
53     @Override
54     public List<SysMenu> selectMenuList(Long userId)
55     {
56         return selectMenuList(new SysMenu(), userId);
57     }
58
59     /**
60      * 查询系统菜单列表
61      * 
62      * @param menu 菜单信息
63      * @return 菜单列表
64      */
65     @Override
66     public List<SysMenu> selectMenuList(SysMenu menu, Long userId)
67     {
68         List<SysMenu> menuList = null;
69         // 管理员显示所有菜单信息
70         if (SysUser.isAdmin(userId))
71         {
72             menuList = menuMapper.selectMenuList(menu);
73         }
74         else
75         {
76             menu.getParams().put("userId", userId);
77             menuList = menuMapper.selectMenuListByUserId(menu);
78         }
79         return menuList;
80     }
81
82     /**
83      * 根据用户ID查询权限
84      * 
85      * @param userId 用户ID
86      * @return 权限列表
87      */
88     @Override
89     public Set<String> selectMenuPermsByUserId(Long userId)
90     {
91         List<String> perms = menuMapper.selectMenuPermsByUserId(userId);
92         Set<String> permsSet = new HashSet<>();
93         for (String perm : perms)
94         {
95             if (StringUtils.isNotEmpty(perm))
96             {
97                 permsSet.addAll(Arrays.asList(perm.trim().split(",")));
98             }
99         }
100         return permsSet;
101     }
102
103     /**
104      * 根据角色ID查询权限
105      * 
106      * @param roleId 角色ID
107      * @return 权限列表
108      */
109     @Override
110     public Set<String> selectMenuPermsByRoleId(Long roleId)
111     {
112         List<String> perms = menuMapper.selectMenuPermsByRoleId(roleId);
113         Set<String> permsSet = new HashSet<>();
114         for (String perm : perms)
115         {
116             if (StringUtils.isNotEmpty(perm))
117             {
118                 permsSet.addAll(Arrays.asList(perm.trim().split(",")));
119             }
120         }
121         return permsSet;
122     }
123
124     /**
125      * 根据用户ID查询菜单
126      * 
127      * @param userId 用户名称
128      * @return 菜单列表
129      */
130     @Override
131     public List<SysMenu> selectMenuTreeByUserId(Long userId)
132     {
133         List<SysMenu> menus = null;
134         if (SecurityUtils.isAdmin(userId))
135         {
136             menus = menuMapper.selectMenuTreeAll();
137         }
138         else
139         {
140             menus = menuMapper.selectMenuTreeByUserId(userId);
141         }
142         return getChildPerms(menus, 0);
143     }
144
145     /**
146      * 根据角色ID查询菜单树信息
147      * 
148      * @param roleId 角色ID
149      * @return 选中菜单列表
150      */
151     @Override
152     public List<Long> selectMenuListByRoleId(Long roleId)
153     {
154         SysRole role = roleMapper.selectRoleById(roleId);
155         return menuMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly());
156     }
157
158     /**
159      * 构建前端路由所需要的菜单
160      * 
161      * @param menus 菜单列表
162      * @return 路由列表
163      */
164     @Override
165     public List<RouterVo> buildMenus(List<SysMenu> menus)
166     {
167         List<RouterVo> routers = new LinkedList<RouterVo>();
168         for (SysMenu menu : menus)
169         {
170             RouterVo router = new RouterVo();
171             router.setHidden("1".equals(menu.getVisible()));
172             router.setName(getRouteName(menu));
173             router.setPath(getRouterPath(menu));
174             router.setComponent(getComponent(menu));
175             router.setQuery(menu.getQuery());
176             router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
177             List<SysMenu> cMenus = menu.getChildren();
178             if (StringUtils.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType()))
179             {
180                 router.setAlwaysShow(true);
181                 router.setRedirect("noRedirect");
182                 router.setChildren(buildMenus(cMenus));
183             }
184             else if (isMenuFrame(menu))
185             {
186                 router.setMeta(null);
187                 List<RouterVo> childrenList = new ArrayList<RouterVo>();
188                 RouterVo children = new RouterVo();
189                 children.setPath(menu.getPath());
190                 children.setComponent(menu.getComponent());
191                 children.setName(StringUtils.capitalize(menu.getPath()));
192                 children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
193                 children.setQuery(menu.getQuery());
194                 childrenList.add(children);
195                 router.setChildren(childrenList);
196             }
197             else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
198             {
199                 router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
200                 router.setPath("/");
201                 List<RouterVo> childrenList = new ArrayList<RouterVo>();
202                 RouterVo children = new RouterVo();
203                 String routerPath = innerLinkReplaceEach(menu.getPath());
204                 children.setPath(routerPath);
205                 children.setComponent(UserConstants.INNER_LINK);
206                 children.setName(StringUtils.capitalize(routerPath));
207                 children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
208                 childrenList.add(children);
209                 router.setChildren(childrenList);
210             }
211             routers.add(router);
212         }
213         return routers;
214     }
215
216     /**
217      * 构建前端所需要树结构
218      * 
219      * @param menus 菜单列表
220      * @return 树结构列表
221      */
222     @Override
223     public List<SysMenu> buildMenuTree(List<SysMenu> menus)
224     {
225         List<SysMenu> returnList = new ArrayList<SysMenu>();
226         List<Long> tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
227         for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext();)
228         {
229             SysMenu menu = (SysMenu) iterator.next();
230             // 如果是顶级节点, 遍历该父节点的所有子节点
231             if (!tempList.contains(menu.getParentId()))
232             {
233                 recursionFn(menus, menu);
234                 returnList.add(menu);
235             }
236         }
237         if (returnList.isEmpty())
238         {
239             returnList = menus;
240         }
241         return returnList;
242     }
243
244     /**
245      * 构建前端所需要下拉树结构
246      * 
247      * @param menus 菜单列表
248      * @return 下拉树结构列表
249      */
250     @Override
251     public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus)
252     {
253         List<SysMenu> menuTrees = buildMenuTree(menus);
254         return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
255     }
256
257     /**
258      * 根据菜单ID查询信息
259      * 
260      * @param menuId 菜单ID
261      * @return 菜单信息
262      */
263     @Override
264     public SysMenu selectMenuById(Long menuId)
265     {
266         return menuMapper.selectMenuById(menuId);
267     }
268
269     /**
270      * 是否存在菜单子节点
271      * 
272      * @param menuId 菜单ID
273      * @return 结果
274      */
275     @Override
276     public boolean hasChildByMenuId(Long menuId)
277     {
278         int result = menuMapper.hasChildByMenuId(menuId);
279         return result > 0;
280     }
281
282     /**
283      * 查询菜单使用数量
284      * 
285      * @param menuId 菜单ID
286      * @return 结果
287      */
288     @Override
289     public boolean checkMenuExistRole(Long menuId)
290     {
291         int result = roleMenuMapper.checkMenuExistRole(menuId);
292         return result > 0;
293     }
294
295     /**
296      * 新增保存菜单信息
297      * 
298      * @param menu 菜单信息
299      * @return 结果
300      */
301     @Override
302     public int insertMenu(SysMenu menu)
303     {
304         return menuMapper.insertMenu(menu);
305     }
306
307     /**
308      * 修改保存菜单信息
309      * 
310      * @param menu 菜单信息
311      * @return 结果
312      */
313     @Override
314     public int updateMenu(SysMenu menu)
315     {
316         return menuMapper.updateMenu(menu);
317     }
318
319     /**
320      * 删除菜单管理信息
321      * 
322      * @param menuId 菜单ID
323      * @return 结果
324      */
325     @Override
326     public int deleteMenuById(Long menuId)
327     {
328         return menuMapper.deleteMenuById(menuId);
329     }
330
331     /**
332      * 校验菜单名称是否唯一
333      * 
334      * @param menu 菜单信息
335      * @return 结果
336      */
337     @Override
338     public boolean checkMenuNameUnique(SysMenu menu)
339     {
340         Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
341         SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId());
342         if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue())
343         {
344             return UserConstants.NOT_UNIQUE;
345         }
346         return UserConstants.UNIQUE;
347     }
348
349     /**
350      * 获取路由名称
351      * 
352      * @param menu 菜单信息
353      * @return 路由名称
354      */
355     public String getRouteName(SysMenu menu)
356     {
357         String routerName = StringUtils.capitalize(menu.getPath());
358         // 非外链并且是一级目录(类型为目录)
359         if (isMenuFrame(menu))
360         {
361             routerName = StringUtils.EMPTY;
362         }
363         return routerName;
364     }
365
366     /**
367      * 获取路由地址
368      * 
369      * @param menu 菜单信息
370      * @return 路由地址
371      */
372     public String getRouterPath(SysMenu menu)
373     {
374         String routerPath = menu.getPath();
375         // 内链打开外网方式
376         if (menu.getParentId().intValue() != 0 && isInnerLink(menu))
377         {
378             routerPath = innerLinkReplaceEach(routerPath);
379         }
380         // 非外链并且是一级目录(类型为目录)
381         if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
382                 && UserConstants.NO_FRAME.equals(menu.getIsFrame()))
383         {
384             routerPath = "/" + menu.getPath();
385         }
386         // 非外链并且是一级目录(类型为菜单)
387         else if (isMenuFrame(menu))
388         {
389             routerPath = "/";
390         }
391         return routerPath;
392     }
393
394     /**
395      * 获取组件信息
396      * 
397      * @param menu 菜单信息
398      * @return 组件信息
399      */
400     public String getComponent(SysMenu menu)
401     {
402         String component = UserConstants.LAYOUT;
403         if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu))
404         {
405             component = menu.getComponent();
406         }
407         else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu))
408         {
409             component = UserConstants.INNER_LINK;
410         }
411         else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu))
412         {
413             component = UserConstants.PARENT_VIEW;
414         }
415         return component;
416     }
417
418     /**
419      * 是否为菜单内部跳转
420      * 
421      * @param menu 菜单信息
422      * @return 结果
423      */
424     public boolean isMenuFrame(SysMenu menu)
425     {
426         return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
427                 && menu.getIsFrame().equals(UserConstants.NO_FRAME);
428     }
429
430     /**
431      * 是否为内链组件
432      * 
433      * @param menu 菜单信息
434      * @return 结果
435      */
436     public boolean isInnerLink(SysMenu menu)
437     {
438         return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
439     }
440
441     /**
442      * 是否为parent_view组件
443      * 
444      * @param menu 菜单信息
445      * @return 结果
446      */
447     public boolean isParentView(SysMenu menu)
448     {
449         return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
450     }
451
452     /**
453      * 根据父节点的ID获取所有子节点
454      * 
455      * @param list 分类表
456      * @param parentId 传入的父节点ID
457      * @return String
458      */
459     public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId)
460     {
461         List<SysMenu> returnList = new ArrayList<SysMenu>();
462         for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext();)
463         {
464             SysMenu t = (SysMenu) iterator.next();
465             // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
466             if (t.getParentId() == parentId)
467             {
468                 recursionFn(list, t);
469                 returnList.add(t);
470             }
471         }
472         return returnList;
473     }
474
475     /**
476      * 递归列表
477      * 
478      * @param list 分类表
479      * @param t 子节点
480      */
481     private void recursionFn(List<SysMenu> list, SysMenu t)
482     {
483         // 得到子节点列表
484         List<SysMenu> childList = getChildList(list, t);
485         t.setChildren(childList);
486         for (SysMenu tChild : childList)
487         {
488             if (hasChild(list, tChild))
489             {
490                 recursionFn(list, tChild);
491             }
492         }
493     }
494
495     /**
496      * 得到子节点列表
497      */
498     private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t)
499     {
500         List<SysMenu> tlist = new ArrayList<SysMenu>();
501         Iterator<SysMenu> it = list.iterator();
502         while (it.hasNext())
503         {
504             SysMenu n = (SysMenu) it.next();
505             if (n.getParentId().longValue() == t.getMenuId().longValue())
506             {
507                 tlist.add(n);
508             }
509         }
510         return tlist;
511     }
512
513     /**
514      * 判断是否有子节点
515      */
516     private boolean hasChild(List<SysMenu> list, SysMenu t)
517     {
518         return getChildList(list, t).size() > 0;
519     }
520
521     /**
522      * 内链域名特殊字符替换
523      * 
524      * @return 替换后的内链域名
525      */
526     public String innerLinkReplaceEach(String path)
527     {
528         return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" },
529                 new String[] { "", "", "", "/", "/" });
530     }
531 }