update at 2026-01-15 19:27:23
This commit is contained in:
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -7,8 +7,8 @@
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<title>火情监控全链路业务监控视图</title>
|
||||
<script type="module" crossorigin src="/assets/index-CXxc8szZ.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-TX7wYp3m.css">
|
||||
<script type="module" crossorigin src="/assets/index-COE8oICG.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CRlS2jVE.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
386
src/App.vue
386
src/App.vue
@@ -3,29 +3,17 @@
|
||||
class="monitor-container"
|
||||
:class="{ 'is-top2': currentStyle === 'top2', 'is-top3': currentStyle === 'top3' }"
|
||||
>
|
||||
<!-- 样式切换按钮 -->
|
||||
<!-- 样式切换下拉框 -->
|
||||
<div
|
||||
class="style-switcher"
|
||||
:class="{ 'is-top2': currentStyle === 'top2', 'is-top3': currentStyle === 'top3' }"
|
||||
>
|
||||
<button
|
||||
:class="['style-btn', { active: currentStyle === 'circle' }]"
|
||||
@click="switchStyle('circle')"
|
||||
>
|
||||
原型-1
|
||||
</button>
|
||||
<button
|
||||
:class="['style-btn', { active: currentStyle === 'top2' }]"
|
||||
@click="switchStyle('top2')"
|
||||
>
|
||||
原型-2
|
||||
</button>
|
||||
<button
|
||||
:class="['style-btn', { active: currentStyle === 'top3' }]"
|
||||
@click="switchStyle('top3')"
|
||||
>
|
||||
原型-3
|
||||
</button>
|
||||
<label class="style-label" for="style-select">原型迭代</label>
|
||||
<select id="style-select" v-model="currentStyle" class="style-select">
|
||||
<option value="top3">原型-3</option>
|
||||
<option value="top2">原型-2</option>
|
||||
<option value="circle">原型-1</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<template v-if="currentStyle === 'top2' || currentStyle === 'top3'">
|
||||
@@ -37,8 +25,8 @@
|
||||
>
|
||||
<div class="top2-scale">
|
||||
<div class="top2-layout">
|
||||
<div class="top2-header" data-node-id="153:2111">
|
||||
<div class="top2-title" data-node-id="153:2112">火情综合监控系统</div>
|
||||
<div class="top2-header" data-node-id="153:2111" :style="headerStyle">
|
||||
<div class="top2-title" data-node-id="153:2112">火情综合监控看板</div>
|
||||
</div>
|
||||
|
||||
<div class="top2-content">
|
||||
@@ -114,21 +102,87 @@
|
||||
</div>
|
||||
<div class="top2-bottom-row">
|
||||
<div class="panel-outline panel-center-bottom-left" data-node-id="153:2091">
|
||||
<div class="panel-label label-metric-22" data-node-id="153:2100">监控指标区22</div>
|
||||
<div class="panel-label label-metric-22" data-node-id="153:2100">
|
||||
{{ currentStyle === 'top3' ? '切图指标' : '监控指标区22' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-outline panel-center-bottom-right" data-node-id="153:2092">
|
||||
<div class="panel-label label-metric-23" data-node-id="153:2102">监控指标区23</div>
|
||||
<div class="panel-label label-metric-23" data-node-id="153:2102">
|
||||
{{ currentStyle === 'top3' ? '魔方指标' : '监控指标区23' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="top2-right-col">
|
||||
<div class="panel-outline panel-right-top" data-node-id="153:2088">
|
||||
<div class="panel-label label-alarm" data-node-id="153:2095">告警看板</div>
|
||||
</div>
|
||||
<div class="panel-outline panel-right-bottom" data-node-id="153:2090">
|
||||
<div class="panel-label label-fault" data-node-id="153:2096">故障看板</div>
|
||||
</div>
|
||||
<template v-if="currentStyle === 'top3'">
|
||||
<div class="panel-outline top3-board top3-alarm" data-node-id="328:1647">
|
||||
<div class="top3-board-title">告警看板</div>
|
||||
<div class="top3-board-table">
|
||||
<div class="top3-board-col top3-rank-col">
|
||||
<div class="top3-table-head"></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-1">1</span></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-2">3</span></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-3">3</span></div>
|
||||
</div>
|
||||
<div class="top3-board-col top3-info-col">
|
||||
<div class="top3-table-head top3-table-head-left">告警信息</div>
|
||||
<div class="top3-table-cell top3-info-cell">告警1</div>
|
||||
<div class="top3-table-cell top3-info-cell">告警2</div>
|
||||
<div class="top3-table-cell top3-info-cell">告警3</div>
|
||||
</div>
|
||||
<div class="top3-board-col top3-metric-col">
|
||||
<div class="top3-table-head top3-table-head-right">指标</div>
|
||||
<div class="top3-table-cell top3-metric-cell">网络</div>
|
||||
<div class="top3-table-cell top3-metric-cell">视联网</div>
|
||||
<div class="top3-table-cell top3-metric-cell">AI分析</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top3-board-bottom">
|
||||
<div class="top3-bottom-title">告警内容</div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-outline top3-board top3-fault" data-node-id="328:1692">
|
||||
<div class="top3-board-title">故障看板</div>
|
||||
<div class="top3-board-table">
|
||||
<div class="top3-board-col top3-rank-col">
|
||||
<div class="top3-table-head"></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-1">1</span></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-2">3</span></div>
|
||||
<div class="top3-table-cell top3-rank-cell"><span class="rank-badge rank-3">3</span></div>
|
||||
</div>
|
||||
<div class="top3-board-col top3-info-col">
|
||||
<div class="top3-table-head top3-table-head-left">故障记录</div>
|
||||
<div class="top3-table-cell top3-info-cell">故障1</div>
|
||||
<div class="top3-table-cell top3-info-cell">故障2</div>
|
||||
<div class="top3-table-cell top3-info-cell">故障3</div>
|
||||
</div>
|
||||
<div class="top3-board-col top3-metric-col">
|
||||
<div class="top3-table-head top3-table-head-right">指标</div>
|
||||
<div class="top3-table-cell top3-metric-cell">网络</div>
|
||||
<div class="top3-table-cell top3-metric-cell">视联网拉流</div>
|
||||
<div class="top3-table-cell top3-metric-cell">AI分析</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top3-board-bottom">
|
||||
<div class="top3-bottom-title">故障根因</div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
<div class="top3-bottom-line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="panel-outline panel-right-top" data-node-id="153:2088">
|
||||
<div class="panel-label label-alarm" data-node-id="153:2095">告警看板</div>
|
||||
</div>
|
||||
<div class="panel-outline panel-right-bottom" data-node-id="153:2090">
|
||||
<div class="panel-label label-fault" data-node-id="153:2096">故障看板</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -151,18 +205,19 @@ import playIcon from './assets/play.svg'
|
||||
import aiIcon from './assets/ai.svg'
|
||||
import picIcon from './assets/pic.svg'
|
||||
import mapKuang from './assets/map-kuang.svg'
|
||||
import headerBack from './assets/header-back.svg'
|
||||
|
||||
type StyleType = 'circle' | 'top2' | 'top3'
|
||||
|
||||
const svgWrapper = ref<HTMLElement | null>(null)
|
||||
const svgContent = ref('')
|
||||
const currentStyle = ref<StyleType>('circle')
|
||||
const currentStyle = ref<StyleType>('top3')
|
||||
const top2Stage = ref<HTMLElement | null>(null)
|
||||
const top2Scale = ref(1)
|
||||
|
||||
const TOP_LAYOUTS = {
|
||||
top2: { width: 1296, height: 692 },
|
||||
top3: { width: 1438, height: 832 },
|
||||
top3: { width: 1438, height: 929 },
|
||||
}
|
||||
let top2ResizeObserver: ResizeObserver | null = null
|
||||
|
||||
@@ -225,13 +280,14 @@ const loadSvg = async (style: StyleType) => {
|
||||
}
|
||||
}
|
||||
|
||||
const switchStyle = (style: StyleType) => {
|
||||
currentStyle.value = style
|
||||
loadSvg(style)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadSvg('circle')
|
||||
nextTick(() => {
|
||||
loadSvg(currentStyle.value)
|
||||
if (currentStyle.value === 'top2' || currentStyle.value === 'top3') {
|
||||
attachTop2Observer()
|
||||
updateTop2Scale()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -239,8 +295,9 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
|
||||
watch(currentStyle, async (style) => {
|
||||
await nextTick()
|
||||
loadSvg(style)
|
||||
if (style === 'top2' || style === 'top3') {
|
||||
await nextTick()
|
||||
attachTop2Observer()
|
||||
updateTop2Scale()
|
||||
} else {
|
||||
@@ -252,6 +309,10 @@ const topLayoutClass = computed(() => (
|
||||
currentStyle.value === 'top3' ? 'layout-top3' : 'layout-top2'
|
||||
))
|
||||
|
||||
const headerStyle = computed(() => (
|
||||
currentStyle.value === 'top3' ? { '--header-back': `url(${headerBack})` } : {}
|
||||
))
|
||||
|
||||
const addFlowingAnimation = () => {
|
||||
if (!svgWrapper.value) return
|
||||
|
||||
@@ -532,7 +593,8 @@ const addTop2Animation = () => {
|
||||
|
||||
.style-switcher {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@@ -545,41 +607,27 @@ const addTop2Animation = () => {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.style-btn {
|
||||
padding: 10px 24px;
|
||||
font-size: 16px;
|
||||
.style-label {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 12px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.style-select {
|
||||
padding: 8px 14px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.style-btn:hover {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-color: rgba(255, 255, 255, 0.5);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.style-btn.active {
|
||||
color: white;
|
||||
background: linear-gradient(135deg, rgba(0, 245, 255, 0.25), rgba(77, 159, 255, 0.25));
|
||||
border-color: #00F5FF;
|
||||
box-shadow: 0 0 20px rgba(0, 245, 255, 0.4),
|
||||
0 0 40px rgba(0, 245, 255, 0.2),
|
||||
inset 0 0 20px rgba(0, 245, 255, 0.1);
|
||||
}
|
||||
|
||||
.style-btn.active:hover {
|
||||
background: linear-gradient(135deg, rgba(0, 245, 255, 0.35), rgba(77, 159, 255, 0.35));
|
||||
box-shadow: 0 0 25px rgba(0, 245, 255, 0.5),
|
||||
0 0 50px rgba(0, 245, 255, 0.3),
|
||||
inset 0 0 25px rgba(0, 245, 255, 0.15);
|
||||
.style-select option {
|
||||
color: #0e1a3f;
|
||||
}
|
||||
|
||||
.title {
|
||||
@@ -668,7 +716,7 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-scale {
|
||||
width: calc(1438px * var(--top2-scale));
|
||||
height: calc(832px * var(--top2-scale));
|
||||
height: calc(929px * var(--top2-scale));
|
||||
}
|
||||
|
||||
.layout-top2 .top2-layout {
|
||||
@@ -678,7 +726,7 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-layout {
|
||||
width: 1438px;
|
||||
height: 832px;
|
||||
height: 929px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
@@ -702,12 +750,16 @@ const addTop2Animation = () => {
|
||||
}
|
||||
|
||||
.layout-top3 .top2-header {
|
||||
height: 50px;
|
||||
border-radius: 16px;
|
||||
background: rgba(229, 229, 229, 0);
|
||||
height: 72px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-image: var(--header-back);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 1120px 72px;
|
||||
}
|
||||
|
||||
.top2-title {
|
||||
@@ -740,7 +792,8 @@ const addTop2Animation = () => {
|
||||
}
|
||||
|
||||
.layout-top3 .top2-content {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 809px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
@@ -755,7 +808,7 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-left-col {
|
||||
width: 315px;
|
||||
height: 734px;
|
||||
height: 809px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
@@ -772,10 +825,10 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-center-col {
|
||||
width: 744px;
|
||||
height: 734px;
|
||||
height: 809px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
gap: 8px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -789,12 +842,170 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-right-col {
|
||||
width: 315px;
|
||||
height: 734px;
|
||||
height: 809px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.top3-board {
|
||||
width: 315px;
|
||||
height: 396.5px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.top3-board-title {
|
||||
font-family: 'Inter', 'Noto Sans JP', sans-serif;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #f02525;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.top3-board-table {
|
||||
width: 100%;
|
||||
height: 156px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.top3-board-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.top3-rank-col {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.top3-info-col {
|
||||
width: 146px;
|
||||
}
|
||||
|
||||
.top3-metric-col {
|
||||
width: 133px;
|
||||
}
|
||||
|
||||
.top3-table-head {
|
||||
height: 40px;
|
||||
background: #043272;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
font-size: 16px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.top3-table-head-left {
|
||||
justify-content: flex-start;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.top3-table-head-right {
|
||||
justify-content: flex-start;
|
||||
padding: 0 0 0 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.top3-table-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.top3-rank-cell {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.top3-info-cell {
|
||||
padding: 0 10px;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
font-size: 18px;
|
||||
color: #ffffff;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.top3-metric-cell {
|
||||
justify-content: flex-start;
|
||||
padding: 0 0 0 16px;
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
font-size: 20px;
|
||||
color: #4de4ff;
|
||||
}
|
||||
|
||||
.rank-badge {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 2px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'Mark Pro', 'Inter', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
letter-spacing: 0.75px;
|
||||
}
|
||||
|
||||
.rank-1 {
|
||||
background: #c85b3f;
|
||||
}
|
||||
|
||||
.rank-2 {
|
||||
background: #b99a3a;
|
||||
}
|
||||
|
||||
.rank-3 {
|
||||
background: #1fb2a4;
|
||||
}
|
||||
|
||||
.top3-board-bottom {
|
||||
width: 100%;
|
||||
height: 180.5px;
|
||||
background: #ffffff;
|
||||
border-bottom-left-radius: 16px;
|
||||
border-bottom-right-radius: 16px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.top3-bottom-title {
|
||||
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
position: absolute;
|
||||
left: 13.03px;
|
||||
top: 15.427px;
|
||||
}
|
||||
|
||||
.top3-bottom-line {
|
||||
width: 246.568px;
|
||||
height: 1.556px;
|
||||
background: rgba(240, 226, 226, 0.9);
|
||||
position: absolute;
|
||||
left: 34.759px;
|
||||
}
|
||||
|
||||
.top3-board-bottom .top3-bottom-line:nth-of-type(2) {
|
||||
top: 72.508px;
|
||||
left: 35.845px;
|
||||
}
|
||||
|
||||
.top3-board-bottom .top3-bottom-line:nth-of-type(3) {
|
||||
top: 109.548px;
|
||||
}
|
||||
|
||||
.top3-board-bottom .top3-bottom-line:nth-of-type(4) {
|
||||
top: 146.573px;
|
||||
}
|
||||
|
||||
.panel-outline {
|
||||
border: 0.297px solid #f0e2e2;
|
||||
border-radius: 10.684px;
|
||||
@@ -810,6 +1021,10 @@ const addTop2Animation = () => {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.top3-board.panel-outline {
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.layout-top2 .panel-left-top {
|
||||
left: 0;
|
||||
top: 0;
|
||||
@@ -819,12 +1034,12 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .panel-left-top {
|
||||
width: 315px;
|
||||
height: 234px;
|
||||
height: 259px;
|
||||
}
|
||||
|
||||
.layout-top3 .panel-left-middle {
|
||||
width: 315px;
|
||||
height: 234px;
|
||||
height: 259px;
|
||||
}
|
||||
|
||||
.layout-top2 .panel-left-bottom {
|
||||
@@ -836,7 +1051,7 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .panel-left-bottom {
|
||||
width: 315px;
|
||||
height: 234px;
|
||||
height: 259px;
|
||||
}
|
||||
|
||||
.layout-top2 .panel-right-top {
|
||||
@@ -880,13 +1095,13 @@ const addTop2Animation = () => {
|
||||
.layout-top3 .panel-center-bottom-left {
|
||||
width: auto;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
height: 242.813px;
|
||||
}
|
||||
|
||||
.layout-top3 .panel-center-bottom-right {
|
||||
width: auto;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
height: 242.813px;
|
||||
}
|
||||
|
||||
.layout-top2 .top2-center {
|
||||
@@ -914,8 +1129,7 @@ const addTop2Animation = () => {
|
||||
|
||||
.layout-top3 .top2-bottom-row {
|
||||
width: 744px;
|
||||
height: auto;
|
||||
flex: 1;
|
||||
height: 242.818px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
|
||||
Reference in New Issue
Block a user