修改地图

This commit is contained in:
lixiaobang 2026-03-20 14:41:22 +08:00
commit a1e7001fb1
2 changed files with 131 additions and 86 deletions

View File

@ -1,48 +1,16 @@
<script setup>
import { computed, ref } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { RadarChart } from 'echarts/charts'
import { TooltipComponent, RadarComponent } from 'echarts/components'
import {computed, onMounted, ref} from 'vue'
import {use} from 'echarts/core'
import {CanvasRenderer} from 'echarts/renderers'
import {RadarChart} from 'echarts/charts'
import {TooltipComponent, RadarComponent} from 'echarts/components'
import VChart from 'vue-echarts'
import api from "@/api/index.js";
const planRows = ref([
{
id: 'S-2026-001',
enabledAt: '2026-02-13 14:05',
scene: '危化品泄漏(中段)+拥堵≥5km',
config: '信号绿波+全路段诱导+应急车道开启',
status: '执行中',
effect: '30s',
},
{
id: 'S-2026-002',
enabledAt: '2026-02-13 14:05',
scene: '危化品泄漏(中段)+拥堵≥5km',
config: '信号绿波+全路段诱导+应急车道开启',
status: '已完成',
effect: '305',
},
{
id: 'S-2026-003',
enabledAt: '2026-02-13 14:05',
scene: '危化品泄漏(中段)+拥堵≥5km',
config: '信号绿波+全路段诱导+应急车道开启',
status: '已暂停',
effect: '305',
},
{
id: 'S-2026-004',
enabledAt: '2026-02-13 14:05',
scene: '危化品泄漏(中段)+拥堵≥5km',
config: '信号绿波+全路段诱导+应急车道开启',
status: '待启用',
effect: '305',
},
])
const planRows = ref([])
const activePlanId = ref('S-2026-001')
const activePlan = computed(() => planRows.value.find(p => p.id === activePlanId.value) ?? planRows.value[0])
const activePlanId = ref('5-2026-001')
const activePlan = computed(() => planRows.value.find(p => p.scheme_id === activePlanId.value) ?? planRows.value[0])
use([CanvasRenderer, RadarChart, RadarComponent, TooltipComponent])
@ -57,23 +25,20 @@ function statusTagType(status) {
}
const efficiencyRadarIndicators = [
{ name: '整体恢复', max: 100 },
{ name: '交通恢复', max: 100 },
{ name: '恢复效率', max: 100 },
{ name: '救援效率', max: 100 },
{ name: '平均延误', max: 100 },
{name: '整体恢复', max: 100},
{name: '交通恢复', max: 100},
{name: '恢复效率', max: 100},
{name: '救援效率', max: 100},
{name: '平均延误', max: 100},
]
//
const efficiencyRadarValue = ref([78, 70, 62, 66, 72])
const efficiencyRadarValue = ref([])
const efficiencyRadarOption = computed(() => {
const mainColor = 'rgba(16,185,129,0.85)'
const lineColor = 'rgba(16,185,129,0.22)'
return {
backgroundColor: 'transparent',
tooltip: { trigger: 'item' },
tooltip: {trigger: 'item'},
radar: {
indicator: efficiencyRadarIndicators,
shape: 'polygon',
@ -85,9 +50,9 @@ const efficiencyRadarOption = computed(() => {
fontSize: 12,
fontFamily: 'AlibabaPuHuiTi-2-55-Regular',
},
axisLine: { lineStyle: { color: lineColor, width: 1 } },
splitLine: { lineStyle: { color: lineColor, width: 1 } },
splitArea: { show: false },
axisLine: {lineStyle: {color: lineColor, width: 1}},
splitLine: {lineStyle: {color: lineColor, width: 1}},
splitArea: {show: false},
},
series: [
{
@ -95,9 +60,9 @@ const efficiencyRadarOption = computed(() => {
data: [
{
value: efficiencyRadarValue.value,
areaStyle: { color: 'rgba(16,185,129,0.25)' },
lineStyle: { color: mainColor, width: 2 },
itemStyle: { color: mainColor },
areaStyle: {color: 'rgba(16,185,129,0.25)'},
lineStyle: {color: mainColor, width: 2},
itemStyle: {color: mainColor},
symbol: 'none',
},
],
@ -105,6 +70,69 @@ const efficiencyRadarOption = computed(() => {
],
}
})
const efficiencyRadar = ref({
overallRecovery: '',
averageDelay: '',
rescueEfficiency: '',
recoveryEfficiency: '',
trafficHasResumed: '',
})
const historyExecutionEval = ref({
recoveryDuration: '',
averageDelay: '',
rescueSpeed: '',
})
const systemEfficiency = ref({
averageTimeConsuming: '',
automaticCallSuccessRate: '',
optimal: '',
recommendationAccuracyRate: '',
})
const getPageData = async () => {
const res = await api.getPageData('quickrecovery')
const data = JSON.parse(res.data)
console.log("🚀 ~ getPageData ~ data: ", data);
planRows.value = data.schemes
const fieldMappings = {
'efficiency_radar': [
['整体恢复', efficiencyRadar, 'overallRecovery'],
['平均延误', efficiencyRadar, 'averageDelay'],
['救援效率', efficiencyRadar, 'rescueEfficiency'],
['恢复效率', efficiencyRadar, 'recoveryEfficiency'],
['交通恢复', efficiencyRadar, 'trafficHasResumed'],
],
'history_execution_eval': [
['恢复时长', historyExecutionEval, 'recoveryDuration'],
['平均延误', historyExecutionEval, 'averageDelay'],
['救援速度', historyExecutionEval, 'rescueSpeed']
],
'system_efficiency': [
['平均耗时', systemEfficiency, 'averageTimeConsuming'],
['自动调用成功率', systemEfficiency, 'automaticCallSuccessRate'],
['最优', systemEfficiency, 'optimal'],
['推荐准确率', systemEfficiency, 'recommendationAccuracyRate'],
],
}
Object.entries(fieldMappings).forEach(([sectionKey, mappings]) => {
const items = data[sectionKey] || []
const map = new Map(items.map(item => [item['project'], item['data']]))
mappings.forEach(([projectName, targetObj, propName]) => {
if (map.has(projectName)) {
targetObj.value[propName] = map.get(projectName)
}
})
})
// fieldMappings indicator
efficiencyRadarValue.value = fieldMappings.efficiency_radar.map(
([, , propName]) => Number(efficiencyRadar.value[propName] || 0)
)
}
onMounted(() => {
getPageData()
})
</script>
<template>
@ -118,17 +146,20 @@ const efficiencyRadarOption = computed(() => {
<div class="card-body left-body">
<div class="table-wrap">
<el-table :data="planRows" size="small" stripe max-height="760" style="width: 100%"
@row-click="(row) => (activePlanId = row.id)">
<el-table-column prop="id" label="方案ID" width="120" />
<el-table-column prop="enabledAt" label="启用时间" width="150" />
<el-table-column prop="scene" label="适用条件简述" min-width="180" />
<el-table-column prop="config" label="配置简述" min-width="220" />
@row-click="(row) => (activePlanId = row.scheme_id)">
<el-table-column prop="scheme_id" label="方案ID" width="120"/>
<el-table-column prop="enable_time" label="启用时间" width="150"/>
<el-table-column prop="applicable_desc" label="适用条件简述" min-width="180"/>
<el-table-column prop="config_desc" label="配置简述" min-width="220"/>
<el-table-column label="执行状态" width="110">
<template #default="{ row }">
<el-tag :type="statusTagType(row.status)" size="small">{{ row.status }}</el-tag>
<el-tag :type="statusTagType(row.execute_status)" size="small">{{
row.execute_status
}}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="effect" label="方案生成效率" width="110" />
<el-table-column prop="plan_gen_efficiency" label="方案生成效率" width="110"/>
<el-table-column label="操作" width="170" fixed="right">
<template #default>
<div class="table-actions">
@ -148,24 +179,26 @@ const efficiencyRadarOption = computed(() => {
<div class="right-col">
<div class="card right-card right-card-1">
<div class="card-header">
<h3>方案详情与优化管理{{ activePlan?.id }}</h3>
<h3>方案详情与优化管理{{ activePlan?.scheme_id }}</h3>
</div>
<div class="card-body">
<div class="opt-grid">
<div class="opt-item xhkz">
<div class="opt-title">信号控制</div>
<div class="opt-sub">干预路口数 <span class="opt-num">+20%</span></div>
<div class="opt-sub">进口流量 <span class="opt-num">-20%</span></div>
<div class="opt-sub">干预路口数 <span class="opt-num">{{activePlan?.detail.downstream_ratio}}</span></div>
<div class="opt-sub">进口流量 <span class="opt-num">{{activePlan?.detail.entrance_green}}</span></div>
</div>
<div class="opt-item ydfl">
<div class="opt-title">诱导分流</div>
<div class="opt-sub">/下游 3km 诱导</div>
<div class="opt-sub">出口分流 <span class="opt-num">70%</span></div>
<div class="opt-sub">/下游 <span class="opt-num">{{activePlan?.detail.upstream_tip}}</span> 诱导</div>
<div class="opt-sub">出口分流 <span class="opt-num">{{ activePlan?.detail.exit_diversion}}</span></div>
</div>
<div class="opt-item gkzz">
<div class="opt-title">管控组织</div>
<div class="opt-sub">核心路段 <span class="opt-num">300m</span></div>
<div class="opt-sub">管控范围 <span class="opt-num">500m</span></div>
<div class="opt-sub">核心路段 <span class="opt-num">{{activePlan?.detail.core_control
}}</span></div>
<div class="opt-sub">管控范围 <span class="opt-num">{{activePlan?.detail.tube_flow
}}</span></div>
</div>
</div>
</div>
@ -182,7 +215,7 @@ const efficiencyRadarOption = computed(() => {
<div class="kpi-label">恢复时长</div>
</div>
<div class="kpi-value">
<span class="kpi-num">25</span><span class="kpi-unit">分钟</span>
<span class="kpi-num">{{historyExecutionEval.recoveryDuration}}</span><span class="kpi-unit">分钟</span>
</div>
</div>
<div class="kpi-card pjyw">
@ -190,7 +223,7 @@ const efficiencyRadarOption = computed(() => {
<div class="kpi-label">平均延误</div>
</div>
<div class="kpi-value">
<span class="kpi-num">15</span><span class="kpi-unit">分钟</span>
<span class="kpi-num">{{historyExecutionEval.averageDelay}}</span><span class="kpi-unit">分钟</span>
</div>
</div>
<div class="kpi-card jysd">
@ -198,7 +231,7 @@ const efficiencyRadarOption = computed(() => {
<div class="kpi-label">救援速度</div>
</div>
<div class="kpi-value">
<span class="kpi-num">45</span><span class="kpi-unit">km/h</span>
<span class="kpi-num">{{historyExecutionEval.rescueSpeed}}</span><span class="kpi-unit">km/h</span>
</div>
</div>
</div>
@ -210,7 +243,7 @@ const efficiencyRadarOption = computed(() => {
</div>
<div class="card-body eval-radar-body">
<div class="radar-stage">
<VChart class="radar" :option="efficiencyRadarOption" autoresize />
<VChart class="radar" :option="efficiencyRadarOption" autoresize/>
</div>
</div>
</div>
@ -265,19 +298,19 @@ const efficiencyRadarOption = computed(() => {
<div class="flow-list-right">
<div class="flow-item">
<span class="flow-item-label">平均耗时</span>
<span class="flow-item-val">45 S</span>
<span class="flow-item-val">{{systemEfficiency.averageTimeConsuming}}</span>
</div>
<div class="flow-item">
<span class="flow-item-label">自动调用成功率</span>
<span class="flow-item-val ok">98%</span>
<span class="flow-item-val ok">{{systemEfficiency.automaticCallSuccessRate}}</span>
</div>
<div class="flow-item">
<span class="flow-item-label">最优<span class="flow-item-label-blue">&lt;3分钟</span></span>
<span class="flow-item-val ok"></span>
<span class="flow-item-val ok">{{systemEfficiency.optimal}}</span>
</div>
<div class="flow-item">
<span class="flow-item-label">推荐准确率</span>
<span class="flow-item-val">92%</span>
<span class="flow-item-val">{{ systemEfficiency.recommendationAccuracyRate}}</span>
</div>
</div>
</div>
@ -478,17 +511,17 @@ const efficiencyRadarOption = computed(() => {
.icon-signal {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.95), rgba(45, 103, 237, 0.22)),
linear-gradient(135deg, rgba(45, 103, 237, 0.85), rgba(99, 172, 255, 0.75));
linear-gradient(135deg, rgba(45, 103, 237, 0.85), rgba(99, 172, 255, 0.75));
}
.icon-guide {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.95), rgba(34, 197, 94, 0.18)),
linear-gradient(135deg, rgba(34, 197, 94, 0.85), rgba(116, 255, 208, 0.6));
linear-gradient(135deg, rgba(34, 197, 94, 0.85), rgba(116, 255, 208, 0.6));
}
.icon-control {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.95), rgba(249, 115, 22, 0.18)),
linear-gradient(135deg, rgba(249, 115, 22, 0.85), rgba(255, 206, 120, 0.7));
linear-gradient(135deg, rgba(249, 115, 22, 0.85), rgba(255, 206, 120, 0.7));
}
.opt-title {
@ -586,17 +619,17 @@ const efficiencyRadarOption = computed(() => {
.kpi-icon-time {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.96), rgba(37, 99, 235, 0.18)),
linear-gradient(135deg, rgba(45, 103, 237, 0.85), rgba(99, 172, 255, 0.55));
linear-gradient(135deg, rgba(45, 103, 237, 0.85), rgba(99, 172, 255, 0.55));
}
.kpi-icon-delay {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.96), rgba(37, 99, 235, 0.14)),
linear-gradient(135deg, rgba(45, 103, 237, 0.72), rgba(147, 197, 253, 0.55));
linear-gradient(135deg, rgba(45, 103, 237, 0.72), rgba(147, 197, 253, 0.55));
}
.kpi-icon-rescue {
background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.96), rgba(37, 99, 235, 0.14)),
linear-gradient(135deg, rgba(45, 103, 237, 0.7), rgba(125, 211, 252, 0.55));
linear-gradient(135deg, rgba(45, 103, 237, 0.7), rgba(125, 211, 252, 0.55));
}
.kpi-mid {

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed } from 'vue'
import {ref, computed, onMounted} from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, BarChart } from 'echarts/charts'
@ -11,6 +11,7 @@ import imgStatusLdpjsd from '@/assets/images/status/ldpjsd.png'
import imgStatusYxcs from '@/assets/images/status/sgdhxcs.png'
import imgStatusYxqcl from '@/assets/images/status/yxqcls.png'
import MapPage from '@/views/map/index.vue'
import api from "@/api/index.js";
use([
CanvasRenderer,
@ -942,6 +943,17 @@ const accidentImpactOption = computed(() => {
],
}
})
const getPageData = async () => {
const res = await api.getPageData('status')
const data = JSON.parse(res.data)
console.log("🚀 ~ getPageData ~ data: ", data);
}
onMounted(() => {
getPageData()
})
</script>
<template>