Skip to content

数据过滤 @Filter

@Filter 注解用于定义数据展示时的过滤条件,参照 HQL 语句的 where 语法。

使用方法

java
@Erupt(
       name = "Test",
       filter = @Filter("EruptTest.name = '张三'"),
)
public class EruptTest extends BaseModel {
 
    @EruptField(
            views = @View(title = "名称"),
            edit = @Edit(title = "名称")
    )
    private String name;
    
}

配置项注解定义

java
public @interface Filter {
    
    String value() default ""; // 条件表达式

    String[] params() default {}; // 回调参数

    // 动态控制过滤条件
    Class<? extends FilterHandler> conditionHandler() default FilterHandler.class; 
}

代码演示

动态控制查询条件

java
@Erupt(
       name = "Test",
       filter = @Filter(value = "name = '123' or name ",
                        params = {"23333"},
                        conditionHandler = AutoFilter.class)
)
public class EruptTest extends BaseModel {
 
    @EruptField(
            views = @View(title = "名称"),
            edit = @Edit(title = "名称")
    )
    private String name;
    
}
java
@Component
public class AutoFilter implements FilterHandler {
    
    /**
     * @param condition 条件表达式
     * @param params    注解参数
     * 
     * 结果:name = '123' or name = '23333'
     */
    @Override
    public String filter(String condition, String[] params) {
        // 生成新的过滤语句
        // return "name is null"
        
        // 拼接查询参数
        return condition + " = '" + params[0] + "'";
    }
    
}

根据用户角色过滤数据

常见的数据权限场景:管理员查看全部数据,部门主管只看本部门数据,普通员工只看自己创建的数据。

java
@Erupt(
        name = "客户",
        filter = @Filter(conditionHandler = RoleDataFilter.class)
)
@Table(name = "customer")
@Entity
public class Customer extends BaseModel {

    @EruptField(
            views = @View(title = "客户名称"),
            edit = @Edit(title = "客户名称")
    )
    private String name;

    @EruptField(views = @View(title = "所属部门"))
    @ManyToOne
    private EruptOrg org;

    @EruptField(views = @View(title = "负责人"))
    @ManyToOne
    private EruptUser owner;

}
java
@Service
public class RoleDataFilter implements FilterHandler {

    @Resource
    private EruptUserService eruptUserService;

    @Override
    public String filter(String condition, String[] params) {
        EruptUser user = eruptUserService.getCurrentEruptUser();
        // 管理员不受限制
        if (user.getIsAdmin()) return null;
        Set<String> roles = user.getRoles().stream()
                .map(EruptRole::getCode).collect(Collectors.toSet());
        // 部门主管:本部门全部数据
        if (roles.contains(RoleCode.MANAGER.name()) && null != user.getEruptOrg()) {
            return "org.id = " + user.getEruptOrg().getId();
        }
        // 普通员工:仅本人负责的数据
        return "owner.id = " + user.getId();
    }

}

TIP

filter 返回 null 或空字符串表示不附加任何条件,即放行全部数据。

拼接条件时务必使用 id 等数值型字段,若必须拼接用户输入的字符串,请先做转义或白名单校验,避免 HQL 注入。多角色叠加时也可以用 or 组合多个条件:

java
List<String> conditions = new ArrayList<>();
if (roles.contains(RoleCode.MANAGER.name())) {
    conditions.add("org.id = " + user.getEruptOrg().getId());
}
if (roles.contains(RoleCode.SALES.name())) {
    conditions.add("owner.id = " + user.getId());
}
return conditions.isEmpty() ? "1 = 2" : String.join(" or ", conditions);

注意事项

  • 过滤条件应符合 HQL 语法规范
  • 可以结合权限系统实现数据级别的访问控制
  • 支持参数化查询以提高安全性

贡献者

The avatar of contributor named as YuePeng YuePeng
The avatar of contributor named as Claude Opus 5 (1M context) Claude Opus 5 (1M context)

页面历史

Released under the Apache-2.0 License.