| | |
| | | class="countCard" |
| | | v-for="(item, index) in carCountData.slice(0, 3)" |
| | | :key="item.id" |
| | | @click="toCarManage(item.id)" |
| | | @click="toCarManage(item.name)" |
| | | > |
| | | <img class="iconImg" :src="imgList[index]" /> |
| | | <div> |
| | |
| | | <div |
| | | class="countCard" |
| | | v-for="(item, index) in carCountData.slice(3, 7)" |
| | | @click="toCarManage(item.id)" |
| | | @click="toCarManage(item.name)" |
| | | :key="item.id" |
| | | > |
| | | <img class="iconImg" :src="imgList[index + 3]" /> |
| | |
| | | </div> |
| | | <!-- 预警情况统计 --> |
| | | <div class="warnCount"> |
| | | <div class="title">预警情况统计</div> |
| | | <div class="title ">预警情况统计</div> |
| | | <div class="countChart" id="countChart"></div> |
| | | <div class="noData" v-if="countList.length == 0"> |
| | | <el-empty description="暂无数据" :image-size="80"></el-empty> |
| | |
| | | </div> |
| | | <!-- 预警排行榜(前10) --> |
| | | <div class="warnRank"> |
| | | <div class="title">预警排行榜(前10)</div> |
| | | <div class="title mt-0">预警排行榜(前10)</div> |
| | | <div class="rankChart" id="rankChart"> |
| | | <div class="rankItem" v-for="(item, index) in rankList" :key="index"> |
| | | <div class="left">{{ item.name }}</div> |
| | |
| | | this.getWarnTop10Data(); |
| | | |
| | | this.initMap(); |
| | | if (this.timer) { |
| | | clearInterval(this.timer); |
| | | } |
| | | // 设置定时器,每分钟刷新一次数据 |
| | | this.timer = setInterval(() => { |
| | | this.getCarCountData(); |
| | |
| | | // 获取预警列表数据 |
| | | async getWarnListData() { |
| | | try { |
| | | const res = await getCarWarnList(); |
| | | const res = await getCarWarnList({pageNum:1,pageSize:100000}); |
| | | this.warnList = res.records; |
| | | } catch (error) { |
| | | this.$message.error("获取预警列表数据失败"); |
| | |
| | | }, |
| | | // 获取视频地址 |
| | | async getVideoUrl(carId) { |
| | | this.carId = carId; |
| | | try { |
| | | const res = await getRealVideo({ id: carId }); |
| | | // 将RTSP流转换为FLV流 |
| | | this.serverIp = res.serverIp; |
| | | this.serverPort = res.serverPort; |
| | | this.carId = carId; |
| | | } catch (error) { |
| | | console.error("获取视频地址失败", error); |
| | | return {}; |
| | |
| | | }, |
| | | |
| | | // 初始化视频播放器 |
| | | initVideoPlayer(videoUrl) { |
| | | initVideoPlayer() { |
| | | console.log('11111',this.serverIp,'2222222222',this.serverPort) |
| | | // 先销毁之前的播放器 |
| | | if (this.flvPlayer) { |
| | |
| | | enableStashBuffer: false, // 启用数据缓存机制,提高视频的流畅度和稳定性。 |
| | | stashInitialSize: 1024, // 初始缓存大小。单位:字节。建议针对直播:调整为1024kb |
| | | stashInitialTime: 0.2, // 缓存初始时间。单位:秒。建议针对直播:调整为200毫秒 |
| | | seekType: "range", // 建议将其设置为“range”模式,以便更快地加载视频数据,提高视频的实时性。 |
| | | seekType: "range", // 建议将其设置为"range"模式,以便更快地加载视频数据,提高视频的实时性。 |
| | | lazyLoad: false, //关闭懒加载模式,从而提高视频的实时性。建议针对直播:调整为false |
| | | lazyLoadMaxDuration: 0.2, // 懒加载的最大时长。单位:秒。建议针对直播:调整为200毫秒 |
| | | deferLoadAfterSourceOpen: false, // 不预先加载视频数据,在 MSE(Media Source Extensions)打开后立即加载数据,提高视频的实时性。建议针对直播:调整为false |
| | |
| | | this.flvPlayer |
| | | .play() |
| | | .then((res) => { |
| | | // 显示视频元素 |
| | | video.style.display = 'block'; |
| | | // 隐藏空状态 |
| | | const emptyElement = video.parentElement.querySelector('.el-empty'); |
| | | if (emptyElement) { |
| | | emptyElement.style.display = 'none'; |
| | | } |
| | | |
| | | this.videoTimer = setInterval(() => { |
| | | playDetection(this.carId); |
| | | }, 5000); |
| | |
| | | this.flvPlayer.detachMediaElement(); |
| | | this.flvPlayer.destroy(); |
| | | this.flvPlayer = null; |
| | | |
| | | // 恢复空状态的显示 |
| | | const video = document.getElementById("monitoringCard"); |
| | | if (video) { |
| | | video.style.display = 'none'; |
| | | const emptyElement = video.parentElement.querySelector('.el-empty'); |
| | | if (emptyElement) { |
| | | emptyElement.style.display = 'block'; |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | |
| | | listRender(record) { |
| | | return `<div style="background: #ffffff; padding: 24px 20px;z-index: 999"> |
| | | <div style="position: relative; width: 460px; height: 330px"> |
| | | |
| | | <video |
| | | <div style="width: 460px; height: 330px; border-radius: 9px; background: #f5f5f5; display: flex; justify-content: center; align-items: center; flex-direction: column"> |
| | | <video |
| | | ref="video" |
| | | style="width: 460px; height: 330px; border-radius: 9px" |
| | | id="monitoringCard" |
| | | ref="monitoringCard" |
| | | :controls="false" |
| | | autoPlay |
| | | width="620"> |
| | | </video> |
| | | style="width: 460px; height: 330px; border-radius: 9px; display: none" |
| | | id="monitoringCard" |
| | | ref="monitoringCard" |
| | | :controls="false" |
| | | autoPlay |
| | | width="620"> |
| | | </video> |
| | | <el-empty description="暂无视频信息" :image-size="80"></el-empty> |
| | | </div> |
| | | <canvas id="myCanvas" style="display:none"></canvas> |
| | | <div style="position: absolute; right: 11px; top: 10px"> |
| | | <div style="display: flex;flex-direction: column;align-items: center;justify-content: center; |
| | |
| | | }, |
| | | axisLabel: { |
| | | color: "rgba(0, 0, 0, 0.45)", |
| | | interval: 0, // 强制显示所有标签 |
| | | width: 60, // 设置标签宽度 |
| | | height: 20, // 设置标签高度 |
| | | overflow: 'truncate', // 截断模式 |
| | | ellipsis: true, // 超出显示省略号 |
| | | rotate: -40, // 可以根据需要调整角度 |
| | | formatter: function(value) { |
| | | if (value.length > 4) { |
| | | return value.substring(0, 4) + '...'; |
| | | } |
| | | return value; |
| | | } |
| | | }, |
| | | }, |
| | | ], |
| | |
| | | .leftMap { |
| | | // width: 100%; |
| | | height: 100%; |
| | | flex: 1; |
| | | flex: 3; |
| | | display: flex; |
| | | position: relative; |
| | | |
| | |
| | | right: 513px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | width: calc(100% - 570px); |
| | | width: calc(100% - 770px); |
| | | |
| | | .title { |
| | | font-weight: 600; |
| | |
| | | } |
| | | |
| | | .right { |
| | | width: 493px; |
| | | // width: 493px; |
| | | flex: 1; |
| | | height: calc(100% - 20px); |
| | | margin: 20px 17px 0 20px; |
| | | background: #ffffff; |
| | | box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2); |
| | | border-radius: 10px 10px 0px 0px; |
| | | padding: 20px; |
| | | overflow-y: auto; |
| | | |
| | | .title { |
| | | margin-top: 30px; |
| | |
| | | text-transform: none; |
| | | margin-bottom: 10px; |
| | | } |
| | | .mt-0{ |
| | | margin-top: 0 !important; |
| | | } |
| | | |
| | | .firCard { |
| | | display: flex; |
| | |
| | | |
| | | .companyCard { |
| | | width: 140px; |
| | | height: 90px; |
| | | // height: 90px; |
| | | background: #f4f4ff; |
| | | border-radius: 0px 10px 10px 0px; |
| | | position: relative; |
| | |
| | | left: 0; |
| | | top: 0; |
| | | width: 4px; |
| | | height: 90px; |
| | | // height: 90px; |
| | | background: #0e6efd; |
| | | border-radius: 2px; |
| | | } |
| | |
| | | position: relative; |
| | | |
| | | #countChart { |
| | | width: 453px; |
| | | height: 150px; |
| | | width: 100%; |
| | | height: 180px; |
| | | } |
| | | |
| | | .noData { |
| | |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 150px; |
| | | height: 180px; |
| | | } |
| | | } |
| | | |
| | |
| | | position: relative; |
| | | |
| | | .rankChart { |
| | | width: 453px; |
| | | height: 300px; |
| | | width: 100%; |
| | | // height: 300px; |
| | | |
| | | .rankItem { |
| | | display: flex; |
| | |
| | | flex: 2; |
| | | padding-right: 25px; |
| | | font-weight: 400; |
| | | font-size: 12px; |
| | | font-size: 13px; |
| | | color: rgba(0, 0, 0, 0.45); |
| | | line-height: 17px; |
| | | text-align: right; |