Merge branch 'dev-v2' into v2.10

This commit is contained in:
taojinlong
2025-11-05 18:12:07 +08:00
27 changed files with 355 additions and 51 deletions

View File

@@ -4,11 +4,14 @@ import com.fasterxml.jackson.core.type.TypeReference;
import io.dataease.api.chart.dto.PageInfo;
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
import io.dataease.chart.charts.impl.DefaultChartHandler;
import io.dataease.constant.DeTypeConstants;
import io.dataease.engine.constant.ExtFieldConstant;
import io.dataease.engine.sql.SQLProvider;
import io.dataease.engine.trans.Dimension2SQLObj;
import io.dataease.engine.trans.ExtWhere2Str;
import io.dataease.engine.trans.Quota2SQLObj;
import io.dataease.engine.utils.Utils;
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
import io.dataease.extensions.datasource.dto.DatasourceRequest;
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
import io.dataease.extensions.datasource.model.SQLMeta;
@@ -16,14 +19,18 @@ 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.IDUtils;
import io.dataease.utils.JsonUtil;
import lombok.Getter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author jianneng
@@ -110,7 +117,7 @@ public class TableNormalHandler extends DefaultChartHandler {
var tablePageMode = (String) filterResult.getContext().get("tablePageMode");
var totalPageSql = "SELECT COUNT(*) FROM (" + SQLProvider.createQuerySQLNoSort(sqlMeta, true, view) + ") COUNT_TEMP";
if (StringUtils.isNotEmpty(totalPageSql) && StringUtils.equalsIgnoreCase(tablePageMode, "page")) {
if (StringUtils.equalsIgnoreCase(tablePageMode, "page")) {
totalPageSql = provider.rebuildSQL(totalPageSql, sqlMeta, crossDs, dsMap);
datasourceRequest.setQuery(totalPageSql);
datasourceRequest.setTotalPageFlag(true);
@@ -131,7 +138,6 @@ public class TableNormalHandler extends DefaultChartHandler {
List<String[]> data = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
//自定义排序
data = ChartDataUtil.resultCustomSort(xAxis, yAxis, view.getSortPriority(), data);
var yoyFiltered = filterResult.getContext().get("yoyFiltered") != null;
if (yoyFiltered) {
// 这里没加分页,因为加了分页参数可能会把原始数据挤出去
@@ -208,6 +214,64 @@ public class TableNormalHandler extends DefaultChartHandler {
} catch (Exception e) {
e.printStackTrace();
}
// 自定义汇总
var basicStyle = (Map<String, Object>) view.getCustomAttr().get("basicStyle");
var showSummary = BooleanUtils.isTrue((Boolean) basicStyle.get("showSummary"));
if (showSummary) {
var fieldList = (List) basicStyle.get("seriesSummary");
if (CollectionUtils.isNotEmpty(fieldList)) {
var customCalcFields = new ArrayList<ChartViewFieldDTO>();
var seriesList = JsonUtil.parseList(JsonUtil.toJSONString(fieldList).toString(), new TypeReference<List<ChartViewFieldDTO>>(){});
var quotaIds = allFields.stream().map(DatasetTableFieldDTO::getDataeaseName).collect(Collectors.toSet());
seriesList.forEach(field -> {
if (!BooleanUtils.isTrue(field.getShow()) || !"custom".equalsIgnoreCase(field.getSummary())) {
return;
}
if (StringUtils.isBlank(field.getOriginName())) {
return;
}
if (!quotaIds.contains(field.getField())) {
return;
}
field.setSummary("");
field.setDeType(DeTypeConstants.DE_FLOAT);
field.setId(IDUtils.snowID());
field.setExtField(ExtFieldConstant.EXT_CALC);
customCalcFields.add(field);
});
if (!customCalcFields.isEmpty()) {
var xFields = sqlMeta.getXFields();
// 清空维度值,获取完结果再设置回去
sqlMeta.setXFields(Collections.emptyList());
List<DatasetTableFieldDTO> tmpList = FieldUtil.transFields(allFields);
tmpList.addAll(customCalcFields);
Quota2SQLObj.quota2sqlObj(sqlMeta, customCalcFields, tmpList, crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage);
String customSumSql = SQLProvider.createQuerySQL(sqlMeta, false, !StringUtils.equalsIgnoreCase(dsMap.values().iterator().next().getType(), "es"), view);
customSumSql = provider.rebuildSQL(customSumSql, sqlMeta, crossDs, dsMap);
var customSumReq = new DatasourceRequest();
customSumReq.setIsCross(crossDs);
customSumReq.setDsList(dsMap);
customSumReq.setQuery(customSumSql);
var customSumData = (List<String[]>) provider.fetchResultField(customSumReq).get("data");
if (CollectionUtils.isNotEmpty(customSumData)) {
var customSumResult = new HashMap<String, BigDecimal>();
// 只取第一行结果
var customSumArr = customSumData.get(0);
for (int i = 0; i < customSumArr.length; i++) {
if (customCalcFields.get(i) != null && customSumArr[i] != null) {
try {
customSumResult.put(customCalcFields.get(i).getField(), new BigDecimal(customSumArr[i]));
} catch (Exception e) {
customSumResult.put(customCalcFields.get(i).getField(), new BigDecimal(0));
}
}
}
result.put("customSumResult", customSumResult);
}
sqlMeta.setXFields(xFields);
}
}
}
return calcResult;
}
}

View File

@@ -511,8 +511,7 @@ const dataVPreview = computed(
const linkOptBarShow = computed(() => {
return Boolean(
canvasStyleData.value.suspensionButtonAvailable &&
!inMobile.value &&
!mobileInPc.value &&
((!inMobile.value && !mobileInPc.value) || !isDashboard()) &&
showPopBar.value &&
!isDesktopFlag
)

View File

@@ -255,6 +255,7 @@ const showSuffix = ref<boolean>(DEFAULT_INDICATOR_STYLE.suffixEnable)
const suffixContent = ref('')
const indicatorNameShow = ref(false)
const indicatorNamePositionBottom = ref(true)
const indicatorNameWrapperStyle = reactive<CSSProperties>({
'margin-top': DEFAULT_INDICATOR_NAME_STYLE.nameValueSpacing + 'px'
@@ -369,8 +370,10 @@ const renderChart = async view => {
}
indicatorNameWrapperStyle['margin-top'] =
(indicatorName.nameValueSpacing ?? DEFAULT_INDICATOR_NAME_STYLE.nameValueSpacing) + 'px'
indicatorNamePositionBottom.value = indicatorName.namePosition !== 'top'
} else {
indicatorNameShow.value = false
indicatorNamePositionBottom.value = false
}
}
}
@@ -595,11 +598,16 @@ defineExpose({
@trackClick="trackClick"
:is-data-v-mobile="dataVMobile"
/>
<div v-if="indicatorNameShow && !indicatorNamePositionBottom">
<span :style="indicatorNameClass">{{ resultName }}</span>
<div :style="indicatorNameWrapperStyle"></div>
</div>
<div>
<span :style="indicatorClass">{{ formattedResult }}</span>
<span :style="indicatorSuffixClass" v-if="showSuffix">{{ suffixContent }}</span>
</div>
<div :style="indicatorNameWrapperStyle" v-if="indicatorNameShow">
<div v-if="indicatorNameShow && indicatorNamePositionBottom">
<div :style="indicatorNameWrapperStyle"></div>
<span :style="indicatorNameClass">{{ resultName }}</span>
</div>
</div>

View File

@@ -348,6 +348,11 @@ const handleFieldIdChange = (val: EnumValue) => {
}
})
customSort()
if (!res?.length) {
options.value = []
selectValue.value = config.value.multiple ? [] : undefined
config.value.defaultValue = selectValue.value
}
})
.finally(() => {
loading.value = false

View File

@@ -1821,6 +1821,9 @@ export default {
dimension_text_style: 'Name style',
dimension_letter_space: 'Name letter spacing',
name_value_spacing: 'Name/value spacing',
name_position: 'Position',
name_position_top: 'Top',
name_position_bottom: 'Bottom',
font_family: 'Font',
letter_space: 'Letter spacing',
font_shadow: 'Font shadow',
@@ -2117,7 +2120,10 @@ export default {
table_field_total_label: 'Field Alias',
table_row_header_freeze: 'Row Header Freeze',
value_formatter_total_out_percent: 'Show percentage',
enable_slider_tip: 'After enabling the slider, the carousel prompt will be disabled.'
enable_slider_tip: 'After enabling the slider, the carousel prompt will be disabled.',
liquid_show_border: 'Show Border',
liquid_border_width: 'Border Width',
liquid_border_distance: 'Border Distance'
},
dataset: {
field_value: 'Field Value',

View File

@@ -1777,6 +1777,9 @@ export default {
dimension_text_style: '名稱樣式',
dimension_letter_space: '名稱字間距',
name_value_spacing: '名稱/值間距',
name_position: '位置',
name_position_top: '上方',
name_position_bottom: '下方',
font_family: '字體',
letter_space: '字間距',
font_shadow: '字體陰影',
@@ -2058,7 +2061,10 @@ export default {
table_field_total_label: '字段別名',
table_row_header_freeze: '行頭凍結',
value_formatter_total_out_percent: '顯示佔比',
enable_slider_tip: '開啟縮略軸後,輪播提示將會失效'
enable_slider_tip: '開啟縮略軸後,輪播提示將會失效',
liquid_show_border: '顯示邊框',
liquid_border_width: '邊框寬度',
liquid_border_distance: '邊框間距'
},
dataset: {
field_value: '欄位值',

View File

@@ -1785,6 +1785,9 @@ export default {
dimension_text_style: '名称样式',
dimension_letter_space: '名称字间距',
name_value_spacing: '名称/值间距',
name_position: '位置',
name_position_top: '上方',
name_position_bottom: '下方',
font_family: '字体',
letter_space: '字间距',
font_shadow: '字体阴影',
@@ -2067,7 +2070,10 @@ export default {
table_field_total_label: '字段别名',
table_row_header_freeze: '行头冻结',
value_formatter_total_out_percent: '显示占比',
enable_slider_tip: '开启缩略轴后,轮播提示将会失效'
enable_slider_tip: '开启缩略轴后,轮播提示将会失效',
liquid_show_border: '显示边框',
liquid_border_width: '边框宽度',
liquid_border_distance: '边框间距'
},
dataset: {
field_value: '字段值',

View File

@@ -306,6 +306,7 @@ declare interface ChartBasicStyle {
show: boolean
field: string
summary: string
originName?: string
}>
/**
* 符号地图符号大小最小值
@@ -729,6 +730,18 @@ declare interface ChartMiscAttr {
* 水波图形状
*/
liquidShape: string
/**
* 水波图边框显示
*/
liquidShowBorder: boolean
/**
* 水波图边框宽度
*/
liquidBorderWidth: number
/**
* 水波图边框距离
*/
liquidBorderDistance: number
/**
* 地图倾角
*/
@@ -1301,6 +1314,10 @@ declare interface ChartIndicatorNameStyle {
* 指标/名称间距
*/
nameValueSpacing: number
/**
* 指标名称位置
*/
namePosition?: 'top' | 'bottom'
}
/**

View File

@@ -33,6 +33,7 @@ declare interface Chart {
tableRow: []
}
customCalc: any
customSumResult?: Record<string, any>
}
xAxis?: Axis[]
xAxisExt?: Axis[]

View File

@@ -9,7 +9,6 @@ import YAxisSelector from '@/views/chart/components/editor/editor-style/componen
import DualYAxisSelector from '@/views/chart/components/editor/editor-style/components/DualYAxisSelector.vue'
import TitleSelector from '@/views/chart/components/editor/editor-style/components/TitleSelector.vue'
import LegendSelector from '@/views/chart/components/editor/editor-style/components/LegendSelector.vue'
import SummarySelector from '@/views/chart/components/editor/editor-style/components/SummarySelector.vue'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import CollapseSwitchItem from '@/components/collapse-switch-item/src/CollapseSwitchItem.vue'
@@ -22,6 +21,7 @@ import BackgroundOverallCommon from '@/components/visualization/component-backgr
import TableHeaderSelector from '@/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue'
import TableCellSelector from '@/views/chart/components/editor/editor-style/components/table/TableCellSelector.vue'
import TableTotalSelector from '@/views/chart/components/editor/editor-style/components/table/TableTotalSelector.vue'
import SummarySelector from '@/views/chart/components/editor/editor-style/components/table/SummarySelector.vue'
import MiscStyleSelector from '@/views/chart/components/editor/editor-style/components/MiscStyleSelector.vue'
import IndicatorValueSelector from '@/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue'
import IndicatorNameSelector from '@/views/chart/components/editor/editor-style/components/IndicatorNameSelector.vue'

View File

@@ -45,6 +45,11 @@ const fontFamily = CHART_FONT_FAMILY_ORIGIN.concat(
)
const fontLetterSpace = CHART_FONT_LETTER_SPACE
const namePositionList = [
{ name: t('chart.name_position_top'), value: 'top' },
{ name: t('chart.name_position_bottom'), value: 'bottom' }
]
const state = reactive({
indicatorNameForm: JSON.parse(JSON.stringify(DEFAULT_INDICATOR_NAME_STYLE)),
basicStyleForm: {} as ChartBasicStyle
@@ -275,6 +280,27 @@ defineExpose({ getFormData })
@change="changeTitleStyle('nameValueSpacing')"
/>
</el-form-item>
<el-form-item
class="form-item name-value-spacing-input"
:class="'form-item-' + themes"
:label="t('chart.name_position')"
>
<el-select
:effect="themes"
v-model="state.indicatorNameForm.namePosition"
size="small"
style="width: 100%"
@change="changeTitleStyle('namePosition')"
>
<el-option
class="custom-style-option"
v-for="option in namePositionList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-form-item>
</el-form>
</div>
</template>

View File

@@ -553,6 +553,59 @@ onMounted(() => {
<!--gauge-end-->
<!--liquid-begin-->
<el-form-item
v-show="showProperty('liquidShowBorder')"
class="form-item"
:class="'form-item-' + themes"
>
<el-checkbox
:effect="themes"
v-model="state.miscForm.liquidShowBorder"
@change="changeMisc('liquidShowBorder')"
>
{{ t('chart.liquid_show_border') }}
</el-checkbox>
</el-form-item>
<el-row :guter="8">
<el-col :span="12">
<el-form-item
v-show="showProperty('liquidBorderWidth')"
class="form-item"
:label="t('chart.liquid_border_width')"
:class="'form-item-' + themes"
>
<el-input-number
v-model="state.miscForm.liquidBorderWidth"
:disabled="!state.miscForm.liquidShowBorder"
:effect="themes"
:min="1"
:max="100"
size="small"
controls-position="right"
@change="changeMisc('liquidBorderWidth')"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
v-show="showProperty('liquidBorderDistance')"
class="form-item"
:label="t('chart.liquid_border_distance')"
:class="'form-item-' + themes"
>
<el-input-number
v-model="state.miscForm.liquidBorderDistance"
:disabled="!state.miscForm.liquidShowBorder"
:effect="themes"
:min="1"
:max="100"
size="small"
controls-position="right"
@change="changeMisc('liquidBorderDistance')"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8">
<el-col :span="12">
<el-form-item

View File

@@ -1,10 +1,12 @@
<script setup lang="ts">
import { useI18n } from '@/hooks/web/useI18n'
import { computed, onMounted, PropType, reactive, watch } from 'vue'
import { computed, onMounted, PropType, reactive, watch, ref, nextTick, inject } from 'vue'
import { DEFAULT_BASIC_STYLE } from '@/views/chart/components/editor/util/chart'
import { cloneDeep, defaultsDeep, filter, find } from 'lodash-es'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import CustomAggrEdit from './CustomAggrEdit.vue'
const dvMainStore = dvMainStoreWithOut()
const { batchOptStatus } = storeToRefs(dvMainStore)
const { t } = useI18n()
@@ -30,6 +32,7 @@ const state = reactive({
show: boolean
field: string
summary: string
originName?: string
}
})
@@ -37,7 +40,12 @@ const emit = defineEmits(['onBasicStyleChange'])
const changeBasicStyle = (prop?: string, requestData = false) => {
emit('onBasicStyleChange', { data: state.basicStyleForm, requestData }, prop)
}
const changeSummaryType = () => {
if (state.currentAxisSummary.summary === 'custom' && !state.currentAxisSummary.originName) {
return
}
changeBasicStyle('seriesSummary')
}
watch(
[
() => props.chart.customAttr.basicStyle.showSummary,
@@ -65,15 +73,38 @@ const summaryTypes = [
{ key: 'sum', name: t('chart.sum') },
{ key: 'avg', name: t('chart.avg') },
{ key: 'max', name: t('chart.max') },
{ key: 'min', name: t('chart.min') }
// { key: 'stddev_pop', name: t('chart.stddev_pop') },
// { key: 'var_pop', name: t('chart.var_pop') }
{ key: 'min', name: t('chart.min') },
{ key: 'custom', name: t('commons.custom') }
]
function onSelectAxis(value) {
state.currentAxisSummary = find(state.basicStyleForm.seriesSummary, s => s.field === value)
}
const calcEdit = ref()
const editCalcField = ref(false)
const dimension = inject('dimension', () => [])
const quota = inject('quota', () => [])
const editField = () => {
editCalcField.value = true
nextTick(() => {
calcEdit.value.initEdit(
state.currentAxisSummary,
quota().filter(ele => ele.id !== '-1')
)
})
}
const closeEditCalc = () => {
editCalcField.value = false
}
const confirmEditCalc = () => {
calcEdit.value.setFieldForm()
const obj = cloneDeep(calcEdit.value.fieldForm)
state.currentAxisSummary.originName = obj.originName
setFieldDefaultValue(state.currentAxisSummary)
closeEditCalc()
changeSummaryType()
}
const init = () => {
const basicStyle = cloneDeep(props.chart.customAttr.basicStyle)
@@ -112,7 +143,14 @@ const init = () => {
state.currentAxisSummary = undefined
}
}
const setFieldDefaultValue = field => {
field.extField = 2
field.chartId = props.chart.id
field.datasetGroupId = props.chart.tableId
field.lastSyncTime = null
field.columnIndex = dimension().length + quota().length
field.deExtractType = field.deType
}
onMounted(() => {
init()
})
@@ -173,21 +211,41 @@ onMounted(() => {
<div class="indented-container">
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-select
v-model="state.currentAxisSummary.summary"
:class="'form-item-' + themes"
class="form-item"
:effect="themes"
:disabled="!state.currentAxisSummary.show"
@change="changeBasicStyle('seriesSummary')"
>
<el-option v-for="c in summaryTypes" :key="c.key" :value="c.key" :label="c.name" />
</el-select>
<el-col :span="state.currentAxisSummary.summary === 'custom' ? 19 : 22" :offset="2">
<el-select
v-model="state.currentAxisSummary.summary"
:class="'form-item-' + themes"
class="form-item"
:effect="themes"
:disabled="!state.currentAxisSummary.show"
@change="changeSummaryType"
>
<el-option v-for="c in summaryTypes" :key="c.key" :value="c.key" :label="c.name" />
</el-select>
</el-col>
<el-col v-if="state.currentAxisSummary.summary === 'custom'" :span="2" :offset="1">
<el-icon style="cursor: pointer">
<Setting @click="editField()" />
</el-icon>
</el-col>
</el-form-item>
</div>
</template>
</el-form>
</div>
<!--图表计算字段-->
<el-dialog
v-model="editCalcField"
width="1000px"
title="自定义总计"
:close-on-click-modal="false"
>
<custom-aggr-edit ref="calcEdit" />
<template #footer>
<el-button secondary @click="closeEditCalc()">{{ t('dataset.cancel') }} </el-button>
<el-button type="primary" @click="confirmEditCalc()">{{ t('dataset.confirm') }} </el-button>
</template>
</el-dialog>
</template>
<style scoped lang="less">

View File

@@ -344,7 +344,10 @@ export const DEFAULT_MISC: ChartMiscAttr = {
symbolSize: 4
}
}
}
},
liquidShowBorder: false,
liquidBorderWidth: 4,
liquidBorderDistance: 8
}
export const DEFAULT_MARK = {
@@ -548,7 +551,8 @@ export const DEFAULT_INDICATOR_NAME_STYLE: ChartIndicatorNameStyle = {
fontFamily: 'Microsoft YaHei',
letterSpace: 0,
fontShadow: false,
nameValueSpacing: 0
nameValueSpacing: 0,
namePosition: 'bottom'
}
export const DEFAULT_TITLE_STYLE_BASE: ChartTextStyle = {

View File

@@ -7,6 +7,7 @@ import { flow, hexColorToRGBA, parseJson } from '@/views/chart/components/js/uti
import { DEFAULT_MISC } from '@/views/chart/components/editor/util/chart'
import { valueFormatter } from '@/views/chart/components/js/formatter'
import { useI18n } from '@/hooks/web/useI18n'
import { defaultsDeep } from 'lodash-es'
const { t } = useI18n()
const DEFAULT_LIQUID_DATA = []
@@ -28,7 +29,15 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
'border-style': ['all'],
'basic-style-selector': ['colors', 'alpha'],
'label-selector': ['fontSize', 'color', 'labelFormatter'],
'misc-selector': ['liquidShape', 'liquidSize', 'liquidMaxType', 'liquidMaxField'],
'misc-selector': [
'liquidShape',
'liquidSize',
'liquidMaxType',
'liquidMaxField',
'liquidShowBorder',
'liquidBorderWidth',
'liquidBorderDistance'
],
'title-selector': [
'title',
'fontSize',
@@ -131,6 +140,15 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
radius: radius,
shape: shape
}
const { misc } = customAttr
if (misc?.liquidShowBorder) {
defaultsDeep(size, {
outline: {
border: misc.liquidBorderWidth ?? DEFAULT_MISC.liquidBorderWidth,
distance: misc.liquidBorderDistance ?? DEFAULT_MISC.liquidBorderDistance
}
})
}
return { ...options, ...size }
}

View File

@@ -354,7 +354,12 @@ export class TableNormal extends S2ChartView<TableSheet> {
s2Options.style.rowCfg = { heightByField }
// 计算汇总加入到数据里,冻结最后一行
s2Options.frozenTrailingRowCount = 1
const summaryObj = getSummaryRow(data, yAxis, basicStyle.seriesSummary) as any
const summaryObj = getSummaryRow(
data,
yAxis,
basicStyle.seriesSummary,
chart.data.customSumResult
) as any
data.push(summaryObj)
}
s2Options.dataCell = viewMeta => {

View File

@@ -2389,7 +2389,7 @@ const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => {
}
// 导出获取汇总行的函数
export function getSummaryRow(data, axis, sumCon = []) {
export function getSummaryRow(data, axis, sumCon = [], customSumResult = {}) {
const summaryObj = { SUMMARY: true }
for (let i = 0; i < axis.length; i++) {
const a = axis[i].dataeaseName
@@ -2473,6 +2473,9 @@ export function getSummaryRow(data, axis, sumCon = []) {
.toNumber() // 计算总体标准差
}
break
case 'custom':
summaryObj[a] = customSumResult[a]
break
}
}

View File

@@ -42,6 +42,11 @@ const props = defineProps({
type: String,
default: 'preview'
},
// 显示悬浮按钮
showPopBar: {
type: Boolean,
default: false
},
downloadStatus: {
required: false,
type: Boolean,
@@ -133,6 +138,7 @@ defineExpose({
:show-position="showPosition"
:download-status="downloadStatus"
:outer-screen-adaptor="screenAdaptor"
:show-pop-bar="showPopBar"
:show-linkage-button="showLinkageButton"
></de-preview>
</div>

View File

@@ -215,6 +215,7 @@ defineExpose({
:canvas-view-info="state.canvasViewInfoPreview"
:dv-info="state.dvInfo"
:cur-gap="state.curPreviewGap"
:show-pop-bar="true"
:show-linkage-button="false"
:is-selector="props.isSelector"
></de-preview>

View File

@@ -26,6 +26,7 @@ import {
exportLogPDF,
exportLogTemplate
} from '@/api/visualization/dataVisualization'
import { deepCopy } from '@/utils/utils'
const userStore = useUserStoreWithOut()
const userName = computed(() => userStore.getName)
@@ -100,6 +101,12 @@ const loadCanvasData = (dvId, weight?, ext?) => {
state.dvInfo = dvInfo
state.curPreviewGap = curPreviewGap
dataInitState.value = true
// 修复铺满全屏模版导出错位问题
if (props.showPosition !== 'multiplexing') {
dvMainStore.setCanvasStyle(deepCopy(canvasStyleResult))
dvMainStore.setComponentData(deepCopy(canvasDataResult))
}
if (props.showPosition === 'preview') {
dvMainStore.updateCurDvInfo(dvInfo)
nextTick(() => {

View File

@@ -1,15 +1,15 @@
<script lang="ts" setup>
import dvFolder from '@/assets/svg/dv-folder.svg'
import icon_dashboard from '@/assets/svg/icon_dashboard.svg'
import { getDefaultSettings } from '@/api/common'
import { useCache } from '@/hooks/web/useCache'
import icon_right_outlined from '@/assets/svg/icon_right_outlined.svg'
import icon_searchOutline_outlined from '@/assets/svg/icon_search-outline_outlined.svg'
import dvSortAsc from '@/assets/svg/dv-sort-asc.svg'
import dvSortDesc from '@/assets/svg/dv-sort-desc.svg'
import { ref, computed, onMounted, watch, onUnmounted } from 'vue'
import { ref, computed, onMounted, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { useCache } from '@/hooks/web/useCache'
import treeSort from '@/utils/treeSortUtils'
import { BusiTreeRequest } from '@/models/tree/TreeNode'
import { interactiveStoreWithOut } from '@/store/modules/interactive'
@@ -31,6 +31,7 @@ const interactiveStore = interactiveStoreWithOut()
const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
const { wsCache } = useCache('sessionStorage')
const { wsCache: wsCacheLocal } = useCache()
const { t } = useI18n()
const dfsTree = (ids, arr) => {
@@ -176,15 +177,19 @@ const getTree = async () => {
}
const setSortType = () => {
const type = wsCache.get('mobile-sort-type')
let sortType = sortList[Number(wsCacheLocal.get('TreeSort-backend')) ?? 1].value
const type = wsCacheLocal.get('mobile-sort-type') ?? sortType
sortTypeChange(type || curSortType.value)
}
onUnmounted(() => {
wsCache.set('mobile-sort-type', curSortType.value)
})
const sortTypeChangeMobile = type => {
wsCacheLocal.set('mobile-sort-type', type)
sortTypeChange(type)
}
onMounted(() => {
onMounted(async () => {
const defaultSort = await getDefaultSettings()
wsCacheLocal.set('TreeSort-backend', defaultSort['basic.defaultSort'] ?? '1')
getTree()
activeDirectName.value = wsCache.get('activeDirectName')
if (wsCache.get('activeTabbar') !== 'direct' || !activeDirectName.value) return
@@ -239,7 +244,7 @@ onMounted(() => {
</el-icon>
</template>
</el-input>
<el-dropdown @command="sortTypeChange" trigger="click">
<el-dropdown @command="sortTypeChangeMobile" trigger="click">
<el-icon class="filter-icon-span">
<Icon v-if="curSortType.includes('asc')" name="dv-sort-asc" class="opt-icon"
><dvSortAsc class="svg-icon opt-icon"

View File

@@ -301,8 +301,7 @@ onMounted(() => {
<style lang="less" scoped>
.ticket {
height: auto;
max-height: 560px;
height: 100%;
.ticket-model {
display: flex;
height: 22px;
@@ -378,12 +377,7 @@ onMounted(() => {
}
}
.ticket-table {
min-height: 156px;
padding: 0 0;
height: 50px;
overflow-y: overlay;
position: relative;
height: calc(100% - 124px);
height: 400px;
:deep(.ticket-exp-head) {
display: flex;

View File

@@ -295,7 +295,7 @@ const continueCreating = () => {
init(null, pid.value)
}
const handleShowFinishPage = ({ id, name, pid }) => {
const handleShowFinishPage = ({ id, name, pid: pidVal }) => {
isShowFinishPage()
.then(res => {
if (editDs.value || !res.data) {
@@ -308,7 +308,7 @@ const handleShowFinishPage = ({ id, name, pid }) => {
}
})
.finally(() => {
pid.value = pid
pid.value = pidVal
})
}

View File

@@ -19,7 +19,7 @@
</parent>
<properties>
<dataease.version>2.10.15</dataease.version>
<dataease.version>2.10.16</dataease.version>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>

View File

@@ -19,4 +19,6 @@ public class UserItem implements Serializable {
private Long id;
@Schema(description = "用户名称")
private String name;
@Schema(description = "账号")
private String account;
}

View File

@@ -4,6 +4,7 @@ import lombok.Data;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -68,7 +69,7 @@ public class Configuration {
protected static final Pattern HOST_PORT_PATTERN = Pattern.compile("//([^:/]+)(?::(\\d+))?");
protected static final Pattern PARAMETERS_PATTERN = Pattern.compile("([^&=]+)=([^&]*)");
private static final Pattern DB_NAME_PATTERN = Pattern.compile("//[^/]+/([^?]+)");
private Map<String, String> parameters;
private Map<String, String> parameters = new HashMap<>();
protected void parseHostAndPort(String jdbcUrl) {
Matcher matcher = HOST_PORT_PATTERN.matcher(jdbcUrl);
if (matcher.find()) {

View File

@@ -1,6 +1,8 @@
package io.dataease.extensions.view.dto;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.io.Serializable;
@@ -34,4 +36,11 @@ public class ChartViewFieldDTO extends ChartViewFieldBaseDTO implements Serializ
*/
@JsonIgnore
private FieldSource source;
/**
* 显隐
*/
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Boolean show;
private String field;
}