xm
2024-06-14 722af26bc6fec32bb289b1df51a9016a4935610f
提交 | 用户 | 时间
722af2 1 package com.dl.system.service.impl;
X 2
3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.tree.Tree;
5 import cn.hutool.core.util.ObjectUtil;
6 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
7 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
8 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
9 import com.dl.common.constant.Constants;
10 import com.dl.common.constant.UserConstants;
11 import com.dl.common.core.domain.entity.SysMenu;
12 import com.dl.common.core.domain.entity.SysRole;
13 import com.dl.common.helper.LoginHelper;
14 import com.dl.common.utils.StreamUtils;
15 import com.dl.common.utils.StringUtils;
16 import com.dl.common.utils.TreeBuildUtils;
17 import com.dl.system.domain.SysRoleMenu;
18 import com.dl.system.domain.vo.MetaVo;
19 import com.dl.system.domain.vo.RouterVo;
20 import com.dl.system.mapper.SysMenuMapper;
21 import com.dl.system.mapper.SysRoleMapper;
22 import com.dl.system.mapper.SysRoleMenuMapper;
23 import com.dl.system.service.ISysMenuService;
24 import lombok.RequiredArgsConstructor;
25 import org.springframework.stereotype.Service;
26
27 import java.util.*;
28
29 /**
30  * 菜单 业务层处理
31  *
32  * @author Lion Li
33  */
34 @RequiredArgsConstructor
35 @Service
36 public class SysMenuServiceImpl implements ISysMenuService {
37
38     private final SysMenuMapper baseMapper;
39     private final SysRoleMapper roleMapper;
40     private final SysRoleMenuMapper roleMenuMapper;
41
42     /**
43      * 根据用户查询系统菜单列表
44      *
45      * @param userId 用户ID
46      * @return 菜单列表
47      */
48     @Override
49     public List<SysMenu> selectMenuList(String userId) {
50         return selectMenuList(new SysMenu(), userId);
51     }
52
53     /**
54      * 查询系统菜单列表
55      *
56      * @param menu 菜单信息
57      * @return 菜单列表
58      */
59     @Override
60     public List<SysMenu> selectMenuList(SysMenu menu, String userId) {
61         List<SysMenu> menuList = null;
62         // 管理员显示所有菜单信息
63         if (LoginHelper.isAdmin(userId)) {
64             menuList = baseMapper.selectList(new LambdaQueryWrapper<SysMenu>()
65                 .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
66                 .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
67                 .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
68                 .orderByAsc(SysMenu::getParentId)
69                 .orderByAsc(SysMenu::getOrderNum));
70         } else {
71             QueryWrapper<SysMenu> wrapper = Wrappers.query();
72             wrapper.eq("sur.user_id", userId)
73                 .like(StringUtils.isNotBlank(menu.getMenuName()), "m.menu_name", menu.getMenuName())
74                 .eq(StringUtils.isNotBlank(menu.getVisible()), "m.visible", menu.getVisible())
75                 .eq(StringUtils.isNotBlank(menu.getStatus()), "m.status", menu.getStatus())
76                 .orderByAsc("m.parent_id")
77                 .orderByAsc("m.order_num");
78             menuList = baseMapper.selectMenuListByUserId(wrapper);
79         }
80         return menuList;
81     }
82
83     /**
84      * 根据用户ID查询权限
85      *
86      * @param userId 用户ID
87      * @return 权限列表
88      */
89     @Override
90     public Set<String> selectMenuPermsByUserId(String userId) {
91         List<String> perms = baseMapper.selectMenuPermsByUserId(userId);
92         Set<String> permsSet = new HashSet<>();
93         for (String perm : perms) {
94             if (StringUtils.isNotEmpty(perm)) {
95                 permsSet.addAll(StringUtils.splitList(perm.trim()));
96             }
97         }
98         return permsSet;
99     }
100
101     /**
102      * 根据角色ID查询权限
103      *
104      * @param roleId 角色ID
105      * @return 权限列表
106      */
107     @Override
108     public Set<String> selectMenuPermsByRoleId(Long roleId) {
109         List<String> perms = baseMapper.selectMenuPermsByRoleId(roleId);
110         Set<String> permsSet = new HashSet<>();
111         for (String perm : perms) {
112             if (StringUtils.isNotEmpty(perm)) {
113                 permsSet.addAll(StringUtils.splitList(perm.trim()));
114             }
115         }
116         return permsSet;
117     }
118
119     /**
120      * 根据用户ID查询菜单
121      *
122      * @param userId 用户名称
123      * @return 菜单列表
124      */
125     @Override
126     public List<SysMenu> selectMenuTreeByUserId(String userId) {
127         List<SysMenu> menus = null;
128         if (LoginHelper.isAdmin(userId)) {
129             menus = baseMapper.selectMenuTreeAll();
130         } else {
131             menus = baseMapper.selectMenuTreeByUserId(userId);
132         }
133         return getChildPerms(menus, 0);
134     }
135
136     /**
137      * 根据角色ID查询菜单树信息
138      *
139      * @param roleId 角色ID
140      * @return 选中菜单列表
141      */
142     @Override
143     public List<Long> selectMenuListByRoleId(Long roleId) {
144         SysRole role = roleMapper.selectById(roleId);
145         return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
146     }
147
148     /**
149      * 构建前端路由所需要的菜单
150      *
151      * @param menus 菜单列表
152      * @return 路由列表
153      */
154     @Override
155     public List<RouterVo> buildMenus(List<SysMenu> menus) {
156         List<RouterVo> routers = new LinkedList<>();
157         for (SysMenu menu : menus) {
158             RouterVo router = new RouterVo();
159             router.setHidden("1".equals(menu.getVisible()));
160             router.setName(getRouteName(menu));
161             router.setPath(getRouterPath(menu));
162             router.setComponent(getComponent(menu));
163             router.setQuery(menu.getQueryParam());
164             router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
165             List<SysMenu> cMenus = menu.getChildren();
166             if (CollUtil.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
167                 router.setAlwaysShow(true);
168                 router.setRedirect("noRedirect");
169                 router.setChildren(buildMenus(cMenus));
170             } else if (isMenuFrame(menu)) {
171                 router.setMeta(null);
172                 List<RouterVo> childrenList = new ArrayList<>();
173                 RouterVo children = new RouterVo();
174                 children.setPath(menu.getPath());
175                 children.setComponent(menu.getComponent());
176                 children.setName(StringUtils.capitalize(menu.getPath()));
177                 children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
178                 children.setQuery(menu.getQueryParam());
179                 childrenList.add(children);
180                 router.setChildren(childrenList);
181             } else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) {
182                 router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
183                 router.setPath("/");
184                 List<RouterVo> childrenList = new ArrayList<>();
185                 RouterVo children = new RouterVo();
186                 String routerPath = innerLinkReplaceEach(menu.getPath());
187                 children.setPath(routerPath);
188                 children.setComponent(UserConstants.INNER_LINK);
189                 children.setName(StringUtils.capitalize(routerPath));
190                 children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
191                 childrenList.add(children);
192                 router.setChildren(childrenList);
193             }
194             routers.add(router);
195         }
196         return routers;
197     }
198
199     /**
200      * 构建前端所需要下拉树结构
201      *
202      * @param menus 菜单列表
203      * @return 下拉树结构列表
204      */
205     @Override
206     public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
207         if (CollUtil.isEmpty(menus)) {
208             return CollUtil.newArrayList();
209         }
210         return TreeBuildUtils.build(menus, (menu, tree) ->
211             tree.setId(menu.getMenuId())
212                 .setParentId(menu.getParentId())
213                 .setName(menu.getMenuName())
214                 .setWeight(menu.getOrderNum()));
215     }
216
217     /**
218      * 根据菜单ID查询信息
219      *
220      * @param menuId 菜单ID
221      * @return 菜单信息
222      */
223     @Override
224     public SysMenu selectMenuById(Long menuId) {
225         return baseMapper.selectById(menuId);
226     }
227
228     /**
229      * 是否存在菜单子节点
230      *
231      * @param menuId 菜单ID
232      * @return 结果
233      */
234     @Override
235     public boolean hasChildByMenuId(Long menuId) {
236         return baseMapper.exists(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
237     }
238
239     /**
240      * 查询菜单使用数量
241      *
242      * @param menuId 菜单ID
243      * @return 结果
244      */
245     @Override
246     public boolean checkMenuExistRole(Long menuId) {
247         return roleMenuMapper.exists(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
248     }
249
250     /**
251      * 新增保存菜单信息
252      *
253      * @param menu 菜单信息
254      * @return 结果
255      */
256     @Override
257     public int insertMenu(SysMenu menu) {
258         return baseMapper.insert(menu);
259     }
260
261     /**
262      * 修改保存菜单信息
263      *
264      * @param menu 菜单信息
265      * @return 结果
266      */
267     @Override
268     public int updateMenu(SysMenu menu) {
269         return baseMapper.updateById(menu);
270     }
271
272     /**
273      * 删除菜单管理信息
274      *
275      * @param menuId 菜单ID
276      * @return 结果
277      */
278     @Override
279     public int deleteMenuById(Long menuId) {
280         return baseMapper.deleteById(menuId);
281     }
282
283     /**
284      * 校验菜单名称是否唯一
285      *
286      * @param menu 菜单信息
287      * @return 结果
288      */
289     @Override
290     public boolean checkMenuNameUnique(SysMenu menu) {
291         boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysMenu>()
292             .eq(SysMenu::getMenuName, menu.getMenuName())
293             .eq(SysMenu::getParentId, menu.getParentId())
294             .ne(ObjectUtil.isNotNull(menu.getMenuId()), SysMenu::getMenuId, menu.getMenuId()));
295         return !exist;
296     }
297
298     /**
299      * 获取路由名称
300      *
301      * @param menu 菜单信息
302      * @return 路由名称
303      */
304     public String getRouteName(SysMenu menu) {
305         String routerName = StringUtils.capitalize(menu.getPath());
306         // 非外链并且是一级目录(类型为目录)
307         if (isMenuFrame(menu)) {
308             routerName = StringUtils.EMPTY;
309         }
310         return routerName;
311     }
312
313     /**
314      * 获取路由地址
315      *
316      * @param menu 菜单信息
317      * @return 路由地址
318      */
319     public String getRouterPath(SysMenu menu) {
320         String routerPath = menu.getPath();
321         // 内链打开外网方式
322         if (menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
323             routerPath = innerLinkReplaceEach(routerPath);
324         }
325         // 非外链并且是一级目录(类型为目录)
326         if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
327             && UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
328             routerPath = "/" + menu.getPath();
329         }
330         // 非外链并且是一级目录(类型为菜单)
331         else if (isMenuFrame(menu)) {
332             routerPath = "/";
333         }
334         return routerPath;
335     }
336
337     /**
338      * 获取组件信息
339      *
340      * @param menu 菜单信息
341      * @return 组件信息
342      */
343     public String getComponent(SysMenu menu) {
344         String component = UserConstants.LAYOUT;
345         if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
346             component = menu.getComponent();
347         } else if (StringUtils.isEmpty(menu.getComponent()) && menu.getParentId().intValue() != 0 && isInnerLink(menu)) {
348             component = UserConstants.INNER_LINK;
349         } else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
350             component = UserConstants.PARENT_VIEW;
351         }
352         return component;
353     }
354
355     /**
356      * 是否为菜单内部跳转
357      *
358      * @param menu 菜单信息
359      * @return 结果
360      */
361     public boolean isMenuFrame(SysMenu menu) {
362         return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
363             && menu.getIsFrame().equals(UserConstants.NO_FRAME);
364     }
365
366     /**
367      * 是否为内链组件
368      *
369      * @param menu 菜单信息
370      * @return 结果
371      */
372     public boolean isInnerLink(SysMenu menu) {
373         return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
374     }
375
376     /**
377      * 是否为parent_view组件
378      *
379      * @param menu 菜单信息
380      * @return 结果
381      */
382     public boolean isParentView(SysMenu menu) {
383         return menu.getParentId().intValue() != 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType());
384     }
385
386     /**
387      * 根据父节点的ID获取所有子节点
388      *
389      * @param list     分类表
390      * @param parentId 传入的父节点ID
391      * @return String
392      */
393     public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
394         List<SysMenu> returnList = new ArrayList<>();
395         for (SysMenu t : list) {
396             // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
397             if (t.getParentId() == parentId) {
398                 recursionFn(list, t);
399                 returnList.add(t);
400             }
401         }
402         return returnList;
403     }
404
405     /**
406      * 递归列表
407      *
408      * @param list
409      * @param t
410      */
411     private void recursionFn(List<SysMenu> list, SysMenu t) {
412         // 得到子节点列表
413         List<SysMenu> childList = getChildList(list, t);
414         t.setChildren(childList);
415         for (SysMenu tChild : childList) {
416             if (hasChild(list, tChild)) {
417                 recursionFn(list, tChild);
418             }
419         }
420     }
421
422     /**
423      * 得到子节点列表
424      */
425     private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
426         return StreamUtils.filter(list, n -> n.getParentId().equals(t.getMenuId()));
427     }
428
429     /**
430      * 判断是否有子节点
431      */
432     private boolean hasChild(List<SysMenu> list, SysMenu t) {
433         return CollUtil.isNotEmpty(getChildList(list, t));
434     }
435
436     /**
437      * 内链域名特殊字符替换
438      */
439     public String innerLinkReplaceEach(String path) {
440         return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "."},
441             new String[]{"", "", "", "/"});
442     }
443 }