示例场景
场景目标:
对使用特定数据来源或特定类型的报表实施导出行数限制,确保用户在导出时明确知晓限制规则,并在必要时限制导出数据量。
具体流程:
限制规则匹配
当用户触发报表导出操作时,系统自动检测当前报表是否使用了受限数据来源或属于受限报表类型。
用户提示与交互
若报表受限:弹出提示框,明确告知用户以下信息:
当前报表受行数限制
允许导出的最大行数(如“最大支持导出 10,000 行数据”)
提供操作选项:继续导出(按限制截断数据)或取消导出
若报表不受限:直接进入默认导出流程。
后续处理
用户选择继续导出:系统仅导出限制范围内的数据(如最多 10,000 行),并自动截断超出行数。
用户选择取消:关闭提示框,终止导出流程,不发起任何导出请求。
整体方案
1. 扩展导出规则,新增行数限制策略
基于当前产品的导出规则体系,新增一种“限制行数导出”动作类型(现有导出动作包括禁止导出、直接导出、申请导出),并支持在该动作中配置允许导出的最大行数限制值。
2. 导出前预校验策略
在用户完成导出弹窗配置并点击“确定”后,发起预校验请求,获取当前报表匹配的最终导出策略(包括是否受行数限制)。
3. 行数限制提示与用户确认
若匹配到“限制行数导出”策略:
弹出提示,明确告知用户:
“当前报表导出受行数限制”
“最大允许导出:X 行”(X 为配置的限制值)
提供操作选项:继续导出(按限制截断数据) 或 取消导出
若不匹配:按产品原有逻辑继续执行导出流程。
4. 执行限制行数导出
若用户选择继续导出,系统自动修改导出配置,强制应用最大行数限制,并调用产品导出接口生成符合限制的数据文件。
产品相关二开扩展接口
1. 产品提供扩展接口,允许扩展导出规则,新增行数限制策略
2. 产品提供扩展接口,允许在导出前可以获取当前报表导出规则策略结果
3. 产品提供扩展接口,允许在点击导出弹窗确定时候扩展二开动作
4. 产品提供扩展接口,允许修改导出配置项直接导出
接口一:
接口二:
接口三:
接口四:
前端接口定义
新透视,时机:AD_HOC_DEFINE_ON_LOADED,调用对象IAdHocAnalysisQuery
新即席,时机:D_QUERY_DEFINE_ON_LOADED,调用对象IDetailedQuery
setCustomOperators
作用: 自定义筛选器操作符
名称 | 类型 | 说明 | |
输入参数 | customOperators | Array | 自定义筛选器操作符对象列表 ] |
返回值 | - | - | - |
后端接口
IBeforeQueryHandler
名称: 查询前处理器
作用: 在查询执行前, 处理查询请求. 比如修改条件值.
接口方法
before(context: QueryContext): void
作用: 组件取数前, 对查询请求进行自定义处理, 如修改条件值.
名称 | 类型 | 说明 | |
输入参数 | context | QueryContext | 查询上下文, 包含查询ID, 报表ID, 报表类型, 查询请求. |
返回值 | 无 |
使用示例
// 以透视分析为例 // 前端扩展新增操作符 this.on(AD_HOC_DEFINE_ON_LOADED, (iAdHocAnalysis) => { console.log('AD_HOC_DEFINE_ON_LOADED') // 自定义操作符定义 const customOperators = [ { id: 'EMPTY_STRING', label_cn: '为空串', label_tw: '為空串', label_en: 'Empty String', noValue:true, supportedDataTypes: ['STRING'], // 只支持字符串数据类型 supportedComponents: ['SELECT', 'MULTI_SELECT', 'LIST', 'MULTI_LIST'] // 支持下拉筛选器类型 }, { id: 'NOT_EMPTY_STRING', label_cn: '不为空串', label_tw: '不為空串', label_en: 'Not Empty String', noValue:true, supportedDataTypes: ['STRING'], // 只支持字符串数据类型 supportedComponents: ['SELECT', 'MULTI_SELECT', 'LIST', 'MULTI_LIST'] // 支持下拉筛选器类型 } ] iAdHocAnalysis.setCustomOperators(customOperators) }) // 后端实现IBeforeQueryHandler根据自定义操作符修改查询条件 public class BeforeQueryHandler implements IBeforeQueryHandler { @Override public void before(QueryContext context) { IQueryCondition ret = QueryConditionUtil.handleCondition(context.getQueryOption().getQueryCondition(), (condition) -> { if (condition instanceof IQueryFieldConditionNode) { IQueryFieldConditionNode node = (IQueryFieldConditionNode) condition; String originalOperator = node.getOriginalOperator(); // 处理 EMPTY_STRING 操作符 if ("EMPTY_STRING".equals(originalOperator)) { IQueryRelationConditionNode co = createEmptyStringCondition(node.getField()); return co; } } return condition; }); } /** * 创建空字符串条件:字段为 NULL 或者是等于空字符串 * @param field 字段 * @return 复合条件 */ private IQueryRelationConditionNode createEmptyStringCondition(IQueryField field) { IQueryRelationConditionNode relationCondition = new QueryRelationConditionNode(); relationCondition.setRelation(LogicOperatorType.OR); relationCondition.setChildNodes(new ArrayList<>()); // 条件1:字段为 NULL IQueryFieldConditionNode nullCondition = new IQueryFieldConditionNode() { @Override public FilterOperationType getOperator() { return FilterOperationType.NULL; } @Override public void setOperator(FilterOperationType operator) { // 不允许修改 } @Override public List<Object> getValues() { return new ArrayList<>(); } @Override public void setValues(List<Object> values) { // 不允许修改 } @Override public IQueryField getField() { return field; } @Override public void setField(IQueryField field) { // 不允许修改 } @Override public String getOriginalOperator() { return "NULL"; } @Override public void setOriginalOperator(String originalOperator) { // 不允许修改 } }; // 条件2:字段等于空字符串 IQueryFieldConditionNode emptyStringCondition = new IQueryFieldConditionNode() { @Override public FilterOperationType getOperator() { return FilterOperationType.EQUALS; } @Override public void setOperator(FilterOperationType operator) { // 不允许修改 } @Override public List<Object> getValues() { List<Object> values = new ArrayList<>(); values.add(""); return values; } @Override public void setValues(List<Object> values) { // 不允许修改 } @Override public IQueryField getField() { return field; } @Override public void setField(IQueryField field) { // 不允许修改 } @Override public String getOriginalOperator() { return "EQUAL"; } @Override public void setOriginalOperator(String originalOperator) { // 不允许修改 } }; // 添加两个子条件 relationCondition.getChildNodes().add(nullCondition); relationCondition.getChildNodes().add(emptyStringCondition); return relationCondition; } }