Traffic6 替换为实时监控画面,更新生产环境 API 直连地址。

Co-authored-by: Cursor <cursoragent@cursor.com>
main
崔方鑫 2026-08-28 13:38:32 +08:00
parent 9686f58e97
commit 131d41f036
2 changed files with 109 additions and 14 deletions

View File

@ -1,2 +1,2 @@
# 生产环境配置 目前是配置代理的方式
VITE_API_BASE_URL=/juntech-ysdp
# 生产环境配置(直连实际地址,需包含应用 context path
VITE_API_BASE_URL=http://10.104.10.151:8888/juntech-ysdp

View File

@ -1,19 +1,108 @@
<template>
<section class="traffic-6">
<div class="traffic-image-list">
<img
v-for="item in imageList"
:key="item"
class="traffic-image"
:src="`./imgs/traffic/${item}`"
alt=""
<div class="traffic-video-list" v-if="videoList.length">
<div
v-for="(item, index) in videoList.slice(0, 4)"
:key="index"
class="traffic-video-wrapper"
>
<video
:ref="el => setVideoRef(el, index)"
class="traffic-video"
controls
autoplay
muted
playsinline
loop
></video>
</div>
</div>
</section>
</template>
<script setup>
const imageList = ['image1.png', 'image2.png', 'image3.png', 'image4.png']
import { ref, onMounted, nextTick } from 'vue'
import HLS from 'hls.js'
import server from '@/utils/service'
const videoList = ref([])
const videoRefs = ref([])
const setVideoRef = (el, index) => {
if (el) {
videoRefs.value[index] = el
}
}
const fetchVideoList = async () => {
try {
const response = await server.getCommonMonitor()
if (response.data.success) {
videoList.value = response.data.data.map(item => ({
url: item.url.trim(),
line: item.line,
station: item.station,
monitor: item.monitor
}))
}
} catch (error) {
console.error('获取视频列表失败:', error)
}
}
const playVideo = (video, videoUrl, index) => {
if (HLS.isSupported()) {
const hls = new HLS({
debug: true,
liveSyncDuration: 3,
maxBufferLength: 30
})
hls.on(HLS.Events.ERROR, (event, data) => {
console.error('视频', index + 1, 'HLS 错误:', event, data)
if (data.fatal) {
hls.destroy()
}
})
hls.loadSource(videoUrl)
hls.attachMedia(video)
video.play().catch(err => {
console.error('视频', index + 1, '播放失败:', err)
})
} else if (video.canPlayType('application/x-mpegURL')) {
video.src = videoUrl
video.load()
video.play().catch(err => {
console.error('视频', index + 1, '播放失败:', err)
})
}
}
const initVideos = async () => {
await fetchVideoList()
if (!videoList.value.length) {
return
}
await nextTick()
setTimeout(() => {
videoRefs.value.forEach((video, index) => {
if (!video) return
const videoItem = videoList.value[index % videoList.value.length]
if (!videoItem?.url) return
playVideo(video, videoItem.url, index)
})
}, 500)
}
onMounted(() => {
initVideos()
})
</script>
<style lang="scss" scoped>
@ -28,7 +117,7 @@ const imageList = ['image1.png', 'image2.png', 'image3.png', 'image4.png']
background-size: cover;
box-sizing: border-box;
.traffic-image-list {
.traffic-video-list {
position: absolute;
top: 58px;
left: 24px;
@ -39,14 +128,20 @@ const imageList = ['image1.png', 'image2.png', 'image3.png', 'image4.png']
align-items: center;
}
.traffic-image {
.traffic-video-wrapper {
width: 100%;
height: 419px;
display: block;
object-fit: cover;
overflow: hidden;
border: 4px solid rgba(0, 102, 255, 0.72);
box-sizing: border-box;
box-shadow: inset 0 0 18px rgba(0, 180, 255, 0.36), 0 0 10px rgba(0, 90, 255, 0.32);
}
.traffic-video {
width: 100%;
height: 100%;
display: block;
object-fit: fill;
}
}
</style>