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