diff --git a/backend/src/main/java/io/dataease/base/domain/PanelGroup.java b/backend/src/main/java/io/dataease/base/domain/PanelGroup.java index db49938b5b..20862845e8 100644 --- a/backend/src/main/java/io/dataease/base/domain/PanelGroup.java +++ b/backend/src/main/java/io/dataease/base/domain/PanelGroup.java @@ -1,36 +1,35 @@ package io.dataease.base.domain; import java.io.Serializable; - -import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class PanelGroup implements Serializable { - @ApiModelProperty("ID") private String id; - @ApiModelProperty("名称") + private String name; - @ApiModelProperty("父ID") + private String pid; - @ApiModelProperty("级别") + private Integer level; - @ApiModelProperty("节点类型") + private String nodeType; - @ApiModelProperty("创建者") + private String createBy; - @ApiModelProperty("创建时间") + private Long createTime; - @ApiModelProperty("类型") + private String panelType; - @ApiModelProperty("源") + private String source; - @ApiModelProperty("拓展1") + private String extend1; - @ApiModelProperty("拓展2") + private String extend2; - @ApiModelProperty("重新标记") + private String remark; + private Boolean mobileLayout; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/base/domain/PanelGroupExample.java b/backend/src/main/java/io/dataease/base/domain/PanelGroupExample.java index 0455d45715..e7d03f3484 100644 --- a/backend/src/main/java/io/dataease/base/domain/PanelGroupExample.java +++ b/backend/src/main/java/io/dataease/base/domain/PanelGroupExample.java @@ -923,6 +923,66 @@ public class PanelGroupExample { addCriterion("remark not between", value1, value2, "remark"); return (Criteria) this; } + + public Criteria andMobileLayoutIsNull() { + addCriterion("mobile_layout is null"); + return (Criteria) this; + } + + public Criteria andMobileLayoutIsNotNull() { + addCriterion("mobile_layout is not null"); + return (Criteria) this; + } + + public Criteria andMobileLayoutEqualTo(Boolean value) { + addCriterion("mobile_layout =", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutNotEqualTo(Boolean value) { + addCriterion("mobile_layout <>", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutGreaterThan(Boolean value) { + addCriterion("mobile_layout >", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutGreaterThanOrEqualTo(Boolean value) { + addCriterion("mobile_layout >=", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutLessThan(Boolean value) { + addCriterion("mobile_layout <", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutLessThanOrEqualTo(Boolean value) { + addCriterion("mobile_layout <=", value, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutIn(List values) { + addCriterion("mobile_layout in", values, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutNotIn(List values) { + addCriterion("mobile_layout not in", values, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutBetween(Boolean value1, Boolean value2) { + addCriterion("mobile_layout between", value1, value2, "mobileLayout"); + return (Criteria) this; + } + + public Criteria andMobileLayoutNotBetween(Boolean value1, Boolean value2) { + addCriterion("mobile_layout not between", value1, value2, "mobileLayout"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { diff --git a/backend/src/main/java/io/dataease/base/domain/PanelGroupWithBLOBs.java b/backend/src/main/java/io/dataease/base/domain/PanelGroupWithBLOBs.java index b697bc31ac..7486de8f04 100644 --- a/backend/src/main/java/io/dataease/base/domain/PanelGroupWithBLOBs.java +++ b/backend/src/main/java/io/dataease/base/domain/PanelGroupWithBLOBs.java @@ -1,8 +1,6 @@ package io.dataease.base.domain; import java.io.Serializable; - -import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,9 +9,8 @@ import lombok.ToString; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PanelGroupWithBLOBs extends PanelGroup implements Serializable { - @ApiModelProperty("仪表板样式") private String panelStyle; - @ApiModelProperty("仪表板数据") + private String panelData; private static final long serialVersionUID = 1L; diff --git a/backend/src/main/java/io/dataease/base/mapper/PanelGroupMapper.xml b/backend/src/main/java/io/dataease/base/mapper/PanelGroupMapper.xml index 0e6fc9a125..758fa2458b 100644 --- a/backend/src/main/java/io/dataease/base/mapper/PanelGroupMapper.xml +++ b/backend/src/main/java/io/dataease/base/mapper/PanelGroupMapper.xml @@ -14,6 +14,7 @@ + @@ -79,7 +80,7 @@ id, `name`, pid, `level`, node_type, create_by, create_time, panel_type, `source`, - extend1, extend2, remark + extend1, extend2, remark, mobile_layout panel_style, panel_data @@ -137,12 +138,14 @@ `level`, node_type, create_by, create_time, panel_type, `source`, extend1, extend2, remark, - panel_style, panel_data) + mobile_layout, panel_style, panel_data + ) values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{pid,jdbcType=VARCHAR}, #{level,jdbcType=INTEGER}, #{nodeType,jdbcType=VARCHAR}, #{createBy,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{panelType,jdbcType=VARCHAR}, #{source,jdbcType=VARCHAR}, #{extend1,jdbcType=VARCHAR}, #{extend2,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, - #{panelStyle,jdbcType=LONGVARCHAR}, #{panelData,jdbcType=LONGVARCHAR}) + #{mobileLayout,jdbcType=BIT}, #{panelStyle,jdbcType=LONGVARCHAR}, #{panelData,jdbcType=LONGVARCHAR} + ) insert into panel_group @@ -183,6 +186,9 @@ remark, + + mobile_layout, + panel_style, @@ -227,6 +233,9 @@ #{remark,jdbcType=VARCHAR}, + + #{mobileLayout,jdbcType=BIT}, + #{panelStyle,jdbcType=LONGVARCHAR}, @@ -280,6 +289,9 @@ remark = #{record.remark,jdbcType=VARCHAR}, + + mobile_layout = #{record.mobileLayout,jdbcType=BIT}, + panel_style = #{record.panelStyle,jdbcType=LONGVARCHAR}, @@ -305,6 +317,7 @@ extend1 = #{record.extend1,jdbcType=VARCHAR}, extend2 = #{record.extend2,jdbcType=VARCHAR}, remark = #{record.remark,jdbcType=VARCHAR}, + mobile_layout = #{record.mobileLayout,jdbcType=BIT}, panel_style = #{record.panelStyle,jdbcType=LONGVARCHAR}, panel_data = #{record.panelData,jdbcType=LONGVARCHAR} @@ -324,7 +337,8 @@ `source` = #{record.source,jdbcType=VARCHAR}, extend1 = #{record.extend1,jdbcType=VARCHAR}, extend2 = #{record.extend2,jdbcType=VARCHAR}, - remark = #{record.remark,jdbcType=VARCHAR} + remark = #{record.remark,jdbcType=VARCHAR}, + mobile_layout = #{record.mobileLayout,jdbcType=BIT} @@ -365,6 +379,9 @@ remark = #{remark,jdbcType=VARCHAR}, + + mobile_layout = #{mobileLayout,jdbcType=BIT}, + panel_style = #{panelStyle,jdbcType=LONGVARCHAR}, @@ -387,6 +404,7 @@ extend1 = #{extend1,jdbcType=VARCHAR}, extend2 = #{extend2,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, + mobile_layout = #{mobileLayout,jdbcType=BIT}, panel_style = #{panelStyle,jdbcType=LONGVARCHAR}, panel_data = #{panelData,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} @@ -403,7 +421,8 @@ `source` = #{source,jdbcType=VARCHAR}, extend1 = #{extend1,jdbcType=VARCHAR}, extend2 = #{extend2,jdbcType=VARCHAR}, - remark = #{remark,jdbcType=VARCHAR} + remark = #{remark,jdbcType=VARCHAR}, + mobile_layout = #{mobileLayout,jdbcType=BIT} where id = #{id,jdbcType=VARCHAR} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index 0c62f9664e..26e97f8a72 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -78,7 +78,8 @@ public class PanelGroupService { @Transactional public PanelGroup saveOrUpdate(PanelGroupRequest request) { try { - panelViewService.syncPanelViews(request); + Boolean mobileLayout = panelViewService.syncPanelViews(request); + request.setMobileLayout(mobileLayout); } catch (Exception e) { e.printStackTrace(); LOGGER.error("更新panelView出错panelId:{}", request.getId()); diff --git a/backend/src/main/java/io/dataease/service/panel/PanelViewService.java b/backend/src/main/java/io/dataease/service/panel/PanelViewService.java index e16b6dfc3b..d5e61935cc 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelViewService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelViewService.java @@ -73,7 +73,8 @@ public class PanelViewService { } @Transactional(propagation=Propagation.REQUIRES_NEW) - public void syncPanelViews(PanelGroupWithBLOBs panelGroup){ + public Boolean syncPanelViews(PanelGroupWithBLOBs panelGroup){ + Boolean mobileLayout = false; String panelId = panelGroup.getId(); Assert.notNull(panelId, "panelId cannot be null"); String panelData = panelGroup.getPanelData(); @@ -85,12 +86,16 @@ public class PanelViewService { if("view".equals(jsonObject.getString("type"))){ panelViewInsertDTOList.add(new PanelViewInsertDTO(jsonObject.getJSONObject("propValue").getString("viewId"),panelId)); } + if(jsonObject.getBoolean("mobileSelected")!=null&&jsonObject.getBoolean("mobileSelected")){ + mobileLayout = true; + } } extPanelViewMapper.deleteWithPanelId(panelId); if(CollectionUtils.isNotEmpty(panelViewInsertDTOList)){ extPanelViewMapper.savePanelView(panelViewInsertDTOList); } } + return mobileLayout; } public List detailList(String panelId){ diff --git a/backend/src/main/resources/db/migration/V29__de1.6.sql b/backend/src/main/resources/db/migration/V29__de1.6.sql index 79c52a4bcf..ef2d50f9cf 100644 --- a/backend/src/main/resources/db/migration/V29__de1.6.sql +++ b/backend/src/main/resources/db/migration/V29__de1.6.sql @@ -8,4 +8,7 @@ CREATE TABLE `dataset_row_permissions` ( `filter` longtext DEFAULT NULL COMMENT '数值', `update_time` bigint(13) NULL DEFAULT NULL, PRIMARY KEY (`id`) -)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; \ No newline at end of file +)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; + +ALTER TABLE `panel_group` +ADD COLUMN `mobile_layout` tinyint(1) NULL DEFAULT 0 COMMENT '启用移动端布局' AFTER `remark`; diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index 49b7d1fe39..aed26555b0 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -60,9 +60,12 @@ - - -
+ + + + + + diff --git a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue index eb3c142c43..8a22079c52 100644 --- a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue @@ -30,6 +30,7 @@ :search-count="searchCount" :h="config.style.height" :edit-mode="'preview'" + :terminal="terminal" /> diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index f3b09c3441..cd99185ff2 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -229,6 +229,7 @@ export default { const canvasWidth = document.getElementById('canvasInfoMain').offsetWidth this.scaleWidth = (canvasWidth) * 100 / this.canvasStyleData.width // 获取宽度比 this.scaleHeight = canvasHeight * 100 / this.canvasStyleData.height// 获取高度比 + this.$store.commit('setPreviewCanvasScale', (this.scaleWidth / 100), (this.scaleHeight / 100)) this.handleScaleChange() }, resetID(data) { diff --git a/frontend/src/components/canvas/components/Editor/index.vue b/frontend/src/components/canvas/components/Editor/index.vue index 85b770d1cd..5693a63d6c 100644 --- a/frontend/src/components/canvas/components/Editor/index.vue +++ b/frontend/src/components/canvas/components/Editor/index.vue @@ -1195,6 +1195,7 @@ export default { matrixStyleOriginWidth: this.matrixStyle.originWidth, matrixStyleOriginHeight: this.matrixStyle.originHeight }) + this.$store.commit('setPreviewCanvasScale', this.scalePointWidth, this.scalePointHeight) } }, getShapeStyleIntDeDrag(style, prop) { diff --git a/frontend/src/components/canvas/custom-component/UserView.vue b/frontend/src/components/canvas/custom-component/UserView.vue index cc8c702f86..78518d257e 100644 --- a/frontend/src/components/canvas/custom-component/UserView.vue +++ b/frontend/src/components/canvas/custom-component/UserView.vue @@ -69,6 +69,7 @@ import DrillPath from '@/views/chart/view/DrillPath' import { areaMapping } from '@/api/map/map' import ChartComponentG2 from '@/views/chart/components/ChartComponentG2' import EditBarView from '@/components/canvas/components/Editor/EditBarView' +import { customAttrTrans, customStyleTrans, recursionTransObj } from '@/components/canvas/utils/style' export default { name: 'UserView', @@ -108,6 +109,10 @@ export default { type: Boolean, require: false, default: true + }, + terminal: { + type: String, + default: 'pc' } }, data() { @@ -125,12 +130,23 @@ export default { msg: '' }, timeMachine: null, + scaleTimeMachine: null, changeIndex: 0, + changeScaleIndex: 0, pre: null, - preCanvasPanel: null + preCanvasPanel: null, + sourceCustomAttrStr: null, + sourceCustomStyleStr: null } }, computed: { + scaleCoefficient() { + if (this.terminal === 'pc') { + return 1.1 + } else { + return 4 + } + }, editBarViewShowFlag() { return this.active && this.inTab }, @@ -209,7 +225,8 @@ export default { 'canvasStyleData', 'nowPanelTrackInfo', 'nowPanelJumpInfo', - 'publicLinkStatus' + 'publicLinkStatus', + 'previewCanvasScale' ]) }, @@ -268,6 +285,16 @@ export default { if (newVal === 'map' && newVal !== oldVal) { this.initAreas() } + }, + // 监控缩放比例 + previewCanvasScale: { + handler(newVal, oldVal) { + console.log('previewCanvasScale:' + JSON.stringify(this.previewCanvasScale)) + this.destroyScaleTimeMachine() + this.changeScaleIndex++ + this.chartScale(this.changeScaleIndex) + }, + deep: true } }, created() { @@ -277,6 +304,24 @@ export default { } }, methods: { + // 根据仪表板的缩放比例,修改视图内部参数 + mergeScale() { + const scale = Math.min(this.previewCanvasScale.scalePointWidth, this.previewCanvasScale.scalePointHeight) * this.scaleCoefficient + const customAttrChart = JSON.parse(this.sourceCustomAttrStr) + const customStyleChart = JSON.parse(this.sourceCustomStyleStr) + recursionTransObj(customAttrTrans, customAttrChart, scale) + recursionTransObj(customStyleTrans, customStyleChart, scale) + this.chart = { + ...this.chart, + customAttr: JSON.stringify(customAttrChart), + customStyle: JSON.stringify(customStyleChart) + } + // console.log('customAttrChartSource:' + JSON.stringify(JSON.parse(this.sourceCustomAttrStr))) + // console.log('customAttrChart:' + JSON.stringify(customAttrChart)) + // console.log('customStyleChartSource:' + JSON.stringify(JSON.parse(this.sourceCustomStyleStr))) + // console.log('customStyleChart:' + JSON.stringify(customStyleChart)) + this.mergeStyle() + }, mergeStyle() { if ((this.requestStatus === 'success' || this.requestStatus === 'merging') && this.chart.stylePriority === 'panel' && this.canvasStyleData.chart) { const customAttrChart = JSON.parse(this.chart.customAttr) @@ -318,6 +363,8 @@ export default { // 将视图传入echart组件 if (response.success) { this.chart = response.data + this.sourceCustomAttrStr = this.chart.customAttr + this.sourceCustomStyleStr = this.chart.customStyle this.chart.drillFields = this.chart.drillFields ? JSON.parse(this.chart.drillFields) : [] if (!response.data.drill) { this.drillClickDimensionList.splice(this.drillClickDimensionList.length - 1, 1) @@ -326,7 +373,7 @@ export default { this.drillFilters = JSON.parse(JSON.stringify(response.data.drillFilters ? response.data.drillFilters : [])) this.drillFields = JSON.parse(JSON.stringify(response.data.drillFields)) this.requestStatus = 'merging' - this.mergeStyle() + this.mergeScale() this.requestStatus = 'success' this.httpRequest.status = true } else { @@ -533,6 +580,10 @@ export default { this.timeMachine && clearTimeout(this.timeMachine) this.timeMachine = null }, + destroyScaleTimeMachine() { + this.scaleTimeMachine && clearTimeout(this.scaleTimeMachine) + this.scaleTimeMachine = null + }, // 边框变化 chartResize(index) { @@ -546,6 +597,18 @@ export default { } }, + // 边框变化 修改视图内部参数 + chartScale(index) { + if (this.$refs[this.element.propValue.id]) { + this.scaleTimeMachine = setTimeout(() => { + if (index === this.changeScaleIndex) { + this.mergeScale() + } + this.destroyScaleTimeMachine() + }, 100) + } + }, + renderComponent() { return this.chart.render } diff --git a/frontend/src/components/canvas/utils/style.js b/frontend/src/components/canvas/utils/style.js index 0bc0e2145c..6c0ca6d9d0 100644 --- a/frontend/src/components/canvas/utils/style.js +++ b/frontend/src/components/canvas/utils/style.js @@ -75,7 +75,7 @@ export function colorRgb(color, opacity) { sColor = sColorNew } // 处理六位的颜色值 - var sColorChange = [] + const sColorChange = [] for (let i = 1; i < 7; i += 2) { sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2))) } @@ -88,3 +88,100 @@ export function colorRgb(color, opacity) { return sColor } } + +export const customAttrTrans = { + 'size': [ + 'barWidth', + 'lineWidth', + 'lineSymbolSize', + 'pieInnerRadius', + 'pieOuterRadius', + 'funnelWidth', // 漏斗图 最大宽度 + 'tableTitleFontSize', + 'tableItemFontSize', + 'tableTitleHeight', + 'tableItemHeight', + 'dimensionFontSize', + 'quotaFontSize', + 'spaceSplit', // 间隔 + 'scatterSymbolSize', // 气泡大小,散点图 + 'treemapWidth', // 矩形树图 + 'treemapHeight', + 'radarSize'// 雷达占比 + ], + 'label': [ + 'fontSize' + ], + 'tooltip': { + 'textStyle': ['fontSize'] + } +} +export const customStyleTrans = { + 'text': ['fontSize'], + 'legend': { + 'textStyle': ['fontSize'] + }, + 'xAxis': { + 'nameTextStyle': ['fontSize'], + 'axisLabel': ['fontSize'], + 'splitLine': { + 'lineStyle': ['width'] + } + }, + 'yAxis': { + 'nameTextStyle': ['fontSize'], + 'axisLabel': ['fontSize'], + 'splitLine': { + 'lineStyle': ['width'] + } + }, + 'split': { + 'name': ['fontSize'], + 'axisLine': { + 'lineStyle': ['width'] + }, + 'axisTick': { + 'lineStyle': ['width'] + }, + 'axisLabel': ['margin', 'fontSize'], + 'splitLine': { + 'lineStyle': ['width'] + } + } +} + +export function getScaleValue(propValue, scale) { + const propValueTemp = Math.round(propValue * scale) + return propValueTemp > 1 ? propValueTemp : 1 +} + +export function recursionTransObj(template, infoObj, scale) { + // console.log('recursionObj++') + for (const templateKey in template) { + // 如果是数组 进行赋值计算 + if (template[templateKey] instanceof Array) { + template[templateKey].forEach(templateProp => { + if (infoObj[templateKey] && infoObj[templateKey][templateProp]) { + const afterValue = getScaleValue(infoObj[templateKey][templateProp], scale) + console.log(templateKey + '.' + templateProp + '=' + infoObj[templateKey][templateProp] + ';scale:' + scale + ',after:' + afterValue) + infoObj[templateKey][templateProp] = afterValue + } + }) + } else { + // 如果是对象 继续进行递归 + if (infoObj[templateKey]) { + recursionTransObj(template[templateKey], infoObj[templateKey], scale) + } + } + } +} + +export function componentScalePublic(chartInfo, heightScale, widthScale) { + const scale = Math.min(heightScale, widthScale) + // attr 缩放转换 + recursionTransObj(this.customAttrTrans, chartInfo.customAttr, scale) + // style 缩放转换 + recursionTransObj(this.customStyleTrans, chartInfo.customStyle, scale) + return chartInfo +} + diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index b82b4c4f39..c46c7b479b 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -57,6 +57,11 @@ const data = { curComponent: null, curCanvasScale: null, curComponentIndex: null, + // 预览仪表板缩放信息 + previewCanvasScale: { + scalePointWidth: 1, + scalePointHeight: 1 + }, // 点击画布时是否点中组件,主要用于取消选中组件用。 // 如果没点中组件,并且在画布空白处弹起鼠标,则取消当前组件的选中状态 isClickComponent: false, @@ -135,7 +140,14 @@ const data = { setCurCanvasScale(state, curCanvasScale) { state.curCanvasScale = curCanvasScale }, - + setPreviewCanvasScale(state, scaleWidth, scaleHeight) { + if (scaleWidth) { + state.previewCanvasScale.scalePointWidth = scaleWidth + } + if (scaleHeight) { + state.previewCanvasScale.scalePointHeight = scaleHeight + } + }, setShapeStyle({ curComponent, canvasStyleData, curCanvasScale }, { top, left, width, height, rotate }) { if (top || top === 0) curComponent.style.top = (top / curCanvasScale.scalePointHeight) + 0.0000001 if (left || left === 0) curComponent.style.left = (left / curCanvasScale.scalePointWidth) + 0.0000001