1090 lines
29 KiB
Vue
1090 lines
29 KiB
Vue
|
|
<template>
|
||
|
|
<div class="dashboard-container">
|
||
|
|
<!-- 顶部标题栏 -->
|
||
|
|
<div class="header-container">
|
||
|
|
<div class="header-left">
|
||
|
|
<img class="back-img" @click="returnToHeadquarters" src="@/assets/images/screen/back_image.png" />
|
||
|
|
<div class="back-button"> {{ selectedPark }} </div>
|
||
|
|
</div>
|
||
|
|
<h1 class="header-title">{{ selectedPark }}综合监控大屏</h1>
|
||
|
|
<div class="header-right">
|
||
|
|
{{ currentTime }}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<!-- 天气预报 -->
|
||
|
|
<WeatherWarning />
|
||
|
|
<!-- 主内容区 -->
|
||
|
|
<div class="content-container">
|
||
|
|
<div class="left-wrapper">
|
||
|
|
<!-- 左上区域 -->
|
||
|
|
<div class="left-top">
|
||
|
|
<div class="panel-title">总体概览</div>
|
||
|
|
<img style="margin: 8px 0" src="@/assets/images/title_border_line_1.png" />
|
||
|
|
<div class="top-card">
|
||
|
|
<div class="top-card-left">
|
||
|
|
<div>
|
||
|
|
<img width="33px" src="@/assets/images/1_224520_821.png" />
|
||
|
|
</div>
|
||
|
|
<span>总计</span>
|
||
|
|
<div class="number-wrapper">
|
||
|
|
<span class="total-number" v-for="item in 6" :key="item">{{ item }}</span>
|
||
|
|
</div>
|
||
|
|
<span>人</span>
|
||
|
|
</div>
|
||
|
|
<div class="top-card-right">
|
||
|
|
<div class="top-card-right-item">
|
||
|
|
<img width="18px" src="@/assets/images/v2_rel0n8.png" />
|
||
|
|
<span>正式员工</span>
|
||
|
|
<div class="type-number-wrapper" style="margin-left: 2vw">
|
||
|
|
<span class="type-number" v-for="item in 3" :key="item">{{ item }}</span>
|
||
|
|
</div>
|
||
|
|
<span>人</span>
|
||
|
|
</div>
|
||
|
|
<div class="top-card-right-item">
|
||
|
|
<img width="18px" src="@/assets/images/v2_rel0n23.png" />
|
||
|
|
<span>外协人员</span>
|
||
|
|
<div class="type-number-wrapper" style="margin-left: 1vw">
|
||
|
|
<span class="type-number" v-for="item in 2" :key="item">{{ item }}</span>
|
||
|
|
</div>
|
||
|
|
<span>人</span>
|
||
|
|
</div>
|
||
|
|
<div class="top-card-right-item">
|
||
|
|
<img width="18px" src="@/assets/images/24508_654.png" />
|
||
|
|
<span>访客</span>
|
||
|
|
<div class="type-number-wrapper">
|
||
|
|
<span class="type-number" v-for="item in 4" :key="item">{{ item }}</span>
|
||
|
|
</div>
|
||
|
|
<span>人</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="bottom-card">
|
||
|
|
<div class="bottom-card-title">
|
||
|
|
<span>隐患排查治理</span>
|
||
|
|
<img width="50%" style="margin: 8px 0" src="@/assets/images/line_1.png" />
|
||
|
|
</div>
|
||
|
|
<div class="type-wrapper">
|
||
|
|
<div class="type-item">
|
||
|
|
<span class="type-btn green">一般</span>
|
||
|
|
<span class="type-num">1234</span>
|
||
|
|
</div>
|
||
|
|
<!-- <div class="type-item">
|
||
|
|
<span class="type-btn blue">较大</span>
|
||
|
|
<span class="type-num">1234</span>
|
||
|
|
</div> -->
|
||
|
|
<div class="type-item">
|
||
|
|
<span class="type-btn yellow">重大</span>
|
||
|
|
<span class="type-num">1234</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="hazard-wrapper">
|
||
|
|
<div ref="progressChartRef" class="progress-chart"></div>
|
||
|
|
<div class="progress-legend">
|
||
|
|
<div class="legend-item"><span class="dot red"></span>已逾期</div>
|
||
|
|
<div class="legend-item"><span class="dot green"></span>已处理</div>
|
||
|
|
</div>
|
||
|
|
<div class="progress-legend">
|
||
|
|
<div class="legend-item"><span class="dot yellow"></span>待排查</div>
|
||
|
|
<div class="legend-item"><span class="dot blue"></span>处理中</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<!-- 左下区域 -->
|
||
|
|
<div class="left-bottom">
|
||
|
|
<div class="panel-title">
|
||
|
|
<div class="tabs">
|
||
|
|
<span class="tab" :class="{ active: activeTab === '消防演练' }" @click="activeTab = '消防演练'">消防演练</span>
|
||
|
|
<span class="divider">|</span>
|
||
|
|
<span
|
||
|
|
class="tab" :class="{ active: activeTab === '安全、保密培训' }"
|
||
|
|
@click="activeTab = '安全、保密培训'">安全、保密培训</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<img style="margin: 8px 0" src="@/assets/images/title_border_line.png" />
|
||
|
|
<div class="bottom-card">
|
||
|
|
<div class="bottom-card-title" style="margin-top: 0;">
|
||
|
|
<span>各园区统计</span>
|
||
|
|
<img width="50%" style="margin: 8px 0" src="@/assets/images/line_1.png" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="row-wrapper">
|
||
|
|
<div class="row-item">
|
||
|
|
<img src="@/assets/images/screen/participants_icon.png" width="20" />
|
||
|
|
<span class="row-item-title">累计参与人次</span>
|
||
|
|
<span class="row-item-number">1234</span>
|
||
|
|
</div>
|
||
|
|
<div class="row-item">
|
||
|
|
<img src="@/assets/images/screen/training_plan_icon.png" width="20" />
|
||
|
|
<span class="row-item-title">培训/考试计划</span>
|
||
|
|
<span class="row-item-number">1234</span>
|
||
|
|
</div>
|
||
|
|
<div class="row-item">
|
||
|
|
<img src="@/assets/images/screen/to_completed_icon.png" width="20" />
|
||
|
|
<span class="row-item-title">待完成人数</span>
|
||
|
|
<span class="row-item-number">1234</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div style="flex: 1; display: flex; width: 100%;">
|
||
|
|
<AlertList style="margin-left: 1vw;" :list-data="source"/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="right-wrapper">
|
||
|
|
<!-- 右上区域 -->
|
||
|
|
<div class="right-top" style="text-align: right">
|
||
|
|
<div class="panel-title">安防告警</div>
|
||
|
|
<div>
|
||
|
|
<img style="margin: 8px 0" src="@/assets/images/title_border_line_1.png" />
|
||
|
|
</div>
|
||
|
|
<div class="tip-container">
|
||
|
|
<div class="tip-image">
|
||
|
|
<img src="@/assets/images/screen/circle_image.png" width="80" height="80" />
|
||
|
|
<span class="number">1234</span>
|
||
|
|
</div>
|
||
|
|
<img src="@/assets/images/screen/tip_bg_image.png" width="100%" height="70" />
|
||
|
|
<div class="tip-content">
|
||
|
|
<div class="col-item">
|
||
|
|
<img src="@/assets/images/screen/warning_img.png" width="23" />
|
||
|
|
<span>告警总数</span>
|
||
|
|
<span style="font-size: 1.2rem; marker-start: 2vw; color: yellow;">456</span>
|
||
|
|
</div>
|
||
|
|
<div class="col-item">
|
||
|
|
<span>已处理</span>
|
||
|
|
<span style="font-size: 1.2rem; marker-start: 2vw; color: greenyellow;">456</span>
|
||
|
|
</div>
|
||
|
|
<div class="col-item" style=" display: flex;margin-left: 2vw; align-items: center;">
|
||
|
|
<span>待处理/处理中</span>
|
||
|
|
<span style="font-size: 1.2rem; marker-start: 2vw; color: yellow;">456</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: end;">
|
||
|
|
<AlertList style="margin-right: 1vw;" title="告警详情" :list-data="source" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<!-- 右下区域 -->
|
||
|
|
<div class="right-bottom" style="text-align: right">
|
||
|
|
<div class="panel-title">超时工单</div>
|
||
|
|
<img style="margin: 8px 0" src="@/assets/images/title_border_line_1.png" />
|
||
|
|
<div class="tip-container">
|
||
|
|
<div class="tip-image">
|
||
|
|
<img src="@/assets/images/screen/circle_image.png" width="80" height="80" />
|
||
|
|
<span class="number">1234</span>
|
||
|
|
</div>
|
||
|
|
<img src="@/assets/images/screen/tip_bg_image.png" width="100%" height="70" />
|
||
|
|
<div class="tip-content">
|
||
|
|
<div class="col-item">
|
||
|
|
<img src="@/assets/images/screen/warning_img.png" width="23" />
|
||
|
|
<span>超时工单数</span>
|
||
|
|
<span style="font-size: 1.2rem; marker-start: 2vw; color: red;">10</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: end;">
|
||
|
|
<AlertList style="margin-right: 1vw;" title="工单详情" :list-data="source" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="center-container">
|
||
|
|
<!-- 中部区域 -->
|
||
|
|
<ParkCenter @point-hover="handlePointHover" @point-leave="handlePointLeave" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 点位信息弹窗 -->
|
||
|
|
<PointInfoPopup
|
||
|
|
v-if="showPointPopup" :visible="showPointPopup" :point-info="currentPoint"
|
||
|
|
:park-name="selectedPark || '雄安园区'" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { ref, onMounted, nextTick, onUnmounted } from 'vue'
|
||
|
|
import { useRoute, useRouter } from 'vue-router'
|
||
|
|
import * as echarts from 'echarts'
|
||
|
|
import ParkCenter from './components/ParkCenter.vue'
|
||
|
|
import PointInfoPopup from './components/PointInfoPopup.vue'
|
||
|
|
import WeatherWarning from './components/WeatherWarning.vue'
|
||
|
|
import AlertList from './components/AlertList.vue'
|
||
|
|
|
||
|
|
interface PointPosition {
|
||
|
|
label: string
|
||
|
|
x: number
|
||
|
|
y: number
|
||
|
|
relativeX: number
|
||
|
|
relativeY: number
|
||
|
|
}
|
||
|
|
|
||
|
|
const route = useRoute()
|
||
|
|
const router = useRouter()
|
||
|
|
|
||
|
|
const selectedPark = ref('')
|
||
|
|
const currentTime = ref<string>('')
|
||
|
|
const activeTab = ref<string>('消防演练')
|
||
|
|
const showPointPopup = ref(false)
|
||
|
|
const currentPoint = ref<PointPosition | null>(null)
|
||
|
|
const progressChart = ref<echarts.ECharts | null>(null)
|
||
|
|
const donutChart = ref<echarts.ECharts | null>(null)
|
||
|
|
const progressChartRef = ref<HTMLElement | null>(null)
|
||
|
|
const donutChartRef = ref<HTMLElement | null>(null)
|
||
|
|
|
||
|
|
const source = ref([
|
||
|
|
{
|
||
|
|
text: '2024-07-10 上午8:00 雄安园区隐患内容管理 状态 处理',
|
||
|
|
error: true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2025-07-09 上海XXX区域A1门禁告警 处理中 紧急',
|
||
|
|
error: true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2025-07-09 上海XXX区域A1门禁告警 处理中 紧急',
|
||
|
|
error: true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果',
|
||
|
|
warn: true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果',
|
||
|
|
warn: true
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
text: '2020-06-18 编辑内容编辑内容编辑内容编辑内容编辑内容 状态 结果'
|
||
|
|
}
|
||
|
|
])
|
||
|
|
|
||
|
|
// 返回上一级:总部
|
||
|
|
const returnToHeadquarters = () => {
|
||
|
|
router.back()
|
||
|
|
}
|
||
|
|
|
||
|
|
const handlePointHover = (position: PointPosition) => {
|
||
|
|
currentPoint.value = position
|
||
|
|
showPointPopup.value = true
|
||
|
|
}
|
||
|
|
|
||
|
|
const handlePointLeave = () => {
|
||
|
|
showPointPopup.value = false
|
||
|
|
currentPoint.value = null
|
||
|
|
}
|
||
|
|
|
||
|
|
// 初始化进度图表
|
||
|
|
const initProgressChart = () => {
|
||
|
|
const chartElement = progressChartRef.value
|
||
|
|
if (chartElement) {
|
||
|
|
progressChart.value = echarts.init(chartElement)
|
||
|
|
const width = progressChart.value.getWidth()
|
||
|
|
|
||
|
|
const progressOption = {
|
||
|
|
series: [
|
||
|
|
{
|
||
|
|
type: 'pie',
|
||
|
|
radius: '60%',
|
||
|
|
center: ['50%', '50%'],
|
||
|
|
left: 0,
|
||
|
|
top: 0,
|
||
|
|
bottom: 0,
|
||
|
|
data: [
|
||
|
|
{ value: 20, name: '已逾期', itemStyle: { color: '#ef4444' } },
|
||
|
|
{ value: 35, name: '已处理', itemStyle: { color: '#10b981' } },
|
||
|
|
{ value: 25, name: '待排查', itemStyle: { color: '#eab308' } },
|
||
|
|
{ value: 20, name: '处理中', itemStyle: { color: '#3b82f6' } },
|
||
|
|
],
|
||
|
|
label: {
|
||
|
|
alignTo: 'edge',
|
||
|
|
formatter: '{time|{c} %}\n',
|
||
|
|
minMargin: 5,
|
||
|
|
edgeDistance: 10,
|
||
|
|
lineHeight: 15,
|
||
|
|
rich: {
|
||
|
|
time: {
|
||
|
|
fontSize: 10,
|
||
|
|
color: '#fff'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
labelLine: {
|
||
|
|
length: 5,
|
||
|
|
length2: 0,
|
||
|
|
maxSurfaceAngle: 10
|
||
|
|
},
|
||
|
|
labelLayout: function (params: any) {
|
||
|
|
const isLeft = params.labelRect.x < width / 2;
|
||
|
|
const points = params.labelLinePoints;
|
||
|
|
points[2][0] = isLeft
|
||
|
|
? params.labelRect.x
|
||
|
|
: params.labelRect.x + params.labelRect.width;
|
||
|
|
return {
|
||
|
|
labelLinePoints: points
|
||
|
|
};
|
||
|
|
},
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
progressChart.value.setOption(progressOption)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 初始化环形图表
|
||
|
|
const initDonutChart = () => {
|
||
|
|
const chartElement = donutChartRef.value
|
||
|
|
if (chartElement) {
|
||
|
|
donutChart.value = echarts.init(chartElement)
|
||
|
|
|
||
|
|
const option = {
|
||
|
|
legend: {
|
||
|
|
bottom: '10%',
|
||
|
|
right: '0%',
|
||
|
|
orient: 'vertical',
|
||
|
|
textStyle: {
|
||
|
|
color: '#ffffff',
|
||
|
|
fontSize: '11px'
|
||
|
|
}
|
||
|
|
},
|
||
|
|
series: [
|
||
|
|
{
|
||
|
|
type: 'pie',
|
||
|
|
radius: ['25%', '55%'],
|
||
|
|
center: ['50%', '50%'],
|
||
|
|
data: [
|
||
|
|
{ value: 12, name: '已完成', itemStyle: { color: '#10b981' } },
|
||
|
|
{ value: 34, name: '进行中', itemStyle: { color: '#3b82f6' } },
|
||
|
|
{ value: 18, name: '待开始', itemStyle: { color: '#eab308' } },
|
||
|
|
{ value: 8, name: '已暂停', itemStyle: { color: '#ef4444' } }
|
||
|
|
],
|
||
|
|
label: {
|
||
|
|
show: true,
|
||
|
|
position: 'outside',
|
||
|
|
formatter: function (params: any) {
|
||
|
|
return params.value + ' ' + params.percent + '%'
|
||
|
|
},
|
||
|
|
fontSize: 12,
|
||
|
|
color: '#ffffff',
|
||
|
|
fontWeight: 'bold'
|
||
|
|
},
|
||
|
|
labelLine: {
|
||
|
|
show: true,
|
||
|
|
length: 15,
|
||
|
|
length2: 10,
|
||
|
|
lineStyle: {
|
||
|
|
color: '#64748b',
|
||
|
|
width: 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
donutChart.value.setOption(option)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
setInterval(() => {
|
||
|
|
const now = new Date()
|
||
|
|
const year = now.getFullYear()
|
||
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
||
|
|
const day = String(now.getDate()).padStart(2, '0')
|
||
|
|
const hours = String(now.getHours()).padStart(2, '0')
|
||
|
|
const minutes = String(now.getMinutes()).padStart(2, '0')
|
||
|
|
const seconds = String(now.getSeconds()).padStart(2, '0')
|
||
|
|
currentTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||
|
|
}, 1000)
|
||
|
|
|
||
|
|
if (typeof route.query.park === 'string') {
|
||
|
|
selectedPark.value = route.query.park
|
||
|
|
}
|
||
|
|
|
||
|
|
// 初始化图表
|
||
|
|
nextTick(() => {
|
||
|
|
initProgressChart()
|
||
|
|
initDonutChart()
|
||
|
|
})
|
||
|
|
|
||
|
|
// 监听窗口大小变化,重绘图表
|
||
|
|
window.addEventListener('resize', () => {
|
||
|
|
if (progressChart.value) {
|
||
|
|
progressChart.value.resize()
|
||
|
|
}
|
||
|
|
if (donutChart.value) {
|
||
|
|
donutChart.value.resize()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
onUnmounted(() => {
|
||
|
|
})
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped lang="scss">
|
||
|
|
/* 响应式设计 - 自动适应不同屏幕尺寸 */
|
||
|
|
@media (width <=1200px) {
|
||
|
|
.dashboard-container {
|
||
|
|
.content-container {
|
||
|
|
column-gap: 4vw;
|
||
|
|
|
||
|
|
.center-container {
|
||
|
|
width: 60vh;
|
||
|
|
height: 60vh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (width <=1024px) {
|
||
|
|
.dashboard-container {
|
||
|
|
.content-container {
|
||
|
|
column-gap: 3vw;
|
||
|
|
padding: 0 8px 15px;
|
||
|
|
|
||
|
|
.left-wrapper {
|
||
|
|
.left-top .hazard-wrapper {
|
||
|
|
.progress-chart {
|
||
|
|
min-height: 180px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-bottom .donut-chart-with-labels {
|
||
|
|
width: 35vw;
|
||
|
|
height: 35vh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.center-container {
|
||
|
|
width: 55vh;
|
||
|
|
height: 55vh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (width <=768px) {
|
||
|
|
.dashboard-container {
|
||
|
|
.content-container {
|
||
|
|
column-gap: 2vw;
|
||
|
|
padding: 0 5px 10px;
|
||
|
|
|
||
|
|
.left-wrapper {
|
||
|
|
.left-top .hazard-wrapper {
|
||
|
|
.progress-chart {
|
||
|
|
min-height: 160px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-bottom .donut-chart-with-labels {
|
||
|
|
width: 40vw;
|
||
|
|
height: 40vh;
|
||
|
|
margin-left: 1vw;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.center-container {
|
||
|
|
top: 60%;
|
||
|
|
width: 50vh;
|
||
|
|
height: 50vh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@media (width <=480px) {
|
||
|
|
.dashboard-container {
|
||
|
|
.content-container {
|
||
|
|
column-gap: 1vw;
|
||
|
|
padding: 0 3px 8px;
|
||
|
|
|
||
|
|
.left-wrapper {
|
||
|
|
.left-top .hazard-wrapper {
|
||
|
|
.progress-chart {
|
||
|
|
min-height: 140px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-bottom .donut-chart-with-labels {
|
||
|
|
width: 45vw;
|
||
|
|
height: 45vh;
|
||
|
|
margin-left: 0.5vw;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.center-container {
|
||
|
|
top: 65%;
|
||
|
|
width: 45vh;
|
||
|
|
height: 45vh;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot {
|
||
|
|
width: 6px;
|
||
|
|
height: 6px;
|
||
|
|
border-radius: 50%;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.red {
|
||
|
|
background-color: #ef4444;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.green {
|
||
|
|
background-color: #10b981;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.yellow {
|
||
|
|
background-color: #eab308;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.blue {
|
||
|
|
background-color: #3b82f6;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.cyan {
|
||
|
|
background-color: #06b6d4;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.purple {
|
||
|
|
background-color: #8b5cf6;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dot.orange {
|
||
|
|
background-color: #f59e0b;
|
||
|
|
}
|
||
|
|
|
||
|
|
.dashboard-container {
|
||
|
|
position: relative;
|
||
|
|
display: flex;
|
||
|
|
width: 100vw;
|
||
|
|
height: 100vh;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
color: #fff;
|
||
|
|
background: url('@/assets/images/v2_rel0n6.png');
|
||
|
|
background-color: #030e22;
|
||
|
|
background-size: cover;
|
||
|
|
flex-direction: column;
|
||
|
|
|
||
|
|
.header-container {
|
||
|
|
display: flex;
|
||
|
|
height: 80px;
|
||
|
|
background: url('@/assets/images/top_bg.png') no-repeat;
|
||
|
|
background-size: 100%;
|
||
|
|
|
||
|
|
.header-left {
|
||
|
|
display: flex;
|
||
|
|
padding-left: 1vw;
|
||
|
|
line-height: 80px;
|
||
|
|
flex: 1;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.back-img {
|
||
|
|
height: 3vh;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.3s ease;
|
||
|
|
}
|
||
|
|
|
||
|
|
.back-button {
|
||
|
|
display: inline-flex;
|
||
|
|
height: 2vh;
|
||
|
|
min-width: 6vw;
|
||
|
|
padding: 4px 16px;
|
||
|
|
margin-left: 0.5vw;
|
||
|
|
font-size: 0.9rem;
|
||
|
|
cursor: pointer;
|
||
|
|
background: rgb(13 24 84 / 80%);
|
||
|
|
border: 1px solid rgb(59 130 246 / 40%);
|
||
|
|
transition: all 0.3s ease;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
}
|
||
|
|
|
||
|
|
.back-button:hover {
|
||
|
|
background: rgb(59 130 246 / 30%);
|
||
|
|
border-color: rgb(59 130 246 / 60%);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.header-right {
|
||
|
|
margin-right: 20px;
|
||
|
|
font-size: 0.9rem;
|
||
|
|
line-height: 80px;
|
||
|
|
text-align: right;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
.header-title {
|
||
|
|
font-size: 1.3rem;
|
||
|
|
font-weight: bold;
|
||
|
|
line-height: 40px;
|
||
|
|
color: #fff;
|
||
|
|
text-align: center;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.content-container {
|
||
|
|
position: relative;
|
||
|
|
display: flex;
|
||
|
|
width: calc(100vw - 20px);
|
||
|
|
height: calc(100vh - 105px);
|
||
|
|
padding: 0 10px 20px;
|
||
|
|
column-gap: 7vw;
|
||
|
|
|
||
|
|
.panel-title {
|
||
|
|
margin: 4px 20px 0;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
font-weight: bold;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bottom-card {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
flex: 1;
|
||
|
|
width: 67%;
|
||
|
|
|
||
|
|
.bottom-card-title {
|
||
|
|
display: flex;
|
||
|
|
margin-top: 5px;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.type-wrapper {
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
column-gap: 2vw;
|
||
|
|
margin-top: 5px;
|
||
|
|
|
||
|
|
.type-item {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
column-gap: 4px;
|
||
|
|
|
||
|
|
.type-btn {
|
||
|
|
display: inline-block;
|
||
|
|
padding: 2px 30px;
|
||
|
|
font-size: 0.7rem;
|
||
|
|
cursor: pointer;
|
||
|
|
background-color: rgb(59 130 246 / 20%);
|
||
|
|
border-radius: 12px;
|
||
|
|
user-select: none;
|
||
|
|
|
||
|
|
&.blue {
|
||
|
|
background-color: rgb(32 148 235);
|
||
|
|
}
|
||
|
|
|
||
|
|
&.green {
|
||
|
|
background-color: rgb(80 139 79);
|
||
|
|
}
|
||
|
|
|
||
|
|
&.yellow {
|
||
|
|
background-color: rgb(204 96 26);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.type-num {
|
||
|
|
margin-top: 0.3vh;
|
||
|
|
font-size: 0.9rem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.hazard-wrapper {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
column-gap: 1.8vw;
|
||
|
|
|
||
|
|
.progress-chart {
|
||
|
|
width: 55%;
|
||
|
|
min-height: 140px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.progress-legend {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: center;
|
||
|
|
gap: 0.5vw;
|
||
|
|
|
||
|
|
.legend-item {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 4px;
|
||
|
|
font-size: 0.7rem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-wrapper {
|
||
|
|
flex: 1;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
row-gap: 1rem;
|
||
|
|
height: 100%;
|
||
|
|
|
||
|
|
.left-top {
|
||
|
|
padding: 0 5px;
|
||
|
|
background-image:
|
||
|
|
url('@/assets/images/screen/left_top_img.png'),
|
||
|
|
url('@/assets/images/screen/left_center_img.png'),
|
||
|
|
url('@/assets/images/screen/left_bottom_img.png');
|
||
|
|
background-position:
|
||
|
|
top center,
|
||
|
|
left center,
|
||
|
|
bottom center;
|
||
|
|
|
||
|
|
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
|
||
|
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||
|
|
|
||
|
|
/* 设置位置 */
|
||
|
|
background-size:
|
||
|
|
100% 90px,
|
||
|
|
cover,
|
||
|
|
100% 68px;
|
||
|
|
flex: 1;
|
||
|
|
|
||
|
|
/* 设置重复方式 */
|
||
|
|
.top-card {
|
||
|
|
display: flex;
|
||
|
|
padding: 0 20px;
|
||
|
|
column-gap: 15px;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
|
||
|
|
.top-card-left {
|
||
|
|
display: flex;
|
||
|
|
height: 12vh;
|
||
|
|
min-width: 15vw;
|
||
|
|
padding: 0 10px;
|
||
|
|
background-image: url('@/assets/imgs/total_count_card_bg.png');
|
||
|
|
background-size: cover;
|
||
|
|
column-gap: 6px;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.number-wrapper {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 2px;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
.total-number {
|
||
|
|
display: inline-block;
|
||
|
|
width: 26px;
|
||
|
|
height: 50px;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
line-height: 50px;
|
||
|
|
color: #fff;
|
||
|
|
text-align: center;
|
||
|
|
background-color: rgb(177 74 201 / 100%);
|
||
|
|
border-radius: 4px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.top-card-right {
|
||
|
|
display: flex;
|
||
|
|
height: 12vh;
|
||
|
|
min-width: 20vw;
|
||
|
|
background-image: url('@/assets/imgs/staff_types_bg.png');
|
||
|
|
background-position: top center;
|
||
|
|
background-size: cover;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: center;
|
||
|
|
row-gap: 4px;
|
||
|
|
|
||
|
|
.top-card-right-item {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
column-gap: 5px;
|
||
|
|
padding: 0 10px;
|
||
|
|
font-size: 0.7rem;
|
||
|
|
color: #fff;
|
||
|
|
|
||
|
|
.type-number-wrapper {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
gap: 2px;
|
||
|
|
font-size: 0.8rem;
|
||
|
|
color: #fff;
|
||
|
|
|
||
|
|
.type-number {
|
||
|
|
display: inline-block;
|
||
|
|
width: 14px;
|
||
|
|
height: 25px;
|
||
|
|
font-size: 0.9rem;
|
||
|
|
line-height: 25px;
|
||
|
|
color: #fff;
|
||
|
|
text-align: center;
|
||
|
|
background-color: #1afb8f;
|
||
|
|
border-radius: 2px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-bottom {
|
||
|
|
background-image:
|
||
|
|
url('@/assets/images/screen/left_top_2_img.png'),
|
||
|
|
url('@/assets/images/screen/left_center_img.png'),
|
||
|
|
url('@/assets/images/screen/left_bottom_img.png');
|
||
|
|
background-position:
|
||
|
|
top center,
|
||
|
|
left center,
|
||
|
|
bottom center;
|
||
|
|
|
||
|
|
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
|
||
|
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||
|
|
|
||
|
|
/* 设置位置 */
|
||
|
|
background-size:
|
||
|
|
100% 90px,
|
||
|
|
cover,
|
||
|
|
100% 68px;
|
||
|
|
flex: 1;
|
||
|
|
|
||
|
|
/* 设置重复方式 */
|
||
|
|
.tabs {
|
||
|
|
display: inline-flex;
|
||
|
|
align-items: center;
|
||
|
|
column-gap: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab {
|
||
|
|
padding: 2px 10px;
|
||
|
|
color: #fff;
|
||
|
|
cursor: pointer;
|
||
|
|
border-radius: 4px;
|
||
|
|
transition: all 0.2s ease-in-out;
|
||
|
|
user-select: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab:hover {
|
||
|
|
color: #1afb8f;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab.active {
|
||
|
|
color: #1afb8f;
|
||
|
|
background: rgb(26 251 143 / 12%);
|
||
|
|
border: 1px solid rgb(26 251 143 / 35%);
|
||
|
|
}
|
||
|
|
|
||
|
|
.divider {
|
||
|
|
margin: 0 2px;
|
||
|
|
color: #94a3b8;
|
||
|
|
}
|
||
|
|
|
||
|
|
.donut-chart-with-labels {
|
||
|
|
width: 30vw;
|
||
|
|
height: 30vh;
|
||
|
|
min-height: 200px;
|
||
|
|
margin-left: 2vw;
|
||
|
|
}
|
||
|
|
|
||
|
|
.row-wrapper {
|
||
|
|
display: flex;
|
||
|
|
width: 67%;
|
||
|
|
column-gap: 1vw;
|
||
|
|
margin-left: 1vw;
|
||
|
|
|
||
|
|
.row-item {
|
||
|
|
display: flex;
|
||
|
|
padding: 0.5vh 0;
|
||
|
|
font-size: 0.7rem;
|
||
|
|
background-color: rgb(4 35 125 / 50%);
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: center;
|
||
|
|
column-gap: 10px;
|
||
|
|
flex: 1;
|
||
|
|
|
||
|
|
.row-item-title {}
|
||
|
|
|
||
|
|
.row-item-number {
|
||
|
|
font-size: 1rem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.right-wrapper {
|
||
|
|
display: flex;
|
||
|
|
height: 100%;
|
||
|
|
flex: 1;
|
||
|
|
flex-direction: column;
|
||
|
|
row-gap: 1rem;
|
||
|
|
|
||
|
|
.right-top {
|
||
|
|
/* 设置重复方式 */
|
||
|
|
display: flex;
|
||
|
|
background-image:
|
||
|
|
url('@/assets/images/screen/right_top_img.png'),
|
||
|
|
url('@/assets/images/screen/right_center_img.png'),
|
||
|
|
url('@/assets/images/screen/right_bottom_img.png');
|
||
|
|
background-position:
|
||
|
|
top center,
|
||
|
|
right center,
|
||
|
|
bottom center;
|
||
|
|
|
||
|
|
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
|
||
|
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||
|
|
|
||
|
|
/* 设置位置 */
|
||
|
|
background-size:
|
||
|
|
100% 90px,
|
||
|
|
cover,
|
||
|
|
100% 68px;
|
||
|
|
flex: 1;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: flex-end;
|
||
|
|
|
||
|
|
.tip-container {
|
||
|
|
position: relative;
|
||
|
|
display: flex;
|
||
|
|
width: 70%;
|
||
|
|
height: 80px;
|
||
|
|
padding-right: 20px;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: end;
|
||
|
|
|
||
|
|
.tip-image {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 0;
|
||
|
|
transform: translateY(-50%) translateX(-50%);
|
||
|
|
|
||
|
|
.number {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 50%;
|
||
|
|
font-size: 1rem;
|
||
|
|
color: #fff;
|
||
|
|
transform: translate(-80%, -50%);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.tip-content {
|
||
|
|
position: absolute;
|
||
|
|
inset: 0% 0 0 6%;
|
||
|
|
display: flex;
|
||
|
|
padding-left: 20px;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.col-item {
|
||
|
|
display: flex;
|
||
|
|
margin-left: 1vw;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
span {
|
||
|
|
margin-right: 10px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.right-bottom {
|
||
|
|
/* 设置重复方式 */
|
||
|
|
|
||
|
|
display: flex;
|
||
|
|
background-image:
|
||
|
|
url('@/assets/images/screen/right_top_img.png'),
|
||
|
|
url('@/assets/images/screen/right_center_img.png'),
|
||
|
|
url('@/assets/images/screen/right_bottom_img.png');
|
||
|
|
background-position:
|
||
|
|
top center,
|
||
|
|
right center,
|
||
|
|
bottom center;
|
||
|
|
|
||
|
|
/* 设置大小,注意中间的背景图应该覆盖整个容器 */
|
||
|
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||
|
|
|
||
|
|
/* 设置位置 */
|
||
|
|
background-size:
|
||
|
|
100% 90px,
|
||
|
|
cover,
|
||
|
|
100% 68px;
|
||
|
|
flex: 1;
|
||
|
|
flex-direction: column;
|
||
|
|
align-items: flex-end;
|
||
|
|
|
||
|
|
.tip-container {
|
||
|
|
position: relative;
|
||
|
|
display: flex;
|
||
|
|
width: 50%;
|
||
|
|
height: 80px;
|
||
|
|
padding-right: 20px;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: end;
|
||
|
|
|
||
|
|
.tip-image {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 0;
|
||
|
|
transform: translateY(-50%) translateX(-50%);
|
||
|
|
|
||
|
|
.number {
|
||
|
|
position: absolute;
|
||
|
|
top: 50%;
|
||
|
|
left: 50%;
|
||
|
|
font-size: 1rem;
|
||
|
|
color: #fff;
|
||
|
|
transform: translate(-80%, -50%);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.tip-content {
|
||
|
|
position: absolute;
|
||
|
|
inset: 0% 0 0 6%;
|
||
|
|
display: flex;
|
||
|
|
padding-left: 20px;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
.col-item {
|
||
|
|
display: flex;
|
||
|
|
margin-left: 1vw;
|
||
|
|
align-items: center;
|
||
|
|
|
||
|
|
span {
|
||
|
|
margin-right: 10px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.center-container {
|
||
|
|
position: fixed;
|
||
|
|
top: 55%;
|
||
|
|
left: 50%;
|
||
|
|
z-index: 1;
|
||
|
|
display: flex;
|
||
|
|
width: 65vh;
|
||
|
|
height: 65vh;
|
||
|
|
color: #fff;
|
||
|
|
background-image: url('@/assets/images/circle_bg.png');
|
||
|
|
background-size: cover;
|
||
|
|
transform: translate(-50%, -50%);
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|