|
<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="操作">
<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" 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.status==='未确认'" state="warning">未确认</t-tag>
<t-tag v-if="alarmDetailData.status==='已处理'" state="success">已处理</t-tag>
<t-tag v-if="alarmDetailData.status==='处理中'" state="info">处理中</t-tag>
<t-tag v-if="alarmDetailData.status==='误报'" state="danger">误报</t-tag>
</div>
</div>
<div class="detail">
<label class="detail_title">报警类型:</label>
<div class="detail_content">{{ alarmDetailData.alarmTypeCode || '' }}</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 }}</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 v-if="alarmDetailData.workEmployeeRoleId!==null" class="detail">
<label class="detail_title">处理人:</label>
<div class="detail_content">{{ alarmDetailData.workEmployeeRoleName }}</div>
</div>
<div v-if="alarmDetailData.workEmployeeRoleId!==null" class="detail">
<label class="detail_title">处理时间:</label>
<div>{{ alarmDetailData.doneDate }}</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>
<video :src="videoDetailData.videoFileUrl" class="video" controls></video>
</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 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 {
data () {
return {
searchdata: {
alarmTypeCode: '', // 报警类型
beginTime: '', // 开始时间
endTime: '' // 结束时间
},
// 报警类型
alarmtypelist: [],
// 报警人
aialarmhandlerlist: [],
// 模态框中的单选按钮
status: '',
// 模态框
details_modal: false,
// 当前行的数据
currentdata: {
index: '',
data: {}
},
// 报警详情数据
alarmDetailData: {},
// 图片详情数据
pictureDetailData: {},
// 视频详情数据
videoDetailData: {},
// 选择的数据
selectdata: [],
// 判断是详情还是处理
clickdetail: 0,
// 一页的数据
data: [{
'workTaskId': '202012031206570506796', //
'status': 'INI', // 状态
'statusTime': '2020-12-03T04:06:58.000+0000', // 状态时间
'processMemo': null, // 处理详情
'alarmTypeCode': 'HAT', // 报警类型
'alarmMemo': '没戴安全帽', // 报警描述
'resourceToolName': null, // 设备名称
'resourceToolCode': null, // 设备编号
'monitorSceneName': '一号工地', // 设备位置
'aiIdenTime': '2020-12-03T04:06:58.000+0000', // 报警时间l
'targetEmployeeRoleId': '1001',
'workEmployeeRoleId': '90001', // 处理人
'processTime': '', // 处理时间
'idenPictureUrl': 'http://pic/2970', // 图片url
'idenVideoUrl': 'http://video/8989' // 视频url
}
],
// 页数
page: 1,
limit: 10,
total: 0
}
},
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) {
this.alarmDetailData = res.data.data.alarmInfo
this.pictureDetailData = res.data.data.pictureInfo
this.videoDetailData = res.data.data.videoInfo
} else { this.$Message.danger('处理失败') }
this.status = ''
this.details_modal = true // 打开模态框
// this.currentdata.data = scope.row // 获取当前行的数据
this.currentdata.index = scope.$index // 获取当前行的索引
},
// 未确认状态的模态框的确认按钮 || 处理中状态的模态框的确认按钮
confimclick () {
// 获取单选框中的值
// console.log(this.msg)
// 判断是否选择了单选框
if (this.status) {
// 向后端发送数据
this.alarmdispose(this.currentdata.data.workTaskId, this.status)
// console.log(this.status)
// 关闭模态框
this.details_modal = false
} else {
this.$Message.warning('请选择按钮')
}
},
async alarmdispose (id, status, processMemo) {
const dict = { 'END': '已解决', 'RUN': '处理中', 'FAL': '误报' }
var res = await aialarmapi.dispose({ 'workTaskId': id, 'status': status, 'processMemo': dict.status })
// console.log(res)
if (res.status === 200) {
this.$Message.success('操作成功')
this.data[this.currentdata.index].status = res.data.data.status
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)
this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
} 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%;
object-fit: fill;
}
</style>
|