| | |
| | | <div class="carCount"> |
| | | <div class="title">车辆统计</div> |
| | | <div class="fir"> |
| | | <div |
| | | class="countCard" |
| | | v-for="(item, index) in carCountData.slice(0, 3)" |
| | | :key="item.id" |
| | | @click="toCarManage(item.name)" |
| | | > |
| | | <div class="countCard" v-for="(item, index) in carCountData.slice(0, 3)" :key="item.id" |
| | | @click="toCarManage(item.name)"> |
| | | <img class="iconImg" :src="imgList[index]" /> |
| | | <div> |
| | | <div class="name">{{ item.name || "" }}(辆)</div> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="sec"> |
| | | <div |
| | | class="countCard" |
| | | v-for="(item, index) in carCountData.slice(3, 7)" |
| | | @click="toCarManage(item.name)" |
| | | :key="item.id" |
| | | > |
| | | <div class="countCard" v-for="(item, index) in carCountData.slice(3, 7)" @click="toCarManage(item.name)" |
| | | :key="item.id"> |
| | | <img class="iconImg" :src="imgList[index + 3]" /> |
| | | <div> |
| | | <div class="name">{{ item.name || "" }}(辆)</div> |
| | |
| | | <div class="name">在线</div> |
| | | <div class="num">{{ carStatusData.online || 0 }}</div> |
| | | </div> |
| | | <el-progress |
| | | type="circle" |
| | | :width="20" |
| | | :show-text="false" |
| | | stroke-linecap="butt" |
| | | :percentage="carStatusData.onlinePercent" |
| | | color="rgba(91, 143, 249, 1)" |
| | | define-back-color="rgba(91, 143, 249, 0.25)" |
| | | class="progressCard" |
| | | ></el-progress> |
| | | <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt" |
| | | :percentage="carStatusData.onlinePercent" color="rgba(91, 143, 249, 1)" |
| | | define-back-color="rgba(91, 143, 249, 0.25)" class="progressCard"></el-progress> |
| | | </div> |
| | | <div class="statusLine"></div> |
| | | <div class="statusCard"> |
| | |
| | | <div class="name">离线</div> |
| | | <div class="num">{{ carStatusData.offline || 0 }}</div> |
| | | </div> |
| | | <el-progress |
| | | type="circle" |
| | | :width="20" |
| | | :show-text="false" |
| | | stroke-linecap="butt" |
| | | :percentage="carStatusData.offlinePercent" |
| | | color="rgba(93, 112, 146, 1)" |
| | | define-back-color="rgba(93, 112, 146, 0.25)" |
| | | class="progressCard" |
| | | ></el-progress> |
| | | <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt" |
| | | :percentage="carStatusData.offlinePercent" color="rgba(93, 112, 146, 1)" |
| | | define-back-color="rgba(93, 112, 146, 0.25)" class="progressCard"></el-progress> |
| | | </div> |
| | | </div> |
| | | <div class="statusSec"> |
| | |
| | | <div class="name">故障</div> |
| | | <div class="num">{{ carStatusData.breakdown || 0 }}</div> |
| | | </div> |
| | | <el-progress |
| | | type="circle" |
| | | :width="20" |
| | | :show-text="false" |
| | | stroke-linecap="butt" |
| | | :percentage="carStatusData.breakdownPercent" |
| | | color="rgba(253, 83, 118, 1)" |
| | | define-back-color="rgba(253, 83, 118, 0.25)" |
| | | class="progressCard" |
| | | ></el-progress> |
| | | <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt" |
| | | :percentage="carStatusData.breakdownPercent" color="rgba(253, 83, 118, 1)" |
| | | define-back-color="rgba(253, 83, 118, 0.25)" class="progressCard"></el-progress> |
| | | </div> |
| | | <div class="statusLine"></div> |
| | | <div class="statusCard"> |
| | |
| | | <div class="name">异常</div> |
| | | <div class="num">{{ carStatusData.abnormal || 0 }}</div> |
| | | </div> |
| | | <el-progress |
| | | type="circle" |
| | | :width="20" |
| | | :show-text="false" |
| | | stroke-linecap="butt" |
| | | :percentage="carStatusData.abnormalPercent" |
| | | color="rgba(246, 189, 22, 1)" |
| | | define-back-color="rgba(246, 189, 22, 0.25)" |
| | | class="progressCard" |
| | | ></el-progress> |
| | | <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt" |
| | | :percentage="carStatusData.abnormalPercent" color="rgba(246, 189, 22, 1)" |
| | | define-back-color="rgba(246, 189, 22, 0.25)" class="progressCard"></el-progress> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="todayWarn"> |
| | | <div class="title">今日预警</div> |
| | | <div class="warnList" v-if="warnList.length > 0"> |
| | | <div |
| | | class="warnItem" |
| | | v-for="(item, index) in warnList" |
| | | :key="index" |
| | | :class=" |
| | | item.warnLevel |
| | | ? ['oneWarn', 'twoWarn', 'threeWarn', 'fourWarn'][ |
| | | item.warnLevel - 1 |
| | | ] |
| | | : 'fiveWarn' |
| | | " |
| | | > |
| | | <div class="warnItem" v-for="(item, index) in warnList" :key="index" :class="item.warnLevel |
| | | ? ['oneWarn', 'twoWarn', 'threeWarn', 'fourWarn'][ |
| | | item.warnLevel - 1 |
| | | ] |
| | | : 'fiveWarn' |
| | | "> |
| | | <div class="grade"> |
| | | {{ |
| | | item.warnLevel |
| | |
| | | <div class="rankChart" id="rankChart"> |
| | | <div class="rankItem" v-for="(item, index) in rankList" :key="index"> |
| | | <div class="left">{{ item.name }}</div> |
| | | <div |
| | | class="rankRight" |
| | | :class="[0, 1, 2].includes(index) ? 'rankColor' : ''" |
| | | > |
| | | <div class="rankRight" :class="[0, 1, 2].includes(index) ? 'rankColor' : ''"> |
| | | <div class="rank" :style="{ width: item.percentage + '%' }"></div> |
| | | </div> |
| | | </div> |
| | |
| | | serverIp: "", //监控ip |
| | | serverPort: "", //监控端口 |
| | | carId: "", //监控车辆 |
| | | urlLink: '',//视频地址 |
| | | }; |
| | | }, |
| | | watch: { |
| | |
| | | // 获取预警列表数据 |
| | | async getWarnListData() { |
| | | try { |
| | | const res = await getCarWarnList({pageNum:1,pageSize:100000}); |
| | | const res = await getCarWarnList({ pageNum: 1, pageSize: 100000 }); |
| | | this.warnList = res.records; |
| | | } catch (error) { |
| | | this.$message.error("获取预警列表数据失败"); |
| | |
| | | // 将RTSP流转换为FLV流 |
| | | this.serverIp = res.serverIp; |
| | | this.serverPort = res.serverPort; |
| | | this.urlLink = res.url; |
| | | } catch (error) { |
| | | console.error("获取视频地址失败", error); |
| | | return {}; |
| | |
| | | |
| | | // 初始化视频播放器 |
| | | initVideoPlayer() { |
| | | console.log('11111',this.serverIp,'2222222222',this.serverPort) |
| | | console.log('11111', this.serverIp, '2222222222', this.serverPort) |
| | | // 先销毁之前的播放器 |
| | | if (this.flvPlayer) { |
| | | this.flvPlayer.destroy(); |
| | |
| | | cors: true, //是否开启跨域 |
| | | hasAudio: false, //是否开启音频 |
| | | hasVideo: true, //是否开启视频 |
| | | url: `http://${this.serverIp}:${this.serverPort}/live?port=1935&app=flv&stream=${this.carId}`, // 后端拿到的视频路径 |
| | | // url: `http://${this.serverIp}:${this.serverPort}/live?port=1935&app=flv&stream=${this.carId}`, // 后端拿到的视频路径 |
| | | url: this.urlLink, // 后端拿到的视频路径 |
| | | enableWorker: true, //启用 Web Worker 进程来加速视频的解码和处理过程 |
| | | enableStashBuffer: false, // 启用数据缓存机制,提高视频的流畅度和稳定性。 |
| | | stashInitialSize: 1024, // 初始缓存大小。单位:字节。建议针对直播:调整为1024kb |
| | |
| | | if (emptyElement) { |
| | | emptyElement.style.display = 'none'; |
| | | } |
| | | |
| | | |
| | | this.videoTimer = setInterval(() => { |
| | | playDetection(this.carId); |
| | | }, 5000); |
| | |
| | | </div> |
| | | </div> |
| | | <div style="display: flex;justify-content: space-between;margin-top: 15px;margin-bottom: 12px;"> |
| | | <div style="font-weight: 500;font-size: 18px;color: rgba(0, 0, 0, 0.85);line-height: 25px;">车牌号:${ |
| | | record.vehicleNumber || "" |
| | | }</div> |
| | | <div style="font-weight: 500; font-size: 18px;color: rgba(0, 0, 0, 0.85);line-height: 25px;">驾驶员:${ |
| | | record.driverName || "" |
| | | }</div> |
| | | <div style="font-weight: 500;font-size: 18px;color: rgba(0, 0, 0, 0.85);line-height: 25px;">车牌号:${record.vehicleNumber || "" |
| | | }</div> |
| | | <div style="font-weight: 500; font-size: 18px;color: rgba(0, 0, 0, 0.85);line-height: 25px;">驾驶员:${record.driverName || "" |
| | | }</div> |
| | | </div> |
| | | <div style="display: flex; justify-content: space-between"> |
| | | <div style="font-weight: 500; font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;width: 200px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;" title="${ |
| | | record.location |
| | | }">位置:${record.location}</div> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">经纬度:${ |
| | | record.longitude + "," + record.latitude |
| | | }</div> |
| | | <div style="font-weight: 500; font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;width: 200px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;" title="${record.location |
| | | }">位置:${record.location}</div> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">经纬度:${record.longitude + "," + record.latitude |
| | | }</div> |
| | | </div> |
| | | <div style="display: flex; justify-content: space-between"> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">当前时速:${ |
| | | record.speed || "" |
| | | }${record.speed && "km/h"}</div> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">驾驶时长:${ |
| | | record.drivingTime |
| | | }</div> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">当前时速:${record.speed || "" |
| | | }${record.speed && "km/h"}</div> |
| | | <div style="font-weight: 500;font-size: 14px; color: rgba(0, 0, 0, 0.65);line-height: 26px;">驾驶时长:${record.drivingTime |
| | | }</div> |
| | | </div> |
| | | <div style="margin-top: 14px;display: flex;justify-content: flex-end;align-items: center;cursor: pointer;" onclick="toCarDetail(${ |
| | | record.id |
| | | <div style="margin-top: 14px;display: flex;justify-content: flex-end;align-items: center;cursor: pointer;" onclick="toCarDetail(${record.id |
| | | })"> |
| | | <div style="font-weight: 400;font-size: 18px; color: rgba(22, 119, 255, 1);line-height: 25px;">车辆详情</div> |
| | | <img style="width:18px;height: 18px;margin-left: 8px;" src="${require("../../assets//homeImg/right.png")}" /> |
| | |
| | | overflow: 'truncate', // 截断模式 |
| | | ellipsis: true, // 超出显示省略号 |
| | | rotate: -40, // 可以根据需要调整角度 |
| | | formatter: function(value) { |
| | | formatter: function (value) { |
| | | if (value.length > 4) { |
| | | return value.substring(0, 4) + '...'; |
| | | } |
| | |
| | | height: 100%; |
| | | } |
| | | } |
| | | |
| | | .mapTop { |
| | | z-index: 99; |
| | | position: absolute; |
| | |
| | | |
| | | .countCard { |
| | | flex: 1; |
| | | background: linear-gradient( |
| | | 180deg, |
| | | rgba(246, 246, 252, 0) 0%, |
| | | #f3f4f8 100% |
| | | ); |
| | | background: linear-gradient(180deg, |
| | | rgba(246, 246, 252, 0) 0%, |
| | | #f3f4f8 100%); |
| | | box-shadow: inset 0px -1px 4px 0px #ffffff; |
| | | border-radius: 10px; |
| | | border: 1px solid #f1f1f1; |
| | |
| | | text-transform: none; |
| | | margin-bottom: 10px; |
| | | } |
| | | .mt-0{ |
| | | |
| | | .mt-0 { |
| | | margin-top: 0 !important; |
| | | } |
| | | |
| | |
| | | color: rgba(82, 196, 26, 1); |
| | | } |
| | | } |
| | | |
| | | .fiveWarn { |
| | | background: rgba(214, 219, 228, 0.3); |
| | | |