Files
fengjie-datascreen/src/views/home/components/box-3.vue
2025-01-16 19:41:46 +08:00

539 lines
16 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="车源地" />
<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.vue'
import jamCount from './jam-count.vue'
import vacancy from './vacancy.vue'
import occupancy from './occupancy.vue'
import vehicleSource from './vehicle-source.vue'
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>