• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Data Operations:Custom RSQL Placeholders and Their Usage in Permissions


I. Common Scenarios for Custom RSQL Placeholders

  • Unified data permission configuration
  • Context variable extension for query expressions

II. Custom RSQL Template

/**
 * Demonstrate the basic definition of Placeholder
 *
 * @author Adamancy Zhang at 13:53 on 2024-03-24
 */
@Component
public class DemoPlaceHolder extends AbstractPlaceHolderParser {

    private static final String PLACEHOLDER_KEY = "${thisPlaceholder}";

    /**
     * Placeholder
     *
     * @return placeholder
     */
    @Override
    public String namespace() {
        return PLACEHOLDER_KEY;
    }

    /**
     * Placeholder replacement value
     *
     * @return the value to replace the placeholder
     */
    @Override
    protected String value() {
        return PamirsSession.getUserId().toString();
    }

    /**
     * Priority
     *
     * @return execution order of placeholders, in ascending order
     */
    @Override
    public Integer priority() {
        return 0;
    }

    /**
     * Activation status
     *
     * @return whether the placeholder is activated
     */
    @Override
    public Boolean active() {
        return true;
    }
}

Note:

  • In some older versions, priority and active may not function. To ensure compatibility during upgrades, please ensure these attributes are configured correctly.
  • The PLACEHOLDER_KEY variable represents the keyword used for the custom placeholder, which should be defined correctly based on the specific business scenario and contextual semantics.
  • To ensure placeholders can be correctly replaced and executed, all placeholders should be unique, especially not repeating system-built-in ones.

III. Priority Issues When Using Placeholders

When replacing multiple placeholders, they will be executed in ascending order based on priority. To specify the replacement order, use Spring's Order annotation for sorting.

import org.springframework.core.annotation.Order;

@Order(0)

IV. Built-in Placeholders in Oinone Platform

PlaceholderData TypeMeaningRemarks
${currentUser}StringCurrent user IDUnavailable when not logged in
${currentRoles}Set<String>Set of current user role IDsUnavailable when not logged in

V. How to Override Built-in Placeholders?

By specifying the placeholder's priority and defining the same namespace, you can prioritize replacement.

VI. How to Define Session-Level Context Variables?

In the above template, we used the built-in context variables of the Oinone platform for demonstration. Usually, we need to add context variables based on actual business scenarios to achieve required functions.

Below, we will demonstrate defining a context variable to get the current employee ID based on the current user.

/**
 * Employee session
 *
 * @author Adamancy Zhang at 14:33 on 2024-03-24
 */
@Component
public class EmployeeSession implements HookBefore {

    private static final String SESSION_KEY = "CUSTOM_EMPLOYEE_ID";

    @Autowired
    private DemoEmployeeService demoEmployeeService;

    public static String getEmployeeId() {
        return PamirsSession.getTransmittableExtend().get(SESSION_KEY);
    }

    @Override
    @Hook(priority = 1)
    public Object run(Function function, Object... args) {
        Long userId = PamirsSession.getUserId();
        if (userId == null) {
            return function;
        }
        if (StringUtils.isBlank(EmployeeSession.getEmployeeId())) {
            PamirsSession.getTransmittableExtend().put(SESSION_KEY, getCurrentEmployeeId());
        }
        return function;
    }

    private String getCurrentEmployeeId() {
        String employeeId = getEmployeeIdByCache();
        if (employeeId == null) {
            employeeId = demoEmployeeService.getCurrentEmployeeId();
        }
        return employeeId;
    }

    private String getEmployeeIdByCache() {
        // do something.
        return null;
    }
}

Note:

  • Use HookBefore to set employeeId in the context when a request is initiated, and use EmployeeSession.getEmployeeId() to retrieve it.
  • Set the HookBefore priority to priority = 1, ensuring this Hook executes after the platform's built-in UserHook to ensure the value in PamirsSession.getUserId() is correctly set.
  • The DemoEmployeeService should be implemented using the platform's @Fun and @Function annotations to ensure this Session works correctly in a distributed environment.
  • The getEmployeeIdByCache method needs to be implemented independently, and using caching at runtime can effectively improve performance.

VII. Using Employee Session in Placeholder

Modify DemoPlaceHolder to use ${currentEmployeeId} to get the employeeId saved in the employee session.

/**
 * Demonstrate using employee session in Placeholder
 *
 * @author Adamancy Zhang at 15:02 on 2024-03-24
 */
@Component
public class DemoPlaceHolder extends AbstractPlaceHolderParser {

    private static final String PLACEHOLDER_KEY = "${currentEmployeeId}";

    /**
     * Placeholder
     *
     * @return placeholder
     */
    @Override
    public String namespace() {
        return PLACEHOLDER_KEY;
    }

    /**
     * Placeholder replacement value
     *
     * @return the value to replace the placeholder
     */
    @Override
    protected String value() {
        return EmployeeSession.getEmployeeId();
    }

    /**
     * Priority
     *
     * @return execution order of placeholders, in ascending order
     */
    @Override
    public Integer priority() {
        return 0;
    }

    /**
     * Activation status
     *
     * @return whether the placeholder is activated
     */
    @Override
    public Boolean active() {
        return true;
    }
}

So far, we have completed an employee ID placeholder.

VIII. Using This Placeholder as a Filter Condition in Permission Configuration

Below, we will simulate a simple business scenario to detail how this placeholder is used in business.

(Ⅰ) Scenario Description

The current system includes two models: Department and Employee, with basic definitions as follows:

1. Department

/**
 * Demo department
 *
 * @author Adamancy Zhang at 15:18 on 2024-03-24
 */
@Model.model(DemoDepartment.MODEL_MODEL)
@Model(displayName = "Demo Department", labelFields = "name")
public class DemoDepartment extends IdModel {

    private static final long serialVersionUID = -300189841334506668L;

    public static final String MODEL_MODEL = "demo.DemoDepartment";

    @Field(displayName = "Department Name")
    private String name;

    @Field(displayName = "Manager")
    private DemoEmployee manager;

}

2. Employee

/**
 * Demo employee
 *
 * @author Adamancy Zhang at 15:17 on 2024-03-24
 */
@Model.model(DemoEmployee.MODEL_MODEL)
@Model.Advanced(unique = {"bindingUserId"})
@Model(displayName = "Demo Employee", labelFields = "name")
public class DemoEmployee extends IdModel {

    private static final long serialVersionUID = -6237083162460091500L;

    public static final String MODEL_MODEL = "demo.DemoEmployee";

    @Field(displayName = "Employee Name")
    private String name;

    @Field.Relation(relationFields = {"bindingUserId"}, referenceFields = {"id"})
    @Field(displayName = "Bound User")
    private PamirsUser bindingUser;

    @Field(displayName = "Bound User ID")
    private Long bindingUserId;

}

We require that the currently logged-in user can only view departments where they serve as managers. Therefore, we need to use the filter condition managerId == ${currentEmployeeId} in permission configuration to make it effective.

The data preparation process is omitted here, only showing the configuration of key pages and final effects.

(Ⅱ) Permission Item Configuration

Switch to the Permissions module in the application, select Permission Item List, create a data permission item, and configure it as shown in the figure below.

(Ⅲ) Role Permission Configuration

Select Role List, click the Permission Configuration button for the specified role in the role table, enter the Permission Configuration page, and configure it as shown in the figure below.

PS: Action permission configuration is omitted here. Configured permissions should ensure the role can correctly access the Demo Department page to view the effect.

(Ⅳ) Bind the Specified Role to the User (Skip if Already Bound)

Switch to the User Center module in the application, select the specified user, and bind the specified role.

(Ⅴ) View Permission Configuration Effects on the Demo Department Page

1. Page Effect Without Permission Configuration

2. Page Effect After Permission Configuration

Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Data Operation:Custom Sort Fields and Sorting Rules During Query
Next
Data Operations:Custom SQL (Mapper) Statements
默认页脚
Copyright © 2026 Mr.Hope