diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java index bcfbcfe54e..1413664c6d 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java @@ -250,6 +250,120 @@ public class DefaultChartHandler extends AbstractChartPlugin { return res; } + protected List getAssistFields(List list, List yAxis, List xAxis) { + List res = new ArrayList<>(); + for (ChartSeniorAssistDTO dto : list) { + DatasetTableFieldDTO curField = dto.getCurField(); + ChartViewFieldDTO field = null; + String alias = ""; + for (int i = 0; i < yAxis.size(); i++) { + ChartViewFieldDTO yField = yAxis.get(i); + if (Objects.equals(yField.getId(), curField.getId())) { + field = yField; + alias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i); + break; + } + } + if (ObjectUtils.isEmpty(field) && CollectionUtils.isNotEmpty(xAxis)) { + for (int i = 0; i < xAxis.size(); i++) { + ChartViewFieldDTO xField = xAxis.get(i); + if (StringUtils.equalsIgnoreCase(String.valueOf(xField.getId()), String.valueOf(curField.getId()))) { + field = xField; + alias = String.format(SQLConstants.FIELD_ALIAS_X_PREFIX, i); + break; + } + } + } + if (ObjectUtils.isEmpty(field)) { + continue; + } + + ChartViewFieldDTO chartViewFieldDTO = new ChartViewFieldDTO(); + BeanUtils.copyBean(chartViewFieldDTO, curField); + chartViewFieldDTO.setSummary(dto.getSummary()); + chartViewFieldDTO.setOriginName(alias);// yAxis的字段别名,就是查找的字段名 + res.add(chartViewFieldDTO); + } + return res; + } + + public List getDynamicThresholdFields(ChartViewDTO view) { + List list = new ArrayList<>(); + Map senior = view.getSenior(); + if (ObjectUtils.isEmpty(senior)) { + return list; + } + ChartSeniorThresholdCfgDTO thresholdCfg = JsonUtil.parseObject((String) JsonUtil.toJSONString(senior.get("threshold")), ChartSeniorThresholdCfgDTO.class); + + if (null == thresholdCfg || !thresholdCfg.isEnable()) { + return list; + } + List tableThreshold = thresholdCfg.getTableThreshold(); + + if (ObjectUtils.isEmpty(tableThreshold)) { + return list; + } + + List conditionsList = tableThreshold.stream() + .filter(item -> !ObjectUtils.isEmpty(item)) + .map(TableThresholdDTO::getConditions) + .flatMap(List::stream) + .filter(condition -> StringUtils.equalsAnyIgnoreCase(condition.getType(), "dynamic")) + .toList(); + + List assistDTOs = conditionsList.stream() + .flatMap(condition -> getConditionFields(condition).stream()) + .filter(this::solveThresholdCondition) + .toList(); + + list.addAll(assistDTOs); + + return list; + } + + private boolean solveThresholdCondition(ChartSeniorAssistDTO fieldDTO) { + Long fieldId = fieldDTO.getFieldId(); + String summary = fieldDTO.getValue(); + if (ObjectUtils.isEmpty(fieldId) || StringUtils.isEmpty(summary)) { + return false; + } + + DatasetTableFieldDTO datasetTableFieldDTO = datasetTableFieldManage.selectById(fieldId); + if (ObjectUtils.isEmpty(datasetTableFieldDTO)) { + return false; + } + ChartViewFieldDTO datasetTableField = new ChartViewFieldDTO(); + BeanUtils.copyBean(datasetTableField, datasetTableFieldDTO); + fieldDTO.setCurField(datasetTableField); + fieldDTO.setSummary(summary); + return true; + } + + private List getConditionFields(ChartSeniorThresholdDTO condition) { + List list = new ArrayList<>(); + if ("between".equals(condition.getTerm())) { + if (!StringUtils.equalsIgnoreCase(condition.getDynamicMaxField().getSummary(), "value")) { + list.add(of(condition.getDynamicMaxField())); + } + if (!StringUtils.equalsIgnoreCase(condition.getDynamicMinField().getSummary(), "value")) { + list.add(of(condition.getDynamicMinField())); + } + } else { + if (!StringUtils.equalsIgnoreCase(condition.getDynamicField().getSummary(), "value")) { + list.add(of(condition.getDynamicField())); + } + } + + return list; + } + + private ChartSeniorAssistDTO of(ThresholdDynamicFieldDTO dynamicField){ + ChartSeniorAssistDTO conditionField = new ChartSeniorAssistDTO(); + conditionField.setFieldId(Long.parseLong(dynamicField.getFieldId())); + conditionField.setValue(dynamicField.getSummary()); + return conditionField; + } + protected String assistSQL(String sql, List assistFields) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < assistFields.size(); i++) { diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java index 12bd57256f..63805ef11e 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java @@ -12,8 +12,9 @@ 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 io.dataease.utils.JsonUtil; +import io.dataease.utils.BeanUtils; import lombok.Getter; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -21,6 +22,8 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; @Component public class TableInfoHandler extends DefaultChartHandler { @@ -135,6 +138,32 @@ public class TableInfoHandler extends DefaultChartHandler { calcResult.setContext(filterResult.getContext()); calcResult.setQuerySql(querySql); calcResult.setOriginData(data); + try { + var dynamicAssistFields = getDynamicThresholdFields(view); + Set fieldIds = xAxis.stream().map(ChartViewFieldDTO::getId).collect(Collectors.toSet()); + List finalXAxis = xAxis; + dynamicAssistFields.forEach(i -> { + if (!fieldIds.contains(i.getFieldId())) { + ChartViewFieldDTO fieldDTO = new ChartViewFieldDTO(); + BeanUtils.copyBean(fieldDTO, i.getCurField()); + finalXAxis.add(fieldDTO); + } + }); + var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); + var assistFields = getAssistFields(dynamicAssistFields, yAxis, xAxis); + if (CollectionUtils.isNotEmpty(assistFields)) { + var req = new DatasourceRequest(); + req.setDsList(dsMap); + var assistSql = assistSQL(querySql, assistFields); + req.setQuery(assistSql); + logger.debug("calcite assistSql sql: " + assistSql); + var assistData = (List) provider.fetchResultField(req).get("data"); + calcResult.setAssistData(assistData); + calcResult.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } return calcResult; } } diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableNormalHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableNormalHandler.java index 36522b8117..bc48648ea3 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableNormalHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableNormalHandler.java @@ -1,9 +1,18 @@ package io.dataease.chart.charts.impl.table; import io.dataease.chart.charts.impl.YoyChartHandler; +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 lombok.Getter; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.Map; + /** * @author jianneng * @date 2024/9/11 11:37 @@ -12,4 +21,29 @@ import org.springframework.stereotype.Component; public class TableNormalHandler extends YoyChartHandler { @Getter private String type = "table-normal"; + + @Override + public T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, Provider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + var result = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider); + try { + var originSql = result.getQuerySql(); + var dynamicAssistFields = getDynamicThresholdFields(view); + var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); + var assistFields = getAssistFields(dynamicAssistFields, yAxis); + if (CollectionUtils.isNotEmpty(assistFields)) { + var req = new DatasourceRequest(); + req.setDsList(dsMap); + var assistSql = assistSQL(originSql, assistFields); + req.setQuery(assistSql); + logger.debug("calcite assistSql sql: " + assistSql); + var assistData = (List) provider.fetchResultField(req).get("data"); + result.setAssistData(assistData); + result.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } } diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java index 3cdbb4159b..38e1ddf391 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java @@ -17,6 +17,7 @@ import io.dataease.utils.BeanUtils; import io.dataease.utils.IDUtils; import io.dataease.utils.JsonUtil; import lombok.Getter; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import reactor.util.function.Tuple2; @@ -35,6 +36,25 @@ public class TablePivotHandler extends GroupChartHandler { T result = super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider); Map customCalc = calcCustomExpr(view, filterResult, sqlMap, sqlMeta, provider); result.getData().put("customCalc", customCalc); + try { + var dsMap = (Map) sqlMap.get("dsMap"); + var originSql = result.getQuerySql(); + var dynamicAssistFields = getDynamicThresholdFields(view); + var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); + var assistFields = getAssistFields(dynamicAssistFields, yAxis); + if (CollectionUtils.isNotEmpty(assistFields)) { + var req = new DatasourceRequest(); + req.setDsList(dsMap); + var assistSql = assistSQL(originSql, assistFields); + req.setQuery(assistSql); + logger.debug("calcite assistSql sql: " + assistSql); + var assistData = (List) provider.fetchResultField(req).get("data"); + result.setAssistData(assistData); + result.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } return result; } diff --git a/core/core-frontend/src/models/chart/chart-senior.d.ts b/core/core-frontend/src/models/chart/chart-senior.d.ts index 8aad7c14fe..2a56510acd 100644 --- a/core/core-frontend/src/models/chart/chart-senior.d.ts +++ b/core/core-frontend/src/models/chart/chart-senior.d.ts @@ -198,6 +198,28 @@ declare interface Threshold { * url */ url: string + /** + * 类型,固定值、动态值 + */ + type: 'fixed' | 'dynamic' + /** + * 动态值字段 + */ + dynamicField: ThresholdDynamicField + /** + * 动态值最小值字段 仅当term为between时使用 + */ + dynamicMinField: ThresholdDynamicField + /** + * 动态值最大值字段 仅当term为between时使用 + */ + dynamicMaxField: ThresholdDynamicField +} + +declare interface ThresholdDynamicField { + fieldId: string + summary: string + field: ChartViewField } /** diff --git a/core/core-frontend/src/views/chart/components/editor/editor-senior/components/Threshold.vue b/core/core-frontend/src/views/chart/components/editor/editor-senior/components/Threshold.vue index 08cd6f84b8..d18e1befdf 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-senior/components/Threshold.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-senior/components/Threshold.vue @@ -193,40 +193,62 @@ const changeTableThreshold = () => { ElMessage.error(t('chart.exp_can_not_empty')) return } - if (ele.term === 'between') { - if ( - !ele.term.includes('null') && - !ele.term.includes('empty') && - (ele.min === '' || ele.max === '') - ) { - ElMessage.error(t('chart.value_can_not_empty')) - return - } - if ( - (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && - (parseFloat(ele.min).toString() === 'NaN' || parseFloat(ele.max).toString() === 'NaN') - ) { - ElMessage.error(t('chart.value_error')) - return - } - if ( - (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && - parseFloat(ele.min) > parseFloat(ele.max) - ) { - ElMessage.error(t('chart.value_min_max_invalid')) - return + if (ele.type !== 'dynamic') { + if (ele.term === 'between') { + if ( + !ele.term.includes('null') && + !ele.term.includes('empty') && + (ele.min === '' || ele.max === '') + ) { + ElMessage.error(t('chart.value_can_not_empty')) + return + } + if ( + (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && + (parseFloat(ele.min).toString() === 'NaN' || parseFloat(ele.max).toString() === 'NaN') + ) { + ElMessage.error(t('chart.value_error')) + return + } + if ( + (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && + parseFloat(ele.min) > parseFloat(ele.max) + ) { + ElMessage.error(t('chart.value_min_max_invalid')) + return + } + } else { + if (!ele.term.includes('null') && !ele.term.includes('empty') && ele.value === '') { + ElMessage.error(t('chart.value_can_not_empty')) + return + } + if ( + (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && + parseFloat(ele.value).toString() === 'NaN' + ) { + ElMessage.error(t('chart.value_error')) + return + } } } else { - if (!ele.term.includes('null') && !ele.term.includes('empty') && ele.value === '') { - ElMessage.error(t('chart.value_can_not_empty')) - return - } - if ( - (field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) && - parseFloat(ele.value).toString() === 'NaN' - ) { - ElMessage.error(t('chart.value_error')) - return + if (ele.term === 'between') { + if ( + !ele.term.includes('null') && + !ele.term.includes('empty') && + (!ele.dynamicMinField?.fieldId || !ele.dynamicMaxField?.fieldId) + ) { + ElMessage.error(t('chart.field_can_not_empty')) + return + } + } else { + if ( + !ele.term.includes('null') && + !ele.term.includes('empty') && + !ele.dynamicField?.fieldId + ) { + ElMessage.error(t('chart.field_can_not_empty')) + return + } } } } @@ -235,7 +257,24 @@ const changeTableThreshold = () => { changeThreshold() closeTableThreshold() } +const getFieldName = field => (field.chartShowName ? field.chartShowName : field.name) +const getDynamicStyleLabel = (item, fieldObj) => { + const handleSummary = field => { + if (!field?.field) { + return '' + } + if (field.summary === 'value') { + return getFieldName(field.field) + '(' + t('chart.field') + ')' + } else { + let suffix = field.summary === 'avg' ? t('chart.drag_block_label_value') : '' + return getFieldName(field.field) + '(' + t('chart.' + field.summary) + suffix + ')' + } + } + if (item.type === 'dynamic') { + return handleSummary(fieldObj) + } +} init() @@ -519,17 +558,15 @@ init() style="flex-direction: column" >
- - - - - + + + {{ fieldItem.field.name }} @@ -577,7 +614,17 @@ init() 默认
-
+
+ + {{ t('chart.fix') }} + +
+
+ + {{ t('chart.dynamic') }} + +
+
{{ item.min }} ≤{{ t('chart.drag_block_label_value') }}≤ {{ item.max }}  
+
+ + {{ getDynamicStyleLabel(item, item.dynamicField) }} + + {{ getDynamicStyleLabel(item, item.dynamicMinField) }}≤{{ + t('chart.drag_block_label_value') + }}≤{{ getDynamicStyleLabel(item, item.dynamicMaxField) }} + +   +