|
|
@@ -0,0 +1,401 @@
|
|
|
+<template>
|
|
|
+ <m-card title="融合成效数据" :width="398" :height="450">
|
|
|
+ <div class="integration-effect">
|
|
|
+ <div class="effect-tabs">
|
|
|
+ <div
|
|
|
+ class="tab-item"
|
|
|
+ v-for="(tab, index) in effectTabs"
|
|
|
+ :key="index"
|
|
|
+ :class="{ active: activeTab === index }"
|
|
|
+ @click="activeTab = index"
|
|
|
+ >
|
|
|
+ {{ tab.name }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="effect-chart">
|
|
|
+ <div v-if="activeTab === 0" class="chart-line">
|
|
|
+ <div class="chart-title">应急响应速度提升 30%</div>
|
|
|
+ <div class="line-container">
|
|
|
+ <div class="line-item">
|
|
|
+ <div class="line-label">融合前</div>
|
|
|
+ <div class="line-bar-wrapper">
|
|
|
+ <div class="line-bar before" style="width: 60%"></div>
|
|
|
+ </div>
|
|
|
+ <div class="line-value">40分钟</div>
|
|
|
+ </div>
|
|
|
+ <div class="line-item">
|
|
|
+ <div class="line-label">融合后</div>
|
|
|
+ <div class="line-bar-wrapper">
|
|
|
+ <div class="line-bar after" style="width: 90%"></div>
|
|
|
+ </div>
|
|
|
+ <div class="line-value">26分钟</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="activeTab === 1" class="chart-bar">
|
|
|
+ <div class="chart-title">成本降低成效</div>
|
|
|
+ <div class="bar-container">
|
|
|
+ <div class="bar-item">
|
|
|
+ <div class="bar-value">-50%</div>
|
|
|
+ <div class="bar-fill" style="height: 70%"></div>
|
|
|
+ <div class="bar-label">数据共享耗时</div>
|
|
|
+ </div>
|
|
|
+ <div class="bar-item">
|
|
|
+ <div class="bar-value">-20%</div>
|
|
|
+ <div class="bar-fill" style="height: 45%"></div>
|
|
|
+ <div class="bar-label">运维成本</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="activeTab === 2" class="chart-ring">
|
|
|
+ <div class="chart-title">决策精准度提升</div>
|
|
|
+ <div class="ring-container">
|
|
|
+ <div class="ring-item">
|
|
|
+ <div class="ring-wrapper">
|
|
|
+ <svg width="80" height="80" viewBox="0 0 80 80">
|
|
|
+ <circle cx="40" cy="40" r="35" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="6" />
|
|
|
+ <circle cx="40" cy="40" r="35" fill="none" stroke="url(#gradient1)" stroke-width="6" stroke-linecap="round"
|
|
|
+ stroke-dasharray="220" stroke-dashoffset="66" transform="rotate(-90 40 40)" />
|
|
|
+ <defs>
|
|
|
+ <linearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
|
+ <stop offset="0%" stop-color="#30DCFF" />
|
|
|
+ <stop offset="100%" stop-color="#43e97b" />
|
|
|
+ </linearGradient>
|
|
|
+ </defs>
|
|
|
+ </svg>
|
|
|
+ <div class="ring-text">
|
|
|
+ <span class="percent">+40%</span>
|
|
|
+ <span class="label">调度命中率</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="ring-item">
|
|
|
+ <div class="ring-wrapper">
|
|
|
+ <svg width="80" height="80" viewBox="0 0 80 80">
|
|
|
+ <circle cx="40" cy="40" r="35" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="6" />
|
|
|
+ <circle cx="40" cy="40" r="35" fill="none" stroke="url(#gradient2)" stroke-width="6" stroke-linecap="round"
|
|
|
+ stroke-dasharray="220" stroke-dashoffset="110" transform="rotate(-90 40 40)" />
|
|
|
+ <defs>
|
|
|
+ <linearGradient id="gradient2" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
|
+ <stop offset="0%" stop-color="#ff6b6b" />
|
|
|
+ <stop offset="100%" stop-color="#ffd93d" />
|
|
|
+ </linearGradient>
|
|
|
+ </defs>
|
|
|
+ </svg>
|
|
|
+ <div class="ring-text">
|
|
|
+ <span class="percent down">-25%</span>
|
|
|
+ <span class="label">内涝误报率</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="effect-compare">
|
|
|
+ <div class="compare-title">融合前后对比</div>
|
|
|
+ <div class="compare-container">
|
|
|
+ <div class="compare-card before">
|
|
|
+ <div class="card-label">融合前</div>
|
|
|
+ <div class="card-items">
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">应急响应</span>
|
|
|
+ <span class="item-value">40分钟</span>
|
|
|
+ </div>
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">数据共享</span>
|
|
|
+ <span class="item-value">2小时</span>
|
|
|
+ </div>
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">调度精准</span>
|
|
|
+ <span class="item-value">60%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="compare-arrow">→</div>
|
|
|
+ <div class="compare-card after">
|
|
|
+ <div class="card-label">融合后</div>
|
|
|
+ <div class="card-items">
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">应急响应</span>
|
|
|
+ <span class="item-value highlight">26分钟</span>
|
|
|
+ </div>
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">数据共享</span>
|
|
|
+ <span class="item-value highlight">1小时</span>
|
|
|
+ </div>
|
|
|
+ <div class="card-item">
|
|
|
+ <span class="item-label">调度精准</span>
|
|
|
+ <span class="item-value highlight">100%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </m-card>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref } from "vue"
|
|
|
+import mCard from "@/components/mCard/index.vue"
|
|
|
+
|
|
|
+const activeTab = ref(0)
|
|
|
+
|
|
|
+const effectTabs = ref([
|
|
|
+ { name: "效率提升" },
|
|
|
+ { name: "成本降低" },
|
|
|
+ { name: "决策精准" },
|
|
|
+])
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.integration-effect {
|
|
|
+ padding: 12px;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.effect-tabs {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ background: rgba(0, 180, 255, 0.05);
|
|
|
+ padding: 6px;
|
|
|
+ border-radius: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.tab-item {
|
|
|
+ flex: 1;
|
|
|
+ padding: 8px 10px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 10px;
|
|
|
+ color: rgba(255, 255, 255, 0.6);
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ &:hover {
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
+ background: rgba(48, 220, 255, 0.1);
|
|
|
+ }
|
|
|
+ &.active {
|
|
|
+ background: linear-gradient(135deg, #30DCFF, #00BFFF);
|
|
|
+ color: #fff;
|
|
|
+ box-shadow: 0 0 15px rgba(48, 220, 255, 0.4);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.effect-chart {
|
|
|
+ flex: 1;
|
|
|
+ background: rgba(0, 180, 255, 0.05);
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 12px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-title {
|
|
|
+ font-size: 11px;
|
|
|
+ color: #30DCFF;
|
|
|
+ font-weight: 600;
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-line .line-container {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.line-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.line-label {
|
|
|
+ width: 50px;
|
|
|
+ font-size: 10px;
|
|
|
+ color: rgba(255, 255, 255, 0.7);
|
|
|
+}
|
|
|
+
|
|
|
+.line-bar-wrapper {
|
|
|
+ flex: 1;
|
|
|
+ height: 18px;
|
|
|
+ background: rgba(255, 255, 255, 0.1);
|
|
|
+ border-radius: 9px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.line-bar {
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 10px;
|
|
|
+ transition: width 1.5s ease;
|
|
|
+ &.before {
|
|
|
+ background: linear-gradient(90deg, rgba(255, 107, 107, 0.8), rgba(255, 217, 61, 0.8));
|
|
|
+ }
|
|
|
+ &.after {
|
|
|
+ background: linear-gradient(90deg, #30DCFF, #43e97b);
|
|
|
+ box-shadow: 0 0 10px rgba(48, 220, 255, 0.4);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.line-value {
|
|
|
+ width: 50px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #30DCFF;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-bar .bar-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ align-items: flex-end;
|
|
|
+ flex: 1;
|
|
|
+ padding: 0 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.bar-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.bar-value {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #ff6b6b;
|
|
|
+}
|
|
|
+
|
|
|
+.bar-fill {
|
|
|
+ width: 40px;
|
|
|
+ background: linear-gradient(to top, #30DCFF, #43e97b);
|
|
|
+ border-radius: 5px 5px 0 0;
|
|
|
+ transition: height 1.5s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.bar-label {
|
|
|
+ font-size: 10px;
|
|
|
+ color: rgba(255, 255, 255, 0.6);
|
|
|
+}
|
|
|
+
|
|
|
+.chart-ring .ring-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.ring-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.ring-wrapper {
|
|
|
+ position: relative;
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+}
|
|
|
+
|
|
|
+.ring-text {
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ text-align: center;
|
|
|
+ .percent {
|
|
|
+ display: block;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #30DCFF;
|
|
|
+ &.down {
|
|
|
+ color: #ff6b6b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .label {
|
|
|
+ display: block;
|
|
|
+ font-size: 9px;
|
|
|
+ color: rgba(255, 255, 255, 0.6);
|
|
|
+ margin-top: 2px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.effect-compare {
|
|
|
+ background: rgba(0, 180, 255, 0.05);
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.compare-title {
|
|
|
+ font-size: 11px;
|
|
|
+ color: #30DCFF;
|
|
|
+ font-weight: 600;
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.compare-container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.compare-card {
|
|
|
+ flex: 1;
|
|
|
+ background: rgba(255, 255, 255, 0.05);
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 8px;
|
|
|
+ &.before {
|
|
|
+ border: 1px solid rgba(255, 107, 107, 0.3);
|
|
|
+ .card-label {
|
|
|
+ color: #ff6b6b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &.after {
|
|
|
+ border: 1px solid rgba(48, 220, 255, 0.3);
|
|
|
+ .card-label {
|
|
|
+ color: #30DCFF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.card-label {
|
|
|
+ font-size: 10px;
|
|
|
+ font-weight: 600;
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-items {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-size: 10px;
|
|
|
+ .item-label {
|
|
|
+ color: rgba(255, 255, 255, 0.5);
|
|
|
+ }
|
|
|
+ .item-value {
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
+ &.highlight {
|
|
|
+ color: #30DCFF;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.compare-arrow {
|
|
|
+ font-size: 18px;
|
|
|
+ color: #30DCFF;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+</style>
|