|
|
|
@ -6,21 +6,23 @@
|
|
|
|
|
!-->
|
|
|
|
|
<template>
|
|
|
|
|
<div class="layout">
|
|
|
|
|
<div v-if="toolIsShow"
|
|
|
|
|
<div
|
|
|
|
|
v-if="toolIsShow"
|
|
|
|
|
class="layout-left"
|
|
|
|
|
:style="{ width: widthLeftForTools + 'px' }">
|
|
|
|
|
<el-tabs type="border-card"
|
|
|
|
|
:stretch="true">
|
|
|
|
|
:style="{ width: widthLeftForTools + 'px' }"
|
|
|
|
|
>
|
|
|
|
|
<el-tabs type="border-card" :stretch="true">
|
|
|
|
|
<!-- 左侧组件栏-->
|
|
|
|
|
<el-tab-pane label="工具栏">
|
|
|
|
|
<!-- <el-divider content-position="center">html</el-divider>-->
|
|
|
|
|
<draggable v-for="widget in widgetTools"
|
|
|
|
|
<draggable
|
|
|
|
|
v-for="widget in widgetTools"
|
|
|
|
|
:key="widget.code"
|
|
|
|
|
@end="(evt) => widgetOnDragged(evt, widget.code)">
|
|
|
|
|
@end="evt => widgetOnDragged(evt, widget.code)"
|
|
|
|
|
>
|
|
|
|
|
<div class="tools-item">
|
|
|
|
|
<span class="tools-item-icon">
|
|
|
|
|
<i class="iconfont"
|
|
|
|
|
:class="widget.icon"></i>
|
|
|
|
|
<i class="iconfont" :class="widget.icon"></i>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="tools-item-text">{{ widget.label }}</span>
|
|
|
|
|
</div>
|
|
|
|
@ -28,12 +30,13 @@
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<!-- 左侧图层-->
|
|
|
|
|
<el-tab-pane label="图层">
|
|
|
|
|
<div v-for="(item, index) in layerWidget"
|
|
|
|
|
<div
|
|
|
|
|
v-for="(item, index) in layerWidget"
|
|
|
|
|
:key="index"
|
|
|
|
|
class="tools-item">
|
|
|
|
|
class="tools-item"
|
|
|
|
|
>
|
|
|
|
|
<span class="tools-item-icon">
|
|
|
|
|
<i class="iconfont"
|
|
|
|
|
:class="item.icon"></i>
|
|
|
|
|
<i class="iconfont" :class="item.icon"></i>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="tools-item-text">{{ item.label }}</span>
|
|
|
|
|
</div>
|
|
|
|
@ -41,111 +44,153 @@
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="layout-left-fold"
|
|
|
|
|
<div
|
|
|
|
|
class="layout-left-fold"
|
|
|
|
|
:style="{ width: widthLeftForToolsHideButton + 'px' }"
|
|
|
|
|
@click="toolIsShow = !toolIsShow">
|
|
|
|
|
@click="toolIsShow = !toolIsShow"
|
|
|
|
|
>
|
|
|
|
|
<i class="iconfont iconzhankai" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="layout-middle"
|
|
|
|
|
:style="{ width: middleWidth + 'px', height: middleHeight + 'px' }">
|
|
|
|
|
<div
|
|
|
|
|
class="layout-middle"
|
|
|
|
|
:style="{ width: middleWidth + 'px', height: middleHeight + 'px' }"
|
|
|
|
|
>
|
|
|
|
|
<div class="top-button">
|
|
|
|
|
<span class="btn">
|
|
|
|
|
<el-tooltip class="item"
|
|
|
|
|
<el-tooltip
|
|
|
|
|
class="item"
|
|
|
|
|
effect="dark"
|
|
|
|
|
content="保存"
|
|
|
|
|
placement="bottom">
|
|
|
|
|
<i class="iconfont iconsave"
|
|
|
|
|
@click="saveData"></i>
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<i class="iconfont iconsave" @click="saveData"></i>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="btn">
|
|
|
|
|
<el-tooltip class="item"
|
|
|
|
|
<el-tooltip
|
|
|
|
|
class="item"
|
|
|
|
|
effect="dark"
|
|
|
|
|
content="预览"
|
|
|
|
|
placement="bottom">
|
|
|
|
|
<i class="iconfont iconyulan"
|
|
|
|
|
@click="viewScreen"></i>
|
|
|
|
|
placement="bottom"
|
|
|
|
|
>
|
|
|
|
|
<i class="iconfont iconyulan" @click="viewScreen"></i>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="workbench-container"
|
|
|
|
|
:style="{ width: bigscreenWidthInWorkbench + 'px', height: bigscreenHeightInWorkbench + 'px' }">
|
|
|
|
|
<vue-ruler-tool v-model="dashboard.presetLine"
|
|
|
|
|
<div
|
|
|
|
|
class="workbench-container"
|
|
|
|
|
:style="{
|
|
|
|
|
width: bigscreenWidthInWorkbench + 'px',
|
|
|
|
|
height: bigscreenHeightInWorkbench + 'px'
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<vue-ruler-tool
|
|
|
|
|
v-model="dashboard.presetLine"
|
|
|
|
|
class="vueRuler"
|
|
|
|
|
:step-length="50"
|
|
|
|
|
:parent="true"
|
|
|
|
|
:position="'relative'"
|
|
|
|
|
:is-scale-revise="true"
|
|
|
|
|
:visible.sync="dashboard.presetLineVisible">
|
|
|
|
|
<div id="workbench"
|
|
|
|
|
:visible.sync="dashboard.presetLineVisible"
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
id="workbench"
|
|
|
|
|
class="workbench"
|
|
|
|
|
:style="{ transform: workbenchTransform, width: bigscreenWidth + 'px', height: bigscreenHeight + 'px', 'background-color': dashboard.backgroundColor, 'background-image': 'url(' + dashboard.backgroundImage + ')', 'background-position': '0% 0%', 'background-size': '100% 100%', 'background-repeat': 'initial', 'background-attachment': 'initial', 'background-origin': 'initial', 'background-clip': 'initial' }"
|
|
|
|
|
@click="setOptionsOnClickScreen">
|
|
|
|
|
<widget v-for="(widget, index) in widgets"
|
|
|
|
|
:style="{
|
|
|
|
|
transform: workbenchTransform,
|
|
|
|
|
width: bigscreenWidth + 'px',
|
|
|
|
|
height: bigscreenHeight + 'px',
|
|
|
|
|
'background-color': dashboard.backgroundColor,
|
|
|
|
|
'background-image': 'url(' + dashboard.backgroundImage + ')',
|
|
|
|
|
'background-position': '0% 0%',
|
|
|
|
|
'background-size': '100% 100%',
|
|
|
|
|
'background-repeat': 'initial',
|
|
|
|
|
'background-attachment': 'initial',
|
|
|
|
|
'background-origin': 'initial',
|
|
|
|
|
'background-clip': 'initial'
|
|
|
|
|
}"
|
|
|
|
|
@click="setOptionsOnClickScreen"
|
|
|
|
|
>
|
|
|
|
|
<widget
|
|
|
|
|
v-for="(widget, index) in widgets"
|
|
|
|
|
:key="index"
|
|
|
|
|
v-model="widget.value"
|
|
|
|
|
:index="index"
|
|
|
|
|
:type="widget.type"
|
|
|
|
|
:bigscreen="{ bigscreenWidth, bigscreenHeight }"
|
|
|
|
|
@onActivated="setOptionsOnClickWidget"
|
|
|
|
|
@contextmenu.prevent.native="rightClick($event, index)" />
|
|
|
|
|
@contextmenu.prevent.native="rightClick($event, index)"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</vue-ruler-tool>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="layout-right"
|
|
|
|
|
:style="{ width: widthLeftForOptions + 'px' }">
|
|
|
|
|
<el-tabs v-model="activeName"
|
|
|
|
|
type="border-card"
|
|
|
|
|
:stretch="true">
|
|
|
|
|
<el-tab-pane v-if="isNotNull(widgetOptions.setup) || isNotNull(widgetOptions.collapse)"
|
|
|
|
|
<div class="layout-right" :style="{ width: widthLeftForOptions + 'px' }">
|
|
|
|
|
<el-tabs v-model="activeName" type="border-card" :stretch="true">
|
|
|
|
|
<el-tab-pane
|
|
|
|
|
v-if="
|
|
|
|
|
isNotNull(widgetOptions.setup) || isNotNull(widgetOptions.collapse)
|
|
|
|
|
"
|
|
|
|
|
name="first"
|
|
|
|
|
label="配置">
|
|
|
|
|
<dynamicForm ref="formData"
|
|
|
|
|
label="配置"
|
|
|
|
|
>
|
|
|
|
|
<dynamicForm
|
|
|
|
|
ref="formData"
|
|
|
|
|
:options="widgetOptions.setup"
|
|
|
|
|
@onChanged="(val) => widgetValueChanged('setup', val)" />
|
|
|
|
|
@onChanged="val => widgetValueChanged('setup', val)"
|
|
|
|
|
/>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<el-tab-pane v-if="isNotNull(widgetOptions.data)"
|
|
|
|
|
<el-tab-pane
|
|
|
|
|
v-if="isNotNull(widgetOptions.data)"
|
|
|
|
|
name="second"
|
|
|
|
|
label="数据">
|
|
|
|
|
<dynamicForm ref="formData"
|
|
|
|
|
label="数据"
|
|
|
|
|
>
|
|
|
|
|
<dynamicForm
|
|
|
|
|
ref="formData"
|
|
|
|
|
:options="widgetOptions.data"
|
|
|
|
|
@onChanged="(val) => widgetValueChanged('data', val)" />
|
|
|
|
|
@onChanged="val => widgetValueChanged('data', val)"
|
|
|
|
|
/>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
<el-tab-pane v-if="isNotNull(widgetOptions.position)"
|
|
|
|
|
<el-tab-pane
|
|
|
|
|
v-if="isNotNull(widgetOptions.position)"
|
|
|
|
|
name="third"
|
|
|
|
|
label="坐标">
|
|
|
|
|
<dynamicForm ref="formData"
|
|
|
|
|
label="坐标"
|
|
|
|
|
>
|
|
|
|
|
<dynamicForm
|
|
|
|
|
ref="formData"
|
|
|
|
|
:options="widgetOptions.position"
|
|
|
|
|
@onChanged="(val) => widgetValueChanged('position', val)" />
|
|
|
|
|
@onChanged="val => widgetValueChanged('position', val)"
|
|
|
|
|
/>
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<content-menu :visible.sync="visibleContentMenu"
|
|
|
|
|
<content-menu
|
|
|
|
|
:visible.sync="visibleContentMenu"
|
|
|
|
|
:style-obj="styleObj"
|
|
|
|
|
@deletelayer="deletelayer" />
|
|
|
|
|
@deletelayer="deletelayer"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { insertDashboard, detailDashboard } from '@/api/bigscreen'
|
|
|
|
|
import { widgetTools, getToolByCode } from './tools'
|
|
|
|
|
import widget from './widget/widget.vue'
|
|
|
|
|
import dynamicForm from './form/dynamicForm.vue'
|
|
|
|
|
import draggable from 'vuedraggable'
|
|
|
|
|
import VueRulerTool from 'vue-ruler-tool' // 大屏设计页面的标尺插件
|
|
|
|
|
import contentMenu from './form/contentMenu'
|
|
|
|
|
import { insertDashboard, detailDashboard } from "@/api/bigscreen";
|
|
|
|
|
import { widgetTools, getToolByCode } from "./tools";
|
|
|
|
|
import widget from "./widget/widget.vue";
|
|
|
|
|
import dynamicForm from "./form/dynamicForm.vue";
|
|
|
|
|
import draggable from "vuedraggable";
|
|
|
|
|
import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
|
|
|
|
|
import contentMenu from "./form/contentMenu";
|
|
|
|
|
export default {
|
|
|
|
|
name: 'Login',
|
|
|
|
|
name: "Login",
|
|
|
|
|
components: {
|
|
|
|
|
draggable,
|
|
|
|
|
VueRulerTool,
|
|
|
|
|
widget,
|
|
|
|
|
dynamicForm,
|
|
|
|
|
contentMenu,
|
|
|
|
|
contentMenu
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
@ -161,22 +206,22 @@ export default {
|
|
|
|
|
// 工作台大屏画布,保存到表gaea_report_dashboard中
|
|
|
|
|
dashboard: {
|
|
|
|
|
id: null,
|
|
|
|
|
title: '', // 大屏页面标题
|
|
|
|
|
title: "", // 大屏页面标题
|
|
|
|
|
width: 1920, // 大屏设计宽度
|
|
|
|
|
height: 1080, // 大屏设计高度
|
|
|
|
|
backgroundColor: '', // 大屏背景色
|
|
|
|
|
backgroundImage: '', // 大屏背景图片
|
|
|
|
|
backgroundColor: "", // 大屏背景色
|
|
|
|
|
backgroundImage: "", // 大屏背景图片
|
|
|
|
|
refreshSeconds: null, // 大屏刷新时间间隔
|
|
|
|
|
presetLine: [], // 辅助线
|
|
|
|
|
presetLineVisible: true, // 辅助线是否显示
|
|
|
|
|
presetLineVisible: true // 辅助线是否显示
|
|
|
|
|
},
|
|
|
|
|
// 大屏的标记
|
|
|
|
|
screenCode: '',
|
|
|
|
|
screenCode: "",
|
|
|
|
|
// 大屏画布中的组件
|
|
|
|
|
widgets: [
|
|
|
|
|
{
|
|
|
|
|
// type和value最终存到数据库中去,保存到gaea_report_dashboard_widget中
|
|
|
|
|
type: 'widget-text',
|
|
|
|
|
type: "widget-text",
|
|
|
|
|
value: {
|
|
|
|
|
setup: {},
|
|
|
|
|
data: {},
|
|
|
|
@ -185,12 +230,12 @@ export default {
|
|
|
|
|
height: 100,
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0,
|
|
|
|
|
zIndex: 0,
|
|
|
|
|
},
|
|
|
|
|
zIndex: 0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// options属性是从工具栏中拿到的tools中拿到
|
|
|
|
|
options: [],
|
|
|
|
|
},
|
|
|
|
|
options: []
|
|
|
|
|
}
|
|
|
|
|
], // 工作区中拖放的组件
|
|
|
|
|
|
|
|
|
|
// 当前激活组件
|
|
|
|
@ -199,83 +244,85 @@ export default {
|
|
|
|
|
widgetOptions: {
|
|
|
|
|
setup: [], // 配置
|
|
|
|
|
data: [], // 数据
|
|
|
|
|
position: [], // 坐标
|
|
|
|
|
position: [] // 坐标
|
|
|
|
|
},
|
|
|
|
|
flagWidgetClickStopPropagation: false, // 点击组件时阻止事件冒泡传递到画布click事件上
|
|
|
|
|
styleObj: {
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0,
|
|
|
|
|
top: 0
|
|
|
|
|
},
|
|
|
|
|
visibleContentMenu: false,
|
|
|
|
|
rightClickIndex: -1,
|
|
|
|
|
activeName: 'first',
|
|
|
|
|
}
|
|
|
|
|
activeName: "first"
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
// 左侧折叠切换时,动态计算中间区的宽度
|
|
|
|
|
middleWidth() {
|
|
|
|
|
var widthLeftAndRight = 0
|
|
|
|
|
var widthLeftAndRight = 0;
|
|
|
|
|
if (this.toolIsShow) {
|
|
|
|
|
widthLeftAndRight += this.widthLeftForTools // 左侧工具栏宽度
|
|
|
|
|
widthLeftAndRight += this.widthLeftForTools; // 左侧工具栏宽度
|
|
|
|
|
}
|
|
|
|
|
widthLeftAndRight += this.widthLeftForToolsHideButton // 左侧工具栏折叠按钮宽度
|
|
|
|
|
widthLeftAndRight += this.widthLeftForOptions // 右侧配置栏宽度
|
|
|
|
|
widthLeftAndRight += this.widthLeftForToolsHideButton; // 左侧工具栏折叠按钮宽度
|
|
|
|
|
widthLeftAndRight += this.widthLeftForOptions; // 右侧配置栏宽度
|
|
|
|
|
|
|
|
|
|
var middleWidth = this.bodyWidth - widthLeftAndRight
|
|
|
|
|
return middleWidth
|
|
|
|
|
var middleWidth = this.bodyWidth - widthLeftAndRight;
|
|
|
|
|
return middleWidth;
|
|
|
|
|
},
|
|
|
|
|
middleHeight() {
|
|
|
|
|
return this.bodyHeight
|
|
|
|
|
return this.bodyHeight;
|
|
|
|
|
},
|
|
|
|
|
// 设计台按大屏的缩放比例
|
|
|
|
|
bigscreenScaleInWorkbench() {
|
|
|
|
|
var widthScale = this.middleWidth / this.bigscreenWidth
|
|
|
|
|
var heightScale = this.middleHeight / this.bigscreenHeight
|
|
|
|
|
return Math.min(widthScale, heightScale)
|
|
|
|
|
var widthScale = this.middleWidth / this.bigscreenWidth;
|
|
|
|
|
var heightScale = this.middleHeight / this.bigscreenHeight;
|
|
|
|
|
return Math.min(widthScale, heightScale);
|
|
|
|
|
},
|
|
|
|
|
workbenchTransform() {
|
|
|
|
|
return `scale(${this.bigscreenScaleInWorkbench}, ${this.bigscreenScaleInWorkbench})`
|
|
|
|
|
return `scale(${this.bigscreenScaleInWorkbench}, ${
|
|
|
|
|
this.bigscreenScaleInWorkbench
|
|
|
|
|
})`;
|
|
|
|
|
},
|
|
|
|
|
// 大屏在设计模式的大小
|
|
|
|
|
bigscreenWidthInWorkbench() {
|
|
|
|
|
return this.getPXUnderScale(this.bigscreenWidth)
|
|
|
|
|
return this.getPXUnderScale(this.bigscreenWidth);
|
|
|
|
|
},
|
|
|
|
|
bigscreenHeightInWorkbench() {
|
|
|
|
|
return this.getPXUnderScale(this.bigscreenHeight)
|
|
|
|
|
return this.getPXUnderScale(this.bigscreenHeight);
|
|
|
|
|
},
|
|
|
|
|
layerWidget() {
|
|
|
|
|
const layerWidgetArr = []
|
|
|
|
|
const layerWidgetArr = [];
|
|
|
|
|
for (let i = 0; i < this.widgets.length; i++) {
|
|
|
|
|
layerWidgetArr.push(getToolByCode(this.widgets[i].type))
|
|
|
|
|
layerWidgetArr.push(getToolByCode(this.widgets[i].type));
|
|
|
|
|
}
|
|
|
|
|
return layerWidgetArr;
|
|
|
|
|
}
|
|
|
|
|
return layerWidgetArr
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
// 一进入时,加载屏幕配置属性
|
|
|
|
|
this.setOptionsOnClickScreen()
|
|
|
|
|
this.setOptionsOnClickScreen();
|
|
|
|
|
|
|
|
|
|
// 如果是新的设计工作台
|
|
|
|
|
this.initEchartData()
|
|
|
|
|
this.widgets = []
|
|
|
|
|
this.initEchartData();
|
|
|
|
|
this.widgets = [];
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
async initEchartData() {
|
|
|
|
|
const reportCode = this.$route.query.reportCode
|
|
|
|
|
const { code, data } = await detailDashboard(reportCode)
|
|
|
|
|
if (code != 200) return
|
|
|
|
|
const processData = this.handleInitEchartsData(data)
|
|
|
|
|
const screenData = this.handleBigScreen(data.dashboard)
|
|
|
|
|
this.widgets = processData
|
|
|
|
|
this.dashboard = screenData
|
|
|
|
|
const reportCode = this.$route.query.reportCode;
|
|
|
|
|
const { code, data } = await detailDashboard(reportCode);
|
|
|
|
|
if (code != 200) return;
|
|
|
|
|
const processData = this.handleInitEchartsData(data);
|
|
|
|
|
const screenData = this.handleBigScreen(data.dashboard);
|
|
|
|
|
this.widgets = processData;
|
|
|
|
|
this.dashboard = screenData;
|
|
|
|
|
},
|
|
|
|
|
handleBigScreen(data) {
|
|
|
|
|
const optionScreen = this.deepClone(getToolByCode('screen').options)
|
|
|
|
|
const setup = optionScreen.setup
|
|
|
|
|
const optionScreen = this.deepClone(getToolByCode("screen").options);
|
|
|
|
|
const setup = optionScreen.setup;
|
|
|
|
|
for (const key in data) {
|
|
|
|
|
for (let i = 0; i < setup.length; i++) {
|
|
|
|
|
if (key == setup[i].name) {
|
|
|
|
|
setup[i].value = data[key]
|
|
|
|
|
setup[i].value = data[key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -284,35 +331,46 @@ export default {
|
|
|
|
|
backgroundImage: data.backgroundImage,
|
|
|
|
|
height: data.height,
|
|
|
|
|
title: data.title,
|
|
|
|
|
width: data.width,
|
|
|
|
|
}
|
|
|
|
|
width: data.width
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
handleInitEchartsData(data) {
|
|
|
|
|
console.log(data)
|
|
|
|
|
const widgets = data.dashboard.widgets
|
|
|
|
|
const widgetsData = []
|
|
|
|
|
const widgets = data.dashboard.widgets;
|
|
|
|
|
const widgetsData = [];
|
|
|
|
|
for (let i = 0; i < widgets.length; i++) {
|
|
|
|
|
var obj = {}
|
|
|
|
|
obj.type = widgets[i].type
|
|
|
|
|
var obj = {};
|
|
|
|
|
obj.type = widgets[i].type;
|
|
|
|
|
obj.value = {
|
|
|
|
|
setup: widgets[i].value.setup,
|
|
|
|
|
data: widgets[i].value.data,
|
|
|
|
|
collapse: widgets[i].value.collapse,
|
|
|
|
|
position: widgets[i].value.position,
|
|
|
|
|
position: widgets[i].value.position
|
|
|
|
|
};
|
|
|
|
|
const tool = this.deepClone(getToolByCode(widgets[i].type));
|
|
|
|
|
const option = tool.options;
|
|
|
|
|
const options = this.handleOptionsData(widgets[i].value, option);
|
|
|
|
|
obj.options = options;
|
|
|
|
|
widgetsData.push(obj);
|
|
|
|
|
}
|
|
|
|
|
const tool = this.deepClone(getToolByCode(widgets[i].type))
|
|
|
|
|
const option = tool.options
|
|
|
|
|
const options = this.handleOptionsData(widgets[i].value, option)
|
|
|
|
|
obj.options = options
|
|
|
|
|
widgetsData.push(obj)
|
|
|
|
|
}
|
|
|
|
|
return widgetsData
|
|
|
|
|
return widgetsData;
|
|
|
|
|
},
|
|
|
|
|
handleOptionsData(data, option) {
|
|
|
|
|
for (const key in data.setup) {
|
|
|
|
|
for (let i = 0; i < option.setup.length; i++) {
|
|
|
|
|
let item = option.setup[i];
|
|
|
|
|
if (Object.prototype.toString.call(item) == "[object Object]") {
|
|
|
|
|
if (key == option.setup[i].name) {
|
|
|
|
|
option.setup[i].value = data.setup[key]
|
|
|
|
|
option.setup[i].value = data.setup[key];
|
|
|
|
|
}
|
|
|
|
|
} else if (Object.prototype.toString.call(item) == "[object Array]") {
|
|
|
|
|
for (let j = 0; j < item.length; j++) {
|
|
|
|
|
const list = item[j].list;
|
|
|
|
|
list.forEach(el => {
|
|
|
|
|
if (key == el.name) {
|
|
|
|
|
el.value = data.setup[key];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -320,7 +378,7 @@ export default {
|
|
|
|
|
for (const key in data.position) {
|
|
|
|
|
for (let i = 0; i < option.position.length; i++) {
|
|
|
|
|
if (key == option.position[i].name) {
|
|
|
|
|
option.position[i].value = data.position[key]
|
|
|
|
|
option.position[i].value = data.position[key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -328,28 +386,17 @@ export default {
|
|
|
|
|
for (const key in data.data) {
|
|
|
|
|
for (let i = 0; i < option.data.length; i++) {
|
|
|
|
|
if (key == option.data[i].name) {
|
|
|
|
|
option.data[i].value = data.data[key]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// // collapse
|
|
|
|
|
// for (const key in data.collapse) {
|
|
|
|
|
// for (let i = 0; i < option.collapse.length; i++) {
|
|
|
|
|
// const itemList = option.collapse[i].list
|
|
|
|
|
// for (let j = 0; j < itemList.length; j++) {
|
|
|
|
|
// if (key == itemList[j].name) {
|
|
|
|
|
// itemList[j].value = data.collapse[key]
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
return option
|
|
|
|
|
option.data[i].value = data.data[key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return option;
|
|
|
|
|
},
|
|
|
|
|
// 保存数据
|
|
|
|
|
async saveData() {
|
|
|
|
|
if (!this.widgets || this.widgets.length == 0) {
|
|
|
|
|
this.$message.error('请添加组件')
|
|
|
|
|
return
|
|
|
|
|
this.$message.error("请添加组件");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const screenData = {
|
|
|
|
|
reportCode: this.$route.query.reportCode,
|
|
|
|
@ -358,44 +405,46 @@ export default {
|
|
|
|
|
width: this.dashboard.width,
|
|
|
|
|
height: this.dashboard.height,
|
|
|
|
|
backgroundColor: this.dashboard.backgroundColor,
|
|
|
|
|
backgroundImage: this.dashboard.backgroundImage,
|
|
|
|
|
backgroundImage: this.dashboard.backgroundImage
|
|
|
|
|
},
|
|
|
|
|
widgets: this.widgets,
|
|
|
|
|
widgets: this.widgets
|
|
|
|
|
};
|
|
|
|
|
const { code, data } = await insertDashboard(screenData);
|
|
|
|
|
if (code == "200") {
|
|
|
|
|
this.$message.success("保存成功!");
|
|
|
|
|
}
|
|
|
|
|
const { code, data } = await insertDashboard(screenData)
|
|
|
|
|
if (code != '200') return
|
|
|
|
|
},
|
|
|
|
|
// 预览
|
|
|
|
|
viewScreen() {
|
|
|
|
|
var routeUrl = this.$router.resolve({
|
|
|
|
|
path: '/report/bigscreen/viewer',
|
|
|
|
|
query: { reportCode: this.$route.query.reportCode },
|
|
|
|
|
})
|
|
|
|
|
window.open(routeUrl.href, '_blank')
|
|
|
|
|
path: "/bigscreen/viewer",
|
|
|
|
|
query: { reportCode: this.$route.query.reportCode }
|
|
|
|
|
});
|
|
|
|
|
window.open(routeUrl.href, "_blank");
|
|
|
|
|
},
|
|
|
|
|
// 在缩放模式下的大小
|
|
|
|
|
getPXUnderScale(px) {
|
|
|
|
|
return this.bigscreenScaleInWorkbench * px
|
|
|
|
|
return this.bigscreenScaleInWorkbench * px;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
|
|
|
|
|
widgetOnDragged(evt, widgetCode) {
|
|
|
|
|
var widgetType = widgetCode
|
|
|
|
|
var widgetType = widgetCode;
|
|
|
|
|
|
|
|
|
|
// 获取结束坐标和列名
|
|
|
|
|
var eventX = evt.originalEvent.clientX // 结束在屏幕的x坐标
|
|
|
|
|
var eventY = evt.originalEvent.clientY // 结束在屏幕的y坐标
|
|
|
|
|
var eventX = evt.originalEvent.clientX; // 结束在屏幕的x坐标
|
|
|
|
|
var eventY = evt.originalEvent.clientY; // 结束在屏幕的y坐标
|
|
|
|
|
|
|
|
|
|
var workbenchPosition = this.getDomTopLeftById('workbench')
|
|
|
|
|
var widgetTopInWorkbench = eventY - workbenchPosition.top
|
|
|
|
|
var widgetLeftInWorkbench = eventX - workbenchPosition.left
|
|
|
|
|
var workbenchPosition = this.getDomTopLeftById("workbench");
|
|
|
|
|
var widgetTopInWorkbench = eventY - workbenchPosition.top;
|
|
|
|
|
var widgetLeftInWorkbench = eventX - workbenchPosition.left;
|
|
|
|
|
|
|
|
|
|
// 计算在缩放模式下的x y
|
|
|
|
|
var x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench
|
|
|
|
|
var y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench
|
|
|
|
|
var x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench;
|
|
|
|
|
var y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench;
|
|
|
|
|
|
|
|
|
|
// 复制一个组件
|
|
|
|
|
var tool = getToolByCode(widgetType)
|
|
|
|
|
var tool = getToolByCode(widgetType);
|
|
|
|
|
var widgetJson = {
|
|
|
|
|
type: widgetType,
|
|
|
|
|
value: {
|
|
|
|
@ -406,89 +455,91 @@ export default {
|
|
|
|
|
height: 0,
|
|
|
|
|
left: 0,
|
|
|
|
|
top: 0,
|
|
|
|
|
zIndex: 0,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
options: tool.options,
|
|
|
|
|
zIndex: 0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
options: tool.options
|
|
|
|
|
};
|
|
|
|
|
// 处理默认值
|
|
|
|
|
const widgetJsonValue = this.handleDefaultValue(widgetJson)
|
|
|
|
|
const widgetJsonValue = this.handleDefaultValue(widgetJson);
|
|
|
|
|
// 将选中的复制组件,放到工作区中去
|
|
|
|
|
this.widgets.push(this.deepClone(widgetJsonValue))
|
|
|
|
|
|
|
|
|
|
this.widgets.push(this.deepClone(widgetJsonValue));
|
|
|
|
|
// 激活新组件的配置属性
|
|
|
|
|
this.setOptionsOnClickWidget(this.widgets.length - 1)
|
|
|
|
|
this.setOptionsOnClickWidget(this.widgets.length - 1);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 对组件默认值处理
|
|
|
|
|
handleDefaultValue(widgetJson) {
|
|
|
|
|
for (const key in widgetJson) {
|
|
|
|
|
if (key == 'options') {
|
|
|
|
|
if (key == "options") {
|
|
|
|
|
// collapse、data、position、setup
|
|
|
|
|
// setup 处理
|
|
|
|
|
for (let i = 0; i < widgetJson.options.setup.length; i++) {
|
|
|
|
|
const item = widgetJson.options.setup[i]
|
|
|
|
|
if (Object.prototype.toString.call(item) == '[object Object]') {
|
|
|
|
|
widgetJson.value.setup[item.name] = item.value
|
|
|
|
|
} else if (Object.prototype.toString.call(item) == '[object Array]') {
|
|
|
|
|
const item = widgetJson.options.setup[i];
|
|
|
|
|
if (Object.prototype.toString.call(item) == "[object Object]") {
|
|
|
|
|
widgetJson.value.setup[item.name] = item.value;
|
|
|
|
|
} else if (
|
|
|
|
|
Object.prototype.toString.call(item) == "[object Array]"
|
|
|
|
|
) {
|
|
|
|
|
for (let j = 0; j < item.length; j++) {
|
|
|
|
|
const list = item[j].list
|
|
|
|
|
list.forEach((el) => {
|
|
|
|
|
widgetJson.value.setup[el.name] = el.value
|
|
|
|
|
})
|
|
|
|
|
const list = item[j].list;
|
|
|
|
|
list.forEach(el => {
|
|
|
|
|
widgetJson.value.setup[el.name] = el.value;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// position
|
|
|
|
|
for (let i = 0; i < widgetJson.options.position.length; i++) {
|
|
|
|
|
const item = widgetJson.options.position[i]
|
|
|
|
|
const item = widgetJson.options.position[i];
|
|
|
|
|
if (item.value) {
|
|
|
|
|
widgetJson.value.position[item.name] = item.value
|
|
|
|
|
widgetJson.value.position[item.name] = item.value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// data 处理
|
|
|
|
|
if (widgetJson.options.data && widgetJson.options.data.length > 0) {
|
|
|
|
|
for (let i = 0; i < widgetJson.options.data.length; i++) {
|
|
|
|
|
const item = widgetJson.options.data[i]
|
|
|
|
|
const item = widgetJson.options.data[i];
|
|
|
|
|
if (item.value) {
|
|
|
|
|
widgetJson.value.data[item.name] = item.value
|
|
|
|
|
widgetJson.value.data[item.name] = item.value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return widgetJson
|
|
|
|
|
return widgetJson;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 如果是点击大屏设计器中的底层,加载大屏底层属性
|
|
|
|
|
setOptionsOnClickScreen() {
|
|
|
|
|
this.screenCode = 'screen'
|
|
|
|
|
this.screenCode = "screen";
|
|
|
|
|
// 选中不同的组件 右侧都显示第一栏
|
|
|
|
|
this.activeName = 'first'
|
|
|
|
|
this.widgetOptions = getToolByCode('screen')['options']
|
|
|
|
|
this.activeName = "first";
|
|
|
|
|
this.widgetOptions = getToolByCode("screen")["options"];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 如果是点击某个组件,获取该组件的配置项
|
|
|
|
|
setOptionsOnClickWidget(index) {
|
|
|
|
|
// 选中不同的组件 右侧都显示第一栏
|
|
|
|
|
this.activeName = 'first'
|
|
|
|
|
this.screenCode = ''
|
|
|
|
|
if (typeof index == 'number') {
|
|
|
|
|
this.activeName = "first";
|
|
|
|
|
this.screenCode = "";
|
|
|
|
|
if (typeof index == "number") {
|
|
|
|
|
if (index < 0 || index >= this.widgets.length) {
|
|
|
|
|
return
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.widgetIndex = index
|
|
|
|
|
console.log(this.deepClone(this.widgets[index]['options']))
|
|
|
|
|
this.widgetOptions = this.deepClone(this.widgets[index]['options'])
|
|
|
|
|
return
|
|
|
|
|
this.widgetIndex = index;
|
|
|
|
|
this.widgetOptions = this.deepClone(this.widgets[index]["options"]);
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
// 执行传递过来的值
|
|
|
|
|
this.widgets[index.index].value.position = index.obj
|
|
|
|
|
this.widgets[index.index].value.position = index.obj;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 将当前选中的组件,右侧属性值更新
|
|
|
|
|
widgetValueChanged(key, val) {
|
|
|
|
|
console.log(key);
|
|
|
|
|
console.log(val);
|
|
|
|
|
/* 更新指定 this.widgets 中第 this.widgetIndex 个组件的value
|
|
|
|
|
widgets: [{
|
|
|
|
|
type: 'widget-text',
|
|
|
|
@ -498,58 +549,62 @@ export default {
|
|
|
|
|
position: {}
|
|
|
|
|
}
|
|
|
|
|
}]*/
|
|
|
|
|
if (this.screenCode == 'screen') {
|
|
|
|
|
this.dashboard = this.deepClone(val)
|
|
|
|
|
if (this.screenCode == "screen") {
|
|
|
|
|
this.dashboard = this.deepClone(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.widgets.length; i++) {
|
|
|
|
|
if (this.widgetIndex == i) {
|
|
|
|
|
this.widgets[i].value[key] = this.deepClone(val)
|
|
|
|
|
this.setDefaultValue(this.widgets[i].options[key], val)
|
|
|
|
|
this.widgets[i].value[key] = this.deepClone(val);
|
|
|
|
|
this.setDefaultValue(this.widgets[i].options[key], val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
console.log(this.widgets);
|
|
|
|
|
},
|
|
|
|
|
rightClick(event, index) {
|
|
|
|
|
this.rightClickIndex = index
|
|
|
|
|
const left = event.clientX
|
|
|
|
|
const top = event.clientY
|
|
|
|
|
this.rightClickIndex = index;
|
|
|
|
|
const left = event.clientX;
|
|
|
|
|
const top = event.clientY;
|
|
|
|
|
if (left || top) {
|
|
|
|
|
this.styleObj = {
|
|
|
|
|
left: left + 'px',
|
|
|
|
|
top: top + 'px',
|
|
|
|
|
display: 'block',
|
|
|
|
|
}
|
|
|
|
|
left: left + "px",
|
|
|
|
|
top: top + "px",
|
|
|
|
|
display: "block"
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
this.visibleContentMenu = true
|
|
|
|
|
return false
|
|
|
|
|
this.visibleContentMenu = true;
|
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
deletelayer() {
|
|
|
|
|
this.widgets.splice(this.rightClickIndex, 1)
|
|
|
|
|
this.widgets.splice(this.rightClickIndex, 1);
|
|
|
|
|
// console.log(this.widgets);
|
|
|
|
|
},
|
|
|
|
|
setDefaultValue(options, val) {
|
|
|
|
|
for (let i = 0; i < options.length; i++) {
|
|
|
|
|
if (Object.prototype.toString.call(options[i]) == '[object Object]') {
|
|
|
|
|
if (Object.prototype.toString.call(options[i]) == "[object Object]") {
|
|
|
|
|
for (const k in val) {
|
|
|
|
|
if (options[i].name == k) {
|
|
|
|
|
options[i].value = val[k]
|
|
|
|
|
options[i].value = val[k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (Object.prototype.toString.call(options[i]) == '[object Array]') {
|
|
|
|
|
} else if (
|
|
|
|
|
Object.prototype.toString.call(options[i]) == "[object Array]"
|
|
|
|
|
) {
|
|
|
|
|
for (let j = 0; j < options[i].length; j++) {
|
|
|
|
|
const list = options[i][j].list
|
|
|
|
|
const list = options[i][j].list;
|
|
|
|
|
for (let z = 0; z < list.length; z++) {
|
|
|
|
|
for (const k in val) {
|
|
|
|
|
if (list[z].name == k) {
|
|
|
|
|
list[z].value = val[k]
|
|
|
|
|
list[z].value = val[k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|