Compare commits

..

2 Commits

Author SHA1 Message Date
6c3a2a45b3 Merge remote-tracking branch 'origin/main' 2025-03-24 10:33:23 +08:00
8627c35324 修改了代码 2025-03-24 10:33:16 +08:00

View File

@ -70,7 +70,13 @@ public class ChartDataManage {
public static final String START_END_SEPARATOR = "_START_END_SPLIT";
private static final Logger logger = LoggerFactory.getLogger(ChartDataManage.class);
/**
* 计算并生成图表数据
*
* @param view 图表视图对象包含图表配置数据集ID过滤条件等信息
* @return 处理后的图表数据对象包含计算后的数据结果和格式化信息
* @throws Exception 当数据校验失败或处理异常时抛出
*/
public ChartViewDTO calcData(ChartViewDTO view) throws Exception {
ChartExtRequest chartExtRequest = view.getChartExtRequest();
if (chartExtRequest == null) {
@ -557,33 +563,45 @@ public class ChartDataManage {
return res;
}
/**
* 根据图表视图配置和字段信息获取指定字段的数据列表
* @param view 图表视图配置对象包含图表扩展请求及字段信息
* @param fieldId 需要查询的字段唯一标识
* @param fieldType 字段类型可选值包括"xAxis""xAxisExt""extStack"
* @return 根据字段类型和数据源处理后的字段值列表去重后返回
* @throws Exception 数据查询或处理异常
*/
public List<String> getFieldData(ChartViewDTO view, Long fieldId, String fieldType) throws Exception {
ChartExtRequest requestList = view.getChartExtRequest();
List<String[]> sqlData = sqlData(view, requestList, fieldId);
List<ChartViewFieldDTO> fieldList = new ArrayList<>();
// 根据字段类型获取对应的字段集合
switch (fieldType) {
case "xAxis" -> fieldList = view.getXAxis();
case "xAxisExt" -> fieldList = view.getXAxisExt();
case "extStack" -> fieldList = view.getExtStack();
}
// 通过ID查询字段信息
DatasetTableFieldDTO field = datasetTableFieldManage.selectById(fieldId);
List<String> res = new ArrayList<>();
if (ObjectUtils.isNotEmpty(field) && fieldList.size() > 0) {
// 找到对应维度
// 遍历字段列表确定当前字段及自定义排序字段的位置
ChartViewFieldDTO chartViewFieldDTO = null;
int index = 0;
int getIndex = 0;
for (int i = 0; i < fieldList.size(); i++) {
ChartViewFieldDTO item = fieldList.get(i);
if (StringUtils.equalsIgnoreCase(item.getSort(), "custom_sort")) {// 此处与已有的自定义字段对比
if (StringUtils.equalsIgnoreCase(item.getSort(), "custom_sort")) {
chartViewFieldDTO = item;
index = i;
}
if (Objects.equals(item.getId(), field.getId())) {// 获得当前自定义的字段
if (Objects.equals(item.getId(), field.getId())) {
getIndex = i;
}
}
// 根据字段类型调整索引偏移量
if (StringUtils.equalsIgnoreCase(fieldType, "xAxisExt")) {
List<ChartViewFieldDTO> xAxis = view.getXAxis();
index += xAxis.size();
@ -596,15 +614,16 @@ public class ChartDataManage {
getIndex += xAxisSize + extSize;
}
// 执行自定义排序后的数据结果
List<String[]> sortResult = resultCustomSort(fieldList, sqlData);
if (ObjectUtils.isNotEmpty(chartViewFieldDTO) && (getIndex >= index)) {
// 获取自定义值与data对应列的结果
// 使用自定义排序规则提取对应列数据
List<String[]> strings = customSort(Optional.ofNullable(chartViewFieldDTO.getCustomSort()).orElse(new ArrayList<>()), sortResult, index);
for (int i = 0; i < strings.size(); i++) {
res.add(strings.get(i)[getIndex]);
}
} else {
// 返回请求结果
// 直接提取原始排序结果中的对应列数据
for (int i = 0; i < sortResult.size(); i++) {
res.add(sortResult.get(i)[getIndex]);
}
@ -613,22 +632,32 @@ public class ChartDataManage {
return res.stream().distinct().collect(Collectors.toList());
}
/**
* 根据图表配置生成并执行SQL查询返回数据结果集
* @param view 图表配置对象包含图表类型轴配置等信息
* @param requestList 图表扩展请求参数
* @param fieldId 字段标识ID
* @return 查询结果数据列表每个元素代表一行数据
* @throws Exception 数据处理或权限验证异常
*/
public List<String[]> sqlData(ChartViewDTO view, ChartExtRequest requestList, Long fieldId) throws Exception {
if (ObjectUtils.isEmpty(view)) {
DEException.throwException(Translator.get("i18n_chart_delete"));
}
// get all fields
// 获取图表所有字段配置
List<ChartViewFieldDTO> allFields = getAllChartFields(view);
// 针对分组切换堆叠时会遇到的问题
// 处理堆叠/分组图表的特殊x轴配置
if (StringUtils.equalsIgnoreCase(view.getType(), "bar-stack") || StringUtils.equalsIgnoreCase(view.getType(), "chart-mix-stack")) {
view.setXAxisExt(new ArrayList<>());
}
// 初始化基础轴配置
List<ChartViewFieldDTO> xAxisBase = new ArrayList<>(view.getXAxis());
List<ChartViewFieldDTO> xAxis = new ArrayList<>(view.getXAxis());
List<ChartViewFieldDTO> xAxisExt = new ArrayList<>(view.getXAxisExt());
// 合并扩展x轴配置针对特定图表类型
if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot")
|| StringUtils.containsIgnoreCase(view.getType(), "group")
|| ("antv".equalsIgnoreCase(view.getRender()) && "line".equalsIgnoreCase(view.getType()))
@ -639,30 +668,31 @@ public class ChartDataManage {
xAxis.addAll(xAxisExt);
}
List<ChartViewFieldDTO> yAxis = new ArrayList<>(view.getYAxis());
// 合并扩展y轴配置针对混合图表类型
if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) {
List<ChartViewFieldDTO> yAxisExt = new ArrayList<>(view.getYAxisExt());
yAxis.addAll(yAxisExt);
}
// 处理仪表盘类型特殊配置
if (StringUtils.equalsIgnoreCase(view.getRender(), "antv") && StringUtils.equalsAnyIgnoreCase(view.getType(), "gauge", "liquid")) {
List<ChartViewFieldDTO> sizeField = getSizeField(view);
yAxis.addAll(sizeField);
}
List<ChartViewFieldDTO> extStack = new ArrayList<>(view.getExtStack());
List<ChartViewFieldDTO> extBubble = new ArrayList<>(view.getExtBubble());
FilterTreeObj fieldCustomFilter = view.getCustomFilter();
List<ChartViewFieldDTO> drill = new ArrayList<>(view.getDrillFields());
// 获取数据集,需校验权限
// 获取数据集权限信息
DatasetGroupInfoDTO table = datasetGroupManage.getDatasetGroupInfoDTO(view.getTableId(), null);
Map<String, ColumnPermissionItem> desensitizationList = new HashMap<>();
List<DataSetRowPermissionsTreeDTO> rowPermissionsTree = permissionManage.getRowPermissionsTree(table.getId(), view.getChartExtRequest().getUser());
chartFilterTreeService.searchFieldAndSet(fieldCustomFilter);
// 处理自定义过滤条件
chartFilterTreeService.searchFieldAndSet(view.getCustomFilter());
// 空值校验当x/y轴都为空时直接返回空结果
if (ObjectUtils.isEmpty(xAxis) && ObjectUtils.isEmpty(yAxis)) {
return new ArrayList<String[]>();
}
// 特殊图表类型配置调整
switch (view.getType()) {
case "label":
yAxis = new ArrayList<>();
@ -685,7 +715,6 @@ public class ChartDataManage {
}
break;
case "table-normal":
break;
case "bar-group":
case "bar-group-stack":
case "flow-map":
@ -693,7 +722,7 @@ public class ChartDataManage {
default:
}
// 获取dsMap,union sql
// 生成联合查询SQL并处理数据源信息
Map<String, Object> sqlMap = datasetSQLManage.getUnionSQLForEdit(table, null);
String sql = (String) sqlMap.get("sql");
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
@ -707,10 +736,11 @@ public class ChartDataManage {
sql = Utils.replaceSchemaAlias(sql, dsMap);
}
// 调用数据源的calcite获得data
// 初始化数据源请求对象
DatasourceRequest datasourceRequest = new DatasourceRequest();
datasourceRequest.setDsList(dsMap);
// 根据数据源类型选择查询提供器
Provider provider;
if (crossDs) {
provider = ProviderFactory.getDefaultProvider();
@ -718,14 +748,14 @@ public class ChartDataManage {
provider = ProviderFactory.getProvider(dsMap.entrySet().iterator().next().getValue().getType());
}
// 执行数据查询
List<String[]> data = new ArrayList<>();
String querySql = null;
//如果不是插件图表 走原生逻辑
if (table.getMode() == 0) {// 直连
if (table.getMode() == 0) { // 直连模式处理
if (ObjectUtils.isEmpty(dsMap)) {
DEException.throwException(Translator.get("i18n_datasource_delete"));
}
// 数据源状态校验
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
DatasourceSchemaDTO ds = next.getValue();
if (StringUtils.isNotEmpty(ds.getStatus()) && "Error".equalsIgnoreCase(ds.getStatus())) {
@ -733,24 +763,26 @@ public class ChartDataManage {
}
}
// 构建SQL元数据并生成最终查询语句
SQLMeta sqlMeta = new SQLMeta();
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs);
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
// 根据图表类型生成不同SQL逻辑
if (StringUtils.equalsAnyIgnoreCase(view.getType(), "indicator", "gauge", "liquid")) {
Quota2SQLObj.quota2sqlObj(sqlMeta, yAxis, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
} else if (StringUtils.containsIgnoreCase(view.getType(), "stack")) {
List<ChartViewFieldDTO> xFields = new ArrayList<>();
xFields.addAll(xAxis);
xFields.addAll(extStack);
xFields.addAll(view.getExtStack());
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xFields, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
Quota2SQLObj.quota2sqlObj(sqlMeta, yAxis, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
} else if (StringUtils.containsIgnoreCase(view.getType(), "scatter")) {
List<ChartViewFieldDTO> yFields = new ArrayList<>();
yFields.addAll(yAxis);
yFields.addAll(extBubble);
yFields.addAll(view.getExtBubble());
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
Quota2SQLObj.quota2sqlObj(sqlMeta, yFields, transFields(allFields), crossDs, dsMap, Utils.getParams(transFields(allFields)), view.getCalParams(), pluginManage);
querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
@ -772,6 +804,7 @@ public class ChartDataManage {
return data;
}
private List<ChartViewFieldDTO> getAllChartFields(ChartViewDTO view) {
// get all fields
Map<String, List<ChartViewFieldDTO>> stringListMap = chartViewManege.listByDQ(view.getTableId(), view.getId(), view);
@ -783,30 +816,52 @@ public class ChartDataManage {
return allFields.stream().filter(ele -> ele.getId() != -1L).collect(Collectors.toList());
}
/**
* 根据检查数据保存图表视图并标记废弃的图表视图
*
* @param checkData 包含需要保留的图表ID的字符串通常为逗号分隔格式
* @param sceneId 图表视图关联的场景ID
* @param chartViewsInfo 包含图表视图信息的映射键为ID值为ChartViewDTO对象
*/
public void saveChartViewFromVisualization(String checkData, Long sceneId, Map<Long, ChartViewDTO> chartViewsInfo) {
if (!MapUtils.isEmpty(chartViewsInfo)) {
List<Long> disuseChartIdList = new ArrayList<>();
// 遍历所有图表视图信息判断是否需要保存或标记为废弃
chartViewsInfo.forEach((key, chartViewDTO) -> {
if (checkData.contains(chartViewDTO.getId() + "")) {
try {
// 如果当前图表ID存在于检查数据中则更新场景ID并保存
chartViewDTO.setSceneId(sceneId);
chartViewManege.save(chartViewDTO);
} catch (Exception e) {
DEException.throwException(e);
}
} else {
// 如果当前图表ID未存在于检查数据中则记录为废弃ID
disuseChartIdList.add(chartViewDTO.getId());
}
});
// 如果存在需要废弃的图表ID列表则批量标记为废弃
if (CollectionUtils.isNotEmpty(disuseChartIdList)) {
chartViewManege.disuse(disuseChartIdList);
}
}
}
/**
* 根据图表视图和字段ID获取钻取字段的数据列表
*
* @param view 图表视图的数据传输对象包含钻取字段等配置信息
* @param fieldId 需要查询的字段ID
* @return 匹配字段ID的数据列表若未找到字段则返回空列表
* @throws Exception 可能抛出的异常具体类型需根据实际业务场景确定
*/
public List<String> getDrillFieldData(ChartViewDTO view, Long fieldId) throws Exception {
List<ChartViewFieldDTO> drillField = view.getDrillFields();
ChartViewFieldDTO targetField = null;
// 查找匹配的钻取字段
for (int i = 0; i < drillField.size(); i++) {
ChartViewFieldDTO tmp = drillField.get(i);
if (tmp.getId().equals(fieldId)) {
@ -814,13 +869,29 @@ public class ChartDataManage {
break;
}
}
if (targetField == null) {
return Collections.emptyList();
}
// 设置X轴为当前目标字段
view.setXAxis(Collections.singletonList(targetField));
// 执行SQL查询获取原始数据
List<String[]> sqlData = sqlData(view, view.getChartExtRequest(), fieldId);
List<String[]> result = customSort(Optional.ofNullable(targetField.getCustomSort()).orElse(new ArrayList<>()), sqlData, 0);
return result.stream().map(i -> i[0]).distinct().collect(Collectors.toList());
// 根据自定义排序规则对数据进行排序
List<String[]> result = customSort(
Optional.ofNullable(targetField.getCustomSort()).orElse(new ArrayList<>()),
sqlData,
0
);
// 提取第一列数据并去重生成最终结果列表
return result.stream()
.map(i -> i[0])
.distinct()
.collect(Collectors.toList());
}
}