You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
585 lines
22 KiB
585 lines
22 KiB
<template>
|
|
<div class="dashboard-design">
|
|
<list-page-slot class="dashboard-design-right" :show-right-common-actions="false">
|
|
<template #right v-if="$route.query?.design !== '0'">
|
|
<el-button type="primary" @click="openDrawer()" v-if="(dataList && dataList.length === 0 && !isMultiple) || isMultiple">新增 </el-button>
|
|
<template v-if="dataList && dataList.length">
|
|
<el-button color="#9926de" :dark="isDark" @click="openDrawer(activeId)">编辑</el-button>
|
|
<template v-if="!getCurrentItem.scadaUrl">
|
|
<el-button color="#626aef" :dark="isDark" @click="dataSourceVisible = true">数据源</el-button>
|
|
</template>
|
|
<el-button type="success" @click="changeView()">预览</el-button>
|
|
|
|
<!-- <el-button color="#9926de" :dark="isDark">导入</el-button>-->
|
|
<!-- <el-button color="#626aef" :dark="isDark">分享</el-button>-->
|
|
<!-- <el-button color="#be11b9" :dark="isDark">数据源</el-button>-->
|
|
</template>
|
|
</template>
|
|
<div ref="dashboardRef" style="height: 100%">
|
|
<drawer :visible="drawerVisible" @toggle="toggle" :show-toggle-button="dataList && dataList.length && isMultiple">
|
|
<template #drawer>
|
|
<div class="dashboard-left">
|
|
<div class="list" ref="listRef">
|
|
<el-card :class="item.id === activeId ? 'active' : ''" v-for="item in dataList" :key="item.id" :body-style="{ padding: '0px', width: '100%' }" @click.stop="changeBoard(item)" :target="item.id">
|
|
<!-- <img :src="item.svgUrl" class="image" />-->
|
|
<div class="info">
|
|
<svg v-if="item.type === '0'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="20" height="17.447681427001953" viewBox="0 0 20 17.447681427001953">
|
|
<g>
|
|
<path
|
|
d="M18.62,1.37931Q18.6194,1.37931,18.6207,12.8411Q18.6207,12.8422,1.38003,12.8419Q1.38062,12.8419,1.37931,1.38009Q1.37931,1.37893,18.62,1.37931ZM0,12.8411C0,13.6017,0.618221,14.2212,1.38003,14.2212L18.62,14.2212C19.3833,14.2212,20,13.6035,20,12.8411L20,1.38009C20,0.619485,19.3818,0,18.62,0L1.38003,0C0.61669,0,0,0.617626,0,1.38009L0,12.8411ZM16.4209,17.4477C16.8018,17.4477,17.1106,17.1389,17.1106,16.758L17.1106,16.7259C17.1106,16.345,16.8018,16.0363,16.4209,16.0363L3.57907,16.0363C3.19819,16.0363,2.88942,16.345,2.88942,16.7259L2.88942,16.758C2.88942,17.1389,3.19819,17.4477,3.57907,17.4477Q3.95996,17.4477,16.4209,17.4477ZM9.29429,16.0523L10.6736,16.0523L10.6736,14.2212L9.3264,14.2212L9.29429,16.0523Z"
|
|
fill="var(--el-text-color-primary)"
|
|
fill-opacity="1"
|
|
/>
|
|
</g>
|
|
</svg>
|
|
<svg v-else xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="18.462501525878906" height="20" viewBox="0 0 18.462501525878906 20">
|
|
<g>
|
|
<path
|
|
d="M6.1532,0C4.4532,0,3.0782,1.3781,3.0782,3.0781L3.0782,8.4625L0.7688,8.4625C0.3458,8.4625,0,8.8082,0,9.2313L0,13.8469C0,14.2699,0.3457,14.6156,0.7688,14.6156L3.0782,14.6156L3.0782,16.9219C3.0782,18.6219,4.4532,20,6.1532,20L15.3844,20C17.0844,20,18.4625,18.6219,18.4625,16.9219L18.4625,6.153C18.4625,5.3376,17.701,4.5528,16.3625,3.2374L15.7938,2.6686L15.225,2.1C13.9098,0.7615,13.1257,0,12.3094,0L6.1532,0ZM6.1532,1.5375L11.7626,1.5375C12.3164,1.676,12.3094,2.3605,12.3094,3.0375L12.3094,5.3844C12.3094,5.8074,12.6551,6.1531,13.0782,6.1531L15.3844,6.1531C16.1537,6.1531,16.925,6.1526,16.925,6.9219L16.925,16.9219C16.925,17.768,16.2306,18.4625,15.3844,18.4625L6.1533,18.4625C5.3071,18.4625,4.6158,17.768,4.6158,16.9219L4.6158,14.6156L12.3095,14.6156C12.7326,14.6156,13.0783,14.27,13.0783,13.8469L13.0783,9.2313C13.0783,8.8082,12.7326,8.4625,12.3095,8.4625L4.6157,8.4625L4.6157,3.0781C4.6157,2.232,5.307,1.5375,6.1532,1.5375ZM3.9032,9.8719C4.2407,9.8719,4.5407,9.9344,4.8032,10.0594L4.6532,10.4156C4.3907,10.3031,4.1407,10.2469,3.9032,10.2469C3.7032,10.2469,3.5532,10.2906,3.4532,10.3781C3.3532,10.4656,3.3032,10.5844,3.3032,10.7344C3.3032,10.9094,3.3407,11.0406,3.4157,11.1281C3.5032,11.2031,3.7094,11.3156,4.0344,11.4656C4.3719,11.6031,4.5907,11.7469,4.6907,11.8969C4.8032,12.0344,4.8594,12.2094,4.8594,12.4219C4.8594,12.7094,4.7594,12.9406,4.5594,13.1156C4.3594,13.2906,4.0719,13.3781,3.6969,13.3781C3.3344,13.3781,3.0469,13.3281,2.8344,13.2281L2.8344,12.8156C3.1344,12.9406,3.4219,13.0031,3.6969,13.0031C3.9469,13.0031,4.1282,12.9594,4.2407,12.8719C4.3657,12.7844,4.4282,12.6469,4.4282,12.4594C4.4282,12.3094,4.3844,12.1844,4.2969,12.0844C4.2344,12.0219,4.0032,11.9031,3.6032,11.7281C3.3407,11.6031,3.1532,11.4656,3.0407,11.3156C2.9282,11.1656,2.8719,10.9719,2.8719,10.7344C2.8719,10.4719,2.9594,10.2656,3.1344,10.1156C3.3219,9.9531,3.5782,9.8719,3.9032,9.8719ZM9.6782,9.8719C10.0282,9.8719,10.3407,9.9344,10.6157,10.0594L10.4469,10.4531C10.1719,10.3156,9.9032,10.2469,9.6407,10.2469C9.2782,10.2469,8.9907,10.3656,8.7782,10.6031C8.5657,10.8406,8.4594,11.1844,8.4594,11.6344C8.4594,12.0844,8.5532,12.4281,8.7407,12.6656C8.9407,12.8906,9.2407,13.0031,9.6407,13.0031C9.8282,13.0031,10.0282,12.9781,10.2407,12.9281L10.2407,11.9156L9.5469,11.9156L9.5469,11.5219L10.6719,11.5219L10.6719,13.2094C10.3219,13.3219,9.9407,13.3781,9.5282,13.3781C9.0657,13.3781,8.6969,13.2281,8.4219,12.9281C8.1469,12.6281,8.0094,12.1906,8.0094,11.6156C8.0094,11.0656,8.1532,10.6406,8.4407,10.3406C8.7407,10.0281,9.1532,9.8719,9.6782,9.8719ZM5.0844,9.9094L5.5532,9.9094L6.2469,12.0844C6.3094,12.2969,6.3782,12.5594,6.4532,12.8719C6.4907,12.6469,6.5594,12.3781,6.6594,12.0656L7.3532,9.9094L7.8032,9.9094L6.6593,13.3406L6.2283,13.3406L5.0844,9.9094Z"
|
|
fill="var(--el-text-color-primary)"
|
|
fill-opacity="1"
|
|
/>
|
|
</g>
|
|
</svg>
|
|
<b style="margin-left: 6px">{{ item.title }}</b>
|
|
<div class="right">
|
|
<!-- <el-tag size="12" style="margin: 0 6px">{{ item.type === "0" ? "svg" : "组态" }}</el-tag>-->
|
|
<el-button type="danger" round size="mini" icon="delete" @click.stop="del(item.id)"></el-button>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<div class="detail-container" v-loading="loading" v-if="!previewVisible">
|
|
<div class="detail" v-show="getCurrentItem.type === '1' && getCurrentItem.scadaUrl">
|
|
<iframe :src="getCurrentItem.scadaUrl" frameborder="0" class="frame"></iframe>
|
|
</div>
|
|
|
|
<template v-if="getCurrentItem.type === '0' && !detailLoading">
|
|
<div class="detail" v-html="detail" :id="activeId" v-if="detail" :style="`background: ${getCurrentItem.backgroundColor} url(${getCurrentItem.imgUrl}) no-repeat center 100%/100%`"></div>
|
|
<el-empty description="暂无数据" v-else />
|
|
</template>
|
|
</div>
|
|
</drawer>
|
|
</div>
|
|
</list-page-slot>
|
|
|
|
<design-config-right-drawer ref="configRightModalRef" v-if="configRightModal" :visible="configRightModal" @close="configRightModal = false" @refreshDataList="query()" />
|
|
<design-data-right-drawer ref="dataRightModalRef" v-if="dataRightModal" :visible="dataRightModal" :id="activeId" @close="dataRightModal = false" @refreshDataList="query()" />
|
|
<data-source-add-or-update
|
|
v-if="dataSourceVisible"
|
|
:visible="dataSourceVisible"
|
|
:id="activeId"
|
|
:title="activeTitle"
|
|
@close="
|
|
dataSourceVisible = false;
|
|
query();
|
|
"
|
|
@refreshDataList="query()"
|
|
/>
|
|
<design-preview-dialog v-if="previewVisible" :visible="previewVisible" :data-list="dataList" @change-view="changeView" :full-path="$route.fullPath" />
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { computed, defineComponent, nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, reactive, toRefs, watch } from "vue";
|
|
import { useRoute } from "vue-router";
|
|
import DesignConfigRightDrawer from "./design-config-right-drawer.vue";
|
|
import DesignDataRightDrawer from "./design-data-right-drawer.vue";
|
|
import Drawer from "@/components/drawer/drawer.vue";
|
|
|
|
import baseService from "@/service/baseService";
|
|
import { ElMessage } from "element-plus";
|
|
import utilService from "@/service/utilService";
|
|
import { isDark } from "@/composables";
|
|
import useView from "@/hooks/useView";
|
|
import DataSourceAddOrUpdate from "@/views/dashboard/data-source-add-or-update.vue";
|
|
import DesignPreviewDialog from "./design-preview-dialog.vue";
|
|
import { getToken } from "@/utils/cache";
|
|
import WebSocketService from "@/utils/websocket";
|
|
import app from "@/constants/app";
|
|
import { IObject } from "@/types/interface";
|
|
import Sortable from "sortablejs";
|
|
|
|
export default defineComponent({
|
|
components: { DataSourceAddOrUpdate, Drawer, DesignConfigRightDrawer, DesignDataRightDrawer, DesignPreviewDialog },
|
|
setup() {
|
|
const route = useRoute();
|
|
|
|
const state = reactive({
|
|
configRightModalRef: null,
|
|
dataRightModalRef: null,
|
|
sortable: null as any,
|
|
getDataListURL: "dashboard/iotdashboard/list",
|
|
activatedIsNeed: false,
|
|
createdIsNeed: false,
|
|
deleteURL: "dashboard/iotdashboard",
|
|
deleteIsBatch: true,
|
|
isDark,
|
|
dataForm: {
|
|
dashboardGroupId: route.query?.id
|
|
},
|
|
socket: {},
|
|
dashboardRef: null,
|
|
listRef: null,
|
|
map: [] as IObject,
|
|
dataSourceList: [] as IObject,
|
|
detail: "",
|
|
activeId: "",
|
|
activeTitle: "",
|
|
configRightModal: false,
|
|
loading: false,
|
|
detailLoading: false,
|
|
dataRightModal: false,
|
|
drawerVisible: false,
|
|
previewVisible: false,
|
|
dataSourceVisible: false
|
|
});
|
|
|
|
const view = useView(state);
|
|
const changeView = () => {
|
|
switchFullScreen();
|
|
|
|
state.previewVisible = !state.previewVisible;
|
|
if (!state.previewVisible) {
|
|
setSvgLayout(state.activeId);
|
|
}
|
|
};
|
|
|
|
const switchFullScreen = () => {
|
|
if (document.fullscreenElement) {
|
|
document.exitFullscreen();
|
|
} else {
|
|
document.documentElement.requestFullscreen();
|
|
}
|
|
};
|
|
|
|
const initSortable = () => {
|
|
const listEl = document.querySelector(".dashboard-left .list") as HTMLElement;
|
|
|
|
state.sortable = new Sortable(listEl, {
|
|
sort: true,
|
|
easing: "cubic-bezier(1, 0, 0, 1)",
|
|
draggable: ".el-card",
|
|
animation: 500,
|
|
onMove: (evt, originalEvent) => {
|
|
return true;
|
|
},
|
|
onEnd: (evt) => {
|
|
const { oldIndex, newIndex } = evt;
|
|
if (oldIndex === newIndex) {
|
|
return;
|
|
}
|
|
|
|
const cards = listEl.querySelectorAll(".el-card") as any;
|
|
|
|
const data = [];
|
|
let sort = 0;
|
|
for (const item of cards) {
|
|
data.push({
|
|
id: item.getAttribute("target"),
|
|
sort
|
|
});
|
|
sort++;
|
|
}
|
|
sortRequest(data);
|
|
|
|
view.query();
|
|
}
|
|
});
|
|
};
|
|
|
|
const del = async (id: string) => {
|
|
await view.deleteHandle(id);
|
|
|
|
state.activeId = "";
|
|
};
|
|
|
|
const toggle = () => {
|
|
state.drawerVisible = !state.drawerVisible;
|
|
|
|
if (state.drawerVisible) {
|
|
nextTick(() => {
|
|
initSortable();
|
|
});
|
|
}
|
|
};
|
|
|
|
watch(
|
|
() => state.dataList,
|
|
(newVal) => {
|
|
if (utilService.isValidArray(newVal)) {
|
|
let item = null as any;
|
|
if (state.activeId) {
|
|
item = utilService.getTargetItemByKey(newVal, state.activeId);
|
|
} else {
|
|
[item] = newVal;
|
|
}
|
|
changeBoard(item);
|
|
} else {
|
|
state.detail = "";
|
|
}
|
|
}
|
|
);
|
|
|
|
const sortRequest = async (data: Array<IObject>) => {
|
|
const { msg, code } = await baseService.post("dashboard/iotdashboard/sort", data);
|
|
|
|
if (code !== 0) {
|
|
return ElMessage.error(msg);
|
|
}
|
|
|
|
ElMessage.success("排序成功!");
|
|
};
|
|
const getCurrentItem = computed(() => {
|
|
return utilService.getTargetItemByKey(state.dataList, state.activeId);
|
|
});
|
|
|
|
watch(
|
|
() => state.previewVisible,
|
|
(newVal: boolean) => {
|
|
newVal ? close() : changeBoard(getCurrentItem.value);
|
|
}
|
|
);
|
|
|
|
const getValByThingAttr = async (dashboardId: string) => {
|
|
const { msg, code, data } = await baseService.get("dashboard/iotdashboard/getDashboardElementLatestAttr", { dashboardId });
|
|
|
|
if (code !== 0) {
|
|
return ElMessage.error(msg);
|
|
}
|
|
|
|
const ret = await baseService.get("dashboard/iotdashboardelement/list", { dashboardId: dashboardId });
|
|
|
|
if (ret.code !== 0) {
|
|
return ElMessage.error(msg);
|
|
}
|
|
|
|
if (utilService.isValidArray(data)) {
|
|
for (const item of data) {
|
|
const target = (document.getElementById(state.activeId) as HTMLElement).querySelector("text[id='" + item.elementId + "']") as HTMLElement;
|
|
|
|
target.innerHTML = item.val || item.elementName;
|
|
}
|
|
}
|
|
};
|
|
|
|
const openDrawer = (id?: string) => {
|
|
state.configRightModal = true;
|
|
|
|
nextTick(() => {
|
|
state.configRightModalRef?.init(id);
|
|
});
|
|
};
|
|
|
|
const changeBoard = (item: IObject) => {
|
|
if (!utilService.isValidObject(item)) return;
|
|
const { id, title, type } = item;
|
|
state.activeId = id;
|
|
close();
|
|
if (type === "1") {
|
|
return;
|
|
}
|
|
state.activeTitle = title;
|
|
getBoardDetail(id);
|
|
|
|
// id && openDrawer(id);
|
|
};
|
|
|
|
const getDataSourceFromServer = async (dashboardId: string) => {
|
|
const { msg, code, data } = await baseService.get("dashboard/iotdashboardelement/getElementByDashboardId", { dashboardId });
|
|
|
|
if (code !== 0) {
|
|
return ElMessage.error(msg);
|
|
}
|
|
|
|
if (utilService.isValidArray(data)) {
|
|
state.dataSourceList = data;
|
|
|
|
// for (const item of data) {
|
|
// const target = document.getElementById(item.elementId) as HTMLElement;
|
|
// target && item.elementName && (target.innerHTML = item.elementName);
|
|
// }
|
|
} else {
|
|
state.dataSourceList = [];
|
|
}
|
|
};
|
|
const setSvgLayout = (id: string) => {
|
|
nextTick(() => {
|
|
const target = document.getElementById(id);
|
|
if (!target) return;
|
|
const svg = target.getElementsByTagName("svg");
|
|
|
|
if (utilService.isValidObject(svg)) {
|
|
const [target] = svg;
|
|
const width = state.dashboardRef?.clientWidth;
|
|
const height = state.dashboardRef?.clientHeight;
|
|
|
|
target.setAttribute("width", width);
|
|
target.setAttribute("height", height);
|
|
target.setAttribute("preserveAspectRatio", "");
|
|
}
|
|
});
|
|
};
|
|
|
|
const getBoardDetail = async (id: string) => {
|
|
state.detailLoading = true;
|
|
const { msg, code, data } = await baseService.get(`/dashboard/iotdashboard/svg/xml/${id}`);
|
|
|
|
state.detailLoading = false;
|
|
|
|
if (code !== 0) {
|
|
return ElMessage.error(msg);
|
|
}
|
|
if (typeof data === "string") {
|
|
state.detail = data;
|
|
|
|
await getDataSourceFromServer(id);
|
|
//await getValByThingAttr(id);
|
|
setSvgLayout(id);
|
|
ws(id);
|
|
setTimeout(addListener, 200);
|
|
} else {
|
|
state.detail = "";
|
|
}
|
|
};
|
|
|
|
const ws = (dashboardId: string) => {
|
|
close();
|
|
|
|
let socketUrl = "";
|
|
const token = getToken();
|
|
if (import.meta.env.PROD) {
|
|
socketUrl = "ws://" + window.location.host + "/thing/websocket?token=" + token + "&dashboardId=" + dashboardId;
|
|
} else {
|
|
socketUrl = app.websocket + "?token=" + token + "&dashboardId=" + dashboardId;
|
|
}
|
|
|
|
state.socket = new WebSocketService(socketUrl);
|
|
|
|
subscribe(dashboardId);
|
|
};
|
|
|
|
const findCalcBodyByElementId = (elementId: string) => {
|
|
return utilService.getTargetItemByKey(state.dataSourceList, elementId, "elementId");
|
|
};
|
|
|
|
const assembleFunc = (calcBody: string, value: string, elementId: string) => {
|
|
const target = document.getElementById(elementId);
|
|
if (!target) return value;
|
|
if (!calcBody) {
|
|
//导入的时候没有calcBody
|
|
if (target) {
|
|
target.innerHTML = value;
|
|
}
|
|
return value;
|
|
}
|
|
const funcStr = `function t(data, target){${calcBody};}`;
|
|
const func = new Function("return " + funcStr);
|
|
//console.log(funcStr, "funcStr");
|
|
//console.log(func, "func");
|
|
try {
|
|
return func()(value, target);
|
|
} catch (e) {
|
|
console.error(funcStr, "组装函数");
|
|
console.error(func, "生成组装函数");
|
|
console.error(calcBody, "计算体");
|
|
console.error(value, "原始值");
|
|
return value;
|
|
}
|
|
};
|
|
|
|
const subscribe = (dashboardId: string) => {
|
|
state.loading = true;
|
|
state.socket.onOpen(() => {
|
|
// state.socket.send(
|
|
// JSON.stringify({
|
|
// msgType: "subscribe",
|
|
// networkId
|
|
// })
|
|
// );
|
|
|
|
state.socket.onMessage((data) => {
|
|
if (utilService.isValidObject(data) && utilService.isValidObject(data.data)) {
|
|
const ret = JSON.parse(data.data || "{}");
|
|
if (utilService.isValidArray(ret.data)) {
|
|
for (const item of ret.data) {
|
|
//匹配一下
|
|
// if (item.networkId === dashboardId) {
|
|
try {
|
|
for (const el of state.dataSourceList) {
|
|
const { thingCode, attrCode, elementId } = el;
|
|
|
|
if (item.thingCode == thingCode && item.attrKey === attrCode) {
|
|
let targetValue = item.val;
|
|
|
|
const { calculateBody } = findCalcBodyByElementId(elementId);
|
|
|
|
assembleFunc(calculateBody, targetValue, elementId);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.warn(`设置${item.thingCode}-${item.attrKey}失败`);
|
|
}
|
|
// }
|
|
}
|
|
} else if (typeof ret.data === "string") {
|
|
ElMessage.warning(ret.data);
|
|
}
|
|
}
|
|
|
|
state.loading = false;
|
|
});
|
|
});
|
|
};
|
|
|
|
const close = () => {
|
|
if (utilService.isValidObject(state.socket)) {
|
|
state.socket.close();
|
|
|
|
state.socket = {};
|
|
|
|
state.map = [];
|
|
}
|
|
state.loading = false;
|
|
};
|
|
|
|
const addListener = () => {
|
|
nextTick(() => {
|
|
//const texts = document.getElementById(state.activeId)?.getElementsByTagName("text");
|
|
const svg = document.getElementById(state.activeId)?.querySelector("svg");
|
|
|
|
if (typeof svg === "object") {
|
|
const children = svg.children;
|
|
|
|
const queryAndClick = (children) => {
|
|
if (utilService.isValidObject(children)) {
|
|
for (const child of children) {
|
|
//const { id, innerHTML } = text;
|
|
//if (id && innerHTML && innerHTML.length >= 0) {
|
|
|
|
if (child.tagName === "g") {
|
|
queryAndClick(child.children);
|
|
} else {
|
|
const { id } = child;
|
|
if (id) {
|
|
child.onclick = () => {
|
|
state.dataRightModal = true;
|
|
nextTick(() => {
|
|
state.dataRightModalRef?.init(state.activeId, id, id);
|
|
});
|
|
};
|
|
}
|
|
|
|
// text.removeListener && text.removeListener("click");
|
|
// text.addEventListener("click", () => {
|
|
// state.dataRightModal = true;
|
|
// nextTick(() => {
|
|
// state.dataRightModalRef?.init(state.activeId, id, innerHTML);
|
|
// });
|
|
// });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
queryAndClick(children);
|
|
}
|
|
});
|
|
};
|
|
|
|
const isMultiple = computed(() => {
|
|
return route.query?.multiple === "1";
|
|
});
|
|
|
|
const methods = { getBoardDetail, changeBoard, openDrawer, isMultiple, del, getCurrentItem, changeView, toggle };
|
|
const resize = () => {
|
|
console.log("onResize");
|
|
setSvgLayout(state.activeId);
|
|
};
|
|
|
|
onActivated(() => {
|
|
view.query();
|
|
//changeBoard(getCurrentItem.value);
|
|
window.addEventListener("resize", resize);
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
close();
|
|
});
|
|
onDeactivated(() => {
|
|
close();
|
|
window.removeEventListener("resize", resize);
|
|
});
|
|
|
|
return {
|
|
...toRefs(view),
|
|
...toRefs(state),
|
|
...toRefs(methods)
|
|
};
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.dashboard-design {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
|
|
.dashboard-design-right {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
::v-deep .drawer {
|
|
.left {
|
|
z-index: 20;
|
|
}
|
|
.layout-toggle-icon {
|
|
z-index: 30;
|
|
}
|
|
}
|
|
|
|
::v-deep .container {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
.detail-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
.detail {
|
|
flex: 1;
|
|
overflow: auto;
|
|
iframe {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
svg {
|
|
text {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
|
|
.el-empty {
|
|
flex: 1;
|
|
}
|
|
}
|
|
}
|
|
::v-deep .el-loading-mask {
|
|
z-index: 15;
|
|
}
|
|
}
|
|
}
|
|
</style>
|