V4修复: jsx改用onInit+columns+render 组件自含对话框
This commit is contained in:
@@ -1,72 +1,33 @@
|
||||
/**
|
||||
* base_device 页面操作列扩展
|
||||
* 按 DeviceGroup 动态渲染对应的操作按钮组件
|
||||
* 框架升级不覆盖此文件(extension 目录受保护)
|
||||
* 在 onInit 中动态注入自定义操作列,按 DeviceGroup 渲染对应按钮组件
|
||||
* 对话框由各按钮组件内部自行管理
|
||||
*/
|
||||
import { h } from 'vue'
|
||||
import VideoDeviceActions from '@/views/warehouse/device_manager/base_device/components/VideoDeviceActions.vue'
|
||||
import IoTDeviceActions from '@/views/warehouse/device_manager/base_device/components/IoTDeviceActions.vue'
|
||||
import AccessDeviceActions from '@/views/warehouse/device_manager/base_device/components/AccessDeviceActions.vue'
|
||||
import BarrierDeviceActions from '@/views/warehouse/device_manager/base_device/components/BarrierDeviceActions.vue'
|
||||
import AlarmDeviceActions from '@/views/warehouse/device_manager/base_device/components/AlarmDeviceActions.vue'
|
||||
import DeviceLivePreview from '@/views/warehouse/device_manager/base_device/components/DeviceLivePreview.vue'
|
||||
import PtzControlPanel from '@/views/warehouse/device_manager/base_device/components/PtzControlPanel.vue'
|
||||
import RealtimeDataPanel from '@/views/warehouse/device_manager/base_device/components/RealtimeDataPanel.vue'
|
||||
import DeviceControlPanel from '@/views/warehouse/device_manager/base_device/components/DeviceControlPanel.vue'
|
||||
import DeviceEditDialog from '@/views/warehouse/device_manager/base_device/components/DeviceEditDialog.vue'
|
||||
import MapBindingPanel from '@/views/warehouse/device_manager/base_device/components/MapBindingPanel.vue'
|
||||
|
||||
// 按 DeviceGroup 映射操作组件
|
||||
const actionMap = {
|
||||
'视频设备': 'VideoDeviceActions',
|
||||
'IoT设备': 'IoTDeviceActions',
|
||||
'门禁设备': 'AccessDeviceActions',
|
||||
'道闸设备': 'BarrierDeviceActions',
|
||||
'报警设备': 'AlarmDeviceActions',
|
||||
'视频设备': VideoDeviceActions,
|
||||
'IoT设备': IoTDeviceActions,
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoDeviceActions, IoTDeviceActions, AccessDeviceActions, BarrierDeviceActions, AlarmDeviceActions,
|
||||
DeviceLivePreview, PtzControlPanel, RealtimeDataPanel, DeviceControlPanel, DeviceEditDialog, MapBindingPanel
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
currentDevice: null,
|
||||
dialogs: { preview: false, ptz: false, realtime: false, control: false, edit: false, map: false }
|
||||
}
|
||||
},
|
||||
|
||||
// 替换框架操作列
|
||||
slots: {
|
||||
'col-action': (h, { row }) => {
|
||||
const compName = actionMap[row.deviceGroup]
|
||||
if (!compName) return null
|
||||
// 渲染自定义按钮组,绑定事件
|
||||
return h(compName, {
|
||||
props: { row },
|
||||
on: {
|
||||
preview: () => this.openDialog('preview', row),
|
||||
ptz: () => this.openDialog('ptz', row),
|
||||
playback: () => console.log('playback', row),
|
||||
snapshot: () => console.log('snapshot', row),
|
||||
syncChannels: () => console.log('syncChannels', row),
|
||||
realtime: () => this.openDialog('realtime', row),
|
||||
control: () => this.openDialog('control', row),
|
||||
refresh: () => this.$emit('refresh'),
|
||||
alarms: () => console.log('alarms', row),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
openDialog(name, device) {
|
||||
this.currentDevice = device
|
||||
this.dialogs[name] = true
|
||||
},
|
||||
onRefresh() {
|
||||
this.$emit('refresh')
|
||||
}
|
||||
onInit() {
|
||||
const gcol = this.columns.find(c => c.field === 'DeviceGroup')
|
||||
if (gcol) gcol.hidden = false
|
||||
this.columns.splice(0, 0, {
|
||||
field: '_actions',
|
||||
title: '操作',
|
||||
type: 'string',
|
||||
width: 300,
|
||||
fixed: 'right',
|
||||
align: 'left',
|
||||
render: (h, { row }) => {
|
||||
const comp = actionMap[row.DeviceGroup]
|
||||
if (!comp) return null
|
||||
return h(comp, { row })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
<template>
|
||||
<div style="display:flex;gap:4px;flex-wrap:wrap">
|
||||
<el-button size="small" type="primary" @click="$emit('realtime')">实时数据</el-button>
|
||||
<el-button v-if="isControl" size="small" @click="$emit('control')">设备控制</el-button>
|
||||
<el-button size="small" type="primary" @click="realtimeVisible=true">实时数据</el-button>
|
||||
<el-button v-if="isControl" size="small" @click="controlVisible=true">设备控制</el-button>
|
||||
<el-button size="small" @click="$emit('refresh')">刷新</el-button>
|
||||
<el-button size="small" type="warning" @click="$emit('alarms')">查看告警</el-button>
|
||||
<RealtimeDataPanel v-model="realtimeVisible" :device="row" />
|
||||
<DeviceControlPanel v-model="controlVisible" :device="row" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import RealtimeDataPanel from './RealtimeDataPanel.vue'
|
||||
import DeviceControlPanel from './DeviceControlPanel.vue'
|
||||
const props = defineProps({ row: { type: Object, default: () => ({}) } })
|
||||
defineEmits(['realtime','control','refresh','alarms'])
|
||||
// 通过 ExtraData 判断是否为控制点
|
||||
defineEmits(['refresh','alarms'])
|
||||
const realtimeVisible = ref(false), controlVisible = ref(false)
|
||||
const isControl = computed(() => {
|
||||
try { return JSON.parse(props.row?.extraData || '{}')?.isControlPoint === true } catch { return false }
|
||||
})
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
<template>
|
||||
<div style="display:flex;gap:4px;flex-wrap:wrap">
|
||||
<el-button size="small" type="primary" @click="$emit('preview')">
|
||||
<el-icon><VideoPlay /></el-icon> 实时预览
|
||||
<el-button size="small" type="primary" @click="previewVisible=true">
|
||||
<el-icon><VideoPlay /></el-icon> 预览
|
||||
</el-button>
|
||||
<el-button size="small" @click="$emit('ptz')">
|
||||
<el-icon><Aim /></el-icon> 云台控制
|
||||
<el-button size="small" @click="ptzVisible=true">
|
||||
<el-icon><Aim /></el-icon> 云台
|
||||
</el-button>
|
||||
<el-button size="small" @click="$emit('playback')">
|
||||
<el-icon><VideoCamera /></el-icon> 查看回放
|
||||
<el-icon><VideoCamera /></el-icon> 回放
|
||||
</el-button>
|
||||
<el-button size="small" @click="$emit('snapshot')">
|
||||
<el-icon><Camera /></el-icon> 获取快照
|
||||
<el-icon><Camera /></el-icon> 快照
|
||||
</el-button>
|
||||
<el-button v-if="row?.isParent==='是'" size="small" type="warning" @click="$emit('syncChannels')">
|
||||
同步通道
|
||||
</el-button>
|
||||
<DeviceLivePreview v-model="previewVisible" :device="row" />
|
||||
<PtzControlPanel v-model="ptzVisible" :device="row" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import DeviceLivePreview from './DeviceLivePreview.vue'
|
||||
import PtzControlPanel from './PtzControlPanel.vue'
|
||||
defineProps({ row: { type: Object, default: () => ({}) } })
|
||||
defineEmits(['preview','ptz','playback','snapshot','syncChannels'])
|
||||
defineEmits(['playback','snapshot','syncChannels'])
|
||||
const previewVisible = ref(false), ptzVisible = ref(false)
|
||||
</script>
|
||||
|
||||
@@ -30,15 +30,14 @@ export default function(){
|
||||
const searchFormOptions = [];
|
||||
const columns = [{field:'DeviceId',title:'设备ID',type:'int',width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'DeviceName',title:'设备名称',type:'string',link:true,width:120,require:true,align:'left'},
|
||||
{field:'AdapterCode',title:'来源适配器(类型:实例)',type:'string',width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'SourceId',title:'源系统设备ID',type:'string',width:120,require:true,align:'left'},
|
||||
{field:'AdapterCode',title:'来源适配器(类型:实例)',type:'string',width:110,hidden:true,align:'left'},
|
||||
{field:'SourceId',title:'源系统设备ID',type:'string',width:120,align:'left'},
|
||||
{field:'DeviceCategory',title:'设备种类(数据字典)',type:'string',bind:{ key:'设备种类',data:[]},width:110,require:true,align:'left'},
|
||||
{field:'DeviceGroup',title:'设备分组(数据字典)',type:'string',bind:{ key:'设备分组',data:[]},width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'PointId',title:'所属点位ID',type:'int',width:110,hidden:true,align:'left'},
|
||||
{field:'GatewayNodeId',title:'所属网关节点ID',type:'int',width:110,hidden:true,align:'left'},
|
||||
{field:'IsParent',title:'是否父设备(数据字典)',type:'string',bind:{ key:'是否父设备',data:[]},width:110,require:true,align:'left'},
|
||||
{field:'ParentDeviceId',title:'父设备ID(自引用,子设备挂父设备下)',type:'int',width:110,hidden:true,align:'left'},
|
||||
{field:'IsOnline',title:'在线状态(数据字典)',type:'string',bind:{ key:'在线状态',data:[]},width:110,require:true,align:'left'},
|
||||
{field:'IsOnline',title:'在线状态(数据字典)',type:'string',bind:{ key:'在线状态',data:[]},width:110,align:'left'},
|
||||
{field:'IpAddress',title:'IP地址',type:'string',width:110,align:'left'},
|
||||
{field:'Port',title:'端口',type:'int',width:110,align:'left'},
|
||||
{field:'Location',title:'安装位置',type:'string',width:180,align:'left'},
|
||||
@@ -56,7 +55,8 @@ export default function(){
|
||||
{field:'CreateDate',title:'创建时间',type:'datetime',width:110,align:'left'},
|
||||
{field:'ModifyID',title:'修改人ID',type:'int',width:80,hidden:true,align:'left'},
|
||||
{field:'Modifier',title:'修改人',type:'string',width:100,align:'left'},
|
||||
{field:'ModifyDate',title:'修改时间',type:'datetime',width:110,align:'left'}];
|
||||
{field:'ModifyDate',title:'修改时间',type:'datetime',width:110,align:'left'},
|
||||
{field:'NodeId',title:'所属网关节点ID',type:'int',width:120,hidden:true,align:'left'}];
|
||||
const detail ={columns:[]};
|
||||
const details = [ {
|
||||
cnName: '视频通道',
|
||||
|
||||
@@ -40,7 +40,64 @@ export default function(){
|
||||
{field:'Modifier',title:'修改人',type:'string',width:100,align:'left'},
|
||||
{field:'ModifyDate',title:'修改时间',type:'datetime',width:110,align:'left'}];
|
||||
const detail ={columns:[]};
|
||||
const details = [];
|
||||
const details = [ {
|
||||
cnName: '设备管理',
|
||||
table: 'base_device',
|
||||
columns: [{field:'DeviceId',title:'设备ID',type:'int',width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'DeviceName',title:'设备名称',type:'string',link:true,width:120,edit:{type:''},require:true,align:'left'},
|
||||
{field:'AdapterCode',title:'来源适配器(类型:实例)',type:'string',width:110,hidden:true,align:'left'},
|
||||
{field:'SourceId',title:'源系统设备ID',type:'string',width:120,align:'left'},
|
||||
{field:'DeviceCategory',title:'设备种类(数据字典)',type:'string',bind:{ key:'设备种类',data:[]},width:110,edit:{type:'select'},require:true,align:'left'},
|
||||
{field:'DeviceGroup',title:'设备分组(数据字典)',type:'string',bind:{ key:'设备分组',data:[]},width:110,hidden:true,edit:{type:'select'},require:true,align:'left'},
|
||||
{field:'PointId',title:'所属点位ID',type:'int',width:110,hidden:true,edit:{type:''},align:'left'},
|
||||
{field:'IsParent',title:'是否父设备(数据字典)',type:'string',bind:{ key:'是否父设备',data:[]},width:110,edit:{type:'select'},require:true,align:'left'},
|
||||
{field:'ParentDeviceId',title:'父设备ID(自引用,子设备挂父设备下)',type:'int',width:110,hidden:true,align:'left'},
|
||||
{field:'IsOnline',title:'在线状态(数据字典)',type:'string',bind:{ key:'在线状态',data:[]},width:110,align:'left'},
|
||||
{field:'IpAddress',title:'IP地址',type:'string',width:110,align:'left'},
|
||||
{field:'Port',title:'端口',type:'int',width:110,align:'left'},
|
||||
{field:'Location',title:'安装位置',type:'string',width:180,edit:{type:''},align:'left'},
|
||||
{field:'Lat',title:'纬度',type:'decimal',width:110,align:'left'},
|
||||
{field:'Lng',title:'经度',type:'decimal',width:110,align:'left'},
|
||||
{field:'MapModelId',title:'三维地图模型ID',type:'string',width:120,edit:{type:''},align:'left'},
|
||||
{field:'MapModelScale',title:'模型缩放比例',type:'decimal',width:110,align:'left'},
|
||||
{field:'MapModelRotation',title:'模型旋转角度(JSON)',type:'string',width:120,align:'left'},
|
||||
{field:'ExtraData',title:'适配器扩展数据JSON(Owl/MC4/门禁字段均存于此)',type:'string',width:110,align:'left'},
|
||||
{field:'LastSyncTime',title:'上次同步时间',type:'datetime',width:110,align:'left'},
|
||||
{field:'Enable',title:'启用状态(数据字典)',type:'string',bind:{ key:'启用状态',data:[]},width:110,edit:{type:'select'},align:'left'},
|
||||
{field:'Remark',title:'备注',type:'string',width:150,edit:{type:'textarea'},align:'left'},
|
||||
{field:'CreateID',title:'创建人ID',type:'int',width:80,hidden:true,align:'left'},
|
||||
{field:'Creator',title:'创建人',type:'string',width:100,align:'left'},
|
||||
{field:'CreateDate',title:'创建时间',type:'datetime',width:110,align:'left'},
|
||||
{field:'ModifyID',title:'修改人ID',type:'int',width:80,hidden:true,align:'left'},
|
||||
{field:'Modifier',title:'修改人',type:'string',width:100,align:'left'},
|
||||
{field:'ModifyDate',title:'修改时间',type:'datetime',width:110,align:'left'},
|
||||
{field:'NodeId',title:'所属网关节点ID',type:'int',width:120,hidden:true,readonly:true,align:'left'}],
|
||||
sortName: 'DeviceName',
|
||||
key: 'DeviceId',
|
||||
buttons:[],
|
||||
delKeys:[],
|
||||
detail:{
|
||||
cnName: '设备管理_视频通道',
|
||||
table: 'video_channel',
|
||||
firstTable: 'gateway_nodes',
|
||||
secondTable: 'base_device',
|
||||
secondKey: 'DeviceId',
|
||||
sortName: 'DeviceId',
|
||||
key: 'ChannelId',
|
||||
buttons:[],
|
||||
delKeys:[],
|
||||
columns: [{field:'ChannelId',title:'通道记录ID',type:'int',width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'OwlChannelId',title:'Owl系统通道ID',type:'string',width:120,hidden:true,require:true,align:'left'},
|
||||
{field:'DeviceId',title:'关联Base_Device设备ID',type:'int',width:110,hidden:true,require:true,align:'left'},
|
||||
{field:'OwlStreamApp',title:'Owl流应用名',type:'string',width:110,align:'left'},
|
||||
{field:'OwlStreamName',title:'Owl流名称',type:'string',width:120,align:'left'},
|
||||
{field:'HasPtz',title:'是否支持云台',type:'byte',width:110,align:'left'},
|
||||
{field:'HasRecording',title:'是否支持录像',type:'byte',width:110,align:'left'},
|
||||
{field:'RecordMode',title:'录像模式',type:'int',width:110,align:'left'},
|
||||
{field:'SnapshotUrl',title:'快照地址',type:'string',width:150,align:'left'},
|
||||
{field:'CreateDate',title:'创建时间',type:'datetime',width:110,align:'left'},]
|
||||
}
|
||||
}];
|
||||
|
||||
return {
|
||||
table,
|
||||
|
||||
Reference in New Issue
Block a user