539 lines
15 KiB
Vue
539 lines
15 KiB
Vue
<template>
|
|
<div class="box-3">
|
|
<Title1 title="交通信息" />
|
|
<div class="traffic-info flex justify-evenly pt-10 pb-20">
|
|
<!-- <div class="cell">
|
|
<img class="icon" src="@/assets/images/icon-1.png" alt="" />
|
|
<div>
|
|
<countup :end-val="homeStore.trafficInfoData.info.ldzs" />
|
|
<div class="label">路段总数</div>
|
|
</div>
|
|
</div> -->
|
|
<div class="cell">
|
|
<img class="icon" src="@/assets/images/icon-2.png" alt="" />
|
|
<div>
|
|
<countup :end-val="homeStore.trafficInfoData.info.dqydld" />
|
|
<div class="label">当前拥堵路段</div>
|
|
</div>
|
|
</div>
|
|
<div class="cell">
|
|
<img class="icon" src="@/assets/images/icon-3.png" alt="" />
|
|
<div>
|
|
<countup :end-val="homeStore.trafficInfoData.info.zydcs" />
|
|
<div class="label">总拥堵次数</div>
|
|
</div>
|
|
</div>
|
|
<div class="cell">
|
|
<img class="icon" src="@/assets/images/icon-4.png" alt="" />
|
|
<div>
|
|
<countup :end-val="homeStore.trafficInfoData.info.zdydsc" />
|
|
<div class="label">最大拥堵时长 </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex">
|
|
<div class="box">
|
|
<div class="pt-10">
|
|
<Title3 title="拥堵路段总数" />
|
|
<Line
|
|
:width="250"
|
|
:height="150"
|
|
:config="{ legend: false }"
|
|
:data="congestionData"
|
|
:xAxisData="congestionXAxisData"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="box">
|
|
<div class="pt-10">
|
|
<Title3 title="拥堵次数占比" />
|
|
<jam-count :list="homeStore.trafficInfoData.data.countRate" />
|
|
</div>
|
|
</div>
|
|
<div class="box">
|
|
<div class="pt-10">
|
|
<Title3 title="拥堵时长" />
|
|
<jam-duration :list="homeStore.trafficInfoData.data.timeRate" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Title1 title="停车信息(调试中)" />
|
|
<div class="stop-box">
|
|
<div>
|
|
<img class="icon" src="@/assets/images/icon-5.png" alt="" />
|
|
<div>
|
|
<div class="label">停车场总数</div>
|
|
<countup class="value" :end-val="homeStore.carStopInfoData.countInfo.ckzs" />
|
|
</div>
|
|
<div>
|
|
<div class="label">车位总数</div>
|
|
<countup class="value" :end-val="homeStore.carStopInfoData.countInfo.zcws" />
|
|
</div>
|
|
<div>
|
|
<div class="label">已使用车位数</div>
|
|
<countup class="value" :end-val="homeStore.carStopInfoData.countInfo.ysycws" />
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div v-for="item in homeStore.carStopInfoData.spotInfo">
|
|
<div class="label">{{ item.name }}</div>
|
|
<div class="value" :class="{ error: item.type == 1, success: item.type == 0 }">
|
|
{{ item.value }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex pt-10">
|
|
<div class="box-1">
|
|
<div class="pt-10">
|
|
<Title3 title="停车场车流量" />
|
|
<div class="pt-10">
|
|
<Line
|
|
:width="250"
|
|
:height="150"
|
|
:config="{ legend: false }"
|
|
:data="parkData"
|
|
:xAxisData="parkXAxisData"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="box-1">
|
|
<div class="pt-10">
|
|
<Title3 title="车源地TOP5" />
|
|
<vehicle-source :list="homeStore.carStopInfoData.dataList1" />
|
|
</div>
|
|
</div>
|
|
<div class="box-1">
|
|
<div class="pt-10">
|
|
<Title3 title="停车场空余" />
|
|
<vacancy :list="homeStore.carStopInfoData.dataList2" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex">
|
|
<div class="flex-1">
|
|
<Title1 title="车船信息" class="title1" />
|
|
</div>
|
|
<div class="flex-1">
|
|
<Title1 title="酒店信息" class="title1" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex">
|
|
<div class="car-ship">
|
|
<div class="mb-6">
|
|
<div class="car">
|
|
<div class="label">车总数</div>
|
|
<div class="flex align-center">
|
|
<countup class="value" :end-val="homeStore.carShipData?.car?.count || 0" />
|
|
<span class="unit">辆</span>
|
|
</div>
|
|
</div>
|
|
<div class="table">
|
|
<div class="header">
|
|
<div>景区</div>
|
|
<div>运行</div>
|
|
<div>空余</div>
|
|
</div>
|
|
<div class="content">
|
|
<vue3-seamless-scroll
|
|
v-model="carMove"
|
|
:list="homeStore.carShipData?.car?.info"
|
|
:limitScrollNum="3"
|
|
:hover="true"
|
|
:step="0.2"
|
|
:copy-num="0"
|
|
:wheel="true"
|
|
:isWatch="true"
|
|
>
|
|
<div
|
|
class="cell"
|
|
v-for="(item, index) in homeStore.carShipData?.car?.info"
|
|
:key="index"
|
|
>
|
|
<div>{{ item.name }}</div>
|
|
<div>{{ item.started_count }}<span class="unit-1">辆</span></div>
|
|
<div>{{ item.not_started_count }}<span class="unit-1">辆</span></div>
|
|
</div>
|
|
</vue3-seamless-scroll>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="ship">
|
|
<div class="label">船总数</div>
|
|
<div class="flex align-center">
|
|
<countup class="value" :end-val="homeStore.carShipData?.ship?.count || 0" />
|
|
<span class="unit">辆</span>
|
|
</div>
|
|
</div>
|
|
<div class="table">
|
|
<div class="header">
|
|
<div>景区</div>
|
|
<div>运行</div>
|
|
<div>空余</div>
|
|
</div>
|
|
<div class="content">
|
|
<vue3-seamless-scroll
|
|
v-model="shipMove"
|
|
:list="homeStore.carShipData?.ship?.info"
|
|
:limitScrollNum="3"
|
|
:hover="true"
|
|
:step="0.2"
|
|
:copy-num="0"
|
|
:wheel="true"
|
|
:isWatch="true"
|
|
>
|
|
<div
|
|
class="cell"
|
|
v-for="(item, index) in homeStore.carShipData?.ship?.info"
|
|
:key="index"
|
|
>
|
|
<div>{{ item.name }}</div>
|
|
<div>{{ item.started_count }}<span class="unit-1">辆</span></div>
|
|
<div>{{ item.not_started_count }}<span class="unit-1">辆</span></div>
|
|
</div>
|
|
</vue3-seamless-scroll>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="hotel">
|
|
<div>
|
|
<div class="item">
|
|
<div class="label">酒店总数</div>
|
|
<countup class="value" :end-val="homeStore.hotelData?.info?.hotel_count || 0" />
|
|
</div>
|
|
<div class="item">
|
|
<div class="label">房间总数</div>
|
|
<countup class="value" :end-val="homeStore.hotelData?.info?.total_room_count || 0" />
|
|
</div>
|
|
<div class="item">
|
|
<div class="label">当前入住总数</div>
|
|
<countup
|
|
class="value success"
|
|
:end-val="homeStore.hotelData?.info?.total_guest_count || 0"
|
|
/>
|
|
</div>
|
|
<div class="item">
|
|
<div class="label">当前入住率</div>
|
|
<div class="flex align-center">
|
|
<countup
|
|
class="value success"
|
|
:end-val="homeStore.hotelData?.info?.occupancy_rate || 0"
|
|
/>
|
|
<span class="suffix">%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="occupancy">
|
|
<Title3 title="酒店入住率" />
|
|
</div>
|
|
<occupancy :list="homeStore.hotelData?.list" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import jamDuration from './jam-duration'
|
|
import jamCount from './jam-count'
|
|
import vacancy from './vacancy'
|
|
import occupancy from './occupancy'
|
|
import vehicleSource from './vehicle-source'
|
|
import countup from 'vue-countup-v3'
|
|
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
|
import { useHomeStore } from '@/stores/home'
|
|
|
|
const homeStore = useHomeStore()
|
|
|
|
const carMove = computed(() => {
|
|
return homeStore.carShipData?.car?.info.length > 3
|
|
})
|
|
const shipMove = computed(() => {
|
|
return homeStore.carShipData?.ship?.info.length > 3
|
|
})
|
|
|
|
const parkData = computed(() => {
|
|
return [{ data: homeStore.carStopInfoData.dataList.map((item) => item.value) }]
|
|
})
|
|
const parkXAxisData = computed(() => {
|
|
return homeStore.carStopInfoData.dataList.map((item) => item.name)
|
|
})
|
|
|
|
const congestionData = computed(() => {
|
|
return [{ data: homeStore.trafficInfoData.data.congestion.map((item) => item.value) }]
|
|
})
|
|
const congestionXAxisData = computed(() => {
|
|
return homeStore.trafficInfoData.data.congestion.map((item) => item.name)
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.box-3 {
|
|
margin-top: vh(120);
|
|
width: vw(774);
|
|
height: vh(956);
|
|
padding-left: vw(8);
|
|
box-sizing: border-box;
|
|
background-image: url('@/assets/images/bg-5.png');
|
|
background-size: 100% 100%;
|
|
.traffic-info {
|
|
height: vh(80);
|
|
}
|
|
.cell {
|
|
display: flex;
|
|
align-items: center;
|
|
.icon {
|
|
width: vw(64);
|
|
height: auto;
|
|
}
|
|
.countup-wrap {
|
|
color: #02f9fa;
|
|
font-size: vw(24);
|
|
font-weight: bold;
|
|
text-shadow: 0 0 9px #0096ff;
|
|
}
|
|
.label {
|
|
font-weight: 400;
|
|
font-size: vw(14);
|
|
margin-top: vh(10);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
}
|
|
.box {
|
|
width: vw(250);
|
|
height: vh(200);
|
|
margin-right: vw(8);
|
|
background-image: url('@/assets/images/bg-3.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.box-1 {
|
|
width: vw(250);
|
|
height: vh(200);
|
|
margin-right: vw(8);
|
|
background-image: url('@/assets/images/bg-3.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.icon {
|
|
width: vw(45);
|
|
height: auto;
|
|
}
|
|
.stop-box {
|
|
display: flex;
|
|
gap: vw(8);
|
|
|
|
& > div {
|
|
flex: 1;
|
|
height: vh(70);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-evenly;
|
|
background-image: url('@/assets/images/bg-4.png');
|
|
background-size: 100% 100%;
|
|
.label {
|
|
font-weight: 400;
|
|
font-size: vw(14);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
.value {
|
|
margin-top: vh(10);
|
|
font-weight: bold;
|
|
font-size: vw(24);
|
|
color: #ffffff;
|
|
}
|
|
.error {
|
|
color: #e21b1b;
|
|
}
|
|
.success {
|
|
color: #02f9fa;
|
|
}
|
|
}
|
|
}
|
|
.car-ship {
|
|
flex: 1;
|
|
& > div {
|
|
position: relative;
|
|
height: vh(114);
|
|
display: flex;
|
|
align-items: center;
|
|
background-image: url('@/assets/images/bg-4.png');
|
|
background-size: 100% 100%;
|
|
.car {
|
|
@extend .icon;
|
|
width: vw(352);
|
|
height: vw(70);
|
|
padding-left: vw(90);
|
|
margin-left: vw(10);
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
background-image: url('@/assets/images/icon-6.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.ship {
|
|
@extend .icon;
|
|
width: vw(352);
|
|
height: vw(70);
|
|
padding-left: vw(90);
|
|
margin-left: vw(10);
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
background-image: url('@/assets/images/icon-7.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
.label {
|
|
margin-bottom: vh(6);
|
|
font-weight: 400;
|
|
font-size: vw(14);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
.value {
|
|
font-weight: bold;
|
|
font-size: vw(24);
|
|
color: #02f9fa;
|
|
}
|
|
.unit {
|
|
font-weight: bold;
|
|
font-size: vw(14);
|
|
color: #02f9fa;
|
|
margin-top: vh(6);
|
|
}
|
|
.table {
|
|
position: absolute;
|
|
left: vw(160);
|
|
width: vw(226);
|
|
height: vh(96);
|
|
z-index: 2;
|
|
background: rgba(0, 150, 255, 0.17);
|
|
.header {
|
|
display: flex;
|
|
height: vh(18);
|
|
line-height: vh(18);
|
|
text-align: center;
|
|
background: rgba(0, 150, 255, 0.4);
|
|
& > div {
|
|
flex: 1;
|
|
font-weight: 400;
|
|
font-size: vw(12);
|
|
color: #fff;
|
|
}
|
|
}
|
|
.content {
|
|
overflow-y: hidden;
|
|
height: vh(82);
|
|
// /* 滚动条整体样式 */
|
|
// &::-webkit-scrollbar {
|
|
// width: vw(4); /* 滚动条的宽度 */
|
|
// }
|
|
// /* 滚动条轨道 */
|
|
// &::-webkit-scrollbar-track {
|
|
// background: 'transparent'; /* 轨道的背景色 */
|
|
// }
|
|
// /* 滚动条滑块 */
|
|
// &::-webkit-scrollbar-thumb {
|
|
// background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
|
|
// border-radius: 5px; /* 滑块的圆角 */
|
|
// }
|
|
}
|
|
.cell {
|
|
display: flex;
|
|
height: vh(27);
|
|
line-height: vh(27);
|
|
text-align: center;
|
|
background: #074686;
|
|
&:nth-child(odd) {
|
|
background: rgba(0, 150, 255, 0.1);
|
|
}
|
|
&:nth-child(even) {
|
|
background: #074686;
|
|
}
|
|
& > div {
|
|
flex: 1;
|
|
}
|
|
& > div:nth-child(1) {
|
|
font-weight: 400;
|
|
font-size: vw(14);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
& > div:nth-child(2) {
|
|
font-weight: bold;
|
|
font-size: vw(18);
|
|
color: #ffffff;
|
|
}
|
|
& > div:nth-child(3) {
|
|
font-weight: bold;
|
|
font-size: vw(18);
|
|
color: #02f9fa;
|
|
}
|
|
.unit-1 {
|
|
font-size: vw(12);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.hotel {
|
|
margin: 0 vw(6);
|
|
& > div:nth-child(1) {
|
|
display: flex;
|
|
width: vw(360);
|
|
height: vh(70);
|
|
background-image: url('@/assets/images/bg-4.png');
|
|
background-size: 100% 100%;
|
|
.item {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
.label {
|
|
font-weight: 400;
|
|
font-size: vw(14);
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
.value {
|
|
margin-top: vh(10);
|
|
font-weight: bold;
|
|
font-size: vw(24);
|
|
color: #ffffff;
|
|
}
|
|
.success {
|
|
color: #02f9fa;
|
|
}
|
|
.suffix {
|
|
margin-top: vh(10);
|
|
font-weight: bold;
|
|
font-size: vw(24);
|
|
color: #02f9fa;
|
|
color: #02f9fa;
|
|
}
|
|
}
|
|
}
|
|
& > div:nth-child(2) {
|
|
padding-top: vh(6);
|
|
margin-top: vh(6);
|
|
width: vw(360);
|
|
background-image: url('@/assets/images/bg-3.png');
|
|
background-size: 100% 100%;
|
|
}
|
|
}
|
|
}
|
|
.occupancy {
|
|
:deep(.title-3) {
|
|
margin-top: vh(6);
|
|
}
|
|
}
|
|
.title1 {
|
|
:deep(.title) {
|
|
width: vw(300) !important;
|
|
}
|
|
}
|
|
</style>
|