Files
fengjie-datascreen/src/views/scenic/components/box-2.vue
2026-01-15 14:30:57 +08:00

1275 lines
34 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="container">
<div class="flex">
<div class="box mr-8">
<Title1 title="排队信息" />
<div
style="cursor: pointer;"
class="count-box flex justify-between">
<count-item
label="今日入园人数"
:count="scenicStore.scenicQueueData.header.jrjdrs"
suffix="人"
@click="handlePop2()"
/>
<count-item
label="今日出园人数"
:count="scenicStore.scenicQueueData.header.jrjdcy"
suffix="人"
@click="handleLineUp()"
/>
<count-item
label="排队人数"
:count="scenicStore.scenicQueueData.header.pdrs"
:color="scenicStore.scenicQueueData.header.pdrs_type == 0 ? '' : '#E21B1B'"
suffix="人"
@click="handleLineUp()"
/>
</div>
<div class="border">
<div class="pt-10">
<Title3 title="景区排队人数" />
</div>
<Line
width="100%"
:height="145"
:data="scenicQueueData"
:xAxisData="scenicQueueXAxisData"
/>
</div>
</div>
<div class="box box-9 mr-8">
<Title1 title="景区承载" />
<div
style="cursor: pointer;"
class="count-box flex justify-between">
<circle-progress
:width="70"
:height="35"
:value="scenicStore.scenicBearData.header.jqRate"
:title="`${scenicStore.scenicBearData.header.jqRate}%`"
subTitle="景区承载率"
/>
<div class="flex flex-1 justify-center" style="text-align: center;">
<count-item
label="景区当前在园人数"
:count="scenicStore.scenicBearData.header.jrjdrs"
suffix="人"
/>
<count-item
label="景区最大承载"
:count="scenicStore.scenicBearData.header.jqzdcz"
suffix="人"
/>
</div>
</div>
<div class="border">
<div class="pt-10">
<Title3 title="今日景区承载量" />
</div>
<Line
width="100%"
:height="145"
:data="scenicBearData"
:xAxisData="scenicBearXAxisData"
/>
</div>
</div>
<div class="box-1 mr-8" v-if="false" style="padding: 0;">
<Title1 title="停车信息" />
<div class="">
<div class=" flex flex-1">
<circle-progress
v-for="(item, index) in garageList"
:key="index"
:width="80"
:height="50"
:value="parseFloat(item.rate)"
:title="item.occupied"
:subTitle="`${item.name}`"
/>
</div>
<div class="ml-20 mb-10 flex flex-1 justify-between">
<count-item label="总停车场" :count="scenicStore.stopCarData.info.count" suffix="个" />
<count-item
label="剩余车位数"
:count="scenicStore.stopCarData.info.occupiedSpaces"
suffix="个"
/>
</div>
</div>
<div class="flex">
<div class="border mr-8 flex-1">
<div class="pt-10">
<Title3 title="今日景区车流量" />
</div>
<Line width="100%" :height="105" :data="carBearData" :xAxisData="carBearXAxisData" />
</div>
<div class="border flex-1">
<div class="pt-10">
<Title3 title="车辆归属地占比" />
</div>
<PieRow
label="今日停车累计"
:dataList="dataLists"
:total="carTotal"
width="100%"
:height="110"
/>
</div>
</div>
</div>
<div class="box-2">
<Title1 title="异常信息 " />
<!-- @click="handleToWorkOrder" -->
<div style="cursor: pointer;" class="count-box flex">
<count-item
v-for="item in headList"
:label="item.name"
:count="item.count"
:type="item.type"
:color="item.type == 0 ? '#0096FF' : '#E21B1B'"
suffix="次"
/>
</div>
<div class="border flex-1">
<div class="pt-10">
<Title3 title="异常告警占比" />
</div>
<PieRow
label="告警总数"
:dataList="scenicStore?.secureData.dataList"
:total="alarmTotal"
width="100%"
:height="145"
/>
</div>
</div>
</div>
<div class="flex mt-8" >
<div class="box-3 mr-8" >
<div class="look-box">
<Title1 title="交通信息" />
<div @click="hanldeLookMap" class="look-btn">查看详情</div>
</div>
<div class="count-box flex">
<count-item
v-for="(item, index) in scenicStore.trafficData.infoList"
:key="index"
:label="item.name"
:count="item?.value || 0"
/>
</div>
<div class="flex">
<div class="border mr-8">
<Title3 title="今日交通负载" />
<traffic-flow :list="scenicStore.trafficData.data.congestion" />
</div>
<div class="border mr-8">
<Title3 title="拥堵次数占比" />
<jam
width="100%"
:height="200"
sub-title="拥堵频次总数"
:list="scenicStore.trafficData.data.countRate"
:text="'暂无拥堵'"
/>
</div>
<div class="border">
<Title3 title="拥堵时长占比" />
<jam
:text="'暂无拥堵'"
width="100%"
:height="200"
sub-title="拥堵总时长(分钟)"
:list="scenicStore.trafficData.data.timeRate"
/>
</div>
</div>
</div>
<div class="box-4 mr-8">
<Title1 title="用户画像" />
<div class="flex" style="height: 90%;">
<div class="border mr-8 flex-1">
<Title3 title="年龄/性别占比" />
<age :list="scenicStore.userPortraitData.data.ageRate" />
<div
class="cell pt-20"
v-for="(item, index) in scenicStore.userPortraitData.data.genderRate"
:key="index"
>
<img v-if="item.name == '男'" class="icon" src="@/assets/images/man.png" />
<img v-if="item.name == '女'" class="icon" src="@/assets/images/woman.png" />
<div class="bg">
<span class="text">{{ item.name }}</span>
<div class="progress">
<el-progress
:percentage="parseFloat(item.value)"
:show-text="false"
:color="
item.name == '女'
? 'linear-gradient( to right, #0A4482 0%, #FF7021 100%)'
: 'linear-gradient( to right, #074D90 0%, #55E0FF 100%)'
"
/>
</div>
<span :class="[item.name == '男' ? 'man' : 'woman']">{{ item.value }}%</span>
</div>
</div>
</div>
<div class="border mr-8 flex-1">
<Title3 title="客源地分析TOP5" />
<RegionTop
:list="scenicStore.userPortraitData.data.provinceRate"
width="100%"
:height="220"
/>
</div>
<div class="border flex-1">
<Title3 title="购票来源" />
<TicketSource
:list="scenicStore.userPortraitData.data.channel"
width="100%"
:height="200"
/>
</div>
</div>
</div>
<div class="box-5">
<Title1 title="车船信息" />
<div class="flex mb-6">
<div class="border mr-8 pt-10 pb-10">
<div class="flex justify-between">
<Title2 title="景区车辆" />
<div class="sum">
<span>总数</span>
<countup
:end-val="
scenicStore.carShipData.car.count?.drivingCount +
scenicStore.carShipData.car.count?.nonDrivingCount
"
/>
</div>
</div>
<div class="car-box mt-10">
<img class="icon" src="@/assets/images/icon-6.png" />
<div class="car-item pr-20">
<div class="label">运营车辆</div>
<div class="value flex">
<countup :end-val="scenicStore.carShipData.car.count?.drivingCount" />
<span class="suffix"> </span>
</div>
</div>
<div class="car-item">
<div class="label">空闲车辆</div>
<div class="value flex">
<countup :end-val="scenicStore.carShipData.car.count?.nonDrivingCount" />
<span class="suffix"> </span>
</div>
</div>
</div>
</div>
<div class="border pt-10 pb-10">
<div class="flex justify-between">
<Title2 title="景区船只" />
<div class="sum">
<span>总数</span>
<countup
:end-val="
scenicStore.carShipData.ship.count?.drivingCount +
scenicStore.carShipData.ship.count?.nonDrivingCount
"
/>
</div>
</div>
<div class="car-box mt-10">
<img class="icon" src="@/assets/images/icon-7.png" />
<div class="car-item pr-20">
<div class="label">运营船只</div>
<div class="value flex">
<countup :end-val="scenicStore.carShipData.ship.count?.drivingCount" />
<span class="suffix"></span>
</div>
</div>
<div class="car-item">
<div class="label">空闲船只</div>
<div class="value flex">
<countup :end-val="scenicStore.carShipData.ship.count?.nonDrivingCount" />
<span class="suffix"></span>
</div>
</div>
</div>
</div>
</div>
<div class="border pt-10 pb-10">
<div id="car-ship" class="car-ship" />
<img class="full" src="@/assets/images/full.png" @click="show = true" />
</div>
</div>
</div>
<el-dialog :title="'徒步客流统计'" center v-model="dialogTableVisible2">
<div class="bom-box">
<div class="table">
<div class="header-title">{{gridTitle}}</div>
<div class="header">
<div @click="handleTabPassFlow(0)" :class="hIndex==0?'h-active':''" >路段</div>
<div @click="handleTabPassFlow(1)" :class="hIndex==1?'h-active':''">点位</div>
</div>
<div class="list">
<div class="item">
<div>名称</div>
<div>进入</div>
<div>离开</div>
<div>保有量</div>
</div>
<div class="item" v-if="hIndex==0" v-for="(item, index) in tjArr.groups" :key="index">
<div>{{ item.title }}</div>
<div>{{ item.enter }}</div>
<div>{{ item.exit }}</div>
<div>{{ item.holdValue }}</div>
</div>
<div class="item" v-if="hIndex==1" v-for="(item, index) in tjArr.single" :key="index">
<div>{{ item.title }}</div>
<div>{{ item.enter }}</div>
<div>{{ item.exit }}</div>
<div>{{ item.holdValue }}</div>
</div>
</div>
</div>
</div>
</el-dialog>
</div>
<big-map
v-model="show"
:carList="scenicStore.carShipData.car.list"
:shipList="scenicStore.carShipData.ship.list"
/>
<traMap :longitude="longitude" :latitude="latitude" v-model="traMapShow"></traMap>
<all-list :events="scenicSpotId" v-model="allShow" />
</template>
<script setup>
import countup from 'vue-countup-v3'
import PubSub from 'pubsub-js'
import allList from './allList'
import carIcon from '@/assets/images/car.png'
import carStopIcon from '@/assets/images/car-stop.png'
import carOfflineIcon from '@/assets/images/car-offline.png'
import {getSpotPassengerFlow} from "@/api/home.js";
import shipIcon from '@/assets/images/ship.png'
import shipStopIcon from '@/assets/images/ship-stop.png'
import shipOfflineIcon from '@/assets/images/ship-offline.png'
import age from './age'
import jam from './jam'
import BigMap from './big-map'
import traMap from './tra-map'
import TrafficFlow from './traffic-flow'
import { useRouter } from 'vue-router'
import { useMap } from '@/hooks/map'
import { useScenicStore } from '@/stores/scenic'
let props = defineProps({
scenicSpotId: {
type: String,
default: () => ''
}
})
const router = useRouter()
const scenicStore = useScenicStore()
const { initMap, addMarker, marker } = useMap()
//景区排队
let allShow = ref(false)
let events = ref({})
const handleLineUp = (item)=>{
allShow.value = true
events.value = item
}
let dialogTableVisible2 = ref(false)
let tjArr = ref([])
let hIndex = ref(0)
const handleTabPassFlow = (index)=>{
hIndex.value = index;
}
const handlePop2 = async()=>{
dialogTableVisible2.value = true
let res = await getSpotPassengerFlow({scenicSpotId:props.scenicSpotId})
tjArr.value = res.data
console.log(res,'res')
}
let show = ref(false)
let scenicChange = null
let carOverlays = ref([])
let shipOverlays = ref([])
let traMapShow = ref(false)
//查看交通信息
let latitude = ref('')
let longitude = ref('')
const hanldeLookMap = () => {
router.push('/traffic')
// traMapShow.value = true
}
const handleToWorkOrder = () => {
router.push('/workOrder')
}
const garageList = computed(() => {
return scenicStore.stopCarData.headList
})
const alarmTotal = computed(() => {
return scenicStore.secureData.dataList.reduce((pre, cur) => {
return pre + cur.count
}, 0)
})
const stopCarDataLists = computed(() => {
return scenicStore.stopCarData.dataLists
})
const carTotal = computed(() => {
return dataLists.value.reduce((pre, cur) => {
return pre + parseInt(cur.count)
}, 0)
})
const carBearData = computed(() => {
return [{ data: scenicStore.stopCarData.dataList.map((item) => item.value) }]
})
const carBearXAxisData = computed(() => {
return scenicStore.stopCarData.dataList.map((item) => item.name)
})
const scenicBearData = computed(() => {
return [{ data: scenicStore.scenicBearData.dataList.map((item) => item.value) }]
})
const scenicBearXAxisData = computed(() => {
return scenicStore.scenicBearData.dataList.map((item) => item.name)
})
const scenicQueueData = computed(() => {
return [{ data: scenicStore.scenicQueueData.dataList.map((item) => item.value) }]
})
const scenicQueueXAxisData = computed(() => {
return scenicStore.scenicQueueData.dataList.map((item) => item.name)
})
let dataLists = ref([])
watch(
() => scenicStore.stopCarData.dataLists,
(val) => {
console.log(val.length, 'watch 监听')
if (val.length) {
dataLists.value = val
} else {
dataLists.value = []
}
},
{ immediate: true }
)
let headList = ref([])
watch(
() => scenicStore.secureData.headList,
(val) => {
if (val.length) {
headList.value = scenicStore.secureData.headList
} else {
headList.value = []
}
},
{ immediate: true }
)
watch(
() => scenicStore.carShipData,
(val) => {
return false
setTimeout(() => {
if (carOverlays.value.length > 0) {
for (let i = 0; i < carOverlays.value.length; i++) {
for (let j = 0; j < val.car.list.length; j++) {
if (carOverlays.value[i].sim == val.car.list[j].sim) {
carOverlays.value[i].setPosition({
lng: val.car.list[j].lng,
lat: val.car.list[j].lat
})
continue
}
}
}
} else {
val.car.list.map((item, i) => {
if (item.status == '行驶') {
addMarker(carIcon, [item.lng, item.lat], [36, 50])
}
if (item.status == '离线') {
addMarker(carOfflineIcon, [item.lng, item.lat], [36, 50])
}
if (item.status == '静止') {
addMarker(carStopIcon, [item.lng, item.lat], [36, 50])
}
carOverlays.value[i] = marker.value
})
}
if (shipOverlays.value.length > 0) {
for (let i = 0; i < shipOverlays.value.length; i++) {
for (let j = 0; j < val.ship.list.length; j++) {
if (carOverlays.value[i].sim == val.ship.list[j].sim) {
carOverlays.value[i].setPosition({
lng: val.ship.list[j].lng,
lat: val.ship.list[j].lat
})
continue
}
}
}
} else {
val.ship.list.map((item, i) => {
if (item.status == '行驶') {
addMarker(shipIcon, [item.lng, item.lat], [36, 50])
}
if (item.status == '离线') {
addMarker(shipOfflineIcon, [item.lng, item.lat], [36, 50])
}
if (item.status == '静止') {
addMarker(shipStopIcon, [item.lng, item.lat], [36, 50])
}
shipOverlays.value[i] = marker.value
})
}
}, 1000)
},
{ immediate: true }
)
onMounted(() => {
scenicChange = PubSub.subscribe('scenicChange', (msg, data) => {
latitude.value = data.lat
longitude.value = data.lng
carOverlays.value = []
shipOverlays.value = []
initMap('car-ship', data.lng, data.lat, 15)
})
})
onUnmounted(() => {
PubSub.unsubscribe(scenicChange)
})
</script>
<style scoped lang="scss">
.h-active{
background-color: #fff;
color:#0063ff;
}
.coll-box{
flex:1 !important;
}
.box-1 {
// margin-top: vh(120);
width: vw(900);
// height: vh(950);
padding: vw(10);
box-sizing: border-box;
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
.header {
display: flex;
margin-top: vh(10);
&__left {
display: flex;
align-items: center;
margin-right:vw(10);
cursor:pointer;
> img {
width: vw(74);
height: auto;
}
}
&__left-item {
position: relative;
width: vw(120);
height: vh(58);
padding-left: vw(10);
display: flex;
flex-direction: column;
justify-content: center;
background-image: url('@/assets/images/ticket-item-bg.png');
background-size: 100% 100%;
// margin-left:vw(30);
.label {
position: absolute;
top: vh(-4);
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: #ffffff;
left:vw(0)
}
}
& > div:nth-child(2) {
flex: 1;
display: flex;
justify-content: space-between;
.label {
font-weight: 400;
font-size: vw(19.2); /* 16×1.2 */
color: #ffffff;
}
.value {
font-weight: bold;
font-size: vw(33.6); /* 28×1.2 */
color: #02f9fa;
text-align: center;
line-height: vh(60);
}
.warning {
color:#DCBB48;;
}
.error {
color: #ff4400;
}
}
.countup-wrap {
color: #02f9fa;
font-size: vw(33.6); /* 28×1.2 */
font-weight: bold;
}
}
.main {
width: 100%;
height: vh(600);
overflow-x: auto;
overflow-y: hidden;
position:relative;
.look-btn{
cursor: pointer;
position: absolute;
right: vw(20);
top: 6%;
transform: translateY(-50%);
padding: vw(20);
display: flex;
align-items: center;
background: #0a4190;
border-radius: vw(4);
font-size: font-vw(18); /* 16×1.2 */
font-weight:700;
color: #fff;
z-index: 999;
img{
width:vw(100);
// height:;
}
}
.scenic-box {
width: 100%;
height: 100%;
}
/* 滚动条整体样式 */
&::-webkit-scrollbar {
height: vh(10); /* 滚动条的宽度 */
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background: 'transparent'; /* 轨道的背景色 */
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
> img {
width: auto;
height: 100%;
}
}
.footer {
.item {
flex: 1;
height: vh(140);
display: flex;
align-items: center;
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
.bg {
padding-left: vw(20);
width: vw(243);
height: vh(40);
display: flex;
align-items: center;
background: linear-gradient(90deg, rgba(0, 150, 255, 0.34) 0%, rgba(0, 150, 255, 0) 100%);
&:nth-child(1) {
margin-bottom: vh(4);
}
.label {
width: vw(120);
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: #fff;
}
.value {
font-weight: bold;
font-size: vw(33.6); /* 28×1.2 */
color: #fff;
}
.success {
color: #02f9fa;
}
.error {
color: #e21b1b;
}
}
}
.list {
margin-top: vh(4);
height: vh(116);
overflow: hidden;
}
.cell {
display: flex;
margin-left: vw(4);
margin-top: vh(12);
&:nth-last-child(1) {
margin-bottom: 0;
}
.tag {
padding: 0 vw(16);
font-weight: bold;
font-size: vw(16.8); /* 14×1.2 */
color: #fff;
display: flex;
align-items: center;
justify-content: center;
border-radius: vw(2);
}
.tag--important {
@extend .tag;
background: #feae00;
}
.tag--warn {
@extend .tag;
background: #d9011b;
}
.tag--normal {
@extend .tag;
background: #2380fb;
}
.content {
margin-left: vw(4);
padding: 0 vw(10);
width: vw(760);
height: vh(24);
line-height: vh(24);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: #ffffff;
border-radius: vw(2);
background: rgba(0, 150, 255, 0.28);
}
}
.more {
cursor: pointer;
width: auto;
height: vh(100);
margin-top: vh(12);
}
}
}
</style>
<style lang="scss" scoped>
:deep(.el-dialog__headerbtn .el-dialog__close){
color:#fff;
font-size:48px; /* 40×1.2 */
position:relative;
top:15px;
right:15px;
}
:deep(.el-dialog__header.show-close){
padding-right:0;
}
:deep(.el-dialog) {
background: url('/src/assets/images/map-bg-2.png') no-repeat top center;
background-size: 100% 100%;
width:vw(1500);
}
:deep(.el-dialog__title) {
color: #fff;
font-weight: bold;
font-size: vw(38.4); /* 32×1.2 */
}
.sp-ico {
width: vw(40);
}
.item-name {
width: 90%;
text-align: center;
}
.sp-img {
width: vw(100);
}
.correspondence {
margin: vw(8);
width: vw(300);
height: vh(1070);
background-image: url('@/assets/images/bg-1.png');
background-size: 100% 100%;
}
.bom-box2{
// margin-top:vh(10);
min-width:vw(900);
height:vh(800);
}
.header-title{
font-size:vw(38.4); /* 32×1.2 */
color:#fff;
text-align:center;
font-weight:bold;
margin-bottom:vh(20);
}
.bom-box {
.table2{
width:100%;
height:vh(740);
}
.table {
width: 100%;
margin-top: vh(5);
.header {
height: vh(28);
font-weight: 400;
font-size: vw(28.8); /* 24×1.2 */
color: #fff;
display: flex;
background: linear-gradient(180deg, rgba(0, 99, 255, 0) 0%, #0063ff 100%);
& > div {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
}
.list {
overflow-y: auto;
height: vh(490);
/* 滚动条整体样式 */
&::-webkit-scrollbar {
width: vw(4); /* 滚动条的宽度 */
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background: 'transparent'; /* 轨道的背景色 */
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
.item {
height: vh(50);
font-weight: 400;
font-size: vw(28.8); /* 24×1.2 */
color: #f1f7ff;
display: flex;
&:nth-child(2n + 1) {
background: linear-gradient(
90deg,
rgba(0, 150, 255, 0) 0%,
rgba(0, 150, 255, 0.22) 100%
);
}
& > div {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
white-space: nowrap; /* 保证文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示文本溢出 */
}
}
}
}
.title {
span {
margin-left: vw(30);
font-weight: 800;
font-size: vw(18); /* 15×1.2 */
line-height: vh(26);
text-align: center;
font-style: normal;
text-transform: none;
background: linear-gradient(90deg, #ffffff 0%, #5cb5ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
}
}
.top-box {
width: 100%;
height: vh(500);
.icon-box {
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: #ffffff;
line-height: vh(16);
flex-wrap: wrap;
.item {
cursor: pointer;
width: 50%;
margin-top: vh(40);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&:nth-child(3n) {
margin-right: 0;
}
& > img {
width: vw(54);
height: auto;
}
}
}
.title {
width: vw(260);
height: vh(26);
text-align: center;
line-height: vh(26);
margin-left: vw(32.5);
font-size: vw(19.2); /* 16×1.2 */
font-weight: 800;
color: #fff;
background-image: url('@/assets/images/title-1.png');
background-size: 100% 100%;
}
}
</style>
<style scoped lang="scss">
.null-box {
width: vw(360);
height: vh(300);
display: flex;
align-items: center;
color: #fff;
text-align: center;
font-size: vw(24); /* 20×1.2 */
justify-content: center;
}
.look-box {
position: relative;
.look-btn {
cursor: pointer;
position: absolute;
right: vw(20);
top: 50%;
transform: translateY(-50%);
padding: vw(12);
display: flex;
align-items: center;
background: #0a4190;
border-radius: vw(4);
font-size: font-vw(18); /* 14×1.2 */
color: #fff;
}
}
:deep(.BMap_cpyCtrl) {
display: none;
}
:deep(.anchorBL) {
display: none;
}
.height70 {
height: vh(70);
}
.legend {
display: flex;
align-items: center;
justify-content: center;
@mixin icon($column) {
width: vw(50);
height: vh(60);
display: flex;
flex-direction: $column;
align-items: center;
justify-content: center;
}
&__wrapper {
display: flex;
flex-wrap: wrap;
gap: vw(8);
width: vw(170);
}
&-item {
color: #fff;
}
&-item:nth-child(1) {
@include icon(column);
background-image: url('@/assets/images/legend-item-1.png');
background-size: 100% 100%;
}
&-item:nth-child(2) {
@include icon(column);
background-image: url('@/assets/images/legend-item-1.png');
background-size: 100% 100%;
}
&-item:nth-child(3) {
@include icon(column);
background-image: url('@/assets/images/legend-item-1.png');
background-size: 100% 100%;
}
&-item:nth-child(4) {
@include icon(column-reverse);
background-image: url('@/assets/images/legend-item-2.png');
background-size: 100% 100%;
}
&-item:nth-child(5) {
@include icon(column-reverse);
background-image: url('@/assets/images/legend-item-2.png');
background-size: 100% 100%;
}
&-item:nth-child(6) {
@include icon(column-reverse);
background-image: url('@/assets/images/legend-item-2.png');
background-size: 100% 100%;
}
&-item-label {
font-weight: 400;
font-size: vw(14.4); /* 12×1.2 */
line-height: vh(14);
}
&-item-value {
font-weight: bold;
font-size: vw(19.2); /* 16×1.2 */
line-height: vh(18);
}
}
.container {
margin: vh(120) 0 0 vw(10);
flex:1;
.count-box {
padding: 0 vw(10);
height: vh(150);
}
.bg {
background: linear-gradient(321deg, #0b2f64 0%, #062b57 100%);
}
.border {
position: relative;
padding: 0 vw(10);
box-sizing: border-box;
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
flex:1;
}
.box {
@extend .bg;
// width: vw(650);
height: vh(880);
min-width: vw(800);
flex:1;
}
.box-9{
// width: vw(750);
}
.box-1 {
@extend .bg;
// height: vh(475);
}
.box-2 {
@extend .bg;
height: vh(880);
flex:1;
}
.box-3 {
@extend .bg;
flex:1;
// width: vw(750);
// height: vh(465);
}
.box-4 {
@extend .bg;
flex:1;
// height: vh(465);
}
.box-5 {
// width: vw(750);
@extend .bg;
// height: vh(465);
height:100%;
flex:1;
}
.car-box {
// width: vw(316);
height: vh(120);
display: flex;
align-items: center;
.icon {
position: absolute;
// width: vw(350);
height: vw(100);
}
.car-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
&:nth-child(2) {
padding-left: vw(80);
}
}
.label {
font-weight: 400;
font-size: vw(24); /* 20×1.2 */
color: #fff;
}
.value {
font-weight: bold;
font-size: vw(33.6); /* 28×1.2 */
color: #02f9fa;
margin-top: vh(10);
align-items: flex-end;
}
.suffix {
font-size: vw(14.4); /* 12×1.2 */
color: #02f9fa;
margin-bottom: vw(4);
}
}
.sum {
font-weight: bold;
font-size: vw(26.4); /* 22×1.2 */
color: #02f9fa;
display: flex;
align-items: center;
}
.car-ship {
// width: vw(660);
width: 100%;
height: vh(780);
}
.full {
cursor: pointer;
position: absolute;
right: vw(20);
bottom: vw(20);
width: vw(50);
z-index: 999;
}
.count {
margin: vw(20) vw(20) 0 vw(20);
height: vh(24);
font-weight: bold;
font-size: vw(16.8); /* 14×1.2 */
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border-left: vw(4) solid #37d8fc;
border-right: vw(4) solid #37d8fc;
background: rgba(0, 150, 255, 0.19);
}
.cell {
margin-left: vw(10);
display: flex;
align-items: center;
.bg {
display: flex;
align-items: center;
height: vh(20);
padding-right: vw(10);
background: linear-gradient(to right, rgba(0, 150, 255, 0), rgba(0, 150, 255, 0.17) 100%);
}
.icon {
width: vw(26);
height: vw(28);
margin-right: vw(4);
}
.text {
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: rgba(255, 255, 255, 0.9);
}
.progress {
width: vw(110);
margin-left: vw(4);
}
.man {
font-weight: bold;
font-size: vw(16.8); /* 14×1.2 */
color: #02f9fa;
margin-left: vw(10);
}
.woman {
font-weight: bold;
font-size: vw(16.8); /* 14×1.2 */
color: #f15a25;
margin-left: vw(10);
}
}
.ticket-box {
margin-top: vh(20);
width: 100%;
height: vh(106);
background-color: radial-gradient(to right, #0a4190 0%, rgba(0, 77, 136, 0.6) 100%);
.title {
width: vw(253);
height: vh(28);
display: flex;
align-items: center;
background-image: url('@/assets/images/title-5.png');
background-size: 100% 100%;
& > span {
padding-left: vw(22);
font-weight: bold;
font-size: vw(18); /* 15×1.2 */
background-image: linear-gradient(to bottom, #ffffff 0%, #75c1ff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
color: transparent; /* 兼容其他浏览器 */
}
}
}
.ticket-wrap {
display: flex;
align-items: center;
justify-content: space-between;
& > img {
width: vw(74);
height: vh(74);
}
& > div {
flex: 1;
height: vh(58);
display: flex;
align-items: center;
background-image: url('@/assets/images/ticket-item-bg.png');
background-size: 100% 100%;
}
.label {
padding-left: vw(10);
font-weight: 400;
font-size: vw(16.8); /* 14×1.2 */
color: rgba(255, 255, 255, 0.9);
}
.countup-wrap {
color: #02f9fa;
font-size: vw(33.6); /* 28×1.2 */
font-weight: bold;
}
}
}
</style>