123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452 |
- <!--
- * @Descripttion: 大屏设计器
- * @Author: lide1202@hotmail.com
- * @Date: 2021-3-13 11:04:24
- * @Last Modified by: lide1202@hotmail.com
- * @Last Modified time: 2021-3-13 11:04:24
- !-->
- <template>
- <div class="layout">
- <div
- v-if="toolIsShow"
- class="layout-left"
- :style="{ width: widthLeftForTools + 'px' }"
- >
- <el-tabs class="layout-left" type="border-card" :stretch="true">
- <!-- 左侧组件栏-->
- <el-tab-pane label="工具栏">
- <span slot="label"><i class="el-icon-date icon"></i>工具栏</span>
- <div class="chart-type">
- <el-tabs class="type-left" tab-position="left">
- <el-tab-pane
- v-for="(item, index) in widgetTools"
- :key="index"
- :label="item.name"
- >
- <li
- v-for="(it, idx) in item.list"
- :key="idx"
- draggable="true"
- @dragstart="dragStart(it.code)"
- @dragend="dragEnd()"
- >
- <div class="tools-item">
- <span class="tools-item-icon">
- <i class="iconfont" :class="it.icon"></i>
- </span>
- <span class="tools-item-text">{{ it.label }}</span>
- </div>
- </li>
- </el-tab-pane>
- </el-tabs>
- </div>
- </el-tab-pane>
- <!-- 左侧图层-->
- <el-tab-pane label="图层">
- <draggable
- v-model="layerWidget"
- @update="datadragEnd"
- :options="{ animation: 300 }"
- >
- <transition-group>
- <div
- v-for="(item, index) in layerWidget"
- :key="'item' + index"
- class="tools-item"
- :class="widgetIndex == index ? 'is-active' : ''"
- @click="layerClick(index)"
- >
- <span class="tools-item-icon">
- <i class="iconfont" :class="item.icon"></i>
- </span>
- <span class="tools-item-text">{{ item.label }}</span>
- </div>
- </transition-group>
- </draggable>
- </el-tab-pane>
- </el-tabs>
- </div>
- <div
- class="layout-left-fold"
- :style="{ width: widthLeftForToolsHideButton + 'px' }"
- @click="toolIsShow = !toolIsShow"
- >
- <i class="el-icon-arrow-right" />
- </div>
- <div
- class="layout-middle"
- :style="{ width: middleWidth + 'px', height: middleHeight + 'px' }"
- >
- <div class="top-button">
- <span class="btn">
- <el-tooltip
- class="item"
- effect="dark"
- content="保存"
- placement="bottom"
- >
- <i class="iconfont iconsave" @click="saveData"></i>
- </el-tooltip>
- </span>
- <span class="btn">
- <el-tooltip
- class="item"
- effect="dark"
- content="预览"
- placement="bottom"
- >
- <i class="iconfont iconyulan" @click="viewScreen"></i>
- </el-tooltip>
- </span>
- <span class="btn">
- <el-tooltip
- class="item"
- effect="dark"
- content="撤销"
- placement="bottom"
- >
- <i class="iconfont iconundo" @click="handleUndo"></i>
- </el-tooltip>
- </span>
- <span class="btn">
- <el-tooltip
- class="item"
- effect="dark"
- content="恢复"
- placement="bottom"
- >
- <i class="iconfont iconhuifubeifen" @click="handleRedo"></i>
- </el-tooltip>
- </span>
- <span class="btn" v-permission="'bigScreenManage:export'">
- <el-tooltip
- class="item"
- effect="dark"
- content="导入"
- placement="bottom"
- >
- <el-upload
- class="el-upload"
- ref="upload"
- :action="uploadUrl"
- :headers="headers"
- accept=".zip"
- :on-success="handleUpload"
- :on-error="handleError"
- :show-file-list="false"
- :limit="1"
- >
- <i class="iconfont icondaoru"></i>
- </el-upload>
- </el-tooltip>
- </span>
- <span class="btn border-left" v-permission="'bigScreenManage:import'">
- <ul class="nav">
- <li>
- <i class="iconfont icondaochu"></i
- ><i class="el-icon-arrow-down"></i>
- <ul>
- <li>
- <el-tooltip
- class="item"
- effect="dark"
- content="适合当前系统"
- placement="right"
- >
- <div @click="exportDashboard(1)">导出(包含数据集)</div>
- </el-tooltip>
- </li>
- <li>
- <el-tooltip
- class="item"
- effect="dark"
- content="适合跨系统"
- placement="right"
- >
- <div @click="exportDashboard(0)">导出(不包含数据集)</div>
- </el-tooltip>
- </li>
- </ul>
- </li>
- </ul>
- </span>
- </div>
- <div
- class="workbench-container"
- :style="{
- width: bigscreenWidthInWorkbench + 'px',
- height: bigscreenHeightInWorkbench + 'px',
- }"
- @mousedown="handleMouseDown"
- >
- <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"
- 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.self="setOptionsOnClickScreen"
- @drop="widgetOnDragged($event)"
- @dragover="dragOver($event)"
- >
- <div v-if="grade" class="bg-grid"></div>
- <widget
- ref="widgets"
- v-for="(widget, index) in widgets"
- :key="index"
- v-model="widget.value"
- :index="index"
- :step="step"
- :type="widget.type"
- :bigscreen="{ bigscreenWidth, bigscreenHeight }"
- @onActivated="setOptionsOnClickWidget"
- @contextmenu.prevent.native="rightClick($event, index)"
- @mousedown.prevent.native="widgetsClick(index)"
- @mouseup.prevent.native="widgetsMouseup"
- />
- </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)
- "
- name="first"
- label="配置"
- >
- <dynamicForm
- ref="formData"
- :options="widgetOptions.setup"
- @onChanged="(val) => widgetValueChanged('setup', val)"
- />
- </el-tab-pane>
- <el-tab-pane
- v-if="isNotNull(widgetOptions.data)"
- name="second"
- label="数据"
- >
- <dynamicForm
- ref="formData"
- :options="widgetOptions.data"
- @onChanged="(val) => widgetValueChanged('data', val)"
- />
- </el-tab-pane>
- <el-tab-pane
- v-if="isNotNull(widgetOptions.position)"
- name="third"
- label="坐标"
- >
- <dynamicForm
- ref="formData"
- :options="widgetOptions.position"
- @onChanged="(val) => widgetValueChanged('position', val)"
- />
- </el-tab-pane>
- </el-tabs>
- </div>
- <content-menu
- :visible.sync="visibleContentMenu"
- :style-obj="styleObj"
- @deletelayer="deletelayer"
- @copylayer="copylayer"
- @istopLayer="istopLayer"
- @setlowLayer="setlowLayer"
- @moveupLayer="moveupLayer"
- @movedownLayer="movedownLayer"
- />
- </div>
- </template>
- <script>
- import {
- insertDashboard,
- detailDashboard,
- importDashboard,
- exportDashboard,
- } from "@/api/bigscreen";
- import { widgetTools, getToolByCode } from "./tools/index";
- import widget from "./widget/widget.vue";
- import dynamicForm from "./components/dynamicForm.vue";
- import draggable from "vuedraggable";
- import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
- import contentMenu from "./components/contentMenu";
- import { getToken } from "@/utils/auth";
- import { Revoke } from "@/utils/revoke"; //处理历史记录 2022-02-22
- export default {
- name: "Login",
- components: {
- draggable,
- VueRulerTool,
- widget,
- dynamicForm,
- contentMenu,
- },
- data() {
- return {
- uploadUrl:
- process.env.BASE_API +
- "/reportDashboard/import/" +
- this.$route.query.reportCode,
- grade: false,
- layerWidget: [],
- widgetTools: widgetTools, // 左侧工具栏的组件图标,将js变量加入到当前作用域
- widthLeftForTools: 200, // 左侧工具栏宽度
- widthLeftForToolsHideButton: 15, // 左侧工具栏折叠按钮宽度
- widthLeftForOptions: 300, // 右侧属性配置区
- widthPaddingTools: 18,
- toolIsShow: true, // 左侧工具栏是否显示
- bigscreenWidth: 1920, // 大屏设计的大小
- bigscreenHeight: 1080,
- revoke: null, //处理历史记录 2022-02-22
- // 工作台大屏画布,保存到表gaea_report_dashboard中
- dashboard: {
- id: null,
- title: "", // 大屏页面标题
- width: 1920, // 大屏设计宽度
- height: 1080, // 大屏设计高度
- backgroundColor: "", // 大屏背景色
- backgroundImage: "", // 大屏背景图片
- refreshSeconds: null, // 大屏刷新时间间隔
- presetLine: [], // 辅助线
- presetLineVisible: true, // 辅助线是否显示
- },
- // 大屏的标记
- screenCode: "",
- dragWidgetCode: "", //从工具栏拖拽的组件code
- // 大屏画布中的组件
- widgets: [
- {
- // type和value最终存到数据库中去,保存到gaea_report_dashboard_widget中
- type: "widget-text",
- value: {
- setup: {},
- data: {},
- position: {
- width: 100,
- height: 100,
- left: 0,
- top: 0,
- zIndex: 0,
- },
- },
- // options属性是从工具栏中拿到的tools中拿到
- options: [],
- },
- ], // 工作区中拖放的组件
- // 当前激活组件
- widgetIndex: 0,
- // 当前激活组件右侧配置属性
- widgetOptions: {
- setup: [], // 配置
- data: [], // 数据
- position: [], // 坐标
- },
- flagWidgetClickStopPropagation: false, // 点击组件时阻止事件冒泡传递到画布click事件上
- styleObj: {
- left: 0,
- top: 0,
- },
- visibleContentMenu: false,
- rightClickIndex: -1,
- activeName: "first",
- };
- },
- computed: {
- step() {
- return Number(100 / (this.bigscreenScaleInWorkbench * 100));
- },
- headers() {
- return {
- Authorization: getToken(), // 直接从本地获取token就行
- };
- },
- // 左侧折叠切换时,动态计算中间区的宽度
- middleWidth() {
- let widthLeftAndRight = 0;
- if (this.toolIsShow) {
- widthLeftAndRight += this.widthLeftForTools; // 左侧工具栏宽度
- }
- widthLeftAndRight += this.widthLeftForToolsHideButton; // 左侧工具栏折叠按钮宽度
- widthLeftAndRight += this.widthLeftForOptions; // 右侧配置栏宽度
- let middleWidth = this.bodyWidth - widthLeftAndRight;
- return middleWidth;
- },
- middleHeight() {
- return this.bodyHeight;
- },
- // 设计台按大屏的缩放比例
- bigscreenScaleInWorkbench() {
- let widthScale =
- (this.middleWidth - this.widthPaddingTools) / this.bigscreenWidth;
- let heightScale =
- (this.middleHeight - this.widthPaddingTools) / this.bigscreenHeight;
- return Math.min(widthScale, heightScale);
- },
- workbenchTransform() {
- return `scale(${this.bigscreenScaleInWorkbench}, ${this.bigscreenScaleInWorkbench})`;
- },
- // 大屏在设计模式的大小
- bigscreenWidthInWorkbench() {
- return this.getPXUnderScale(this.bigscreenWidth) + this.widthPaddingTools;
- },
- bigscreenHeightInWorkbench() {
- return (
- this.getPXUnderScale(this.bigscreenHeight) + this.widthPaddingTools
- );
- },
- },
- watch: {
- widgets: {
- handler(val) {
- this.handlerLayerWidget(val);
- //以下部分是记录历史
- this.$nextTick(() => {
- this.revoke.push(this.widgets);
- });
- },
- deep: true,
- },
- },
- created() {
- /* 以下是记录历史的 */
- this.revoke = new Revoke();
- },
- mounted() {
- // 如果是新的设计工作台
- this.initEchartData();
- this.widgets = [];
- window.addEventListener("mouseup", () => {
- this.grade = false;
- });
- },
- methods: {
- /**
- * @description: 恢复
- * @param {*}
- * @return {*}
- */
- handleUndo() {
- const record = this.revoke.undo();
- if (!record) {
- return false;
- }
- this.widgets = record;
- },
- /**
- * @description: 重做
- * @param {*}
- * @return {*}
- */
- handleRedo() {
- const record = this.revoke.redo();
- if (!record) {
- return false;
- }
- this.widgets = record;
- },
- handlerLayerWidget(val) {
- const layerWidgetArr = [];
- for (let i = 0; i < val.length; i++) {
- const obj = {};
- obj.icon = getToolByCode(val[i].type).icon;
- const options = val[i].options["setup"];
- options.forEach((el) => {
- if (el.name == "layerName") {
- obj.label = el.value;
- }
- });
- layerWidgetArr.push(obj);
- }
- this.layerWidget = layerWidgetArr;
- },
- 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;
- this.bigscreenWidth = this.dashboard.width;
- this.bigscreenHeight = this.dashboard.height;
- },
- handleBigScreen(data) {
- const optionScreen = 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];
- }
- }
- }
- this.setOptionsOnClickScreen();
- return {
- backgroundColor: (data && data.backgroundColor) || "",
- backgroundImage: (data && data.backgroundImage) || "",
- height: (data && data.height) || "1080",
- title: (data && data.title) || "",
- width: (data && data.width) || "1920",
- };
- },
- handleInitEchartsData(data) {
- const widgets = data.dashboard ? data.dashboard.widgets : [];
- const widgetsData = [];
- for (let i = 0; i < widgets.length; i++) {
- let obj = {};
- obj.type = widgets[i].type;
- obj.value = {
- setup: widgets[i].value.setup,
- data: widgets[i].value.data,
- 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);
- }
- 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];
- }
- } 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];
- }
- });
- }
- }
- }
- }
- // position
- 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];
- }
- }
- }
- // data
- 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];
- }
- }
- }
- return option;
- },
- // 保存数据
- async saveData() {
- if (!this.widgets || this.widgets.length == 0) {
- this.$message.error("请添加组件");
- return;
- }
- const screenData = {
- reportCode: this.$route.query.reportCode,
- dashboard: {
- title: this.dashboard.title,
- width: this.dashboard.width,
- height: this.dashboard.height,
- backgroundColor: this.dashboard.backgroundColor,
- backgroundImage: this.dashboard.backgroundImage,
- },
- widgets: this.widgets,
- };
- const { code, data } = await insertDashboard(screenData);
- if (code == "200") {
- this.$message.success("保存成功!");
- }
- },
- // 预览
- viewScreen() {
- let routeUrl = this.$router.resolve({
- path: "/bigscreen/viewer",
- query: { reportCode: this.$route.query.reportCode },
- });
- window.open(routeUrl.href, "_blank");
- },
- // 导出
- async exportDashboard(val) {
- const fileName = this.$route.query.reportCode + ".zip";
- const param = {
- reportCode: this.$route.query.reportCode,
- showDataSet: val,
- };
- exportDashboard(param).then((res) => {
- const that = this;
- const type = res.type;
- if (type == "application/json") {
- let reader = new FileReader();
- reader.readAsText(res, "utf-8");
- reader.onload = function () {
- const data = JSON.parse(reader.result);
- that.$message.error(data.message);
- };
- return;
- }
- const blob = new Blob([res], { type: "application/octet-stream" });
- if (window.navigator.msSaveOrOpenBlob) {
- //msSaveOrOpenBlob方法返回bool值
- navigator.msSaveBlob(blob, fileName); //本地保存
- } else {
- const link = document.createElement("a"); //a标签下载
- link.href = window.URL.createObjectURL(blob);
- link.download = fileName;
- link.click();
- window.URL.revokeObjectURL(link.href);
- }
- });
- },
- // 上传成功的回调
- handleUpload(response, file, fileList) {
- //清除el-upload组件中的文件
- this.$refs.upload.clearFiles();
- //刷新大屏页面
- this.initEchartData();
- if (response.code == "200") {
- this.$message({
- message: "导入成功!",
- type: "success",
- });
- } else {
- this.$message({
- message: response.message,
- type: "error",
- });
- }
- },
- handleError(err) {
- this.$message({
- message: "上传失败!",
- type: "error",
- });
- },
- // 在缩放模式下的大小
- getPXUnderScale(px) {
- return this.bigscreenScaleInWorkbench * px;
- },
- dragStart(widgetCode) {
- this.dragWidgetCode = widgetCode;
- },
- dragEnd() {
- this.dragWidgetCode = "";
- },
- dragOver(evt) {
- evt.preventDefault();
- evt.stopPropagation();
- evt.dataTransfer.dropEffect = "copy";
- },
- // 拖动一个组件放到工作区中去,在拖动结束时,放到工作区对应的坐标点上去
- widgetOnDragged(evt) {
- let widgetType = this.dragWidgetCode;
- // 获取结束坐标和列名
- let eventX = evt.clientX; // 结束在屏幕的x坐标
- let eventY = evt.clientY; // 结束在屏幕的y坐标
- let workbenchPosition = this.getDomTopLeftById("workbench");
- let widgetTopInWorkbench = eventY - workbenchPosition.top;
- let widgetLeftInWorkbench = eventX - workbenchPosition.left;
- // 计算在缩放模式下的x y
- let x = widgetLeftInWorkbench / this.bigscreenScaleInWorkbench;
- let y = widgetTopInWorkbench / this.bigscreenScaleInWorkbench;
- // 复制一个组件
- let tool = getToolByCode(widgetType);
- let widgetJson = {
- type: widgetType,
- value: {
- setup: {},
- data: {},
- position: {
- width: 0,
- height: 0,
- left: 0,
- top: 0,
- zIndex: 0,
- },
- },
- options: tool.options,
- };
- // 处理默认值
- const widgetJsonValue = this.handleDefaultValue(widgetJson);
- //2022年02月22日 修复:可以拖拽放到鼠标的位置
- widgetJsonValue.value.position.left =
- x - widgetJsonValue.value.position.width / 2;
- widgetJsonValue.value.position.top =
- y - widgetJsonValue.value.position.height / 2;
- // 将选中的复制组件,放到工作区中去
- this.widgets.push(this.deepClone(widgetJsonValue));
- // 激活新组件的配置属性
- this.setOptionsOnClickWidget(this.widgets.length - 1);
- },
- // 对组件默认值处理
- handleDefaultValue(widgetJson) {
- for (const key in widgetJson) {
- 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]"
- ) {
- for (let j = 0; j < item.length; j++) {
- 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];
- if (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];
- if (item.value) {
- widgetJson.value.data[item.name] = item.value;
- }
- }
- }
- }
- }
- return widgetJson;
- },
- layerClick(index) {
- this.widgetIndex = index;
- this.widgetsClick(index);
- },
- // 如果是点击大屏设计器中的底层,加载大屏底层属性
- setOptionsOnClickScreen() {
- this.screenCode = "screen";
- // 选中不同的组件 右侧都显示第一栏
- this.activeName = "first";
- this.widgetOptions = getToolByCode("screen")["options"];
- },
- // 如果是点击某个组件,获取该组件的配置项
- setOptionsOnClickWidget(obj) {
- this.screenCode = "";
- if (typeof obj == "number") {
- this.widgetOptions = this.deepClone(this.widgets[obj]["options"]);
- return;
- }
- if (obj.index < 0 || obj.index >= this.widgets.length) {
- return;
- }
- this.widgetIndex = obj.index;
- this.widgets[obj.index].value.position = obj;
- this.widgets[obj.index].options.position.forEach((el) => {
- for (const key in obj) {
- if (el.name == key) {
- el.value = obj[key];
- }
- }
- });
- this.widgetOptions = this.deepClone(this.widgets[obj.index]["options"]);
- },
- widgetsClick(index) {
- const draggableArr = this.$refs.widgets;
- for (let i = 0; i < draggableArr.length; i++) {
- if (i == index) {
- this.$refs.widgets[i].$refs.draggable.setActive(true);
- } else {
- this.$refs.widgets[i].$refs.draggable.setActive(false);
- }
- }
- this.setOptionsOnClickWidget(index);
- this.grade = true;
- },
- widgetsMouseup(e) {
- this.grade = false;
- },
- handleMouseDown() {
- const draggableArr = this.$refs.widgets;
- for (let i = 0; i < draggableArr.length; i++) {
- this.$refs.widgets[i].$refs.draggable.setActive(false);
- }
- },
- // 将当前选中的组件,右侧属性值更新
- widgetValueChanged(key, val) {
- console.log("key", key);
- console.log("val", val);
- console.log(this.widgetOptions);
- if (this.screenCode == "screen") {
- let newSetup = new Array();
- this.dashboard = this.deepClone(val);
- console.log("asd", this.dashboard);
- console.log(this.widgetOptions);
- if (this.bigscreenWidth != this.dashboard.width) {
- this.bigscreenWidth = this.dashboard.width;
- }
- if (this.bigscreenHeight != this.dashboard.height) {
- this.bigscreenHeight = this.dashboard.height;
- }
- this.widgetOptions.setup.forEach((el) => {
- if (el.name == "width") {
- el.value = this.bigscreenWidth;
- } else if (el.name == "height") {
- el.value = this.bigscreenHeight;
- } else if (this.dashboard.hasOwn(el.name)) {
- el["value"] = this.dashboard[el.name];
- }
- newSetup.push(el);
- });
- console.log(newSetup);
- this.widgetOptions.setup = newSetup;
- } else {
- 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);
- }
- }
- }
- },
- rightClick(event, index) {
- this.rightClickIndex = index;
- const left = event.clientX;
- const top = event.clientY;
- if (left || top) {
- this.styleObj = {
- left: left + "px",
- top: top + "px",
- display: "block",
- };
- }
- this.visibleContentMenu = true;
- return false;
- },
- setDefaultValue(options, val) {
- for (let i = 0; i < options.length; i++) {
- if (Object.prototype.toString.call(options[i]) == "[object Object]") {
- for (const k in val) {
- if (options[i].name == k) {
- options[i].value = val[k];
- }
- }
- } 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;
- for (let z = 0; z < list.length; z++) {
- for (const k in val) {
- if (list[z].name == k) {
- list[z].value = val[k];
- }
- }
- }
- }
- }
- }
- },
- datadragEnd(evt) {
- evt.preventDefault();
- this.widgets = this.swapArr(this.widgets, evt.oldIndex, evt.newIndex);
- },
- // 数组 元素互换位置
- swapArr(arr, oldIndex, newIndex) {
- arr[oldIndex] = arr.splice(newIndex, 1, arr[oldIndex])[0];
- return arr;
- },
- // 删除
- deletelayer() {
- this.widgets.splice(this.rightClickIndex, 1);
- },
- // 复制
- copylayer() {
- const obj = this.deepClone(this.widgets[this.rightClickIndex]);
- this.widgets.splice(this.widgets.length, 0, obj);
- },
- // 置顶
- istopLayer() {
- if (this.rightClickIndex + 1 < this.widgets.length) {
- const temp = this.widgets.splice(this.rightClickIndex, 1)[0];
- this.widgets.push(temp);
- }
- },
- // 置底
- setlowLayer() {
- if (this.rightClickIndex != 0) {
- this.widgets.unshift(this.widgets.splice(this.rightClickIndex, 1)[0]);
- }
- },
- // 上移一层
- moveupLayer() {
- if (this.rightClickIndex != 0) {
- this.widgets[this.rightClickIndex] = this.widgets.splice(
- this.rightClickIndex - 1,
- 1,
- this.widgets[this.rightClickIndex]
- )[0];
- } else {
- this.widgets.push(this.widgets.shift());
- }
- },
- // 下移一层
- movedownLayer() {
- if (this.rightClickIndex != this.widgets.length - 1) {
- this.widgets[this.rightClickIndex] = this.widgets.splice(
- this.rightClickIndex + 1,
- 1,
- this.widgets[this.rightClickIndex]
- )[0];
- } else {
- this.widgets.unshift(this.widgets.splice(this.rightClickIndex, 1)[0]);
- }
- },
- },
- };
- </script>
- <style scoped lang="scss">
- .mr10 {
- margin-right: 10px;
- }
- .ml20 {
- margin-left: 20px;
- }
- .border-right {
- border-right: 1px solid #273b4d;
- }
- .border-left {
- border-left: 1px solid #273b4d;
- }
- .el-icon-arrow-down {
- font-size: 10px;
- }
- .is-active {
- background: #31455d !important;
- color: #bfcbd9 !important;
- }
- .layout {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- width: 100%;
- height: 100%;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- overflow: hidden;
- .layout-left {
- display: inline-block;
- height: 100%;
- box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border: 0px;
- background-color: #263445;
- //工具栏一个元素
- .tools-item {
- display: flex;
- position: relative;
- width: 100%;
- height: 48px;
- align-items: center;
- -webkit-box-align: center;
- padding: 0 6px;
- cursor: pointer;
- font-size: 12px;
- margin-bottom: 1px;
- .tools-item-icon {
- color: #409eff;
- margin-right: 10px;
- width: 53px;
- height: 30px;
- line-height: 30px;
- text-align: center;
- display: block;
- border: 1px solid #3a4659;
- background: #282a30;
- }
- .tools-item-text {
- }
- }
- }
- .layout-left-fold {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- height: 100%;
- font-size: 12px;
- overflow: hidden;
- background-color: #242a30;
- cursor: pointer;
- padding-top: 26%;
- i {
- font-size: 18px;
- width: 18px;
- height: 23px;
- margin-left: 0px;
- color: #bfcbd9;
- }
- }
- .layout-middle {
- // display: flex;
- position: relative;
- //width: calc(100% - 445px);
- height: 100%;
- background-color: rgb(36, 42, 48);
- box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border: 1px solid rgb(36, 42, 48);
- align-items: center;
- vertical-align: middle;
- text-align: center;
- .top-button {
- display: flex;
- flex-direction: row;
- height: 40px;
- line-height: 40px;
- margin-left: 9px;
- .btn {
- color: #788994;
- width: 55px;
- text-align: center;
- display: block;
- cursor: pointer;
- .el-icon-arrow-down {
- transform: rotate(0deg);
- -ms-transform: rotate(0deg); /* IE 9 */
- -moz-transform: rotate(0deg); /* Firefox */
- -webkit-transform: rotate(0deg); /* Safari 和 Chrome */
- -o-transform: rotate(0deg); /* Opera */
- transition: all 0.4s ease-in-out;
- }
- &:hover {
- background: rgb(25, 29, 34);
- .el-icon-arrow-down {
- transform: rotate(180deg);
- -ms-transform: rotate(180deg); /* IE 9 */
- -moz-transform: rotate(180deg); /* Firefox */
- -webkit-transform: rotate(180deg); /* Safari 和 Chrome */
- -o-transform: rotate(180deg); /* Opera */
- transition: all 0.4s ease-in-out;
- }
- }
- }
- }
- .workbench-container {
- position: relative;
- -webkit-transform-origin: 0 0;
- transform-origin: 0 0;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- .vueRuler {
- width: 100%;
- padding: 18px 0px 0px 18px;
- }
- .workbench {
- background-color: #1e1e1e;
- position: relative;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-transform-origin: 0 0;
- transform-origin: 0 0;
- margin: 0;
- padding: 0;
- }
- .bg-grid {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-size: 30px 30px, 30px 30px;
- background-image: linear-gradient(
- hsla(0, 0%, 100%, 0.1) 1px,
- transparent 0
- ),
- linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 1px, transparent 0);
- // z-index: 2;
- }
- }
- .bottom-text {
- width: 100%;
- color: #a0a0a0;
- font-size: 16px;
- position: absolute;
- bottom: 20px;
- }
- }
- .layout-right {
- display: inline-block;
- height: 100%;
- }
- /deep/ .el-tabs--border-card {
- border: 0;
- .el-tabs__header {
- .el-tabs__nav {
- .el-tabs__item {
- background-color: #242f3b;
- border: 0px;
- }
- .el-tabs__item.is-active {
- background-color: #31455d;
- }
- }
- }
- .el-tabs__content {
- background-color: #242a30;
- height: calc(100vh - 39px);
- overflow-x: hidden;
- overflow-y: auto;
- .el-tab-pane {
- color: #bfcbd9;
- }
- &::-webkit-scrollbar {
- width: 5px;
- height: 14px;
- }
- &::-webkit-scrollbar-track,
- &::-webkit-scrollbar-thumb {
- border-radius: 1px;
- border: 0 solid transparent;
- }
- &::-webkit-scrollbar-track-piece {
- /*修改滚动条的背景和圆角*/
- background: #29405c;
- -webkit-border-radius: 7px;
- }
- &::-webkit-scrollbar-track {
- box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
- }
- &::-webkit-scrollbar-thumb {
- min-height: 20px;
- background-clip: content-box;
- box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
- }
- &::-webkit-scrollbar-corner {
- background: transparent;
- }
- /*修改垂直滚动条的样式*/
- &::-webkit-scrollbar-thumb:vertical {
- background-color: #00113a;
- -webkit-border-radius: 7px;
- }
- /*修改水平滚动条的样式*/
- &::-webkit-scrollbar-thumb:horizontal {
- background-color: #00113a;
- -webkit-border-radius: 7px;
- }
- }
- }
- }
- ul,
- li {
- list-style: none;
- margin: 0;
- padding: 0;
- }
- .nav {
- width: 40px;
- padding: 0;
- list-style: none;
- /* overflow: hidden; */
- }
- .nav {
- zoom: 1;
- }
- .nav:before,
- .nav:after {
- content: "";
- display: table;
- }
- .nav:after {
- clear: both;
- }
- .nav > li {
- width: 55px;
- text-align: left;
- position: relative;
- }
- .nav > li a {
- float: left;
- padding: 12px 30px;
- color: #999;
- font: bold 12px;
- text-decoration: none;
- }
- .nav > li:hover {
- color: #788994;
- }
- .nav > li ul {
- visibility: hidden;
- position: absolute;
- z-index: 1000;
- list-style: none;
- left: 0;
- padding: 0;
- background-color: rgb(36, 42, 48);
- opacity: 0;
- _margin: 0;
- width: 120px;
- transition: all 0.2s ease-in-out;
- }
- .nav > li:hover > ul {
- opacity: 1;
- visibility: visible;
- margin: 0;
- li:hover {
- background-color: rgb(25, 29, 34);
- }
- }
- .nav ul li {
- float: left;
- display: block;
- border: 0;
- width: 100%;
- font-size: 12px;
- }
- .nav ul a {
- padding: 10px;
- width: 100%;
- display: block;
- float: none;
- height: 120px;
- border: 1px solid #30445c;
- background-color: rgb(25, 29, 34);
- transition: all 0.2s ease-in-out;
- }
- .nav ul a:hover {
- border: 1px solid #3c5e88;
- }
- .nav ul li:first-child > a:hover:before {
- border-bottom-color: #04acec;
- }
- .nav ul ul {
- top: 0;
- left: 120px;
- width: 400px;
- height: 300px;
- overflow: auto;
- padding: 10px;
- _margin: 0;
- }
- .nav ul ul li {
- width: 120px;
- height: 120px;
- margin-right: 3px;
- display: block;
- float: left;
- }
- .nav .item {
- padding: 5px;
- }
- /deep/ .vue-ruler-h {
- opacity: 0.3;
- }
- /deep/ .vue-ruler-v {
- opacity: 0.3;
- }
- .layout-left {
- width: 200px;
- background: #242a30;
- overflow-x: hidden;
- overflow-y: auto;
- .chart-type {
- display: flex;
- flex-direction: row;
- overflow: hidden;
- .type-left {
- width: 100%;
- height: calc(100vh - 80px);
- text-align: center;
- /deep/.el-tabs__header {
- width: 30%;
- margin-right: 0;
- .el-tabs__nav-wrap {
- &::after {
- background: transparent;
- }
- .el-tabs__item {
- text-align: center;
- width: 100% !important;
- color: #fff;
- padding: 0;
- font-size: 12px !important;
- }
- }
- }
- /deep/.el-tabs__content {
- width: 70%;
- }
- }
- }
- //工具栏一个元素
- .tools-item {
- display: flex;
- position: relative;
- width: 100%;
- height: 48px;
- align-items: center;
- -webkit-box-align: center;
- padding: 0 6px;
- cursor: pointer;
- font-size: 12px;
- margin-bottom: 1px;
- .tools-item-icon {
- color: #409eff;
- margin-right: 10px;
- width: 53px;
- height: 30px;
- line-height: 30px;
- text-align: center;
- display: block;
- border: 1px solid #3a4659;
- background: #282a30;
- }
- .tools-item-text {
- font-size: 12px !important;
- }
- }
- /deep/.el-tabs__content {
- padding: 0;
- }
- }
- /* 设置滚动条的样式 */
- ::-webkit-scrollbar {
- width: 0;
- }
- /* 滚动槽 */
- ::-webkit-scrollbar-track {
- -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3);
- }
- /* 滚动条滑块 */
- ::-webkit-scrollbar-thumb {
- background: rgba(0, 0, 0, 0.1);
- -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5);
- }
- ::-webkit-scrollbar-thumb:window-inactive {
- background: rgba(255, 0, 0, 0.4);
- }
- </style>
|