diff --git a/report-ui/src/store/index.js b/report-ui/src/store/index.js index f011f382..89cec40a 100644 --- a/report-ui/src/store/index.js +++ b/report-ui/src/store/index.js @@ -7,6 +7,7 @@ import app from './modules/app' import user from './modules/user' import cacheView from './modules/cachaView' import help from './modules/help' +import designer from './modules/designer' Vue.use(Vuex) @@ -18,7 +19,8 @@ const store = new Vuex.Store({ app, user, cacheView, - help + help, + designer }, state: { }, plugins: [initPlugin], diff --git a/report-ui/src/store/modules/designer.js b/report-ui/src/store/modules/designer.js new file mode 100644 index 00000000..ae275cac --- /dev/null +++ b/report-ui/src/store/modules/designer.js @@ -0,0 +1,42 @@ +/* + * @Author: chengsl + * @Date: 2022-11-08 10:30:37 + * @LastEditors: chengsl + * @LastEditTime: 2023-02-24 09:54:34 + * @Description: 设计器公用变量 + */ + +const designer = { + state: { + allComponentLinkage: [], // 所有组件之间的联动配置 + }, + + mutations: { + SET_ALL_COMPONENT_LINKAGE: (state, params) => { + var { index = -1, widgetId = '', linkageArr } = params + try { + console.log('params---', params) + linkageArr = linkageArr.map(item => { + const arr = item.widgetValue.split('-$-') + return { + originId: widgetId, + targetId: arr[0], + targetName: arr[1], + paramsConfig: item.paramsConfig + } + }) + } catch (error) { + linkageArr = [] // 兼容异常错误导致页面加载不出来 + } + state.allComponentLinkage[index] = { + index: +index, + widgetId, + linkageArr + } + } + }, + + actions: {} +} + +export default designer diff --git a/report-ui/src/views/bigscreenDesigner/designer/components/componentLinkage.vue b/report-ui/src/views/bigscreenDesigner/designer/components/componentLinkage.vue new file mode 100644 index 00000000..44f25771 --- /dev/null +++ b/report-ui/src/views/bigscreenDesigner/designer/components/componentLinkage.vue @@ -0,0 +1,290 @@ + + + + diff --git a/report-ui/src/views/bigscreenDesigner/designer/components/dynamicForm.vue b/report-ui/src/views/bigscreenDesigner/designer/components/dynamicForm.vue index 2e607796..c44db5c7 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/components/dynamicForm.vue +++ b/report-ui/src/views/bigscreenDesigner/designer/components/dynamicForm.vue @@ -294,6 +294,15 @@ v-model="formData[itemChildList.name]" @change="changed($event, itemChildList.name)" /> + @@ -319,6 +328,7 @@ import dynamicAddTable from "./dynamicAddTable.vue"; import customUpload from "./customUpload.vue"; import dynamicAddRadar from "./dynamicAddRadar"; import MonacoEditor from "@/components/MonacoEditor/index"; +import componentLinkage from './componentLinkage'; export default { name: "DynamicForm", components: { @@ -330,6 +340,7 @@ export default { customUpload, dynamicAddRadar, MonacoEditor, + componentLinkage }, model: { prop: "value", @@ -341,6 +352,18 @@ export default { type: [Object], default: () => {}, }, + layerWidget: { + type: Array, + default: () => [] + }, + widgetParamsConfig: { + type: Array, + default: () => [] + }, + widgetIndex: { + type: Number, + default: -1 + } }, data() { return { diff --git a/report-ui/src/views/bigscreenDesigner/designer/index.vue b/report-ui/src/views/bigscreenDesigner/designer/index.vue index 63f0aa98..200a1a67 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/index.vue +++ b/report-ui/src/views/bigscreenDesigner/designer/index.vue @@ -80,46 +80,46 @@ :style="{ width: middleWidth + 'px', height: middleHeight + 'px' }" >
- + - + - + - + - + - + - + - + @@ -321,6 +321,9 @@ @@ -412,7 +415,7 @@ export default { title: "", // 大屏页面标题 width: 1920, // 大屏设计宽度 height: 1080, // 大屏设计高度 - backgroundColor: "", // 大屏背景色 + backgroundColor: "#1E1E1E", // 大屏背景色 backgroundImage: "", // 大屏背景图片 refreshSeconds: null, // 大屏刷新时间间隔 presetLine: [], // 辅助线 @@ -460,7 +463,9 @@ export default { activeName: "first", scaleNum: 0, // 当前缩放百分比的值 sizeRange: [20, 40, 60, 80, 100, 150, 200, 300, 400], // 缩放百分比 - currentSizeRangeIndex: -1 // 当前是哪个缩放比分比 + currentSizeRangeIndex: -1, // 当前是哪个缩放比分比, + currentWidgetTotal: 0, + widgetParamsConfig: [], // 各组件动态数据集的参数配置情况 }; }, computed: { @@ -530,6 +535,7 @@ export default { widgets: { handler(val) { this.handlerLayerWidget(val); + this.handlerdynamicDataParamsConfig(val) //以下部分是记录历史 this.$nextTick(() => { this.revoke.push(this.widgets); @@ -638,7 +644,13 @@ export default { const layerWidgetArr = []; for (let i = 0; i < val.length; i++) { const obj = {}; - obj.icon = getToolByCode(val[i].type).icon; + const myItem = getToolByCode(val[i].type) + obj.icon = myItem.icon; + obj.code = myItem.code // 组件类型code + obj.widgetId = val[i].value.widgetId || '' // 唯一id + if (val[i].value.paramsKeys) { + obj.paramsKeys = val[i].value.paramsKeys + } const options = val[i].options["setup"]; options.forEach((el) => { if (el.name == "layerName") { @@ -649,6 +661,12 @@ export default { } this.layerWidget = layerWidgetArr; }, + // 返回每个组件的动态数据集参数配置情况 + handlerdynamicDataParamsConfig(val) { + this.widgetParamsConfig = val.map(item => { + return item.value.data + }) + }, async initEchartData() { const reportCode = this.$route.query.reportCode; const { code, data } = await detailDashboard(reportCode); @@ -672,7 +690,7 @@ export default { } this.setOptionsOnClickScreen(); return { - backgroundColor: (data && data.backgroundColor) || "", + backgroundColor: (data && data.backgroundColor) || (!data ? '#1e1e1e' : ''), backgroundImage: (data && data.backgroundImage) || "", height: (data && data.height) || "1080", title: (data && data.title) || "", @@ -690,10 +708,19 @@ export default { data: widgets[i].value.data, position: widgets[i].value.position, }; - const tool = this.deepClone(getToolByCode(widgets[i].type)); + const tool = this.deepClone(getToolByCode(widgets[i].type)) + if (!tool) { + const message = '暂未提供该组件或该组件下线了,组件code: ' + widgets[i].type + console.error(message) + if (process.env.NODE_ENV === 'development') { // 40@remarks 看生产要不要提示 + this.$message.error(message) + } + continue // 找不到就跳过,避免整个报表都加载不出来 + } const option = tool.options; const options = this.handleOptionsData(widgets[i].value, option); obj.options = options; + obj.value.widgetId = obj.value.setup.widgetId widgetsData.push(obj); } return widgetsData; @@ -753,6 +780,9 @@ export default { }, widgets: this.widgets, }; + screenData.widgets.forEach(widget => { + widget.value.setup.widgetId = widget.value.widgetId + }) const { code, data } = await insertDashboard(screenData); if (code == "200") { this.$message.success("保存成功!"); @@ -831,9 +861,24 @@ export default { }, dragStart(widgetCode) { this.dragWidgetCode = widgetCode; + this.currentWidgetTotal = this.widgets.length // 当前操作面板上有多少各组件 }, dragEnd() { - this.dragWidgetCode = ""; + this.dragWidgetCode = "";/** + * 40@remarks 新增组件到操作面板后,右边的配置有更新,但是当前选中的组件没更新,导致配置错乱的bug; + * 由于拖动组件拖到非操作面板上是不会添加组件,还需判断是否添加组件到操作面板上; + */ + this.$nextTick(()=>{ + if (this.widgets.length === this.currentWidgetTotal + 1) { // 确实新增了一个组件到操作面板上 + console.log(`新添加 '${this.widgets[this.currentWidgetTotal].value.setup.layerName}' 组件到操作面板`) + const uuid = Number(Math.random().toString().substr(2)).toString(36) + this.widgets[this.currentWidgetTotal].value.widgetId = uuid + this.layerWidget[this.currentWidgetTotal].widgetId = uuid + const index = this.widgets.length - 1 + this.layerClick(index) // 选中当前新增的组件 + this.grade = false // 去除网格线 + } + }) }, dragOver(evt) { evt.preventDefault(); @@ -1080,7 +1125,13 @@ export default { // 复制 copylayer() { const obj = this.deepClone(this.widgets[this.rightClickIndex]); + obj.value.position.top += 40 // 复制的元素向右下角偏移一点 + obj.value.position.left += 40 + obj.value.widgetId = Number(Math.random().toString().substr(2)).toString(36) this.widgets.splice(this.widgets.length, 0, obj); + this.$nextTick(() => { + this.layerClick(this.widgets.length - 1) // 复制后定位到最新的组件 + }) }, // 置顶 istopLayer() { diff --git a/report-ui/src/views/bigscreenDesigner/designer/linkageLogic.js b/report-ui/src/views/bigscreenDesigner/designer/linkageLogic.js new file mode 100644 index 00000000..b00bf3f6 --- /dev/null +++ b/report-ui/src/views/bigscreenDesigner/designer/linkageLogic.js @@ -0,0 +1,128 @@ +/* + * @Author: chengsl + * @Date: 2023-02-24 09:40:13 + * @LastEditors: chengsl + * @LastEditTime: 2023-02-24 13:12:24 + * @Description: 各联动组件的参数配置 参数paramsKey的值具体封装时再改 + */ +import { eventBus as bus } from "@/utils/eventBus"; +export const lickageParamsConfig = [ + // { + // name: '按钮组', + // code: 'widgetButtonGroup', + // paramsKey: [] // 40@remarks 动态:[...row, index] + // }, + { + name: '柱图', + code: 'widget-barchart', + paramsKey: ['name', 'value'] + }, + // …… + { + name: '折线图', + code: 'widget-linechart', + paramsKey: ['name', 'value'] + }, + { + name: '百分比图', + code: 'widgetPiePercentageChart', + paramsKey: ['value'] + }, +] + +export const getOneConfigByCode = function(code) { + return lickageParamsConfig.find(item => { return item.code === code }) +} + +export const getOneConfigByName = function(name) { + return lickageParamsConfig.find(item => { return item.name === name }) +} + +/** + * 源组件 - 初始化联动逻辑 + * @param self 组件实例对象 this + * @param isActiveClick 主动触发(非echart类click事件触发) + * @param buttonConfig 按钮组组件的配置 + * 40@remarks + * 1、v-chart 需添加 ref="myVChart" 以获取实例 + * 2、 发消息发过去的对象 待封装配置动态兼容 + */ +export const originWidgetLinkageLogic = function(self, isActiveClick = false, buttonConfig = {}) { + // if (self.allComponentLinkage && self.allComponentLinkage.length && self.allComponentLinkage[self.widgetIndex].index !== -1 && self.allComponentLinkage[self.widgetIndex].linkageArr.length) { + if (self.optionsSetup.componentLinkage && self.optionsSetup.componentLinkage.length) { + if (isActiveClick) { // 主动触发 + self.allComponentLinkage[self.widgetIndex].linkageArr.forEach(item => { + console.log(`bus_${item.originId}_${item.targetId}`, ' -联动逻辑点击-发送消息', buttonConfig) + bus.$emit(`bus_${item.originId}_${item.targetId}`, buttonConfig.currentData) + }) + } else { // chart 组件 + self.$refs.myVChart.chart.on('click', function(params) { + self.allComponentLinkage[self.widgetIndex].linkageArr.forEach(item => { + console.log(`bus_${item.originId}_${item.targetId}`, ' -联动逻辑点击-发送消息', params) + let message = {} + const widgetConfigTemp = getOneConfigByCode(self.value.widgetCode) + if (widgetConfigTemp && widgetConfigTemp.paramsKey.length) { // 动态加载各组件的参数来封装 + widgetConfigTemp.paramsKey.forEach(key => { + message[key] = params[key] + }) + // 40@remarks 部分组件 传参需要特殊处理下 + // …… + // 40@remarks 专用于测试联动发消息 手动改造消息内容 + // if (self.value.widgetCode === 'widgetMap2d') { + // const nameTemp = ['苹果', '三星', '小米', '华为', 'OPPO', 'VIVO'] + // // message = { + // // name: nameTemp[(params.dataIndex % 6)], + // // value: params.value, + // // dataIndex: params.dataIndex + // // } + // // message.name = nameTemp[(+params.value % 6)] + // message.name = nameTemp[(parseInt(Math.random() * 6) % 6)] + // } + // if (self.value.widgetCode === 'widget-piechart') { + // message.name = (parseInt(Math.random() * 2) % 2) === 0 ? '深圳市' : '盐田区' + // } + } else { + message = { + name: params.name, + value: params.value + } + } + bus.$emit(`bus_${item.originId}_${item.targetId}`, message) + }) + }) + } + } +} + +/** + * 目标组件 - 初始化联动逻辑 + * @param self 组件实例对象 this + * @returns + */ +export const targetWidgetLinkageLogic = function(self) { + const busEvents = [] + // 有无有关联的组件 + if (!self.allComponentLinkage || !self.allComponentLinkage.length) return + self.allComponentLinkage.some(item => { + if (item.index !== -1 && item.linkageArr.length) { + item.linkageArr.some(obj => { + if (obj.targetId === self.value.setup.widgetId) { + self.hasLinkage = true + busEvents.push({ + eventName: `bus_${obj.originId}_${obj.targetId}`, + paramsConfig: obj.paramsConfig + }) + return true + } + }) + } + }) + if (self.hasLinkage) { + busEvents.forEach(item => { + bus.$on(item.eventName, e => { + console.log(item.eventName, ' 接收消息e', e) + self.setOptionsData(e, item.paramsConfig) + }) + }) + } +} diff --git a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/barCharts/widget-barchart.js b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/barCharts/widget-barchart.js index 2f55a78c..c55403b4 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/barCharts/widget-barchart.js +++ b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/barCharts/widget-barchart.js @@ -564,6 +564,18 @@ export const widgetBarchart = { }, ], }, + { + name: '组件联动', + list: [ + { + type: 'componentLinkage', + label: '', + name: 'componentLinkage', + required: false, + value: [] + } + ] + } ], ], // 数据 diff --git a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/lineCharts/widget-linechart.js b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/lineCharts/widget-linechart.js index f9fc91a1..b47cbdc6 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/lineCharts/widget-linechart.js +++ b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/lineCharts/widget-linechart.js @@ -587,6 +587,18 @@ export const widgetLinechart = { }, ], }, + { + name: '组件联动', + list: [ + { + type: 'componentLinkage', + label: '', + name: 'componentLinkage', + required: false, + value: [] + } + ] + } ], ], // 数据 diff --git a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/percentCharts/widget-pie-percentage.js b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/percentCharts/widget-pie-percentage.js index a8a349fe..3d1d9fc1 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/tools/configure/percentCharts/widget-pie-percentage.js +++ b/report-ui/src/views/bigscreenDesigner/designer/tools/configure/percentCharts/widget-pie-percentage.js @@ -169,6 +169,18 @@ export const widgetPiePercentage = { value: '#173164' }, ] + }, + { + name: '组件联动', + list: [ + { + type: 'componentLinkage', + label: '', + name: 'componentLinkage', + required: false, + value: [] + } + ] } ], ], diff --git a/report-ui/src/views/bigscreenDesigner/designer/tools/index.js b/report-ui/src/views/bigscreenDesigner/designer/tools/index.js index 4a298073..7a20a42d 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/tools/index.js +++ b/report-ui/src/views/bigscreenDesigner/designer/tools/index.js @@ -3,8 +3,8 @@ * @version: * @Author: qianlishi * @Date: 2021-08-29 06:43:07 - * @LastEditors: qianlishi qianlishi@anji-plus.com - * @LastEditTime: 2022-11-07 15:35:42 + * @LastEditors: chengsl + * @LastEditTime: 2023-02-24 10:29:26 */ import { widgetTool } from "./main" const screenConfig = { @@ -52,7 +52,7 @@ const screenConfig = { name: 'backgroundColor', required: false, placeholder: '', - value: 'rgba(45, 86, 126, 1)', + value: '#1E1E1E', }, { type: 'custom-upload', @@ -72,6 +72,7 @@ export const converArr = (data) => { let tempArr = [], newArr = [] for (let i = 0; i < data.length; i++) { const item = data[i] + item.widgetId = '' if (tempArr.indexOf(item.type) === -1) { newArr.push({ name: item.tabName, diff --git a/report-ui/src/views/bigscreenDesigner/designer/tools/main.js b/report-ui/src/views/bigscreenDesigner/designer/tools/main.js index 660c04cc..e7159139 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/tools/main.js +++ b/report-ui/src/views/bigscreenDesigner/designer/tools/main.js @@ -3,8 +3,8 @@ * @version: * @Author: qianlishi * @Date: 2021-08-29 07:46:46 - * @LastEditors: qianlishi qianlishi@anji-plus.com - * @LastEditTime: 2023-01-09 13:16:19 + * @LastEditors: chengsl + * @LastEditTime: 2023-02-23 15:23:20 */ import { widgetText } from "./configure/texts/widget-text" @@ -70,7 +70,7 @@ export const widgetTool = [ widgetLineCompare, widgetDecoratePie, widgetMoreBarLine, - widgetWordCloud, + // widgetWordCloud, widgetHeatmap, widgetRadar, widgetBarLineStack, diff --git a/report-ui/src/views/bigscreenDesigner/designer/widget/bar/widgetBarchart.vue b/report-ui/src/views/bigscreenDesigner/designer/widget/bar/widgetBarchart.vue index c4d12d21..bfcd0ce7 100644 --- a/report-ui/src/views/bigscreenDesigner/designer/widget/bar/widgetBarchart.vue +++ b/report-ui/src/views/bigscreenDesigner/designer/widget/bar/widgetBarchart.vue @@ -1,10 +1,11 @@