当前位置: 首页> 娱乐> 明星 > 网页制作怎么插图片_莱芜网站建设案例_网站内部链接优化方法_外链屏蔽逐步解除

网页制作怎么插图片_莱芜网站建设案例_网站内部链接优化方法_外链屏蔽逐步解除

时间:2025/7/11 1:13:02来源:https://blog.csdn.net/weixin_45631815/article/details/142489039 浏览次数:0次
网页制作怎么插图片_莱芜网站建设案例_网站内部链接优化方法_外链屏蔽逐步解除

一、代码

package com.dkd.framework.aspectj;import com.dkd.common.annotation.DataScope;
import com.dkd.common.core.domain.BaseEntity;
import com.dkd.common.core.domain.entity.SysRole;
import com.dkd.common.core.domain.entity.SysUser;
import com.dkd.common.core.domain.model.LoginUser;
import com.dkd.common.core.text.Convert;
import com.dkd.common.utils.SecurityUtils;
import com.dkd.common.utils.StringUtils;
import com.dkd.framework.security.context.PermissionContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;/*** 数据过滤处理** @author ruoyi*/
@Aspect
@Component
public class DataScopeAspect
{/*** 全部数据权限*/public static final String DATA_SCOPE_ALL = "1";/*** 自定数据权限*/public static final String DATA_SCOPE_CUSTOM = "2";/*** 部门数据权限*/public static final String DATA_SCOPE_DEPT = "3";/*** 部门及以下数据权限*/public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";/*** 仅本人数据权限*/public static final String DATA_SCOPE_SELF = "5";/*** 数据权限过滤关键字*/public static final String DATA_SCOPE = "dataScope";@Before("@annotation(controllerDataScope)")public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable{// 清理数据范围(权限)过滤条件(params.dataScope)防止sql注入clearDataScope(point);// 设置数据范围(权限)过滤条件handleDataScope(point, controllerDataScope);}protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope){// 获取当前的登录用户LoginUser loginUser = SecurityUtils.getLoginUser();if (StringUtils.isNotNull(loginUser)){// 获取用户基本信息SysUser currentUser = loginUser.getUser();// 如果是超级管理员,则不过滤数据if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()){// 获取目标方法的权限字符串  例如:用户列表(system:user:list)String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());// 设置数据范围(权限)过滤条件,根据当前用户、部门别名、用户别名和权限标识对切点对象进行过滤处理dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),controllerDataScope.userAlias(), permission);}}}/*** 数据范围过滤** @param joinPoint 切点* @param user 用户* @param deptAlias 部门别名* @param userAlias 用户别名* @param permission 权限字符*/public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission){// 构建SQL字符串,用于拼接数据范围条件StringBuilder sqlString = new StringBuilder();// 用于存储已经添加的数据范围类型,避免重复添加List<String> conditions = new ArrayList<String>();// 遍历用户的所有角色for (SysRole role : user.getRoles()){// 获取当前角色的数据范围条件类型 1~5String dataScope = role.getDataScope();// 如果数据范围类型是自定义类型且已添加,则跳过本次循环if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)){continue;}// 如果当前角色权限列表不包含目标方法的权限字符串(system:user:list),则跳过本次循环if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))){continue;}// 如果角色的数据范围类型是全部数据,则清空SQL字符串并添加数据范围类型,结束循环if (DATA_SCOPE_ALL.equals(dataScope)){sqlString = new StringBuilder();conditions.add(dataScope);break;}// 如果角色的数据范围类型是自定义数据else if (DATA_SCOPE_CUSTOM.equals(dataScope)){// 拼接SQL条件,限制部门ID在角色所关联的部门范围内sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,role.getRoleId()));}// 如果角色的数据范围类型是本部门数据else if (DATA_SCOPE_DEPT.equals(dataScope)){// 拼接SQL条件,限制部门ID等于用户所在部门IDsqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));}// 如果角色的数据范围类型是本部门及子部门数据else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)){// 拼接SQL条件,限制部门ID等于用户所在部门ID或在用户所在部门的子孙部门中sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",deptAlias, user.getDeptId(), user.getDeptId()));}// 如果角色的数据范围类型是仅本人数据else if (DATA_SCOPE_SELF.equals(dataScope)){// 如果用户表别名不为空,拼接SQL条件限制用户ID等于当前用户IDif (StringUtils.isNotBlank(userAlias)){sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));}else{ // 否则,拼接SQL条件限制部门ID为0,即不查询任何数据sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));}}// 添加当前角色的数据范围类型条件conditions.add(dataScope);}// 如果数据范围类型集合(即多角色情况下,所有角色都不包含传递过来目标方法的权限字符),则添加一个条件使SQL查询不返回任何数据if (StringUtils.isEmpty(conditions)){sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));}// 如果SQL字符串不为空,则将构造好的数据范围条件添加到方法参数对象中,用于后续的SQL查询if (StringUtils.isNotBlank(sqlString.toString())){// 获取切点方法的第一个参数Object params = joinPoint.getArgs()[0];// 检查参数是否非空且为BaseEntity类型if (StringUtils.isNotNull(params) && params instanceof BaseEntity){// 将参数转换为BaseEntity类型BaseEntity baseEntity = (BaseEntity) params;// 向BaseEntity的params属性中添加数据范围条件baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");}}}/*** 拼接权限sql前先清空params.dataScope参数防止注入*/private void clearDataScope(final JoinPoint joinPoint){// 获取切点方法的第一个参数Object params = joinPoint.getArgs()[0];// 检查参数不为null且是否为BaseEntity类型if (StringUtils.isNotNull(params) && params instanceof BaseEntity){// 将参数转为BaseEntity类型BaseEntity baseEntity = (BaseEntity) params;// 将数据权限过滤条件设置为空baseEntity.getParams().put(DATA_SCOPE, "");}}
}

二、代码使用

(一)、核心功能

1.数据权限控制

根据用户的权限和角色,动态生成 SQL 查询条件,确保用户只能看到自己有权访问的数据。

2.AOP 实现

使用 AspectJ 实现 AOP,通过 @Before 注解在方法执行前进行数据权限过滤。

3.多种数据范围类型

支持多种数据范围类型,包括全部数据、自定义数据、部门数据、部门及子部门数据、仅本人数据等

(二)、基本配置

@Aspect
@Component
public class DataScopeAspect {// 数据权限常量定义public static final String DATA_SCOPE_ALL = "1";public static final String DATA_SCOPE_CUSTOM = "2";public static final String DATA_SCOPE_DEPT = "3";public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";public static final String DATA_SCOPE_SELF = "5";public static final String DATA_SCOPE = "dataScope";

(三)、@Before 注解

@Before("@annotation(controllerDataScope)")
public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable {// 清理数据范围(权限)过滤条件(params.dataScope)防止sql注入clearDataScope(point);// 设置数据范围(权限)过滤条件handleDataScope(point, controllerDataScope);
}

这个方法在带有 @DataScope 注解的方法执行前被调用,主要负责清理和设置数据范围过滤条件。

(四)、handleDataScope 方法

protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {// 获取当前的登录用户LoginUser loginUser = SecurityUtils.getLoginUser();if (StringUtils.isNotNull(loginUser)) {// 获取用户基本信息SysUser currentUser = loginUser.getUser();// 如果是超级管理员,则不过滤数据if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {// 获取目标方法的权限字符串  例如:用户列表(system:user:list)String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext());// 设置数据范围(权限)过滤条件dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),controllerDataScope.userAlias(), permission);}}
}

该方法首先获取当前登录用户的信息,然后检查是否为超级管理员。如果不是超级管理员,则根据用户的角色和权限生成 SQL 查询条件。

(五)、dataScopeFilter 方法

public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission) {// 构建SQL字符串,用于拼接数据范围条件StringBuilder sqlString = new StringBuilder();List<String> conditions = new ArrayList<>();for (SysRole role : user.getRoles()) {String dataScope = role.getDataScope();if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) {continue;}if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) {continue;}if (DATA_SCOPE_ALL.equals(dataScope)) {sqlString = new StringBuilder();conditions.add(dataScope);break;} else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,role.getRoleId()));} else if (DATA_SCOPE_DEPT.equals(dataScope)) {sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));} else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",deptAlias, user.getDeptId(), user.getDeptId()));} else if (DATA_SCOPE_SELF.equals(dataScope)) {if (StringUtils.isNotBlank(userAlias)) {sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));} else {sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));}}conditions.add(dataScope);}if (StringUtils.isEmpty(conditions)) {sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));}if (StringUtils.isNotBlank(sqlString.toString())) {Object params = joinPoint.getArgs()[0];if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {BaseEntity baseEntity = (BaseEntity) params;baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");}}
}

该方法根据用户的不同角色和权限生成 SQL 查询条件,并将其添加到方法参数对象中。具体逻辑如下:
遍历用户的所有角色,根据每个角色的数据范围类型生成 SQL 条件。
最终生成的 SQL 条件会被添加到 BaseEntity 的 params 属性中,用于后续的 SQL 查询。

(六)、clearDataScope 方法

private void clearDataScope(final JoinPoint joinPoint) {Object params = joinPoint.getArgs()[0];if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {BaseEntity baseEntity = (BaseEntity) params;baseEntity.getParams().put(DATA_SCOPE, "");}
}

该方法用于清除 BaseEntity 中的数据范围条件,防止 SQL 注入攻击。

关键字:网页制作怎么插图片_莱芜网站建设案例_网站内部链接优化方法_外链屏蔽逐步解除

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: