页面树结构
转至元数据结尾
转至元数据起始

需求说明

需求场景: 报表有个客户id字段, 每个业务人员负责一批客户(这个是动态的, 可能有不同批次), 业务人员需要在报表中筛选自己负责的某批客户. 因此期望筛选器的备选值是批次号, 表格真正刷新时, 是用该批次的客户id进行筛选。

接口说明

版本:since Hotfix_SmartbiV11_20250616

IBeforeQueryHandler

名称: 查询前处理器

作用: 在查询执行前, 处理查询请求. 比如修改条件值.

生效对象: 仪表盘, 即席, 透视的所有组件取数.

包: Commons

路径: smartbix.query.handler

实现: IBaseQueryHandler 空接口

接口方法

before(context: QueryContext): void

作用: 组件取数前, 对查询请求进行自定义处理, 如修改条件值.


名称

类型

说明

输入参数

context

QueryContext

查询上下文, 包含查询ID, 报表ID, 报表类型, 查询请求.

返回值



ICustomExecutor

名称: 查询处理器

作用: 自定义组件查询的处理器. 比如自定义筛选器备选值. 一般不直接实现这个接口, 而是实现其抽象类, 减少开放工作量.

生效对象: 仪表盘, 即席, 透视的组件取数.

包: Commons

路径: smartbix.query.handler

接口方法

getQueryOption(): IQueryOption

作用: 获取查询请求


名称

类型

说明

输入参数



返回值

queryOption

IQueryOption

查询请求, 包含查询条件, 查询字段, 排序, 私有字段, 分页, 数据来源等

refresh(): Object

作用: 执行查询请求, 并返回查询结果集


名称

类型

说明

输入参数



返回值

result

Object

查询结果集, 不同组件查询结果集格式不同. 具体组件具体分析.

AbstractCustomExecutor (仪表盘组件取数器抽象类)

名称: 仪表盘组件查询处理器器抽象类

作用: 仅为仪表盘自定义组件查询的处理器, 实现了ICustomExecutor中的getQueryOption方法, 仅需要补充refresh方法的实现即可.

生效对象: 仪表盘的组件取数

包: Page

路径: smartbix.page.executor2

接口方法

getQueryOption(): IQueryOption

详见ICustomExecutor

refresh(): Object


名称

类型

说明

输入参数



返回值

result

Object

非树筛选器/参数 结果集格式:

{

data: [

[ value: Cell, display: Cell ], // display可以不存, 即 [value: Cell]

[value2: Cell, display2: Cell],

...

]

}

Cell: { value: string | number, displayValue: string }

树参数 结果集格式:

{

data: [

[value: Cell],

[value2: Cell],

....

]

}

Cell: { value: string | number, displayValue: string, id: string, parentId: string }

树筛选器 结果集格式:

[

value: Cell,

value2: Cell,

...

]

Cell: {

id: string, // 格式: parentId + '$$$^V^$$$' + value

parentId: string,

value: string,

displayValue: string,

levelId: string, // 值是该字段的uniqueId

children: [Cell]

}

AbstractCustomExecutor (即席和透视的组件取数器抽象类)

名称: 即席和透视的组件查询处理器抽象类

作用: 仅为即席和透视自定义组件查询的处理器, 实现了ICustomExecutor中的getQueryOption方法, 仅需要补充refresh方法的实现即可.

生效对象: 即席和透视的组件取数

包: ModelQuery

路径: smartbix.analysis.query

接口方法

getQueryOption(): IQueryOption

详见ICustomExecutor

refresh(): Object


名称

类型

说明

输入参数



返回值

result

Object

非树筛选器/参数 结果集格式:

{

data: [value: Cell, value2: Cell, ...]

}

Cell: { value: string | number, displayValue: string }

树参数 结果集格式:

{

data: [value: Cell, value2: Cell, ...]

}

Cell: { value: string | number, displayValue: string, id: string, parentId: string }

树筛选器 结果集格式:

[

value: Cell,

value2: Cell,

...

]

Cell: {

id: string, // 格式: parentId + '$$$^V^$$$' + value

parentId: string,

value: string,

displayValue: string,

levelId: string, // 值是该字段的uniqueId

children: [Cell]

}

QueryHandlerManager

名称: 查询处理器管理类

作用: 用于注册/注销 IBeforeQueryHandler和ICustomExecutor

生效对象: 仪表盘, 即席, 透视

包: Commons

路径: smartbix.query.handler

限制: 注册取数器时, 名称不能含双下划线, 不能与系统中存在的bean名称重复, 因此命名因该特殊些.

类方法

getInstance(): QueryHandlerManager

作用: 返回一个查询处理器管理类实例

addExecutor(executorName: String, executorClass: Class<? extends ICustomExecutor>): void

作用: 注册组件查询处理器


名称

类型

说明

输入参数

executorName

String

查询处理器名称, 不允许包含双下划线, 不允许与系统中任何bean命名重复, 因此实际命名时, 请多加限定词.

executorClass

Class<? extends ICustomExcutor>

查询处理器类

返回值


注册失败, 会打印日志, 不会报错

removeExecutor(executorName: String): boolean

作用: 注销组件查询处理器


名称

类型

说明

输入参数

executorName

String

查询处理器名称

返回值

succeeded

boolean

当处理器存在且移除成功, 返回true

add(reportType: String, handler: IBaseQueryHandler): void

作用: 注册组件查询前处理器


名称

类型

说明

输入参数

reportType

String

报表类型, DETAILED_QUERY 即席查询 AD_HOC_ANALYSIS 透视分析 SMARTBIX_PAGE 仪表盘

handler

IBaseQueryHandler

基础查询处理器的实现类, 如IBeforeQueryHandler

返回值



remove(reportType: String, handler: IBaseQueryHandler): boolean

作用: 注销组件查询前处理器


名称

类型

说明

输入参数

reportType

String

报表类型, DETAILED_QUERY 即席查询 AD_HOC_ANALYSIS 透视分析 SMARTBIX_PAGE 仪表盘

handler

IBaseQueryHandler

基础查询处理器的实现类, 如IBeforeQueryHandler

返回值

succeeded

boolean

处理器存在且注销成功, 则返回true

接口依赖的类

QueryContent

名称: 查询上下文

作用: 存储了当前查询的上下文, 包括报表ID, 报表类型, 查询请求, 查询ID

生效对象: 仪表盘, 即席, 透视的组件查询前处理器

包: Commons

路径: smartbix.query.handler

getQueryId(): String

作用: 返回查询ID

getReportId(): String

作用: 返回报表ID

getReportType(): String

作用: 返回报表类型, DETAILED_QUERY 即席查询 AD_HOC_ANALYSIS 透视分析 SMARTBIX_PAGE 仪表盘

getQueryOption(): IQueryOption

作用: 返回查询请求

IQueryOption

名称: 查询请求

作用: 用于描述组件查询. 包括筛选器/参数搜索时的key, 查询条件, 私有字段, 分页信息, 取数字段, 数据来源, 排序.

生效对象: 仪表盘, 即席, 透视的组件查询前处理器

包: Commons

路径: smartbix.query.handler

getKeyword(): String

作用: 搜索key, 仅针对筛选器和参数的查询接口.

getQueryCondition(): IQueryCondition

作用: 获取查询条件

getPrivateDatasetFields(): List<IQueryPrivateDefine>

作用: 获取私有字段列表

getQueryFields(): List<IQueryField>

作用: 获取查询字段


名称

类型

说明

输入参数



返回值

queryFields

List<IQueryField>

// 参数查询接口, 格式

[{ name: '参数在数据模型中的名称' }]

// 其它有字段的查询接口: 格式

[{ id, name, alias, desc, type, ... }]

getDataSource(): IDataSource

作用: 获取数据来源定义


名称

类型

说明

输入参数



返回值

dataSource

IDataSource

IDataSource 格式: { id: String, type: String }

getPagination(): Pagination

作用: 获取分页信息


名称

类型

说明

输入参数



返回值

pagination

Pagination

Pagination 格式: { num: int, size: int }, num >= 0

getRowQuerySorts(): List<IQuerySort>

作用: 获取行排序. 通用组件排序都在这里. 但目前只有仪表盘组件支持, 即席透视未支持. 即席透视需要从queryField.orderBy中获取


名称

类型

说明

输入参数



返回值

rowQuerySorts

List<IQuerySort>

行排序

getColQuerySorts(): List<IQuerySort>

作用: 获取列排序

IQueryOrder

名称: 查询排序

作用: 定义字段排序设置

生效对象: 仪表盘组件查询, (即席透视待支持)

包: Commons

路径: smartbix.query

sortDirection(): SortDirection

作用: 获取排序方式


名称

类型

说明

输入参数



返回值

sortDirection

SortDirection

排序方式: ASC 升序, BASC 全局升序, DESC 降序, BDESC 全局降序

sortField(): Optional<IQueryField>

作用: 获取排序字段

sortByCustomization(): List<String>

作用: 获取自定义成员排序的成员顺序

sortByField(): Optional<IQueryField>

作用: 获取排序依据, 如果不存在, 排序字段就是排序依据

getOrderPriority(): int

作用: 获取排序优先级, 数字越大越优先

sortMemberPath(): List<?>

作用: 获取表头排序时该列的表头路径

IQueryCondition

名称: 查询条件

作用: 用于统一查询条件, 所有类型的查询条件都要继承它

生效对象: 仪表盘, 即席, 透视的查询条件

包: Commons

路径: smartbix.query.handler

canIgnore(): boolean

作用: 判断该条件是否可忽略. 不工作的条件即可忽略, 如带等于操作符的无条件值的字段条件

getNodeType(): QueryConditionNodeType

作用: 获取条件类型


名称

类型

说明

输入参数



返回值

nodeType

QueryConditionNodeType

条件类型: RELATION 关系, FIELD_FILTER 字段条件, PARAM_FILTER 参数条件, NONE_FILTER 表达式条件

IQueryFieldConditionNode

名称: 字段查询条件

作用: 筛选字段值, 继承了IQueryCondition. 来源于字段条件

生效对象: 仪表盘, 即席, 透视的组件查询条件

包: Commons

路径: smartbix.query.handler

getOperator(): FilterOperationType

作用: 获取比较运算符.

setOperator(operator: FilterOperationType): void

作用: 设置比较运算符

getValues(): List<Object>

作用: 获取条件值

setValues(values: List<Object>): void

作用: 设置条件值

getField(): IQuryField

作用: 获取筛选字段

setField(field: IQueryField): void

作用: 设置筛选字段

IQueryParamConditionNode

名称: 参数查询条件

作用: 筛选参数值, 继承了IQueryCondition, 来源于参数条件

生效对象: 仪表盘, 即席, 透视的组件查询条件

包: Commons

路径: smartbix.query.handler

getId(): String

作用: 获取数据模型参数id, 不一定存在

getName(): String

作用: 获取数据模型参数名称

getAlias(): String

作用: 获取参数别名, 不一定存在

getValues(): List<Object>

作用: 获取参数查询条件的值

setValues(values: List<Object>): void

作用: 设置参数查询条件的值

IQueryNoneConditionNode

名称: 表达式条件

作用: 直接使用条件值和比较运算符进行比较, 从而筛选查询结果集. 继承了IQueryCondition

生效对象: 仪表盘树状表的组件查询条件

包: Commons

路径: smartbix.query.handler

getValues(): List<Object>

作用: 获取条件值, 值必须是两个

setValues(values: List<Object>): void

作用: 设置条件值, 值必须是两个

getOperator(): FilterOperationType

作用: 获取比较运算符.(条件第一个值和第二个值比较)

setOperator(operator: FilterOperationType): void

作用: 设置比较运算符(条件第一个值和第二个值比较)

IQueryRelationConditionNode

名称: 关系查询条件

作用: 使用OR AND NOR关系组织条件, 做复杂筛选

生效对象: 仪表盘, 即席, 透视的组件查询条件

包: Commons

路径: smartbix.query.handler

getRelation(): LogicOperatorType

作用: 获取条件关系, OR 或, AND 与, NOR 非

setRelation(relation: LogicOperatorType): void

作用: 设置条件关系

getChildNodes(): List<IQueryCondition>

作用: 获取子条件

setChildNodes(childNodes: List<IQueryCondition>): void

作用: 设置子条件

前端接口说明

自定义ICustomExecutor, 需要指定查询的executorName, 这一步骤需要前端二开实现.

IFilter

名称: 仪表盘 或 即席 或 透视 在筛选器初始化时的二开接口的第一个入参

作用: 筛选器和参数的二开接口调用

接口方法

setQueryType(queryType: string): void

作用: 设置筛选器查询时的查询器名称

使用说明

扩展包依赖

项目

说明

Commons

提供IBeforeQueryHandler接口, 用于组件取数前修改查询请求(比如条件值)

提供ICustomExecutor接口, 用于定义组件取数器

提供QueryHandlerManger管理器, 用于注册ICustomExecutor和IBeforeQueryHandler

提供QueryCondtionUtil工具类, 用于修改组件取数请求的条件值

Framework.interface

提供IModule接口, 用于扩展包激活时, 注册组件取数执行器, 组件取数前处理器

提供IShutdownHook接口, 用于扩展包卸载时, 注销组件取数执行器, 组件取数前处理器

ModelQuery

提供即席透视的组件取数器的抽象实现smartbix.analysis.query.AbstractCustomExecutor

想要自定义即席透视组件的取数器时, 需要继承该类

Page

提供仪表盘的组件取数器的抽象实现smartbix.page.executor2.AbstractCustomExecutor

想要自定义仪表盘组件的取数器时, 需要继承该类

SmartbiVLibManager

提供ObjectNode和ArrayNode, 用于包装取数器结果

使用示例

更完整的用例, 请访问扩展包http://10.10.201.35:8888/RD/Extensions的 XPlayWrightExtensionTemplate 项目

1. 新建筛选器取数器, 用于自定义筛选器的备选值

即席透视筛选器的查询器
package smartbi.smartbix.extension.custom.analysis;

import smartbi.smartbix.extension.custom.StandbyValueProvider;
import smartbix.analysis.query.AbstractCustomExecutor;

/**
 * 即席透视列表筛选器(参数)取数器(命名不允许有双下划线)
 */
public class CustomPortletExecutor extends AbstractCustomExecutor {
	@Override
	public Object refresh() {
		String keyword = this.getQueryOption().getKeyword();
		return StandbyValueProvider.getStandbyValue(keyword);
	}
}
备选值提供器
package smartbi.smartbix.extension.custom;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import smartbix.util.SmartbiXObjectMapper;
import smartbixlibs.com.fasterxml.jackson.databind.node.ArrayNode;
import smartbixlibs.com.fasterxml.jackson.databind.node.ObjectNode;

public final class StandbyValueProvider {
	private StandbyValueProvider() {
	}

	/**
	 * 备选值
	 * @param keyword 搜索关键词
	 * @return 备选值
	 */
	public static ObjectNode getStandbyValue(String keyword) {
		List<String> values = getRealValueList(keyword);
		ObjectNode result = SmartbiXObjectMapper.getInstance().createObjectNode();
		ArrayNode data = result.putArray("data");
		values.stream().forEach(v -> {
			ObjectNode col = data.addObject();
			col.put("value", v);
			col.put("displayValue", v);
		});
		return result;
	}

	private static List<String> getRealValueList(String keyword) {
		List<String> values = new ArrayList<>();
		values.add("CUSTOM_X北_CUSTOM");
		values.add("华南");
		values.add("华东");
		values.add("西南");
		if (keyword == null || "".equals(keyword)) {
			return values;
		}
		return values.stream().filter(v -> v.indexOf(keyword) >= 0)
				.collect(Collectors.toList());
	}
}

2. 新建查询前处理器, 用于修改被该筛选器影响的组件的条件值(比如批次号替换为一系列客户id)

组件查询前处理器
package smartbi.smartbix.extension.custom;

import java.util.ArrayList;
import java.util.List;

import smartbix.query.handler.IBeforeQueryHandler;
import smartbix.query.handler.IQueryFieldConditionNode;
import smartbix.query.handler.IQueryParamConditionNode;
import smartbix.query.handler.QueryConditionUtil;
import smartbix.query.handler.QueryContext;

/**
 * 组件查询前处理器
 */
public class BeforeQueryHandler implements IBeforeQueryHandler {
	@Override
	public void before(QueryContext context) {
		QueryConditionUtil.handleCondition(context.getQueryOption().getQueryCondition(), (condition) -> {
			if (condition instanceof IQueryFieldConditionNode) {
				IQueryFieldConditionNode node = (IQueryFieldConditionNode) condition;
				node.setValues(processConditionValues(node.getValues()));
			} else if (condition instanceof IQueryParamConditionNode) {
				IQueryParamConditionNode node = (IQueryParamConditionNode) condition;
				node.setValues(processConditionValues(node.getValues()));
			}
			return condition;
		});
	}

	private List<Object> processConditionValues(List<Object> oldValues) {
		List<Object> newValues = new ArrayList<>();
		oldValues.forEach(v -> {
			if ("CUSTOM_X北_CUSTOM".equals(v)) {
				newValues.add("华北");
				newValues.add("东北");
				newValues.add("西北");
			} else {
				newValues.add(v);
			}
		});
		return newValues;
	}
}

3. 将上面两个处理器注册

扩展包Module类
package smartbi.smartbix.extension.custom;

import smartbi.framework.IModule;
import smartbi.framework.IShutdownHook;
import smartbix.query.handler.QueryHandlerManager;

/**
 * 自定义取数器Module
 */
public class CustomExecutorModule implements IModule, IShutdownHook {
	private static CustomExecutorModule instance = new CustomExecutorModule();
	private BeforeQueryHandler handler = new BeforeQueryHandler();

	/**
	 * @return CustomExecutorModule
	 */
	public static CustomExecutorModule getInstance() {
		return instance;
	}

	@Override
	public void shutdown() {
		QueryHandlerManager.getInstance().remove("DETAILED_QUERY", handler);
		QueryHandlerManager.getInstance().remove("AD_HOC_ANALYSIS", handler);
		QueryHandlerManager.getInstance().removeExecutor("Custom_Portlet_Executor");
	}

	@Override
	public void activate() {
		QueryHandlerManager.getInstance().add("DETAILED_QUERY", handler);
		QueryHandlerManager.getInstance().add("AD_HOC_ANALYSIS", handler);
      QueryHandlerManager.getInstance().addExecutor("Custom_Portlet_Executor", smartbi.smartbix.extension.custom.analysis.CustomPortletExecutor.class);
    }
}

4. 前端二开设置筛选器取数时, 使用自定义的取数器

透视筛选器初始化时(前端二开)
// 透视
this.on(AD_HOC_FILTER_ON_INIT, (filter, iAdHocAnalysis) => {
  filter.setQueryType('Custom_Portlet_Executor')
})



  • 无标签