|
<template>
<div class="ai_alarm">
<!-- 顶部的查询组件 -->
<div class="alarm_header">
<div>
<span class="title">报警类型 : </span>
<t-select v-model="searchdata.alarmTypeCode" style="width:200px;height:32px">
<t-option v-for="item in alarmtypelist" :key="item.code" :value="item.code">{{ item.value }}</t-option>
</t-select>
</div>
<div>
<span class="title">开始时间 : </span>
<t-date-picker :confirm="false" v-model="searchdata.beginTime" placeholder="请选择开始时间" style="width:200px;height:32px"></t-date-picker>
</div>
<div>
<span class="title">结束时间 : </span>
<t-date-picker :confirm="false" v-model="searchdata.endTime" placeholder="请选择结束时间" style="width:200px;height:32px"></t-date-picker>
</div>
</div>
<div class="alarm_header">
<!-- <div class="alarm_people">
<span class="title">报警人 : </span>
<t-select v-model="searchdata.handler" style="width:200px;height:32px">
<t-option value="你好">选项1</t-option>
<t-option value="世界">选项2</t-option>
<t-option v-for="item in aialarmhandlerlist" :value="item.id" :key="item.id">{{ item.alarmhandler }}</t-option>
</t-select>
</div> -->
<!-- 导出excel组件 -->
<div>
<t-button color="primary" icon="upload" style="width:128px;height:32px" class="upload">导出至Excel</t-button>
</div>
<div>
<t-button color="primary" @click="btnsearch">查询</t-button>
<t-button @click="reset">重置</t-button>
</div>
</div>
<!-- 表格 -->
<t-table :data="data" line @selection-change="handleSelectionChange">
<t-table-column type="selection" width="50"></t-table-column>
<t-table-column label="状态" width="100">
<template slot-scope="scope">
<t-tag v-if="scope.row.status=== 'RUN'" state="info">处理中</t-tag>
<t-tag v-if="scope.row.status=== 'INI'" state="warning">未确认</t-tag>
<t-tag v-if="scope.row.status=== 'END'" state="success">已处理</t-tag>
<t-tag v-if="scope.row.status=== 'FAL'" state="danger">误报</t-tag>
</template>
</t-table-column>
<t-table-column label="报警类型" prop="alarmTypeName">
</t-table-column>
<t-table-column label="报警描述" prop="alarmMemo" width="110">
</t-table-column>
<t-table-column label="设备名称" prop="resourceToolName" width="110">
</t-table-column>
<t-table-column label="设备编号" prop="resourceToolCode" width="90">
</t-table-column>
<t-table-column label="设备位置" prop="monitorSceneName" width="120">
</t-table-column>
<t-table-column label="报警时间" prop="aiIdenTime" width="160px">
</t-table-column>
<t-table-column label="处理人" prop="workEmployeeRoleName" width="70">
</t-table-column>
<t-table-column label="处理时间" prop="processTime" width="160px">
</t-table-column>
<t-table-column label="操作" width="120">
<template slot-scope="scope">
<a href="javascript:void(0)" size="sm" style="color:#0089D4" @click="handleClick(scope,0)">详情</a>
<a v-if="scope.row.status=='RUN'||scope.row.status=='FAL'" style="color:#0089D4" @click="handleClick(scope,1)">关闭</a>
<a v-if="scope.row.status=='INI'" style="color:#0089D4" @click="handleClick(scope,1)">处理</a>
</template>
</t-table-column>
</t-table>
<!-- 分页 -->
<t-pager :total="total" :current="page" :page-size="limit" show-elevator class="pager" @on-change="onChange"></t-pager>
<!-- 模态框-->
<t-modal :visibled.sync="details_modal" :title="clickdetail==0?'报警详情':'报警处理'" width="732px">
<div style="text-align:center">
<div class="details_item1">
<div class="detail">
<label class="detail_title">状态:</label>
<div class="detail_content">
<t-tag v-if="alarmDetailData.statusZh==='未确认'" state="warning">未确认</t-tag>
<t-tag v-if="alarmDetailData.statusZh==='已处理'" state="success">已处理</t-tag>
<t-tag v-if="alarmDetailData.statusZh==='处理中'" state="info">处理中</t-tag>
<t-tag v-if="alarmDetailData.statusZh==='误报'" state="danger">误报</t-tag>
</div>
</div>
<div class="detail">
<label class="detail_title">报警类型:</label>
<div class="detail_content">{{ alarmDetailData.alarmTypeCodeZh || '' }}</div>
</div>
<div class="detail">
<label class="detail_title">报警描述:</label>
<div class="detail_content">{{ alarmDetailData.alarmMemo }}</div>
</div>
<div class="detail">
<label class="detail_title">报警时间:</label>
<div class="detail_content">{{ alarmDetailData.aiIdenTime|formatDateTime }}</div>
</div>
<div class="detail">
<label class="detail_title">设备编号:</label>
<div class="detail_content">{{ alarmDetailData.resourceToolCode ||'暂无编号' }}</div>
</div>
<div class="detail">
<label class="detail_title">设备位置:</label>
<div class="detail_content">{{ alarmDetailData.monitorSceneName }}</div>
</div>
<div class="detail">
<label class="detail_title">处理人:</label>
<div class="detail_content">{{ alarmDetailData.workEmployeeRoleName|| '--' }}</div>
</div>
<div class="detail">
<label class="detail_title">处理时间:</label>
<div>{{ alarmDetailData.disposeDate || '--' }}</div>
</div>
</div>
<div class="details_item2">
<div>
<div>识别图片</div>
<div><img :src="pictureDetailData.fileUrl" alt="" srcset="" style="width:100%;height:100%"></div>
</div>
<div>
<div>识别视频</div>
<div class="video">
<!-- <video :src="videoDetailData.videoFileUrl" class="video" controls></video> -->
<video-player ref="videoPlayer" :playsinline="true" :options="playerOptions" class="video-player vjs-custom-skin"></video-player>
</div>
</div>
</div>
<div v-if="clickdetail==1">
<div v-if="alarmDetailData.status!='END'" class="radio">
<div>报警处理 : </div>
<div v-if="alarmDetailData.status=='INI'">
<t-radio-group v-model="status">
<t-radio label="RUN">
<span>确认</span>
</t-radio>
<t-radio label="FAL">
<span>误判</span>
</t-radio>
</t-radio-group>
</div>
<div v-if="alarmDetailData.status=='RUN'||alarmDetailData.status=='FAL'">
<t-radio-group v-model="status">
<t-radio label="END">关闭</t-radio>
</t-radio-group>
</div>
</div>
</div>
</div>
<div slot="footer">
<div v-if="clickdetail==1">
<div>
<t-button @click="details_modal=false">取消</t-button>
<t-button :loading="loading" color="primary" @click="confimclick">确认</t-button>
</div>
</div>
<div v-else>
<t-button type="danger" long @click="details_modal=false">关闭</t-button>
</div>
</div>
</t-modal>
</div>
</template>
<script>
import aialarmapi from '@/api/aialarm'
import formatDateTime from '@/utils/formatDateTime.js'
export default {
filters: {
formatDateTime
},
data () {
return {
searchdata: {
alarmTypeCode: '', // 报警类型
beginTime: '', // 开始时间
endTime: '' // 结束时间
},
// 报警类型
alarmtypelist: [],
// 报警人
aialarmhandlerlist: [],
// 模态框中的单选按钮
status: '',
// 模态框
details_modal: false,
// 当前行的数据
currentdata: {
index: '',
data: {}
},
// 报警详情数据
alarmDetailData: {},
// 图片详情数据
pictureDetailData: {},
// 视频详情数据
videoDetailData: {},
// 选择的数据
selectdata: [],
// 判断是详情还是处理
clickdetail: 0,
// 一页的数据
data: [],
// 页数
page: 1,
limit: 10,
total: 0,
loading: false,
playerOptions: {
playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
autoplay: false, // 如果true,浏览器准备好时开始回放。
muted: true, // 默认情况下将会消除任何音频。
loop: false, // 导致视频一结束就重新开始。
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: 'zh-CN',
aspectRatio: '13:10', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
// fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
// 是否流体自适应容器宽高
fluid: true,
// // 设置视频播放器的显示宽度(以像素为单位)
// width: '100px',
// // 设置视频播放器的显示高度(以像素为单位)
// height: '300px',
sources: [{
type: 'video/mp4', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
src: '' // url地址
}],
notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true,
// durationDisplay: true,
remainingTimeDisplay: false,
fullscreenToggle: true, // 全屏按钮,
pictureInPictureToggle: false
}
}
}
},
mounted () {
this.gettype()
this.search()
},
methods: {
// 选择行
handleSelectionChange (val) {
// console.log(val)
this.selectdata = val
},
// 点击详情
async handleClick (scope, val) {
this.clickdetail = val
// 去除模态框中的单选项
let res = await aialarmapi.getAlarmDetail({ params: { 'workTaskId': scope.row.workTaskId } })
if (res.status === 200) {
console.log(res.data.data)
this.alarmDetailData = res.data.data.alarmInfo
this.pictureDetailData = res.data.data.pictureInfo
this.videoDetailData = res.data.data.videoInfo
if (this.videoDetailData) {
// console.log(2222222222222)
this.playerOptions.sources[0].src = this.videoDetailData.videoFileUrl
} else {
this.playerOptions.sources[0].src = ''
}
// console.log(this.playerOptions.sources[0].src)
} else { this.$Message.danger('处理失败') }
this.status = ''
this.details_modal = true // 打开模态框
// this.currentdata.data = scope.row // 获取当前行的数据
this.currentdata.index = scope.$index // 获取当前行的索引
},
// 未确认状态的模态框的确认按钮 || 处理中状态的模态框的确认按钮
confimclick () {
this.loading = true
// 获取单选框中的值
// console.log(this.msg)
// 判断是否选择了单选框
if (this.status) {
// 向后端发送数据
this.alarmdispose(this.alarmDetailData.workTaskId, this.status)
// console.log(this.status)
} else {
this.$Message.warning('请选择按钮')
this.loading = false
}
},
async alarmdispose (id, status, processMemo) {
const dict = { 'END': '已解决', 'RUN': '处理中', 'FAL': '误报' }
// console.log(id, status, dict[status])
var res = await aialarmapi.dispose({ 'workTaskId': id, 'status': status, 'processMemo': dict.status })
if (res.status === 200) {
this.$Message.success('操作成功')
this.search()
this.loading = false
// 关闭模态框
this.details_modal = false
this.$store.commit('alarm/add', 1)
// this.data[this.currentdata.index].status = res.data.data.status
// if (res.data.data.status === 'END') {
// this.data[this.currentdata.index].processTime = res.data.data.doneDate
// }
} else {
this.$Message.danger('处理失败')
}
},
onChange (val) {
// console.log(val)
this.page = val
this.search()
},
// 点击查询按钮
btnsearch () {
if (this.page === 1) {
this.search()
} else {
this.page = 1
}
},
// 获取报警类型
async gettype () {
var res = await aialarmapi.getAiAlarmType()
// console.log(res)
if (res.status === 200) {
// this.alarmtypelist = res.data.data
// console.log(this.alarmtypelist)
// console.log(res.data)
this.alarmtypelist = res.data
}
},
// 查询数据时
async search () {
var flag = this.startreend(this.searchdata.beginTime, this.searchdata.endTime)
// console.log(flag)
if (flag) {
// 查询
var params = this.searchdata
params.pageNumber = this.page
params.pageSize = this.limit
var res = await aialarmapi.getAiAlarmList({
params: params
})
// console.log(res)
if (res.status === 200) {
this.data = res.data.data.data
this.data = this.data.map((item) => { item.aiIdenTime = formatDateTime(item.aiIdenTime); return item })
console.log(this.data)
console.log('数据是', res)
// this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
this.total = res.data.data.total
} else {
this.$Message.danger('数据获取失败')
}
} else {
this.$Message.danger('开始时间不能在结束时间的后面')
}
},
// 重置
reset () {
for (var index in this.searchdata) {
this.searchdata[index] = ''
}
// console.log(this.searchdata)
this.page = 1
this.$Message.success('数据重置成功')
},
// 字符串更改为时间类型
stringtodate (date) {
date = date.substring(0, 19)
date = date.replace(/-/g, '/')
var timestamp = new Date(date).getTime()
return timestamp
},
// 验证开始时间·和结束时间
startreend (startdate, enddate) {
startdate = this.stringtodate(startdate)
enddate = this.stringtodate(enddate)
if (startdate > enddate) {
return false
} else {
return true
}
}
}
}
</script>
<style lang='scss' >
.ai_alarm {
font-size: 14px;
padding: 6px 24px;
.upload {
font-size: 14px;
line-height: 22px;
}
.table th,
.table td {
padding: 0 0 0 21px;
}
.alarm_header {
display: flex;
justify-content: space-between;
margin-top: 24px;
margin-bottom: 24px;
.title {
display: inline-block;
width: 70px;
height: 20px;
font-size: 14px;
text-align: right;
color: rgba($color: #000000, $alpha: 0.65);
}
}
}
.pager {
float: right;
margin-top: 26px;
}
.details_item1 {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
height: 192px;
align-items: center;
border-radius: 4px;
background-color: rgba(245, 245, 245, 1);
padding: 0 16px;
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
.detail {
width: 49%;
display: flex;
.detail_title {
display: block;
width: 70px;
height: 22px;
text-align: right;
}
.detail_content {
flex: 1;
text-align: left;
}
}
}
.details_item2 {
display: flex;
justify-content: space-between;
margin-top: 24px;
> div {
width: 49%;
> div:nth-child(1) {
text-align: left;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
margin-bottom: 8px;
}
> div:nth-child(2) {
height: 250px;
// border: 1px solid black;
border-radius: 5px;
overflow: hidden;
}
}
}
.radio {
margin-top: 19px;
float: left;
display: flex;
align-items: center;
> div:nth-child(1) {
margin-right: 5px;
}
}
.video {
width: 100%;
height: 100%;
margin: 0 auto;
}
</style>
|