Files
fengjie-datascreen/src/views/home/components/box-1.vue
2025-02-22 12:59:47 +08:00

383 lines
10 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="box-2">
<Title1 title="景区信息" />
<div class="list flex pt-20">
<div class="item" v-for="(item, index) in homeStore.scenicData.scenicSpot" :key="index">
<img v-if="index == 0" class="item-icon" src="@/assets/images/core.png" />
<img v-if="index == 1" class="item-icon" src="@/assets/images/queue.png" />
<img v-if="index == 2" class="item-icon" src="@/assets/images/congestion.png" />
<span class="item-label">{{ item.name }}</span>
<div class="item-value flex align-end rela">
<countup :end-val="item.value" /><span class="unit"></span>
</div>
</div>
</div>
<div class="flex pt-20">
<div class="box">
<Title2 title="景区排队" />
<div class="statistic">
<div
class="statistic-item"
v-for="(item, index) in homeStore.scenicQueueData.info"
:key="index"
>
<span class="statistic-title">{{ item.name }}</span>
<span v-if="item.value > 0" class="statistic-value">
<span class="prefix">排队</span>
<countup class="value" :end-val="item.value" />
<span class="suffix"></span>
</span>
<span v-else class="statistic-value">{{ item.value }}</span>
</div>
</div>
<div class="flex rela">
<Title3 title="景区排队人数" />
</div>
<div class="pt-20">
<Line
:width="370"
:height="140"
:config="{ legend: false }"
:data="scenicQueueList"
:xAxisData="scenicQueueXAxisData"
/>
</div>
</div>
<div class="box">
<Title2 title="景区承载" />
<div class="statistic">
<div
class="statistic-item"
v-for="(item, index) in homeStore.scenicBearData.info"
:key="index"
>
<gauge :value="parseFloat(item.value)" />
<span class="statistic-title">{{ item.name }}</span>
</div>
</div>
<Title3 title="今日景区承载量" />
<div class="pt-20">
<Line
:width="370"
:height="140"
:config="{ legend: false }"
:data="scenicBearList"
:xAxisData="scenicBearXAxisData"
/>
</div>
</div>
</div>
<div class="ticket-box">
<Title2 title="景区购票" />
<div class="ticket-wrap">
<img src="@/assets/images/ticket.png" />
<div v-for="(item, index) in homeStore.scenicData.data" :key="index">
<span class="label">{{ item.name }}</span>
<countup :end-val="item.value" />
</div>
</div>
</div>
<Title1 title="游客画像" />
<div class="flex">
<div class="age-box">
<Title3 title="年龄/性别" />
<div class="mt-8">
<age :list="homeStore.userPortraitData?.ageRate" />
</div>
<div
class="cell pt-20"
v-for="(item, index) in homeStore?.userPortraitData.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="Number(item.value)"
:show-text="false"
:color="`linear-gradient( to right, ${
item.name == '男' ? '#074D90' : '#0A4482'
} 0%, ${item.name == '男' ? '#55E0FF' : '#FF7021'} 100%)`"
/>
</div>
<span class="man">{{ item.value }}%</span>
</div>
</div>
</div>
<div class="box-1">
<Title3 title="客源地TOP5" />
<RegionTop :list="homeStore.userPortraitData.provinceRate" :width="230" :height="260" />
</div>
<div class="box-1">
<Title3 title="购票渠道" />
<TicketSource :list="homeStore.userPortraitData.channel" :width="230" :height="230" />
</div>
</div>
</div>
</template>
<script setup>
import age from './age'
import gauge from './gauge'
import countup from 'vue-countup-v3'
import { useHomeStore } from '@/stores/home'
const homeStore = useHomeStore()
// 今日景区承载量
const scenicBearList = computed(() => {
return [{ data: homeStore.scenicBearData.dataList.map((item) => item.value) }]
})
const scenicBearXAxisData = computed(() => {
return homeStore.scenicBearData.dataList.map((item) => item.name)
})
// 今日景区排队量
const scenicQueueList = computed(() => {
return [{ data: homeStore.scenicQueueData.dataList.map((item) => item.value) }]
})
const scenicQueueXAxisData = computed(() => {
return homeStore.scenicQueueData.dataList.map((item) => item.name)
})
</script>
<style lang="scss" scoped>
.box-2 {
margin-top: vh(120);
width: vw(800);
height: vh(950);
padding: vw(8);
box-sizing: border-box;
background-image: url('@/assets/images/bg-2.png');
background-size: 100% 100%;
.dropdown {
position: absolute;
right: vw(8);
bottom: -30%;
z-index: 990;
}
.list {
height: vh(72);
}
.item {
position: relative;
height: vh(52);
margin: 0 vh(10);
flex: 1;
z-index: 1;
display: flex;
align-items: center;
background-size: 100% 100%;
&-icon {
position: absolute;
width: 100%;
height: auto;
z-index: -1;
}
&-label {
position: absolute;
left: vw(70);
top: vh(-10);
font-weight: 400;
font-size: vw(16);
color: #ffffff;
}
&-value {
position: absolute;
left: vw(70);
.countup-wrap {
color: #02f9fa;
font-size: vw(28);
font-weight: bold;
}
}
}
.unit {
color: #02f9fa;
font-size: vw(14);
margin-bottom: vh(4);
}
.box {
width: vw(384);
height: vh(320);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(10);
}
.statistic {
display: flex;
margin-top: vh(12);
width: 100%;
height: vh(88);
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;
}
&-title {
font-size: vw(16);
color: #fff;
}
&-value {
margin-top: vh(10);
font-weight: bold;
font-size: vw(20);
color: #02f9fa;
display: flex;
align-items: flex-end;
}
.value {
font-weight: bold;
font-size: vw(28);
color: #ff4400;
}
.prefix,
.suffix {
color: #ff4400;
font-size: vw(12);
margin-bottom: vh(4);
}
}
}
.age-box {
width: vw(320);
height: vh(296);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(1) {
margin-right: vw(8);
}
}
.box-1 {
width: vw(230);
height: vh(296);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
&:nth-child(2) {
margin-right: vw(8);
}
}
.count {
margin: vh(10) vw(20) 0 vw(20);
height: vh(24);
font-weight: bold;
font-size: vw(14);
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: auto;
margin-right: vw(4);
}
.text {
font-weight: 400;
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
}
.progress {
width: vw(150);
margin-left: vw(4);
:deep(.el-progress-bar__outer) {
background-color: #0858ae !important;
}
}
.man {
font-weight: bold;
font-size: vw(14);
color: #02f9fa;
margin-left: vw(10);
}
.woman {
font-weight: bold;
font-size: vw(14);
color: #f15a25;
margin-left: vw(10);
}
}
.ticket-box {
margin-top: vh(20);
width: 100%;
height: vh(106);
background: linear-gradient(to right, rgba(0, 77, 136, 0) 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(15);
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 {
margin-top: vh(8);
display: flex;
align-items: center;
justify-content: space-between;
& > img {
width: vw(74);
height: auto;
}
& > 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(14);
color: rgba(255, 255, 255, 0.9);
}
.countup-wrap {
color: #02f9fa;
font-size: vw(28);
font-weight: bold;
}
}
}
</style>