<template>
|
<div class="app-container">
|
<el-row :gutter="24" style="display: flex;flex-wrap: wrap">
|
<el-col :span="6" v-for="item in cameraList" :key="item.id">
|
<el-card class="box-card" :body-style="{ padding: '0px' }">
|
<div slot="header" class="clearfix">
|
<span style="font-weight: 800;margin-right: 10px">{{ item.name }}</span>
|
<span
|
style="font-size: 12px;color: deepskyblue; border: 1px solid deepskyblue;padding: 2px 5px;border-radius:8px; ">{{
|
item.regionName
|
}}</span>
|
<el-dropdown trigger="click" style="float: right; padding: 3px 0;cursor:pointer;">
|
<div type="text"><i class="el-icon-more" style="font-size: 24px;color: #9a9a9a"></i></div>
|
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-item class="dropdown-item">
|
<div @click="openDetails(item.id)">详情</div>
|
</el-dropdown-item>
|
<el-dropdown-item class="dropdown-item">
|
<div @click="handleUpdate(item.id)">编辑</div>
|
</el-dropdown-item>
|
<el-dropdown-item class="dropdown-item">
|
<div @click='handleDelete(item.id)'>删除</div>
|
</el-dropdown-item>
|
<el-dropdown-item class="dropdown-item">
|
<div @click='getCameraPic(item.id)'>抓图</div>
|
</el-dropdown-item>
|
</el-dropdown-menu>
|
</el-dropdown>
|
</div>
|
<div class="text item">
|
<div class="text-top">
|
<div class="text-top-img">
|
<el-image
|
style="width: 210px;height: 128px"
|
:src="imgUrl+item.picture"
|
:preview-src-list="[imgUrl+item.picture]"
|
fit="cover">
|
</el-image>
|
</div>
|
<!-- <div class="text-top-img">-->
|
<!-- <img :src="item.picture" style="width: 210px;height: 128px">-->
|
<!-- </div>-->
|
<div class="text-top-cantent">
|
<p>型号:{{ item.cameraModel }}</p>
|
<!-- <p>状态: {{ item.status == 1 ? '在线' : '离线' }}</p>-->
|
<p>状态:<dict-tag style="display: inline-block;margin: 0 0 0 5px;" :options="dict.type.sys_line_status"
|
:value="item.status"/></p>
|
<p>报警:<span style="text-decoration:underline; color: red;">{{ item.alarmCount }}</span></p>
|
</div>
|
</div>
|
<div class="text-top-btext">
|
<p>运行算法: <span v-for="i in item.rules" :key="i.id"
|
style="font-size: 12px;color: yellowgreen;margin: 0 0 0 5px; border: 1px solid yellowgreen;padding: 2px 8px;border-radius:8px; ">{{i.ruleName }}</span></p>
|
</div>
|
</div>
|
<div class="text item text-bottom">
|
<el-button type="warning" icon="el-icon-video-camera" @click="videoClick(item)">视频预览</el-button>
|
<el-button type="primary" icon="el-icon-video-play" @click="openfiring(item.id)">重启设备</el-button>
|
|
</div>
|
</el-card>
|
</el-col>
|
<!-- <el-col :span="24" v-if="!cameraList.length">-->
|
<!-- <el-card class="box-card" :body-style="{ padding: '0px' }">-->
|
<!-- <div style="display: flex;justify-content: center;align-items: center">-->
|
<!-- <div>-->
|
<!-- <img style="width: 500px" src="@/assets/401_images/401.gif">-->
|
<!-- <h1>暂无设备...... 亲 你可以点击下方新增按钮 增加设备</h1>-->
|
<!-- </div>-->
|
|
<!-- </div>-->
|
<!-- </el-card>-->
|
<!-- </el-col>-->
|
</el-row>
|
<div class="button-bottom">
|
<el-button size="medium" plain icon="el-icon-plus" @click="handleAdd">新增设备</el-button>
|
<el-button size="medium" plain icon="el-icon-video-play" @click="openfiringAll">全部重启</el-button>
|
</div>
|
<el-drawer
|
title="设备详情"
|
:visible.sync="drawer"
|
direction="rtl"
|
size="45%">
|
<div style="padding: 20px">
|
<el-card class="right-card">
|
<div slot="header" class="clearfix">
|
<span class="clearfix-left"></span><span style="font-weight: 800;margin-right: 10px">基本信息</span>
|
</div>
|
<div class="text">
|
<div class="text-center">
|
<div class="text-top-img">
|
<img :src="imgUrl+form.picture">
|
</div>
|
<div class="text-top-cantent">
|
<div class="text-top">
|
<div class="text-top-left">
|
<p>设备名称:<span>{{ form.name }}</span></p>
|
<p>布防区域:<span>{{ form.regionName }}</span></p>
|
<p>登录账号:<span>{{ form.cameraUser }}</span></p>
|
<p>设备IP:<span>{{ form.cameraIp }}</span></p>
|
</div>
|
<div class="text-top-right">
|
<p>设备型号:<span>{{ form.cameraModel }}</span></p>
|
<!-- <p>设备状态:<span v-if="form.status==1"-->
|
<!-- style="font-size: 12px;color: #69f784; border: 1px solid #69f784;padding: 2px 8px;border-radius:8px; ">在线</span>-->
|
<!-- <span v-else-->
|
<!-- style="font-size: 12px;color: red; border: 1px solid red;padding: 2px 8px;border-radius:8px; ">离线</span>-->
|
<!-- </p>-->
|
<p>设备状态:<dict-tag style="height: 20px;display: inline-block;margin: 0 0 0 5px;" :options="dict.type.sys_line_status"
|
:value="form.status"/></p>
|
<p>登录密码:<span>{{ form.cameraPassword }}</span></p>
|
<p>设备端口:<span>{{ form.cameraPort }}</span></p>
|
</div>
|
</div>
|
<div class="text-bottom">
|
<el-button type="warning" icon="el-icon-video-camera" @click="openvideo=true">视频预览</el-button>
|
<el-button type="primary" style="background-color:red;border: 0;" icon="el-icon-video-pause"
|
@click="openfiring(form.id)">重启设备
|
</el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
<div class="text-top-btext">
|
<el-card class="right-card">
|
<div slot="header" class="clearfix">
|
<span class="clearfix-left"></span><span style="font-weight: 800;margin-right: 10px">算法信息</span>
|
</div>
|
<div class="text item">
|
<el-table v-loading="loading" :data="form.rules">
|
<el-table-column label="执行算法" align="center" prop="ruleId">
|
<template slot-scope="scope">
|
<div>
|
{{ getfilter(scope.row.ruleId) }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="录取片段" align="center" prop="isRecord">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.isRecord=='1'? '是':'否' }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="录取时间/秒" align="center" prop="recordDuration">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.recordDuration }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="聚集人数" align="center" prop="peopleNumber"/>
|
</el-table>
|
</div>
|
</el-card>
|
|
</div>
|
<!--历史报警-->
|
<el-card class="right-card">
|
<div slot="header" class="clearfix">
|
<span class="clearfix-left"></span><span style="font-weight: 800;margin-right: 10px">历史报警</span>
|
</div>
|
<div class="text item">
|
|
<el-table v-loading="loading" :data="cameraList1">
|
<el-table-column label="报警时间" align="center" prop="alarmTime"/>
|
<el-table-column label="报警内容" align="center" prop="content"/>
|
<el-table-column label="报警类型" align="center" prop="ruleName">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.ruleName }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="报警状态" align="center" prop="dealWith" width="180">
|
<template slot-scope="scope">
|
<span>{{ sysIsDealDict(scope.row.dealWith) }}</span>
|
</template>
|
</el-table-column>
|
</el-table>
|
<pagination
|
:total="total"
|
:page.sync="query.pageNum"
|
:limit.sync="query.pageSize"
|
:pageSizes.sync="pageSizes"
|
@pagination="openDetails(0)"
|
></pagination>
|
|
</div>
|
</el-card>
|
<!--/历史报警-->
|
</div>
|
</el-drawer>
|
<!-- 添加或修改设备管理对话框 -->
|
<el-dialog :title="title" :visible.sync="open" @close="close" width="46%" append-to-body>
|
<el-steps :active="active" finish-status="success">
|
<el-step title="设备信息"></el-step>
|
<el-step title="算法选择"></el-step>
|
<el-step title="信息确认"></el-step>
|
</el-steps>
|
<section style="margin: 20px 0 0 0">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<div v-if="active == 0">
|
<el-row type="flex" class="row-bg">
|
<el-col :span="12">
|
<el-form-item class="pic-upload" label="现场图片" prop="picture">
|
<el-upload
|
:action="url"
|
:headers="headers"
|
:limit="1"
|
list-type="picture-card"
|
:on-preview="handlePictureCardPreview"
|
:on-success="handleAvatarSuccess"
|
:on-remove="handleRemove"
|
:on-change="handlechange"
|
:file-list="fileList"
|
:class="{hide:hideUpload||fileList.length}"
|
>
|
<i class="el-icon-plus"></i>
|
</el-upload>
|
<el-dialog append-to-body :visible.sync="dialogVisible">
|
<img width="100%" :src="dialogImageUrl" alt="">
|
</el-dialog>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" class="grid-content">
|
<el-form-item label="设备名称" prop="name">
|
<el-input style="width: 220px" v-model="form.name" placeholder="请输入名称"/>
|
</el-form-item>
|
<el-form-item label="设备型号" prop="cameraModel" style="margin: 22px 0 0 0;">
|
<el-input style="width: 220px" v-model="form.cameraModel" placeholder="请输入型号"/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row type="flex" class="row-bg">
|
<el-col :span="12">
|
<el-form-item label="布防区域" prop="region">
|
<el-select style="width: 220px" v-model="form.region" placeholder="请选择区域" clearable>
|
<el-option
|
v-for="dict in dict.type.sys_mine_region"
|
:key="dict.value"
|
:label="dict.label"
|
:value="dict.value"
|
style="width: 220px"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" class="grid-content">
|
<el-form-item label="设备状态" prop="status">
|
<el-select style="width: 220px" v-model="form.status" placeholder="请选择区域" clearable>
|
<el-option
|
v-for="dict in dict.type.sys_line_status"
|
:key="dict.value"
|
:label="dict.label"
|
:value="dict.value"
|
style="width: 220px"
|
/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row type="flex" class="row-bg">
|
<el-col :span="12">
|
<el-form-item label="登录账号" prop="cameraUser">
|
<el-input style="width: 220px" v-model="form.cameraUser" placeholder="请输入登录账号"/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" class="grid-content">
|
<el-form-item label="登录密码" prop="cameraPassword">
|
<el-input style="width: 220px" v-model="form.cameraPassword" placeholder="请输入登录密码"/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row type="flex" class="row-bg">
|
<el-col :span="12">
|
<el-form-item label="ip" prop="cameraIp">
|
<el-input style="width: 220px" v-model="form.cameraIp" placeholder="请输入ip"/>
|
</el-form-item>
|
|
</el-col>
|
<el-col :span="12" class="grid-content">
|
<el-form-item label="端口" prop="cameraPort">
|
<el-input type="number" style="width: 220px" v-model="form.cameraPort" placeholder="请输入端口"/>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</div>
|
</el-form>
|
|
<div v-if="active == 1">
|
<div>
|
<div style="margin-left: 20px;text-align: right;">
|
<img src="@/assets/images/sign.png" @click="addXfxgPlanRegionList"
|
style="width:22px;height:22px;cursor: pointer">
|
</div>
|
<div style="">
|
<div v-for="(item,index) in yxsfPlanRegionList" :key="item.id" style="margin-top:8px;">
|
<div
|
style="border: #cccccc 1px solid;background-color: #f3f3f3;border-radius: 10px;">
|
<div style="text-align: right;margin-right: 20px;margin-top: 10px">
|
<span @click="handleDeleteXfxgPlanRegion(index)" style="cursor: pointer">删除</span>
|
</div>
|
<div>
|
<el-form :model="item" :rules="sfGzrules" label-width="80px">
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="执行算法">
|
<el-select style="width: 220px;" v-model="item.ruleId" @change="getChange" placeholder="请选择执行算法">
|
<el-option
|
v-for="item in zxSfList"
|
:key="item.id"
|
:label="item.ruleName"
|
:value="item.id">
|
</el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<!-- <el-col :span="12" v-if="item.ruleId==4">-->
|
<!-- <el-form-item label="聚集人数">-->
|
<!-- <el-input-number style="width: 220px;cursor: pointer" v-model="item.peopleNumber" @change="handlenumChange" :min="1" :max="10"></el-input-number>-->
|
<!--<!– <el-input v-model="item.peopleNumber" placeholder="请输入聚集人数"–>-->
|
<!--<!– style="width: 220px;cursor: pointer"/>–>-->
|
<!-- </el-form-item>-->
|
|
<!-- </el-col>-->
|
<el-col :span="12">
|
<el-form-item label="录取片段">
|
<el-select v-model="item.isRecord" placeholder="请选择是否录取片段" style="width: 220px">
|
<el-option
|
v-for="dict in options"
|
:key="dict.value"
|
:label="dict.label"
|
:value="dict.value"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12" v-if="item.isRecord=='1'">
|
<el-form-item label="录取时间">
|
<el-input-number style="width: 220px;cursor: pointer" v-model="item.recordDuration" @change="handlenumChange" :min="1" :max="10"></el-input-number> 秒
|
</el-form-item>
|
|
</el-col>
|
<el-col :span="12" >
|
<el-form-item label="算法区域">
|
<el-input v-model="item.ruleArea" placeholder="请选择算法区域"
|
style="width: 220px;cursor: pointer" @focus="openUserInfo(index,item,0)"/>
|
</el-form-item>
|
</el-col>
|
<!-- <el-col :span="12" v-if="item.ruleId == 1">-->
|
<!-- <el-form-item label="左侧区域">-->
|
<!-- <el-input v-model="item.leftArea" placeholder="请选择左侧区域"-->
|
<!-- style="width: 220px;cursor: pointer" @focus="openUserInfo(index,item,1)"/>-->
|
<!-- </el-form-item>-->
|
<!-- </el-col>-->
|
<!-- <el-col :span="12" v-if="item.ruleId == 1">-->
|
<!-- <el-form-item label="中间区域">-->
|
<!-- <el-input v-model="item.centerArea" placeholder="请选择中间区域"-->
|
<!-- style="width: 220px;cursor: pointer" @focus="openUserInfo(index,item,2)"/>-->
|
<!-- </el-form-item>-->
|
<!-- </el-col>-->
|
<!-- <el-col :span="12" v-if="item.ruleId == 1">-->
|
<!-- <el-form-item label="右侧区域">-->
|
<!-- <el-input v-model="item.rightArea" placeholder="请选择右侧区域"-->
|
<!-- style="width: 220px;cursor: pointer" @focus="openUserInfo(index,item,3)"/>-->
|
<!-- </el-form-item>-->
|
<!-- </el-col>-->
|
</el-row>
|
</el-form>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div v-if="active == 2">
|
<div style="padding: 20px">
|
<el-card class="right-card">
|
<div slot="header" class="clearfix">
|
<span class="clearfix-left"></span><span style="font-weight: 800;margin-right: 10px">设备信息</span>
|
</div>
|
<div class="text">
|
<div class="text-center">
|
<div class="text-top-img">
|
<img :src="imgUrl+form.picture" style="width: 280px; height: 180px;">
|
</div>
|
<div class="text-top-cantent">
|
<div class="text-top">
|
<div class="text-top-left"
|
style="display: flex;flex-direction: column;justify-content: space-between;margin-right: 10px">
|
<p>设备名称:<span>{{ form.name }}</span></p>
|
<p>布防区域:<span>{{ form.region }}</span></p>
|
<p>登录账号:<span>{{ form.cameraUser }}</span></p>
|
|
<p>端口:<span>{{ form.cameraPort }}</span></p>
|
</div>
|
<div class="text-top-right"
|
style="display: flex;flex-direction: column;justify-content: space-between;">
|
<p>设备型号:<span>{{ form.cameraModel }}</span></p>
|
<p>设备状态:<dict-tag style="display: inline-block;" :options="dict.type.sys_line_status"
|
:value="form.status"/>
|
</p>
|
<p>登录密码:<span>{{ form.cameraPassword }}</span></p>
|
<p>IP:<span>{{ form.cameraIp }}</span></p>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
<!--历史报警-->
|
<el-card class="right-card">
|
<div slot="header" class="clearfix">
|
<span class="clearfix-left"></span><span style="font-weight: 800;margin-right: 10px">算法选择</span>
|
</div>
|
<div class="text item">
|
<el-table v-loading="loading" :data="yxsfPlanRegionList">
|
<el-table-column label="执行算法" align="center" prop="ruleId">
|
<template slot-scope="scope">
|
<div>
|
{{ getfilter(scope.row.ruleId) }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="录取片段" align="center" prop="isRecord">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.isRecord=='1'? '是':'否' }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="录取时间/秒" align="center" prop="recordDuration">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.recordDuration }}
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="聚集人数" align="center" prop="peopleNumber"/>
|
</el-table>
|
</div>
|
</el-card>
|
<!--/历史报警-->
|
</div>
|
</div>
|
</section>
|
<div class="footer" style="text-align: center;margin-top: 20px">
|
<el-button
|
v-if="active > 0"
|
type="info"
|
icon="el-icon-arrow-left"
|
@click="prevSyb"
|
>上一步
|
</el-button>
|
<el-button
|
v-if="active < step - 1"
|
type="primary"
|
icon="el-icon-arrow-right"
|
@click="next"
|
>下一步
|
</el-button>
|
<el-button v-if="active == step - 1" type="primary" @click="submitForm"
|
>确定
|
</el-button>
|
</div>
|
</el-dialog>
|
|
<el-dialog title="现场视频" :visible.sync="openvideo" @close="closeClick" width="50%" append-to-body>
|
<div style="width: 100%;height: 500px;" >
|
<index-spjk-spxx1998 :showId="1998" ref="indexSpjkSpxx1998Ref"></index-spjk-spxx1998>
|
</div>
|
</el-dialog>
|
|
<el-dialog title="算法区域标识框" :visible.sync="openSvg" width="1000px" append-to-body>
|
<CameraSvgEditor ref="cameraSvgEditorRef" :cameraImgUrl="imgUrl+form.picture" :cameraImgUrlRedraw="cameraImgUrlRedraw"
|
@cameraSvgEditorReturn="cameraSvgEditorReturn"></CameraSvgEditor>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import {
|
listCamera,
|
getCamera,
|
delCamera,
|
addCamera,
|
updateCamera,
|
startCamera,
|
getCameraPic,
|
startCameraAll
|
} from "@/api/aibrain/camera";
|
import {selectList} from "@/api/system/rule"
|
import {getToken} from "@/utils/auth";
|
import CameraSvgEditor from "@/views/aibrain/camera/cameraSvgEditor";
|
import {listAlarm} from "@/api/aibrain/alarm";
|
import Stomp from 'stompjs'
|
import {MQ_SERVICE, MQ_USERNAME, MQ_PASSWORD} from '@/config/linkparam'
|
|
import indexSpjkSpxx1998 from "@/views/common/index_spjk_rtsp";
|
|
|
|
export default {
|
name: "Camera",
|
components: {
|
CameraSvgEditor,
|
indexSpjkSpxx1998,
|
},
|
dicts: ['sys_line_status', 'sys_yes_no', 'sys_mine_region', 'sys_is_deal'],
|
data() {
|
// 自定义校验规则
|
const validateFile2 = (rule, value, callback) => {
|
if (!this.form.picture) { //当'this.resourceForm.imageUrl'不等于‘true’
|
callback(new Error("请上传图片"))
|
} else {
|
callback()
|
}
|
}
|
return {
|
openvideo:false,
|
hideUpload: false,
|
// 报警列表
|
cameraList1: [],
|
active: 0,
|
step: 3,
|
fileList: [],
|
// 抽屉
|
drawer: false,
|
// 算法数剧
|
allListInfo: [],
|
options: [{
|
value: '0',
|
label: '否'
|
}, {
|
value: '1',
|
label: '是'
|
}],
|
// 算法关联表格数据
|
yxsfPlanRegionList: [
|
{
|
id: "",
|
//算法ID
|
ruleId: "",
|
//算法名称
|
ruleName: "",
|
// 划定区域
|
ruleArea: "",
|
// 左侧区域
|
leftArea: "",
|
// 中间区域
|
centerArea: "",
|
// 右侧区域
|
rightArea: "",
|
//报警联动录像
|
isRecord: '',
|
//报警联动录像时长
|
recordDuration: "",
|
// 报警人数
|
peopleNumber: ''
|
},
|
],
|
// 遮罩层
|
loading: true,
|
// 选中数组
|
ids: [],
|
// 非单个禁用
|
single: true,
|
// 非多个禁用
|
multiple: true,
|
// 显示搜索条件
|
showSearch: true,
|
// 总条数
|
total: 0,
|
// 设备管理表格数据
|
cameraList: [],
|
// 弹出层标题
|
title: "",
|
// 是否显示弹出层
|
// 是否显示算法标识弹出层
|
openSvg: false,
|
cameraImgUrl: "http://localhost:81/dev-api/profile/avatar/2023/03/13/blob_20230313144418A001.png",
|
cameraImgUrlRedraw: '[{"x":"597.00","y":"270.50"},{"x":"936.00","y":"339.50"},{"x":"786.00","y":"504.50"},{"x":"609.00","y":"432.50"}]',
|
cameraRule: null,
|
open: false,
|
// 备注时间范围
|
daterangeCreateTime: [],
|
// 备注时间范围
|
daterangeUpdateTime: [],
|
pageSizes: [5, 10, 15, 20],
|
// 查询参数
|
queryParams: {
|
name: null,
|
status: null,
|
region: null,
|
videoSwitch: null,
|
createTime: null,
|
},
|
query: {
|
pageNum: 1,
|
pageSize: 5,
|
},
|
// 表单参数
|
form: {},
|
cameraQueryId: null,
|
sfGzrules: {
|
ruleName: [
|
{required: true, message: "执行算法不能为空", trigger: "blur"},
|
],
|
isRecord: [
|
{required: true, message: "录取片段不能为空", trigger: "blur"},
|
],
|
ruleArea: [
|
{required: true, message: "算法区域不能为空", trigger: "blur"},
|
]
|
},
|
// 表单校验
|
rules: {
|
picture: [
|
{required: true, validator: validateFile2, trigger: "change"},
|
],
|
name: [
|
{required: true, message: "设备名称不能为空", trigger: "blur"},
|
],
|
cameraModel: [
|
{required: true, message: "设备型号不能为空", trigger: "blur"},
|
],
|
region: [
|
{required: true, message: "区域不能为空", trigger: "change"},
|
],
|
status: [
|
{required: true, message: "设备状态不能为空", trigger: "change"},
|
],
|
cameraIp: [
|
{required: true, message: "ip不能为空", trigger: "blur"},
|
{ pattern:/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/, message: '请输入正确的ip', trigger: 'blur' }
|
],
|
cameraPort: [
|
{required: true, message: "端口不能为空", trigger: "blur"},
|
{ pattern:/^(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5]))$/, message: '只能输入数字', trigger: 'blur'}
|
],
|
cameraUser: [
|
{required: true, message: "登录账号不能为空", trigger: "blur"},
|
],
|
cameraPassword: [
|
{required: true, message: "登录密码不能为空", trigger: "blur"},
|
// {pattern: /^(\w){6,20}$/, message: '只能输入6-20个字母、数字、下划线'}
|
],
|
remark: [
|
{required: true, message: "运行算法不能为空", trigger: "blur"},
|
],
|
},
|
imgLocation: null,
|
zxSfList: [],
|
dialogImageUrl: '',
|
dialogVisible: false,
|
disabled: false,
|
sysIsDeal: [],
|
url: process.env.VUE_APP_BASE_API + '/common/upload',
|
headers: {Authorization: "Bearer " + getToken()},
|
openSvgindex:null,
|
imgUrl:process.env.VUE_APP_BASE_API,
|
client: Stomp.client(MQ_SERVICE),
|
videoIp: '/topic/VideoRealTopic192168164',
|
pictrueimgs:null,
|
|
// webRtcServer: null,
|
// videoUrl: 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4',
|
};
|
},
|
created() {
|
this.getList();
|
this.selectList()
|
this.getDicts("sys_is_deal").then(response => {
|
this.sysIsDeal = response.data;
|
});
|
// this.connect();
|
},
|
methods: {
|
videoClick(item){
|
this.openvideo = true;
|
setTimeout(() => {
|
this.$refs.indexSpjkSpxx1998Ref.joinSXT(item);
|
}, 100);
|
},
|
/** 用于配置监听的队列与回调的方法 */
|
onConnected: function (frame) {
|
console.log(frame, '****')
|
/**
|
* 定时器 先执行视频队列多个的返回
|
* */
|
// let that = this
|
// setTimeout(() => {
|
// if (that.cameraList.length) {
|
// /**
|
// * 视频队列多个 VideoRealTopic19216811 调用多个mq监听返回多个视频视频
|
// * */
|
// that.cameraList.forEach(x => {
|
// that.client.subscribe('/queue/VideoRealTopic' + x.cameraIp.replace(/\./g, ''), that.responseCallback, that.onFailed)
|
// })
|
// }
|
// }, 1000)
|
this.client.subscribe(this.videoIp, this.responseCallback, this.onFailed);
|
this.client.debug=null;
|
|
},
|
// 监听失败的回调
|
onFailed: function (frame) {
|
// console.log('Failed: *************', frame)
|
},
|
getCurrentTime() {
|
//获取当前时间并打印
|
var _this = this;
|
let nowD=new Date();
|
let yy = nowD.getFullYear();
|
let mm = nowD.getMonth()+1;
|
let dd = nowD.getDate();
|
let hh = nowD.getHours();
|
let mf = nowD.getMinutes()<10 ? '0'+nowD.getMinutes() : nowD.getMinutes();
|
let ss = nowD.getSeconds()<10 ? '0'+nowD.getSeconds() : nowD.getSeconds();
|
let SSS = nowD.getMilliseconds()<10 ? '0'+nowD.getMilliseconds() : nowD.getMilliseconds();
|
_this.gettime = yy+'/'+mm+'/'+dd+' '+hh+':'+mf+':'+ss+'.'+SSS;
|
return _this.gettime;
|
},
|
|
// 监听成功的回调,获取消息
|
responseCallback(frame) {
|
// console.log(frame,'..............responseCallback')
|
var eventData = JSON.parse(frame.body);
|
|
console.log(this.getCurrentTime()+'-----111111------'+frame.body);
|
if (eventData.pictureBase64) {
|
// 返回消息队列的 id 和 点击id相同
|
// if (eventData.cameraId == this.videoCameraId) {
|
//赋值视频数据
|
this.pictrueimgs = eventData;
|
// }
|
// let that = this;
|
// setTimeout(() => {
|
// that.cameraList.forEach((x, index) => {
|
// /**
|
// * 2. 判断点击id和多个mq返回的数据id相同 视频播放显示对应的点击数据
|
// * */
|
// if (x.id === eventData.cameraId) {
|
// // 响应式增加数据
|
// that.$set(x, 'pictrueimgs', eventData)
|
// }
|
// })
|
// }, 1000)
|
|
}
|
},
|
/** 用于初始化连接 */
|
connect: function () {
|
// console.log('用于初始化连接' , this.client)
|
var headers = {
|
'login': MQ_USERNAME,
|
'passcode': MQ_PASSWORD
|
}
|
// 心跳发送频率
|
this.client.heartbeat.outgoing = 50000;
|
// 心跳接收频率
|
this.client.heartbeat.incoming = 50000;
|
this.client.connect(headers, this.onConnected, this.onFailed)
|
|
},
|
closeClick(){
|
this.openvideo = false;
|
// 停止当前mq消息
|
this.client.disconnect();
|
// 重新赋值初始化mq
|
this.client = Stomp.client(MQ_SERVICE);
|
},
|
// //连接视频主减初始化
|
// connectVideoInit(){
|
// this.playVideo();
|
// },
|
// //播放视频
|
// playVideo(){
|
// //需要查看的rtsp地址
|
// console.log('shipin'+ this.videoUrl)
|
// this.webRtcServer.connect(this.videoUrl)
|
// //rtsp://user:password@ip:port/h264/ch1/main/av_stream--海康
|
// //rtsp://user:password@ip:port/cam/realmonitor?channel=1&subtype=0--大华
|
// },
|
// //切换视频
|
// handleChange() {
|
// this.webRtcServer.connect('rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4')
|
// },
|
// //销毁视频
|
// destroyVideo(){
|
// if(this.webRtcServer){
|
// this.webRtcServer.disconnect()
|
// this.webRtcServer = null
|
// }
|
// },
|
getChange(e){
|
// console.log('123321'+e)
|
},
|
getLsbj() {
|
this.$router.push('/alarm');
|
},
|
getfilter(val) {
|
const obj = this.zxSfList
|
return obj.filter(x => x.id == val)[0].ruleName
|
},
|
async selectList() {
|
const {rows} = await selectList()
|
|
this.zxSfList = rows
|
},
|
openUserInfo(index, item, place) {
|
this.openSvg = true
|
this.openSvgindex = index
|
this.cameraRule = place
|
// console.log('place'+ place)
|
// console.log('item'+ JSON.stringify(item))
|
if(place == 1){
|
this.cameraImgUrlRedraw = item.leftArea
|
}else if(place == 2){
|
this.cameraImgUrlRedraw = item.centerArea
|
}else if(place == 3){
|
this.cameraImgUrlRedraw = item.rightArea
|
}else{
|
this.cameraImgUrlRedraw = item.ruleArea
|
}
|
// this.$refs.cameraSvgEditorRef.init()
|
// setInterval(()=>{
|
// item.ruleArea = this.imgLocation
|
// let a = this.imgLocation
|
// },500)
|
|
},
|
|
addXfxgPlanRegionList() {
|
let obj = {};
|
obj.regionId = null;
|
obj.checkRule = null;
|
obj.checkNumber = null;
|
obj.xfxgTaskUserList = null;
|
obj.users = "";
|
this.yxsfPlanRegionList.push(obj)
|
// let a = this.yxsfPlanRegionList.filter(x=>x.ruleName!='')
|
// let b = this.zxSfList.filter(i=>{
|
// let ii = null
|
// a.forEach((item)=>{
|
// ii = item.ruleName
|
// })
|
// return ii!==i.id
|
// })
|
// console.log('bb'+JSON.stringify(a))
|
},
|
/** 计划区域关联删除按钮操作 */
|
handleDeleteXfxgPlanRegion(index) {
|
this.yxsfPlanRegionList.splice(index, 1);
|
},
|
cameraSvgEditorReturn(imgLocation) {
|
// console.log("这个是返回的图片定位点:" + this.cameraRule);
|
if(this.cameraRule == 1){
|
this.yxsfPlanRegionList[this.openSvgindex].leftArea = imgLocation
|
}else if(this.cameraRule == 2){
|
this.yxsfPlanRegionList[this.openSvgindex].centerArea = imgLocation
|
}else if(this.cameraRule == 3){
|
this.yxsfPlanRegionList[this.openSvgindex].rightArea = imgLocation
|
}else{
|
this.yxsfPlanRegionList[this.openSvgindex].ruleArea = imgLocation
|
}
|
// this.imgLocation = imgLocation
|
this.openSvg = false;
|
},
|
next() {
|
if (this.active === 0) {
|
this.$refs["form"].validate((valid) => {
|
if (valid) {
|
this.active++
|
}
|
})
|
}else if (this.active == 1) {
|
const flg = this.yxsfPlanRegionList.some(x => {
|
if (!x.ruleId) {
|
return this.$message.error('执行算法不能为空')
|
}
|
if (!x.isRecord) {
|
return this.$message.error('录取片段不能为空')
|
}
|
// if (!x.ruleArea) {
|
// return this.$message.error('算法区域不能为空')
|
// }
|
})
|
if (flg) return false
|
this.active++
|
}
|
if (this.active > 2) this.active = 0;
|
},
|
prevSyb() {
|
this.active--
|
if (this.active < 0) this.active = 0;
|
},
|
handlechange(file, fileList) {
|
this.hideUpload = true
|
},
|
handlenumChange(val){
|
// console.log('num++'+val)
|
},
|
sysIsDealDict(val) {
|
var idx = this.sysIsDeal.findIndex(item => item.dictValue == val)
|
if (idx != -1) {
|
return this.sysIsDeal[idx].dictLabel
|
} else {
|
return ''
|
}
|
},
|
handleRemove(file, fileList) {
|
this.hideUpload = false
|
this.fileList = [];
|
this.dialogImageUrl = "";
|
this.$message.success("删除成功");
|
},
|
handlePictureCardPreview(file) {
|
// console.log('上传时' + file)
|
this.dialogImageUrl = process.env.VUE_APP_BASE_API + file.fileName;
|
this.dialogVisible = true;
|
},
|
handleAvatarSuccess(res, file) {
|
// console.log(JSON.stringify(file.response))
|
this.form.picture = file.response.fileName;
|
this.fileList = [{url:process.env.VUE_APP_BASE_API +file.response.fileName}]
|
},
|
/** 查询设备管理列表 */
|
getList() {
|
this.loading = true;
|
this.queryParams.params = {};
|
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
|
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
|
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
|
}
|
if (null != this.daterangeUpdateTime && '' != this.daterangeUpdateTime) {
|
this.queryParams.params["beginUpdateTime"] = this.daterangeUpdateTime[0];
|
this.queryParams.params["endUpdateTime"] = this.daterangeUpdateTime[1];
|
}
|
listCamera(this.queryParams).then(response => {
|
// console.log('1111' + JSON.stringify(response))
|
this.cameraList = response.rows;
|
this.total = response.total;
|
this.loading = false;
|
});
|
},
|
// 取消按钮
|
cancel() {
|
this.open = false;
|
this.reset();
|
},
|
// 表单重置
|
reset() {
|
this.form = {
|
id: null,
|
name: null,
|
picture: null,
|
cameraModel: null,
|
status: null,
|
region: null,
|
cameraIp: null,
|
cameraPort: null,
|
cameraUser: null,
|
cameraPassword: null,
|
videoSwitch: null,
|
videoDuration: null,
|
createBy: null,
|
createTime: null,
|
updateBy: null,
|
updateTime: null,
|
remark: null,
|
rules: [],
|
};
|
this.yxsfPlanRegionList = [{
|
id: "",
|
//算法ID
|
ruleId: null,
|
//算法名称
|
ruleName: null,
|
// 划定区域
|
ruleArea: null,
|
//报警联动录像
|
isRecord: null,
|
//报警联动录像时长
|
recordDuration: null,
|
// 报警人数
|
peopleNumber: null
|
},]
|
this.fileList = []
|
this.resetForm("form");
|
},
|
/** 搜索按钮操作 */
|
handleQuery() {
|
this.queryParams.pageNum = 1;
|
this.getList();
|
},
|
/** 重置按钮操作 */
|
resetQuery() {
|
this.daterangeCreateTime = [];
|
this.daterangeUpdateTime = [];
|
this.resetForm("queryForm");
|
this.handleQuery();
|
},
|
// 多选框选中数据
|
handleSelectionChange(selection) {
|
this.ids = selection.map(item => item.id)
|
this.single = selection.length !== 1
|
this.multiple = !selection.length
|
},
|
/** 新增按钮操作 */
|
handleAdd() {
|
this.reset();
|
this.hideUpload = false
|
this.active = 0
|
this.open = true;
|
this.title = "新增设备";
|
},
|
openfiring(id) {
|
this.$confirm('确定变更设备状态?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
var params = {
|
id: id,
|
}
|
// console.log("--------------status:"+status)
|
startCamera(params).then((res)=>{
|
this.$message({
|
type: 'success',
|
message: res.msg
|
});
|
})
|
|
|
}).catch(() => {
|
this.$message({
|
type: 'error',
|
message: '已取消'
|
});
|
});
|
let that = this
|
setTimeout(()=>{
|
that.getList();
|
},1000)
|
},
|
|
openfiringAll() {
|
this.$confirm('确定重启全部设备?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
startCameraAll().then((res) => {
|
this.$message({
|
type: 'success',
|
message: res.msg
|
});
|
})
|
|
}).catch(() => {
|
this.$message({
|
type: 'error',
|
message: '11111已取消'
|
});
|
});
|
},
|
|
openDetails(id) {
|
if (id != 0) {
|
this.cameraQueryId = id;
|
}
|
var params = {
|
cameraId: this.cameraQueryId,
|
pageNum: this.query.pageNum,
|
pageSize: this.query.pageSize,
|
}
|
getCamera(id).then(response => {
|
this.form = response.data;
|
});
|
|
/** 查询报警信息管理列表 */
|
// console.log(params, "传递参数")
|
listAlarm(params).then(response => {
|
this.cameraList1 = response.rows;
|
this.drawer = true;
|
this.total = response.total;
|
});
|
},
|
/** 修改按钮操作 */
|
handleUpdate(id) {
|
this.reset();
|
getCamera(id).then(response => {
|
this.form = response.data;
|
if (response.data.rules.length) {
|
this.yxsfPlanRegionList = response.data.rules
|
}
|
|
/** 编辑按钮操作 */
|
this.open = true
|
this.active = 0
|
this.fileList = [{url:this.imgUrl+ this.form.picture}]
|
});
|
|
},
|
/** 提交按钮 */
|
submitForm() {
|
if (this.form.id != null) {
|
this.form.rules = this.yxsfPlanRegionList
|
updateCamera(this.form).then(response => {
|
this.$modal.msgSuccess("修改成功");
|
this.open = false;
|
this.getList();
|
});
|
} else {
|
this.form.rules = this.yxsfPlanRegionList
|
addCamera(this.form).then(response => {
|
this.$modal.msgSuccess("新增成功");
|
this.open = false;
|
this.getList();
|
});
|
}
|
},
|
/** 删除按钮操作 */
|
handleDelete(e) {
|
this.$modal.confirm('是否确认删除设备管理编号为"' + e + '"的数据项?').then(function () {
|
return delCamera(e);
|
}).then(() => {
|
this.getList();
|
this.$modal.msgSuccess("删除成功");
|
}).catch(() => {
|
});
|
},
|
getCameraPic(id) {
|
this.$confirm('确定抓取设备现场图片?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
var params = {
|
id: id,
|
}
|
getCameraPic(params).then((res)=>{
|
var type = 'error';
|
if (res.code == 200){
|
type = 'success'
|
}
|
this.$message({
|
type: type,
|
message: res.msg,
|
});
|
})
|
}).catch(() => {
|
this.$message({
|
type: 'error',
|
message: '已取消'
|
});
|
});
|
},
|
/** 导出按钮操作 */
|
handleExport() {
|
this.download('aibrain/camera/export', {
|
...this.queryParams
|
}, `camera_${new Date().getTime()}.xlsx`)
|
},
|
close() {
|
// console.log('oki')
|
this.active = 0
|
|
},
|
},
|
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
::v-deep .hide .el-upload--picture-card {
|
display: none;
|
}
|
|
.button-bottom {
|
width: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
::v-deep .el-upload--picture-card {
|
height: 100px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
::v-deep .el-upload-list__item-actions {
|
//width: 200px;
|
height: 100px;
|
}
|
|
::v-deep .el-upload-list--picture-card .el-upload-list__item {
|
//width: 200px;
|
height: 100px;
|
}
|
|
//.grid-content {
|
// margin: 0 50px 0 0;
|
//}
|
|
.box-card {
|
margin: 0 10px 20px 10px;
|
.clearfix {
|
}
|
|
.text {
|
color: #777777;
|
font-size: 14px;
|
border-bottom: 1px solid #e6ebf5;
|
padding: 20px 10px 0 20px;
|
|
.text-top {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
|
.text-top-img {
|
margin-right: 20px;
|
|
img {
|
width: 100%;
|
border-radius: 10px;
|
}
|
}
|
|
.text-top-cantent {
|
padding: 0 10px 0 0;
|
}
|
}
|
|
.text-top-btext {
|
p {
|
display: flex;
|
flex-wrap: wrap;
|
clear: both;
|
margin: 4px;
|
}
|
}
|
}
|
|
.text-bottom {
|
//border-bottom: 0;
|
display: flex;
|
justify-content: space-evenly;
|
align-items: center;
|
padding: 10px;
|
}
|
}
|
|
.right-card .text .text-center[data-v-525318a3] {
|
display: -webkit-box;
|
display: -ms-flexbox;
|
display: flex;
|
text-align: start;
|
font-size: 15px;
|
}
|
|
.right-card {
|
&:first-child {
|
margin-bottom: 20px;
|
}
|
|
.clearfix {
|
.clearfix-left {
|
display: inline-block;
|
vertical-align: text-top;
|
width: 4px;
|
height: 16px;
|
transform: translateX(-15px);
|
background-color: #2294c9;
|
margin: 0;
|
}
|
}
|
|
.text {
|
.text-center {
|
display: flex;
|
text-align: start;
|
|
.text-top-img {
|
flex: 1;
|
margin-right: 20px;
|
|
img {
|
width: 100%;
|
height: 210px;
|
border-radius: 10px;
|
}
|
}
|
|
.text-top-cantent {
|
flex: 1;
|
|
.text-top {
|
display: flex;
|
justify-content: space-around;
|
|
.text-top-left, .text-top-right {
|
p {
|
&:last-child {
|
//text-indent: 2em;
|
}
|
|
span {
|
margin: 0 0 0 5px;
|
}
|
}
|
}
|
|
.text-top-right {
|
p {
|
&:last-child {
|
//text-indent: 3em;
|
}
|
}
|
}
|
}
|
|
.text-bottom {
|
display: flex;
|
justify-content: space-evenly;
|
align-items: center;
|
padding: 10px;
|
}
|
}
|
}
|
}
|
}
|
</style>
|