页面长这样
/*
Navicat Premium Data Transfer
Source Server : 本地
Source Server Type : MySQL
Source Server Version : 80038
Source Host : 127.0.0.1:3306
Source Schema : health
Target Server Type : MySQL
Target Server Version : 80038
File Encoding : 65001
Date: 27/08/2024 15:11:35
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_role_field
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_field`;
CREATE TABLE `sys_role_field` (
`role_id` bigint NOT NULL COMMENT '角色ID',
`field_id` bigint NOT NULL COMMENT '字段ID',
PRIMARY KEY (`role_id`, `field_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和字段关联表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
/*
Navicat Premium Data Transfer
Source Server : 本地
Source Server Type : MySQL
Source Server Version : 80038
Source Host : 127.0.0.1:3306
Source Schema : health
Target Server Type : MySQL
Target Server Version : 80038
File Encoding : 65001
Date: 28/08/2024 10:54:38
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_field
-- ----------------------------
DROP TABLE IF EXISTS `sys_field`;
CREATE TABLE `sys_field` (
`field_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字段ID',
`field_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字段英文名',
`entity_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '实体类名',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注信息',
PRIMARY KEY (`field_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字段表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
/**
* 通过角色查询字段列表
*/
@PreAuthorize("@ss.hasPermi('system:field:list')")
@GetMapping(value = "/listByRoleId/{roleId}")
public AjaxResult listByRoleId(@PathVariable("roleId") Long roleId) {
AjaxResult ajax = AjaxResult.success();
List<Long> list = sysFieldService.selectSysFieldListByRoleId(roleId);
ajax.put("roleId", roleId);
ajax.put("fieldIds", list);
ajax.put("rows", sysFieldService.selectSysFieldList(null));
return ajax;
}
/**
* 字段分配给角色
*/
@PreAuthorize("@ss.hasPermi('system:field:add')")
@Log(title = "字段", businessType = BusinessType.GRANT)
@PutMapping("/addAuthFields")
public AjaxResult addFieldRole(Long roleId, Long[] fieldIds) {
return toAjax(sysFieldService.insertAuthFields(roleId, fieldIds));
}
SysFieldMapper.xml
<select id="selectSysFieldListByUserId" parameterType="Long" resultMap="SysFieldResult">
SELECT DISTINCT f.field_id,
f.entity_class,
f.field_name
FROM sys_field f
LEFT JOIN sys_role_field rf ON f.field_id = rf.field_id
LEFT JOIN sys_user_role ur ON ur.role_id = rf.role_id
LEFT JOIN sys_role ro ON ur.role_id = ro.role_id
LEFT JOIN sys_user u ON ur.user_id = u.user_id
WHERE u.user_id = #{userId}
</select>
<select id="selectSysFieldListByRoleId" parameterType="Long" resultType="Long">
SELECT rf.field_id
FROM sys_role_field rf
WHERE rf.role_id = #{roleId}
</select>
FieldScopeAspect.java
package com.ruoyi.framework.aspectj;
import com.github.pagehelper.Page;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysField;
import com.ruoyi.system.mapper.SysFieldMapper;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.List;
/**
* 字段权限处理
*/
@Aspect
@Component
public class FieldScopeAspect {
private static final Logger log = LoggerFactory.getLogger(FieldScopeAspect.class);
@Autowired
private SysFieldMapper fieldMapper;
@Pointcut("@annotation(com.ruoyi.common.annotation.FieldScope)")
public void serviceMethods() {
}
// 后置通知,在方法执行后执行
@AfterReturning(pointcut = "serviceMethods()", returning = "result")
public void afterReturning(Object result) {
// 获取当前的用户
LoginUser loginUser = SecurityUtils.getLoginUser();
if (StringUtils.isNotNull(loginUser)) {
SysUser currentUser = loginUser.getUser();
// 如果不是超级管理员,则过滤数据
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
try {
fieldScopeFilter(result, loginUser);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* 字段过滤方法
*
* @param result
* @param loginUser
* @throws IllegalAccessException
*/
private void fieldScopeFilter(Object result, LoginUser loginUser) throws IllegalAccessException {
List<SysField> fieldList = fieldMapper.selectSysFieldListByUserId(loginUser.getUserId());
//如果有查询到的字段权限,则往下继续
if (fieldList != null) {
//被注解的方法返回分页的列表结果(多条记录)
if (result.getClass() == Page.class) {
Page<?> page = (Page<?>) result;
List<?> list = page.getResult();
for (Object object : list) {
executeMethodResult(object, fieldList);
}
}
//被注解的方法返回对象的结果(单条记录)
else {
executeMethodResult(result, fieldList);
}
}
}
/**
* 处理被注解方法的返回值
*
* @param object
* @param fieldList
* @throws IllegalAccessException
*/
private void executeMethodResult(Object object, List<SysField> fieldList) throws IllegalAccessException {
String simpleEntityClassName = object.getClass().getSimpleName();//方法返回的实体类名称
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
for (SysField sysField : fieldList) {
String entityClass = sysField.getEntityClass();//查询到的实体类名称
String fieldName = sysField.getFieldName();
if (simpleEntityClassName.equals(entityClass)) {
String[] fieldNameArray = fieldName.split("\\.");
//含有二级对象属性的情况
if (fieldNameArray.length > 1) {
if (field.getName().equals(fieldNameArray[0])) {
field.setAccessible(true);
Object subObject = field.get(object);
try {
Field subField = subObject.getClass().getDeclaredField(fieldNameArray[1]);
subField.setAccessible(true);
subField.set(subObject, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(fieldNameArray[1] + "字段不存在");
}
}
} else {
if (field.getName().equals(fieldName)) {
field.setAccessible(true);
field.set(object, null);
}
}
}
}
}
}
}
package com.ruoyi.common.annotation;
import java.lang.annotation.*;
/**
* 字段权限过滤注解
*
* @author wufei
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FieldScope {
String value();
}
使用时在对应的service层加入@FieldScope("")注解