|
|
@@ -0,0 +1,204 @@
|
|
|
+<template>
|
|
|
+ <div class="fluid-dashboard">
|
|
|
+ <div class="frame-top">
|
|
|
+ <div class="title">{{ title }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="frame-left"></div>
|
|
|
+ <div class="frame-right"></div>
|
|
|
+ <div class="frame-bottom"></div>
|
|
|
+
|
|
|
+ <slot name="map"></slot>
|
|
|
+
|
|
|
+ <div class="ui-layer">
|
|
|
+
|
|
|
+ <header class="top-header">
|
|
|
+ <div class="header-left">
|
|
|
+ <slot name="header-left"></slot>
|
|
|
+ </div>
|
|
|
+ <div class="header-right">
|
|
|
+ <slot name="header-right"></slot>
|
|
|
+ </div>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <main class="main-layout" :class="layoutClass">
|
|
|
+
|
|
|
+ <aside class="left-sidebar">
|
|
|
+ <slot name="left"></slot>
|
|
|
+ </aside>
|
|
|
+
|
|
|
+ <section class="center-area">
|
|
|
+ <slot name="center"></slot>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <aside class="right-sidebar">
|
|
|
+ <slot name="right"></slot>
|
|
|
+ </aside>
|
|
|
+
|
|
|
+ </main>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <slot name="dialogs"></slot>
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: 'DashboardLayout',
|
|
|
+ props: {
|
|
|
+ // 接收外部传入的 class,用于动态切换 CSS 网格布局
|
|
|
+ // 例如传入 "special-situation-monitoring"
|
|
|
+ layoutClass: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ title: '交通型号控制平台',
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+/* ================= 根容器 ================= */
|
|
|
+.fluid-dashboard {
|
|
|
+ width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #050a17;
|
|
|
+ /* 兜底深色背景 */
|
|
|
+}
|
|
|
+
|
|
|
+/* ================= 大屏装饰边框 ================= */
|
|
|
+.frame-top,
|
|
|
+.frame-left,
|
|
|
+.frame-right,
|
|
|
+.frame-bottom {
|
|
|
+ position: absolute;
|
|
|
+ pointer-events: none;
|
|
|
+ /* 【核心】鼠标事件穿透,不挡底层交互 */
|
|
|
+ z-index: 50;
|
|
|
+ /* 层级高于 UI,低于弹窗 */
|
|
|
+}
|
|
|
+
|
|
|
+.frame-top {
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100px;
|
|
|
+ background: url('@/assets/images/layout-top.png') no-repeat center top;
|
|
|
+ background-size: 100% 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.frame-top .title {
|
|
|
+ font-family: var(--title-font-family);
|
|
|
+ font-size: 48px;
|
|
|
+ color: #707070;
|
|
|
+ line-height: 63px;
|
|
|
+ text-align: center;
|
|
|
+ font-style: normal;
|
|
|
+ text-transform: none;
|
|
|
+ background: linear-gradient(90deg, #9ED3FD 0%, #FFFFFF 100%);
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+}
|
|
|
+
|
|
|
+.frame-left {
|
|
|
+ top: 10px;
|
|
|
+ left: 0;
|
|
|
+ width: 16px;
|
|
|
+ height: calc(100% - 10px - 40px);
|
|
|
+ background: url('@/assets/images/layout-left.png') no-repeat left center;
|
|
|
+ background-size: 100% 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.frame-right {
|
|
|
+ top: 10px;
|
|
|
+ right: 0;
|
|
|
+ width: 16px;
|
|
|
+ height: calc(100% - 10px - 40px);
|
|
|
+ background: url('@/assets/images/layout-right.png') no-repeat right center;
|
|
|
+ background-size: 100% 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.frame-bottom {
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 17px;
|
|
|
+ /* background: url('@/assets/images/layout-bottom.png') no-repeat center bottom; */
|
|
|
+ background-size: 100% 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* ================= UI 层与网格布局 ================= */
|
|
|
+.ui-layer {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ z-index: 2;
|
|
|
+ pointer-events: none;
|
|
|
+ /* 让鼠标穿透点到下层的地图 */
|
|
|
+ display: grid;
|
|
|
+ grid-template-rows: 80px 1fr;
|
|
|
+ /* 头部 80px,其余给主体 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 恢复具体功能区域的鼠标交互 */
|
|
|
+.top-header,
|
|
|
+.left-sidebar,
|
|
|
+.center-area,
|
|
|
+.right-sidebar {
|
|
|
+ pointer-events: auto;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- 头部 --- */
|
|
|
+.top-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-end;
|
|
|
+ padding: 0 50px;
|
|
|
+ /* 左右内边距,避开边框图片 */
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.header-right {
|
|
|
+ position: absolute;
|
|
|
+ right: 50px;
|
|
|
+ bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- 主体网格 --- */
|
|
|
+.main-layout {
|
|
|
+ display: grid;
|
|
|
+ /* 默认网格:左320,中间自适应,右480 */
|
|
|
+ grid-template-columns: 320px 1fr 480px;
|
|
|
+ gap: 20px;
|
|
|
+ /* 【关键】给四周留出 padding,防止里面的图表被外围的装饰边框挡住! */
|
|
|
+ padding: 20px 50px 60px 50px;
|
|
|
+ height: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+/* 特殊模式下的网格变体 (通过 layoutClass 触发) */
|
|
|
+.main-layout.special-situation-monitoring {
|
|
|
+ grid-template-columns: 500px 1fr 480px;
|
|
|
+}
|
|
|
+
|
|
|
+/* --- 区域容器设定 --- */
|
|
|
+.left-sidebar,
|
|
|
+.right-sidebar {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.center-area {
|
|
|
+ position: relative;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+</style>
|