feat:对接监控大屏

This commit is contained in:
zjc
2025-01-16 16:02:01 +08:00
parent 2a11f91d36
commit 70495d3c95
20 changed files with 336 additions and 237 deletions

View File

@@ -3,7 +3,7 @@ import request from './request'
// 彩云天气 // 彩云天气
export function getWeatherApi() { export function getWeatherApi() {
return request({ return request({
url: '/api/largeScreen/source/weather', url: '/fjtcc-api/api/largeScreen/source/weather',
method: 'get' method: 'get'
}) })
} }
@@ -11,7 +11,7 @@ export function getWeatherApi() {
// 核心景区视频 // 核心景区视频
export function getVideoListApi(data) { export function getVideoListApi(data) {
return request({ return request({
url: '/api/largeScreen/video/list', url: '/fjtcc-api/api/largeScreen/video/list',
method: 'post', method: 'post',
data data
}) })
@@ -20,7 +20,7 @@ export function getVideoListApi(data) {
// 刷新播放地址 // 刷新播放地址
export function postRefreshApi(data) { export function postRefreshApi(data) {
return request({ return request({
url: '/api/largeScreen/video/refresh', url: '/fjtcc-api/api/largeScreen/video/refresh',
method: 'post', method: 'post',
data data
}) })
@@ -29,7 +29,7 @@ export function postRefreshApi(data) {
// 景区 // 景区
export function getSpotListApi() { export function getSpotListApi() {
return request({ return request({
url: '/api/largeScreen/spot/list', url: '/fjtcc-api/api/largeScreen/spot/list',
method: 'get' method: 'get'
}) })
} }
@@ -37,7 +37,7 @@ export function getSpotListApi() {
// 百度地图拥堵 // 百度地图拥堵
export function getBaiduMapCrowdedApi(data) { export function getBaiduMapCrowdedApi(data) {
return request({ return request({
url: '/api/largeScreen/spot/baiduMapCrowded', url: '/fjtcc-api/api/largeScreen/spot/baiduMapCrowded',
method: 'get', method: 'get',
params: data params: data
}) })

View File

@@ -3,7 +3,7 @@ import request from './request'
// 最新消息 // 最新消息
export function getNewsListApi() { export function getNewsListApi() {
return request({ return request({
url: '/api/largeScreen/news/list', url: '/fjtcc-api/api/largeScreen/news/list',
method: 'get' method: 'get'
}) })
} }
@@ -11,7 +11,7 @@ export function getNewsListApi() {
// 异常点位告警排行 // 异常点位告警排行
export function getNewsPointRankApi() { export function getNewsPointRankApi() {
return request({ return request({
url: '/api/largeScreen/news/pointRank', url: '/fjtcc-api/api/largeScreen/news/pointRank',
method: 'get' method: 'get'
}) })
} }
@@ -19,7 +19,7 @@ export function getNewsPointRankApi() {
// 消息分类统计 // 消息分类统计
export function getNewsStateApi() { export function getNewsStateApi() {
return request({ return request({
url: '/api/largeScreen/news/state', url: '/fjtcc-api/api/largeScreen/news/state',
method: 'get' method: 'get'
}) })
} }
@@ -27,7 +27,7 @@ export function getNewsStateApi() {
// 消息统计 // 消息统计
export function getNewsTotalApi() { export function getNewsTotalApi() {
return request({ return request({
url: '/api/largeScreen/news/total', url: '/fjtcc-api/api/largeScreen/news/total',
method: 'get' method: 'get'
}) })
} }

View File

@@ -2,22 +2,16 @@ import axios from 'axios'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
let devToken = import { baseUrl, proBaseUrl, mode, devToken, proToken } from '@/utils/config'
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ'
let proToken =
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.dSLZekRsYf5ZZDCYqFEOgHTi4GeHD0m10gGHXrbgpc-hD52Zt7Vw05cxhQ-lzY29yf2IxH0oYi28DBfHdtf9SA'
const router = useRouter()
/** /**
* @description axios初始化 * @description axios初始化
*/ */
const instance = axios.create({ const instance = axios.create({
// baseURL: 'http://36.138.38.16:6180/fjtcc-api', baseURL: mode == 'dev' ? baseUrl : proBaseUrl,
baseURL: 'http://36.138.38.16:8001/fjtcc-api',
// baseURL: 'http://192.168.77.200/fjtcc-api',
timeout: 100000, timeout: 100000,
headers: { headers: {
Authorization: devToken, Authorization: mode == 'dev' ? devToken : proToken,
'Content-Type': 'application/json;charset=UTF-8' 'Content-Type': 'application/json;charset=UTF-8'
} }
}) })

View File

@@ -3,7 +3,7 @@ import request from './request'
// 最新舆情 // 最新舆情
export function getHotNewApi() { export function getHotNewApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/hotNew', url: '/fjtcc-api/api/largeScreen/gsdata/hotNew',
method: 'post' method: 'post'
}) })
} }
@@ -11,7 +11,7 @@ export function getHotNewApi() {
// 数据来源分析 // 数据来源分析
export function getMediaTypeApi() { export function getMediaTypeApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/mediaType', url: '/fjtcc-api/api/largeScreen/gsdata/mediaType',
method: 'post' method: 'post'
}) })
} }
@@ -19,7 +19,7 @@ export function getMediaTypeApi() {
// 景区统计 // 景区统计
export function getStateApi() { export function getStateApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/state', url: '/fjtcc-api/api/largeScreen/gsdata/state',
method: 'post' method: 'post'
}) })
} }
@@ -27,7 +27,7 @@ export function getStateApi() {
// 舆情统计 // 舆情统计
export function getTotalApi() { export function getTotalApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/total', url: '/fjtcc-api/api/largeScreen/gsdata/total',
method: 'post' method: 'post'
}) })
} }
@@ -35,7 +35,7 @@ export function getTotalApi() {
// 词频分析 // 词频分析
export function getHotWordApi() { export function getHotWordApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/hotWord', url: '/fjtcc-api/api/largeScreen/gsdata/hotWord',
method: 'post' method: 'post'
}) })
} }
@@ -43,7 +43,7 @@ export function getHotWordApi() {
// 舆情指数 // 舆情指数
export function getLineChartApi(data) { export function getLineChartApi(data) {
return request({ return request({
url: '/api/largeScreen/gsdata/lineChart', url: '/fjtcc-api/api/largeScreen/gsdata/lineChart',
method: 'get', method: 'get',
params: data params: data
}) })
@@ -52,7 +52,7 @@ export function getLineChartApi(data) {
// 地域分析 // 地域分析
export function getAreaApi(data) { export function getAreaApi(data) {
return request({ return request({
url: '/api/largeScreen/gsdata/area', url: '/fjtcc-api/api/largeScreen/gsdata/area',
method: 'get', method: 'get',
params: data params: data
}) })
@@ -61,7 +61,7 @@ export function getAreaApi(data) {
// 景区选择 // 景区选择
export function getSpotApi() { export function getSpotApi() {
return request({ return request({
url: '/api/largeScreen/gsdata/spot', url: '/fjtcc-api/api/largeScreen/gsdata/spot',
method: 'post' method: 'post'
}) })
} }

View File

@@ -3,7 +3,7 @@ import request from './request'
// 最新工单 // 最新工单
export function getListApi() { export function getListApi() {
return request({ return request({
url: '/api/largeScreen/workorder/list', url: '/fjtcc-api/api/largeScreen/workorder/list',
method: 'get' method: 'get'
}) })
} }
@@ -11,7 +11,7 @@ export function getListApi() {
// 统计 // 统计
export function getTotalApi() { export function getTotalApi() {
return request({ return request({
url: '/api/largeScreen/workorder/total', url: '/fjtcc-api/api/largeScreen/workorder/total',
method: 'get' method: 'get'
}) })
} }
@@ -19,7 +19,7 @@ export function getTotalApi() {
// 工单总数(折线图) // 工单总数(折线图)
export function getLineChartApi() { export function getLineChartApi() {
return request({ return request({
url: '/api/largeScreen/workorder/lineChart', url: '/fjtcc-api/api/largeScreen/workorder/lineChart',
method: 'get' method: 'get'
}) })
} }
@@ -27,7 +27,7 @@ export function getLineChartApi() {
// 工单完成比例 // 工单完成比例
export function getCompleteRateApi() { export function getCompleteRateApi() {
return request({ return request({
url: '/api/largeScreen/workorder/completeRate', url: '/fjtcc-api/api/largeScreen/workorder/completeRate',
method: 'get' method: 'get'
}) })
} }
@@ -35,7 +35,7 @@ export function getCompleteRateApi() {
// 工单景区占比 // 工单景区占比
export function getSpotRateApi() { export function getSpotRateApi() {
return request({ return request({
url: '/api/largeScreen/workorder/spotRate', url: '/fjtcc-api/api/largeScreen/workorder/spotRate',
method: 'get' method: 'get'
}) })
} }
@@ -43,7 +43,7 @@ export function getSpotRateApi() {
// 工单类型占比 // 工单类型占比
export function getTypeRateApi() { export function getTypeRateApi() {
return request({ return request({
url: '/api/largeScreen/workorder/typeRate', url: '/fjtcc-api/api/largeScreen/workorder/typeRate',
method: 'get' method: 'get'
}) })
} }

View File

@@ -1,7 +1,6 @@
<template> <template>
<div class="core-video"> <div class="core-video">
<div class="title">核心景区视频</div> <div class="title">核心景区视频</div>
<ul class="list"> <ul class="list">
<li <li
class="item" class="item"
@@ -11,7 +10,7 @@
@click.shop="handleItem(item)" @click.shop="handleItem(item)"
> >
<div> <div>
<p :class="[index % 2 === 0 ? 'item-title--primary' : 'item-title--error']"> <p class="item-title--primary">
{{ item.cameraName }} {{ item.cameraName }}
</p> </p>
<video <video
@@ -48,7 +47,7 @@
const getVideoList = async () => { const getVideoList = async () => {
let res = await getVideoListApi({ let res = await getVideoListApi({
businessVideoDisplayPosition: '' businessVideoDisplayPosition: 'core_scenic_area_video'
}) })
list.value = res.data list.value = res.data
nextTick(() => { nextTick(() => {

View File

@@ -186,24 +186,7 @@
path: '/sceneTesting' path: '/sceneTesting'
} }
] ]
navRight.value = [ navRight.value = []
{
name: '路段',
path: '/roadTesting'
},
{
name: '路段',
path: '/roadTesting'
},
{
name: '路段',
path: '/roadTesting'
},
{
name: '路段',
path: '/roadTesting'
}
]
isBack.value = true isBack.value = true
break break
case '/sceneTesting': case '/sceneTesting':

View File

@@ -26,9 +26,9 @@
() => modelValue.value, () => modelValue.value,
(val) => { (val) => {
if (val) { if (val) {
nextTick(() => { setTimeout(() => {
init() init()
}) }, 1000)
} }
}, },
{ {
@@ -50,16 +50,16 @@
.dialog { .dialog {
z-index: 9999; z-index: 9999;
:deep(.el-dialog) { :deep(.el-dialog) {
width: vw(2540); width: vw(1600);
height: vh(900); height: vw(900);
padding: 0; padding: 0;
} }
:deep(.el-dialog__header) { :deep(.el-dialog__header) {
padding-bottom: 0 !important; padding-bottom: 0 !important;
} }
.video { .video {
width: vw(2540); width: vw(1600);
height: vh(900); height: vw(900);
} }
.close { .close {
cursor: pointer; cursor: pointer;

View File

@@ -1,120 +1,224 @@
<template> <template>
<div class="video-box"> <div v-if="videoLog == 1" class="video-wrapper">
<div class="flex video-one-1" v-if="videoLog == 1"> <div class="video-list">
<div <div
@click="handleItemVideo" class="video-item"
class="v-item" v-for="(item, index) in videoList"
:class="index == 0 ? 'v-error-bg' : ''" :key="index"
v-for="(item, index) in 15" @click="handleItemVideo(item.hlsUrl, item.cameraName, item.updateTime)"
> >
<vue3VideoPlay v-bind="options" /> <div class="video-item__inner">
<video
class="video-item__video"
:id="'monitorVideo' + index"
muted
autoplay
:controls="false"
style="object-fit: cover"
>
<source src="" type="application/x-mpegURL" />
</video>
<p class="video-item__title--primary">
{{ item.cameraName }}
</p>
</div>
</div>
</div> </div>
</div> </div>
<div class="video-live flex" v-if="videoLog == 2"> <div class="video-detail" v-if="videoLog == 2">
<div class="video-lt v-error-bg"> <div class="video-detail__wrapper v-error-bg">
<div class="desc">核心路段这是一条信息说明</div> <div class="video-detail__title">
<vue3VideoPlay v-bind="options" /> <span>{{ videoTitle }}</span>
<span>{{ videoUpdateTime }}</span>
</div> </div>
<div class="video-rt"> <video
class="video-detail__video"
ref="videoRef"
muted
autoplay
controls
style="object-fit: cover"
>
<source src="" type="application/x-mpegURL" />
</video>
</div>
<!-- <div class="video-rt">
<div class="title"> <div class="title">
<span>最近联系</span> <span>最近联系</span>
</div> </div>
<div class="rt-v-box"> <div class="rt-v-box">
<div class="rt-video v-error-bg" v-for="item in 8"> <div class="rt-video v-error-bg" v-for="item in 8">
<div class="desc">核心路段这是一条信息说明</div> <div class="desc">核心路段这是一条信息说明</div>
<vue3VideoPlay v-bind="options" />
</div>
</div>
</div> </div>
</div> </div>
</div> -->
</div> </div>
</template> </template>
<script setup> <script setup>
import { fitChartSize } from '@/utils/dataUtil' import { postRefreshApi } from '@/api/home'
const options = reactive({ import Hls from 'hls.js'
src: 'http://192.168.1.60:8080/live/340200000013200000011_34020000001320000001/hls.m3u8', //视频源
type: 'm3u8', //视频类型 let props = defineProps({
width: '100%', list: {
height: '100%', type: Array,
color: '#409eff', //主题色 default: () => []
title: '', //视频名称 }
muted: false, //静音
webFullScreen: false,
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
autoPlay: true, //自动播放
loop: false, //循环播放
mirror: false, //镜像画面
ligthOff: false, //关灯模式
volume: 0.3, //默认音量大小
control: true, //是否显示控制
controlBtns: [
// "audioTrack",
// "quality",
// "speedRate",
// "volume",
'setting',
'pip',
'pageFullScreen',
'fullScreen'
] //显示所有按钮,
}) })
const videoLog = ref(1)
const handleItemVideo = () => { const videoList = ref([])
console.log('单击视频')
watch(
() => props.list,
(val) => {
videoList.value = val
nextTick(() => {
videoList.value.forEach(async (item, index) => {
const video = document.getElementById(`monitorVideo${index}`)
let res = await postRefreshApi({
type: 'hls',
businessVideoDisplayPosition: item.businessVideoDisplayPosition,
cameraIndexCode: item.cameraIndexCode
})
item.hlsUrl = res.data.hlsUrl
const hls = new Hls()
hls.loadSource(res.data.hlsUrl)
hls.attachMedia(video)
hls.on(Hls.Events.MANIFEST_PARSED, () => {
video.play()
})
})
})
},
{ immediate: true }
)
let videoLog = ref(1)
let videoRef = ref()
let videoTitle = ref('')
let videoUpdateTime = ref('')
const handleItemVideo = (url, title, time) => {
videoLog.value = 2 videoLog.value = 2
videoTitle.value = title
videoUpdateTime.value = time
nextTick(() => {
const hls = new Hls()
console.log(url, '111')
console.log(videoRef.value, '222')
hls.loadSource(url)
hls.attachMedia(videoRef.value)
hls.on(Hls.Events.MANIFEST_PARSED, () => {
videoRef.value.play()
})
})
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-box { .video {
flex: 1; &-wrapper {
display: flex; width: 100%;
.video-one-1 { height: vh(960);
padding: vh(30) vw(20);
background-image: url('/src/assets/images/log-v-bg.png'); background-image: url('/src/assets/images/log-v-bg.png');
background-size: 100% 100%; background-size: 100% 100%;
flex-wrap: wrap;
padding-top: 0;
padding: vh(30) vw(20);
margin-left: vw(20);
} }
.video-live { &-list {
justify-content: space-between; overflow-y: auto;
width: 100%;
height: 100%;
gap: vw(8);
display: flex;
flex-wrap: wrap;
align-content: flex-start;
&::-webkit-scrollbar {
width: vw(4); /* 滚动条的宽度 */
}
/* 滚动条轨道 */
&::-webkit-scrollbar-track {
background: 'transparent'; /* 轨道的背景色 */
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
background: rgba(0, 150, 255, 0.63); /* 滑块的背景色 */
border-radius: 5px; /* 滑块的圆角 */
}
}
&-item {
width: vw(404);
height: vh(300);
padding: vw(10);
background-image: url('/src/assets/images/item-primary.png');
background-size: 100% 100%;
&:nth-child(5n) {
margin-right: 0;
}
}
&-item__inner {
position: relative;
}
&-item__title {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
padding: vh(10) vw(10);
color: #fff;
font-size: vw(14);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
z-index: 999;
}
&-item__title--error {
@extend .video-item__title;
background-color: rgba(226, 27, 27, 0.72);
}
&-item__title--primary {
@extend .video-item__title;
background-color: rgba(4, 30, 69, 0.72);
}
&-item__video {
width: 100%;
height: vh(286);
}
&-detail {
margin-left: vw(10); margin-left: vw(10);
.video-lt { display: flex;
justify-content: space-between;
}
&-detail__wrapper {
position: relative;
padding: vh(40) vw(50);
width: vw(1666); width: vw(1666);
height: vh(950); height: vh(950);
background-image: url('/src/assets/images/one-video-bg.png'); background-image: url('/src/assets/images/one-video-bg.png');
background-size: 100% 100%; background-size: 100% 100%;
padding: vh(40) vw(50); }
position: relative; &-detail__title {
.desc {
position: absolute; position: absolute;
// width:100%;
left: vw(50); left: vw(50);
right: vw(50); right: vw(50);
top: 40 (vh); top: 40 (vh);
z-index: 9; z-index: 9;
background: rgba(4, 30, 69, 0.5);
border-radius: 0px 0px 0px 0px;
text-align: center;
font-weight: 400; font-weight: 400;
font-size: vw(14); font-size: vw(14);
color: #ffffff; color: #ffffff;
padding: vw(20); padding: vw(20);
text-align: left; display: flex;
font-style: normal; justify-content: space-between;
text-transform: none; background: rgba(4, 30, 69, 0.5);
}
}
.v-error-bg {
// background-image: url('/src/assets/images/v-item-bg-1.png');
// background-size: 100% 100%;
.desc {
background: rgba(226, 27, 27, 0.5);
} }
&-detail__video {
width: 100%;
height: vh(880);
} }
.video-live {
.video-rt { .video-rt {
width: vw(400); width: vw(400);
height: vh(950); height: vh(950);
@@ -204,18 +308,5 @@
} }
} }
} }
.v-item {
width: vw(400);
height: vh(300);
background-image: url('/src/assets/images/v-item-bg.png');
background-size: 100% 100%;
padding: vw(20);
margin-right: vw(4);
margin-bottom: vh(4);
}
.v-error-bg {
background-image: url('/src/assets/images/v-item-bg-1.png');
background-size: 100% 100%;
}
} }
</style> </style>

View File

@@ -1,8 +1,4 @@
import { ref } from 'vue' import { ref } from 'vue'
import { useHomeStore } from '@/stores/home'
const homeStore = useHomeStore()
export function useWebSocket(url) { export function useWebSocket(url) {
let socket = ref(null) // socket对象 let socket = ref(null) // socket对象
let isConnected = ref(false) // 是否连接成功 let isConnected = ref(false) // 是否连接成功
@@ -27,44 +23,6 @@ export function useWebSocket(url) {
if (JSON.parse(message.data)) { if (JSON.parse(message.data)) {
let data = JSON.parse(message.data) let data = JSON.parse(message.data)
dataRes.value = data dataRes.value = data
switch (data.type) {
case 'userPortrait':
homeStore.setUserPortraitData(data.data)
break
case 'admission':
homeStore.setScenicData(data)
break
case 'queuingInScenicSpots':
homeStore.setScenicQueueData(data)
break
case 'queuingScenicSpots':
homeStore.setScenicBearData(data)
break
case 'visitorInfo':
homeStore.setVisitorInfoData(data.data)
break
case 'visitorDataInfo':
homeStore.setVisitorInfoList(data.data)
break
case 'baiduMap':
homeStore.setBaiduMapData(data.data)
break
case 'wordkOrderlist':
homeStore.setWordkOrderList(data.data)
break
case 'trafficInformation':
homeStore.setTrafficInfoData(data)
break
case 'carStopInfo':
homeStore.setCarStopInfoData(data)
break
case 'carShipData':
homeStore.setCarShipData(data.data)
break
case 'hotelData':
homeStore.setHotelData(data.data)
break
}
} }
} }
socket.value.onclose = () => { socket.value.onclose = () => {

12
src/utils/config.js Normal file
View File

@@ -0,0 +1,12 @@
export const baseUrl = 'http://36.138.38.16:8001'
export const proBaseUrl = ' http://192.168.77.200'
export const socketBaseUrl = 'ws://36.138.38.16:81'
export const proSocketBaseUrl = 'ws://192.168.77.200:8060'
export const mode = 'pro'
export const devToken =
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ'
export const proToken =
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.dSLZekRsYf5ZZDCYqFEOgHTi4GeHD0m10gGHXrbgpc-hD52Zt7Vw05cxhQ-lzY29yf2IxH0oYi28DBfHdtf9SA'

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="box-4"> <div class="box-3">
<Title1 title="交通信息" /> <Title1 title="交通信息" />
<div class="traffic-info flex justify-evenly pt-10 pb-20"> <div class="traffic-info flex justify-evenly pt-10 pb-20">
<!-- <div class="cell"> <!-- <div class="cell">
@@ -275,10 +275,10 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box-4 { .box-3 {
margin-top: vh(120); margin-top: vh(120);
width: vw(774); width: vw(774);
height: vh(950); height: vh(956);
padding-left: vw(8); padding-left: vw(8);
box-sizing: border-box; box-sizing: border-box;
background-image: url('@/assets/images/bg-5.png'); background-image: url('@/assets/images/bg-5.png');

View File

@@ -86,12 +86,11 @@
left: '4%', left: '4%',
right: '4%', right: '4%',
top: '16%', top: '16%',
bottom: '-10%', bottom: '4%',
containLabel: true containLabel: false
}, },
xAxis: [ xAxis: [
{ {
// max: 10000,
splitLine: { splitLine: {
show: false show: false
}, },
@@ -101,13 +100,13 @@
], ],
yAxis: [ yAxis: [
{ {
type: 'category',
splitLine: { splitLine: {
show: false show: false
}, },
axisLine: { axisLine: {
show: false show: false
}, },
type: 'category',
axisTick: { axisTick: {
show: false show: false
}, },

View File

@@ -85,9 +85,9 @@
grid: { grid: {
left: '4%', left: '4%',
right: '4%', right: '4%',
top: '16%', top: '14%',
bottom: '-10%', bottom: '4%',
containLabel: true containLabel: false
}, },
xAxis: [ xAxis: [
{ {
@@ -101,17 +101,16 @@
], ],
yAxis: [ yAxis: [
{ {
type: 'category',
splitLine: { splitLine: {
show: false show: false
}, },
axisLine: { axisLine: {
show: false show: false
}, },
type: 'category',
axisTick: { axisTick: {
show: false show: false
}, },
data: [],
axisLabel: { axisLabel: {
show: false show: false
} }
@@ -195,6 +194,6 @@
<style scoped lang="scss"> <style scoped lang="scss">
.occupancy { .occupancy {
width: vw(360); width: vw(360);
height: vh(120); height: vh(130);
} }
</style> </style>

View File

@@ -27,18 +27,18 @@
right: '4%', right: '4%',
top: '10%', top: '10%',
bottom: '-4%', bottom: '-4%',
containLabel: true containLabel: false
}, },
xAxis: [{ max: 100, show: false }], xAxis: [{ max: 100, show: false }],
yAxis: [ yAxis: [
{ {
type: 'category',
splitLine: { splitLine: {
show: false show: false
}, },
axisLine: { axisLine: {
show: false show: false
}, },
type: 'category',
axisTick: { axisTick: {
show: false show: false
}, },

View File

@@ -8,9 +8,15 @@
import box1 from './components/box-1.vue' import box1 from './components/box-1.vue'
import box2 from './components/box-2.vue' import box2 from './components/box-2.vue'
import box3 from './components/box-3.vue' import box3 from './components/box-3.vue'
import { useWebSocket } from '@/hooks/socket'
const { isConnected, sendMessage } = useWebSocket('ws://36.138.38.16:81/ws/third-party') import { useWebSocket } from '@/hooks/socket'
import { useHomeStore } from '@/stores/home'
import { mode, socketBaseUrl, proSocketBaseUrl } from '@/utils/config'
const homeStore = useHomeStore()
const { isConnected, dataRes, sendMessage } = useWebSocket(
`${mode == 'dev' ? socketBaseUrl : proSocketBaseUrl}/ws/third-party`
)
watch( watch(
() => isConnected.value, () => isConnected.value,
@@ -26,7 +32,52 @@
} }
} }
) )
watch(
() => dataRes.value,
(val) => {
if (val) {
console.log(val, '首页接受消息')
switch (val.type) {
case 'userPortrait':
homeStore.setUserPortraitData(val.data)
break
case 'admission':
homeStore.setScenicData(val)
break
case 'queuingInScenicSpots':
homeStore.setScenicQueueData(val)
break
case 'queuingScenicSpots':
homeStore.setScenicBearData(val)
break
case 'visitorInfo':
homeStore.setVisitorInfoData(val.data)
break
case 'visitorDataInfo':
homeStore.setVisitorInfoList(val.data)
break
case 'baiduMap':
homeStore.setBaiduMapData(val.data)
break
case 'wordkOrderlist':
homeStore.setWordkOrderList(val.data)
break
case 'trafficInformation':
homeStore.setTrafficInfoData(val)
break
case 'carStopInfo':
homeStore.setCarStopInfoData(val)
break
case 'carShipData':
homeStore.setCarShipData(val.data)
break
case 'hotelData':
homeStore.setHotelData(val.data)
break
}
}
}
)
const switchSpot = (e) => { const switchSpot = (e) => {
sendMessage( sendMessage(
JSON.stringify({ JSON.stringify({

View File

@@ -3,20 +3,21 @@
<div class="box-2"> <div class="box-2">
<Nav /> <Nav />
<!-- 视频 --> <!-- 视频 -->
<Monitor /> <Monitor :list="videoList" />
</div> </div>
</template> </template>
<script setup> <script setup>
import Nav from '@/components/Nav/index.vue' import Nav from '@/components/Nav/index.vue'
import Monitor from '@/components/Monitor/index.vue' import Monitor from '@/components/Monitor/index.vue'
import { getVideoListApi, postRefreshApi } from '@/api/home' import { getVideoListApi } from '@/api/home'
let videoList = ref([])
const getVideoList = async () => { const getVideoList = async () => {
let res = await getVideoListApi({ let res = await getVideoListApi({
businessVideoDisplayPosition: '' businessVideoDisplayPosition: ''
}) })
console.log(res, 'res') videoList.value = res.data
} }
onMounted(() => { onMounted(() => {
@@ -25,9 +26,9 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box-2 { .box-2 {
margin-top: vh(120);
width: vw(2356); width: vw(2356);
height: vh(965); height: vh(965);
margin-top: vh(120);
display: flex; display: flex;
} }
</style> </style>

View File

@@ -8,9 +8,13 @@
import box2 from './components/box-2.vue' import box2 from './components/box-2.vue'
import { useWebSocket } from '@/hooks/socket' import { useWebSocket } from '@/hooks/socket'
import { useScenicStore } from '@/stores/scenic' import { useScenicStore } from '@/stores/scenic'
import { mode, socketBaseUrl, proSocketBaseUrl } from '@/utils/config'
const scenicStore = useScenicStore() const scenicStore = useScenicStore()
const { isConnected, sendMessage, dataRes } = useWebSocket('ws://36.138.38.16:81/ws/scenic-spot')
const { isConnected, sendMessage, dataRes } = useWebSocket(
`${mode == 'dev' ? socketBaseUrl : proSocketBaseUrl}/ws/scenic-spot`
)
watch( watch(
() => isConnected.value, () => isConnected.value,

View File

@@ -28,7 +28,10 @@
</div> </div>
<div class="chart"> <div class="chart">
<div class="chart-item" v-for="item in 4" :key="item"> <div class="chart-item" v-for="item in 4" :key="item">
<Title3 title="拥堵频次占比" /> <Title3 v-if="item == 1" title="拥堵频次占比" />
<Title3 v-if="item == 2" title="拥堵时长占比" />
<Title3 v-if="item == 3" title="拥堵类型频次占比" />
<Title3 v-if="item == 4" title="拥堵类型时长占比" />
<div class="chart__inner"> <div class="chart__inner">
<spotRate :dataList="spotRateData" :total="8888" /> <spotRate :dataList="spotRateData" :total="8888" />
<ul class="chart__legend"> <ul class="chart__legend">

View File

@@ -77,7 +77,7 @@
<div class="chart__wrapper"> <div class="chart__wrapper">
<Title3 title="景区工单占比" /> <Title3 title="景区工单占比" />
<div class="chart__inner"> <div class="chart__inner">
<spotRate :dataList="spotRateData" :total="8888" /> <spotRate :dataList="spotRateData" :total="spotRateTotal" />
<ul class="chart__legend"> <ul class="chart__legend">
<li class="chart__legend-item" v-for="(item, index) in spotRateData" :key="index"> <li class="chart__legend-item" v-for="(item, index) in spotRateData" :key="index">
<p class="dot" :style="{ background: colors[index] }" /> <p class="dot" :style="{ background: colors[index] }" />
@@ -90,7 +90,7 @@
<div class="chart__wrapper"> <div class="chart__wrapper">
<Title3 title="景区工单类型占比" /> <Title3 title="景区工单类型占比" />
<div class="chart__inner"> <div class="chart__inner">
<spotRate :dataList="typeRateData" :total="8888" /> <spotRate :dataList="typeRateData" :total="typeRateTotal" />
<ul class="chart__legend"> <ul class="chart__legend">
<li class="chart__legend-item" v-for="(item, index) in typeRateData" :key="index"> <li class="chart__legend-item" v-for="(item, index) in typeRateData" :key="index">
<p class="dot" :style="{ background: colors[index] }" /> <p class="dot" :style="{ background: colors[index] }" />
@@ -150,6 +150,8 @@
let typeRateData = ref([]) let typeRateData = ref([])
let spotRateData = ref([]) let spotRateData = ref([])
let pointRankData = ref([]) let pointRankData = ref([])
let spotRateTotal = ref(0)
let typeRateTotal = ref(0)
const getNewsPointRank = async () => { const getNewsPointRank = async () => {
let res = await getNewsPointRankApi() let res = await getNewsPointRankApi()
@@ -158,10 +160,12 @@
const getTypeRate = async () => { const getTypeRate = async () => {
let res = await getTypeRateApi() let res = await getTypeRateApi()
typeRateData.value = res.data.data typeRateData.value = res.data.data
typeRateTotal.value = res.data.total
} }
const getSpotRate = async () => { const getSpotRate = async () => {
let res = await getSpotRateApi() let res = await getSpotRateApi()
spotRateData.value = res.data.data spotRateData.value = res.data.data
spotRateTotal.value = res.data.total
} }
const getCompleteRate = async () => { const getCompleteRate = async () => {
let res = await getCompleteRateApi() let res = await getCompleteRateApi()
@@ -391,10 +395,11 @@
} }
.alarm { .alarm {
width: vw(200);
background: #0a4190; background: #0a4190;
&__wrapper { &__wrapper {
flex: 1; width: vw(200);
height: vh(270); height: vh(270);
background: #054581; /* 滚动条整体样式 */ background: #054581; /* 滚动条整体样式 */
&::-webkit-scrollbar { &::-webkit-scrollbar {