diff --git a/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java b/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java index 4b6ffc6c28..0c8aeb4e11 100644 --- a/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java +++ b/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java @@ -43,10 +43,9 @@ public class SqlparserUtils { } SqlParser.Config config = - SqlParser.configBuilder() - .setLex(Lex.JAVA) - .setIdentifierMaxLength(256) - .build(); + SqlParser.config() + .withLex(Lex.JAVA) + .withIdentifierMaxLength(256); SqlParser sqlParser = SqlParser.create(tmpSql, config); SqlNode sqlNode; try { diff --git a/core/core-backend/src/main/java/io/dataease/dataset/utils/SqlUtils.java b/core/core-backend/src/main/java/io/dataease/dataset/utils/SqlUtils.java index fb29110bc6..23a12baed7 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/utils/SqlUtils.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/utils/SqlUtils.java @@ -21,10 +21,9 @@ public class SqlUtils { } SqlParser.Config config = - SqlParser.configBuilder() - .setLex(Lex.JAVA) - .setIdentifierMaxLength(256) - .build(); + SqlParser.config() + .withLex(Lex.JAVA) + .withIdentifierMaxLength(256); // 创建解析器 SqlParser sqlParser = SqlParser .create(sql, config); diff --git a/core/core-backend/src/main/java/io/dataease/engine/constant/SQLConstants.java b/core/core-backend/src/main/java/io/dataease/engine/constant/SQLConstants.java index 34b57a47f7..130d0c2e3d 100644 --- a/core/core-backend/src/main/java/io/dataease/engine/constant/SQLConstants.java +++ b/core/core-backend/src/main/java/io/dataease/engine/constant/SQLConstants.java @@ -73,7 +73,7 @@ public class SQLConstants { public static final String DEFAULT_INT_FORMAT = "DECIMAL(18,0)"; - public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(27,8)"; + public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(26,8)"; public static final String WHERE_VALUE_NULL = "(NULL,'')"; diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java index 539c3cda64..7397c82bea 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java @@ -101,6 +101,7 @@ public class DataVisualizationServer implements DataVisualizationApi { } } + @DeLog(id = "#p0", ot = LogOT.READ, stExp = "#p1") @Override @XpackInteract(value = "dataVisualizationServer", original = true) public DataVisualizationVO findById(Long dvId, String busiFlag) { diff --git a/core/core-frontend/.env.base b/core/core-frontend/.env.base index d9c575a520..8a93b1c1c6 100644 --- a/core/core-frontend/.env.base +++ b/core/core-frontend/.env.base @@ -1,3 +1,3 @@ # 接口前缀 -VITE_API_BASEPATH="/de2api" +VITE_API_BASEPATH="./de2api" VITE_VERSION="0.0.0" diff --git a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue index 153eeb445c..7a7be23b11 100644 --- a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue +++ b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue @@ -232,6 +232,7 @@ const { } = toRefs(props) const domId = ref('shape-id-' + element.value.id) const pointList = ['lt', 't', 'rt', 'r', 'rb', 'b', 'lb', 'l'] +const pointCorner = ['lt', 'rt', 'rb', 'lb'] const pointList2 = ['r', 'l'] const initialAngle = { // 每个点对应的初始角度 @@ -608,6 +609,7 @@ const handleMouseDownOnPoint = (point, e) => { let isFirst = true const needLockProportion = isNeedLockProportion() + const originRadio = curComponent.value.style.width / curComponent.value.style.height const move = moveEvent => { // 第一次点击时也会触发 move,所以会有“刚点击组件但未移动,组件的大小却改变了”的情况发生 // 因此第一次点击时不触发 move 事件 @@ -628,6 +630,27 @@ const handleMouseDownOnPoint = (point, e) => { }) //Temp dataV坐标偏移 offsetDataVAdaptor(style, point) + // 保持宽搞比例调整 + if (curComponent.value.maintainRadio) { + // 高度偏移量 + const heightOffset = style.height - defaultStyle.value.height + // 宽度偏移量 + const widthOffset = style.width - defaultStyle.value.width + // 保持宽高比例是相对宽度偏移量 + const adaptorWidthOffset = heightOffset * originRadio + // 保持宽高比例是相对高度偏移量 + const adaptorHeightOffset = widthOffset / originRadio + if (pointCorner.includes(point)) { + style.height = defaultStyle.value.height + adaptorHeightOffset + } else if (Math.abs(widthOffset) > Math.abs(adaptorWidthOffset)) { + // 调整高度 + style.height = defaultStyle.value.height + adaptorHeightOffset + } else { + // 调整宽度 + style.width = defaultStyle.value.width + adaptorWidthOffset + } + } + dvMainStore.setShapeStyle(style) // 矩阵逻辑 如果当前是仪表板(矩阵模式)则要进行矩阵重排 dashboardActive.value && emit('onResizing', moveEvent) diff --git a/core/core-frontend/src/components/visualization/common/ComponentPosition.vue b/core/core-frontend/src/components/visualization/common/ComponentPosition.vue index 1216dc57ea..eb09577e50 100644 --- a/core/core-frontend/src/components/visualization/common/ComponentPosition.vue +++ b/core/core-frontend/src/components/visualization/common/ComponentPosition.vue @@ -17,6 +17,17 @@ + + + 保持宽高比 + + @@ -71,9 +82,19 @@ const onPositionChange = key => { if (!positionMounted.value[key]) { positionMounted.value[key] = 0 } + const originRadio = curComponent.value.style.width / curComponent.value.style.height curComponent.value.style[key] = Math.round( (positionMounted.value[key] * canvasStyleData.value.scale) / 100 ) + if (curComponent.value.maintainRadio) { + if (key === 'width') { + curComponent.value.style['height'] = curComponent.value.style['width'] / originRadio + positionMounted.value['height'] = Math.round(positionMounted.value['width'] / originRadio) + } else if (key === 'height') { + curComponent.value.style['width'] = curComponent.value.style['height'] * originRadio + positionMounted.value['width'] = Math.round(positionMounted.value['height'] * originRadio) + } + } if (curComponent.value.component === 'Group') { //如果当前组件是Group分组 则要进行内部组件深度计算 @@ -84,6 +105,10 @@ const onPositionChange = key => { snapshotStore.recordSnapshotCache() } +const maintainRadioChange = () => { + snapshotStore.recordSnapshotCache() +} + const positionInit = () => { if (curComponent.value) { Object.keys(positionMounted.value).forEach(key => { diff --git a/core/core-frontend/src/config/axios/service.ts b/core/core-frontend/src/config/axios/service.ts index 788a77e704..cad708a721 100644 --- a/core/core-frontend/src/config/axios/service.ts +++ b/core/core-frontend/src/config/axios/service.ts @@ -104,7 +104,7 @@ service.interceptors.request.use( config.data = qs.stringify(config.data) } if (embeddedStore.baseUrl) { - config.baseURL = embeddedStore.baseUrl + 'de2api/' + config.baseURL = PATH_URL } if (linkStore.getLinkToken) { diff --git a/core/core-frontend/src/custom-component/component-list.ts b/core/core-frontend/src/custom-component/component-list.ts index f97c190f74..d2c788cfd0 100644 --- a/core/core-frontend/src/custom-component/component-list.ts +++ b/core/core-frontend/src/custom-component/component-list.ts @@ -58,6 +58,7 @@ export const commonAttr = { events: {}, groupStyle: {}, // 当一个组件成为 Group 的子组件时使用 isLock: false, // 是否锁定组件 + maintainRadio: false, // 布局时保持宽高比例 isShow: true, // 是否显示组件 collapseName: ['position', 'background', 'style', 'picture'], // 编辑组件时记录当前使用的是哪个折叠面板,再次回来时恢复上次打开的折叠面板,优化用户体验 linkage: { diff --git a/core/core-frontend/src/custom-component/indicator/DeIndicator.vue b/core/core-frontend/src/custom-component/indicator/DeIndicator.vue index 4242a34d4b..5b37c41ced 100644 --- a/core/core-frontend/src/custom-component/indicator/DeIndicator.vue +++ b/core/core-frontend/src/custom-component/indicator/DeIndicator.vue @@ -12,6 +12,7 @@ import { DEFAULT_INDICATOR_STYLE } from '@/views/chart/components/editor/util/chart' import { valueFormatter } from '@/views/chart/components/js/formatter' +import { hexColorToRGBA } from '@/views/chart/components/js/util' const props = defineProps({ view: { @@ -222,15 +223,21 @@ const renderChart = async view => { if (!view) { return } + + const TEMP_DEFAULT_CHART = cloneDeep(BASE_VIEW_CONFIG) + delete TEMP_DEFAULT_CHART.customAttr.basicStyle.alpha + const chart = deepCopy({ - ...defaultsDeep(view, cloneDeep(BASE_VIEW_CONFIG)), + ...defaultsDeep(view, TEMP_DEFAULT_CHART), data: chartData.value }) + recursionTransObj(customAttrTrans, chart.customAttr, scale.value, terminal.value) recursionTransObj(customStyleTrans, chart.customStyle, scale.value, terminal.value) if (chart.customAttr) { const customAttr = chart.customAttr + if (customAttr.indicator) { switch (customAttr.indicator.hPosition) { case 'left': @@ -254,6 +261,15 @@ const renderChart = async view => { } indicatorColor.value = customAttr.indicator.color + let suffixColor = customAttr.indicator.suffixColor + + if (customAttr.basicStyle && customAttr.basicStyle.alpha !== undefined) { + indicatorColor.value = hexColorToRGBA( + customAttr.basicStyle.colors[0], + customAttr.basicStyle.alpha + ) + suffixColor = hexColorToRGBA(customAttr.basicStyle.colors[1], customAttr.basicStyle.alpha) + } indicatorClass.value = { color: thresholdColor.value, @@ -270,7 +286,7 @@ const renderChart = async view => { } indicatorSuffixClass.value = { - color: customAttr.indicator.suffixColor, + color: suffixColor, 'font-size': customAttr.indicator.suffixFontSize + 'px', 'font-family': defaultTo( CHART_CONT_FAMILY_MAP[customAttr.indicator.suffixFontFamily], @@ -287,9 +303,15 @@ const renderChart = async view => { suffixContent.value = defaultTo(customAttr.indicator.suffix, '') } if (customAttr.indicatorName && customAttr.indicatorName.show) { + let nameColor = customAttr.indicatorName.color + + if (customAttr.basicStyle && customAttr.basicStyle.alpha !== undefined) { + nameColor = hexColorToRGBA(customAttr.basicStyle.colors[2], customAttr.basicStyle.alpha) + } + indicatorNameShow.value = true indicatorNameClass.value = { - color: customAttr.indicatorName.color, + color: nameColor, 'font-size': customAttr.indicatorName.fontSize + 'px', 'font-family': defaultTo( CHART_CONT_FAMILY_MAP[customAttr.indicatorName.fontFamily], diff --git a/core/core-frontend/src/layout/components/ToolboxCfg.vue b/core/core-frontend/src/layout/components/ToolboxCfg.vue index 28fadec780..3ed1672fa4 100644 --- a/core/core-frontend/src/layout/components/ToolboxCfg.vue +++ b/core/core-frontend/src/layout/components/ToolboxCfg.vue @@ -44,7 +44,7 @@ onMounted(() => { popper-class="toolbox-top-popover" placement="bottom-end" width="208" - trigger="click" + trigger="hover" > import { useI18n } from '@/hooks/web/useI18n' -import { PropType, toRefs, nextTick, watch } from 'vue' +import { PropType, toRefs, nextTick, watch, ref } from 'vue' import MiscSelector from '@/views/chart/components/editor/editor-style/components/MiscSelector.vue' import LabelSelector from '@/views/chart/components/editor/editor-style/components/LabelSelector.vue' import TooltipSelector from '@/views/chart/components/editor/editor-style/components/TooltipSelector.vue' @@ -90,6 +90,9 @@ const emit = defineEmits([ 'onIndicatorNameChange' ]) +const indicatorValueRef = ref() +const indicatorNameRef = ref() + const showProperties = (property: EditorProperty) => properties.value?.includes(property) const onMiscChange = (val, prop) => { @@ -117,11 +120,19 @@ const onTextChange = (val, prop) => { } const onIndicatorChange = (val, prop) => { - state.initReady && emit('onIndicatorChange', val, prop) + const value = { indicatorValue: val, indicatorName: undefined } + if (prop === 'color' || prop === 'suffixColor') { + value.indicatorName = indicatorNameRef.value?.getFormData() + } + state.initReady && emit('onIndicatorChange', value, prop) } const onIndicatorNameChange = (val, prop) => { - state.initReady && emit('onIndicatorNameChange', val, prop) + const value = { indicatorName: val, indicatorValue: undefined } + if (prop === 'color') { + value.indicatorValue = indicatorValueRef.value?.getFormData() + } + state.initReady && emit('onIndicatorNameChange', value, prop) } const onLegendChange = (val, prop) => { @@ -243,6 +254,7 @@ watch( title="指标值" > { } const init = () => { + const TEMP_DEFAULT_BASIC_STYLE = cloneDeep(DEFAULT_BASIC_STYLE) + delete TEMP_DEFAULT_BASIC_STYLE.alpha + + state.basicStyleForm = defaultsDeep( + cloneDeep(props.chart?.customAttr?.basicStyle), + cloneDeep(TEMP_DEFAULT_BASIC_STYLE) + ) + const customText = defaultsDeep( cloneDeep(props.chart?.customAttr?.indicatorName), cloneDeep(DEFAULT_INDICATOR_NAME_STYLE) ) + if (state.basicStyleForm.alpha !== undefined) { + const color = hexColorToRGBA(state.basicStyleForm.colors[2], state.basicStyleForm.alpha) + + customText.color = color + } + state.indicatorNameForm = cloneDeep(customText) //第一次颜色可能赋值失败,单独赋值一次 @@ -85,6 +102,12 @@ watch( }, { deep: true } ) + +function getFormData() { + return state.indicatorNameForm +} + +defineExpose({ getFormData })