This commit is contained in:
bb_pan 2025-01-21 18:12:34 +08:00
parent 2d93fe0f2e
commit 365794ab8b
5 changed files with 217 additions and 135 deletions

View File

@ -0,0 +1,31 @@
import request from '@/utils/request';
// 获取视频设备列表
export const getList = (params) => {
return request.get('/smart-site/video_equipment/list', { params });
};
// 获取设备类型列表
export const getTypeList = (data) => {
return request.post('/smart-site/video_equipment/getTypeList', data);
};
// 新增视频设备
export const addVideoDevice = (data) => {
return request.post('/smart-site/video_equipment/add', data);
};
// 编辑视频设备
export const editVideoDevice = (data) => {
return request.post('/smart-site/video_equipment/edit', data);
};
// 删除视频设备
export const delVideoDevice = (id) => {
return request.post(`/smart-site/video_equipment/del/${id}`);
};
// 获取视频设备详情
export const getVideoDeviceDetail = (id) => {
return request.get(`/smart-site/video_equipment/${id}`);
};

View File

@ -12,7 +12,7 @@ import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import { download, derive } from '@/utils/request'
import './assets/icons' // icon
import './permission' // permission control
@ -56,6 +56,7 @@ Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.derive = derive
Vue.prototype.handleTree = handleTree
Vue.prototype.indexContinuation = indexContinuation

View File

@ -184,4 +184,33 @@ export function download(url, params, filename, config) {
})
}
// 通用导出方法
export function derive(url, params, filename, config) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
return service.post(url, JSON.stringify(params), {
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'encryption': 'encryption'
},
responseType: 'blob',
...config
}).then(async (data) => {
const isBlob = blobValidate(data);
if (isBlob) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
})
}
export default service

View File

@ -136,8 +136,8 @@
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogConfirm"> </el-button>
<el-button @click="dialogVisible = false">{{ isDetail ? '关 闭' : '取 消' }}</el-button>
<el-button type="primary" @click="dialogConfirm" v-if="!isDetail"> </el-button>
</span>
</el-dialog>
</div>

View File

@ -10,8 +10,8 @@
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="" prop="deviceStatus">
<el-select v-model="queryParams.deviceStatus" placeholder="设备状态" clearable>
<el-form-item label="" prop="onLine">
<el-select v-model="queryParams.onLine" placeholder="设备状态" clearable>
<el-option v-for="item in deviceStatusOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
@ -48,13 +48,13 @@
<template v-slot="scope" v-if="column.prop == 'qrCode'">
<span style="color: #409eff; cursor: pointer" @click="checkQrCode(scope.row)">查看</span>
</template>
<template v-slot="scope" v-else-if="column.prop == 'isAccess'">
<div style="display: flex; align-items: center">
<div class="dot" v-if="scope.row.isAccess == 1"></div>
<template v-slot="scope" v-else-if="column.prop == 'isT'">
<div style="display: flex; align-items: center; justify-content: center">
<div class="dot" v-if="scope.row.isT == 1"></div>
<div class="dot-red" v-else></div>
<div>{{ scope.row.isAccess == 1 ? '是' : '否' }}</div>
<div>{{ scope.row.isT == 1 ? '是' : '否' }}</div>
<div
v-if="scope.row.isAccess == 1"
v-if="scope.row.isT == 1"
style="margin-left: 5px; color: #409eff; cursor: pointer"
@click="handleDetail(scope.row)"
>
@ -62,18 +62,20 @@
</div>
</div>
</template>
<template v-slot="scope" v-else-if="column.prop == 'deviceStatus'">
<div style="display: flex; align-items: center">
<div class="dot" v-if="scope.row.deviceStatus == 1"></div>
<template v-slot="scope" v-else-if="column.prop == 'onLine'">
<div style="display: flex; align-items: center; justify-content: center">
<div class="dot" v-if="scope.row.onLine == 1"></div>
<div class="dot-red" v-else></div>
<div>{{ scope.row.deviceStatus == 1 ? '在用' : '闲置' }}</div>
<div>{{ scope.row.onLine == 1 ? '在用' : '闲置' }}</div>
</div>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column label="操作" align="center" width="255">
<template slot-scope="scope">
<el-button type="warning" plain size="mini" icon="el-icon-set-up" @click="handleMonitoringAndDebug(scope.row)">调试</el-button>
<el-button type="warning" plain size="mini" icon="el-icon-set-up" @click="handleMonitoringAndDebug(scope.row)"
>调试</el-button
>
<el-button type="primary" plain size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">
编辑
</el-button>
@ -95,70 +97,71 @@
<!-- 弹框 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">
<el-form
ref="dialogForm"
:model="dialogForm"
label-width="170px"
:rules="dialogRules"
>
<el-form-item label="设备类型" prop="deviceType" v-if="showItem">
<el-select v-model="dialogForm.deviceType" placeholder="请选择设备类型" clearable style="width: 100%">
<el-form ref="dialogForm" :model="dialogForm" label-width="170px" :rules="dialogRules">
<el-form-item label="设备类型" prop="devType" v-if="showItem">
<el-select v-model="dialogForm.devType" placeholder="请选择设备类型" clearable style="width: 100%">
<el-option v-for="item in deviceTypeOpts" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName" v-if="showItem">
<el-input v-model="dialogForm.deviceName" placeholder="请输入设备名称" clearable />
<el-form-item label="设备名称" prop="devName" v-if="showItem">
<el-input v-model="dialogForm.devName" placeholder="请输入设备名称" clearable maxlength="64" />
</el-form-item>
<el-form-item label="MACID" prop="macId" v-if="showItem">
<el-input v-model="dialogForm.macId" placeholder="请输入MACID" clearable />
<el-form-item label="MAC编码" prop="macId" v-if="showItem">
<el-input v-model="dialogForm.macId" placeholder="请输入MAC编码" clearable maxlength="64" />
</el-form-item>
<el-form-item label="国标编码" prop="gbCode" v-if="showItem">
<el-input v-model="dialogForm.gbCode" placeholder="请输入国标编码" clearable maxlength="64" />
</el-form-item>
<el-form-item label="puid" prop="puId" v-if="showItem">
<el-input v-model="dialogForm.puId" placeholder="请输入puid" clearable />
<el-input v-model="dialogForm.puId" placeholder="请输入puid" clearable maxlength="64" />
</el-form-item>
<el-form-item label="是否接入统一视频" prop="isAccess" v-if="showItem">
<el-radio-group v-model="dialogForm.isAccess" @input="changeIsAccess">
<el-form-item label="视频下标" prop="videoIndex" v-if="showItem">
<el-input v-model="dialogForm.videoIndex" placeholder="请输入视频下标" clearable maxlength="64" />
</el-form-item>
<el-form-item label="是否接入统一视频" prop="isT" v-if="showItem">
<el-radio-group v-model="dialogForm.isT" @input="changeIsAccess">
<el-radio-button label="1"></el-radio-button>
<el-radio-button label="0"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="统一视频名称" prop="unifiedVideoName" v-if="dialogForm.isAccess == '1'">
<el-form-item label="统一视频名称" prop="tName" v-if="dialogForm.isT == '1'">
<el-input
v-model="dialogForm.unifiedVideoName"
v-model="dialogForm.tName"
placeholder="请输入统一视频名称"
clearable
:disabled="!showItem"
maxlength="64"
/>
</el-form-item>
<el-form-item label="统一视频编码" prop="unifiedVideoCode" v-if="dialogForm.isAccess == '1'">
<el-form-item label="统一视频编码" prop="tCode" v-if="dialogForm.isT == '1'">
<el-input
v-model="dialogForm.unifiedVideoCode"
v-model="dialogForm.tCode"
placeholder="请输入统一视频编码"
clearable
:disabled="!showItem"
maxlength="64"
/>
</el-form-item>
<el-form-item
label="统一视频前端协议编码"
prop="unifiedVideoFrontEndProtocolCode"
v-if="dialogForm.isAccess == '1'"
>
<el-form-item label="统一视频前端协议编码" prop="tWbCode" v-if="dialogForm.isT == '1'">
<el-input
v-model="dialogForm.unifiedVideoFrontEndProtocolCode"
v-model="dialogForm.tWbCode"
placeholder="请输入统一视频前端协议编码"
clearable
:disabled="!showItem"
maxlength="64"
/>
</el-form-item>
<el-form-item label="统一设备协议编码" prop="unifiedDeviceProtocolCode" v-if="dialogForm.isAccess == '1'">
<el-form-item label="统一设备协议编码" prop="tDevCode" v-if="dialogForm.isT == '1'">
<el-input
v-model="dialogForm.unifiedDeviceProtocolCode"
v-model="dialogForm.tDevCode"
placeholder="请输入统一设备协议编码"
clearable
:disabled="!showItem"
maxlength="64"
/>
</el-form-item>
<el-form-item label="备注" prop="remark" v-if="showItem">
<el-input type="textarea" v-model="dialogForm.remark" placeholder="请输入备注" clearable />
<el-input type="textarea" v-model="dialogForm.remark" placeholder="请输入备注" clearable maxlength="100" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -170,15 +173,14 @@
<!-- 二维码弹框 -->
<el-dialog title="二维码查看" :visible.sync="qrVisible" width="36%">
<div style="text-align: center">
<vue-qr ref="qrCode" :text="qrData.qrCode" color-dark="#333" :size="390" :margin="10"></vue-qr>
<div>设备编号: {{ qrData.deviceNo }}</div>
<div>设备名称: {{ qrData.deviceName }}</div>
<vue-qr ref="qrCode" :text="qrData.macId" color-dark="#333" :size="390" :margin="10"></vue-qr>
<div>设备编号: {{ qrData.gbCode }}</div>
<div>设备名称: {{ qrData.devName }}</div>
<!-- 下载 -->
<el-button type="primary" @click="downloadQrCode" style="margin-top: 20px"> </el-button>
</div>
</el-dialog>
<el-dialog title="调试" :visible.sync="videoDebug" width="70%" height="80%">
<MonitoringAndDebug />
</el-dialog>
@ -187,13 +189,20 @@
<script>
import VueQr from 'vue-qr'
import MonitoringAndDebug from '@/views/deviceManagement/videoDeviceMgmt/monitoringAndDebug.vue';
import MonitoringAndDebug from '@/views/deviceManagement/videoDeviceMgmt/monitoringAndDebug.vue'
import {
getList,
getTypeList,
addVideoDevice,
editVideoDevice,
delVideoDevice,
getVideoDeviceDetail,
} from '@/api/deviceManagement'
export default {
components: {
VueQr,
MonitoringAndDebug
MonitoringAndDebug,
},
data() {
return {
@ -202,76 +211,50 @@ export default {
pageNum: 1,
pageSize: 10,
keyWord: '', //
deviceStatus: '', //
onLine: '', //
},
deviceStatusOptions: [
{ label: '用', value: '1' },
{ label: '闲置', value: '2' },
{ label: '用', value: '1' },
{ label: '闲置', value: '0' },
], //
total: 0, //
//
tableColumns: [
{ label: '设备类型', prop: 'deviceType' },
{ label: '设备名称', prop: 'deviceName' },
{ label: '设备类型', prop: 'devTypeName' },
{ label: '设备名称', prop: 'devName' },
{ label: 'MACID', prop: 'macId' },
{ label: 'puid', prop: 'puId' },
{ label: '二维码', prop: 'qrCode' },
{ label: '是否接入统一视频', prop: 'isAccess' },
{ label: '是否接入统一视频', prop: 'isT' },
{ label: '备注', prop: 'remark' },
{ label: '更新人', prop: 'updateBy' },
{ label: '更新人', prop: 'updater' },
{ label: '更新时间', prop: 'updateTime' },
{ label: '设备状态', prop: 'deviceStatus' },
{ label: '设备状态', prop: 'onLine' },
],
//
tableList: [
{
deviceType: '设备类型设备类型设备类型设备类型设备类型',
deviceNo: '473829107443214',
deviceName: 'bns球机-1',
macId: 'MACID',
puId: 'puid',
qrCode: '1233456789',
isAccess: '1',
remark: '备注',
updateBy: '更新人',
updateTime: '更新时间',
deviceStatus: '1',
},
{
deviceType: '设备类型',
deviceNo: '473829107443214',
deviceName: 'bns球机-2',
macId: 'MACID',
puId: 'puid',
qrCode: '1233456789',
isAccess: '0',
remark: '备注',
updateBy: '更新人',
updateTime: '更新时间',
deviceStatus: '0',
},
],
tableList: [],
qrVisible: false,
videoDebug: false,
qrData: {
qrCode: '',
deviceNo: '',
deviceName: '',
devName: '',
},
dialogTitle: '新增',
isAdd: true,
dialogVisible: false,
showItem: true,
dialogForm: {
deviceType: '', //
deviceName: '', //
devType: '', //
devTypeName: '', //
devName: '', //
macId: '', // MACID
nationalStandardCode: '', //
gbCode: '', //
puId: '', // puid
isAccess: '0', //
unifiedVideoName: '', //
unifiedVideoCode: '', //
unifiedVideoFrontEndProtocolCode: '', //
unifiedDeviceProtocolCode: '', //
videoIndex: '0', //
isT: '0', //
tName: '', //
tCode: '', //
tWbCode: '', //
tDevCode: '', //
remark: '', //
},
deviceTypeOpts: [
@ -279,34 +262,25 @@ export default {
{ label: '设备类型2', value: '2' },
],
dialogRules: {
deviceType: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
nationalStandardCode: [{ required: true, message: '请输入国标编码', trigger: 'blur' }],
devType: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
devName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
gbCode: [{ required: true, message: '请输入国标编码', trigger: 'blur' }],
macId: [{ required: true, message: '请输入MACID', trigger: 'blur' }],
puId: [{ required: true, message: '请输入puid', trigger: 'blur' }],
isAccess: [
// videoIndex number ,
videoIndex: [
{ required: true, message: '请输入视频下标', trigger: 'blur' },
{
required: true,
message: '请选择是否接入统一视频',
trigger: 'blur',
},
],
unifiedVideoName: [{ required: true, message: '请输入统一视频名称', trigger: 'blur' }],
unifiedVideoCode: [{ required: true, message: '请输入统一视频编码', trigger: 'blur' }],
unifiedVideoFrontEndProtocolCode: [
{
required: true,
message: '请输入统一视频前端协议编码',
trigger: 'blur',
},
],
unifiedDeviceProtocolCode: [
{
required: true,
message: '请输入统一设备协议编码',
pattern: /^[0-9,]*$/,
message: '只能输入数字和逗号',
trigger: 'blur',
},
],
isT: [{ required: true, message: '请选择是否接入统一视频', trigger: 'blur' }],
tName: [{ required: true, message: '请输入统一视频名称', trigger: 'blur' }],
tCode: [{ required: true, message: '请输入统一视频编码', trigger: 'blur' }],
tWbCode: [{ required: true, message: '请输入统一视频前端协议编码', trigger: 'blur' }],
tDevCode: [{ required: true, message: '请输入统一设备协议编码', trigger: 'blur' }],
},
}
},
@ -329,17 +303,30 @@ export default {
async getList() {
console.log('列表-查询', this.queryParams)
try {
// const params = { ...this.queryParams }
// const res = await
// console.log('🚀 ~ ~ res:', res)
// this.tableList = res.rows
// this.total = res.total
this.tableList = []
const params = { ...this.queryParams }
const res = await getList(params)
console.log('🚀 ~ 获取列表 ~ res:', res)
this.tableList = res.rows
this.total = res.total
} catch (error) {
console.log('🚀 ~ 获取列表 ~ error:', error)
this.tableList = []
this.total = 0
}
},
//
async getTypeList() {
try {
const params = { dictType: 'smart_device_type' }
const res = await getTypeList(params)
console.log('🚀 ~ 获取设备类型 ~ res:', res)
this.deviceTypeOpts = res.data
} catch (error) {
console.log('🚀 ~ 获取设备类型 ~ error:', error)
this.deviceTypeOpts = []
}
},
//
selectionChange(val) {
console.log('selectionChange', val)
@ -362,30 +349,45 @@ export default {
downloadQrCode() {
console.log('下载二维码')
const a = document.createElement('a') // a
a.download = this.qrData.deviceName // 
a.download = this.qrData.devName // 
a.href = this.$refs.qrCode.$el.src // 
a.click()
},
//
async getDetail(id) {
try {
const res = await getVideoDeviceDetail(id)
console.log('🚀 ~ 获取详情 ~ res:', res)
this.dialogForm = res.data
} catch (error) {
console.log('🚀 ~ 获取详情 ~ error:', error)
}
},
//
handleAdd() {
this.getTypeList()
console.log('新增')
this.dialogTitle = '新增'
this.dialogVisible = true
this.dialogForm.isAccess = '0'
this.dialogForm.isT = '0'
this.isAdd = true
this.showItem = true
this.$nextTick(() => {
this.$refs.dialogForm.clearValidate()
this.$refs.dialogForm.resetFields()
})
},
//
handleEdit(row) {
this.getTypeList()
console.log('编辑', row)
this.dialogTitle = '编辑'
this.isAdd = false
this.dialogVisible = true
this.dialogForm.isAccess = row.isAccess
this.dialogForm.isT = row.isT
this.showItem = true
this.$nextTick(() => {
this.$refs.dialogForm.clearValidate()
this.getDetail(row.id)
})
},
//
@ -398,7 +400,7 @@ export default {
console.log('查看配置', row)
this.dialogTitle = '统一平台配置'
this.dialogVisible = true
this.dialogForm.isAccess = row.isAccess
this.dialogForm = row
this.showItem = false
this.$nextTick(() => {
this.$refs.dialogForm.clearValidate()
@ -412,8 +414,9 @@ export default {
cancelButtonText: '取消',
type: 'warning',
}).then(async () => {
// const params = { }
// const res = await
const res = await delVideoDevice(row.id)
console.log('🚀 ~ 删除 ~ res:', res)
this.getList()
this.$message({
type: 'success',
message: '删除成功!',
@ -424,10 +427,10 @@ export default {
handleExport() {
try {
let fileName = `数据_${new Date().getTime()}.xLsx`
let url = ''
let url = '/smart-site/video_equipment/export'
const params = { ...this.queryParams }
console.log('🚀 ~ 导出 ~ params:', params)
// this.derive(url, params, fileName)
this.derive(url, params, fileName)
} catch (error) {
console.log('导出数据失败', error)
}
@ -435,13 +438,31 @@ export default {
//
dialogConfirm() {
console.log('dialogConfirm')
this.$refs.dialogForm.validate((valid) => {
this.$refs.dialogForm.validate(async (valid) => {
if (valid) {
this.dialogVisible = false
if (this.dialogForm.isT == '0') {
this.dialogForm.tName = ''
this.dialogForm.tCode = ''
this.dialogForm.tWbCode = ''
this.dialogForm.tDevCode = ''
}
const params = { ...this.dialogForm }
console.log('🚀 ~ this.$refs.dialogForm.validate ~ params:', params)
let res = {}
if (this.isAdd) {
//
res = await addVideoDevice(params)
} else {
//
res = await editVideoDevice(params)
}
console.log('🚀 ~ 弹框确认 ~ res:', res)
this.$message({
type: 'success',
message: '操作成功!',
})
this.getList()
this.dialogVisible = false
} else {
return false
}