diff --git a/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java b/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java index 3e5d0ddc25..0f1a1971a2 100644 --- a/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java +++ b/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java @@ -25,7 +25,7 @@ public class MybatisPlusGenerator { /** * 这是要生成代码的表名称 */ - private static final String TABLE_NAME = "visualization_report_filter"; + private static final String TABLE_NAME = "visualization_outer_params_target_view_info"; /** * 下面两个配置基本上不用动 diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numeric/IndicatorHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numeric/IndicatorHandler.java index e39125fcb5..8ff6b8c71d 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numeric/IndicatorHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numeric/IndicatorHandler.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; +import java.util.Objects; @Component public class IndicatorHandler extends YoyChartHandler { @@ -36,23 +37,19 @@ public class IndicatorHandler extends YoyChartHandler { var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis); var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); var allFields = (List) filterResult.getContext().get("allFields"); - ChartViewFieldDTO chartViewFieldDTO = yAxis.get(0); - ChartFieldCompareDTO compareCalc = chartViewFieldDTO.getCompareCalc(); + ChartViewFieldDTO yAxisChartViewFieldDTO = yAxis.get(0); + ChartFieldCompareDTO compareCalc = yAxisChartViewFieldDTO.getCompareCalc(); boolean isYoy = org.apache.commons.lang3.StringUtils.isNotEmpty(compareCalc.getType()) && !org.apache.commons.lang3.StringUtils.equalsIgnoreCase(compareCalc.getType(), "none"); if (isYoy) { xAxis.clear(); // 设置维度字段,从同环比中获取用户选择的字段 - xAxis.addAll(allFields.stream().filter(i -> org.springframework.util.StringUtils.endsWithIgnoreCase(i.getId().toString(), yAxis.get(0).getCompareCalc().getField().toString())).toList()); + xAxis.addAll(allFields.stream().filter(i -> org.springframework.util.StringUtils.endsWithIgnoreCase(i.getId().toString(), compareCalc.getField().toString())).toList()); xAxis.get(0).setSort("desc"); - if (org.springframework.util.StringUtils.endsWithIgnoreCase("month_mom", compareCalc.getType())) { - xAxis.get(0).setDateStyle("y_M"); - } - if (org.springframework.util.StringUtils.endsWithIgnoreCase("day_mom", compareCalc.getType())) { + if(Objects.isNull(compareCalc.getCustom())){ xAxis.get(0).setDateStyle("y_M_d"); - } - if (org.springframework.util.StringUtils.endsWithIgnoreCase("year_mom", compareCalc.getType())) { - xAxis.get(0).setDateStyle("y"); + }else{ + xAxis.get(0).setDateStyle(compareCalc.getCustom().getTimeType()); } } formatResult.getAxisMap().put(ChartAxis.xAxis, xAxis); diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableHeatmapHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableHeatmapHandler.java new file mode 100644 index 0000000000..f33ea05d1a --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableHeatmapHandler.java @@ -0,0 +1,86 @@ +package io.dataease.chart.charts.impl.table; + +import io.dataease.chart.charts.impl.DefaultChartHandler; +import io.dataease.chart.utils.ChartDataBuild; +import io.dataease.engine.sql.SQLProvider; +import io.dataease.engine.trans.Dimension2SQLObj; +import io.dataease.engine.trans.Quota2SQLObj; +import io.dataease.engine.utils.Utils; +import io.dataease.extensions.datasource.dto.DatasourceRequest; +import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO; +import io.dataease.extensions.datasource.model.SQLMeta; +import io.dataease.extensions.datasource.provider.Provider; +import io.dataease.extensions.view.dto.*; +import io.dataease.extensions.view.util.ChartDataUtil; +import io.dataease.extensions.view.util.FieldUtil; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Component +public class TableHeatmapHandler extends DefaultChartHandler { + + @Getter + private String type = "t-heatmap"; + + @Override + public AxisFormatResult formatAxis(ChartViewDTO view) { + var result = super.formatAxis(view); + var xAxis = new ArrayList(view.getXAxis()); + xAxis.addAll(view.getXAxisExt()); + xAxis.addAll(view.getExtColor()); + result.getAxisMap().put(ChartAxis.xAxis, xAxis); + return result; + } + + public Map buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List data) { + var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis); + Map result = ChartDataBuild.transChartData( xAxis, new ArrayList<>(), view, data, false); + return result; + } + + @Override + public T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, Provider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry next : dsMap.entrySet()) { + dsList.add(next.getValue().getType()); + } + boolean needOrder = Utils.isNeedOrder(dsList); + boolean crossDs = Utils.isCrossDs(dsMap); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDsList(dsMap); + var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis); + var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); + List yFields = new ArrayList<>(); + yFields.addAll(chartViewManege.transFieldDTO(Collections.singletonList(chartViewManege.createCountField(view.getTableId())))); + yAxis.addAll(yFields); + xAxis = xAxis.stream().filter(i-> !StringUtils.equalsIgnoreCase(i.getDataeaseName(),yAxis.get(0).getDataeaseName())).toList(); + var allFields = (List) filterResult.getContext().get("allFields"); + Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, FieldUtil.transFields(allFields), crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage); + Quota2SQLObj.quota2sqlObj(sqlMeta, yAxis, FieldUtil.transFields(allFields), crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage); + String querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view); + querySql = provider.rebuildSQL(querySql, sqlMeta, crossDs, dsMap); + datasourceRequest.setQuery(querySql); + logger.debug("calcite chart sql: " + querySql); + List data = (List) provider.fetchResultField(datasourceRequest).get("data"); + //自定义排序 + data = ChartDataUtil.resultCustomSort(xAxis, data); + //数据重组逻辑可重载 + var result = this.buildResult(view, formatResult, filterResult, data); + T calcResult = (T) new ChartCalcDataResult(); + calcResult.setData(result); + calcResult.setContext(filterResult.getContext()); + calcResult.setQuerySql(querySql); + calcResult.setOriginData(data); + return calcResult; + } + +} + + diff --git a/core/core-backend/src/main/java/io/dataease/chart/dao/auto/entity/CoreChartView.java b/core/core-backend/src/main/java/io/dataease/chart/dao/auto/entity/CoreChartView.java index a3444089e9..7b35082b79 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/dao/auto/entity/CoreChartView.java +++ b/core/core-backend/src/main/java/io/dataease/chart/dao/auto/entity/CoreChartView.java @@ -137,7 +137,7 @@ public class CoreChartView implements Serializable { private Long updateTime; /** - * 缩略图 + * 缩略图 */ private String snapshot; @@ -206,6 +206,16 @@ public class CoreChartView implements Serializable { */ private Boolean aggregate; + private String flowMapStartName; + + private String flowMapEndName; + + /** + * 颜色维度field + */ + private String extColor; + + public Long getId() { return id; } @@ -510,6 +520,30 @@ public class CoreChartView implements Serializable { this.aggregate = aggregate; } + public String getFlowMapStartName() { + return flowMapStartName; + } + + public void setFlowMapStartName(String flowMapStartName) { + this.flowMapStartName = flowMapStartName; + } + + public String getFlowMapEndName() { + return flowMapEndName; + } + + public void setFlowMapEndName(String flowMapEndName) { + this.flowMapEndName = flowMapEndName; + } + + public String getExtColor() { + return extColor; + } + + public void setExtColor(String extColor) { + this.extColor = extColor; + } + @Override public String toString() { return "CoreChartView{" + @@ -551,6 +585,9 @@ public class CoreChartView implements Serializable { ", copyFrom = " + copyFrom + ", copyId = " + copyId + ", aggregate = " + aggregate + + ", flowMapStartName=" + flowMapStartName + + ", flowMapEndName=" + flowMapEndName + + ", extColor=" + extColor + "}"; } } diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java index 1c3158f6f8..4e4d8a9c2c 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java @@ -144,6 +144,7 @@ public class ChartDataManage { // 过滤来自仪表板的条件 List extFilterList = new ArrayList<>(); //组件过滤条件 + List sqlVariables = datasetGroupManage.getSqlParams(Collections.singletonList(view.getTableId())); if (ObjectUtils.isNotEmpty(chartExtRequest.getFilter())) { for (ChartExtFilterDTO request : chartExtRequest.getFilter()) { // 解析多个fieldId,fieldId是一个逗号分隔的字符串 @@ -153,7 +154,6 @@ public class ChartDataManage { } boolean hasParameters = false; - List sqlVariables = datasetGroupManage.getSqlParams(Collections.singletonList(view.getTableId())); if (CollectionUtils.isNotEmpty(sqlVariables)) { for (SqlVariableDetails parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) { String parameterId = StringUtils.endsWith(parameter.getId(), START_END_SEPARATOR) ? parameter.getId().split(START_END_SEPARATOR)[0] : parameter.getId(); @@ -234,18 +234,35 @@ public class ChartDataManage { //联动过滤条件和外部参数过滤条件全部加上 if (ObjectUtils.isNotEmpty(filters)) { for (ChartExtFilterDTO request : filters) { - DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(Long.valueOf(request.getFieldId())); - request.setDatasetTableField(datasetTableField); - request.setFilterType(2); - // 相同数据集 - if (Objects.equals(datasetTableField.getDatasetGroupId(), view.getTableId())) { - if (ObjectUtils.isNotEmpty(request.getViewIds())) { - if (request.getViewIds().contains(view.getId())) { + // 包含 DE 的为数据集参数 + if(request.getFieldId().contains("DE")){ + // 组装sql 参数原始数据 + if (CollectionUtils.isNotEmpty(sqlVariables)) { + for(SqlVariableDetails sourceVariables : sqlVariables){ + if(sourceVariables.getId().equals(request.getFieldId())){ + if(CollectionUtils.isEmpty(request.getParameters())){ + request.setParameters(new ArrayList<>()); + } + request.getParameters().add(sourceVariables); + } + } + + } + }else { + DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(Long.valueOf(request.getFieldId())); + request.setDatasetTableField(datasetTableField); + request.setFilterType(2); + // 相同数据集 + if (Objects.equals(datasetTableField.getDatasetGroupId(), view.getTableId())) { + if (ObjectUtils.isNotEmpty(request.getViewIds())) { + if (request.getViewIds().contains(view.getId())) { + extFilterList.add(request); + } + } else { extFilterList.add(request); } - } else { - extFilterList.add(request); } + } } } @@ -604,7 +621,8 @@ public class ChartDataManage { if (StringUtils.equalsIgnoreCase(view.getType(), "table-pivot") || StringUtils.containsIgnoreCase(view.getType(), "group") || ("antv".equalsIgnoreCase(view.getRender()) && "line".equalsIgnoreCase(view.getType())) - || StringUtils.equalsIgnoreCase(view.getType(), "flow-map")) { + || StringUtils.equalsIgnoreCase(view.getType(), "flow-map") + || StringUtils.equalsIgnoreCase(view.getType(), "t-heatmap")) { xAxis.addAll(xAxisExt); } List yAxis = new ArrayList<>(view.getYAxis()); @@ -754,16 +772,22 @@ public class ChartDataManage { public void saveChartViewFromVisualization(String checkData, Long sceneId, Map chartViewsInfo) { if (!MapUtils.isEmpty(chartViewsInfo)) { + List disuseChartIdList = new ArrayList<>(); chartViewsInfo.forEach((key, chartViewDTO) -> { - if (checkData.indexOf(chartViewDTO.getId() + "") > -1) { + if (checkData.contains(chartViewDTO.getId() + "")) { try { chartViewDTO.setSceneId(sceneId); chartViewManege.save(chartViewDTO); } catch (Exception e) { DEException.throwException(e); } + } else { + disuseChartIdList.add(chartViewDTO.getId()); } }); + if (CollectionUtils.isNotEmpty(disuseChartIdList)) { + chartViewManege.disuse(disuseChartIdList); + } } } } diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java index fbba49ec89..7fe8b9576f 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java @@ -26,6 +26,7 @@ import io.dataease.extensions.datasource.model.SQLObj; import io.dataease.extensions.view.dto.*; import io.dataease.extensions.view.filter.FilterTreeObj; import io.dataease.i18n.Translator; +import io.dataease.license.config.XpackInteract; import io.dataease.utils.BeanUtils; import io.dataease.utils.IDUtils; import io.dataease.utils.JsonUtil; @@ -98,6 +99,9 @@ public class ChartViewManege { coreChartViewMapper.deleteById(id); } + @XpackInteract(value = "chartViewManage") + public void disuse(List chartIdList) {} + @Transactional public void deleteBySceneId(Long sceneId, List chartIds) { QueryWrapper wrapper = new QueryWrapper<>(); @@ -252,6 +256,7 @@ public class ChartViewManege { public ChartBaseVO chartBaseInfo(Long id) { ChartBasePO po = extChartViewMapper.queryChart(id); + if (ObjectUtils.isEmpty(po)) return null; ChartBaseVO vo = BeanUtils.copyBean(new ChartBaseVO(), po); TypeReference> tokenType = new TypeReference<>() {}; vo.setXAxis(JsonUtil.parseList(po.getXAxis(), tokenType)); @@ -324,6 +329,9 @@ public class ChartViewManege { record.setDrillFields(objectMapper.writeValueAsString(dto.getDrillFields())); record.setCustomFilter(objectMapper.writeValueAsString(dto.getCustomFilter())); record.setViewFields(objectMapper.writeValueAsString(dto.getViewFields())); + record.setFlowMapStartName(objectMapper.writeValueAsString(dto.getFlowMapStartName())); + record.setFlowMapEndName(objectMapper.writeValueAsString(dto.getFlowMapEndName())); + record.setExtColor(objectMapper.writeValueAsString(dto.getExtColor())); return record; } @@ -349,6 +357,9 @@ public class ChartViewManege { dto.setDrillFields(JsonUtil.parseList(record.getDrillFields(), tokenType)); dto.setCustomFilter(JsonUtil.parseObject(record.getCustomFilter(), FilterTreeObj.class)); dto.setViewFields(JsonUtil.parseList(record.getViewFields(), tokenType)); + dto.setFlowMapStartName(JsonUtil.parseList(record.getFlowMapStartName(), tokenType)); + dto.setFlowMapEndName(JsonUtil.parseList(record.getFlowMapEndName(), tokenType)); + dto.setExtColor(JsonUtil.parseList(record.getExtColor(), tokenType)); return dto; diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java index bb09b35534..3715efd527 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java @@ -112,7 +112,8 @@ public class DatasetDataManage { sql = provider.transSqlDialect(sql, datasourceRequest.getDsList()); } else { // parser sql params and replace default value - String originSql = SqlparserUtils.handleVariableDefaultValue(new String(Base64.getDecoder().decode(tableInfoDTO.getSql())), datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage); + String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(tableInfoDTO.getSql()))); + originSql = SqlparserUtils.handleVariableDefaultValue(originSql, datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage); // add sql table schema sql = SQLUtils.buildOriginPreviewSql(SqlPlaceholderConstants.TABLE_PLACEHOLDER, 0, 0); @@ -344,13 +345,16 @@ public class DatasetDataManage { dsMap.put(datasourceSchemaDTO.getId(), datasourceSchemaDTO); DatasourceRequest datasourceRequest = new DatasourceRequest(); datasourceRequest.setDsList(dsMap); + Provider provider = ProviderFactory.getProvider(datasourceSchemaDTO.getType()); // parser sql params and replace default value - String originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(new String(Base64.getDecoder().decode(dto.getSql()))), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage); + + String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(dto.getSql()))); + originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(originSql), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage); // sql 作为临时表,外层加上limit String sql; - Provider provider = ProviderFactory.getProvider(datasourceSchemaDTO.getType()); + if (Utils.isNeedOrder(List.of(datasourceSchemaDTO.getType()))) { // 先根据sql获取表字段 String sqlField = SQLUtils.buildOriginPreviewSql(SqlPlaceholderConstants.TABLE_PLACEHOLDER, 0, 0); diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java index 62069e2157..70549c206e 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java @@ -19,7 +19,9 @@ import io.dataease.extensions.datasource.dto.DatasetTableDTO; import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO; import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO; import io.dataease.extensions.datasource.dto.DsTypeDTO; +import io.dataease.extensions.datasource.factory.ProviderFactory; import io.dataease.extensions.datasource.model.SQLObj; +import io.dataease.extensions.datasource.provider.Provider; import io.dataease.extensions.datasource.vo.DatasourceConfiguration; import io.dataease.extensions.datasource.vo.XpackPluginsDatasourceVO; import io.dataease.extensions.view.dto.ChartExtFilterDTO; @@ -64,25 +66,37 @@ public class DatasetSQLManage { private List filterParameters(ChartExtRequest chartExtRequest, Long datasetTableId) { List parameters = new ArrayList<>(); + if (chartExtRequest != null && ObjectUtils.isNotEmpty(chartExtRequest.getOuterParamsFilters())) { + for (ChartExtFilterDTO filterDTO : chartExtRequest.getOuterParamsFilters()) { + if (CollectionUtils.isEmpty(filterDTO.getValue())) { + continue; + } + filterParametersAdaptor(parameters,filterDTO,datasetTableId); + } + } if (chartExtRequest != null && ObjectUtils.isNotEmpty(chartExtRequest.getFilter())) { for (ChartExtFilterDTO filterDTO : chartExtRequest.getFilter()) { if (CollectionUtils.isEmpty(filterDTO.getValue())) { continue; } - if (ObjectUtils.isNotEmpty(filterDTO.getParameters())) { - for (SqlVariableDetails parameter : filterDTO.getParameters()) { - if (parameter.getDatasetTableId().equals(datasetTableId)) { - parameter.setValue(filterDTO.getValue()); - parameter.setOperator(filterDTO.getOperator()); - parameters.add(parameter); - } - } - } + filterParametersAdaptor(parameters,filterDTO,datasetTableId); } } return parameters; } + private void filterParametersAdaptor(List parameters,ChartExtFilterDTO filterDTO,Long datasetTableId){ + if (ObjectUtils.isNotEmpty(filterDTO.getParameters())) { + for (SqlVariableDetails parameter : filterDTO.getParameters()) { + if (parameter.getDatasetTableId().equals(datasetTableId)) { + parameter.setValue(filterDTO.getValue()); + parameter.setOperator(filterDTO.getOperator()); + parameters.add(parameter); + } + } + } + } + public Map getUnionSQLForEdit(DatasetGroupInfoDTO dataTableInfoDTO, ChartExtRequest chartExtRequest) throws Exception { Map dsMap = new LinkedHashMap<>(); List union = dataTableInfoDTO.getUnion(); @@ -430,8 +444,10 @@ public class DatasetSQLManage { if (StringUtils.equalsIgnoreCase(currentDs.getType(), DatasetTableTypeConstants.DATASET_TABLE_DB)) { tableObj = SQLObj.builder().tableSchema(tableSchema).tableName(infoDTO.getTable()).tableAlias(tableAlias).build(); } else if (StringUtils.equalsIgnoreCase(currentDs.getType(), DatasetTableTypeConstants.DATASET_TABLE_SQL)) { + Provider provider = ProviderFactory.getProvider(dsMap.entrySet().iterator().next().getValue().getType()); // parser sql params and replace default value - String sql = SqlparserUtils.handleVariableDefaultValue(new String(Base64.getDecoder().decode(infoDTO.getSql())), currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage); + String sql = provider.replaceComment(new String(Base64.getDecoder().decode(infoDTO.getSql()))); + sql = SqlparserUtils.handleVariableDefaultValue(sql, currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage); // add table schema if (isCross) { sql = SqlUtils.addSchema(sql, tableSchema); diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java index 45a7a28ea3..48f09f941d 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/CalciteProvider.java @@ -382,7 +382,7 @@ public class CalciteProvider extends Provider { // schema ResultSet resultSet = null; - try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery(), datasourceRequest.getTableFieldWithValues())) { if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -390,12 +390,13 @@ public class CalciteProvider extends Provider { if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) { LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery()); for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) { - statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); + ((PreparedStatement) statement).setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue()); } + resultSet = ((PreparedStatement) statement).executeQuery(); + } else { + resultSet = statement.executeQuery(datasourceRequest.getQuery()); } - - resultSet = statement.executeQuery(); fieldList = getField(resultSet, datasourceRequest); dataList = getData(resultSet, datasourceRequest); } catch (SQLException e) { @@ -426,7 +427,7 @@ public class CalciteProvider extends Provider { // schema ResultSet resultSet = null; - try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery(), datasourceRequest.getTableFieldWithValues())) { if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -434,13 +435,14 @@ public class CalciteProvider extends Provider { if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) { LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery()); for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) { - statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); + ((PreparedStatement) statement).setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue()); } + ((PreparedStatement) statement).execute(); + } else { + statement.execute(datasourceRequest.getQuery()); } - statement.execute(); - } catch (SQLException e) { DEException.throwException("SQL ERROR: " + e.getMessage()); } catch (Exception e) { @@ -465,7 +467,7 @@ public class CalciteProvider extends Provider { // schema ResultSet resultSet = null; - try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); PreparedStatement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery())) { + try (ConnectionObj con = getConnection(datasourceRequest.getDatasource()); Statement statement = getPreparedStatement(con.getConnection(), datasourceConfiguration.getQueryTimeout(), datasourceRequest.getQuery(), datasourceRequest.getTableFieldWithValues())) { if (DatasourceConfiguration.DatasourceType.valueOf(value.getType()) == DatasourceConfiguration.DatasourceType.oracle) { statement.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA = " + datasourceConfiguration.getSchema()); } @@ -473,13 +475,14 @@ public class CalciteProvider extends Provider { if (CollectionUtils.isNotEmpty(datasourceRequest.getTableFieldWithValues())) { LogUtil.info("execWithPreparedStatement sql: " + datasourceRequest.getQuery()); for (int i = 0; i < datasourceRequest.getTableFieldWithValues().size(); i++) { - statement.setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); + ((PreparedStatement) statement).setObject(i + 1, datasourceRequest.getTableFieldWithValues().get(i).getValue(), datasourceRequest.getTableFieldWithValues().get(i).getType()); LogUtil.info("execWithPreparedStatement param[" + (i + 1) + "]: " + datasourceRequest.getTableFieldWithValues().get(i).getValue()); } + return ((PreparedStatement) statement).executeUpdate(); + } else { + return statement.executeUpdate(datasourceRequest.getQuery()); } - return statement.executeUpdate(); - } catch (SQLException e) { DEException.throwException("SQL ERROR: " + e.getMessage()); } catch (Exception e) { @@ -1158,16 +1161,22 @@ public class CalciteProvider extends Provider { return stat; } - public PreparedStatement getPreparedStatement(Connection connection, int queryTimeout, String sql) throws Exception { + public Statement getPreparedStatement(Connection connection, int queryTimeout, String sql, List values) throws Exception { if (connection == null) { throw new Exception("Failed to get connection!"); } - PreparedStatement stat = connection.prepareStatement(sql); - try { - stat.setQueryTimeout(queryTimeout); - } catch (Exception e) { + if (CollectionUtils.isNotEmpty(values)) { + PreparedStatement stat = null; + try { + stat = connection.prepareStatement(sql); + stat.setQueryTimeout(queryTimeout); + } catch (Exception e) { + DEException.throwException(e.getMessage()); + } + return stat; + } else { + return getStatement(connection, queryTimeout); } - return stat; } protected boolean isDefaultClassLoader(String customDriver) { diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationOuterParamsTargetViewInfo.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationOuterParamsTargetViewInfo.java index 393127f6f2..e36f2ea50f 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationOuterParamsTargetViewInfo.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationOuterParamsTargetViewInfo.java @@ -1,5 +1,6 @@ package io.dataease.visualization.dao.auto.entity; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; @@ -9,7 +10,7 @@ import java.io.Serializable; *

* * @author fit2cloud - * @since 2024-03-08 + * @since 2024-08-21 */ @TableName("visualization_outer_params_target_view_info") public class VisualizationOuterParamsTargetViewInfo implements Serializable { @@ -19,6 +20,7 @@ public class VisualizationOuterParamsTargetViewInfo implements Serializable { /** * 主键 */ + @TableId("target_id") private String targetId; /** @@ -27,10 +29,15 @@ public class VisualizationOuterParamsTargetViewInfo implements Serializable { private String paramsInfoId; /** - * 联动视图ID + * 联动视图ID/联动过滤项ID */ private String targetViewId; + /** + * 联动数据集id/联动过滤组件id + */ + private String targetDsId; + /** * 联动字段ID */ @@ -70,6 +77,14 @@ public class VisualizationOuterParamsTargetViewInfo implements Serializable { this.targetViewId = targetViewId; } + public String getTargetDsId() { + return targetDsId; + } + + public void setTargetDsId(String targetDsId) { + this.targetDsId = targetDsId; + } + public String getTargetFieldId() { return targetFieldId; } @@ -100,6 +115,7 @@ public class VisualizationOuterParamsTargetViewInfo implements Serializable { "targetId = " + targetId + ", paramsInfoId = " + paramsInfoId + ", targetViewId = " + targetViewId + + ", targetDsId = " + targetDsId + ", targetFieldId = " + targetFieldId + ", copyFrom = " + copyFrom + ", copyId = " + copyId + diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationOuterParamsTargetViewInfoMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationOuterParamsTargetViewInfoMapper.java index 1d4f56197a..0e6a211399 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationOuterParamsTargetViewInfoMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationOuterParamsTargetViewInfoMapper.java @@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper; *

* * @author fit2cloud - * @since 2024-03-08 + * @since 2024-08-21 */ @Mapper public interface VisualizationOuterParamsTargetViewInfoMapper extends BaseMapper { diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java index 89555ad4d9..abe21e2657 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java @@ -1,6 +1,7 @@ package io.dataease.visualization.dao.ext.mapper; +import io.dataease.api.dataset.vo.CoreDatasetGroupVO; import io.dataease.api.visualization.dto.VisualizationOuterParamsDTO; import io.dataease.api.visualization.dto.VisualizationOuterParamsInfoDTO; import org.apache.ibatis.annotations.Mapper; @@ -20,4 +21,6 @@ public interface ExtVisualizationOuterParamsMapper { void deleteOuterParamsWithVisualizationId(@Param("visualizationId") String visualizationId); List getVisualizationOuterParamsInfo(@Param("visualizationId") String visualizationId); + + List queryDsWithVisualizationId(@Param("visualizationId") String visualizationId); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java index b252b15559..56ec45a7d9 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java @@ -1,10 +1,20 @@ package io.dataease.visualization.server; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fasterxml.jackson.core.type.TypeReference; +import com.ibm.icu.impl.coll.CollationLoader; +import io.dataease.api.dataset.vo.CoreDatasetGroupVO; +import io.dataease.api.dataset.vo.CoreDatasetTableFieldVO; import io.dataease.api.visualization.VisualizationOuterParamsApi; import io.dataease.api.visualization.dto.VisualizationOuterParamsDTO; import io.dataease.api.visualization.dto.VisualizationOuterParamsInfoDTO; import io.dataease.api.visualization.response.VisualizationOuterParamsBaseResponse; +import io.dataease.dataset.dao.auto.entity.CoreDatasetTable; +import io.dataease.dataset.dao.auto.mapper.CoreDatasetTableMapper; +import io.dataease.engine.constant.DeTypeConstants; +import io.dataease.extensions.view.dto.SqlVariableDetails; import io.dataease.utils.BeanUtils; +import io.dataease.utils.JsonUtil; import io.dataease.visualization.dao.auto.entity.VisualizationOuterParams; import io.dataease.visualization.dao.auto.entity.VisualizationOuterParamsInfo; import io.dataease.visualization.dao.auto.entity.VisualizationOuterParamsTargetViewInfo; @@ -13,14 +23,13 @@ import io.dataease.visualization.dao.auto.mapper.VisualizationOuterParamsMapper; import io.dataease.visualization.dao.auto.mapper.VisualizationOuterParamsTargetViewInfoMapper; import io.dataease.visualization.dao.ext.mapper.ExtVisualizationOuterParamsMapper; import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** @@ -41,12 +50,21 @@ public class VisualizationOuterParamsService implements VisualizationOuterParams @Resource private VisualizationOuterParamsTargetViewInfoMapper outerParamsTargetViewInfoMapper; + @Resource + private CoreDatasetTableMapper coreDatasetTableMapper; + + @Override public VisualizationOuterParamsDTO queryWithVisualizationId(String visualizationId) { VisualizationOuterParamsDTO visualizationOuterParamsDTO = extOuterParamsMapper.queryWithVisualizationId(visualizationId); return visualizationOuterParamsDTO; } + @Override + public VisualizationOuterParamsDTO queryWithVisualizationIdDS(String dvId) { + return null; + } + @Override public void updateOuterParamsSet(VisualizationOuterParamsDTO outerParamsDTO) { String visualizationId = outerParamsDTO.getVisualizationId(); @@ -85,4 +103,32 @@ public class VisualizationOuterParamsService implements VisualizationOuterParams List result = extOuterParamsMapper.getVisualizationOuterParamsInfo(visualizationId); return new VisualizationOuterParamsBaseResponse(Optional.ofNullable(result).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(VisualizationOuterParamsInfoDTO::getSourceInfo, VisualizationOuterParamsInfoDTO::getTargetInfoList))); } + + @Override + public List queryDsWithVisualizationId(String visualizationId) { + List result = extOuterParamsMapper.queryDsWithVisualizationId(visualizationId); + if(!CollectionUtils.isEmpty(result)){ + result.forEach(coreDatasetGroupVO -> { + List fields = coreDatasetGroupVO.getDatasetFields(); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("dataset_group_id", coreDatasetGroupVO.getId()); + List tableResult = coreDatasetTableMapper.selectList(wrapper); + if(!CollectionUtils.isEmpty(tableResult)){ + tableResult.forEach(coreDatasetTable -> { + String sqlVarDetail = coreDatasetTable.getSqlVariableDetails(); + if(StringUtils.isNotEmpty(sqlVarDetail)){ + TypeReference> listTypeReference = new TypeReference>() { + }; + List defaultsSqlVariableDetails = JsonUtil.parseList(sqlVarDetail, listTypeReference); + defaultsSqlVariableDetails.forEach(sqlVariableDetails -> { + String varFieldId = coreDatasetTable.getId()+"|DE|"+sqlVariableDetails.getVariableName(); + fields.add(new CoreDatasetTableFieldVO(varFieldId,sqlVariableDetails.getVariableName(), DeTypeConstants.DE_STRING)); + }); + } + }); + } + }); + } + return result; + } } diff --git a/core/core-backend/src/main/resources/db/desktop/V2.10__ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.10__ddl.sql index f6a904983a..e3710f0e31 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.10__ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.10__ddl.sql @@ -6,3 +6,19 @@ alter table `core_dataset_table_field` add params text null comment '计算字 alter table `core_datasource` add `enable_data_fill` tinyint default 0 null comment '启用数据填报功能'; + + +ALTER TABLE `visualization_outer_params_target_view_info` + MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '联动视图ID/联动过滤项ID' , + ADD COLUMN `target_ds_id` varchar(50) NULL COMMENT '联动数据集id/联动过滤组件id' ; + + +alter table `core_chart_view` + add flow_map_start_name longtext comment '流向地图起点名称field'; +alter table `core_chart_view` + add flow_map_end_name longtext comment '流向地图终点名称field'; +alter table `core_chart_view` + add ext_color longtext comment '颜色维度field'; + +update visualization_outer_params_target_view_info tvi INNER JOIN core_chart_view ccv on tvi.target_view_id = ccv.id + set tvi.target_ds_id = ccv.table_id diff --git a/core/core-backend/src/main/resources/db/migration/V2.10__ddl.sql b/core/core-backend/src/main/resources/db/migration/V2.10__ddl.sql index 855346aeea..0ed36649c2 100644 --- a/core/core-backend/src/main/resources/db/migration/V2.10__ddl.sql +++ b/core/core-backend/src/main/resources/db/migration/V2.10__ddl.sql @@ -57,3 +57,16 @@ CREATE TABLE `xpack_threshold_instance` ); +ALTER TABLE `visualization_outer_params_target_view_info` + MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '联动视图ID/联动过滤项ID' , + ADD COLUMN `target_ds_id` varchar(50) NULL COMMENT '联动数据集id/联动过滤组件id' ; + +alter table `core_chart_view` + add flow_map_start_name longtext comment '流向地图起点名称field'; +alter table `core_chart_view` + add flow_map_end_name longtext comment '流向地图终点名称field'; +alter table `core_chart_view` + add ext_color longtext comment '颜色维度field'; + +update visualization_outer_params_target_view_info tvi INNER JOIN core_chart_view ccv on tvi.target_view_id = ccv.id + set tvi.target_ds_id = ccv.table_id diff --git a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml index deee3d6678..929470701e 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml @@ -160,7 +160,9 @@ FROM data_visualization_info where data_visualization_info.delete_flag = 0 and data_visualization_info.id = #{dvId} - and data_visualization_info.type = #{dvType} + + and data_visualization_info.type = #{dvType} + + + + + + diff --git a/core/core-frontend/src/api/visualization/dataVisualization.ts b/core/core-frontend/src/api/visualization/dataVisualization.ts index d35c8db3ce..16ea48a45f 100644 --- a/core/core-frontend/src/api/visualization/dataVisualization.ts +++ b/core/core-frontend/src/api/visualization/dataVisualization.ts @@ -107,3 +107,11 @@ export const export2AppCheck = params => { loading: true }) } + +export const queryOuterParamsDsInfo = async dvId => { + return request.get({ + url: '/outerParams/queryDsWithVisualizationId/' + dvId, + method: 'get', + loading: false + }) +} diff --git a/core/core-frontend/src/assets/svg/t-heatmap-dark.svg b/core/core-frontend/src/assets/svg/t-heatmap-dark.svg new file mode 100644 index 0000000000..0e550c0c4b --- /dev/null +++ b/core/core-frontend/src/assets/svg/t-heatmap-dark.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/t-heatmap-origin.svg b/core/core-frontend/src/assets/svg/t-heatmap-origin.svg new file mode 100644 index 0000000000..a19b1d00ed --- /dev/null +++ b/core/core-frontend/src/assets/svg/t-heatmap-origin.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/t-heatmap.svg b/core/core-frontend/src/assets/svg/t-heatmap.svg new file mode 100644 index 0000000000..b6c865615f --- /dev/null +++ b/core/core-frontend/src/assets/svg/t-heatmap.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/components/dashboard/DbToolbar.vue b/core/core-frontend/src/components/dashboard/DbToolbar.vue index 88a76582ff..9c65c4c3c0 100644 --- a/core/core-frontend/src/components/dashboard/DbToolbar.vue +++ b/core/core-frontend/src/components/dashboard/DbToolbar.vue @@ -354,7 +354,10 @@ const openOuterParamsSet = () => { ElMessage.warning('请先保存当前页面') return } - outerParamsSetRef.value.optInit() + //设置需要先触发保存 + canvasSave(() => { + outerParamsSetRef.value.optInit() + }) } const saveBatchChange = () => { diff --git a/core/core-frontend/src/components/data-visualization/DvToolbar.vue b/core/core-frontend/src/components/data-visualization/DvToolbar.vue index 7bbbba187c..86a244e73a 100644 --- a/core/core-frontend/src/components/data-visualization/DvToolbar.vue +++ b/core/core-frontend/src/components/data-visualization/DvToolbar.vue @@ -247,7 +247,10 @@ const openOuterParamsSet = () => { ElMessage.warning('请先保存当前页面') return } - outerParamsSetRef.value.optInit() + //设置需要先触发保存 + canvasSave(() => { + outerParamsSetRef.value.optInit() + }) } const multiplexingCanvasOpen = () => { diff --git a/core/core-frontend/src/components/data-visualization/canvas/ContextMenuDetails.vue b/core/core-frontend/src/components/data-visualization/canvas/ContextMenuDetails.vue index 91d0e726c1..9dac63bb6d 100644 --- a/core/core-frontend/src/components/data-visualization/canvas/ContextMenuDetails.vue +++ b/core/core-frontend/src/components/data-visualization/canvas/ContextMenuDetails.vue @@ -11,6 +11,7 @@ import { ElDivider } from 'element-plus-secondary' import eventBus from '@/utils/eventBus' import { getCurInfo } from '@/store/modules/data-visualization/common' import { useEmitt } from '@/hooks/web/useEmitt' +import { XpackComponent } from '@/components/plugin' const dvMainStore = dvMainStoreWithOut() const copyStore = copyStoreWithOut() const lockStore = lockStoreWithOut() @@ -245,6 +246,11 @@ const editQueryCriteria = () => {
  • 下移一层
  • 置于顶层
  • 置于底层
  • +
  • - + 选择参数关联组件 +
    -
    联动组件
    -
    -
    联动组件字段
    -
    +
    +
    + + + +
    +
    +
    查询组件
    +
    关联条件
    -
    +
    -
    -
    - - - - {{ item.title }} - - -
    +
    +
    + + {{ findFilterName(baseFilter.id) }}
    - - -
    -
    - + + {{ item.name }} + + +
    +
    +
    + + +
    +
    +
    + + + +
    +
    +
    图表
    +
    关联字段或参数
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    + {{ baseDatasetInfo.name }} +
    +
    + + - {{ viewField.name }} + {{ item.name }}
    - - - - - + +
    +
    +
    选择关联的图表
    +
    +
    + 全选 +
    +
    +
    +
    +
    + +
    +
    + +
    + {{ viewInfo.chartName }} +
    +
    +
    - - - - {{ t('visualization.add_param_link_field') }} - -
    @@ -164,10 +244,8 @@ - {{ t('commons.cancel') }} - {{ t('commons.confirm') }} - + {{ t('commons.cancel') }} + {{ t('commons.confirm') }} @@ -177,12 +255,12 @@ import { ref, reactive, computed, nextTick } from 'vue' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { storeToRefs } from 'pinia' -import { ElMessage } from 'element-plus-secondary' +import { ElCol, ElMessage } from 'element-plus-secondary' import { useI18n } from '@/hooks/web/useI18n' import { deepCopy } from '@/utils/utils' import generateID from '@/utils/generateID' import { queryWithVisualizationId, updateOuterParamsSet } from '@/api/visualization/outerParams' -import { viewDetailList } from '@/api/visualization/dataVisualization' +import { queryOuterParamsDsInfo, viewDetailList } from '@/api/visualization/dataVisualization' import checkArrayRepeat from '@/utils/check' import HandleMore from '@/components/handle-more/src/HandleMore.vue' import { fieldType } from '@/utils/attr' @@ -196,6 +274,8 @@ const curEditDataId = ref(null) const snapshotStore = snapshotStoreWithOut() const state = reactive({ + filterExpand: true, + datasetExpand: true, loading: false, outerParamsSetVisible: false, optMenu: [ @@ -219,6 +299,8 @@ const state = reactive({ checked: false, outerParamsInfoArray: [] }, + baseDatasetInfo: [], + baseFilterInfo: [], outerParamsInfoArray: [], mapOuterParamsInfoArray: {}, panelList: [], @@ -284,13 +366,28 @@ const getFieldArray = id => { return state.viewIdFieldArrayMap[id] } -const initParams = () => { +const initParams = async () => { + state.baseFilterInfo = [] + state.baseDatasetInfo = [] + // 同步过滤组件信息 + componentData.value.forEach(componentItem => { + if (componentItem.component === 'VQuery') { + state.baseFilterInfo.push(componentItem) + } + }) + // 同步基础数据集信息 + await queryOuterParamsDsInfo(dvInfo.value.id).then(rsp => { + state.baseDatasetInfo = rsp.data + }) // 获取当前仪表板外部跳转信息 queryWithVisualizationId(dvInfo.value.id).then(rsp => { state.outerParams = rsp.data state.outerParamsInfoArray = state.outerParams?.outerParamsInfoArray if (state.outerParamsInfoArray.length >= 1) { state.outerParamsInfoArray.forEach(outerParamsInfo => { + const newBaseFilterInfo = deepCopy(state.baseFilterInfo) + const newBaseDatasetInfo = deepCopy(state.baseDatasetInfo) + paramsCheckedAdaptor(outerParamsInfo, newBaseFilterInfo, newBaseDatasetInfo) state.mapOuterParamsInfoArray[outerParamsInfo.paramsInfoId] = outerParamsInfo }) state.curNodeId = null @@ -300,22 +397,104 @@ const initParams = () => { }) } }) + getPanelViewList(dvInfo.value.id) } +const findFields = (type, datasetFields) => { + if (type === 'parameterList') { + return datasetFields.filter(field => field.attachId.indexOf('DE') > -1) + } else { + return datasetFields.filter(field => field.attachId.indexOf('DE') === -1) + } +} + +const datasetInfoChange = datasetInfo => { + let viewCheckCount = 0 + datasetInfo.datasetViews.forEach(dsView => { + if (dsView['checked']) { + viewCheckCount++ + } + }) + datasetInfo['checkAll'] = viewCheckCount === datasetInfo.datasetViews.length + datasetInfo['checkAllIsIndeterminate'] = + viewCheckCount > 0 && viewCheckCount < datasetInfo.datasetViews.length +} + +const paramsCheckedAdaptor = (outerParamsInfo, newBaseFilterInfo, newBaseDatasetInfo) => { + const dsFieldIdSelected = {} + const viewMatchIds = [] + outerParamsInfo.targetViewInfoList.forEach(targetViewInfo => { + viewMatchIds.push(targetViewInfo.targetViewId) + dsFieldIdSelected[targetViewInfo.targetDsId] = + targetViewInfo.targetFieldId === 'empty' + ? targetViewInfo.targetViewId + : targetViewInfo.targetFieldId + }) + if (newBaseDatasetInfo) { + newBaseDatasetInfo.forEach(datasetInfo => { + datasetInfo['fieldIdSelected'] = dsFieldIdSelected[datasetInfo.id] + datasetInfo['viewExpand'] = true + let viewCheckCount = 0 + datasetInfo.datasetViews.forEach(dsView => { + if (viewMatchIds.includes(dsView.chartId)) { + dsView['checked'] = true + viewCheckCount++ + } else { + dsView['checked'] = false + } + }) + datasetInfo['checkAll'] = viewCheckCount === datasetInfo.datasetViews.length + datasetInfo['checkAllIsIndeterminate'] = + viewCheckCount > 0 && viewCheckCount < datasetInfo.datasetViews.length + if (datasetInfo['fieldIdSelected'] && datasetInfo['fieldIdSelected'].indexOf('DE') > -1) { + datasetInfo['activelist'] = 'parameterList' + } else { + datasetInfo['activelist'] = 'dimensionList' + } + }) + } + if (newBaseFilterInfo) { + newBaseFilterInfo.forEach(filterInfo => { + filterInfo['filterSelected'] = dsFieldIdSelected[filterInfo.id] + }) + } + outerParamsInfo['filterInfo'] = newBaseFilterInfo + outerParamsInfo['datasetInfo'] = newBaseDatasetInfo +} + const cancel = () => { state.outerParamsSetVisible = false } const save = () => { - if (checkArrayRepeat(state.outerParams.outerParamsInfoArray, 'paramName')) { - ElMessage.warning({ - message: t('visualization.repeat_params'), - showClose: true + const outerParamsCopy = deepCopy(state.outerParams) + outerParamsCopy.outerParamsInfoArray?.forEach(outerParamsInfo => { + outerParamsInfo.targetViewInfoList = [] + outerParamsInfo.filterInfo?.forEach(baseFilterInfo => { + // 存在过滤器选项被选 + if (baseFilterInfo.filterSelected) { + outerParamsInfo.targetViewInfoList.push({ + targetViewId: baseFilterInfo.filterSelected, + targetDsId: baseFilterInfo.id, + targetFieldId: 'empty' + }) + } }) - return - } - updateOuterParamsSet(state.outerParams).then(() => { + outerParamsInfo.datasetInfo?.forEach(baseDatasetInfo => { + // 存在数据集字段被选中 + if (baseDatasetInfo.fieldIdSelected) { + baseDatasetInfo.datasetViews?.forEach(dsView => { + outerParamsInfo.targetViewInfoList.push({ + targetViewId: dsView.chartId, + targetDsId: baseDatasetInfo.id, + targetFieldId: baseDatasetInfo.fieldIdSelected + }) + }) + } + }) + }) + updateOuterParamsSet(outerParamsCopy).then(() => { ElMessage({ message: t('commons.save_success'), type: 'success', @@ -395,6 +574,9 @@ const addOuterParamsInfo = () => { state.outerParams.checked = true const outerParamsInfo = deepCopy(state.defaultOuterParamsInfo) outerParamsInfo['paramsInfoId'] = generateID() + const newBaseFilterInfo = deepCopy(state.baseFilterInfo) + const newBaseDatasetInfo = deepCopy(state.baseDatasetInfo) + paramsCheckedAdaptor(outerParamsInfo, newBaseFilterInfo, newBaseDatasetInfo) state.outerParamsInfoArray.push(outerParamsInfo) state.mapOuterParamsInfoArray[outerParamsInfo.paramsInfoId] = outerParamsInfo curEditDataId.value = outerParamsInfo['paramsInfoId'] @@ -410,12 +592,24 @@ const removeOuterParamsInfo = (node, data) => { state.curNodeId = null } } +const batchSelectChange = (value, baseDatasetInfo) => { + // do change + baseDatasetInfo.datasetViews.forEach(viewInfo => { + viewInfo.checked = value + }) + baseDatasetInfo.checkAll = value + baseDatasetInfo.checkAllIsIndeterminate = false +} const optInit = () => { state.outerParamsSetVisible = true initParams() } +const findFilterName = id => { + return dvMainStore.canvasViewInfo[id]?.title +} + defineExpose({ optInit }) @@ -488,12 +682,14 @@ defineExpose({ .preview-show { border-left: 1px solid #e6e6e6; background-size: 100% 100% !important; + height: 100%; + overflow-y: auto; } .view-type-icon { color: var(--ed-color-primary); width: 22px; - height: 16px; + height: 14px; } .custom-tree { @@ -529,8 +725,26 @@ defineExpose({ .inner-content { width: 100%; - padding: 16px 16px 8px 16px; - font-size: 14px !important; + font-size: 14px; +} + +.outer-filter-content { + width: 100%; +} + +.outer-dataset-content { + width: 100%; + padding-left: 16px; +} + +.inner-filter-content { + width: 100%; + margin-top: 12px; +} + +.inner-dataset-content { + width: 100%; + margin-top: 12px; } .slot-class { @@ -644,4 +858,54 @@ defineExpose({ .params-class ::deep(.ed-dialog__body) { padding: 10px 20px 20px; } + +.new-params-title { + height: 56px; + font-size: 14px; + font-weight: 500; + padding: 16px; + border-bottom: 1px solid rgba(31, 35, 41, 0.15); +} + +.new-params-filter { + padding: 16px; + border-bottom: 1px solid rgba(31, 35, 41, 0.15); +} + +.new-params-ds { + padding: 16px; +} + +.expand-custom { + width: 16px; + height: 16px; + border-radius: 4px; + padding: 0px 1px; + color: rgba(100, 106, 115, 1); + &:hover { + background: rgba(31, 35, 41, 0.1); + cursor: pointer; + } +} + +.ds-view-content { + width: calc(100% - 16px); + border-radius: 4px; + margin: 8px 16px 0 16px; + padding: 12px; + background: rgba(245, 246, 247, 1); +} + +.ds-content-title { + font-size: 14px; + font-weight: 500; + color: rgba(100, 106, 115, 1); +} + +.custom-view-diver { + width: 1px; + margin: 4px 4px; + height: 14px; + background: rgba(31, 35, 41, 0.15); +} diff --git a/core/core-frontend/src/components/visualization/OuterParamsSetDS.vue b/core/core-frontend/src/components/visualization/OuterParamsSetDS.vue new file mode 100644 index 0000000000..2298b24eb7 --- /dev/null +++ b/core/core-frontend/src/components/visualization/OuterParamsSetDS.vue @@ -0,0 +1,647 @@ + + + + + diff --git a/core/core-frontend/src/custom-component/v-query/Component.vue b/core/core-frontend/src/custom-component/v-query/Component.vue index b86d8dab16..ca773ef79a 100644 --- a/core/core-frontend/src/custom-component/v-query/Component.vue +++ b/core/core-frontend/src/custom-component/v-query/Component.vue @@ -347,13 +347,15 @@ const drop = e => { checkedFieldsMap[ele.id] = componentInfo.id } }) + // URL 字段类型换成文本字段类型 + const displayType = componentInfo.deType === 7 ? 0 : componentInfo.deType list.value.push({ ...infoFormat(componentInfo), auto: true, optionValueSource: 1, checkedFields, checkedFieldsMap, - displayType: `${componentInfo.deType}` + displayType }) }) element.value.propValue = [...list.value] diff --git a/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue b/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue index 456ed034ab..8e80718dc1 100644 --- a/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue +++ b/core/core-frontend/src/custom-component/v-query/QueryConditionConfiguration.vue @@ -330,6 +330,9 @@ const setType = () => { if (!(field?.deType === 1 && curComponent.value.displayType === '7')) { curComponent.value.displayType = `${[3, 4].includes(field?.deType) ? 2 : field?.deType}` } + if (field?.deType === 7) { + curComponent.value.displayType = '0' + } if ( displayType !== curComponent.value.displayType && !([3, 4].includes(+displayType) && +curComponent.value.displayType === 2) @@ -1848,7 +1851,8 @@ defineExpose({ v-for="ele in curComponent.dataset.fields.filter( ele => ele.deType === +curComponent.displayType || - ([3, 4].includes(ele.deType) && +curComponent.displayType === 2) + ([3, 4].includes(ele.deType) && +curComponent.displayType === 2) || + (ele.deType === 7 && +curComponent.displayType === 0) )" :key="ele.id" :label="ele.name" @@ -1899,7 +1903,8 @@ defineExpose({ v-for="ele in curComponent.dataset.fields.filter( ele => ele.deType === +curComponent.displayType || - ([3, 4].includes(ele.deType) && +curComponent.displayType === 2) + ([3, 4].includes(ele.deType) && +curComponent.displayType === 2) || + (ele.deType === 7 && +curComponent.displayType === 0) )" :key="ele.id" :label="ele.name" diff --git a/core/core-frontend/src/layout/components/Header.vue b/core/core-frontend/src/layout/components/Header.vue index cd386ebd48..85eea39994 100644 --- a/core/core-frontend/src/layout/components/Header.vue +++ b/core/core-frontend/src/layout/components/Header.vue @@ -146,10 +146,18 @@ onMounted(() => {
    - + - + { :base-url="aiBaseUrl" >
    -
    +
    diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index a00d722c6a..ee6b72d807 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -1116,6 +1116,7 @@ export default { table_column_fixed: '固定列宽', table_column_custom: '自定义', chart_table_pivot: '透视表', + chart_table_heatmap: '热力图', table_pivot_row: '数据行', field_error_tips: '该字段所对应的数据集原始字段发生变更(包括维度、指标,字段类型,字段被删除等),建议重新编辑', @@ -2787,6 +2788,8 @@ export default { name: '告警名称', grid_title: '告警管理', grid: '告警列表', - record: '告警记录' + record: '告警记录', + module_name: '阈值告警', + setting: '阈值告警设置' } } diff --git a/core/core-frontend/src/models/chart/chart.d.ts b/core/core-frontend/src/models/chart/chart.d.ts index 2dff80aff4..0365d5f5f0 100644 --- a/core/core-frontend/src/models/chart/chart.d.ts +++ b/core/core-frontend/src/models/chart/chart.d.ts @@ -68,6 +68,8 @@ declare interface Chart { flowMapStartName?: Axis[] flowMapEndName?: Axis[] showPosition: string + + extColor: Axis[] } declare type CustomAttr = DeepPartial | JSONString> declare type CustomStyle = DeepPartial | JSONString> diff --git a/core/core-frontend/src/models/chart/editor.d.ts b/core/core-frontend/src/models/chart/editor.d.ts index 72186e22dc..b2e21a1170 100644 --- a/core/core-frontend/src/models/chart/editor.d.ts +++ b/core/core-frontend/src/models/chart/editor.d.ts @@ -57,7 +57,7 @@ declare type AxisType = | 'area' | 'flowMapStartName' | 'flowMapEndName' - | 'flowMapColor' + | 'extColor' /** * 轴配置 */ diff --git a/core/core-frontend/src/store/modules/appearance.ts b/core/core-frontend/src/store/modules/appearance.ts index 31c94c3f02..a755618e4a 100644 --- a/core/core-frontend/src/store/modules/appearance.ts +++ b/core/core-frontend/src/store/modules/appearance.ts @@ -12,8 +12,11 @@ interface AppearanceState { customColor?: string navigateBg?: string navigate?: string + mobileLogin?: string + mobileLoginBg?: string help?: string showAi?: string + showCopilot?: string showDoc?: string showAbout?: string bg?: string @@ -36,9 +39,12 @@ export const useAppearanceStore = defineStore('appearanceStore', { customColor: '', navigateBg: '', navigate: '', + mobileLogin: '', + mobileLoginBg: '', help: '', showDoc: '0', showAi: '0', + showCopilot: '0', showAbout: '0', bg: '', login: '', @@ -60,6 +66,18 @@ export const useAppearanceStore = defineStore('appearanceStore', { } return null }, + getMobileLogin(): string { + if (this.mobileLogin) { + return baseUrl + this.mobileLogin + } + return null + }, + getMobileLoginBg(): string { + if (this.mobileLoginBg) { + return baseUrl + this.mobileLoginBg + } + return null + }, getHelp(): string { return this.help }, @@ -117,6 +135,9 @@ export const useAppearanceStore = defineStore('appearanceStore', { getShowAi(): boolean { return isBtnShow(this.showAi) }, + getShowCopilot(): boolean { + return isBtnShow(this.showCopilot) + }, getShowDoc(): boolean { return isBtnShow(this.showDoc) }, @@ -128,6 +149,12 @@ export const useAppearanceStore = defineStore('appearanceStore', { setNavigate(data: string) { this.navigate = data }, + setMobileLogin(data: string) { + this.mobileLogin = data + }, + setMobileLoginBg(data: string) { + this.mobileLoginBg = data + }, setHelp(data: string) { this.help = data }, @@ -177,8 +204,11 @@ export const useAppearanceStore = defineStore('appearanceStore', { return } this.navigate = data.navigate + this.mobileLogin = data.mobileLogin + this.mobileLoginBg = data.mobileLoginBg this.help = data.help this.showAi = data.showAi + this.showCopilot = data.showCopilot this.showDoc = data.showDoc this.showAbout = data.showAbout this.navigateBg = data.navigateBg diff --git a/core/core-frontend/src/views/about/index.vue b/core/core-frontend/src/views/about/index.vue index c436f51dfa..64fac972ed 100644 --- a/core/core-frontend/src/views/about/index.vue +++ b/core/core-frontend/src/views/about/index.vue @@ -81,7 +81,10 @@ const setLicense = lic => { dynamicCardClass.value = 'about-card-medium' } } - +const removeDistributeModule = () => { + const key = 'xpack-model-distributed' + localStorage.removeItem(key) +} const importLic = file => { const reader = new FileReader() reader.onload = function (e) { @@ -93,6 +96,7 @@ const importLic = file => { reader.readAsText(file) } const validateHandler = (param, success) => { + removeDistributeModule() validateApi(param).then(success) } const getLicense = result => { diff --git a/core/core-frontend/src/views/chart/components/editor/drag-item/QuotaItem.vue b/core/core-frontend/src/views/chart/components/editor/drag-item/QuotaItem.vue index 7cb7e1b1d0..7b069feba5 100644 --- a/core/core-frontend/src/views/chart/components/editor/drag-item/QuotaItem.vue +++ b/core/core-frontend/src/views/chart/components/editor/drag-item/QuotaItem.vue @@ -402,7 +402,7 @@ onMounted(() => { --> { + const checkedField = state.fieldList.filter(ele => ele.id === compareItem.value.compareCalc.field) + if (checkedField && checkedField.length > 0) { + checkedField[0].dateStyle = state.dateFormatter + if (!compareItem.value.compareCalc.custom) { + compareItem.value.compareCalc.custom = { timeType: 'y_M_d' } + } + compareItem.value.compareCalc.custom.timeType = state.dateFormatter + } + initCompareType() +} + +const initDateFormatter = () => { + const timeType = compareItem.value.compareCalc.custom?.timeType + if (isIndicator.value && timeType) { + state.dateFormatter = timeType + changeDateFormatter() + } +} + watch( () => props.chart, () => { initFieldList() initCompareType() + initDateFormatter() }, { deep: true } ) @@ -109,15 +137,6 @@ const initCompareType = () => { } else { state.compareList = [] } - if (isIndicator.value) { - state.compareList = [ - { name: 'day_mom', value: 'day_mom' }, - { name: 'month_mom', value: 'month_mom' }, - { name: 'year_mom', value: 'year_mom' }, - { name: 'month_yoy', value: 'month_yoy' }, - { name: 'year_yoy', value: 'year_yoy' } - ] - } // 如果没有选中一个同环比类型,则默认选中第一个 if ( (!compareItem.value.compareCalc.type || @@ -136,9 +155,9 @@ const fieldFormatter = field => { return field.name + '(' + t('chart.' + field.dateStyle) + ')' } } - initFieldList() initCompareType() +initDateFormatter()