Files
fengjie-datascreen/src/views/home/components/box-2.vue
2025-01-26 01:27:56 +08:00

549 lines
16 KiB
Vue

<template>
<div class="box-3">
<div class="header">
<div class="flex">
<div class="left">
<div class="item">
<div class="label">今年总游客数</div>
<scroll-number :count="homeStore.visitorInfoData.total_count_this_year" prefix="1" />
</div>
<div class="item">
<div class="label">全县景区总游客人数</div>
<scroll-number :count="homeStore.visitorInfoData.total_count_today" prefix="2" />
</div>
<div class="item">
<div class="label">总在园人数</div>
<scroll-number
:count="homeStore.visitorInfoData.total_count_today_within_three_hours"
prefix="3"
/>
</div>
</div>
<div class="right">
<div class="item" v-for="(item, index) in homeStore.visitorInfoList" :key="index">
<div class="label">{{ item.name }}</div>
<div :class="[item.type == 1 ? 'value--error' : 'value--primary']">{{
item.value
}}</div>
</div>
</div>
</div>
</div>
<div class="rela">
<div class="alarm-box">
<ul class="flex">
<li class="alarm-item" v-for="(item, index) in list" :key="index">
<img class="icon" :src="item.icon" />
<span>{{ item.label }}</span>
</li>
</ul>
</div>
<div class="map" id="map" />
<!-- <div class="spot-wrap">
<ul class="spot-list">
<li
class="spot-item"
v-for="(item, index) in spotList"
:key="index"
@click="handleMap(item.scenicSpotId)"
>
<img :src="`http://36.138.38.16:8001/fjtcc-api${item.img}`" />
</li>
</ul>
</div> -->
</div>
<div class="footer">
<div class="left">
<div>
<div class="flex justify-center pt-10">
<div class="item">
<p class="label">今日工单总条数</p>
<countup :end-val="homeStore.wordkOrderData.toDayData.count" />
</div>
<div class="item">
<p class="label">工单完成数</p>
<countup class="complete" :end-val="homeStore.wordkOrderData.toDayData.end" />
</div>
</div>
<div class="progress-box">
<span class="text">工单完成数</span>
<div class="progress-1">
<el-progress
:percentage="parseFloat(homeStore.wordkOrderData.toDayData.rate)"
:show-text="false"
/>
</div>
<span class="value">{{ homeStore.wordkOrderData.toDayData.rate }}%</span>
</div>
</div>
<div>
<div class="flex justify-center pt-10">
<div class="item">
<p class="label">紧急工单数</p>
<countup class="error" :end-val="homeStore.wordkOrderData.warnData.count" />
</div>
<div class="item">
<p class="label">紧急工单完成数</p>
<countup class="complete" :end-val="homeStore.wordkOrderData.warnData.end" />
</div>
</div>
<div class="progress-box">
<span class="text">工单完成数</span>
<div class="progress-2">
<el-progress
:percentage="parseFloat(homeStore.wordkOrderData.warnData.rate)"
:show-text="false"
/>
</div>
<span class="value">{{ homeStore.wordkOrderData.warnData.rate }}%</span>
</div>
</div>
</div>
<div>
<vue3-seamless-scroll
class="right"
:list="homeStore.wordkOrderList"
:limitScrollNum="3"
:hover="true"
:step="0.2"
:wheel="true"
:isWatch="true"
>
<div class="item" v-for="(item, index) in homeStore.wordkOrderList" :key="index">
<span :class="`item-tag--${item.level}`">{{ item.level_text }}</span>
<p class="content">
{{ item.title }}
</p>
</div>
</vue3-seamless-scroll>
</div>
</div>
</div>
</template>
<script setup>
import countup from 'vue-countup-v3'
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
import ScrollNumber from '@/components/ScrollNumber/index.vue'
import { getSpotListApi, getBaiduMapApi, getBaiduMapCrowdedApi } from '@/api/home'
import icon8 from '@/assets/images/icon-8.png'
import icon9 from '@/assets/images/icon-9.png'
import icon10 from '@/assets/images/icon-10.png'
import icon11 from '@/assets/images/icon-11.png'
import carIcon from '@/assets/images/car.png'
import shipIcon from '@/assets/images/ship.png'
import { useMap } from '@/hooks/map'
import { useHomeStore } from '@/stores/home'
const homeStore = useHomeStore()
let emit = defineEmits(['switch-spot'])
const { map, initMap, addMarker } = useMap()
let spotList = ref([])
let list = ref([
{
label: '安全异常',
icon: icon8
},
{
label: '排队异常',
icon: icon9
},
{
label: '停车异常',
icon: icon10
},
{
label: '舆论异常',
icon: icon11
}
])
let current = ref(0)
watch(
() => [map.value, homeStore.carShipData],
() => {
if (map.value && homeStore.carShipData) {
homeStore.carShipData?.car?.list.map((item) => {
if (item.lng && item.lat) {
addMarker(carIcon, [item.lng, item.lat], [36, 50])
}
})
homeStore.carShipData?.ship?.list.map((item) => {
if (item.lng && item.lat) {
addMarker(shipIcon, [item.lng, item.lat], [36, 50])
}
})
}
},
{
immediate: true
}
)
const handleMap = (e) => {
emit('switch-spot', e)
// map.value.centerAndZoom(new BMapGL.Point('108.704166', '30.94776'), 16)
}
const getSpotList = async () => {
let res = await getSpotListApi()
spotList.value = res.data
getBaiduMap()
}
const getBaiduMap = async () => {
let res = await getBaiduMapApi({
nodeid: 7162
})
initMap('map', res.data.index.lng, res.data.index.lat, 15, false)
map.value.setMapStyleV2({
styleId: 'd1e61f575b3ef4e2df71ab6a5690ddab' // 23c9fb8e1c604995f97f0f1cebd7036fF
})
res.data.list.map((item) => {
item.map((i) => {
// 创建折线
let arr = []
i.path.map((j) => {
arr.push(new BMapGL.Point(j[0], j[1]))
})
var polyline = new BMapGL.Polyline(arr, {
strokeColor: '#9AFF02',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(polyline)
})
})
// getBaiduMapCrowded()
}
const getBaiduMapCrowded = async () => {
let res = await getBaiduMapCrowdedApi({
nodeid: spotList.value[current.value].nodeid
})
let data = res.data
if (data) {
data.forEach((bmci) => {
let linkStates = JSON.parse(bmci.link_states)
for (let key in linkStates) {
let bmciArr = []
if (linkStates.hasOwnProperty(key)) {
let bm = []
if (key == 1) {
bm = linkStates[key].split(';')
bm.forEach((bmItem) => {
bmciArr.push(new BMapGL.Point(bmItem.split(',')[0], bmItem.split(',')[1]))
bmciArr.push(new BMapGL.Point(bmItem.split(',')[2], bmItem.split(',')[3]))
var bmciPolyline = new BMapGL.Polyline(bmciArr, {
strokeColor: 'red',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(bmciPolyline)
})
} else if (key == 2) {
bm = linkStates[key].split(';')
bm.forEach((bmItem) => {
bmciArr.push(new BMapGL.Point(bmItem.split(',')[0], bmItem.split(',')[1]))
bmciArr.push(new BMapGL.Point(bmItem.split(',')[2], bmItem.split(',')[3]))
var bmciPolyline = new BMapGL.Polyline(bmciArr, {
strokeColor: 'red',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(bmciPolyline)
})
} else if (key == 3) {
bm = linkStates[key].split(';')
bm.forEach((bmItem) => {
bmciArr.push(new BMapGL.Point(bmItem.split(',')[0], bmItem.split(',')[1]))
bmciArr.push(new BMapGL.Point(bmItem.split(',')[2], bmItem.split(',')[3]))
var bmciPolyline = new BMapGL.Polyline(bmciArr, {
strokeColor: 'red',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(bmciPolyline)
})
} else if (key == 4) {
bm = linkStates[key].split(';')
bm.forEach((bmItem) => {
bmciArr.push(new BMapGL.Point(bmItem.split(',')[0], bmItem.split(',')[1]))
bmciArr.push(new BMapGL.Point(bmItem.split(',')[2], bmItem.split(',')[3]))
var bmciPolyline = new BMapGL.Polyline(bmciArr, {
strokeColor: 'red',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(bmciPolyline)
})
} else {
bm = linkStates[key].split(';')
bm.forEach((bmItem) => {
bmciArr.push(new BMapGL.Point(bmItem.split(',')[0], bmItem.split(',')[1]))
bmciArr.push(new BMapGL.Point(bmItem.split(',')[2], bmItem.split(',')[3]))
var bmciPolyline = new BMapGL.Polyline(bmciArr, {
strokeColor: 'red',
strokeWeight: 8,
strokeOpacity: 0.8
})
map.value.addOverlay(bmciPolyline)
})
}
}
}
})
}
}
onMounted(() => {
getSpotList()
})
</script>
<style lang="scss" scoped>
:deep(.BMap_cpyCtrl) {
display: none;
}
:deep(.anchorBL) {
display: none;
}
.map {
width: 100%;
height: vh(700);
background-color: transparent;
}
.box-3 {
width: vw(1614);
height: vh(950);
margin-top: vh(120);
.header {
width: vw(1614);
height: vh(128);
padding: 0 vw(90);
box-sizing: border-box;
background-image: url('@/assets/images/group.png');
background-size: 100% 100%;
.left {
display: flex;
width: vw(740);
margin-top: vh(20);
}
.right {
flex: 1;
display: flex;
margin-top: vh(20);
}
.item {
flex: 1;
.label {
margin-bottom: vh(20);
font-weight: 400;
font-size: vw(18);
color: rgba(255, 255, 255, 0.9);
}
.value {
font-weight: bold;
font-size: vw(28);
line-height: vh(33);
&--error {
@extend .value;
color: #ff4400;
}
&--primary {
@extend .value;
color: #02f9fa;
}
}
}
.countup-wrap {
display: inline-block;
width: vw(40);
height: vh(40);
margin-right: vw(4);
border-radius: vw(4);
color: #ffffff;
font-size: vw(28);
font-weight: bold;
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #00b7ff 0%, #0033ff 100%);
}
}
.alarm-box {
position: absolute;
top: vw(20);
left: vw(20);
z-index: 99;
.alarm-item {
width: vw(110);
height: vh(40);
margin-right: vw(4);
font-weight: 400;
font-size: vw(14);
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom, rgba(238, 44, 44, 0) 0%, #ee2c2c 100%);
.icon {
width: vw(20);
height: vw(20);
margin-right: vw(4);
}
}
}
.spot-wrap {
position: absolute;
bottom: vw(20);
left: vw(20);
z-index: 999;
}
.spot-list {
display: flex;
align-items: center;
}
.spot-item {
cursor: pointer;
width: vw(80);
height: vw(80);
margin-right: vw(10);
> img {
width: 100%;
height: 100%;
}
}
.footer {
margin-top: vh(4);
display: flex;
height: vh(120);
background-image: url('@/assets/images/bg-2.png');
background-size: 100% 100%;
.left {
flex: 1;
display: flex;
margin-top: vh(4);
& > div {
flex: 1;
height: vh(110);
margin-right: vw(6);
background-image: url('@/assets/images/bg-3.png');
background-size: 100% 100%;
.item {
padding: vh(10) vw(24);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.label {
margin-bottom: vh(10);
font-weight: 400;
font-size: vw(14);
color: #ffffff;
}
.countup-wrap {
color: #02f9fa;
font-size: vw(28);
font-weight: bold;
}
.error {
color: #e21b1b;
}
.complete {
color: #ffffff;
}
.progress-box {
margin-top: vh(10);
display: flex;
align-items: center;
justify-content: center;
.text {
margin-right: vw(10);
font-weight: 400;
font-size: vw(14);
color: #ffffff;
}
.progress {
width: vw(100);
:deep(.el-progress-bar__outer) {
height: vh(4) !important;
background-color: #0858ae !important;
}
}
.progress-1 {
@extend .progress;
:deep(.el-progress-bar__inner) {
background: linear-gradient(to right, #0566bb 0%, #00c4f9 100%);
}
}
.progress-2 {
@extend .progress;
:deep(.el-progress-bar__inner) {
background: linear-gradient(to right, #0566bb 0%, #d6383a 100%);
}
}
.value {
margin-left: vw(10);
font-weight: 400;
font-size: vw(14);
color: #ffffff;
}
}
}
}
.right {
margin-top: vh(4);
padding: vh(10) vw(10);
height: vh(106);
width: vw(1040);
overflow: hidden;
.item {
display: flex;
margin-bottom: vh(10);
&-tag {
padding: 0 vw(16);
font-weight: bold;
font-size: vw(14);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
border-radius: vw(2);
}
&-tag--important {
@extend .item-tag;
background: #feae00;
}
&-tag--warn {
@extend .item-tag;
background: #d9011b;
}
&-tag--normal {
@extend .item-tag;
background: #2380fb;
}
.content {
margin-left: vw(4);
padding: 0 vw(10);
width: vw(950);
height: vh(24);
line-height: vh(24);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 400;
font-size: vw(14);
color: #ffffff;
border-radius: vw(2);
background: rgba(0, 150, 255, 0.28);
}
}
}
}
}
</style>