Files
fengjie-datascreen/src/views/home/components/box-3.vue
2026-01-06 14:33:52 +08:00

582 lines
17 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="95%"
:height="100"
:config="{ legend: false }"
:data="congestionData"
:xAxisData="congestionXAxisData"
/>
</div>
</div>
<div class="box">
<div class="pt-10">
<Title3 title="拥堵次数占比" />
<jam-count :text="'暂无拥堵'" :list="homeStore.trafficInfoData.data.countRate" />
</div>
</div>
<div class="box">
<div class="pt-10">
<Title3 title="拥堵时长" />
<jam-duration :text="'暂无拥堵'" :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,type3: item.type==2 }">
{{ 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="95%"
:height="94"
: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="停车场使用" />
<blcok v-if="splitList.length">
<el-carousel trigger="click" indicator-position="none" autoplay arrow="never" interval="5000">
<el-carousel-item v-for="(item,index) in splitList" :key="index">
<vacancy :list="item" />
</el-carousel-item>
</el-carousel>
</blcok>
</div>
</div>
</div>
<div class="flex" v-if="false">
<!-- <div class="flex-1">
<Title1 title="车船信息" class="title1" />
</div> -->
<div class="flex-1" >
<Title1 title="酒店信息" class="title1" />
</div>
</div>
<div class="flex" v-if="false">
<div class="car-ship" v-if="false">
<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 class="small-text">{{ 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 class="small-text">{{ 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 splitArray = (arr,len)=>{
let result = [];
for (let i = 0; i < arr.length; i += len) {
result.push(arr.slice(i, i + len));
}
return result;
}
const splitList = computed(()=>{
let splittedArrays = splitArray(homeStore.carStopInfoData.dataList2, 3);
return splittedArrays
})
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)
})
console.log(homeStore.carStopInfoData.spotInfo,'homeStore.carStopInfoData.spotInfo')
</script>
<style lang="scss" scoped>
.small-text{
font-size:vw(12);
}
.box-3 {
margin-top: vh(120);
width: vw(1200);
height:100%;
// height: vh(2056);
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(124);
height: auto;
}
.countup-wrap {
color: #02f9fa;
font-size: font-vw(24);
font-weight: bold;
text-shadow: 0 0 9px #0096ff;
}
.label {
font-weight: 400;
font-size: font-vw(18);
margin-top: vh(10);
color: rgba(255, 255, 255, 0.9);
}
}
.box {
width: 33%;
// height: vh(200);
margin-right: vw(8);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
}
.box-1 {
// width: vw(300);
flex:1;
height: vh(450);
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(120);
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: font-vw(16);
color: rgba(255, 255, 255, 0.9);
}
.value {
margin-top: vh(10);
font-weight: bold;
font-size: font-vw(22);
color: #ffffff;
}
.error {
color:#DCBB48;
}
.success {
color: #02F9FA;
// color:#E21B1B;
}
.type3{
color: #F75000;
}
}
}
.car-ship {
width:100%;
// flex: 1;
& > div {
position: relative;
height: vh(235);
display: flex;
align-items: center;
background-image: url('@/assets/images/bg-4.png');
background-size: cover;
.car {
@extend .icon;
width: vw(352);
height: vw(70);
padding-left: vw(90);
margin-left: vw(30);
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: font-vw(14);
color: rgba(255, 255, 255, 0.9);
}
.value {
font-weight: bold;
font-size: font-vw(22);
color: #02f9fa;
}
.unit {
font-weight: bold;
font-size: vw(14);
color: #02f9fa;
margin-top: vh(6);
}
.table {
position: absolute;
left: vw(200);
// width: vw(350);
width:80%;
// height: vh(196);
height:90%;
z-index: 2;
background: rgba(0, 150, 255, 0.17);
.header {
display: flex;
height: vh(48);
line-height: vh(48);
text-align: center;
background: rgba(0, 150, 255, 0.4);
& > div {
flex: 1;
font-weight: 400;
font-size: font-vw(20);
color: #fff;
// height: vh(50);
// line-height: vh(50);
}
}
.content {
overflow-y: hidden;
// height: vh(282);
// /* 滚动条整体样式 */
// &::-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(50);
// line-height: vh(50);
padding:vw(10);
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) {
overflow: hidden;
text-overflow: ellipsis;
display: block;
white-space: nowrap;
font-weight: 400;
font-size: font-vw(18);
color: rgba(255, 255, 255, 0.9);
}
& > div:nth-child(2) {
font-weight: bold;
font-size: font-vw(18);
color: #ffffff;
}
& > div:nth-child(3) {
font-weight: bold;
font-size: font-vw(18);
color: #02f9fa;
}
.unit-1 {
font-size: vw(18);
}
}
}
}
}
.hotel {
flex:1;
margin: 0 vw(6);
& > div:nth-child(1) {
display: flex;
// width: vw(360);
height: vh(100);
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: font-vw(18);
color: rgba(255, 255, 255, 0.9);
}
.value {
margin-top: vh(10);
font-weight: bold;
font-size: font-vw(20);
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>