inleft
2022-02-09 9bcb19959eeb9da9bde2561e7278f6d0a55eb151
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.role.service.impl;
26
27 import cn.hutool.core.bean.BeanUtil;
28 import cn.hutool.core.collection.CollectionUtil;
29 import cn.hutool.core.lang.Dict;
30 import cn.hutool.core.util.ObjectUtil;
31 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
32 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
33 import org.springframework.stereotype.Service;
34 import org.springframework.transaction.annotation.Transactional;
35 import vip.xiaonuo.core.consts.CommonConstant;
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.exception.PermissionException;
40 import vip.xiaonuo.core.exception.ServiceException;
41 import vip.xiaonuo.core.exception.enums.PermissionExceptionEnum;
42 import vip.xiaonuo.core.factory.PageFactory;
43 import vip.xiaonuo.core.pojo.page.PageResult;
44 import vip.xiaonuo.sys.core.enums.DataScopeTypeEnum;
45 import vip.xiaonuo.sys.modular.org.service.SysOrgService;
46 import vip.xiaonuo.sys.modular.role.entity.SysRole;
47 import vip.xiaonuo.sys.modular.role.enums.SysRoleExceptionEnum;
48 import vip.xiaonuo.sys.modular.role.mapper.SysRoleMapper;
49 import vip.xiaonuo.sys.modular.role.param.SysRoleParam;
50 import vip.xiaonuo.sys.modular.role.service.SysRoleDataScopeService;
51 import vip.xiaonuo.sys.modular.role.service.SysRoleMenuService;
52 import vip.xiaonuo.sys.modular.role.service.SysRoleService;
53 import vip.xiaonuo.sys.modular.user.service.SysUserRoleService;
54
55 import javax.annotation.Resource;
56 import java.util.List;
57 import java.util.Set;
58 import java.util.stream.Collectors;
59
60 /**
61  * 系统角色service接口实现类
62  *
63  * @author xuyuxiang
64  * @date 2020/3/13 15:55
65  */
66 @Service
67 public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
68
69     @Resource
70     private SysUserRoleService sysUserRoleService;
71
72     @Resource
73     private SysRoleMenuService sysRoleMenuService;
74
75     @Resource
76     private SysRoleDataScopeService sysRoleDataScopeService;
77
78     @Resource
79     private SysOrgService sysOrgService;
80
81     @Override
82     public List<Dict> getLoginRoles(Long userId) {
83         List<Dict> dictList = CollectionUtil.newArrayList();
84         //获取用户角色id集合
85         List<Long> roleIdList = sysUserRoleService.getUserRoleIdList(userId);
86         if (ObjectUtil.isNotEmpty(roleIdList)) {
87             LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
88             queryWrapper.in(SysRole::getId, roleIdList).eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode());
89             //根据角色id集合查询并返回结果
90             dictList = this.list(queryWrapper).stream().map(sysRole -> {
91                 Dict dict = Dict.create();
92                 dict.put(CommonConstant.ID, sysRole.getId());
93                 dict.put(CommonConstant.CODE, sysRole.getCode());
94                 dict.put(CommonConstant.NAME, sysRole.getName());
95                 return dict;
96             }).collect(Collectors.toList());
97         }
98         return dictList;
99     }
100
101     @Override
102     public PageResult<SysRole> page(SysRoleParam sysRoleParam) {
103         LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
104         if (ObjectUtil.isNotNull(sysRoleParam)) {
105             //根据名称模糊查询
106             if (ObjectUtil.isNotEmpty(sysRoleParam.getName())) {
107                 queryWrapper.like(SysRole::getName, sysRoleParam.getName());
108             }
109             //根据编码模糊查询
110             if (ObjectUtil.isNotEmpty(sysRoleParam.getCode())) {
111                 queryWrapper.like(SysRole::getCode, sysRoleParam.getCode());
112             }
113         }
114
115         queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode());
116         //根据排序升序排列,序号越小越在前
117         queryWrapper.orderByAsc(SysRole::getSort);
118         return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
119     }
120
121     @Override
122     public List<Dict> list(SysRoleParam sysRoleParam) {
123         List<Dict> dictList = CollectionUtil.newArrayList();
124         LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
125         if (ObjectUtil.isNotNull(sysRoleParam)) {
126             //根据角色名称或编码模糊查询
127             if (ObjectUtil.isNotEmpty(sysRoleParam.getName())) {
128                 queryWrapper.and(i -> i.like(SysRole::getName, sysRoleParam.getName())
129                         .or().like(SysRole::getCode, sysRoleParam.getName()));
130             }
131         }
132         //只查询正常状态
133         queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode());
134         //根据排序升序排列,序号越小越在前
135         queryWrapper.orderByAsc(SysRole::getSort);
136         this.list(queryWrapper).forEach(sysRole -> {
137             Dict dict = Dict.create();
138             dict.put(CommonConstant.ID, sysRole.getId());
139             dict.put(CommonConstant.NAME, sysRole.getName() + SymbolConstant.LEFT_SQUARE_BRACKETS
140                     + sysRole.getCode() + SymbolConstant.RIGHT_SQUARE_BRACKETS);
141             dictList.add(dict);
142         });
143         return dictList;
144     }
145
146     @Override
147     public List<Dict> dropDown() {
148         List<Dict> dictList = CollectionUtil.newArrayList();
149         LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
150         //如果当前登录用户不是超级管理员,则查询自己拥有的
151         if (!LoginContextHolder.me().isSuperAdmin()) {
152
153             //查询自己拥有的
154             List<String> loginUserRoleIds = LoginContextHolder.me().getLoginUserRoleIds();
155             if (ObjectUtil.isEmpty(loginUserRoleIds)) {
156                 return dictList;
157             }
158             queryWrapper.in(SysRole::getId, loginUserRoleIds);
159         }
160         //只查询正常状态
161         queryWrapper.eq(SysRole::getStatus, CommonStatusEnum.ENABLE.getCode());
162         this.list(queryWrapper)
163                 .forEach(sysRole -> {
164                     Dict dict = Dict.create();
165                     dict.put(CommonConstant.ID, sysRole.getId());
166                     dict.put(CommonConstant.CODE, sysRole.getCode());
167                     dict.put(CommonConstant.NAME, sysRole.getName());
168                     dictList.add(dict);
169                 });
170         return dictList;
171     }
172
173     @Override
174     public void add(SysRoleParam sysRoleParam) {
175         //校验参数,检查是否存在相同的名称和编码
176         checkParam(sysRoleParam, false);
177         SysRole sysRole = new SysRole();
178         BeanUtil.copyProperties(sysRoleParam, sysRole);
179         sysRole.setStatus(CommonStatusEnum.ENABLE.getCode());
180         this.save(sysRole);
181     }
182
183     @Transactional(rollbackFor = Exception.class)
184     @Override
185     public void delete(SysRoleParam sysRoleParam) {
186         SysRole sysRole = this.querySysRole(sysRoleParam);
187         sysRole.setStatus(CommonStatusEnum.DELETED.getCode());
188         this.updateById(sysRole);
189         Long id = sysRole.getId();
190         //级联删除该角色对应的角色-数据范围关联信息
191         sysRoleDataScopeService.deleteRoleDataScopeListByRoleId(id);
192
193         //级联删除该角色对应的用户-角色表关联信息
194         sysUserRoleService.deleteUserRoleListByRoleId(id);
195
196         //级联删除该角色对应的角色-菜单表关联信息
197         sysRoleMenuService.deleteRoleMenuListByRoleId(id);
198     }
199
200     @Override
201     public void edit(SysRoleParam sysRoleParam) {
202         SysRole sysRole = this.querySysRole(sysRoleParam);
203         //校验参数,检查是否存在相同的名称和编码
204         checkParam(sysRoleParam, true);
205         BeanUtil.copyProperties(sysRoleParam, sysRole);
206         //不能修改状态,用修改状态接口修改状态
207         sysRole.setStatus(null);
208         this.updateById(sysRole);
209     }
210
211     @Override
212     public SysRole detail(SysRoleParam sysRoleParam) {
213         return this.querySysRole(sysRoleParam);
214     }
215
216     @Transactional(rollbackFor = Exception.class)
217     @Override
218     public void grantMenu(SysRoleParam sysRoleParam) {
219         this.querySysRole(sysRoleParam);
220         sysRoleMenuService.grantMenu(sysRoleParam);
221     }
222
223     @Transactional(rollbackFor = Exception.class)
224     @Override
225     public void grantData(SysRoleParam sysRoleParam) {
226         SysRole sysRole = this.querySysRole(sysRoleParam);
227         boolean superAdmin = LoginContextHolder.me().isSuperAdmin();
228         //如果登录用户不是超级管理员,则进行数据权限校验
229         if (!superAdmin) {
230             Integer dataScopeType = sysRoleParam.getDataScopeType();
231             //如果授权的角色的数据范围类型为全部,则没权限,只有超级管理员有
232             if (DataScopeTypeEnum.ALL.getCode().equals(dataScopeType)) {
233                 throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
234             }
235             //如果授权的角色数据范围类型为自定义,则要判断授权的数据范围是否在自己的数据范围内
236             if (DataScopeTypeEnum.DEFINE.getCode().equals(dataScopeType)) {
237                 List<Long> dataScope = sysRoleParam.getDataScope();
238                 //要授权的数据范围列表
239                 List<Long> grantOrgIdList = sysRoleParam.getGrantOrgIdList();
240                 if (ObjectUtil.isNotEmpty(grantOrgIdList)) {
241                     //数据范围为空
242                     if (ObjectUtil.isEmpty(dataScope)) {
243                         throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
244                     } else if (!dataScope.containsAll(grantOrgIdList)) {
245                         //所要授权的数据不在自己的数据范围内
246                         throw new PermissionException(PermissionExceptionEnum.NO_PERMISSION_OPERATE);
247                     }
248                 }
249             }
250         }
251         sysRole.setDataScopeType(sysRoleParam.getDataScopeType());
252         this.updateById(sysRole);
253         sysRoleDataScopeService.grantDataScope(sysRoleParam);
254     }
255
256     @Override
257     public List<Long> getUserDataScopeIdList(List<Long> roleIdList, Long orgId) {
258         Set<Long> resultList = CollectionUtil.newHashSet();
259
260         //定义角色中最大数据范围的类型,目前系统按最大范围策略来,如果你同时拥有ALL和SELF的权限,系统最后按ALL返回
261         Integer strongerDataScopeType = DataScopeTypeEnum.SELF.getCode();
262
263         //获取用户自定义数据范围的角色集合
264         List<Long> customDataScopeRoleIdList = CollectionUtil.newArrayList();
265         if (ObjectUtil.isNotEmpty(roleIdList)) {
266             List<SysRole> sysRoleList = this.listByIds(roleIdList);
267             for (SysRole sysRole : sysRoleList) {
268                 if (DataScopeTypeEnum.DEFINE.getCode().equals(sysRole.getDataScopeType())) {
269                     customDataScopeRoleIdList.add(sysRole.getId());
270                 } else {
271                     if (sysRole.getDataScopeType() <= strongerDataScopeType) {
272                         strongerDataScopeType = sysRole.getDataScopeType();
273                     }
274                 }
275             }
276         }
277
278         //自定义数据范围的角色对应的数据范围
279         List<Long> roleDataScopeIdList = sysRoleDataScopeService.getRoleDataScopeIdList(customDataScopeRoleIdList);
280
281         //角色中拥有最大数据范围类型的数据范围
282         List<Long> dataScopeIdList = sysOrgService.getDataScopeListByDataScopeType(strongerDataScopeType, orgId);
283
284         resultList.addAll(dataScopeIdList);
285         resultList.addAll(roleDataScopeIdList);
286         return CollectionUtil.newArrayList(resultList);
287     }
288
289     @Override
290     public String getNameByRoleId(Long roleId) {
291         SysRole sysRole = this.getById(roleId);
292         if (ObjectUtil.isEmpty(sysRole)) {
293             throw new ServiceException(SysRoleExceptionEnum.ROLE_NOT_EXIST);
294         }
295         return sysRole.getName();
296     }
297
298     @Override
299     public List<Long> ownMenu(SysRoleParam sysRoleParam) {
300         SysRole sysRole = this.querySysRole(sysRoleParam);
301         return sysRoleMenuService.getRoleMenuIdList(CollectionUtil.newArrayList(sysRole.getId()));
302     }
303
304     @Override
305     public List<Long> ownData(SysRoleParam sysRoleParam) {
306         SysRole sysRole = this.querySysRole(sysRoleParam);
307         return sysRoleDataScopeService.getRoleDataScopeIdList(CollectionUtil.newArrayList(sysRole.getId()));
308     }
309
310     /**
311      * 校验参数,检查是否存在相同的名称和编码
312      *
313      * @author xuyuxiang
314      * @date 2020/3/28 14:59
315      */
316     private void checkParam(SysRoleParam sysRoleParam, boolean isExcludeSelf) {
317         Long id = sysRoleParam.getId();
318         String name = sysRoleParam.getName();
319         String code = sysRoleParam.getCode();
320
321         LambdaQueryWrapper<SysRole> queryWrapperByName = new LambdaQueryWrapper<>();
322         queryWrapperByName.eq(SysRole::getName, name)
323                 .ne(SysRole::getStatus, CommonStatusEnum.DELETED.getCode());
324
325         LambdaQueryWrapper<SysRole> queryWrapperByCode = new LambdaQueryWrapper<>();
326         queryWrapperByCode.eq(SysRole::getCode, code)
327                 .ne(SysRole::getStatus, CommonStatusEnum.DELETED.getCode());
328
329         //是否排除自己,如果排除自己则不查询自己的id
330         if (isExcludeSelf) {
331             queryWrapperByName.ne(SysRole::getId, id);
332             queryWrapperByCode.ne(SysRole::getId, id);
333         }
334         int countByName = this.count(queryWrapperByName);
335         int countByCode = this.count(queryWrapperByCode);
336
337         if (countByName >= 1) {
338             throw new ServiceException(SysRoleExceptionEnum.ROLE_NAME_REPEAT);
339         }
340         if (countByCode >= 1) {
341             throw new ServiceException(SysRoleExceptionEnum.ROLE_CODE_REPEAT);
342         }
343     }
344
345     /**
346      * 获取系统角色
347      *
348      * @author xuyuxiang
349      * @date 2020/3/28 14:59
350      */
351     private SysRole querySysRole(SysRoleParam sysRoleParam) {
352         SysRole sysRole = this.getById(sysRoleParam.getId());
353         if (ObjectUtil.isNull(sysRole)) {
354             throw new ServiceException(SysRoleExceptionEnum.ROLE_NOT_EXIST);
355         }
356         return sysRole;
357     }
358 }