new-bi 多个视图处理 发表于 2022-07-09 | 分类于 ---代码备份 | 2022-07-09 17:15:41123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435package com.amoros.newbi.service.service.impl;import cn.hutool.core.collection.CollectionUtil;import cn.hutool.core.lang.Assert;import cn.hutool.core.lang.Console;import cn.hutool.core.map.MapUtil;import cn.hutool.core.thread.AsyncUtil;import cn.hutool.core.util.BooleanUtil;import cn.hutool.core.util.SerializeUtil;import com.amoros.newbi.service.context.TenantIdHolder;import com.amoros.newbi.service.dataobject.dto.DateTimeBo;import com.amoros.newbi.service.dataobject.dto.QueryResultWrapper;import com.amoros.newbi.service.dataobject.dto.QueryResultWrappers;import com.amoros.newbi.service.dataobject.properties.BiConfig;import com.amoros.newbi.service.dataobject.properties.BiReportProperties;import com.amoros.newbi.service.dataobject.properties.ViewConfig;import com.amoros.newbi.service.dataobject.qry.BiQueryParams;import com.amoros.newbi.service.dataobject.qry.BiReportQry;import com.amoros.newbi.service.processor.ProcessorManager;import com.amoros.newbi.service.processor.agg.AggProcessor;import com.amoros.newbi.service.processor.post.PostProcessor;import com.amoros.newbi.service.processor.pre.PreProcessor;import com.amoros.newbi.service.service.BiService;import com.amoros.newbi.service.util.MDCUtil;import datart.api.service.DataProviderService;import datart.api.service.custom.qry.TableVariable;import datart.api.service.custom.qry.ViewQry;import datart.api.service.custom.result.QueryResult;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;import java.util.Map;import java.util.concurrent.CompletableFuture;import java.util.stream.Collectors;import java.util.stream.Stream;@Slf4j@Servicepublic class BiServiceImpl implements BiService { @Autowired private BiReportProperties biReportProperties; @Autowired private DataProviderService dataProviderService; @Override public QueryResultWrappers biReport(BiReportQry biReportQry) { // [0] 初始化参数 String reportCode = biReportQry.getReportCode(); BiQueryParams queryParams = biReportQry.getBiQueryParams(); // [1] 正常时间 => 财年时间 updateFiscalTime(queryParams); // [2] 获取配置 reportCode => bi.yml 配置 BiConfig biConfig = biReportProperties.getConfig().get(reportCode); Assert.notNull(biConfig, "获取不到 bi 相关配置,reportCode=[{}]", reportCode); // [3] 依次处理所有视图 QueryResultWrappers wrappers = handleMultiView(biConfig.getViewConfigList(), queryParams); // [4] 所有视图处理完毕 => 聚合处理器 wrappers = aggProcess(wrappers, biConfig, queryParams); // [5] 返回结果 return wrappers; } private QueryResultWrappers handleMultiView2(List<ViewConfig> viewConfigList, BiQueryParams queryParams) { // 查询 => List List<ViewQry> viewQryList = viewConfigList.stream() .flatMap(viewConfig -> { BiQueryParams _queryParams = SerializeUtil.clone(queryParams); preProcess(viewConfig, _queryParams); ViewQry viewQry = getViewQry(viewConfig, _queryParams); if (!BooleanUtil.isTrue(viewConfig.getCompareData())) { return Stream.of(viewQry); } _queryParams.setStartDate(_queryParams.getDateTimeBo().getComparedStartDate()); _queryParams.setEndDate(_queryParams.getDateTimeBo().getComparedEndDate()); ViewQry viewQry_yoy = getViewQry(viewConfig, _queryParams); _queryParams.setStartDate(_queryParams.getDateTimeBo().getChainStartDate()); _queryParams.setEndDate(_queryParams.getDateTimeBo().getChainEndDate()); ViewQry viewQry_mom = getViewQry(viewConfig, _queryParams); return Stream.of(viewQry, viewQry_yoy, viewQry_mom); }).collect(Collectors.toList()); // yoy // queryParams.setStartDate(queryParams.getDateTimeBo().getComparedStartDate()); // queryParams.setEndDate(queryParams.getDateTimeBo().getComparedEndDate()); // mom // queryParams.setStartDate(queryParams.getDateTimeBo().getChainStartDate()); // queryParams.setEndDate(queryParams.getDateTimeBo().getChainEndDate()); long start = System.currentTimeMillis(); List<QueryResult> queryResultList = dataProviderService.selectListView(viewQryList); Console.error(System.currentTimeMillis() - start); // 组装 QueryResultWrappers wrappers = new QueryResultWrappers(); int k = 0; for (int i = 0; i < queryResultList.size(); i++) { ViewConfig viewConfig = viewConfigList.get(i - 2 * k); QueryResultWrapper wrapper = new QueryResultWrapper(); BiQueryParams _queryParams = SerializeUtil.clone(queryParams); preProcess(viewConfig, _queryParams); QueryResult source = queryResultList.get(i); source = postProcess(source, viewConfig, _queryParams); wrapper.setSource(source); // 处理比较数据(同比、环比) if (BooleanUtil.isTrue(viewConfig.getCompareData())) { k++; QueryResult yoy = queryResultList.get(++i); yoy = postProcess(yoy, viewConfig, _queryParams); wrapper.setYoy(yoy); QueryResult mom = queryResultList.get(++i); mom = postProcess(mom, viewConfig, _queryParams); wrapper.setMom(mom); } wrappers.add(wrapper); } return wrappers; } private ViewQry getViewQry(ViewConfig viewConfig, BiQueryParams _queryParams) { // [1] 查询参数 => SQL 查询变量 String viewPath = viewConfig.getViewPath(); ViewQry viewQry = ViewQry.of(viewPath).put(_queryParams); // [2] 表名变量(yml取变量值) => 表名变量放入时,不加单引号 if (CollectionUtil.isNotEmpty(viewConfig.getTableVariable())) { TableVariable tableVariable = viewConfig.getTableVariable().get(_queryParams.getDateType()); tableVariable.forEach(viewQry::put); } // [3] 列名变量(查询参数中取变量值) => 列名变量放入时,不加单引号 _queryParams.getColumnVariable().forEach(viewQry::put); // [4] 租户变量自动填充 viewQry.putSingleQuote("tenant_id", TenantIdHolder.get()); return viewQry; } /** * 处理多个视图 * * @param viewConfigList 多个视图配置 * @param queryParams 查询参数 * @return 视图查询结果封装集 */ private QueryResultWrappers handleMultiView(List<ViewConfig> viewConfigList, BiQueryParams queryParams) { // 1、遍历 视图配置列表 // 2、异步处理 视图配置 ===> 每个视图都会被处理为 QueryResultWrapper 对象 // 3、获取异步处理结果 => 封装为 QueryResultWrappers return viewConfigList.stream() .map(e -> handleSingleViewAsync(e, queryParams)) .map(AsyncUtil::get) .collect(Collectors.toCollection(QueryResultWrappers::new)); } /** * 异步处理单个视图 * * @param tenantId 防止经销商上下文的丢失 => 异步处理时,重新 set * @param traceId 防止日志追踪id上下文的丢失 => 异步处理时,重新 set * @return 异步处理对象 => get() 阻塞获取结果 */ private CompletableFuture<QueryResultWrapper> handleSingleViewAsync(ViewConfig viewConfig, BiQueryParams queryParams) { // 0、防止经销商上下文的丢失 => 异步处理时,重新 set // 0、防止日志追踪id上下文的丢失 => 异步处理时,重新 set final String tenantId = TenantIdHolder.get(); final String traceId = MDCUtil.get(); return CompletableFuture.supplyAsync(() -> { TenantIdHolder.set(tenantId); MDCUtil.set(traceId); return handleSingleView2(viewConfig, SerializeUtil.clone(queryParams)); }); } /** * 处理单个视图 * * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 单个视图查询结果包装【查询结果,同比,环比,...】 */ private QueryResultWrapper handleSingleView(ViewConfig viewConfig, BiQueryParams queryParams) { DateTimeBo dateTimeBo = queryParams.getDateTimeBo(); QueryResultWrapper wrapper = new QueryResultWrapper(); // [1] 前置处理、视图查询、后置处理 preProcess(viewConfig, queryParams);//-------------------------------pre-前置处理 QueryResult source = viewSelect(viewConfig, queryParams);//----------视图查询 source = postProcess(source, viewConfig, queryParams);//-------------post-后置处理 wrapper.setSource(source); // [2] 处理比较数据(同比、环比) handleCompareData(wrapper, viewConfig, queryParams); return wrapper; } private QueryResultWrapper handleSingleView2(ViewConfig viewConfig, BiQueryParams queryParams) { String tenantId = TenantIdHolder.get(); String traceId = MDCUtil.get(); TenantIdHolder.set(tenantId); MDCUtil.set(traceId); DateTimeBo dateTimeBo = queryParams.getDateTimeBo(); QueryResultWrapper wrapper = new QueryResultWrapper(); CompletableFuture<Object> f1; CompletableFuture<Object> f2; CompletableFuture<Object> f3; // [1] 前置处理、视图查询、后置处理 if (1 == 1) { f1 = CompletableFuture.supplyAsync(() -> { BiQueryParams _biQueryParams = SerializeUtil.clone(queryParams); preProcess(viewConfig, _biQueryParams);//-------------------------------pre-前置处理 QueryResult source = viewSelect(viewConfig, _biQueryParams);//----------视图查询 source = postProcess(source, viewConfig, _biQueryParams);//-------------post-后置处理 wrapper.setSource(source); return null; }); } // [2] 处理比较数据(同比、环比) // handleCompareData(wrapper, viewConfig, queryParams); boolean isCompareData = BooleanUtil.isTrue(viewConfig.getCompareData()); if (2 == 2) { f2 = CompletableFuture.supplyAsync(() -> { if (isCompareData) { BiQueryParams _biQueryParams = SerializeUtil.clone(queryParams); // 2、yoy (year on year) 同比数据查询 _biQueryParams.setStartDate(dateTimeBo.getComparedStartDate()); _biQueryParams.setEndDate(dateTimeBo.getComparedEndDate()); QueryResult yoy = viewSelect(viewConfig, _biQueryParams); yoy = postProcess(yoy, viewConfig, _biQueryParams); wrapper.setYoy(yoy); } return null; }); } if (3 == 3) { f3 = CompletableFuture.supplyAsync(() -> { if (isCompareData) { BiQueryParams _biQueryParams = SerializeUtil.clone(queryParams); // 3、mon (month on month) 环比数据查询 _biQueryParams.setStartDate(dateTimeBo.getChainStartDate()); _biQueryParams.setEndDate(dateTimeBo.getChainEndDate()); QueryResult mom = viewSelect(viewConfig, _biQueryParams); mom = postProcess(mom, viewConfig, _biQueryParams); wrapper.setMom(mom); } return null; }); } AsyncUtil.waitAll(f1, f2, f3); return wrapper; } /** * 处理比较数据(同比、环比) * * @param wrapper 查询结果包装器 * @param viewConfig 视图配置 * @param queryParams 查询参数 */ private void handleCompareData(QueryResultWrapper wrapper, ViewConfig viewConfig, BiQueryParams queryParams) { // 1、未开启同环比 => 直接返回 if (!BooleanUtil.isTrue(viewConfig.getCompareData())) { return; } String startDate = queryParams.getStartDate(); String endDate = queryParams.getEndDate(); // 2、yoy (year on year) 同比数据查询 DateTimeBo dateTimeBo = queryParams.getDateTimeBo(); queryParams.setStartDate(dateTimeBo.getComparedStartDate()); queryParams.setEndDate(dateTimeBo.getComparedEndDate()); QueryResult yoy = viewSelect(viewConfig, queryParams); yoy = postProcess(yoy, viewConfig, queryParams); wrapper.setYoy(yoy); // 3、mon (month on month) 环比数据查询 queryParams.setStartDate(dateTimeBo.getChainStartDate()); queryParams.setEndDate(dateTimeBo.getChainEndDate()); QueryResult mom = viewSelect(viewConfig, queryParams); mom = postProcess(mom, viewConfig, queryParams); wrapper.setMom(mom); // 4、时间重置 => 因为上面把时间替换为了 同比/环比时间 queryParams.setStartDate(startDate); queryParams.setEndDate(endDate); } /** * 更新财年时间 * * @param queryParams 查询参数 */ private void updateFiscalTime(BiQueryParams queryParams) { // 1. 日:无需更新财年时间 if (queryParams.getDateType().isDay()) { return; } // 2. 更新财年时间 DateTimeBo dateTimeBo = queryParams.getDateTimeBo(); queryParams.setStartDate(dateTimeBo.getFiscalStartDate()); queryParams.setEndDate(dateTimeBo.getFiscalEndDate()); } /** * 视图查询(构建查询变量,feign调用 datart) * * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 视图查询结果 */ private QueryResult viewSelect(ViewConfig viewConfig, BiQueryParams queryParams) { // [1] 查询参数 => SQL 查询变量 String viewPath = viewConfig.getViewPath(); ViewQry viewQry = ViewQry.of(viewPath).put(queryParams); // [2] 表名变量(yml取变量值) => 表名变量放入时,不加单引号 if (CollectionUtil.isNotEmpty(viewConfig.getTableVariable())) { TableVariable tableVariable = viewConfig.getTableVariable().get(queryParams.getDateType()); tableVariable.forEach(viewQry::put); } // [3] 列名变量(查询参数中取变量值) => 列名变量放入时,不加单引号 queryParams.getColumnVariable().forEach(viewQry::put); // [4] 租户变量自动填充 viewQry.putSingleQuote("tenant_id", TenantIdHolder.get()); // [5] 视图查询 => feign 调用 datart 服务 return dataProviderService.selectList(viewQry); } /** * 前置处理 * * @param viewConfig 视图配置 * @param queryParams 查询参数 */ private void preProcess(ViewConfig viewConfig, BiQueryParams queryParams) { Map<String, String> preProcessors = viewConfig.getPreProcessor(); if (MapUtil.isEmpty(preProcessors)) { return; } for (Map.Entry<String, String> e : preProcessors.entrySet()) { String key = e.getKey(); String value = e.getValue(); PreProcessor preProcessor = ProcessorManager.getPreProcessor(key); Assert.notNull(preProcessor, "找不到前置处理器,bi.yml 配置有误 key=[{}]", key); preProcessor.process(viewConfig, value, queryParams); } } /** * 后置处理 * * @param queryResult 视图查询结果 * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 视图查询结果 */ private QueryResult postProcess(QueryResult queryResult, ViewConfig viewConfig, BiQueryParams queryParams) { Map<String, String> postProcessor = viewConfig.getPostProcessor(); if (MapUtil.isEmpty(postProcessor)) { return queryResult; } for (Map.Entry<String, String> e : postProcessor.entrySet()) { String key = e.getKey(); String value = e.getValue(); PostProcessor processor = ProcessorManager.getPostProcessor(key); Assert.notNull(processor, "找不到后置处理器,bi.yml 配置有误 key=[{}]", key); queryResult = processor.process(queryResult, value, queryParams); } return queryResult; } /** * 聚合处理 * * @param wrappers 视图查询结果包装集 * @param biConfig 报表配置 * @param queryParams 查询参数 * @return 视图查询结果包装集 */ private QueryResultWrappers aggProcess(QueryResultWrappers wrappers, BiConfig biConfig, BiQueryParams queryParams) { Map<String, String> aggProcessor = biConfig.getAggProcessor(); if (MapUtil.isEmpty(aggProcessor)) { return wrappers; } for (Map.Entry<String, String> e : aggProcessor.entrySet()) { String key = e.getKey(); String value = e.getValue(); AggProcessor processor = ProcessorManager.getAggProcessor(key); Assert.notNull(processor, "找不到聚合处理器,bi.yml 配置有误 key=[{}]", key); wrappers = processor.process(wrappers, value, queryParams); } return wrappers; }} 2022-08-02 18:35:38123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308package com.amoros.newbi.service.service.impl;import cn.hutool.core.collection.CollectionUtil;import cn.hutool.core.lang.Assert;import cn.hutool.core.map.MapUtil;import cn.hutool.core.thread.AsyncUtil;import cn.hutool.core.util.BooleanUtil;import cn.hutool.core.util.SerializeUtil;import com.amoros.newbi.service.context.TenantIdHolder;import com.amoros.newbi.service.dataobject.dto.DateTimeBo;import com.amoros.newbi.service.dataobject.dto.QueryResultWrapper;import com.amoros.newbi.service.dataobject.dto.QueryResultWrappers;import com.amoros.newbi.service.dataobject.properties.BiConfig;import com.amoros.newbi.service.dataobject.properties.BiReportProperties;import com.amoros.newbi.service.dataobject.properties.ViewConfig;import com.amoros.newbi.service.dataobject.qry.BiQueryParams;import com.amoros.newbi.service.dataobject.qry.BiReportQry;import com.amoros.newbi.service.processor.ProcessorManager;import com.amoros.newbi.service.processor.agg.AggProcessor;import com.amoros.newbi.service.processor.post.PostProcessor;import com.amoros.newbi.service.processor.pre.PreProcessor;import com.amoros.newbi.service.service.BiService;import com.amoros.newbi.service.util.MDCUtil;import datart.api.service.DataProviderService;import datart.api.service.custom.qry.TableVariable;import datart.api.service.custom.qry.ViewQry;import datart.api.service.custom.result.QueryResult;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.Arrays;import java.util.Date;import java.util.List;import java.util.Map;import java.util.concurrent.CompletableFuture;import java.util.function.Supplier;import java.util.stream.Collectors;@Slf4j@Servicepublic class BiServiceImpl implements BiService { @Autowired private BiReportProperties biReportProperties; @Autowired private DataProviderService dataProviderService; @Override public QueryResultWrappers biReport(BiReportQry biReportQry) { // [0] 初始化参数 String reportCode = biReportQry.getReportCode(); BiQueryParams queryParams = biReportQry.getBiQueryParams(); // [1] 正常时间 => 财年时间 updateFiscalTime(queryParams); // [2] 获取配置 reportCode => bi.yml 配置 BiConfig biConfig = biReportProperties.getConfig().get(reportCode); Assert.notNull(biConfig, "获取不到 bi 相关配置,reportCode=[{}]", reportCode); // [3] 依次处理所有视图 QueryResultWrappers wrappers = handleMultiView(biConfig.getViewConfigList(), queryParams); // [4] 所有视图处理完毕 => 聚合处理器 wrappers = aggProcess(wrappers, biConfig, queryParams); // [5] 返回结果 return wrappers; } /** * 处理多个视图 => 异步处理每一个视图配置 ↓↓↓ * * @param viewConfigList 多个视图配置 * @param queryParams 查询参数 * @return 视图查询结果封装集 */ private QueryResultWrappers handleMultiView(List<ViewConfig> viewConfigList, BiQueryParams queryParams) { // 1、遍历 视图配置列表 // 2、异步处理 视图配置 ===> 每个视图都会被处理为 QueryResultWrapper 对象 CompletableFuture<QueryResultWrapper>[] completableFutures = viewConfigList.stream() .map(viewConfig -> supplyAsync(() -> handleSingleView(viewConfig, queryParams))) .toArray(CompletableFuture[]::new); // 3、等待所有视图查询完成 AsyncUtil.waitAll(completableFutures); // 4、获取异步处理结果 => 封装为 QueryResultWrappers return Arrays.stream(completableFutures) .map(AsyncUtil::get) .collect(Collectors.toCollection(QueryResultWrappers::new)); } /** * 异步处理每一个视图配置 => 多线程处理 source、yoy、mom * * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 单个视图查询结果包装【查询结果,同比,环比,...】 */ private QueryResultWrapper handleSingleView(ViewConfig viewConfig, BiQueryParams queryParams) { QueryResultWrapper wrapper = new QueryResultWrapper(); DateTimeBo bo = queryParams.getDateTimeBo(); // [1] source 源数据查询 CompletableFuture<Void> f_source = runAsync(() -> { wrapper.setSource(handleView(viewConfig, queryParams, bo.getStartDate(), bo.getEndDate())); }); if (!BooleanUtil.isTrue(viewConfig.getCompareData())) { AsyncUtil.get(f_source); return wrapper; } /** * ↓↓↓ 同环比处理 ↓↓↓ */ // [2] yoy (year on year) 同比数据查询 CompletableFuture<Void> f_yoy = runAsync(() -> { wrapper.setYoy(handleView(viewConfig, queryParams, bo.getComparedStartDate(), bo.getComparedEndDate())); }); // [3] mon (month on month) 环比数据查询 CompletableFuture<Void> f_mom = runAsync(() -> { wrapper.setMom(handleView(viewConfig, queryParams, bo.getChainStartDate(), bo.getChainEndDate())); }); AsyncUtil.waitAll(f_source, f_yoy, f_mom);// 等待 source、yoy、mom 都处理完毕 => return return wrapper; } /** * 处理视图 => 前置处理、视图查询、后置处理 * * @param viewConfig 视图配置 * @param queryParams 查询参数 * @param startDate 开始时间 * @param endDate 结束时间 * @return 视图查询结果 */ private QueryResult handleView(ViewConfig viewConfig, BiQueryParams queryParams, Date startDate, Date endDate) { // deep clone => 防并发修改 BiQueryParams _biQueryParams = SerializeUtil.clone(queryParams); _biQueryParams.setStartDate(startDate); _biQueryParams.setEndDate(endDate); // 前置处理、视图查询、后置处理 preProcess(viewConfig, _biQueryParams); QueryResult queryResult = viewSelect(viewConfig, _biQueryParams); queryResult = postProcess(queryResult, viewConfig, _biQueryParams); return queryResult; } /** * 更新财年时间 * * @param queryParams 查询参数 */ private void updateFiscalTime(BiQueryParams queryParams) { // 1. 日:无需更新财年时间 if (queryParams.getDateType().isDay()) { return; } // 2. 更新财年时间 DateTimeBo dateTimeBo = queryParams.getDateTimeBo(); queryParams.setStartDate(dateTimeBo.getFiscalStartDate()); queryParams.setEndDate(dateTimeBo.getFiscalEndDate()); } /** * 视图查询(构建查询变量,feign调用 datart) * * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 视图查询结果 */ private QueryResult viewSelect(ViewConfig viewConfig, BiQueryParams queryParams) { // [1] 查询参数 => SQL 查询变量 String viewPath = viewConfig.getViewPath(); ViewQry viewQry = ViewQry.of(viewPath).put(queryParams); // [2] 表名变量(yml取变量值) => 表名变量放入时,不加单引号 if (CollectionUtil.isNotEmpty(viewConfig.getTableVariable())) { TableVariable tableVariable = viewConfig.getTableVariable().get(queryParams.getDateType()); tableVariable.forEach(viewQry::put); } // [3] 列名变量(查询参数中取变量值) => 列名变量放入时,不加单引号 queryParams.getColumnVariable().forEach(viewQry::put); // [4] 租户变量自动填充 viewQry.putSingleQuote("tenant_id", TenantIdHolder.get()); // [5] 视图查询 => feign 调用 datart 服务 return dataProviderService.selectList(viewQry); } /** * 前置处理 * * @param viewConfig 视图配置 * @param queryParams 查询参数 */ private void preProcess(ViewConfig viewConfig, BiQueryParams queryParams) { Map<String, String> preProcessors = viewConfig.getPreProcessor(); if (MapUtil.isEmpty(preProcessors)) { return; } for (Map.Entry<String, String> e : preProcessors.entrySet()) { String key = e.getKey(); String value = e.getValue(); PreProcessor preProcessor = ProcessorManager.getPreProcessor(key); Assert.notNull(preProcessor, "找不到前置处理器,bi.yml 配置有误 key=[{}]", key); preProcessor.process(viewConfig, value, queryParams); } } /** * 后置处理 * * @param queryResult 视图查询结果 * @param viewConfig 视图配置 * @param queryParams 查询参数 * @return 视图查询结果 */ private QueryResult postProcess(QueryResult queryResult, ViewConfig viewConfig, BiQueryParams queryParams) { Map<String, String> postProcessor = viewConfig.getPostProcessor(); if (MapUtil.isEmpty(postProcessor)) { return queryResult; } for (Map.Entry<String, String> e : postProcessor.entrySet()) { String key = e.getKey(); String value = e.getValue(); PostProcessor processor = ProcessorManager.getPostProcessor(key); Assert.notNull(processor, "找不到后置处理器,bi.yml 配置有误 key=[{}]", key); queryResult = processor.process(queryResult, value, queryParams); } return queryResult; } /** * 聚合处理 * * @param wrappers 视图查询结果包装集 * @param biConfig 报表配置 * @param queryParams 查询参数 * @return 视图查询结果包装集 */ private QueryResultWrappers aggProcess(QueryResultWrappers wrappers, BiConfig biConfig, BiQueryParams queryParams) { Map<String, String> aggProcessor = biConfig.getAggProcessor(); if (MapUtil.isEmpty(aggProcessor)) { return wrappers; } for (Map.Entry<String, String> e : aggProcessor.entrySet()) { String key = e.getKey(); String value = e.getValue(); AggProcessor processor = ProcessorManager.getAggProcessor(key); Assert.notNull(processor, "找不到聚合处理器,bi.yml 配置有误 key=[{}]", key); wrappers = processor.process(wrappers, value, queryParams); } return wrappers; } /** * 异步处理 [有返回值] */ private <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier) { // 0、防止经销商上下文的丢失 => 异步处理时,重新 set // 0、防止日志追踪id上下文的丢失 => 异步处理时,重新 set final String tenantId = TenantIdHolder.get(); final String traceId = MDCUtil.get(); return CompletableFuture.supplyAsync(() -> { TenantIdHolder.set(tenantId); MDCUtil.set(traceId); return supplier.get(); }); } /** * 异步处理 [无返回值] */ private CompletableFuture<Void> runAsync(Runnable runnable) { // 0、防止经销商上下文的丢失 => 异步处理时,重新 set // 0、防止日志追踪id上下文的丢失 => 异步处理时,重新 set final String tenantId = TenantIdHolder.get(); final String traceId = MDCUtil.get(); return CompletableFuture.runAsync(() -> { TenantIdHolder.set(tenantId); MDCUtil.set(traceId); runnable.run(); }); }}