spring boot mybatis 数据范围配合权限使用
来源:锐游网
1.声明有所有数据范围
@Getter
public enum DataRangeEnum {
platform("","","platformRangImpl"),
instalment("","","instalmentRangImpl"),
intermediary("","","intermediaryRangeImpl"),
finance("","","financeRangeImpl"),
region("","","regionRangeImpl"),
province("","","provinceRangeImpl"),
city("","","cityRangeImpl"),
fkPersonal("","","fkPersonalRangeImpl"),
dhPersonal("","","dhPersonalRangeImpl"),
countermanPersonal("","","countermanPersonalRangeImpl");
private String title;
private String desc;
private String impl;
DataRangeEnum( String title,String desc, String impl) {
this.title = title;
this.desc = desc;
this.impl = impl;
}
/**
* 获取数据权限枚举
*/
public static DataRangeEnum getDataRangeEnum(String name){
if (StringUtils.isBlank(name)){
return null;
}
DataRangeEnum[] enums = DataRangeEnum.values();
for (DataRangeEnum rangeEnum : enums){
if (StringUtils.equals(rangeEnum.name(),name)){
return rangeEnum;
}
}
return null;
}
2 获取用户当前的数据范围
public Map<String, String> getRangeValue() {
Map<String, String> map = new HashMap<>();
//判断用户是否存在
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes == null){
log.error("--getRangeValue--未找到RequestAttributes 类的值");
throw new BizException("获取当前登录用户信息失败",RangeConstant.dataRangError);
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String token = request.getHeader(CommonConstant.BEAUTY_SESSIONID);
if (StringUtils.isBlank(token)){
log.error("--getRangeValue--未找到后台用户token");
throw new BizException("获取当前登录用户信息失败",RangeConstant.dataRangError);
}
LoginAccountInfoDTO userInfo = (LoginAccountInfoDTO) redisUtil.get(RedisConstant.USER_ACCOUNT_PREFIX + token);
if (ObjectUtils.isEmpty(userInfo)){
log.error("--getRangeValue--未找到后台用户信息");
throw new BizException("获取当前登录用户信息失败",RangeConstant.dataRangError);
}
//全部权限放开
if (userInfo.getUserBaseInfo().getUserOrgTag().intValue() == 1){
return map;
}
//当前身份
String identity = request.getHeader(CommonConstant.CURRENT_USER_ID);
List<LoginUserInfoDTO> userInfoList = userInfo.getUserInfoList();
if (CollectionUtils.isEmpty(userInfoList)){
log.error("--getRangeValue--当前登录用户:{}未有身份信息",userInfo.getUserBaseInfo().getRealName());
throw new BizException("当前登录用户未有身份信息",RangeConstant.dataRangError);
}
Optional<LoginUserInfoDTO> optional = userInfoList.stream().filter(item -> item.getId().equals(identity)).findFirst();// 匹配现有登录用户
if (!optional.isPresent()){
log.error("--getRangeValue--未找到用户:{}当前身份信息",userInfo.getUserBaseInfo().getRealName());
throw new BizException("未找到用户当前身份信息",RangeConstant.dataRangError);
}
LoginUserInfoDTO currentUser = optional.get();
SsoOrg ssoOrg = currentUser.getSsoOrg();
if (ObjectUtils.isEmpty(ssoOrg)){
log.error("--getRangeValue--未找到用户:{}当前身份所属机构",userInfo.getUserBaseInfo().getRealName());
throw new BizException("用户当前身份所属机构",RangeConstant.dataRangError);
}
String topOrgId = currentUser.getParentOrgId(); // 顶级机构id
Integer topOrgType = currentUser.getOrgType(); //顶级机构类型
List<SsoDataRangeDTO> dataRanges = currentUser.getDataRangeList();
if (CollectionUtils.isEmpty(dataRanges)){
log.error("--getRangeValue--未找到用户:{}当前身份的数据权限",userInfo.getUserBaseInfo().getRealName());
throw new BizException("用户当前身份没有数据权限",RangeConstant.dataRangError);
}
SsoDataRangeDTO ssoDataRangeDTO = dataRanges.get(0);
//数据范围
DataRangeEnum rangeEnum = DataRangeEnum.getDataRangeEnum(ssoDataRangeDTO.getId());
if (rangeEnum == null){
log.error("--getRangeValue--用户:{}暂未开发数据权限:{}",userInfo.getUserBaseInfo().getRealName(),99);
throw new BizException("系统暂未开发该身份的数据权限",RangeConstant.dataRangError);
}
IRangeValue rangeValue = (IRangeValue)context.getBean(rangeEnum.getImpl());
return rangeValue.getUserRange(userInfo.getUserBaseInfo().getId(),topOrgId,topOrgType,ssoOrg);
这里是获取当前后台当前用户信息,最终获取数据权限
3.声明实现方法
public interface IRangeValue {
/**
* 获取当前用户数据值
* @param userId 当前登录用户id
* @param topOrgId 顶级机构id
* @param topOrgType 顶级机构类型
* @param ssoOrg 当前机构
* @return 对应的参数
*/
Map<String, String> getUserRange(String userId,String topOrgId,Integer topOrgType, SsoOrg ssoOrg);
}
具体的实现代码和接口入参自己定义
4.应用场景
在用户查看列表的时候,写入切面进行处理
@Slf4j
@Aspect
@Configuration
public class DalAspect {
@Resource
private RedisUtil redisUtil;
@Resource
private IDataRange dataRange;
/** Aop切点新增的表达式,*SelectAop* 这个单词各个模块自定义 */
private static final String AOP_POINTCUT_EXPRESSION_SELECT_PAGE = "execution(* com.beauty..*.*mapper..*.*SelectAop*(..)))";
@Pointcut(AOP_POINTCUT_EXPRESSION_SELECT_PAGE)
public void selectPageMethods(){
}
@Before("selectPageMethods()")
public void beforeSelectPage(JoinPoint jp){
log.info("---进入查询拦截---");
Object[] args = jp.getArgs();
if (args == null || args.length <= 0) {
return;
}
for (Object argument : args) {
if (argument.getClass() != null && StringUtils.equals(argument.getClass().getName(), "com.baomidou.mybatisplus.plugins.Page")) {
continue;
}
BeanWrapper beanWrapper = new BeanWrapperImpl(argument);
if (beanWrapper.isWritableProperty(RangeConstant.dataRageParams)) {
Map<String,String> map = dataRange.getRangeValue();
beanWrapper.setPropertyValue(RangeConstant.dataRageParams, map);
}
}
log.info("---查询拦截成功---");
}
xml的处理
<if test="orderPage.dataRageParams.platformId != null">
AND platform_id = #{orderPage.dataRageParams.platformId}
</if>
<if test="orderPage.dataRageParams.intermediaryOrgId != null">
AND company_id = #{orderPage.dataRageParams.intermediaryOrgId}
</if>
<if test="orderPage.dataRageParams.financeOrgId != null">
AND bl_member_id = #{orderPage.dataRageParams.financeOrgId}
</if>
<if test="orderPage.dataRageParams.region != null">
AND region = #{orderPage.dataRageParams.region}
</if>
<if test="orderPage.dataRageParams.province != null">
AND province = #{orderPage.dataRageParams.province}
</if>
<if test="orderPage.dataRageParams.city != null">
AND city = #{orderPage.dataRageParams.city}
</if>
这里就是完整的一套数据范围处理
因篇幅问题不能全部显示,请点此查看更多更全内容