commit | author | age
|
9bcb19
|
1 |
/* |
I |
2 |
Copyright [2020] [https://www.xiaonuo.vip] |
|
3 |
|
|
4 |
Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 |
you may not use this file except in compliance with the License. |
|
6 |
You may obtain a copy of the License at |
|
7 |
|
|
8 |
http://www.apache.org/licenses/LICENSE-2.0 |
|
9 |
|
|
10 |
Unless required by applicable law or agreed to in writing, software |
|
11 |
distributed under the License is distributed on an "AS IS" BASIS, |
|
12 |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 |
See the License for the specific language governing permissions and |
|
14 |
limitations under the License. |
|
15 |
|
|
16 |
Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: |
|
17 |
|
|
18 |
1.请不要删除和修改根目录下的LICENSE文件。 |
|
19 |
2.请不要删除和修改Snowy源码头部的版权声明。 |
|
20 |
3.请保留源码和相关描述文件的项目出处,作者声明等。 |
|
21 |
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy |
|
22 |
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy |
|
23 |
6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip |
|
24 |
*/ |
|
25 |
package vip.xiaonuo.sys.modular.menu.service.impl; |
|
26 |
|
|
27 |
import cn.hutool.core.bean.BeanUtil; |
|
28 |
import cn.hutool.core.collection.CollectionUtil; |
|
29 |
import cn.hutool.core.util.ObjectUtil; |
|
30 |
import cn.hutool.core.util.StrUtil; |
|
31 |
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
32 |
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
|
33 |
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|
34 |
import org.springframework.stereotype.Service; |
|
35 |
import org.springframework.transaction.annotation.Transactional; |
|
36 |
import vip.xiaonuo.core.consts.SymbolConstant; |
|
37 |
import vip.xiaonuo.core.context.login.LoginContextHolder; |
|
38 |
import vip.xiaonuo.core.enums.CommonStatusEnum; |
|
39 |
import vip.xiaonuo.core.enums.YesOrNotEnum; |
|
40 |
import vip.xiaonuo.core.exception.ServiceException; |
|
41 |
import vip.xiaonuo.core.factory.TreeBuildFactory; |
|
42 |
import vip.xiaonuo.core.pojo.node.LoginMenuTreeNode; |
|
43 |
import vip.xiaonuo.sys.core.cache.ResourceCache; |
|
44 |
import vip.xiaonuo.sys.core.enums.AdminTypeEnum; |
|
45 |
import vip.xiaonuo.sys.core.enums.MenuOpenTypeEnum; |
|
46 |
import vip.xiaonuo.sys.core.enums.MenuTypeEnum; |
|
47 |
import vip.xiaonuo.sys.core.enums.MenuWeightEnum; |
|
48 |
import vip.xiaonuo.sys.modular.menu.entity.SysMenu; |
|
49 |
import vip.xiaonuo.sys.modular.menu.enums.SysMenuExceptionEnum; |
|
50 |
import vip.xiaonuo.sys.modular.menu.mapper.SysMenuMapper; |
|
51 |
import vip.xiaonuo.sys.modular.menu.node.MenuBaseTreeNode; |
|
52 |
import vip.xiaonuo.sys.modular.menu.param.SysMenuParam; |
|
53 |
import vip.xiaonuo.sys.modular.menu.service.SysMenuService; |
|
54 |
import vip.xiaonuo.sys.modular.role.service.SysRoleMenuService; |
|
55 |
import vip.xiaonuo.sys.modular.user.entity.SysUser; |
|
56 |
import vip.xiaonuo.sys.modular.user.service.SysUserRoleService; |
|
57 |
import vip.xiaonuo.sys.modular.user.service.SysUserService; |
|
58 |
|
|
59 |
import javax.annotation.Resource; |
|
60 |
import java.util.List; |
|
61 |
import java.util.Set; |
|
62 |
import java.util.stream.Collectors; |
|
63 |
|
|
64 |
/** |
|
65 |
* 系统菜单service接口实现类 |
|
66 |
* |
|
67 |
* @author xuyuxiang |
|
68 |
* @date 2020/3/13 16:05 |
|
69 |
*/ |
|
70 |
@Service |
|
71 |
@SuppressWarnings("unchecked") |
|
72 |
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService { |
|
73 |
|
|
74 |
@Resource |
|
75 |
private SysUserService sysUserService; |
|
76 |
|
|
77 |
@Resource |
|
78 |
private SysUserRoleService sysUserRoleService; |
|
79 |
|
|
80 |
@Resource |
|
81 |
private SysRoleMenuService sysRoleMenuService; |
|
82 |
|
|
83 |
@Resource |
|
84 |
private ResourceCache resourceCache; |
|
85 |
|
|
86 |
@Override |
|
87 |
public List<String> getLoginPermissions(Long userId, List<Long> menuIdList) { |
|
88 |
Set<String> permissions = CollectionUtil.newHashSet(); |
|
89 |
if (ObjectUtil.isNotEmpty(menuIdList)) { |
|
90 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
91 |
queryWrapper.in(SysMenu::getId, menuIdList).ne(SysMenu::getType, MenuTypeEnum.DIR.getCode()) |
|
92 |
.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); |
|
93 |
|
|
94 |
this.list(queryWrapper).forEach(sysMenu -> { |
|
95 |
if(MenuTypeEnum.BTN.getCode().equals(sysMenu.getType())) { |
|
96 |
permissions.add(sysMenu.getPermission()); |
|
97 |
} else { |
|
98 |
String removePrefix = StrUtil.removePrefix(sysMenu.getRouter(), SymbolConstant.LEFT_DIVIDE); |
|
99 |
String permission = removePrefix.replaceAll(SymbolConstant.LEFT_DIVIDE, SymbolConstant.COLON); |
|
100 |
permissions.add(permission); |
|
101 |
} |
|
102 |
}); |
|
103 |
} |
|
104 |
return CollectionUtil.newArrayList(permissions); |
|
105 |
} |
|
106 |
|
|
107 |
@Override |
|
108 |
public List<SysMenu> getLoginMenus(Long userId, String appCode, List<Long> menuIdList) { |
|
109 |
//如果是超级管理员则展示所有系统权重菜单,不能展示业务权重菜单 |
|
110 |
SysUser sysUser = sysUserService.getById(userId); |
|
111 |
Integer adminType = sysUser.getAdminType(); |
|
112 |
|
|
113 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
114 |
|
|
115 |
if (AdminTypeEnum.SUPER_ADMIN.getCode().equals(adminType)) { |
|
116 |
|
|
117 |
//查询权重不为业务权重的且类型不是按钮的 |
|
118 |
queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) |
|
119 |
.eq(SysMenu::getApplication, appCode) |
|
120 |
.notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) |
|
121 |
.notIn(SysMenu::getWeight, MenuWeightEnum.DEFAULT_WEIGHT.getCode()) |
|
122 |
.orderByAsc(SysMenu::getSort); |
|
123 |
} else { |
|
124 |
|
|
125 |
//非超级管理员则获取自己角色所拥有的菜单集合 |
|
126 |
if (ObjectUtil.isNotEmpty(menuIdList)) { |
|
127 |
queryWrapper.in(SysMenu::getId, menuIdList) |
|
128 |
.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) |
|
129 |
.eq(SysMenu::getApplication, appCode) |
|
130 |
.notIn(SysMenu::getType, MenuTypeEnum.BTN.getCode()) |
|
131 |
.orderByAsc(SysMenu::getSort); |
|
132 |
} else { |
|
133 |
//如果角色的菜单为空,则查不到菜单 |
|
134 |
return CollectionUtil.newArrayList(); |
|
135 |
} |
|
136 |
} |
|
137 |
//查询列表 |
|
138 |
return this.list(queryWrapper); |
|
139 |
} |
|
140 |
|
|
141 |
/** |
|
142 |
* 将SysMenu格式菜单转换为LoginMenuTreeNode菜单 |
|
143 |
* |
|
144 |
* @author xuyuxiang |
|
145 |
* @date 2020/4/17 17:53 |
|
146 |
*/ |
|
147 |
@Override |
|
148 |
public List<LoginMenuTreeNode> convertSysMenuToLoginMenu(List<SysMenu> sysMenuList) { |
|
149 |
List<LoginMenuTreeNode> antDesignMenuTreeNodeList = CollectionUtil.newArrayList(); |
|
150 |
sysMenuList.forEach(sysMenu -> { |
|
151 |
LoginMenuTreeNode loginMenuTreeNode = new LoginMenuTreeNode(); |
|
152 |
loginMenuTreeNode.setComponent(sysMenu.getComponent()); |
|
153 |
loginMenuTreeNode.setId(sysMenu.getId()); |
|
154 |
loginMenuTreeNode.setName(sysMenu.getCode()); |
|
155 |
loginMenuTreeNode.setPath(sysMenu.getRouter()); |
|
156 |
loginMenuTreeNode.setPid(sysMenu.getPid()); |
|
157 |
LoginMenuTreeNode.Meta mateItem = new LoginMenuTreeNode().new Meta(); |
|
158 |
mateItem.setIcon(sysMenu.getIcon()); |
|
159 |
mateItem.setTitle(sysMenu.getName()); |
|
160 |
mateItem.setLink(sysMenu.getLink()); |
|
161 |
//是否可见 |
|
162 |
mateItem.setShow(!YesOrNotEnum.N.getCode().equals(sysMenu.getVisible())); |
|
163 |
//设置的首页,默认打开此链接 |
|
164 |
loginMenuTreeNode.setRedirect(sysMenu.getRedirect()); |
|
165 |
//是否是外链 |
|
166 |
if (MenuOpenTypeEnum.OUTER.getCode().equals(sysMenu.getOpenType())) { |
|
167 |
//打开外链 |
|
168 |
mateItem.setTarget("_blank"); |
|
169 |
loginMenuTreeNode.setPath(sysMenu.getLink()); |
|
170 |
loginMenuTreeNode.setRedirect(sysMenu.getLink()); |
|
171 |
} |
|
172 |
loginMenuTreeNode.setMeta(mateItem); |
|
173 |
antDesignMenuTreeNodeList.add(loginMenuTreeNode); |
|
174 |
}); |
|
175 |
return antDesignMenuTreeNodeList; |
|
176 |
} |
|
177 |
|
|
178 |
@Override |
|
179 |
public List<String> getUserMenuAppCodeList(Long userId, List<Long> roleIdList) { |
|
180 |
Set<String> appCodeSet = CollectionUtil.newHashSet(); |
|
181 |
|
|
182 |
if (ObjectUtil.isNotEmpty(roleIdList)) { |
|
183 |
List<Long> menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); |
|
184 |
|
|
185 |
if (ObjectUtil.isNotEmpty(menuIdList)) { |
|
186 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
187 |
queryWrapper.in(SysMenu::getId, menuIdList) |
|
188 |
.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); |
|
189 |
appCodeSet = this.list(queryWrapper).stream().map(SysMenu::getApplication).collect(Collectors.toSet()); |
|
190 |
} |
|
191 |
} |
|
192 |
|
|
193 |
return CollectionUtil.newArrayList(appCodeSet); |
|
194 |
} |
|
195 |
|
|
196 |
@Override |
|
197 |
public List<SysMenu> list(SysMenuParam sysMenuParam) { |
|
198 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
199 |
if (ObjectUtil.isNotNull(sysMenuParam)) { |
|
200 |
//根据所属应用查询 |
|
201 |
if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { |
|
202 |
queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); |
|
203 |
} |
|
204 |
//根据菜单名称模糊查询 |
|
205 |
if (ObjectUtil.isNotEmpty(sysMenuParam.getName())) { |
|
206 |
queryWrapper.like(SysMenu::getName, sysMenuParam.getName()); |
|
207 |
} |
|
208 |
} |
|
209 |
queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); |
|
210 |
//根据排序升序排列,序号越小越在前 |
|
211 |
queryWrapper.orderByAsc(SysMenu::getSort); |
|
212 |
List<SysMenu> sysMenuList = this.list(queryWrapper); |
|
213 |
//将结果集处理成树 |
|
214 |
return new TreeBuildFactory<SysMenu>().doTreeBuild(sysMenuList); |
|
215 |
} |
|
216 |
|
|
217 |
@Override |
|
218 |
public void add(SysMenuParam sysMenuParam) { |
|
219 |
// 校验参数 |
|
220 |
checkParam(sysMenuParam, false); |
|
221 |
|
|
222 |
SysMenu sysMenu = new SysMenu(); |
|
223 |
BeanUtil.copyProperties(sysMenuParam, sysMenu); |
|
224 |
|
|
225 |
// 设置新的pid |
|
226 |
String newPids = createNewPids(sysMenuParam.getPid()); |
|
227 |
sysMenu.setPids(newPids); |
|
228 |
|
|
229 |
// 设置启用状态 |
|
230 |
sysMenu.setStatus(CommonStatusEnum.ENABLE.getCode()); |
|
231 |
|
|
232 |
this.save(sysMenu); |
|
233 |
} |
|
234 |
|
|
235 |
@Transactional(rollbackFor = Exception.class) |
|
236 |
@Override |
|
237 |
public void delete(SysMenuParam sysMenuParam) { |
|
238 |
Long id = sysMenuParam.getId(); |
|
239 |
//级联删除子节点 |
|
240 |
List<Long> childIdList = this.getChildIdListById(id); |
|
241 |
childIdList.add(id); |
|
242 |
LambdaUpdateWrapper<SysMenu> updateWrapper = new LambdaUpdateWrapper<>(); |
|
243 |
updateWrapper.in(SysMenu::getId, childIdList) |
|
244 |
.set(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); |
|
245 |
this.update(updateWrapper); |
|
246 |
//级联删除该菜单及子菜单对应的角色-菜单表信息 |
|
247 |
sysRoleMenuService.deleteRoleMenuListByMenuIdList(childIdList); |
|
248 |
} |
|
249 |
|
|
250 |
@Override |
|
251 |
@Transactional(rollbackFor = Exception.class) |
|
252 |
public void edit(SysMenuParam sysMenuParam) { |
|
253 |
|
|
254 |
// 校验参数 |
|
255 |
checkParam(sysMenuParam, true); |
|
256 |
|
|
257 |
// 获取修改的菜单的旧数据(库中的) |
|
258 |
SysMenu oldMenu = this.querySysMenu(sysMenuParam); |
|
259 |
|
|
260 |
// 本菜单旧的pids |
|
261 |
Long oldPid = oldMenu.getPid(); |
|
262 |
String oldPids = oldMenu.getPids(); |
|
263 |
|
|
264 |
// 生成新的pid和pids |
|
265 |
Long newPid = sysMenuParam.getPid(); |
|
266 |
String newPids = this.createNewPids(sysMenuParam.getPid()); |
|
267 |
|
|
268 |
// 是否更新子应用的标识 |
|
269 |
boolean updateSubAppsFlag = false; |
|
270 |
|
|
271 |
// 是否更新子节点的pids的标识 |
|
272 |
boolean updateSubPidsFlag = false; |
|
273 |
|
|
274 |
// 如果应用有变化 |
|
275 |
if (!sysMenuParam.getApplication().equals(oldMenu.getApplication())) { |
|
276 |
// 父节点不是根节点不能移动应用 |
|
277 |
if (!oldPid.equals(0L)) { |
|
278 |
throw new ServiceException(SysMenuExceptionEnum.CANT_MOVE_APP); |
|
279 |
} |
|
280 |
updateSubAppsFlag = true; |
|
281 |
} |
|
282 |
|
|
283 |
// 父节点有变化 |
|
284 |
if (!newPid.equals(oldPid)) { |
|
285 |
updateSubPidsFlag = true; |
|
286 |
} |
|
287 |
|
|
288 |
// 开始更新所有子节点的配置 |
|
289 |
if (updateSubAppsFlag || updateSubPidsFlag) { |
|
290 |
|
|
291 |
// 查找所有叶子节点,包含子节点的子节点 |
|
292 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
293 |
queryWrapper.like(SysMenu::getPids, oldMenu.getId()); |
|
294 |
List<SysMenu> list = this.list(queryWrapper); |
|
295 |
|
|
296 |
// 更新所有子节点的应用为当前菜单的应用 |
|
297 |
if (ObjectUtil.isNotEmpty(list)) { |
|
298 |
|
|
299 |
// 更新所有子节点的application |
|
300 |
if (updateSubAppsFlag) { |
|
301 |
list.forEach(child -> child.setApplication(sysMenuParam.getApplication())); |
|
302 |
} |
|
303 |
// 更新所有子节点的pids |
|
304 |
if (updateSubPidsFlag) { |
|
305 |
list.forEach(child -> { |
|
306 |
// 子节点pids组成 = 当前菜单新pids + 当前菜单id + 子节点自己的pids后缀 |
|
307 |
String oldParentCodesPrefix = oldPids + SymbolConstant.LEFT_SQUARE_BRACKETS + oldMenu.getId() |
|
308 |
+ SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA; |
|
309 |
String oldParentCodesSuffix = child.getPids().substring(oldParentCodesPrefix.length()); |
|
310 |
String menuParentCodes = newPids + SymbolConstant.LEFT_SQUARE_BRACKETS + oldMenu.getId() |
|
311 |
+ SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA + oldParentCodesSuffix; |
|
312 |
child.setPids(menuParentCodes); |
|
313 |
}); |
|
314 |
} |
|
315 |
|
|
316 |
this.updateBatchById(list); |
|
317 |
} |
|
318 |
} |
|
319 |
|
|
320 |
// 拷贝参数到实体中 |
|
321 |
BeanUtil.copyProperties(sysMenuParam, oldMenu); |
|
322 |
|
|
323 |
// 设置新的pids |
|
324 |
oldMenu.setPids(newPids); |
|
325 |
//不能修改状态,用修改状态接口修改状态 |
|
326 |
oldMenu.setStatus(null); |
|
327 |
this.updateById(oldMenu); |
|
328 |
} |
|
329 |
|
|
330 |
@Override |
|
331 |
public SysMenu detail(SysMenuParam sysMenuParam) { |
|
332 |
return this.querySysMenu(sysMenuParam); |
|
333 |
} |
|
334 |
|
|
335 |
@Override |
|
336 |
public List<MenuBaseTreeNode> tree(SysMenuParam sysMenuParam) { |
|
337 |
List<MenuBaseTreeNode> menuTreeNodeList = CollectionUtil.newArrayList(); |
|
338 |
|
|
339 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
340 |
|
|
341 |
if (ObjectUtil.isNotNull(sysMenuParam)) { |
|
342 |
if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { |
|
343 |
queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); |
|
344 |
} |
|
345 |
} |
|
346 |
queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()) |
|
347 |
.in(SysMenu::getType, CollectionUtil.newArrayList(MenuTypeEnum.DIR.getCode(), MenuTypeEnum.MENU.getCode())); |
|
348 |
//根据排序升序排列,序号越小越在前 |
|
349 |
queryWrapper.orderByAsc(SysMenu::getSort); |
|
350 |
this.list(queryWrapper).forEach(sysMenu -> { |
|
351 |
MenuBaseTreeNode menuTreeNode = new MenuBaseTreeNode(); |
|
352 |
menuTreeNode.setId(sysMenu.getId()); |
|
353 |
menuTreeNode.setParentId(sysMenu.getPid()); |
|
354 |
menuTreeNode.setValue(String.valueOf(sysMenu.getId())); |
|
355 |
menuTreeNode.setTitle(sysMenu.getName()); |
|
356 |
menuTreeNode.setWeight(sysMenu.getSort()); |
|
357 |
menuTreeNodeList.add(menuTreeNode); |
|
358 |
}); |
|
359 |
return new TreeBuildFactory<MenuBaseTreeNode>().doTreeBuild(menuTreeNodeList); |
|
360 |
} |
|
361 |
|
|
362 |
@Override |
|
363 |
public List<MenuBaseTreeNode> treeForGrant(SysMenuParam sysMenuParam) { |
|
364 |
List<MenuBaseTreeNode> menuTreeNodeList = CollectionUtil.newArrayList(); |
|
365 |
|
|
366 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
367 |
//根据应用查询 |
|
368 |
if (ObjectUtil.isNotNull(sysMenuParam)) { |
|
369 |
if (ObjectUtil.isNotEmpty(sysMenuParam.getApplication())) { |
|
370 |
queryWrapper.eq(SysMenu::getApplication, sysMenuParam.getApplication()); |
|
371 |
} |
|
372 |
} |
|
373 |
//如果是超级管理员给角色授权菜单时可选择所有菜单 |
|
374 |
if (LoginContextHolder.me().isSuperAdmin()) { |
|
375 |
queryWrapper.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); |
|
376 |
} else { |
|
377 |
//非超级管理员则获取自己拥有的菜单,分配给人员,防止越级授权 |
|
378 |
Long userId = LoginContextHolder.me().getSysLoginUserId(); |
|
379 |
List<Long> roleIdList = sysUserRoleService.getUserRoleIdList(userId); |
|
380 |
if (ObjectUtil.isNotEmpty(roleIdList)) { |
|
381 |
List<Long> menuIdList = sysRoleMenuService.getRoleMenuIdList(roleIdList); |
|
382 |
if (ObjectUtil.isNotEmpty(menuIdList)) { |
|
383 |
queryWrapper.in(SysMenu::getId, menuIdList) |
|
384 |
.eq(SysMenu::getStatus, CommonStatusEnum.ENABLE.getCode()); |
|
385 |
} else { |
|
386 |
//如果角色的菜单为空,则查不到菜单 |
|
387 |
return CollectionUtil.newArrayList(); |
|
388 |
} |
|
389 |
} else { |
|
390 |
//如果角色为空,则根本没菜单 |
|
391 |
return CollectionUtil.newArrayList(); |
|
392 |
} |
|
393 |
} |
|
394 |
//根据排序升序排列,序号越小越在前 |
|
395 |
queryWrapper.orderByAsc(SysMenu::getSort); |
|
396 |
this.list(queryWrapper).forEach(sysMenu -> { |
|
397 |
MenuBaseTreeNode menuTreeNode = new MenuBaseTreeNode(); |
|
398 |
menuTreeNode.setId(sysMenu.getId()); |
|
399 |
menuTreeNode.setParentId(sysMenu.getPid()); |
|
400 |
menuTreeNode.setValue(String.valueOf(sysMenu.getId())); |
|
401 |
menuTreeNode.setTitle(sysMenu.getName()); |
|
402 |
menuTreeNode.setWeight(sysMenu.getSort()); |
|
403 |
menuTreeNodeList.add(menuTreeNode); |
|
404 |
}); |
|
405 |
return new TreeBuildFactory<MenuBaseTreeNode>().doTreeBuild(menuTreeNodeList); |
|
406 |
} |
|
407 |
|
|
408 |
@Override |
|
409 |
public boolean hasMenu(String appCode) { |
|
410 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
411 |
queryWrapper.eq(SysMenu::getApplication, appCode) |
|
412 |
.ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); |
|
413 |
return this.list(queryWrapper).size() != 0; |
|
414 |
} |
|
415 |
|
|
416 |
/** |
|
417 |
* 校验参数 |
|
418 |
* |
|
419 |
* @author xuyuxiang |
|
420 |
* @date 2020/3/27 9:15 |
|
421 |
*/ |
|
422 |
private void checkParam(SysMenuParam sysMenuParam, boolean isExcludeSelf) { |
|
423 |
//菜单类型(字典 0目录 1菜单 2按钮) |
|
424 |
Integer type = sysMenuParam.getType(); |
|
425 |
|
|
426 |
String router = sysMenuParam.getRouter(); |
|
427 |
|
|
428 |
String permission = sysMenuParam.getPermission(); |
|
429 |
|
|
430 |
Integer openType = sysMenuParam.getOpenType(); |
|
431 |
|
|
432 |
if (MenuTypeEnum.DIR.getCode().equals(type)) { |
|
433 |
if (ObjectUtil.isEmpty(router)) { |
|
434 |
throw new ServiceException(SysMenuExceptionEnum.MENU_ROUTER_EMPTY); |
|
435 |
} |
|
436 |
} |
|
437 |
|
|
438 |
if (MenuTypeEnum.MENU.getCode().equals(type)) { |
|
439 |
if (ObjectUtil.isEmpty(router)) { |
|
440 |
throw new ServiceException(SysMenuExceptionEnum.MENU_ROUTER_EMPTY); |
|
441 |
} |
|
442 |
if (ObjectUtil.isEmpty(openType)) { |
|
443 |
throw new ServiceException(SysMenuExceptionEnum.MENU_OPEN_TYPE_EMPTY); |
|
444 |
} |
|
445 |
} |
|
446 |
|
|
447 |
if (MenuTypeEnum.BTN.getCode().equals(type)) { |
|
448 |
if (ObjectUtil.isEmpty(permission)) { |
|
449 |
throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_EMPTY); |
|
450 |
} else { |
|
451 |
Set<String> urlSet = resourceCache.getAllResources(); |
|
452 |
|
|
453 |
if (!permission.contains(SymbolConstant.COLON)) { |
|
454 |
throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_ERROR); |
|
455 |
} |
|
456 |
permission = SymbolConstant.COLON + permission; |
|
457 |
if (!urlSet.contains(permission.replaceAll(SymbolConstant.COLON, SymbolConstant.LEFT_DIVIDE))) { |
|
458 |
throw new ServiceException(SysMenuExceptionEnum.MENU_PERMISSION_NOT_EXIST); |
|
459 |
} |
|
460 |
} |
|
461 |
} |
|
462 |
|
|
463 |
// 如果是编辑菜单时候,pid和id不能一致,一致会导致无限递归 |
|
464 |
if (isExcludeSelf) { |
|
465 |
if (sysMenuParam.getId().equals(sysMenuParam.getPid())) { |
|
466 |
throw new ServiceException(SysMenuExceptionEnum.PID_CANT_EQ_ID); |
|
467 |
} |
|
468 |
|
|
469 |
// 如果是编辑,父id不能为自己的子节点 |
|
470 |
List<Long> childIdListById = this.getChildIdListById(sysMenuParam.getId()); |
|
471 |
if(ObjectUtil.isNotEmpty(childIdListById)) { |
|
472 |
if(childIdListById.contains(sysMenuParam.getPid())) { |
|
473 |
throw new ServiceException(SysMenuExceptionEnum.PID_CANT_EQ_CHILD_ID); |
|
474 |
} |
|
475 |
} |
|
476 |
} |
|
477 |
|
|
478 |
Long id = sysMenuParam.getId(); |
|
479 |
String name = sysMenuParam.getName(); |
|
480 |
String code = sysMenuParam.getCode(); |
|
481 |
|
|
482 |
LambdaQueryWrapper<SysMenu> queryWrapperByName = new LambdaQueryWrapper<>(); |
|
483 |
queryWrapperByName.eq(SysMenu::getName, name) |
|
484 |
.ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); |
|
485 |
|
|
486 |
LambdaQueryWrapper<SysMenu> queryWrapperByCode = new LambdaQueryWrapper<>(); |
|
487 |
queryWrapperByCode.eq(SysMenu::getCode, code) |
|
488 |
.ne(SysMenu::getStatus, CommonStatusEnum.DELETED.getCode()); |
|
489 |
|
|
490 |
if (isExcludeSelf) { |
|
491 |
queryWrapperByName.ne(SysMenu::getId, id); |
|
492 |
queryWrapperByCode.ne(SysMenu::getId, id); |
|
493 |
} |
|
494 |
int countByName = this.count(queryWrapperByName); |
|
495 |
int countByCode = this.count(queryWrapperByCode); |
|
496 |
|
|
497 |
if (countByName >= 1) { |
|
498 |
throw new ServiceException(SysMenuExceptionEnum.MENU_NAME_REPEAT); |
|
499 |
} |
|
500 |
if (countByCode >= 1) { |
|
501 |
throw new ServiceException(SysMenuExceptionEnum.MENU_CODE_REPEAT); |
|
502 |
} |
|
503 |
} |
|
504 |
|
|
505 |
/** |
|
506 |
* 获取系统菜单 |
|
507 |
* |
|
508 |
* @author xuyuxiang |
|
509 |
* @date 2020/3/27 9:13 |
|
510 |
*/ |
|
511 |
private SysMenu querySysMenu(SysMenuParam sysMenuParam) { |
|
512 |
SysMenu sysMenu = this.getById(sysMenuParam.getId()); |
|
513 |
if (ObjectUtil.isNull(sysMenu)) { |
|
514 |
throw new ServiceException(SysMenuExceptionEnum.MENU_NOT_EXIST); |
|
515 |
} |
|
516 |
return sysMenu; |
|
517 |
} |
|
518 |
|
|
519 |
/** |
|
520 |
* 创建pids的值 |
|
521 |
* <p> |
|
522 |
* 如果pid是0顶级节点,pids就是 [0], |
|
523 |
* <p> |
|
524 |
* 如果pid不是顶级节点,pids就是 pid菜单的pids + [pid] + , |
|
525 |
* |
|
526 |
* @author xuyuxiang |
|
527 |
* @date 2020/3/26 11:28 |
|
528 |
*/ |
|
529 |
private String createNewPids(Long pid) { |
|
530 |
if (pid.equals(0L)) { |
|
531 |
return SymbolConstant.LEFT_SQUARE_BRACKETS + 0 + SymbolConstant.RIGHT_SQUARE_BRACKETS |
|
532 |
+ SymbolConstant.COMMA; |
|
533 |
} else { |
|
534 |
//获取父菜单 |
|
535 |
SysMenu parentMenu = this.getById(pid); |
|
536 |
return parentMenu.getPids() |
|
537 |
+ SymbolConstant.LEFT_SQUARE_BRACKETS + pid + SymbolConstant.RIGHT_SQUARE_BRACKETS |
|
538 |
+ SymbolConstant.COMMA; |
|
539 |
} |
|
540 |
} |
|
541 |
|
|
542 |
/** |
|
543 |
* 根据节点id获取所有子节点id集合 |
|
544 |
* |
|
545 |
* @author xuyuxiang |
|
546 |
* @date 2020/3/26 11:31 |
|
547 |
*/ |
|
548 |
private List<Long> getChildIdListById(Long id) { |
|
549 |
List<Long> childIdList = CollectionUtil.newArrayList(); |
|
550 |
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>(); |
|
551 |
queryWrapper.like(SysMenu::getPids, SymbolConstant.LEFT_SQUARE_BRACKETS + id + |
|
552 |
SymbolConstant.RIGHT_SQUARE_BRACKETS); |
|
553 |
this.list(queryWrapper).forEach(sysMenu -> childIdList.add(sysMenu.getId())); |
|
554 |
return childIdList; |
|
555 |
} |
|
556 |
} |