<template>
|
<div class="CameraInfo">
|
<div class="cameraHeader">
|
<div class="title">摄像机信息</div>
|
|
<el-form class="addForm" ref="addForm" :model="form" :rules="rules" label-width="88px" label-position="left">
|
<div class="row">
|
<el-form-item label="设备ID" prop="rtsp">
|
<el-input v-model="form.rtsp" placeholder="rtsp://" :disabled="isDisabled" size="small"></el-input>
|
</el-form-item>
|
|
<el-form-item label="处理分辨率">
|
<el-select v-model="form.resolution" placeholder="本机分辨率" size="small">
|
<el-option
|
v-for="item in resolutionList"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</div>
|
|
<div class="row">
|
<el-form-item label="设备名称" prop="name">
|
<el-input v-model="form.name" placeholder="请输入设备名称" :disabled="isDisabled" size="small"></el-input>
|
</el-form-item>
|
|
<el-form-item label="坐标" class="position">
|
<label slot="label">坐标</label>
|
<el-input v-model="form.latitude" placeholder="经度" :disabled="isDisabled" size="small"></el-input>
|
<el-input v-model="form.longitude" placeholder="纬度" :disabled="isDisabled" size="small"></el-input>
|
</el-form-item>
|
</div>
|
|
<div class="row">
|
<el-form-item label="设备地址" prop="addr">
|
<el-input v-model="form.addr" placeholder="请输入地址描述" :disabled="isDisabled" size="small"></el-input>
|
</el-form-item>
|
|
<el-form-item label="事件声音">
|
<div class="flex-wrap">
|
<el-switch v-model="form.voiceEnable" :width="56"></el-switch>
|
</div>
|
</el-form-item>
|
</div>
|
|
<div class="row">
|
<el-form-item label="设备别名" prop="alias" v-show="isGb28182">
|
<el-input v-model="form.alias" placeholder="请输入设备别名" size="small"></el-input>
|
</el-form-item>
|
</div>
|
|
<!-- <div class="row">
|
<el-form-item label="所属集群">
|
<el-select
|
v-model="form.cluster"
|
placeholder="请选择所属集群"
|
size="small"
|
class="clusterSelect"
|
>
|
<el-option
|
v-for="item in clusterList"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</div> -->
|
|
<!-- 添加传感器 -->
|
<CameraInfoEditor ref="cameraEditor" :Carmeras="form" :sensors="sensors"></CameraInfoEditor>
|
|
<div class="btns">
|
<el-button
|
type="danger"
|
size="small"
|
@click="deleteCamera"
|
v-if="!isAdd"
|
:disabled="isDisabled"
|
class="delBtn"
|
>删除摄像机</el-button
|
>
|
<el-button size="small" type="primary" @click="onSubmit('addForm')" :disabled="conDisabled" class="saveBtn"
|
>保存</el-button
|
>
|
</div>
|
|
<input v-model="form.id" type="hidden" />
|
<input v-model="form.areaid" type="hidden" />
|
</el-form>
|
</div>
|
|
<div class="cameraBody">
|
<div class="info">
|
<div class="title">算力信息</div>
|
<div class="hashrate">
|
<div class="card">
|
<img src="/images/hashrate/realTime2.png" alt="" />
|
<div class="data">
|
<div class="label">实时算力</div>
|
<div class="number">
|
<span>{{ PollData.RealTimeValidCount }}</span
|
>路
|
</div>
|
</div>
|
</div>
|
|
<div class="card">
|
<img src="/images/hashrate/polling.png" alt="" />
|
<div class="data">
|
<div class="label">轮询算力</div>
|
<div class="number">
|
<span>{{ PollData.PollValidCount }}</span
|
>路
|
</div>
|
</div>
|
</div>
|
|
<div class="card">
|
<img src="/images/hashrate/static.png" alt="" />
|
<div class="data">
|
<div class="label">数据栈算力</div>
|
<div class="number">
|
<span>{{ PollData.stackChannelCount }}</span
|
>路
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<sysinfo :stroke="24" v-if="PollData.barCharts && PollData.barCharts.length !== 0" />
|
</div>
|
|
<div class="camera">
|
<div class="connect">
|
<el-button size="small" type="primary" @click="cameraConnet" :disabled="conDisabled">连接测试</el-button>
|
</div>
|
|
<div class="video">
|
<wasm-player
|
:cameraName="videoItem.name"
|
:cameraID="videoItem.id"
|
:isGb="videoItem.cameraType === 1"
|
:rtspUrl="videoItem.rtsp"
|
:isRunning="false"
|
:showArea="false"
|
v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && visibilityState"
|
></wasm-player>
|
<video v-else poster="/images/hashrate/video-poster.png" preload="none"></video>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { createCamera, updateCameraInfo, getCameraInfo, delCamera } from "@/api/camera"
|
import { getSoundList } from "@/api/event"
|
|
import WasmPlayer from "@/components/wasmPlayer"
|
import CameraInfoEditor from "./components/CameraInfoEditor"
|
import Sysinfo from "@/components/subComponents/SystemInfo"
|
|
export default {
|
name: "CameraInfo",
|
components: {
|
WasmPlayer,
|
CameraInfoEditor,
|
Sysinfo
|
},
|
props: {
|
cameraList: {
|
default: () => {
|
return []
|
},
|
type: Array
|
}
|
},
|
created() {
|
document.querySelector("html").style["min-width"] = "1280px"
|
},
|
data() {
|
return {
|
videoItem: null,
|
visibilityState: true,
|
soundList: [],
|
togglePlay: true,
|
eventAudio: new Audio(),
|
soundPath: "",
|
form: {},
|
// 记录添加状态
|
isAdd: false,
|
addParentId: "",
|
rules: {
|
name: [{ required: true, message: "设备名称不能为空", trigger: "blur" }],
|
rtsp: [{ required: true, message: "RTSP地址不能为空", trigger: "blur" }],
|
addr: [{ required: true, message: "设备地址不能为空", trigger: "blur" }]
|
},
|
resolutionList: [],
|
//传感器列表
|
sensors: [],
|
voice: null,
|
clusterList: [
|
{
|
label: "集群1",
|
value: 0
|
},
|
{
|
label: "集群2",
|
value: 1
|
}
|
]
|
}
|
},
|
computed: {
|
isSelected() {
|
return this.TreeDataPool.selectedNode.type !== "4"
|
},
|
isGb28182() {
|
return this.TreeDataPool.selectedNode.cameraType === 1
|
},
|
isDisabled() {
|
if (this.isGb28182) {
|
return true
|
}
|
|
return this.isAdd ? false : this.TreeDataPool.selectedNode.type !== "4"
|
},
|
conDisabled() {
|
return this.isAdd ? false : this.TreeDataPool.selectedNode.type !== "4"
|
}
|
},
|
mounted() {
|
this.initFormData()
|
document.addEventListener("visibilitychange", () => {
|
this.visibilitychange()
|
})
|
this.getSounds()
|
|
this.eventAudio.addEventListener("ended", () => {
|
this.togglePlay = true
|
})
|
},
|
methods: {
|
getSounds() {
|
getSoundList()
|
.then((res) => {
|
if (res.success) {
|
this.soundList = res.data.voices
|
}
|
})
|
.catch((e) => console.log(e))
|
},
|
selSound(sound) {
|
this.soundPath = sound.path
|
this.form.voiceId = sound.id
|
this.togglePlay = true
|
this.eventAudio.pause()
|
// this.eventAudio.
|
},
|
togglePlayer() {
|
if (!this.soundPath) {
|
this.$notify({
|
type: "info",
|
message: "请先选择一个声音!"
|
})
|
return false
|
}
|
this.eventAudio.src = this.soundPath
|
if (this.togglePlay) {
|
this.eventAudio.play()
|
this.togglePlay = false
|
} else {
|
this.eventAudio.pause()
|
this.togglePlay = true
|
}
|
// this.togglePlay = !this.togglePlay
|
},
|
visibilitychange() {
|
switch (document.visibilityState) {
|
case "hidden":
|
this.visibilityState = false
|
break
|
case "visible":
|
this.visibilityState = true
|
break
|
}
|
},
|
selectCamera(node) {
|
this.isAdd = false
|
this.videoItem = null
|
this.$refs.addForm.resetFields()
|
this.voice = null
|
|
if (node.type === "4") {
|
getCameraInfo(node.id).then((res) => {
|
if (res.success) {
|
if (res.data.resolutions) {
|
let list = res.data.resolutions.map((i) => {
|
let obj = {}
|
if (i.width == 0 && i.height == 0) {
|
obj.label = "本机分辨率"
|
obj.value = "0*0"
|
} else {
|
obj.label = i.width + "*" + i.height
|
obj.value = i.width + "*" + i.height
|
}
|
return obj
|
})
|
this.resolutionList = list
|
this.sensors = res.data.sensors
|
}
|
|
this.$nextTick(() => {
|
this.initFormData()
|
Object.assign(this.form, res.data)
|
|
this.soundList.forEach((element) => {
|
if (this.form.voiceId == element.id) {
|
this.voice = element
|
}
|
})
|
|
if (this.form.run_type !== -1) {
|
this.form.isAI = true
|
} else {
|
this.form.isAI = false
|
}
|
this.form.resolution = this.form.resolution_width + "*" + this.form.resolution_height
|
})
|
}
|
})
|
}
|
},
|
// 保存
|
onSubmit(formName) {
|
let list = this.$refs.cameraEditor.getResult()
|
this.$refs[formName].validate(async (valid) => {
|
if (valid) {
|
const isRequire = this.verifyRequrie()
|
if (!isRequire) return false
|
|
this.form.latitude = Number.isNaN(parseFloat(this.form.latitude)) ? 0 : parseFloat(this.form.latitude)
|
this.form.longitude = Number.isNaN(parseFloat(this.form.longitude)) ? 0 : parseFloat(this.form.longitude)
|
this.form.sensors = list
|
this.form.resolution_width = Number(this.form.resolution.split("*")[0])
|
this.form.resolution_height = Number(this.form.resolution.split("*")[1])
|
let _this = this
|
// 更新
|
if (this.form.id !== "") {
|
this.form.areaid = this.TreeDataPool.getParent(this.form.id, this.isGb28182)
|
console.log(this.TreeDataPool.selectedNode)
|
|
let tem = {
|
camera: this.form,
|
sensors: this.form.sensors
|
}
|
tem.camera.clusterId = sessionStorage.getItem("clusterId")
|
tem.camera.devId = sessionStorage.getItem("devId")
|
delete tem.camera.sensors
|
|
updateCameraInfo(tem)
|
.then((rsp) => {
|
if (rsp.success) {
|
this.$notify({
|
type: "success",
|
message: "摄像机信息修改成功!"
|
})
|
this.TreeDataPool.fetchTreeData()
|
console.log(this.TreeDataPool.selectedNode)
|
//_this.$root.$children[0].$refs['leftTree'].$refs.tree.ztreeObj.checkNode(_this.TreeDataPool.selectedNode, true, false, false);
|
//选中修改后的节点
|
let { evt, treeId } = _this.$root.$children[0].$refs["leftTree"].$refs.tree
|
console.log(evt, treeId)
|
// this.$nextTick(()=>{
|
//_this.$root.$children[0].$refs['leftTree'].$refs.tree.handleCreated()
|
// })
|
} else {
|
this.selectCamera(this.TreeDataPool.selectedNode)
|
this.$notify({
|
type: "error",
|
message: "摄像机信息修改失败!"
|
})
|
}
|
})
|
.catch((err) => {})
|
} else {
|
this.form.areaid = this.addParentId
|
|
let tem = {
|
camera: this.form,
|
sensors: this.form.sensors
|
}
|
tem.camera.clusterId = sessionStorage.getItem("clusterId")
|
tem.camera.devId = sessionStorage.getItem("devId")
|
tem.camera.parentUserId = ""
|
tem.camera.enable = false
|
delete tem.camera.sensors
|
createCamera(tem)
|
.then((rsp) => {
|
if (rsp.success) {
|
this.$notify({
|
type: "success",
|
message: "摄像机添加成功!"
|
})
|
this.TreeDataPool.selectedNode = rsp.data.camera
|
this.TreeDataPool.fetchTreeData()
|
// 后端返回结果为0,查询后为4
|
this.TreeDataPool.selectedNode.type = "4"
|
this.selectCamera(this.TreeDataPool.selectedNode)
|
} else {
|
this.$notify({
|
type: "error",
|
message: "摄像机添加失败!"
|
})
|
}
|
})
|
.catch((err) => {
|
this.$notify({
|
type: "error",
|
message: err.msg
|
})
|
})
|
}
|
}
|
})
|
},
|
// 连接测试
|
cameraConnet() {
|
this.videoItem = null
|
this.$nextTick(() => {
|
this.videoItem = {
|
name: this.form.name,
|
rtsp: this.form.rtsp,
|
id: this.form.id,
|
isRunning: this.form.run_enable,
|
cameraType: this.form.type
|
}
|
|
console.log(this.videoItem)
|
})
|
},
|
// * 验证必选项
|
verifyRequrie() {
|
if (this.isGb28182) {
|
return true
|
}
|
// const rtspReg = /^(rtsp:\/\/)([a-zA-Z0-9_]+):([a-zA-Z0-9_]+)@(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{4}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])(\/)([a-zA-Z0-9_/]+)$/;
|
// !rtspReg.test(this.form.rtsp
|
|
if (this.form.rtsp === "") {
|
this.$notify({
|
type: "warning",
|
message: "请输入正确的rtsp地址"
|
})
|
return false
|
}
|
return true
|
},
|
// 删除摄像机
|
deleteCamera() {
|
this.$confirm("是否删除此摄像机?", {
|
center: true,
|
cancelButtonClass: "comfirm-class-cancle",
|
confirmButtonClass: "comfirm-class-sure"
|
}).then(() => {
|
if (!this.form.id) {
|
this.$notify({
|
type: "warning",
|
message: "尚未添加摄像机"
|
})
|
return
|
}
|
delCamera({
|
id: this.form.id,
|
clusterId: this.TreeDataPool.clusterId,
|
devId: this.TreeDataPool.devId
|
}).then((res) => {
|
if (res.success) {
|
this.initFormData()
|
this.$notify({
|
type: "success",
|
message: "删除成功!"
|
})
|
this.TreeDataPool.fetchTreeData()
|
this.TreeDataPool.selectedNode = {}
|
} else {
|
this.$notify({
|
type: "error",
|
message: "删除失败!"
|
})
|
}
|
})
|
})
|
},
|
// 清空输入框
|
initFormData() {
|
this.form = {
|
latitude: 0,
|
rtsp: "",
|
longitude: 0,
|
name: "",
|
addr: "",
|
alias: "",
|
areaid: "",
|
brand: "",
|
id: "",
|
ip: "",
|
reserved: "",
|
run_type: -1,
|
isAI: false,
|
username: "",
|
password: "",
|
resolution: "",
|
voiceId: "",
|
voiceEnable: false
|
}
|
},
|
// 添加设备
|
addDevice(node) {
|
this.isAdd = true
|
this.addParentId = node
|
this.resolutionList = [
|
{
|
label: "本机分辨率",
|
value: "0*0"
|
},
|
{
|
label: "1920*1080",
|
value: "1920*1080"
|
},
|
{
|
label: "2688*1520",
|
value: "2688*1520"
|
}
|
]
|
this.initFormData()
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.CameraInfo {
|
box-sizing: border-box;
|
|
.cameraHeader {
|
box-sizing: border-box;
|
margin-bottom: 24px;
|
padding: 25px 20px;
|
background-color: #fff;
|
}
|
|
.cameraBody {
|
display: flex;
|
|
.title {
|
margin-bottom: 60px;
|
}
|
|
.info {
|
box-sizing: border-box;
|
flex: 2;
|
padding: 20px;
|
margin-right: 24px;
|
height: 588px;
|
background-color: #fff;
|
|
.hashrate {
|
display: flex;
|
justify-content: space-between;
|
|
.card {
|
display: flex;
|
flex: 1;
|
align-items: center;
|
|
img {
|
margin-right: 5px;
|
width: 72px;
|
height: 72px;
|
}
|
|
.label {
|
font-size: 14px;
|
}
|
|
.number {
|
font-size: 16px;
|
font-weight: 700;
|
}
|
|
span {
|
font-size: 32px;
|
}
|
}
|
}
|
|
.chart {
|
margin-top: 90px;
|
.row {
|
margin-bottom: 30px;
|
display: flex;
|
height: 24px;
|
.label {
|
width: 48px;
|
}
|
|
.el-progress ::v-deep {
|
flex: 1;
|
border-radius: 15px;
|
.el-progress-bar__inner {
|
background: linear-gradient(270deg, #0065ff 0%, rgba(0, 101, 255, 0.25) 100%);
|
}
|
|
.el-progress-bar__outer {
|
background-color: #d4e3fa;
|
}
|
}
|
|
.number {
|
margin-left: 20px;
|
font-size: 14px;
|
color: #0065ff;
|
}
|
}
|
}
|
}
|
|
.camera {
|
box-sizing: border-box;
|
padding: 20px;
|
flex: 3;
|
height: 588px;
|
background-color: #fff;
|
|
.connect {
|
margin-bottom: 20px;
|
display: flex;
|
justify-content: flex-end;
|
}
|
|
.el-button {
|
width: 88px;
|
background-color: #0065ff;
|
}
|
}
|
}
|
|
@media screen and (max-width: 1600px) {
|
.cameraBody {
|
display: block;
|
|
.info {
|
margin-right: 0;
|
margin-bottom: 24px;
|
}
|
}
|
|
.camera {
|
height: auto !important;
|
}
|
}
|
|
.title {
|
box-sizing: border-box;
|
margin-bottom: 30px;
|
padding-left: 10px;
|
border-left: 4px solid #0065ff;
|
font-size: 16px;
|
font-weight: 700;
|
}
|
|
.video-player {
|
height: 0;
|
padding-bottom: 56.33%;
|
}
|
|
.addForm {
|
.row {
|
display: flex;
|
|
.el-form-item ::v-deep {
|
width: 441px;
|
margin-bottom: 40px;
|
}
|
.el-form-item.position ::v-deep .el-form-item__content {
|
display: flex;
|
|
.el-input {
|
margin-right: 10px;
|
width: 100px;
|
}
|
}
|
.el-form-item:nth-child(1) {
|
margin-right: 50px;
|
}
|
}
|
|
.el-input ::v-deep {
|
width: 360px;
|
height: 32px;
|
|
input {
|
border-radius: 0;
|
border-color: #c0c5cc;
|
&::-webkit-input-placeholder {
|
color: #999;
|
}
|
|
&:focus {
|
border-color: #0065ff;
|
}
|
}
|
}
|
|
.el-select ::v-deep {
|
width: 313px;
|
height: 32px;
|
|
input:focus {
|
border-color: #0065ff;
|
}
|
|
.el-input.is-focus .el-input__inner {
|
border-color: #0065ff;
|
}
|
|
input {
|
border-radius: 0;
|
height: 32px;
|
}
|
}
|
|
.clusterSelect.el-select {
|
width: 360px;
|
}
|
|
.el-switch ::v-deep {
|
height: 32px;
|
.el-switch__core {
|
height: 32px;
|
border-radius: 16px;
|
}
|
.el-switch__core::after {
|
margin-top: 2px;
|
margin-left: 4px;
|
width: 24px;
|
height: 24px;
|
background-color: #999999;
|
}
|
}
|
.el-switch.is-checked ::v-deep {
|
.el-switch__core {
|
background-color: #d4e3fa;
|
border-color: #d4e3fa;
|
}
|
.el-switch__core::after {
|
margin-left: -28px;
|
background-color: #0065ff;
|
}
|
}
|
}
|
|
.btns {
|
display: flex;
|
justify-content: flex-end;
|
margin-top: 20px;
|
|
.delBtn {
|
margin: 0 24px 0 0;
|
box-sizing: content-box;
|
margin: 9px 24px;
|
color: #ff4b33;
|
font-size: 16px;
|
background-color: #fff;
|
border: 1px solid #ff4b33;
|
border-radius: 0;
|
}
|
|
.saveBtn {
|
margin: 0;
|
box-sizing: content-box;
|
margin: 9px 24px;
|
color: #fff;
|
font-size: 16px;
|
background-color: #0065ff;
|
border: 1px solid #0065ff;
|
border-radius: 0;
|
}
|
}
|
}
|
</style>
|