<template> <!-- 摄像头基础信息管理 --> <div class="publicContainer"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> <el-form-item label="摄像头名称" prop="name"> <el-input v-model="queryParams.name" placeholder="请输入摄像头名称" clearable @keyup.enter="handleQuery" /> </el-form-item> <el-form-item label="类型" prop="cameraType"> <el-select filterable v-model="queryParams.cameraType" placeholder="选择摄像头类型" style="width: 190px" clearable> <el-option v-for="item in videotype" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" /> </el-select> </el-form-item> <el-form-item label="状态" prop="status"> <el-select filterable v-model="queryParams.status" placeholder="选择摄像头状态" style="width: 190px" clearable> <el-option v-for="item in stateList" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" /> </el-select> </el-form-item> <el-form-item label="数据来源" prop="cameraSource"> <el-select filterable v-model="queryParams.cameraSource" placeholder="请输入数据来源" style="width: 190px"> <el-option v-for="item in cameraSourceList" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> <el-form-item> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['cameraResource:cameraResource:add']">新增</el-button> </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="RefreshRight" @click="synchronization" v-hasPermi="['cameraResource:cameraResource:edit']"> 同步 </el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="Download" color="#626aef" @click="sycndownload" v-hasPermi="['cameraResource:cameraResource:edit']" > 插件下载 </el-button> </el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="cameraResourceList" @selection-change="handleSelectionChange" max-height="650"> <el-table-column type="selection" width="55" /> <el-table-column label="海康编码" prop="indexCode" /> <el-table-column label="摄像头名称" prop="name" /> <el-table-column label="摄像头类型" prop="cameraType"> <template #default="scope"> <span>{{ scope.row.cameraType == 1 ? '枪机' : '球机' }}</span> </template> </el-table-column> <el-table-column label="在线状态" prop="state"> <template #default="scope"> <span :class="scope.row.state == 1 ? 'color' : 'red'">{{ scope.row.state == 1 ? '在线' : '离线' }}</span> </template> </el-table-column> <el-table-column label="分组类型" prop="groupName" /> <el-table-column label="数据来源" prop="cameraSource"> <template #default="scope"> <span>{{ scope.row.cameraSource == 1 ? '新建' : scope.row.cameraSource == 2 ? '共享' : '' }}</span> </template> </el-table-column> <el-table-column label="摄像头地址" prop="cameraAddress" /> <el-table-column label="责任人" prop="cameraUserName" /> <el-table-column label="权属单位" prop="ownershipUnit" /> <el-table-column label="是否显示" prop="isShow"> <template #default="scope"> <span @click="changeisShow(scope.row)" :class="scope.row.isShow == 0 ? 'color' : 'red'">{{ scope.row.isShow == 0 ? '是' : '否' }}</span> </template> </el-table-column> <el-table-column label="操作" class-name="small-padding fixed-width"> <template #default="scope"> <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['cameraResource:cameraResource:edit']"> 修改 </el-button> <el-button link type="primary" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['cameraResource:cameraResource:view']"> 详情 </el-button> </template> </el-table-column> </el-table> <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> <!-- 添加或修改摄像头基础信息对话框 --> <el-dialog :title="title" v-model="open" width="1150px" append-to-body> <el-form ref="cameraResourceRef" :model="form" :rules="rules" label-width="120px"> <el-row :gutter="10" class="mb8"> <el-col :span="12"> <el-form-item label="海康编码" prop="indexCode"> <el-input v-model="form.indexCode" :disabled="title.includes('修改')" placeholder="请输入海康编码" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="摄像头名称" prop="name"> <el-input v-model="form.name" :disabled="title.includes('修改')" placeholder="请输入摄像头名称" /> </el-form-item> </el-col> </el-row> <el-row :gutter="10" class="mb8"> <el-col :span="12"> <el-form-item label="摄像头地址" prop="cameraAddress"> <el-input v-model="form.cameraAddress" placeholder="请输入摄像头地址" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="摄像头坐标" prop="point"> <el-input v-model="form.point" @focus="openMapDialog" placeholder="请输入摄像头坐标" /> </el-form-item> </el-col> </el-row> <el-row :gutter="10" class="mb8"> <el-col :span="12"> <el-form-item label="摄像头类型" prop="cameraType"> <el-select filterable v-model="form.cameraType" placeholder="选择摄像头类型" style="width: 610px" @change="videotypechagne"> <el-option v-for="item in videotype" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="视频分组" prop="groupId"> <el-select filterable v-model="form.groupId" placeholder="选择视频分组" style="width: 610px" @change="cameraGroupchange"> <el-option v-for="item in cameraGroupList" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> </el-row> <el-row :gutter="10" class="mb8"> <el-col :span="12"> <el-form-item label="责任人" prop="cameraUserId"> <el-select filterable v-model="form.cameraUserId" placeholder="选择责任人" style="width: 610px" @change="peoplechange"> <el-option v-for="dict in allpeople" :key="dict.userId" :label="dict.nickName" :value="dict.userId" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="联系方式" prop="phone"> <el-input v-model="form.phone" placeholder="请输入联系方式" /> </el-form-item> </el-col> </el-row> <el-row :gutter="10" class="mb8"> <el-col :span="12"> <el-form-item label="权属单位" prop="ownershipUnit"> <el-input v-model="form.ownershipUnit" placeholder="请输入权属单位" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="数据来源" prop="cameraSource"> <el-select filterable v-model="form.cameraSource" placeholder="请输入数据来源" style="width: 610px"> <el-option v-for="item in cameraSourceList" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="摄像头所属区域" prop="regionIndexCode"> <el-select filterable v-model="form.regionIndexCode" placeholder="请选择所属区域维护" style="width: 610px"> <el-option v-for="item in regionsoptions" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="摄像头播放地址" prop="cameraUrl" v-show="form.cameraSource == 2"> <el-input v-model="form.cameraUrl" placeholder="请输入摄像头播放地址" /> </el-form-item> </el-col> </el-row> <el-form-item label="摄像头照片" prop="imageList"> <ImageFileUpload :limit="1" :saveFileArr="form.imageList" :listType="'picture-card'" :refField="'imageList'" :refType="'camera_info'" ></ImageFileUpload> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="info" @click="cancel">取 消</el-button> <el-button type="primary" @click="submitForm">确 定</el-button> </div> </template> </el-dialog> <!-- 摄像头基础信息详情 --> <el-dialog title="摄像头基础信息详情" v-model="detailOpen" width="900px" append-to-body> <div class="publicContainer"> <div class="publicDetail"> <div class="part"> <p class="title">海康编码:</p> <p class="content"> {{ dialogFormDetail.indexCode }} </p> </div> <div class="part"> <p class="title">摄像头名称:</p> <p class="content"> {{ dialogFormDetail.name }} </p> </div> <div class="part"> <p class="title">经度:</p> <p class="content"> {{ dialogFormDetail.x }} </p> </div> <div class="part"> <p class="title">维度:</p> <p class="content"> {{ dialogFormDetail.y }} </p> </div> <div class="part"> <p class="title">状态:</p> <p class="content"> {{ dialogFormDetail.cameraStatus == 0 ? '不在线' : '在线' }} </p> </div> <div class="part"> <p class="title">摄像头地址:</p> <p class="content"> {{ dialogFormDetail.cameraAddress }} </p> </div> <div class="part"> <p class="title">视频类型:</p> <p class="content"> {{ dialogFormDetail.cameraType == 1 ? '枪机' : '球机' }} </p> </div> <div class="part"> <p class="title">权属单位:</p> <p class="content"> {{ dialogFormDetail.ownershipUnit }} </p> </div> </div> </div> <template #footer> <div class="dialog-footer"> <el-button @click="cancel">关 闭</el-button> </div> </template> </el-dialog> <!-- 地址选择 --> <el-dialog title="选择单位地址" v-model="mapDialogOpen" width="1100px" append-to-body destroy-on-close> <div class="map-box" style="height: 630px"> <mapBox :isShowTool="false" :isShowSearch="true" :isSelectAddress="true" @getPlace="getAddress"></mapBox> </div> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="mapDialogOpen = false">确 定</el-button> </div> </template> </el-dialog> </div> </template> <script setup name="CameraResource"> import { pagecameraResource, getcameraResource, addcameraResource, updatecameraResource, cameraInfotb, } from '@/api/cameraResource/cameraResource'; import { pageregionStation } from '@/api/cameraResource/regionStation'; import { listcameraGroupInfo } from '@/api/cameraResource/cameraGroupInfo'; import mapBox from '@/components/Map/index.vue'; import ImageFileUpload from '@/components/ImageFileUpload/index.vue'; //图片文件上传 import { listUser } from '@/api/system/user'; import { getConfigKey } from '@/api/system/config'; import { isPhone } from '@/utils/validate'; const { proxy } = getCurrentInstance(); const mapDialogOpen = ref(false); //地图弹框 const cameraResourceList = ref([]); const open = ref(false); const loading = ref(true); const showSearch = ref(true); const ids = ref([]); const single = ref(true); const multiple = ref(true); const total = ref(0); const title = ref(''); const detailOpen = ref(false); const allpeople = ref([]); //所有人 const regionsoptions = ref([]); //区域编号 const checkDutyTellPhone = (rule, value, callback) => { if (!isPhone(value)) { callback(new Error('电话号码格式错误')); } else { callback(); } }; const cameraGroupList = ref([]); const stateList = ref([ { dictValue: 1, dictLabel: '在线' }, { dictValue: 0, dictLabel: '离线' }, ]); const videotype = ref([ { dictValue: 2, dictLabel: '球机' }, { dictValue: 1, dictLabel: '枪机' }, ]); const cameraSourceList = ref([ { value: 1, label: '新建' }, { value: 2, label: '共享' }, ]); const data = reactive({ form: {}, queryParams: { pageNum: 1, pageSize: 10, indexCode: '', name: null, regionIndexCode: null, isTop: null, isShow: null, x: null, y: null, geometrys: null, cameraStatus: null, isHighSpot: null, cameraAddress: null, imageList: null, cameraType: null, ownershipUnit: null, status: null, cameraSource: null, }, rules: { // name: [{ required: true, message: "不能为空", trigger: "blur" }], cameraUserId: [{ required: true, message: '不能为空', trigger: 'change' }], indexCode: [{ required: true, message: '不能为空', trigger: 'blur' }], name: [{ required: true, message: '不能为空', trigger: 'blur' }], cameraAddress: [{ required: true, message: '不能为空', trigger: 'blur' }], cameraType: [{ required: true, message: '不能为空', trigger: 'change' }], // groupId: [{ required: true, message: '不能为空', trigger: 'change' }], phone: [{ required: false, trigger: 'blur', validator: checkDutyTellPhone }], }, dialogFormDetail: {}, //详情弹框数据 }); const { queryParams, form, rules, dialogFormDetail } = toRefs(data); //打开单位地址地图弹框 function openMapDialog() { mapDialogOpen.value = true; setTimeout(() => { if (window.newfiberMap && form.value.x && form.value.y) { let position = [form.value.x, form.value.y]; newfiberMap.removeByIds(['addressSearch']); newfiberMap.geojsonToMap( NewFiberMap.Data.ToGeoJSON.beansWktToGeoJson([ { id: 'addressSearch', name: form.value.cameraAddress, geometrys: `POINT(${position.join(' ')})`, type: NewFiberMap.Enum.VectorType.ICON, style: { url: NewFiberMapConfig.SDK_INIT_SRC_PREFIX + '/static/images/running_path/marker.png', width: 50, height: 50, }, labelOptions: { font: '13px HarmonyOS Sans SC-Bold, HarmonyOS Sans SC', color: 'rgb(255,255,255,1)', pixelOffset: [0, -38], backgroundColor: 'rgba(64,158,255,1)', showBackground: true, distanceDisplayCondition: [Number.MIN_VALUE, 55000], }, }, ]) ); newfiberMap.getMap().flyTo(newfiberMap.getLayers(['addressSearch'][0])); } }, 100); } function getAddress(val) { form.value.cameraAddress = val.caseAddress; form.value.point = val.lonLat[0] + ',' + val.lonLat[1]; form.value.x = val.lonLat[0]; form.value.y = val.lonLat[1]; } // 获得所有人的接口 function getallpeople() { let params = { pageNum: 1, pageSize: 9999, }; listUser(params).then(res => { allpeople.value = res.data; }); } function changeisShow(row) { row.isShow = row.isShow == 0 ? 1 : 0; updatecameraResource(row).then(response => { proxy.$modal.msgSuccess('修改成功'); open.value = false; getList(); }); } // 获得所有分组的接口 function GetlistcameraGroupInfo() { listcameraGroupInfo().then(res => { cameraGroupList.value = res.data; console.log(1233123, cameraGroupList.value); }); } function peoplechange(value) { var obj = allpeople.value.filter(item => { return item.userId == value; })[0]; if (obj) { form.value.cameraUserName = obj.nickName; form.value.phone = obj.phonenumber; } } function videotypechagne(value) { var obj = videotype.value.filter(item => { return item.dictValue == value; })[0]; // form.value.planTypeName = obj.dictLabel } function cameraGroupchange(value) { var obj = cameraGroupList.value.filter(item => { return item.id == value; })[0]; form.value.groupName = obj.name; } /** 搜索摄像头基础信息列表 */ function getList() { loading.value = false; pagecameraResource(queryParams.value).then(response => { cameraResourceList.value = response.data; total.value = response.total; loading.value = false; }); } // 取消按钮 function cancel() { open.value = false; detailOpen.value = false; reset(); } // 表单重置 function reset() { form.value = { id: null, indexCode: null, name: null, regionIndexCode: null, isTop: null, isShow: null, x: null, y: null, geometrys: null, cameraStatus: null, isHighSpot: null, cameraAddress: null, imageList: [], cameraType: null, ownershipUnit: null, remark: null, status: null, delFlag: null, createBy: null, createTime: null, updateBy: null, updateTime: null, cameraUserName: null, cameraUserId: null, phone: null, groupId: null, groupName: null, point: '', cameraSource: null, }; proxy.resetForm('cameraResourceRef'); } /** 搜索按钮操作 */ function handleQuery() { queryParams.value.pageNum = 1; getList(); } /** 重置按钮操作 */ function resetQuery() { proxy.resetForm('queryRef'); handleQuery(); } // 多选框选中数据 function handleSelectionChange(selection) { ids.value = selection.map(item => item.id); single.value = selection.length != 1; multiple.value = !selection.length; } /** 新增按钮操作 */ function handleAdd() { reset(); open.value = true; title.value = '添加摄像头基础信息'; } /** 修改按钮操作 */ function handleUpdate(row) { reset(); const _id = row.id || ids.value; getcameraResource(_id).then(response => { form.value = response.data; form.value.cameraUserId = Number(form.value.cameraUserId); console.log(99, response.data); form.value.point = response.data.x + ',' + response.data.y; open.value = true; title.value = '修改摄像头基础信息'; }); } /** 同步按钮操作 */ function synchronization() { proxy.$modal.loading('正在同步数据,请稍候...'); cameraInfotb() .then(res => { proxy.$modal.closeLoading(); getList(); }) .catch(error => { proxy.$modal.closeLoading(); }); } async function sycndownload() { let { data } = await getConfigKey('hikvision.plug.url'); const iframe = document.createElement('iframe'); // 创建一个HTML 元素 iframe.style.display = 'none'; // 隐藏iframe 防止影响页面 iframe.style.height = 0; // 高度设置0 防止影响页面 iframe.src = data; // 下载链接 document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求 // 5分钟之后删除 setTimeout(() => { iframe.remove(); }, 5 * 60 * 1000); } /** 提交按钮 */ function submitForm() { proxy.$refs['cameraResourceRef'].validate(valid => { if (valid) { if (form.value.id != null) { updatecameraResource(form.value).then(response => { proxy.$modal.msgSuccess('修改成功'); open.value = false; getList(); }); } else { addcameraResource(form.value).then(response => { proxy.$modal.msgSuccess('新增成功'); open.value = false; getList(); }); } } }); } /** 搜索摄像头资源所属区域维护列表 */ function getList2() { loading.value = true; let param = { pageNum: 1, pageSize: 9999, }; pageregionStation(param).then(response => { regionsoptions.value = response.data; }); } //查看详情操作 function handleDetail(row) { detailOpen.value = true; dialogFormDetail.value = row; } getList2(); getList(); getallpeople(); GetlistcameraGroupInfo(); </script> <style lang="scss" scoped> .color { color: #54d2ff; cursor: pointer; } .red { color: rgb(216, 43, 43); cursor: pointer; } </style>