懒羊羊
2023-08-30 1ac2bc1590406d9babec036e154d8d08f34a6aa1
提交 | 用户 | 时间
1ac2bc 1 package cn.stylefeng.guns.sys.modular.rest.service;
2
3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.util.StrUtil;
5 import cn.stylefeng.guns.base.pojo.node.MenuNode;
6 import cn.stylefeng.guns.base.pojo.node.ZTreeNode;
7 import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
8 import cn.stylefeng.guns.sys.core.constant.factory.ConstantFactory;
9 import cn.stylefeng.guns.sys.core.constant.state.MenuStatus;
10 import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
11 import cn.stylefeng.guns.sys.core.listener.ConfigListener;
12 import cn.stylefeng.guns.sys.modular.rest.entity.RestMenu;
13 import cn.stylefeng.guns.sys.modular.rest.mapper.RestMenuMapper;
14 import cn.stylefeng.guns.sys.modular.system.model.MenuDto;
15 import cn.stylefeng.roses.core.util.ToolUtil;
16 import cn.stylefeng.roses.kernel.model.exception.RequestEmptyException;
17 import cn.stylefeng.roses.kernel.model.exception.ServiceException;
18 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
19 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
20 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
21 import org.springframework.stereotype.Service;
22 import org.springframework.transaction.annotation.Transactional;
23
24 import javax.annotation.Resource;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Map;
28
29 /**
30  * <p>
31  * 菜单表 服务实现类
32  * </p>
33  *
34  * @author stylefeng
35  * @since 2018-12-07
36  */
37 @Service
38 public class RestMenuService extends ServiceImpl<RestMenuMapper, RestMenu> {
39
40     @Resource
41     private RestMenuMapper restMenuMapper;
42
43     /**
44      * 添加菜单
45      *
46      * @author fengshuonan
47      * @Date 2018/12/23 5:59 PM
48      */
49     @Transactional
50     public void addMenu(MenuDto menuDto) {
51
52         if (ToolUtil.isOneEmpty(menuDto, menuDto.getCode(), menuDto.getName(), menuDto.getPid(), menuDto.getMenuFlag(), menuDto.getUrl(), menuDto.getSystemType())) {
53             throw new RequestEmptyException();
54         }
55
56         //判断是否已经存在该编号
57         String existedMenuName = ConstantFactory.me().getMenuNameByCode(menuDto.getCode());
58         if (ToolUtil.isNotEmpty(existedMenuName)) {
59             throw new ServiceException(BizExceptionEnum.EXISTED_THE_MENU);
60         }
61
62         //组装属性,设置父级菜单编号
63         RestMenu resultMenu = this.menuSetPcode(menuDto);
64
65         resultMenu.setStatus(MenuStatus.ENABLE.getCode());
66
67         this.save(resultMenu);
68     }
69
70     /**
71      * 更新菜单
72      *
73      * @author fengshuonan
74      * @Date 2019/2/27 4:09 PM
75      */
76     @Transactional(rollbackFor = Exception.class)
77     public void updateMenu(MenuDto menuDto) {
78
79         //如果菜单为空
80         if (menuDto == null || ToolUtil.isOneEmpty(menuDto.getMenuId(), menuDto.getCode())) {
81             throw new RequestEmptyException();
82         }
83
84         //获取旧的菜单
85         Long id = menuDto.getMenuId();
86         RestMenu menu = this.getById(id);
87
88         if (menu == null) {
89             throw new RequestEmptyException();
90         }
91
92         //设置父级菜单编号
93         RestMenu resultMenu = this.menuSetPcode(menuDto);
94
95         //查找该节点的子集合,并修改相应的pcodes和level(因为修改菜单后,层级可能变化了)
96         updateSubMenuLevels(menu, resultMenu);
97
98         this.updateById(resultMenu);
99     }
100
101     /**
102      * 更新所有子菜单的结构
103      *
104      * @param oldMenu 原来的菜单
105      * @param newMenu 新菜单
106      * @author fengshuonan
107      * @Date 2019/2/27 4:25 PM
108      */
109     @Transactional(rollbackFor = Exception.class)
110     public void updateSubMenuLevels(RestMenu oldMenu, RestMenu newMenu) {
111
112         List<RestMenu> menus = restMenuMapper.getMenusLikePcodes(oldMenu.getCode());
113
114         for (RestMenu menu : menus) {
115
116             //更新pcode
117             if (oldMenu.getCode().equals(menu.getPcode())) {
118                 menu.setPcode(newMenu.getCode());
119             }
120
121             //更新pcodes
122             String oldPcodesPrefix = oldMenu.getPcodes() + "[" + oldMenu.getCode() + "],";
123             String oldPcodesSuffix = menu.getPcodes().substring(oldPcodesPrefix.length());
124             String menuPcodes = newMenu.getPcodes() + "[" + newMenu.getCode() + "]," + oldPcodesSuffix;
125             menu.setPcodes(menuPcodes);
126
127             //更新levels
128             int level = StrUtil.count(menuPcodes, "[");
129             menu.setLevels(level);
130
131             //更新systemType
132             menu.setSystemType(newMenu.getSystemType());
133
134             this.updateById(menu);
135         }
136
137     }
138
139     /**
140      * 删除菜单
141      *
142      * @author stylefeng
143      * @Date 2017/5/5 22:20
144      */
145     @Transactional
146     public void delMenu(Long menuId) {
147
148         //删除菜单
149         this.restMenuMapper.deleteById(menuId);
150
151         //删除关联的relation
152         this.restMenuMapper.deleteRelationByMenu(menuId);
153     }
154
155     /**
156      * 删除菜单包含所有子菜单
157      *
158      * @author stylefeng
159      * @Date 2017/6/13 22:02
160      */
161     @Transactional
162     public void delMenuContainSubMenus(Long menuId) {
163
164         RestMenu menu = restMenuMapper.selectById(menuId);
165
166         //删除当前菜单
167         delMenu(menuId);
168
169         //删除所有子菜单
170         List<RestMenu> menus = restMenuMapper.getMenusLikePcodes(menu.getCode());
171
172         for (RestMenu temp : menus) {
173             delMenu(temp.getMenuId());
174         }
175     }
176
177     /**
178      * 根据条件查询菜单
179      *
180      * @return
181      * @date 2017年2月12日 下午9:14:34
182      */
183     public Page<Map<String, Object>> selectMenus(String condition, String level, Long menuId) {
184
185         //获取menuId的code
186         String code = "";
187         if (menuId != null && menuId != 0L) {
188             RestMenu menu = this.getById(menuId);
189             code = menu.getCode();
190         }
191
192         Page page = LayuiPageFactory.defaultPage();
193
194         return this.baseMapper.selectMenus(page, condition, level, menuId, code);
195     }
196
197     /**
198      * 根据条件查询菜单
199      *
200      * @return
201      * @date 2017年2月12日 下午9:14:34
202      */
203     public List<Long> getMenuIdsByRoleId(Long roleId) {
204         return this.baseMapper.getMenuIdsByRoleId(roleId);
205     }
206
207     /**
208      * 获取菜单列表树
209      *
210      * @return
211      * @date 2017年2月19日 下午1:33:51
212      */
213     public List<ZTreeNode> menuTreeList() {
214         return this.baseMapper.menuTreeList();
215     }
216
217     /**
218      * 获取菜单列表树
219      *
220      * @return
221      * @date 2017年2月19日 下午1:33:51
222      */
223     public List<ZTreeNode> menuTreeListByMenuIds(List<Long> menuIds) {
224         return this.baseMapper.menuTreeListByMenuIds(menuIds);
225     }
226
227     /**
228      * 删除menu关联的relation
229      *
230      * @param menuId
231      * @return
232      * @date 2017年2月19日 下午4:10:59
233      */
234     public int deleteRelationByMenu(Long menuId) {
235         return this.baseMapper.deleteRelationByMenu(menuId);
236     }
237
238     /**
239      * 获取资源url通过角色id
240      *
241      * @param roleId
242      * @return
243      * @date 2017年2月19日 下午7:12:38
244      */
245     public List<String> getResUrlsByRoleId(Long roleId) {
246         return this.baseMapper.getResUrlsByRoleId(roleId);
247     }
248
249     /**
250      * 根据角色获取菜单
251      *
252      * @param roleIds
253      * @return
254      * @date 2017年2月19日 下午10:35:40
255      */
256     public List<MenuNode> getMenusByRoleIds(List<Long> roleIds) {
257         List<MenuNode> menus = this.baseMapper.getMenusByRoleIds(roleIds);
258
259         //给所有的菜单url加上ctxPath
260         for (MenuNode menuItem : menus) {
261             menuItem.setUrl(ConfigListener.getConf().get("contextPath") + menuItem.getUrl());
262         }
263
264         return menus;
265     }
266
267     /**
268      * 根据code查询菜单
269      *
270      * @author fengshuonan
271      * @Date 2018/12/20 21:54
272      */
273     public RestMenu selectByCode(String code) {
274         RestMenu menu = new RestMenu();
275         menu.setCode(code);
276         QueryWrapper<RestMenu> queryWrapper = new QueryWrapper<>(menu);
277         return this.baseMapper.selectOne(queryWrapper);
278     }
279
280     /**
281      * 根据请求的父级菜单编号设置pcode和层级
282      *
283      * @author fengshuonan
284      * @Date 2018/12/23 5:54 PM
285      */
286     public RestMenu menuSetPcode(MenuDto menuParam) {
287
288         RestMenu resultMenu = new RestMenu();
289         BeanUtil.copyProperties(menuParam, resultMenu);
290
291         if (ToolUtil.isEmpty(menuParam.getPid()) || menuParam.getPid().equals(0L)) {
292             resultMenu.setPcode("0");
293             resultMenu.setPcodes("[0],");
294             resultMenu.setLevels(1);
295         } else {
296             Long pid = menuParam.getPid();
297             RestMenu pMenu = this.getById(pid);
298             Integer pLevels = pMenu.getLevels();
299             resultMenu.setPcode(pMenu.getCode());
300
301             //如果编号和父编号一致会导致无限递归
302             if (menuParam.getCode().equals(menuParam.getPcode())) {
303                 throw new ServiceException(BizExceptionEnum.MENU_PCODE_COINCIDENCE);
304             }
305
306             resultMenu.setLevels(pLevels + 1);
307             resultMenu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
308         }
309
310         return resultMenu;
311     }
312
313     /**
314      * 获取菜单树形列表
315      *
316      * @author fengshuonan
317      * @Date 2019/2/23 22:02
318      */
319     public List<Map<String, Object>> selectMenuTree(String condition, String level) {
320         List<Map<String, Object>> maps = this.baseMapper.selectMenuTree(condition, level);
321
322         if (maps == null) {
323             maps = new ArrayList<>();
324         }
325
326         //修复菜单查询bug,带条件的暂时先父级置为0
327         if (ToolUtil.isNotEmpty(condition) || ToolUtil.isNotEmpty(level)) {
328             if (maps.size() > 0) {
329
330                 //将pcode置为root
331                 for (Map<String, Object> menu : maps) {
332                     menu.put("pcode", "0");
333                 }
334             }
335         }
336
337         //创建根节点
338         RestMenu menu = new RestMenu();
339         menu.setMenuId(-1L);
340         menu.setName("根节点");
341         menu.setCode("0");
342         menu.setPcode("-2");
343         maps.add(BeanUtil.beanToMap(menu));
344
345         return maps;
346     }
347
348 }