Commit 4bc4891ec33fab5729e0b8925be0e122c389ffb7

Authored by loveumiko
1 parent 5200cae0

feat: 新增GBT协议相关修改和新增

@@ -4,7 +4,9 @@ import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/F @@ -4,7 +4,9 @@ import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/F
4 import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules'; 4 import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';
5 import { h } from 'vue'; 5 import { h } from 'vue';
6 import SnHelpMessage from './SnHelpMessage.vue'; 6 import SnHelpMessage from './SnHelpMessage.vue';
  7 +import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
7 import { OrgTreeSelect } from '../../common/OrgTreeSelect'; 8 import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  9 +import { findDictItemByCode } from '/@/api/system/dict';
8 10
9 useComponentRegister('OrgTreeSelect', OrgTreeSelect); 11 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
10 12
@@ -42,6 +44,16 @@ export enum MediaType { @@ -42,6 +44,16 @@ export enum MediaType {
42 M3U8 = 'm3u8', 44 M3U8 = 'm3u8',
43 } 45 }
44 46
  47 +const streamingTypeList = [
  48 + { label: 'GBT-28181', value: 'GBT-28181' },
  49 + { label: '其他', value: 'other' },
  50 +];
  51 +
  52 +export enum streamingType {
  53 + GBT = 'GBT-28181',
  54 + OTHER = 'other',
  55 +}
  56 +
45 // 表格列数据 57 // 表格列数据
46 export const columns: BasicColumn[] = [ 58 export const columns: BasicColumn[] = [
47 { 59 {
@@ -148,6 +160,44 @@ export const formSchema: QFormSchema[] = [ @@ -148,6 +160,44 @@ export const formSchema: QFormSchema[] = [
148 }, 160 },
149 }, 161 },
150 { 162 {
  163 + field: 'streamingType',
  164 + label: '流媒体类型',
  165 + component: 'Select',
  166 + ifShow({ values }) {
  167 + return values.accessMode == AccessMode.Streaming;
  168 + },
  169 + componentProps() {
  170 + return {
  171 + placeholder: '请选择流媒体类型',
  172 + defaultValue: streamingType.OTHER,
  173 + options: streamingTypeList,
  174 + };
  175 + },
  176 + },
  177 + {
  178 + field: 'device',
  179 + label: '设备选择',
  180 + ifShow({ values }) {
  181 + return values.streamingType == streamingType.GBT;
  182 + },
  183 + component: 'ApiSelect',
  184 + componentProps() {
  185 + return {
  186 + api: findDictItemByCode,
  187 + params: {
  188 + dictCode: 'device_type',
  189 + },
  190 + valueField: 'itemValue',
  191 + labelField: 'itemText',
  192 + placeholder: '请选择设备类型',
  193 + onChange: (value: DeviceTypeEnum) => {
  194 + console.log(value, 'value');
  195 + },
  196 + getPopupContainer: () => document.body,
  197 + };
  198 + },
  199 + },
  200 + {
151 field: 'brand', 201 field: 'brand',
152 label: '视频厂家', 202 label: '视频厂家',
153 component: 'Input', 203 component: 'Input',
@@ -193,7 +243,9 @@ export const formSchema: QFormSchema[] = [ @@ -193,7 +243,9 @@ export const formSchema: QFormSchema[] = [
193 label: '流媒体配置', 243 label: '流媒体配置',
194 component: 'Select', 244 component: 'Select',
195 ifShow({ values }) { 245 ifShow({ values }) {
196 - return values.accessMode === AccessMode.Streaming; 246 + return (
  247 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  248 + );
197 }, 249 },
198 slot: 'videoPlatformIdSlot', 250 slot: 'videoPlatformIdSlot',
199 componentProps: { 251 componentProps: {
@@ -206,7 +258,9 @@ export const formSchema: QFormSchema[] = [ @@ -206,7 +258,9 @@ export const formSchema: QFormSchema[] = [
206 component: 'RadioGroup', 258 component: 'RadioGroup',
207 defaultValue: StreamType.MASTER, 259 defaultValue: StreamType.MASTER,
208 ifShow({ values }) { 260 ifShow({ values }) {
209 - return values.accessMode === AccessMode.Streaming; 261 + return (
  262 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  263 + );
210 }, 264 },
211 componentProps: { 265 componentProps: {
212 placeholder: '请选择码流', 266 placeholder: '请选择码流',
@@ -224,7 +278,9 @@ export const formSchema: QFormSchema[] = [ @@ -224,7 +278,9 @@ export const formSchema: QFormSchema[] = [
224 component: 'RadioGroup', 278 component: 'RadioGroup',
225 defaultValue: PlayProtocol.HTTP, 279 defaultValue: PlayProtocol.HTTP,
226 ifShow({ values }) { 280 ifShow({ values }) {
227 - return values.accessMode === AccessMode.Streaming; 281 + return (
  282 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  283 + );
228 }, 284 },
229 helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'], 285 helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'],
230 componentProps: { 286 componentProps: {
@@ -242,7 +298,9 @@ export const formSchema: QFormSchema[] = [ @@ -242,7 +298,9 @@ export const formSchema: QFormSchema[] = [
242 component: 'Input', 298 component: 'Input',
243 rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }], 299 rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
244 ifShow({ values }) { 300 ifShow({ values }) {
245 - return values.accessMode === AccessMode.Streaming; 301 + return (
  302 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  303 + );
246 }, 304 },
247 componentProps: { 305 componentProps: {
248 placeholder: '请输入监控点编号', 306 placeholder: '请输入监控点编号',
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 @open-gateway-device="handleOpenGatewayDevice" 16 @open-gateway-device="handleOpenGatewayDevice"
17 /> 17 />
18 </TabPane> 18 </TabPane>
19 - <TabPane key="modelOfMatter" tab="物模型数据"> 19 + <TabPane v-if="!isTransportType" key="modelOfMatter" tab="物模型数据">
20 <ModelOfMatter :deviceDetail="deviceDetail" /> 20 <ModelOfMatter :deviceDetail="deviceDetail" />
21 </TabPane> 21 </TabPane>
22 <!-- <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'"> 22 <!-- <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'">
@@ -28,32 +28,43 @@ @@ -28,32 +28,43 @@
28 <!-- <TabPane key="5" tab="命令下发" v-if="deviceDetail?.deviceType !== 'SENSOR'"> 28 <!-- <TabPane key="5" tab="命令下发" v-if="deviceDetail?.deviceType !== 'SENSOR'">
29 <CommandIssuance :deviceDetail="deviceDetail" /> 29 <CommandIssuance :deviceDetail="deviceDetail" />
30 </TabPane> --> 30 </TabPane> -->
31 - <TabPane key="3" tab="告警"><Alarm :id="deviceDetail.id" /></TabPane>  
32 - <TabPane key="4" tab="子设备" v-if="deviceDetail?.deviceType === 'GATEWAY'"> 31 + <TabPane v-if="!isTransportType" key="3" tab="告警"><Alarm :id="deviceDetail.id" /></TabPane>
  32 + <TabPane
  33 + key="4"
  34 + tab="子设备"
  35 + v-if="deviceDetail?.deviceType === 'GATEWAY' && !isTransportType"
  36 + >
33 <ChildDevice 37 <ChildDevice
34 :fromId="deviceDetail?.tbDeviceId" 38 :fromId="deviceDetail?.tbDeviceId"
35 @openTbDeviceDetail="handleOpenTbDeviceDetail" 39 @openTbDeviceDetail="handleOpenTbDeviceDetail"
36 /> 40 />
37 </TabPane> 41 </TabPane>
38 - <TabPane key="7" tab="命令下发记录"> 42 + <TabPane v-if="!isTransportType" key="7" tab="命令下发记录">
39 <CommandRecord :deviceDetail="deviceDetail" :fromId="deviceDetail?.tbDeviceId" /> 43 <CommandRecord :deviceDetail="deviceDetail" :fromId="deviceDetail?.tbDeviceId" />
40 </TabPane> 44 </TabPane>
41 <!-- 网关设备并且场家是TBox --> 45 <!-- 网关设备并且场家是TBox -->
42 <TabPane 46 <TabPane
43 key="6" 47 key="6"
44 tab="TBox" 48 tab="TBox"
45 - v-if="deviceDetail?.deviceType === 'GATEWAY' && deviceDetail?.brand == 'TBox'" 49 + v-if="
  50 + deviceDetail?.deviceType === 'GATEWAY' &&
  51 + deviceDetail?.brand == 'TBox' &&
  52 + !isTransportType
  53 + "
46 > 54 >
47 <TBoxDetail :deviceDetail="deviceDetail" /> 55 <TBoxDetail :deviceDetail="deviceDetail" />
48 </TabPane> 56 </TabPane>
49 <!-- 网关设备并且是TBox --> 57 <!-- 网关设备并且是TBox -->
50 58
51 - <TabPane key="eventManage" tab="事件管理"> 59 + <TabPane v-if="!isTransportType" key="eventManage" tab="事件管理">
52 <EventManage :tbDeviceId="deviceDetail.tbDeviceId" /> 60 <EventManage :tbDeviceId="deviceDetail.tbDeviceId" />
53 </TabPane> 61 </TabPane>
54 - <TabPane key="task" tab="任务"> 62 + <TabPane v-if="!isTransportType" key="task" tab="任务">
55 <Task :tbDeviceId="deviceDetail.tbDeviceId" /> 63 <Task :tbDeviceId="deviceDetail.tbDeviceId" />
56 </TabPane> 64 </TabPane>
  65 + <TabPane key="videoChannel" tab="视频通道">
  66 + <VideoChannel :deviceDetail="deviceDetail" :fromId="deviceDetail?.tbDeviceId" />
  67 + </TabPane>
57 </Tabs> 68 </Tabs>
58 </BasicDrawer> 69 </BasicDrawer>
59 </template> 70 </template>
@@ -74,6 +85,7 @@ @@ -74,6 +85,7 @@
74 import EventManage from '../tabs/EventManage/index.vue'; 85 import EventManage from '../tabs/EventManage/index.vue';
75 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 86 import { DeviceRecord } from '/@/api/device/model/deviceModel';
76 import Task from '../tabs/Task.vue'; 87 import Task from '../tabs/Task.vue';
  88 + import { VideoChannel } from '../tabs/VideoChannel/index';
77 89
78 export default defineComponent({ 90 export default defineComponent({
79 name: 'DeviceModal', 91 name: 'DeviceModal',
@@ -91,6 +103,7 @@ @@ -91,6 +103,7 @@
91 CommandRecord, 103 CommandRecord,
92 EventManage, 104 EventManage,
93 Task, 105 Task,
  106 + VideoChannel,
94 }, 107 },
95 emits: ['reload', 'register', 'openTbDeviceDetail', 'openGatewayDeviceDetail'], 108 emits: ['reload', 'register', 'openTbDeviceDetail', 'openGatewayDeviceDetail'],
96 setup(_props, { emit }) { 109 setup(_props, { emit }) {
@@ -99,9 +112,12 @@ @@ -99,9 +112,12 @@
99 const deviceDetailRef = ref(); 112 const deviceDetailRef = ref();
100 const deviceDetail = ref<DeviceRecord>({} as unknown as DeviceRecord); 113 const deviceDetail = ref<DeviceRecord>({} as unknown as DeviceRecord);
101 const tbDeviceId = ref(''); 114 const tbDeviceId = ref('');
  115 +
  116 + const isTransportType = ref<Boolean>(false); //获取产品是不是GB/T 28181
102 // 详情回显 117 // 详情回显
103 const [register] = useDrawerInner(async (data) => { 118 const [register] = useDrawerInner(async (data) => {
104 - const { id } = data; 119 + const { id, transportType } = data;
  120 + isTransportType.value = transportType == 'GB/T28181' ? true : false;
105 // 设备详情 121 // 设备详情
106 const res = await getDeviceDetail(id); 122 const res = await getDeviceDetail(id);
107 deviceDetail.value = res; 123 deviceDetail.value = res;
@@ -132,6 +148,7 @@ @@ -132,6 +148,7 @@
132 tbDeviceId, 148 tbDeviceId,
133 handleOpenTbDeviceDetail, 149 handleOpenTbDeviceDetail,
134 handleOpenGatewayDevice, 150 handleOpenGatewayDevice,
  151 + isTransportType,
135 }; 152 };
136 }, 153 },
137 }); 154 });
  1 +import { h } from 'vue';
  2 +import { BasicColumn, FormSchema } from '/@/components/Table';
  3 +import { Tag } from 'ant-design-vue';
  4 +
  5 +export const configColumns: BasicColumn[] = [
  6 + {
  7 + title: '通道编号',
  8 + dataIndex: 'channellNumber',
  9 + },
  10 + {
  11 + title: '设备名称',
  12 + dataIndex: 'deviceName',
  13 + },
  14 + {
  15 + title: '通道名称',
  16 + dataIndex: 'channelName',
  17 + },
  18 + {
  19 + title: '厂家',
  20 + dataIndex: 'manufacturer',
  21 + },
  22 + {
  23 + title: '开启音频',
  24 + dataIndex: 'turnOnAudio',
  25 + slots: { customRender: 'turnOnAudio' },
  26 + },
  27 + {
  28 + title: '状态',
  29 + dataIndex: 'state',
  30 + format: (text) => {
  31 + return h(
  32 + Tag,
  33 + {
  34 + color: Number(text) === 1 ? 'green' : 'blue',
  35 + },
  36 + () => (Number(text) === 1 ? '在线' : '离线')
  37 + );
  38 + },
  39 + },
  40 + {
  41 + title: '操作',
  42 + dataIndex: 'action',
  43 + },
  44 +];
  45 +
  46 +export const searchFormSchema: FormSchema[] | any = [{}];
  1 +import VideoChannel from './index.vue';
  2 +export { VideoChannel };
  1 +<template>
  2 + <BasicTable
  3 + class="bg-neutral-100 dark:text-gray-300 dark:bg-dark-700 p-4"
  4 + @register="registerTable"
  5 + >
  6 + <template #turnOnAudio="{ record }">
  7 + <Switch
  8 + :checked="record.status === 1"
  9 + :loading="record.pendingStatus"
  10 + checkedChildren="开启"
  11 + unCheckedChildren="关闭"
  12 + @change="(checked:boolean)=>handleTurnVideo(checked,record)"
  13 + />
  14 + </template>
  15 + <template #action="{ record }">
  16 + <TableAction
  17 + :actions="[
  18 + {
  19 + label: '播放',
  20 + auth: 'api:yt:sceneLinkage:get',
  21 + icon: 'ant-design:playCircle-outlined',
  22 + onClick: handlePlay.bind(null, record),
  23 + },
  24 + ]"
  25 + /></template>
  26 + </BasicTable>
  27 +</template>
  28 +
  29 +<script lang="ts" setup>
  30 + import { configColumns, searchFormSchema } from './config';
  31 + import { BasicTable, useTable, TableAction } from '/@/components/Table';
  32 + import { Switch } from 'ant-design-vue';
  33 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  34 + import { watch } from 'vue';
  35 +
  36 + const props = defineProps({
  37 + fromId: {
  38 + type: String,
  39 + default: '',
  40 + },
  41 + deviceDetail: {
  42 + type: Object as PropType<DeviceRecord>,
  43 + required: true,
  44 + },
  45 + });
  46 +
  47 + watch(
  48 + () => props,
  49 + () => {
  50 + console.log(props, 'props');
  51 + }
  52 + );
  53 +
  54 + const [registerTable] = useTable({
  55 + // api: deviceCommandRecordGetQuery,
  56 + columns: configColumns,
  57 + showTableSetting: true,
  58 + bordered: true,
  59 + showIndexColumn: false,
  60 + formConfig: {
  61 + labelWidth: 120,
  62 + schemas: searchFormSchema,
  63 + },
  64 + beforeFetch: (params) => {
  65 + console.log(params);
  66 + },
  67 + useSearchForm: true,
  68 + });
  69 +
  70 + const handleTurnVideo = (checked: Boolean, record: Recordable) => {
  71 + console.log(checked, record, 'record');
  72 + };
  73 +
  74 + const handlePlay = (record: Recordable) => {
  75 + console.log(record);
  76 + };
  77 +</script>
@@ -336,10 +336,12 @@ @@ -336,10 +336,12 @@
336 } 336 }
337 337
338 function handleDetail(record: Recordable) { 338 function handleDetail(record: Recordable) {
339 - const { id, tbDeviceId } = record; 339 + const { id, tbDeviceId, deviceProfile } = record;
  340 + const { transportType } = deviceProfile || {};
340 openDrawer(true, { 341 openDrawer(true, {
341 id, 342 id,
342 tbDeviceId, 343 tbDeviceId,
  344 + transportType,
343 }); 345 });
344 } 346 }
345 347
@@ -127,11 +127,12 @@ @@ -127,11 +127,12 @@
127 } 127 }
128 }; 128 };
129 const handleStepNext = (e, data) => { 129 const handleStepNext = (e, data) => {
  130 + const { deviceType } = unref(DevConStRef)?.getFieldsValue() || {};
130 if (e) { 131 if (e) {
131 current.value++; 132 current.value++;
132 unref(isUpdate) 133 unref(isUpdate)
133 - ? unref(TransConStRef)?.editOrAddTransportTypeStatus(true)  
134 - : unref(TransConStRef)?.editOrAddTransportTypeStatus(false); 134 + ? unref(TransConStRef)?.editOrAddTransportTypeStatus(true, deviceType)
  135 + : unref(TransConStRef)?.editOrAddTransportTypeStatus(false, deviceType);
135 } else { 136 } else {
136 setTransConfEditFormData(data); 137 setTransConfEditFormData(data);
137 } 138 }
@@ -45,19 +45,20 @@ @@ -45,19 +45,20 @@
45 ifShowBtn: { type: Boolean, default: true }, 45 ifShowBtn: { type: Boolean, default: true },
46 }); 46 });
47 47
48 - const [register, { validate, setFieldsValue, resetFields, updateSchema }] = useForm({  
49 - labelWidth: 100,  
50 - schemas: step1Schemas,  
51 - actionColOptions: {  
52 - span: 14,  
53 - },  
54 - showResetButton: false,  
55 - showActionButtonGroup: props.ifShowBtn ? true : false,  
56 - submitButtonOptions: {  
57 - text: '下一步',  
58 - },  
59 - submitFunc: customSubmitFunc,  
60 - }); 48 + const [register, { validate, setFieldsValue, resetFields, updateSchema, getFieldsValue }] =
  49 + useForm({
  50 + labelWidth: 100,
  51 + schemas: step1Schemas,
  52 + actionColOptions: {
  53 + span: 14,
  54 + },
  55 + showResetButton: false,
  56 + showActionButtonGroup: props.ifShowBtn ? true : false,
  57 + submitButtonOptions: {
  58 + text: '下一步',
  59 + },
  60 + submitFunc: customSubmitFunc,
  61 + });
61 const editOrAddNameStatus = (nameStatus) => 62 const editOrAddNameStatus = (nameStatus) =>
62 updateSchema({ 63 updateSchema({
63 field: 'name', 64 field: 'name',
@@ -129,6 +130,7 @@ @@ -129,6 +130,7 @@
129 resetFormData, 130 resetFormData,
130 getFormData, 131 getFormData,
131 editOrAddDeviceTypeStatus, 132 editOrAddDeviceTypeStatus,
  133 + getFieldsValue,
132 }); 134 });
133 </script> 135 </script>
134 <style lang="less" scoped> 136 <style lang="less" scoped>
1 <template> 1 <template>
2 <div 2 <div
3 class="step2-style" 3 class="step2-style"
4 - :style="[isMqttType == 'DEFAULT' ? { minHeight: 0 + 'px' } : { minHeight: 800 + 'px' }]" 4 + :style="[
  5 + isMqttType == 'DEFAULT' || isMqttType == 'GB/T28181'
  6 + ? { minHeight: 0 + 'px' }
  7 + : { minHeight: 800 + 'px' },
  8 + ]"
5 > 9 >
6 <div 10 <div
7 :style="[ 11 :style="[
@@ -138,6 +142,7 @@ @@ -138,6 +142,7 @@
138 const getSnmpVal = await snmpRef.value?.getFormData(); 142 const getSnmpVal = await snmpRef.value?.getFormData();
139 const getTcpVal = await tcpRef.value?.getFormData(); 143 const getTcpVal = await tcpRef.value?.getFormData();
140 step2Data.transportConfiguration = { 144 step2Data.transportConfiguration = {
  145 + type: isMqttType.value,
141 ...getMqttVal, 146 ...getMqttVal,
142 ...getCoapVal, 147 ...getCoapVal,
143 ...getLwm2mVal, 148 ...getLwm2mVal,
@@ -148,19 +153,26 @@ @@ -148,19 +153,26 @@
148 return step2Data; 153 return step2Data;
149 }; 154 };
150 155
151 - const editOrAddTransportTypeStatus = (status: boolean) => { 156 + const editOrAddTransportTypeStatus = (status: boolean, deviceType?: string) => {
  157 + const options = [
  158 + { label: '默认', value: 'DEFAULT' },
  159 + { label: 'MQTT', value: 'MQTT' },
  160 + { label: 'CoAP', value: 'COAP' },
  161 + // { label: 'LWM2M', value: 'LWM2M' },
  162 + // { label: 'SNMP', value: 'SNMP' },
  163 + { label: 'TCP/UDP', value: 'TCP' },
  164 + ];
  165 + if (deviceType == 'DIRECT_CONNECTION') {
  166 + options.push({ label: 'GB/T 28181', value: 'GB/T28181' });
  167 + }
  168 + if (deviceType != 'DIRECT_CONNECTION' && isMqttType.value == 'GB/T28181') {
  169 + setFieldsValue({ transportType: null });
  170 + }
152 updateSchema({ 171 updateSchema({
153 field: 'transportType', 172 field: 'transportType',
154 componentProps: { 173 componentProps: {
155 disabled: status, 174 disabled: status,
156 - options: [  
157 - { label: '默认', value: 'DEFAULT' },  
158 - { label: 'MQTT', value: 'MQTT' },  
159 - { label: 'CoAP', value: 'COAP' },  
160 - // { label: 'LWM2M', value: 'LWM2M' },  
161 - // { label: 'SNMP', value: 'SNMP' },  
162 - { label: 'TCP/UDP', value: 'TCP' },  
163 - ], 175 + options,
164 onChange(e) { 176 onChange(e) {
165 isMqttType.value = e; 177 isMqttType.value = e;
166 }, 178 },
@@ -78,6 +78,6 @@ export const getSendValues = async (option, getDesign, checked) => { @@ -78,6 +78,6 @@ export const getSendValues = async (option, getDesign, checked) => {
78 78
79 export const CommandTypeEnumLIst = { 79 export const CommandTypeEnumLIst = {
80 '0': { CUSTOM: 0, name: '自定义' }, 80 '0': { CUSTOM: 0, name: '自定义' },
81 - '1': { CUSTOM: 0, name: '服务' },  
82 - '2': { CUSTOM: 0, name: '属性' }, 81 + '1': { CUSTOM: 1, name: '服务' },
  82 + '2': { CUSTOM: 2, name: '属性' },
83 }; 83 };