目录
代码
controller层
@PreAuthorize("@ss.hasPermi('system:myworkshop:list')")
@GetMapping("/list")
public TableDataInfo list(Myworkshop myworkshop)
{
startPage();
List<Myworkshop> list = myworkshopService.selectMyworkshopList(myworkshop);
return getDataTable(list);
}
controller层调用service层的selsectMyworkshopList函数
service层Impl
@Override
@DataScope(deptAlias = "d",userAlias = "u")
public List<Myworkshop> selectMyworkshopList(Myworkshop myworkshop)
{
return myworkshopMapper.selectMyworkshopList(myworkshop);
}
使用DataScope注解,deptAlias为部门表别称,userAlias为用户表别称
返回给controller对应用户的数据
mapper.xml
select l.id, l.name, l.temp, l.dept_id from myworkshop l left join sys_dept d on l.dept_id=d.dept_id where l.id is not null
将l和sys_sept d相连, 条件为两表dept_id相等,且l中的 id值不为空。
datascope传参${params.dataScope}
AOP
DataScope注解内部
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
/**
* 部门表的别名
*/
public String deptAlias() default "";
/**
* 用户表的别名
*/
public String userAlias() default "";
}
DataScope对应的切面类
@Aspect
@Component
public class DataScopeAspect
切面类中的方法
doBefore函数
@Before("@annotation(controllerDataScope)")
public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
{
clearDataScope(point);
handleDataScope(point, controllerDataScope);
}
Before:监听注解,类型为controllerDataScope 对应的注解类型@DataScope
监听到有使用DdataScope注解的函数时,首先执行doBefore函数
clearDataScope
/**
* 拼接权限sql前先清空params.dataScope参数防止注入
*/
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, "");
}
}
}
首先joinPoint.getArgs()[0]获取参数,判断传入参数是否为BaseEtity子类防止注入,然后进行权限SQL拼接。
handleDtaScope
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())
{
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias());
}
}
}
获取当前用户,判断是否过滤数据。
dataScopeFilter
/**
* 数据范围过滤
*
* @param joinPoint 切点
* @param user 用户
* @param userAlias 别名
*/
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
{
StringBuilder sqlString = new StringBuilder();
for (SysRole role : user.getRoles())
{
。。。。。。
else if (DATA_SCOPE_DEPT.equals(dataScope))
{
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
}
。。。。。。。
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中插入的语句为OR d.dept_id=201
下一个if语句将OR转换为AND
AND (d.dept_id = 105)这个语句被传回给${params.datascope}
总结