flx:视频监控新增批量导入、移动、删除

This commit is contained in:
Rain_ 2025-09-09 14:10:49 +08:00
parent 31e082a4ba
commit d38f0b6325
3 changed files with 621 additions and 307 deletions

View File

@ -85,3 +85,13 @@ export const addOcrZonePlaceApi = data => post('xmgl/ocrZonePlace/add', data);
export const editOcrZonePlaceApi = data => post('xmgl/ocrZonePlace/edit', data); export const editOcrZonePlaceApi = data => post('xmgl/ocrZonePlace/edit', data);
// 删除ocr识别区域位置信息 // 删除ocr识别区域位置信息
export const deleteOcrZonePlaceApi = data => post('xmgl/ocrZonePlace/delete', data); export const deleteOcrZonePlaceApi = data => post('xmgl/ocrZonePlace/delete', data);
// 摄像机列表
// 批量删除
export const deleteVideoItemBatchApi = data => post('xmgl/videoItem/deleteBatch', data);
// 下载模版
export const downloadExcelTemplateApi = data => get('xmgl/videoItem/downloadExcelTemplate', data);
// 导入模版
export const importExcelApi = data => post('xmgl/videoItem/importExcel', data);
// 移动分组
export const moveGroupApi = data => post('xmgl/videoItem/moveGroup', data);

View File

@ -1,42 +1,81 @@
<template> <template>
<div style="padding-top:15px"> <div style="padding-top: 15px">
<el-table class="tables" :data="cameraList"> <el-table
<el-table-column prop="videoName" align="center" class="tables"
@select="onSelect"
@select-all="onSelect"
ref="multipleTable"
:data="cameraList"
>
<el-table-column
type="selection"
align="center"
width="55"
></el-table-column>
<el-table-column
prop="videoName"
align="center"
:label="$t('message.videoManage.equipment_list.name')" :label="$t('message.videoManage.equipment_list.name')"
></el-table-column> ></el-table-column>
<!-- 直播url --> <!-- 直播url -->
<el-table-column v-if="videoInfo.videoType==2" prop="liveRadioUrl" :label="$t('message.videoManage.liveUrl')" <el-table-column
align="center"></el-table-column> v-if="videoInfo.videoType == 2"
<el-table-column v-else prop="serialNumber" :label="videoInfo.videoType==3?$t('message.videoManage.dialog_newVideo.cameraCode'):$t('message.videoManage.equipment_list.serial_number')" prop="liveRadioUrl"
align="center"></el-table-column> :label="$t('message.videoManage.liveUrl')"
align="center"
></el-table-column>
<el-table-column
v-else
prop="serialNumber"
:label="
videoInfo.videoType == 3
? $t('message.videoManage.dialog_newVideo.cameraCode')
: $t('message.videoManage.equipment_list.serial_number')
"
align="center"
></el-table-column>
<el-table-column prop="deviceState" align="center" label="设备在线状态"> <el-table-column prop="deviceState" align="center" label="设备在线状态">
<template slot-scope="scope"> <template slot-scope="scope">
{{scope.row.deviceState == 1 ? '在线' : '离线'}} {{ scope.row.deviceState == 1 ? "在线" : "离线" }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="ip" align="center" <el-table-column
prop="ip"
align="center"
label="设备ip" label="设备ip"
></el-table-column> ></el-table-column>
<el-table-column prop="nvrSn" align="center" label="nvr编号"> <el-table-column prop="nvrSn" align="center" label="nvr编号">
</el-table-column> </el-table-column>
<el-table-column prop="serialNumber" :label="$t('message.videoManage.equipment_list.deviceTypeTitle')" <el-table-column
align="center"> prop="serialNumber"
:label="$t('message.videoManage.equipment_list.deviceTypeTitle')"
align="center"
>
<template slot-scope="scope"> <template slot-scope="scope">
{{$t('message.videoManage.deviceType')[scope.row.deviceType-1]}} {{ $t("message.videoManage.deviceType")[scope.row.deviceType - 1] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column width="250" <el-table-column
:label="$t('message.alarmValueSet.operation')"> width="250"
:label="$t('message.alarmValueSet.operation')"
>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="tableBtns"> <div class="tableBtns">
<div @click="beforeEdit(scope.row)" class="operationText"> <div @click="beforeEdit(scope.row)" class="operationText">
<img src="@/assets/images/icon-edit.png" width="15px" height="15px"/> <img
<span>{{$t('message.alarmValueSet.edit')}}</span> src="@/assets/images/icon-edit.png"
width="15px"
height="15px"
/>
<span>{{ $t("message.alarmValueSet.edit") }}</span>
</div> </div>
<div @click="beforeDelete(scope.row)" class="operationText"> <div @click="beforeDelete(scope.row)" class="operationText">
<img src="@/assets/images/icon-delete.png" width="15px" height="15px"/> <img
<span>{{$t('message.videoManage.delete')}}</span> src="@/assets/images/icon-delete.png"
width="15px"
height="15px"
/>
<span>{{ $t("message.videoManage.delete") }}</span>
</div> </div>
</div> </div>
</template> </template>
@ -92,31 +131,56 @@
<tag type="success" text="success"></tag> <tag type="success" text="success"></tag>
<tag type="info" text="info"></tag>--> <tag type="info" text="info"></tag>-->
<el-dialog :modal-append-to-body="false" :title="$t('message.videoManage.dialog_play_title')" :visible.sync="play.show" width="90%" <el-dialog
class="play" @close="close"> :modal-append-to-body="false"
<div style="height: 600px;"> :title="$t('message.videoManage.dialog_play_title')"
<ck-play v-if="playType==='pt'" :showSelectBtn="false" :url="play.params.url"></ck-play> :visible.sync="play.show"
<ysy-play v-if="playType==='ysy'" :ysy-params="play.params"></ysy-play> width="90%"
class="play"
@close="close"
>
<div style="height: 600px">
<ck-play
v-if="playType === 'pt'"
:showSelectBtn="false"
:url="play.params.url"
></ck-play>
<ysy-play
v-if="playType === 'ysy'"
:ysy-params="play.params"
></ysy-play>
</div> </div>
</el-dialog> </el-dialog>
<!--删除弹窗--> <!--删除弹窗-->
<el-dialog :modal-append-to-body="false" :title="$t('message.videoManage.dialog_delete_title')" :visible.sync="Popup.delete" width="667px"> <el-dialog
:modal-append-to-body="false"
:title="$t('message.videoManage.dialog_delete_title')"
:visible.sync="Popup.delete"
width="667px"
>
<div class="dialog_content"> <div class="dialog_content">
<div class="platforms-title"> <div class="platforms-title">
{{$t('message.videoManage.prompt_before_deleting')[0]}}{{Popup.title}}{{$t('message.videoManage.prompt_before_deleting')[1]}} {{ $t("message.videoManage.prompt_before_deleting")[0] }}{{
Popup.title
}}{{ $t("message.videoManage.prompt_before_deleting")[1] }}
</div> </div>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button class="zdy-btn" @click="Popup.delete=false" size="medium"> <el-button
class="zdy-btn"
@click="Popup.delete = false"
size="medium"
>
<div> <div>
<img src="../../../assets/images/cancel.png" alt=""> <img src="../../../assets/images/cancel.png" alt="" />
<span>{{$t('message.videoManage.btn_cancel')}}</span> <span>{{ $t("message.videoManage.btn_cancel") }}</span>
</div> </div>
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
icon="el-icon-circle-check" icon="el-icon-circle-check"
@click="ToDelete" @click="ToDelete"
size="medium">{{$t('message.videoManage.btn_determine')}} size="medium"
>{{ $t("message.videoManage.btn_determine") }}
</el-button> </el-button>
</div> </div>
</div> </div>
@ -125,21 +189,21 @@
</template> </template>
<script> <script>
import { import {
selectVideoItemListByTypeApi, selectVideoItemListByTypeApi,
deleteVideoItemApi, deleteVideoItemApi,
editVideoItemApi editVideoItemApi,
} from '@/assets/js/api/equipmentCenter/cameraList' } from "@/assets/js/api/equipmentCenter/cameraList";
import tag from '../../../components/tag' import tag from "../../../components/tag";
import ysyPlay from '../../../views/projectFront/videoManage/ysyPlayAndPlayback' import ysyPlay from "../../../views/projectFront/videoManage/ysyPlayAndPlayback";
import ckPlay from '@/components/videoModule/ckPlayer' import ckPlay from "@/components/videoModule/ckPlayer";
export default { export default {
name: "cameraList", name: "cameraList",
components: { components: {
tag, tag,
ysyPlay, ysyPlay,
ckPlay ckPlay,
}, },
mounted() { mounted() {
// this.getSelectVideoItemListByTypeApi(); // this.getSelectVideoItemListByTypeApi();
@ -151,126 +215,139 @@
return { return {
/*videoItemInfo: {}, /*videoItemInfo: {},
deviceTypeList: this.$t('message.videoManage.equipment_list.deviceType'),//['', '', '', '', '', '']*/ deviceTypeList: this.$t('message.videoManage.equipment_list.deviceType'),//['', '', '', '', '', '']*/
tag_exception: ['normal', 'info', 'violet', 'danger', 'warning', 'info', 'normal'], tag_exception: [
"normal",
"info",
"violet",
"danger",
"warning",
"info",
"normal",
],
// tag_deviceType: ['info'], // tag_deviceType: ['info'],
playType: '', playType: "",
Popup: { Popup: {
delete: false, delete: false,
params: {} params: {},
}, },
play: { play: {
show: false, show: false,
params: { params: {
url: '', url: "",
accessToken: '' accessToken: "",
} },
}, },
current: -1, current: -1,
icon: { icon: {
video: require('../../../assets/images/icon-watch-video.png'), video: require("../../../assets/images/icon-watch-video.png"),
video_gray: require('../../../assets/images/icon-watch-video-gray.png') video_gray: require("../../../assets/images/icon-watch-video-gray.png"),
}, },
currentPage: 1, currentPage: 1,
videoInfo: {}, videoInfo: {},
cameraList: [] cameraList: [],
} };
}, },
methods: { methods: {
onSelect() {
this.$emit("selectDevice", this.$refs.multipleTable.selection);
},
setVideoInfo(obj) { setVideoInfo(obj) {
this.videoInfo = {videoType: obj.videoType, projectSn: obj.projectSn}; this.videoInfo = { videoType: obj.videoType, projectSn: obj.projectSn };
// console.log('', this.videoInfo); // console.log('', this.videoInfo);
this.getSelectVideoItemListByTypeApi(); this.getSelectVideoItemListByTypeApi();
}, },
getSelectVideoItemListByTypeApi(id) { getSelectVideoItemListByTypeApi(id) {
console.log('参数', this.videoInfo); console.log("参数", this.videoInfo);
this.videoInfo.groupId=id this.videoInfo.groupId = id;
selectVideoItemListByTypeApi(this.videoInfo).then(result => { selectVideoItemListByTypeApi(this.videoInfo).then((result) => {
if (result.success) { if (result.success) {
console.log('下面的列表渲染',result) console.log("下面的列表渲染", result);
this.cameraList = result.result; this.cameraList = result.result;
// console.log('videoInfo', this.videoInfo, '', this.cameraList); // console.log('videoInfo', this.videoInfo, '', this.cameraList);
} }
}) });
},
handleSizeChange() {
},
handleCurrentChange() {
}, },
handleSizeChange() {},
handleCurrentChange() {},
toPlay(type, params) { toPlay(type, params) {
this.play.show = true; this.play.show = true;
this.playType = type; this.playType = type;
this.play.params = params; this.play.params = params;
console.log('打印params', params) console.log("打印params", params);
}, },
close() { close() {
this.play = { this.play = {
show: false, show: false,
params: { params: {
url: '', url: "",
accessToken: '' accessToken: "",
} },
} };
console.log('打印play', this.play) console.log("打印play", this.play);
}, },
beforeEdit(obj) { beforeEdit(obj) {
// this.Popup.editDevice = true; // this.Popup.editDevice = true;
// this.Popup.params.itemId = itemId; // this.Popup.params.itemId = itemId;
this.$emit('editDevice', obj); this.$emit("editDevice", obj);
console.log('编辑的item', obj) console.log("编辑的item", obj);
}, },
beforeDelete(itemId) { beforeDelete(itemId) {
//groupId //groupId
this.Popup.delete = true; this.Popup.delete = true;
this.Popup.params.itemId = itemId.itemId; this.Popup.params.itemId = itemId.itemId;
this.Popup.title = itemId.videoName; this.Popup.title = itemId.videoName;
this.Popup.groupId = itemId.groupId this.Popup.groupId = itemId.groupId;
console.log('删除的设备',itemId.videoName) console.log("删除的设备", itemId.videoName);
}, },
ToDelete() { ToDelete() {
deleteVideoItemApi({itemId: this.Popup.params.itemId}).then(result => { deleteVideoItemApi({ itemId: this.Popup.params.itemId }).then(
console.log('删除成功', result); (result) => {
console.log("删除成功", result);
if (result.success) { if (result.success) {
this.$message.success(result.message); this.$message.success(result.message);
this.Popup.delete = false; this.Popup.delete = false;
this.getSelectVideoItemListByTypeApi(this.Popup.groupId) this.getSelectVideoItemListByTypeApi(this.Popup.groupId);
}
});
}
} }
} }
);
},
},
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.flex { .flex {
display: flex; display: flex;
} }
.play /deep/ .el-dialog { .play /deep/ .el-dialog {
height: 90%; height: 90%;
} }
.Playable { // .Playable {
//
cursor: pointer; cursor: pointer;
} }
.NotPlayable { // .NotPlayable {
//
cursor: not-allowed; cursor: not-allowed;
} }
.current_selected { .current_selected {
background-color: rgba(243, 245, 255, 1); background-color: rgba(243, 245, 255, 1);
box-shadow: 0 1px 8px 2px rgba(81, 129, 246, 0.16); box-shadow: 0 1px 8px 2px rgba(81, 129, 246, 0.16);
} }
.gray { .gray {
color: rgba(38, 45, 71, 0.6); color: rgba(38, 45, 71, 0.6);
} }
.alarm-container:hover { .alarm-container:hover {
.current_selected; .current_selected;
} }
.alarm-container { .alarm-container {
.flex; .flex;
justify-content: space-between; justify-content: space-between;
border: 1px solid rgba(233, 233, 233, 1); border: 1px solid rgba(233, 233, 233, 1);
@ -335,9 +412,9 @@
} }
} }
} }
} }
.zdy-btn { .zdy-btn {
div { div {
display: flex; display: flex;
align-items: center; align-items: center;
@ -348,9 +425,9 @@
margin-right: 6px; margin-right: 6px;
} }
} }
} }
.zdy-radio-group { .zdy-radio-group {
/deep/ .el-form-item__label { /deep/ .el-form-item__label {
line-height: normal; line-height: normal;
} }
@ -364,13 +441,13 @@
margin: 0 0 15px 0; margin: 0 0 15px 0;
} }
} }
} }
.zdy-radio-group-3rows { .zdy-radio-group-3rows {
.zdy-radio-group; .zdy-radio-group;
/deep/ .el-radio-group > label { /deep/ .el-radio-group > label {
width: 30%; width: 30%;
} }
} }
</style> </style>

View File

@ -140,6 +140,39 @@
<el-button type="primary" @click="accountServerObj" size="medium" <el-button type="primary" @click="accountServerObj" size="medium"
>{{ $t("message.videoManage.configAccount") }} >{{ $t("message.videoManage.configAccount") }}
</el-button> </el-button>
<el-button type="primary" @click="exportBtnTemplate" size="medium"
>模版下载
</el-button>
<el-upload
style="margin: 0px 15px; display: inline"
class="upload-demo expintBtn"
name="excelFile"
:on-success="handleImportSuccess"
:action="$http.defaults.baseURL + 'xmgl/videoItem/importExcel'"
:data="{ projectSn: projectSn, videoType: videoType }"
:show-file-list="false"
accept=".xlsx, .xls"
:headers="headers"
>
<el-button size="medium" type="primary">批量导入</el-button>
</el-upload>
<el-button
:disabled="selectionList.length == 0"
:type="selectionList.length == 0 ? 'info' : 'primary'"
@click="moveGroupClick"
plain
size="medium"
>批量移动
</el-button>
<el-button
:disabled="selectionList.length == 0"
:type="selectionList.length == 0 ? 'info' : 'danger'"
size="medium"
class="delete_btn"
plain
@click="deleteAttendanceBatch"
>删除</el-button
>
<!-- AI布防 --> <!-- AI布防 -->
<!-- <el-button <!-- <el-button
v-if="videoType == 3" v-if="videoType == 3"
@ -204,12 +237,82 @@
this.videoType === 4 this.videoType === 4
" "
@editDevice="edit" @editDevice="edit"
@selectDevice="selectDevice"
ref="cameralc" ref="cameralc"
></camera-list-lc> ></camera-list-lc>
</vue-scroll> </vue-scroll>
</div> </div>
</div> </div>
</div> </div>
<!-- 批量移动 -->
<el-dialog
:modal-append-to-body="false"
title="批量移动"
:visible.sync="moveGroupDialog"
width="667px"
>
<div class="dialog_content">
<el-form
class="dialogFormBox"
ref="moveGroupDialog"
label-width="100px"
size="medium"
:model="currentVideoTypeDetail"
:rules="formRules"
>
<!-- 所属分组 -->
<el-form-item :label="$t('message.videoManage.group')" prop="groupId">
<el-select
v-model="selectFormVal"
placeholder="请选择"
filterable
remote
:remote-method="filterData"
@visible-change="visibleChange"
clearable
@change="selectFormChange"
ref="searchSelect"
>
<el-option style="height: auto" :value="[]">
<el-tree
:data="videoTreeDataUp"
node-key="id"
ref="groupFormTree"
highlight-current
:props="defaultProps"
:default-expand-all="false"
@node-click="treeFormClick"
:filter-node-method="filterNode"
>
</el-tree>
<!-- :default-expanded-keys="defaultExpandArr" -->
</el-option>
</el-select>
</el-form-item>
</el-form>
<div class="dialog-footer">
<!--取消-->
<el-button
class="zdy-btn"
@click="moveGroupDialog = false"
size="medium"
>
<div>
<img src="../../../assets/images/cancel.png" alt="" />
<span>{{ $t("message.videoManage.btn_cancel") }}</span>
</div>
</el-button>
<!--确定-->
<el-button
type="primary"
icon="el-icon-circle-check"
@click="setMoveGroup"
size="medium"
>{{ $t("message.videoManage.btn_determine") }}
</el-button>
</div>
</div>
</el-dialog>
<!-- nvr --> <!-- nvr -->
<el-dialog <el-dialog
:modal-append-to-body="false" :modal-append-to-body="false"
@ -1244,6 +1347,10 @@ import {
editPluginApi, editPluginApi,
delPluginApi, delPluginApi,
getAllNvrApi, getAllNvrApi,
deleteVideoItemBatchApi,
downloadExcelTemplateApi,
importExcelApi,
moveGroupApi,
} from "@/assets/js/api/equipmentCenter/cameraList"; } from "@/assets/js/api/equipmentCenter/cameraList";
import { getEnterpriseInfoListApi } from "@/assets/js/api/specialWork"; import { getEnterpriseInfoListApi } from "@/assets/js/api/specialWork";
import { getProjectChilderSystemUserListApi } from "@/assets/js/api/configManage"; import { getProjectChilderSystemUserListApi } from "@/assets/js/api/configManage";
@ -1554,6 +1661,8 @@ export default {
isRouterAlive: false, isRouterAlive: false,
laborManagementInfoList: [], laborManagementInfoList: [],
filterText: "", filterText: "",
selectionList: [],
moveGroupDialog: false,
}; };
}, },
created() { created() {
@ -1568,15 +1677,133 @@ export default {
components: { cameraList, cameraListLc, gdMap }, components: { cameraList, cameraListLc, gdMap },
computed: { computed: {
videoTreeDataUp() { videoTreeDataUp() {
const resultList = this.recursion(this.videoTreeData) const resultList = this.recursion(this.videoTreeData);
console.log(11111222, resultList) console.log(11111222, resultList);
return resultList; return resultList;
}, },
headers() {
return { Authorization: this.$store.state.userInfo.token };
},
}, },
methods: { methods: {
visibleChange(event){ moveGroupClick() {
console.log(event) this.selectFormVal = "";
if(event){ this.currentVideoTypeDetail.groupId = "";
this.moveGroupDialog = true;
},
setMoveGroup() {
this.$refs.moveGroupDialog.validate((valid) => {
if (valid) {
if (this.selectionList.length === 0)
return this.$message.warning("请勾选需要移动的数据!");
const itemIds = this.selectionList.map((item) => item.itemId);
const params = {
itemIds,
videoGroupId: this.currentVideoTypeDetail.groupId,
projectSn: this.projectSn,
};
moveGroupApi(params).then((res) => {
if (res.success) {
this.$message.success(res.message);
this.moveGroupDialog = false;
this.getVideoList();
}
});
} else {
console.log("error submit!!");
return false;
}
});
},
//
handleImportSuccess(res) {
if (res.code == 200) {
this.$message.success(res.message);
if (this.videoType === 1) {
this.$refs.camera.setVideoInfo(this.configInfoParams);
} else {
this.$refs.cameralc.setVideoInfo(this.configInfoParams);
}
} else {
this.$message.error(res.message);
}
console.log("导入", res);
},
//
exportBtnTemplate() {
const requestData = {
projectSn: this.projectSn,
videoType: this.videoType,
};
fetch(
this.$http.defaults.baseURL +
`xmgl/videoItem/downloadExcelTemplate?projectSn=${this.projectSn}&videoType=${this.videoType}`,
{
method: "get",
headers: {
Authorization: this.$store.state.userInfo.token,
"Content-Type": "application/json", // JSON
},
// body: JSON.stringify(requestData),
}
)
.then((response) => {
//
if (!response.ok) {
throw new Error("导出失败");
}
return response.blob();
})
.then((blob) => {
console.log("导出成功");
//
const url = window.URL.createObjectURL(blob);
// <a>
const link = document.createElement("a");
link.href = url;
link.download = "视频监控点模板.xlsx"; //
//
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// URL
window.URL.revokeObjectURL(url);
//
// 使blob
})
.catch((error) => {
//
console.error(error);
});
},
selectDevice(event) {
console.log(event);
this.selectionList = event;
},
deleteAttendanceBatch() {
if (this.selectionList.length === 0)
return this.$message.warning("请勾选需要删除的数据!");
this.$confirm("删除后操作不可恢复,请谨慎操作!", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
console.log(this.selectionList);
const itemIds = this.selectionList
.map((item) => item.itemId)
.join(",");
deleteVideoItemBatchApi({ itemIds }).then((res) => {
this.selectionList = [];
this.$refs.cameralc.setVideoInfo(this.configInfoParams);
});
})
.catch(() => {});
},
visibleChange(event) {
console.log(event);
if (event) {
this.filterText = ""; this.filterText = "";
} }
}, },
@ -1588,13 +1815,13 @@ export default {
}, },
recursion(array) { recursion(array) {
// id // id
return array.filter(item => { return array.filter((item) => {
if (item.children && item.children.length > 0) { if (item.children && item.children.length > 0) {
this.recursion(item.children); this.recursion(item.children);
} }
console.log(item.groupName, item.groupName.indexOf(this.filterText)); console.log(item.groupName, item.groupName.indexOf(this.filterText));
return item.groupName.indexOf(this.filterText) !== -1; return item.groupName.indexOf(this.filterText) !== -1;
}) });
}, },
filterNode(value, data) { filterNode(value, data) {
if (!value) return true; if (!value) return true;
@ -1749,7 +1976,7 @@ export default {
// appSecret: '0a5836c68a7edabcc78e6a18f05bb317' // appSecret: '0a5836c68a7edabcc78e6a18f05bb317'
}; };
this.isRouterAlive = false; this.isRouterAlive = false;
if(this.currentGroupInfo.id) { if (this.currentGroupInfo.id) {
this.treeFormClick(this.currentGroupInfo); this.treeFormClick(this.currentGroupInfo);
} }
this.$nextTick(() => { this.$nextTick(() => {