Commit 4bc4891ec33fab5729e0b8925be0e122c389ffb7

Authored by loveumiko
1 parent 5200cae0

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

... ... @@ -4,7 +4,9 @@ import { FormSchema as QFormSchema, useComponentRegister } from '/@/components/F
4 4 import { CameraVideoUrl, CameraMaxLength } from '/@/utils/rules';
5 5 import { h } from 'vue';
6 6 import SnHelpMessage from './SnHelpMessage.vue';
  7 +import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
7 8 import { OrgTreeSelect } from '../../common/OrgTreeSelect';
  9 +import { findDictItemByCode } from '/@/api/system/dict';
8 10
9 11 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
10 12
... ... @@ -42,6 +44,16 @@ export enum MediaType {
42 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 58 export const columns: BasicColumn[] = [
47 59 {
... ... @@ -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 201 field: 'brand',
152 202 label: '视频厂家',
153 203 component: 'Input',
... ... @@ -193,7 +243,9 @@ export const formSchema: QFormSchema[] = [
193 243 label: '流媒体配置',
194 244 component: 'Select',
195 245 ifShow({ values }) {
196   - return values.accessMode === AccessMode.Streaming;
  246 + return (
  247 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  248 + );
197 249 },
198 250 slot: 'videoPlatformIdSlot',
199 251 componentProps: {
... ... @@ -206,7 +258,9 @@ export const formSchema: QFormSchema[] = [
206 258 component: 'RadioGroup',
207 259 defaultValue: StreamType.MASTER,
208 260 ifShow({ values }) {
209   - return values.accessMode === AccessMode.Streaming;
  261 + return (
  262 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  263 + );
210 264 },
211 265 componentProps: {
212 266 placeholder: '请选择码流',
... ... @@ -224,7 +278,9 @@ export const formSchema: QFormSchema[] = [
224 278 component: 'RadioGroup',
225 279 defaultValue: PlayProtocol.HTTP,
226 280 ifShow({ values }) {
227   - return values.accessMode === AccessMode.Streaming;
  281 + return (
  282 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  283 + );
228 284 },
229 285 helpMessage: ['平台使用https的hls协议,需联系海康开放平台专家支持。'],
230 286 componentProps: {
... ... @@ -242,7 +298,9 @@ export const formSchema: QFormSchema[] = [
242 298 component: 'Input',
243 299 rules: [...CameraVideoUrl, { required: true, message: '摄像头编号是必填项' }],
244 300 ifShow({ values }) {
245   - return values.accessMode === AccessMode.Streaming;
  301 + return (
  302 + values.accessMode === AccessMode.Streaming && values.streamingType != streamingType.GBT
  303 + );
246 304 },
247 305 componentProps: {
248 306 placeholder: '请输入监控点编号',
... ...
... ... @@ -16,7 +16,7 @@
16 16 @open-gateway-device="handleOpenGatewayDevice"
17 17 />
18 18 </TabPane>
19   - <TabPane key="modelOfMatter" tab="物模型数据">
  19 + <TabPane v-if="!isTransportType" key="modelOfMatter" tab="物模型数据">
20 20 <ModelOfMatter :deviceDetail="deviceDetail" />
21 21 </TabPane>
22 22 <!-- <TabPane key="2" tab="实时数据" v-if="deviceDetail?.deviceType !== 'GATEWAY'">
... ... @@ -28,32 +28,43 @@
28 28 <!-- <TabPane key="5" tab="命令下发" v-if="deviceDetail?.deviceType !== 'SENSOR'">
29 29 <CommandIssuance :deviceDetail="deviceDetail" />
30 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 37 <ChildDevice
34 38 :fromId="deviceDetail?.tbDeviceId"
35 39 @openTbDeviceDetail="handleOpenTbDeviceDetail"
36 40 />
37 41 </TabPane>
38   - <TabPane key="7" tab="命令下发记录">
  42 + <TabPane v-if="!isTransportType" key="7" tab="命令下发记录">
39 43 <CommandRecord :deviceDetail="deviceDetail" :fromId="deviceDetail?.tbDeviceId" />
40 44 </TabPane>
41 45 <!-- 网关设备并且场家是TBox -->
42 46 <TabPane
43 47 key="6"
44 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 55 <TBoxDetail :deviceDetail="deviceDetail" />
48 56 </TabPane>
49 57 <!-- 网关设备并且是TBox -->
50 58
51   - <TabPane key="eventManage" tab="事件管理">
  59 + <TabPane v-if="!isTransportType" key="eventManage" tab="事件管理">
52 60 <EventManage :tbDeviceId="deviceDetail.tbDeviceId" />
53 61 </TabPane>
54   - <TabPane key="task" tab="任务">
  62 + <TabPane v-if="!isTransportType" key="task" tab="任务">
55 63 <Task :tbDeviceId="deviceDetail.tbDeviceId" />
56 64 </TabPane>
  65 + <TabPane key="videoChannel" tab="视频通道">
  66 + <VideoChannel :deviceDetail="deviceDetail" :fromId="deviceDetail?.tbDeviceId" />
  67 + </TabPane>
57 68 </Tabs>
58 69 </BasicDrawer>
59 70 </template>
... ... @@ -74,6 +85,7 @@
74 85 import EventManage from '../tabs/EventManage/index.vue';
75 86 import { DeviceRecord } from '/@/api/device/model/deviceModel';
76 87 import Task from '../tabs/Task.vue';
  88 + import { VideoChannel } from '../tabs/VideoChannel/index';
77 89
78 90 export default defineComponent({
79 91 name: 'DeviceModal',
... ... @@ -91,6 +103,7 @@
91 103 CommandRecord,
92 104 EventManage,
93 105 Task,
  106 + VideoChannel,
94 107 },
95 108 emits: ['reload', 'register', 'openTbDeviceDetail', 'openGatewayDeviceDetail'],
96 109 setup(_props, { emit }) {
... ... @@ -99,9 +112,12 @@
99 112 const deviceDetailRef = ref();
100 113 const deviceDetail = ref<DeviceRecord>({} as unknown as DeviceRecord);
101 114 const tbDeviceId = ref('');
  115 +
  116 + const isTransportType = ref<Boolean>(false); //获取产品是不是GB/T 28181
102 117 // 详情回显
103 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 122 const res = await getDeviceDetail(id);
107 123 deviceDetail.value = res;
... ... @@ -132,6 +148,7 @@
132 148 tbDeviceId,
133 149 handleOpenTbDeviceDetail,
134 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 336 }
337 337
338 338 function handleDetail(record: Recordable) {
339   - const { id, tbDeviceId } = record;
  339 + const { id, tbDeviceId, deviceProfile } = record;
  340 + const { transportType } = deviceProfile || {};
340 341 openDrawer(true, {
341 342 id,
342 343 tbDeviceId,
  344 + transportType,
343 345 });
344 346 }
345 347
... ...
... ... @@ -127,11 +127,12 @@
127 127 }
128 128 };
129 129 const handleStepNext = (e, data) => {
  130 + const { deviceType } = unref(DevConStRef)?.getFieldsValue() || {};
130 131 if (e) {
131 132 current.value++;
132 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 136 } else {
136 137 setTransConfEditFormData(data);
137 138 }
... ...
... ... @@ -45,19 +45,20 @@
45 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 62 const editOrAddNameStatus = (nameStatus) =>
62 63 updateSchema({
63 64 field: 'name',
... ... @@ -129,6 +130,7 @@
129 130 resetFormData,
130 131 getFormData,
131 132 editOrAddDeviceTypeStatus,
  133 + getFieldsValue,
132 134 });
133 135 </script>
134 136 <style lang="less" scoped>
... ...
1 1 <template>
2 2 <div
3 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 10 <div
7 11 :style="[
... ... @@ -138,6 +142,7 @@
138 142 const getSnmpVal = await snmpRef.value?.getFormData();
139 143 const getTcpVal = await tcpRef.value?.getFormData();
140 144 step2Data.transportConfiguration = {
  145 + type: isMqttType.value,
141 146 ...getMqttVal,
142 147 ...getCoapVal,
143 148 ...getLwm2mVal,
... ... @@ -148,19 +153,26 @@
148 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 171 updateSchema({
153 172 field: 'transportType',
154 173 componentProps: {
155 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 176 onChange(e) {
165 177 isMqttType.value = e;
166 178 },
... ...
... ... @@ -78,6 +78,6 @@ export const getSendValues = async (option, getDesign, checked) => {
78 78
79 79 export const CommandTypeEnumLIst = {
80 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 };
... ...