SmartSubstationPlatform/riis-web/src/views/task/silentmonitor/index.vue
2025-04-24 14:53:21 +08:00

513 lines
18 KiB
Vue

<script lang="ts">
export default {
name: "silentmonitor", // 静默监视
};
</script>
<script setup lang="ts">
import Page from '@/components/Pagination/page.vue'
import { ref, onMounted, nextTick } from "vue";
import JessibucaPlayer from '@/components/jessibuca/index1.vue'
import { ElMessage } from "element-plus";
import { getAlarmListByType,getAlarmListPage,getSubstationAreaByCode } from "@/api/silentmonitor";
import { getDeviceByType } from "@/api/device";
import moment from 'moment'
import axios from 'axios';
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
const treeloading = ref(false)
const tableData:any = ref([])
// 查询参数
const queryInfo:any = ref({
current: 1, // 当前页
size:10, // 页大小
stationId:userStore.stationId,
areaId:'', // 区域ID
patrolDeviceName:'', // 摄像机名称
monitorType:'', // 告警类型
startDate: '', // 开始时间
endDate: '',// 结束时间
desc:'',
})
const dateArr: any = ref([])
tableData.value = []
const alarmInfo:any = ref({})
const total = ref(0)
function getData() { // 获取列表信息
queryInfo.value.startDate = ""
queryInfo.value.endDate = ""
if (dateArr.value != null && dateArr.value.length != 0) {
queryInfo.value.startDate = dateArr.value[0]
queryInfo.value.endDate = dateArr.value[1]
}
treeloading.value = true
getAlarmListByType(queryInfo.value).then((res: any) => {
treeloading.value = false
tableData.value = res.data.records
total.value = res.data.total
}).catch(()=>{
treeloading.value = false
})
}
//重置
function resetting() {
queryInfo.value = {
current: 1, // 当前页
size:10, // 页大小
stationId:userStore.stationId,
areaId:'', // 区域ID
patrolDeviceName:'', // 摄像机名称
monitorType:'', // 告警类型
startDate: '', // 开始时间
endDate: '',// 结束时间
}
dateArr.value = []
getData()
}
const playDeviceId = ref("")
const playChannelId = ref("")
function queryRecordDetails(row:any){
playDeviceId.value = ""
playChannelId.value = ""
let startTimeStr = moment(new Date(row).getTime() - 15*1000).format("YYYY-MM-DD HH:mm:ss");
let endTimeStr = moment(new Date(row).getTime() + 15*1000).format("YYYY-MM-DD HH:mm:ss");
axios.get(userStore.webApiMonitorUrl + '/api/gb_record/queryNvrRecord/' + alarmInfo.value.patroldeviceCode + '/' +alarmInfo.value.patroldeviceCode + '?startTime=' + startTimeStr + '&endTime=' + endTimeStr, {}).then((res: any) => {
if(res.data.code === 0) {
// 处理时间信息
clickNum.value = clickNum.value +1
playDeviceId.value = res.data.data.deviceId
playChannelId.value = res.data.data.channelId
setTime(startTimeStr, endTimeStr);
playRecord()
}
}).catch(function (error: any) {
})
}
function rowClick(row:any){
if(row.areaId == alarmInfo.value.areaId && row.monitorType == alarmInfo.value.monitorType ){
return
}
alarmInfo.value = row
queryRecordDetails(row.alarmDate)
getGiveanalarm()
}
function rowGiveanalarmClick(row:any){
queryRecordDetails(row.alarmDate)
}
const startTime = ref('')
const endTime = ref('')
const tmpTime = ref(0)
const tmpStartTime = ref(0) // 视频开始时间
function setTime(startTimes:any, endTimes:any){
startTime.value = startTimes;
endTime.value = endTimes;
tmpTime.value = new Date(endTimes).getTime() - new Date(startTimes).getTime()
tmpStartTime.value = new Date(startTimes).getTime()
}
const streamId = ref("")
function gbPlay(){// 视频回放播放功能
axios.get(userStore.webApiMonitorUrl + '/api/playback/resume/' + streamId.value, {}).then((res: any) => {
}).catch(function (error: any) {
});
}
function gbPause(){ // 视频回放暂停功能
axios.get(userStore.webApiMonitorUrl + '/api/playback/pause/' + streamId.value, {}).then((res: any) => {
}).catch(function (error: any) {
})
}
const videoUrl = ref('ws://192.168.1.119:81/rtp/47868E3C.live.flv')
const isCheckAll = ref(false)
const AreaList:any = ref([]) // 告警等级
const SilentMonitoringTypeList:any = ref([])
const checkFlagList:any = ref([{
id:"0",
itemcode:"0",
dictname:"未核查"
},{
id:"1",
itemcode:"1",
dictname:"已审核"
},{
id:"2",
itemcode:"2",
dictname:"已修正"
}
])
function getArrType() { // 查询字典方法
const params = {
stationCode: userStore.stationCode
}
getSubstationAreaByCode(params).then((res: any) => {
AreaList.value = res.data
})
const paramstypes = {
dictcode: 'SilentMonitoringType'
}
getDeviceByType(paramstypes).then((res: any) => {
SilentMonitoringTypeList.value = res.data
})
}
function currency(list: any, itemcode: any) {
let dictname = ''
list.forEach((element: any) => {
if (element.itemcode == itemcode) {
dictname = element.dictname
}
})
return dictname
}
const streamInfo:any = ref({})
const app = ref("")
const mediaServerId = ref("")
const ssrc = ref("")
const clickNum = ref(0)
const recordVideoPlayer:any = ref(null)
function stopPlayRecord (callback:any) {
recordVideoPlayer.value.pause()
videoUrl.value = '';
axios.get(userStore.webApiMonitorUrl + '/api/playback/stop/' + playDeviceId.value + "/" + playChannelId.value + "/" + streamId.value, {}).then((res: any) => {
if (callback) callback()
})
}
function sliderChange(e:any){
if (streamId.value !== "") {
stopPlayRecord(()=> {
streamId.value = "";
sliderChange(e);
})
} else {
axios.get(userStore.webApiMonitorUrl + '/api/playback/start/' + playDeviceId.value + "/" + playChannelId.value + '?startTime=' + e + '&endTime=' + endTime.value, {}).then((res: any) => {
if(res.data.code === 0) {
// 处理时间信息
streamInfo.value = res.data.data;
app.value = res.data.data.app;
streamId.value = res.data.data.stream;
mediaServerId.value = res.data.data.mediaServerId;
ssrc.value = res.data.data.ssrc;
videoUrl.value = getUrlByStreamInfo()
}
}).catch(function (error: any) {
});
}
}
function playRecord (){
if (streamId.value !== "") {
stopPlayRecord(()=> {
streamId.value = "";
playRecord();
})
} else {
axios.get(userStore.webApiMonitorUrl + '/api/playback/start/' + playDeviceId.value + "/" + playChannelId.value + '?startTime=' + startTime.value + '&endTime=' + endTime.value, {}).then((res: any) => {
if(res.data.code === 0) {
// 处理时间信息
streamInfo.value = res.data.data;
app.value = res.data.data.app;
streamId.value = res.data.data.stream;
mediaServerId.value = res.data.data.mediaServerId;
ssrc.value = res.data.data.ssrc;
videoUrl.value = getUrlByStreamInfo()
}
}).catch(function (error: any) {
});
}
}
function getUrlByStreamInfo(){
if (location.protocol === "https:") {
videoUrl.value = streamInfo.value["wss_flv"]
}else {
videoUrl.value = streamInfo.value["ws_flv"]
}
return videoUrl.value;
}
const giveanalarmData:any = ref([])
const giveanalarmArr:any = ref([])
const searchInfo:any =ref({
current: 1, // 当前页
size:10, // 页大小
})
const giveanalarmloading:any =ref(false)
const giveanalarmtotal:any =ref(0)
function resetgiveanalarm() {// 重置告警信息
giveanalarmArr.value = []
getGiveanalarm()
}
function getGiveanalarm() { // 获取列表信息
searchInfo.value.startDate = ""
searchInfo.value.endDate = ""
if (giveanalarmArr.value != null && giveanalarmArr.value.length != 0) {
searchInfo.value.startDate = giveanalarmArr.value[0]
searchInfo.value.endDate = giveanalarmArr.value[1]
}
searchInfo.value.patrolDeviceCode = alarmInfo.value.patroldeviceCode
searchInfo.value.monitorType = alarmInfo.value.monitorType
giveanalarmloading.value = true
getAlarmListPage(searchInfo.value).then((res: any) => {
giveanalarmloading.value = false
for(let i = 0 ;i<res.data.records.length;i++){
res.data.records[i].smallFilePath = userStore.webApiBaseUrl +"/previewimage?size=small&filename=" + encodeURI(res.data.records[i].defectFilePath)
res.data.records[i].srcList = [userStore.webApiBaseUrl +"/previewimage?filename=" + encodeURI(res.data.records[i].defectFilePath)]
res.data.records[i].defectFilePath = userStore.webApiBaseUrl +"/previewimage?filename=" + encodeURI(res.data.records[i].defectFilePath)
}
giveanalarmData.value = res.data.records
giveanalarmtotal.value = res.data.total
}).catch(()=>{
giveanalarmloading.value = false
})
}
function sortChange(column:any){
if(column.order == "descending"){
if(column.prop == "count"){
queryInfo.value.asc = "count"
queryInfo.value.desc = null
}else{
queryInfo.value.asc = "alarmDate"
queryInfo.value.desc = null
}
// 正序
} else if(column.order == "ascending") {
if(column.prop == "count"){
queryInfo.value.asc = null
queryInfo.value.desc = "count"
}else{
queryInfo.value.asc = null
queryInfo.value.desc = "alarmDate"
}
// column.order == "ascending" 上升
} else {
queryInfo.value.asc = null
queryInfo.value.desc = null
}
getData()
}
const ImgPath = ref("")
onMounted(() => {
let endDate = moment(new Date()).format('YYYY-MM-DD')
const now = new Date(endDate)
const year = now.getFullYear();
const month = now.getMonth();
const day = now.getDate();
let startDate = moment( new Date(year,month-1,day)).format('YYYY-MM-DD')
giveanalarmArr.value=[startDate,endDate]
getArrType()
getData()
})
</script>
<template>
<div class="alarmInfo-box">
<div class="alarmInfo-left">
<div style="position: relative;display: flex;align-items: center; justify-content: space-between;">
<div style="display: flex;align-items: center;padding:5px 0;" >
<el-input v-model="queryInfo.patrolDeviceName" style="width:200px" placeholder="摄像机名称" clearable class="marginright"
@clear="getData()" @keyup.enter="getData()" />
<el-select v-model="queryInfo.areaId" class="marginright" placeholder="区域" @change="getData" :teleported="false" :popper-append-to-body="false" clearable>
<el-option v-for="item in AreaList" :key="item.areaId" :label="item.areaName" :value="item.areaId" />
</el-select>
<el-select v-model="queryInfo.monitorType" placeholder="告警类型" @change="getData" :teleported="false" :popper-append-to-body="false" clearable>
<el-option v-for="item in SilentMonitoringTypeList" :key="item.id" :label="item.dictname" :value="item.itemcode" />
</el-select>
<el-button class="searchButton" type="primary" @click="getData">搜索</el-button>
<el-button class="searchButton" type="primary" @click="resetting">重置</el-button>
</div>
</div>
<el-table :data="tableData"
v-loading="treeloading" highlight-current-row element-loading-background="rgb(11, 40, 34)"
style="width: 100%;margin:auto;position: relative;margin-top: 15px; height:calc(100vh - 270px); overflow: auto "
stripe :header-cell-style="tableBg"
@row-click="rowClick" @sort-change="sortChange"
>
<el-table-column type="index" align="center" label="序号" width="50px" />
<el-table-column prop="patroldeviceName" label="摄像机名称" />
<el-table-column prop="areaName" label="区域名称" />
<el-table-column prop="place" label="安装位置" />
<el-table-column prop="monitorType" label="告警类型" width="160px" align="center">
<template #default="scope">
<span>{{currency(SilentMonitoringTypeList,scope.row.monitorType)}}</span>
</template>
</el-table-column>
<el-table-column prop="alarmDate" label="最近告警时间" width="170px" align="center" sortable="alarmDate"/>
<el-table-column prop="count" label="告警次数" width="120px" align="center" sortable="custom">
<template #default="scope">
<span style="color: #FFBD00;">{{scope.row.count}}</span>
</template>
</el-table-column>
</el-table>
<div style="display: flex;justify-content: center;margin-top: 5px;">
<Page style="position: relative;z-index: 100;" :total="total" v-model:size="queryInfo.size"
v-model:current="queryInfo.current" @pagination="getData()"></Page>
</div>
</div>
<div class="alarmInfo-right">
<div style="width: 100%;height: 50%;">
<div style="display:flex;align-items: center;">
<div class="alarmInfo-line"></div>
<div class="alarmInfo-title">历史录像 <span style="font-weight: 100;color: #fff;font-size: 16px;"> (视频采集前后15秒)</span></div>
</div>
<div class="video-box">
<div v-if="alarmInfo.patroldeviceCode == undefined">
<img src="@/assets/monitorsystem/gjqr_wsp.png">
<div style=" font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 18px;
color: rgba(255, 255, 255, 0.6);
text-align: center;
padding-top: 10px;">暂无视频</div>
</div>
<JessibucaPlayer v-if="alarmInfo.patroldeviceCode != undefined" ref="recordVideoPlayer" :isrecord="'alarmInfo'" :_uid="99" :visible.sync="true" :videoUrl="videoUrl" height="100px"
:tmpTime="tmpTime"
:endTime="endTime" :tmpStartTime="tmpStartTime"
:hasAudio="false" fluent autoplay live
:clickNum="clickNum" @sliderChange="sliderChange" @gbPlay="gbPlay" @gbPause="gbPause"></JessibucaPlayer>
</div>
</div>
<div class="alarmInfo-visitation">
<div style="display:flex;align-items: center;height: 40px;padding-left: 15px;padding-top:10px">
<div class="alarmInfo-line"></div>
<div class="alarmInfo-title">告警列表</div>
</div>
<div class="alarmimg">
<div v-if="alarmInfo.patroldeviceCode == undefined">
<img src="@/assets/monitorsystem/jmjs_wnr.png">
<div style="font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 18px;
color: rgba(255, 255, 255, 0.6);
text-align: center;
padding-top: 10px;">暂无内容</div>
</div>
<div style="width:100%;height:100%;padding:0 20px" v-if="alarmInfo.patroldeviceCode != undefined">
<div style="display: flex;align-items: center;padding-top:20px">
<span>告警时间:</span>
<el-date-picker v-model="giveanalarmArr" type="daterange" range-separator="至" start-placeholder="开始时间"
popper-class="elDatePicker" format="YYYY-MM-DD" value-format="YYYY-MM-DD" end-placeholder="结束时间" :clearable="false" style="max-width: 370px;"
@change="getGiveanalarm"/>
</div>
<el-table :data="giveanalarmData" stripe :header-cell-style="tableBg"
v-loading="giveanalarmloading" highlight-current-row element-loading-background="rgb(11, 40, 34)"
style="width: 100%;margin:auto;position: relative;margin-top: 15px; height:calc(100% - 85px); overflow: auto "
@row-click="rowGiveanalarmClick">
<el-table-column type="index" align="center" label="序号" width="50px" />
<el-table-column prop="alarmDate" label="告警时间" width="170px" align="center"/>
<el-table-column prop="content" label="告警信息" />
<el-table-column prop="defectFilePath" label="告警图片" width="90px" show>
<template #default="scope">
<el-image
style="width: 40px; height: 40px"
:src="scope.row.smallFilePath"
:zoom-rate="1.2"
:preview-src-list="scope.row.srcList"
:preview-teleported="true"
fit="cover"
/>
</template>
</el-table-column>
</el-table>
<Page style="position: relative;z-index: 100;margin-top: 5px;" :total="giveanalarmtotal" v-model:size="searchInfo.size"
v-model:current="searchInfo.current" @pagination="getGiveanalarm()"
:jumper="'hide'"
></Page>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.alarmInfo-box {
display: flex;
justify-content: space-between;
padding: 15px;
padding-top: 60px;
padding-bottom: 0;
.alarmInfo-left{
padding: 8px 15px;
margin-right: 15px;
width: calc(65vw);
height: calc(100vh - 160px);
background: url(@/assets/newimg/xsjk_1235_700.png);
background-size: 100% 100%;
}
.alarmInfo-right{
width: calc(33.5vw);
height: calc(100vh - 160px);
display: flex;
flex-wrap: wrap;
align-content: space-between;
overflow:auto;
.alarmInfo-line{
width: 4px;
height: 15px;
background: inherit;
background-color: #009BFF;
margin-right: 8px;
}
.alarmInfo-title{
font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
font-weight: 700;
font-style: normal;
font-size: 18px;
color: #ffffff;
}
.video-box{
width: 100%;
height: calc(100% - 45px);
background-color: rgba(40, 40, 40, 1);
margin-top: 10px;
display:flex;
justify-content:center;
align-items:center;
}
.alarmInfo-visitation{
width: 100%;
height: 50%;
background: url(@/assets/patrolmonitor/xsjk_640.png);
background-size: 100% 100%;
}
.alarmimg{
width: 100%;
height: calc(100% - 65px);
display:flex;
align-items:center;
justify-content:center;
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 14px;
color: #FFFFFF;
}
}
}
.searchButton {
// border: #059a67 solid 1px;
// background-color: #08503a;
// color: #00F9A2;
margin-left: 10px;
}
.marginright{
margin-right: 10px;
}
</style>