566 lines
16 KiB
Vue
566 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="alarm-item__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, marker, initMap, addMarker, clearOverlays } = useMap()
|
|
|
|
let spotList = ref([])
|
|
|
|
let list = ref([
|
|
{
|
|
label: '安全异常',
|
|
icon: icon8
|
|
},
|
|
{
|
|
label: '排队异常',
|
|
icon: icon9
|
|
},
|
|
{
|
|
label: '停车异常',
|
|
icon: icon10
|
|
},
|
|
{
|
|
label: '舆论异常',
|
|
icon: icon11
|
|
}
|
|
])
|
|
let current = ref(0)
|
|
let markers = []
|
|
let timter = null
|
|
|
|
watch(
|
|
() => [map.value, homeStore.carShipData],
|
|
() => {
|
|
return
|
|
if (map.value && homeStore.carShipData) {
|
|
// clearOverlays()
|
|
markers.forEach((item) => {
|
|
map.value.removeOverlay(item) // 移除每个标记
|
|
})
|
|
homeStore.carShipData?.car?.list.map((item) => {
|
|
if (item.lng && item.lat) {
|
|
addMarker(carIcon, [item.lng, item.lat], [36, 50])
|
|
markers.push(marker.value)
|
|
}
|
|
})
|
|
homeStore.carShipData?.ship?.list.map((item) => {
|
|
if (item.lng && item.lat) {
|
|
addMarker(shipIcon, [item.lng, item.lat], [36, 50])
|
|
markers.push(marker.value)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
{
|
|
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
|
|
})
|
|
map.value.setTrafficOn()
|
|
// 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)
|
|
// })
|
|
// })
|
|
// timter = setInterval(() => {
|
|
// getBaiduMapCrowded()
|
|
// }, 5000)
|
|
}
|
|
const getBaiduMapCrowded = async () => {
|
|
let res = await getBaiduMapCrowdedApi({
|
|
nodeid: 5118
|
|
})
|
|
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()
|
|
})
|
|
// onUnmounted(() => {
|
|
// if (timer) clearInterval(timer)
|
|
// })
|
|
</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 {
|
|
margin-right: vh(20);
|
|
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 {
|
|
padding: 0 vw(20);
|
|
height: vw(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>
|