Commit 7f314a805fc268242594461e8a1db783c9ecb8bc
1 parent
21e79e8c
feat: product profile view details transport protocol panel modify to description
Showing
13 changed files
with
623 additions
and
110 deletions
@@ -69,18 +69,69 @@ export interface ClientSettings { | @@ -69,18 +69,69 @@ export interface ClientSettings { | ||
69 | pagingTransmissionWindow: string; | 69 | pagingTransmissionWindow: string; |
70 | powerMode: string; | 70 | powerMode: string; |
71 | psmActivityTimer: number; | 71 | psmActivityTimer: number; |
72 | + | ||
73 | + clientOnlyObserveAfterConnect: string; | ||
74 | + fwUpdateResource: string; | ||
75 | + fwUpdateStrategy: number; | ||
76 | + swUpdateResource: string; | ||
77 | + swUpdateStrategy: number; | ||
78 | +} | ||
79 | + | ||
80 | +export interface Bootstrap { | ||
81 | + securityMode: string; | ||
82 | + shortServerId: number; | ||
83 | + bootstrapServerIs: boolean; | ||
84 | + host: string; | ||
85 | + port: number; | ||
86 | + clientHoldOffTime: number; | ||
87 | + serverPublicKey?: any; | ||
88 | + serverCertificate?: any; | ||
89 | + bootstrapServerAccountTimeout: number; | ||
90 | + lifetime: number; | ||
91 | + defaultMinPeriod: number; | ||
92 | + notifIfDisabled: boolean; | ||
93 | + binding: string; | ||
94 | +} | ||
95 | + | ||
96 | +export interface Mapping { | ||
97 | + dataType: string; | ||
98 | + key: string; | ||
99 | + oid: string; | ||
100 | +} | ||
101 | + | ||
102 | +export interface CommunicationConfigs { | ||
103 | + spec: string; | ||
104 | + mappings: Mapping[]; | ||
105 | + queryingFrequencyMs: number; | ||
72 | } | 106 | } |
73 | 107 | ||
74 | export interface TransportConfiguration { | 108 | export interface TransportConfiguration { |
75 | type: string; | 109 | type: string; |
76 | deviceTelemetryTopic: string; | 110 | deviceTelemetryTopic: string; |
77 | deviceAttributesTopic: string; | 111 | deviceAttributesTopic: string; |
112 | + | ||
113 | + // MQTT | ||
78 | transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration; | 114 | transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration; |
115 | + | ||
116 | + // COAP | ||
79 | clientSettings: ClientSettings; | 117 | clientSettings: ClientSettings; |
80 | coapDeviceTypeConfiguration: { | 118 | coapDeviceTypeConfiguration: { |
81 | coapDeviceType: string; | 119 | coapDeviceType: string; |
82 | transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration; | 120 | transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration; |
83 | }; | 121 | }; |
122 | + | ||
123 | + // LWM2M | ||
124 | + bootstrapServerUpdateEnable: boolean; | ||
125 | + bootstrap: Bootstrap[]; | ||
126 | + clientLwM2mSettings: ClientSettings; | ||
127 | + | ||
128 | + // SNMP | ||
129 | + retries: number; | ||
130 | + timeoutMs: number; | ||
131 | + communicationConfigs: CommunicationConfigs[]; | ||
132 | + | ||
133 | + // TCP | ||
134 | + scriptId: string; | ||
84 | } | 135 | } |
85 | 136 | ||
86 | export interface ProvisionConfiguration { | 137 | export interface ProvisionConfiguration { |
@@ -24,12 +24,11 @@ export interface ScriptRecord { | @@ -24,12 +24,11 @@ export interface ScriptRecord { | ||
24 | id: string; | 24 | id: string; |
25 | creator: string; | 25 | creator: string; |
26 | createTime: string; | 26 | createTime: string; |
27 | - updater: string; | ||
28 | - updateTime: string; | ||
29 | name: string; | 27 | name: string; |
30 | - convertJs: string; | ||
31 | - enabled: boolean; | ||
32 | tenantId: string; | 28 | tenantId: string; |
33 | description: string; | 29 | description: string; |
34 | - status: boolean; | 30 | + convertJs: string; |
31 | + status: number; | ||
32 | + dataType: string; | ||
33 | + saveOriginalData: boolean; | ||
35 | } | 34 | } |
@@ -54,7 +54,7 @@ export const getScriptManageDetail = (id: string) => { | @@ -54,7 +54,7 @@ export const getScriptManageDetail = (id: string) => { | ||
54 | 54 | ||
55 | // 获取脚本选项列表 | 55 | // 获取脚本选项列表 |
56 | export const getScriptManageMeList = () => { | 56 | export const getScriptManageMeList = () => { |
57 | - return defHttp.get({ | 57 | + return defHttp.get<ScriptRecord[]>({ |
58 | url: ScriptManagerApi.SCRIPT_MELIST_URL, | 58 | url: ScriptManagerApi.SCRIPT_MELIST_URL, |
59 | }); | 59 | }); |
60 | }; | 60 | }; |
@@ -27,6 +27,7 @@ | @@ -27,6 +27,7 @@ | ||
27 | import { useDrawer } from '/@/components/Drawer'; | 27 | import { useDrawer } from '/@/components/Drawer'; |
28 | import productDefault from '/@/assets/icons/product-default.svg'; | 28 | import productDefault from '/@/assets/icons/product-default.svg'; |
29 | import { usePermission } from '/@/hooks/web/usePermission'; | 29 | import { usePermission } from '/@/hooks/web/usePermission'; |
30 | + import { useRoute } from 'vue-router'; | ||
30 | 31 | ||
31 | defineProps<{ | 32 | defineProps<{ |
32 | mode: EnumTableCardMode; | 33 | mode: EnumTableCardMode; |
@@ -43,7 +44,7 @@ | @@ -43,7 +44,7 @@ | ||
43 | const { createMessage } = useMessage(); | 44 | const { createMessage } = useMessage(); |
44 | const { createSyncConfirm } = useSyncConfirm(); | 45 | const { createSyncConfirm } = useSyncConfirm(); |
45 | 46 | ||
46 | - const [register, { getFieldsValue }] = useForm({ | 47 | + const [register, { getFieldsValue, setFieldsValue }] = useForm({ |
47 | showAdvancedButton: true, | 48 | showAdvancedButton: true, |
48 | labelWidth: 100, | 49 | labelWidth: 100, |
49 | compact: true, | 50 | compact: true, |
@@ -83,14 +84,18 @@ | @@ -83,14 +84,18 @@ | ||
83 | .map((item) => item.id); | 84 | .map((item) => item.id); |
84 | }); | 85 | }); |
85 | 86 | ||
86 | - const getDataSource = async () => { | 87 | + const getDataSource = async (otherParams: Recordable = {}) => { |
87 | try { | 88 | try { |
88 | loading.value = true; | 89 | loading.value = true; |
90 | + if (otherParams) { | ||
91 | + setFieldsValue(otherParams); | ||
92 | + } | ||
89 | const params = getFieldsValue(); | 93 | const params = getFieldsValue(); |
90 | const { items, total } = await deviceConfigGetQuery({ | 94 | const { items, total } = await deviceConfigGetQuery({ |
91 | page: pagination.current, | 95 | page: pagination.current, |
92 | pageSize: unref(colNumber) * 2, | 96 | pageSize: unref(colNumber) * 2, |
93 | ...params, | 97 | ...params, |
98 | + ...otherParams, | ||
94 | }); | 99 | }); |
95 | pagination.total = total; | 100 | pagination.total = total; |
96 | dataSource.value = items.map((item) => ({ ...item, checked: false })); | 101 | dataSource.value = items.map((item) => ({ ...item, checked: false })); |
@@ -192,9 +197,9 @@ | @@ -192,9 +197,9 @@ | ||
192 | throw error; | 197 | throw error; |
193 | } | 198 | } |
194 | }; | 199 | }; |
195 | - | 200 | + const { query: routeParams } = useRoute(); |
196 | onMounted(() => { | 201 | onMounted(() => { |
197 | - getDataSource(); | 202 | + getDataSource(routeParams); |
198 | }); | 203 | }); |
199 | </script> | 204 | </script> |
200 | 205 | ||
@@ -255,7 +260,7 @@ | @@ -255,7 +260,7 @@ | ||
255 | <Image | 260 | <Image |
256 | @click.stop | 261 | @click.stop |
257 | :height="144" | 262 | :height="144" |
258 | - :src="item.image" | 263 | + :src="item.image || IMAGE_FALLBACK" |
259 | placeholder | 264 | placeholder |
260 | :fallback="IMAGE_FALLBACK" | 265 | :fallback="IMAGE_FALLBACK" |
261 | /> | 266 | /> |
@@ -3,7 +3,12 @@ | @@ -3,7 +3,12 @@ | ||
3 | import { useDescription, Description } from '/@/components/Description'; | 3 | import { useDescription, Description } from '/@/components/Description'; |
4 | import { Input } from 'ant-design-vue'; | 4 | import { Input } from 'ant-design-vue'; |
5 | import { h } from 'vue'; | 5 | import { h } from 'vue'; |
6 | - import { COAPDeviceTypeEnum, PowerModeNameEnum, TransportPayloadTypeEnum } from './const'; | 6 | + import { |
7 | + COAPDeviceTypeEnum, | ||
8 | + PowerModeEnum, | ||
9 | + PowerModeNameEnum, | ||
10 | + TransportPayloadTypeEnum, | ||
11 | + } from './const'; | ||
7 | 12 | ||
8 | type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration']; | 13 | type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration']; |
9 | const props = defineProps<{ | 14 | const props = defineProps<{ |
@@ -23,7 +28,7 @@ | @@ -23,7 +28,7 @@ | ||
23 | }; | 28 | }; |
24 | 29 | ||
25 | const showPowerModeIsEDRX = (data: TransportConfiguration) => { | 30 | const showPowerModeIsEDRX = (data: TransportConfiguration) => { |
26 | - return data.clientSettings.powerMode === PowerModeNameEnum.E_DRX; | 31 | + return data.clientSettings.powerMode === PowerModeEnum.E_DRX; |
27 | }; | 32 | }; |
28 | 33 | ||
29 | const [register] = useDescription({ | 34 | const [register] = useDescription({ |
1 | +<script lang="ts" setup> | ||
2 | + import { Input, Tabs } from 'ant-design-vue'; | ||
3 | + import { computed, h, unref } from 'vue'; | ||
4 | + import { | ||
5 | + BindingNameEnum, | ||
6 | + FirmwareUpdateStrategyNameEnum, | ||
7 | + PowerModeNameEnum, | ||
8 | + SecurityModeNameEnum, | ||
9 | + } from './const'; | ||
10 | + import { Bootstrap, ClientSettings, DeviceRecord } from '/@/api/device/model/deviceModel'; | ||
11 | + import { CollapseContainer } from '/@/components/Container'; | ||
12 | + import { useDescription, Description, DescItem } from '/@/components/Description'; | ||
13 | + | ||
14 | + type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration']; | ||
15 | + const props = defineProps<{ | ||
16 | + record: TransportConfiguration; | ||
17 | + }>(); | ||
18 | + | ||
19 | + enum TabKeyEnum { | ||
20 | + LWM2M_MODEL = 'LWM2M Model', | ||
21 | + BOOTSTRAP = 'Bootstrap', | ||
22 | + OTHER_SETTINGS = 'Other settings', | ||
23 | + JSON_CONFIG_PROFILE_DEVICE = 'JSON Config Profile Device', | ||
24 | + } | ||
25 | + | ||
26 | + const getBootstrapSetting = computed(() => { | ||
27 | + const { record } = props; | ||
28 | + return record.bootstrap; | ||
29 | + }); | ||
30 | + | ||
31 | + const getOtherSetting = computed(() => { | ||
32 | + const { record } = props; | ||
33 | + return record.clientLwM2mSettings; | ||
34 | + }); | ||
35 | + | ||
36 | + const [registerLWM2MModel] = useDescription({ | ||
37 | + layout: 'vertical', | ||
38 | + column: 2, | ||
39 | + data: {}, | ||
40 | + schema: [ | ||
41 | + { | ||
42 | + field: 'objectList', | ||
43 | + label: '对象列表', | ||
44 | + render: () => h('div', { class: 'min-h-6' }), | ||
45 | + }, | ||
46 | + ], | ||
47 | + }); | ||
48 | + | ||
49 | + const getCollapseTitle = (item: Bootstrap) => { | ||
50 | + return `LwM2M Server Short server ID: ${item.shortServerId} Security config mode: ${item.securityMode}`; | ||
51 | + }; | ||
52 | + | ||
53 | + const bootstrapDescriptionSchema: DescItem[] = [ | ||
54 | + { | ||
55 | + label: '安全配置', | ||
56 | + field: 'securityMode', | ||
57 | + render: (_, data: Bootstrap) => SecurityModeNameEnum[data.securityMode], | ||
58 | + }, | ||
59 | + { | ||
60 | + label: '短服务器ID', | ||
61 | + field: 'shortServerId', | ||
62 | + }, | ||
63 | + { | ||
64 | + label: '主机', | ||
65 | + field: 'host', | ||
66 | + }, | ||
67 | + { | ||
68 | + label: '端口', | ||
69 | + field: 'port', | ||
70 | + }, | ||
71 | + { | ||
72 | + label: '延迟时间', | ||
73 | + field: 'clientHoldOffTime', | ||
74 | + }, | ||
75 | + { | ||
76 | + label: '超时后的账户', | ||
77 | + field: 'bootstrapServerAccountTimeout', | ||
78 | + }, | ||
79 | + { | ||
80 | + label: '注册生存期', | ||
81 | + field: 'lifetime', | ||
82 | + }, | ||
83 | + { | ||
84 | + label: '两次通知之间的最小周期', | ||
85 | + field: 'defaultMinPeriod', | ||
86 | + }, | ||
87 | + { | ||
88 | + label: 'Binding', | ||
89 | + field: 'binding', | ||
90 | + span: 2, | ||
91 | + render: (_, data: Bootstrap) => BindingNameEnum[data.binding], | ||
92 | + }, | ||
93 | + { | ||
94 | + label: '禁用或脱机时的通知存储', | ||
95 | + field: 'notifIfDisabled', | ||
96 | + render: (_, data: Bootstrap) => (data.notifIfDisabled ? '启用' : '禁用'), | ||
97 | + }, | ||
98 | + ]; | ||
99 | + console.log(unref(getOtherSetting)); | ||
100 | + const [registerOtherSettings] = useDescription({ | ||
101 | + layout: 'vertical', | ||
102 | + column: 2, | ||
103 | + data: unref(getOtherSetting), | ||
104 | + schema: [ | ||
105 | + { | ||
106 | + label: '固件更新策略', | ||
107 | + field: 'fwUpdateStrategy', | ||
108 | + span: 2, | ||
109 | + render: (_, data: ClientSettings) => FirmwareUpdateStrategyNameEnum[data.fwUpdateStrategy], | ||
110 | + }, | ||
111 | + { | ||
112 | + label: '固件更新COAP资源', | ||
113 | + field: 'fwUpdateResource', | ||
114 | + span: 2, | ||
115 | + }, | ||
116 | + { | ||
117 | + label: '软件更新策略', | ||
118 | + field: 'swUpdateStrategy', | ||
119 | + span: 2, | ||
120 | + render: (_, data: ClientSettings) => FirmwareUpdateStrategyNameEnum[data.swUpdateStrategy], | ||
121 | + }, | ||
122 | + { | ||
123 | + label: '软件更新COAP资源', | ||
124 | + field: 'swUpdateResource', | ||
125 | + span: 2, | ||
126 | + }, | ||
127 | + { | ||
128 | + label: '节能模式', | ||
129 | + field: 'powerMode', | ||
130 | + render: (_, data: ClientSettings) => PowerModeNameEnum[data.powerMode], | ||
131 | + }, | ||
132 | + { | ||
133 | + label: 'PSM活动计时器', | ||
134 | + field: 'edrxCycle', | ||
135 | + }, | ||
136 | + { | ||
137 | + label: 'PSM活动计时器单位', | ||
138 | + field: 'edrxCycleTimeUnit', | ||
139 | + render: () => '秒', | ||
140 | + }, | ||
141 | + { | ||
142 | + label: '支持复合读/写观察操作', | ||
143 | + field: '', | ||
144 | + render: () => '禁用', | ||
145 | + }, | ||
146 | + ], | ||
147 | + }); | ||
148 | + | ||
149 | + const [registerJSONConfig] = useDescription({ | ||
150 | + layout: 'vertical', | ||
151 | + column: 2, | ||
152 | + data: props.record, | ||
153 | + schema: [ | ||
154 | + { | ||
155 | + field: 'json', | ||
156 | + label: 'LWM2M', | ||
157 | + render: (_, data: TransportConfiguration) => { | ||
158 | + return h(Input.TextArea, { value: JSON.stringify(data, null, 2), autoSize: true }); | ||
159 | + }, | ||
160 | + }, | ||
161 | + ], | ||
162 | + }); | ||
163 | +</script> | ||
164 | + | ||
165 | +<template> | ||
166 | + <Tabs> | ||
167 | + <Tabs.TabPane :tab="TabKeyEnum.LWM2M_MODEL" :key="TabKeyEnum.LWM2M_MODEL"> | ||
168 | + <Description @register="registerLWM2MModel" /> | ||
169 | + </Tabs.TabPane> | ||
170 | + <Tabs.TabPane :tab="TabKeyEnum.BOOTSTRAP" :key="TabKeyEnum.BOOTSTRAP"> | ||
171 | + <CollapseContainer | ||
172 | + v-for="(item, index) in getBootstrapSetting" | ||
173 | + :key="index" | ||
174 | + :title="getCollapseTitle(item)" | ||
175 | + class="mt-4" | ||
176 | + > | ||
177 | + <Description | ||
178 | + layout="vertical" | ||
179 | + :column="2" | ||
180 | + :schema="bootstrapDescriptionSchema" | ||
181 | + :data="item" | ||
182 | + /> | ||
183 | + </CollapseContainer> | ||
184 | + </Tabs.TabPane> | ||
185 | + <Tabs.TabPane :tab="TabKeyEnum.OTHER_SETTINGS" :key="TabKeyEnum.OTHER_SETTINGS"> | ||
186 | + <Description @register="registerOtherSettings" /> | ||
187 | + </Tabs.TabPane> | ||
188 | + <Tabs.TabPane | ||
189 | + :tab="TabKeyEnum.JSON_CONFIG_PROFILE_DEVICE" | ||
190 | + :key="TabKeyEnum.JSON_CONFIG_PROFILE_DEVICE" | ||
191 | + > | ||
192 | + <Description @register="registerJSONConfig" /> | ||
193 | + </Tabs.TabPane> | ||
194 | + </Tabs> | ||
195 | +</template> |
1 | +<script lang="ts" setup> | ||
2 | + import { Table } from 'ant-design-vue'; | ||
3 | + import { computed, h } from 'vue'; | ||
4 | + import { SNMPDataTypeEnum, SNMPRangeNameEnum } from './const'; | ||
5 | + import { DeviceRecord } from '/@/api/device/model/deviceModel'; | ||
6 | + import { CollapseContainer } from '/@/components/Container'; | ||
7 | + import { DescItem, Description, useDescription } from '/@/components/Description'; | ||
8 | + | ||
9 | + type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration']; | ||
10 | + | ||
11 | + const props = defineProps<{ | ||
12 | + record: TransportConfiguration; | ||
13 | + }>(); | ||
14 | + | ||
15 | + const getSNMPList = computed(() => { | ||
16 | + const { record } = props; | ||
17 | + return record.communicationConfigs; | ||
18 | + }); | ||
19 | + | ||
20 | + const [register] = useDescription({ | ||
21 | + layout: 'vertical', | ||
22 | + column: 2, | ||
23 | + data: props.record, | ||
24 | + schema: [ | ||
25 | + { | ||
26 | + label: '接入协议', | ||
27 | + field: 'type', | ||
28 | + span: 2, | ||
29 | + }, | ||
30 | + { | ||
31 | + label: '超时毫秒', | ||
32 | + field: 'timeoutMs', | ||
33 | + }, | ||
34 | + { | ||
35 | + label: '重试次数', | ||
36 | + field: 'retries', | ||
37 | + }, | ||
38 | + ], | ||
39 | + }); | ||
40 | + | ||
41 | + const schema: DescItem[] = [ | ||
42 | + { | ||
43 | + label: '范围', | ||
44 | + field: 'spec', | ||
45 | + render: (val: string) => getTitle(val), | ||
46 | + }, | ||
47 | + { | ||
48 | + label: '查询频率(毫秒)', | ||
49 | + field: 'queryingFrequencyMs', | ||
50 | + }, | ||
51 | + { | ||
52 | + label: 'Mapping', | ||
53 | + field: 'mappings', | ||
54 | + render: (val) => { | ||
55 | + return h(Table, { | ||
56 | + size: 'small', | ||
57 | + bordered: true, | ||
58 | + pagination: false, | ||
59 | + columns: [ | ||
60 | + { | ||
61 | + title: '数据类型', | ||
62 | + dataIndex: 'dataType', | ||
63 | + customRender: ({ text }) => SNMPDataTypeEnum[text], | ||
64 | + }, | ||
65 | + { | ||
66 | + title: 'DataKey', | ||
67 | + dataIndex: 'key', | ||
68 | + }, | ||
69 | + { | ||
70 | + title: 'OID', | ||
71 | + dataIndex: 'oid', | ||
72 | + }, | ||
73 | + ], | ||
74 | + dataSource: val, | ||
75 | + }); | ||
76 | + }, | ||
77 | + }, | ||
78 | + ]; | ||
79 | + | ||
80 | + const getTitle = (range: string) => { | ||
81 | + return SNMPRangeNameEnum[range]; | ||
82 | + }; | ||
83 | +</script> | ||
84 | + | ||
85 | +<template> | ||
86 | + <Description @register="register" /> | ||
87 | + <CollapseContainer | ||
88 | + v-for="(item, index) in getSNMPList" | ||
89 | + :key="index" | ||
90 | + class="mt-4" | ||
91 | + :title="getTitle(item.spec)" | ||
92 | + > | ||
93 | + <Description :data="item" layout="vertical" :column="2" :schema="schema" /> | ||
94 | + </CollapseContainer> | ||
95 | +</template> |
1 | +<script lang="ts" setup> | ||
2 | + import { Button, Tag } from 'ant-design-vue'; | ||
3 | + import { h, onMounted, ref, unref } from 'vue'; | ||
4 | + import { DeviceRecord } from '/@/api/device/model/deviceModel'; | ||
5 | + import { ScriptRecord } from '/@/api/scriptmanage/model/scriptModel'; | ||
6 | + import { getScriptManageMeList } from '/@/api/scriptmanage/scriptManager'; | ||
7 | + import { Description, useDescription } from '/@/components/Description'; | ||
8 | + import { useModal } from '/@/components/Modal'; | ||
9 | + import CoverScriptModal from '/@/views/scriptmanage/converscript/ConverScriptModal.vue'; | ||
10 | + | ||
11 | + const props = defineProps<{ | ||
12 | + record: DeviceRecord['profileData']['transportConfiguration']; | ||
13 | + }>(); | ||
14 | + | ||
15 | + const scriptInfo = ref<ScriptRecord>({} as unknown as ScriptRecord); | ||
16 | + | ||
17 | + const [register, { setDescProps }] = useDescription({ | ||
18 | + layout: 'vertical', | ||
19 | + column: 2, | ||
20 | + data: props.record, | ||
21 | + schema: [ | ||
22 | + { | ||
23 | + field: 'type', | ||
24 | + label: '接入协议', | ||
25 | + span: 2, | ||
26 | + }, | ||
27 | + { | ||
28 | + field: 'scriptName', | ||
29 | + label: '转换脚本', | ||
30 | + render: (value: string) => { | ||
31 | + return h('div', [ | ||
32 | + h(Tag, { color: 'blue' }, () => value), | ||
33 | + h(Button, { type: 'link', onClick: handleTestScript }, () => '测试脚本'), | ||
34 | + ]); | ||
35 | + }, | ||
36 | + }, | ||
37 | + ], | ||
38 | + }); | ||
39 | + | ||
40 | + const [registerModal, { openModal }] = useModal(); | ||
41 | + | ||
42 | + const handleTestScript = () => { | ||
43 | + openModal(true, { | ||
44 | + isUpdate: false, | ||
45 | + isTest: true, | ||
46 | + record: unref(scriptInfo).id, | ||
47 | + isText: 'test', | ||
48 | + isTitle: 'test', | ||
49 | + }); | ||
50 | + }; | ||
51 | + | ||
52 | + onMounted(() => { | ||
53 | + getTransforScriptInfo(); | ||
54 | + }); | ||
55 | + | ||
56 | + const getTransforScriptInfo = async () => { | ||
57 | + try { | ||
58 | + const list = await getScriptManageMeList(); | ||
59 | + const record = list.find((item) => item.id === props.record.scriptId); | ||
60 | + scriptInfo.value = record!; | ||
61 | + setDescProps({ | ||
62 | + data: Object.assign(props.record, record, { scriptName: record?.name || '' }), | ||
63 | + }); | ||
64 | + } catch (error) {} | ||
65 | + }; | ||
66 | +</script> | ||
67 | + | ||
68 | +<template> | ||
69 | + <section> | ||
70 | + <Description @register="register" /> | ||
71 | + <CoverScriptModal @register="registerModal" /> | ||
72 | + </section> | ||
73 | +</template> |
@@ -3,7 +3,10 @@ | @@ -3,7 +3,10 @@ | ||
3 | import COAPDescription from './COAPDescription.vue'; | 3 | import COAPDescription from './COAPDescription.vue'; |
4 | import { TransportTypeEnum } from './const'; | 4 | import { TransportTypeEnum } from './const'; |
5 | import DefaultConfiguration from './DefaultConfiguration.vue'; | 5 | import DefaultConfiguration from './DefaultConfiguration.vue'; |
6 | + import LWM2MDescription from './LWM2MDescription.vue'; | ||
6 | import MQTTConfiguration from './MQTTConfiguration.vue'; | 7 | import MQTTConfiguration from './MQTTConfiguration.vue'; |
8 | + import SNMPDescription from './SNMPDescription.vue'; | ||
9 | + import TCPDescription from './TCPDescription.vue'; | ||
7 | import { DeviceRecord } from '/@/api/device/model/deviceModel'; | 10 | import { DeviceRecord } from '/@/api/device/model/deviceModel'; |
8 | 11 | ||
9 | const props = defineProps<{ | 12 | const props = defineProps<{ |
@@ -32,5 +35,20 @@ | @@ -32,5 +35,20 @@ | ||
32 | :record="getTransportInfo" | 35 | :record="getTransportInfo" |
33 | v-if="getTransportInfo.type === TransportTypeEnum.COAP" | 36 | v-if="getTransportInfo.type === TransportTypeEnum.COAP" |
34 | /> | 37 | /> |
38 | + | ||
39 | + <LWM2MDescription | ||
40 | + :record="getTransportInfo" | ||
41 | + v-if="getTransportInfo.type === TransportTypeEnum.LWM2M" | ||
42 | + /> | ||
43 | + | ||
44 | + <SNMPDescription | ||
45 | + :record="getTransportInfo" | ||
46 | + v-if="getTransportInfo.type === TransportTypeEnum.SNMP" | ||
47 | + /> | ||
48 | + | ||
49 | + <TCPDescription | ||
50 | + :record="getTransportInfo" | ||
51 | + v-if="getTransportInfo.type === TransportTypeEnum.TCP" | ||
52 | + /> | ||
35 | </section> | 53 | </section> |
36 | </template> | 54 | </template> |
@@ -4,6 +4,7 @@ export enum TransportTypeEnum { | @@ -4,6 +4,7 @@ export enum TransportTypeEnum { | ||
4 | COAP = 'COAP', | 4 | COAP = 'COAP', |
5 | LWM2M = 'LWM2M', | 5 | LWM2M = 'LWM2M', |
6 | SNMP = 'SNMP', | 6 | SNMP = 'SNMP', |
7 | + TCP = 'TCP', | ||
7 | } | 8 | } |
8 | 9 | ||
9 | export enum TransportPayloadTypeEnum { | 10 | export enum TransportPayloadTypeEnum { |
@@ -21,6 +22,12 @@ export enum COAPDeviceTypeNameEnum { | @@ -21,6 +22,12 @@ export enum COAPDeviceTypeNameEnum { | ||
21 | EFENTO = 'Efento NB-IoT', | 22 | EFENTO = 'Efento NB-IoT', |
22 | } | 23 | } |
23 | 24 | ||
25 | +export enum PowerModeEnum { | ||
26 | + PSM = 'PSM', | ||
27 | + DRX = 'DRX', | ||
28 | + E_DRX = 'E_DRX', | ||
29 | +} | ||
30 | + | ||
24 | export enum PowerModeNameEnum { | 31 | export enum PowerModeNameEnum { |
25 | PSM = 'Power Saving Mode (PSM)', | 32 | PSM = 'Power Saving Mode (PSM)', |
26 | DRX = 'Discontinuous Reception (DRX)', | 33 | DRX = 'Discontinuous Reception (DRX)', |
@@ -33,3 +40,50 @@ export enum TimeUnitEnum { | @@ -33,3 +40,50 @@ export enum TimeUnitEnum { | ||
33 | MINUTE = 'minute', | 40 | MINUTE = 'minute', |
34 | HOUR = 'hour', | 41 | HOUR = 'hour', |
35 | } | 42 | } |
43 | + | ||
44 | +export enum SecurityModeNameEnum { | ||
45 | + NO_SEC = 'No Security', | ||
46 | + PSK = 'Pre-Shared Key', | ||
47 | + RPK = 'Raw Public Key', | ||
48 | + X509 = 'X.509 Certificate', | ||
49 | +} | ||
50 | + | ||
51 | +export enum BindingNameEnum { | ||
52 | + U = 'U: Client is reachable via the UDP binding at any time.', | ||
53 | + M = 'M: Client is reachable via the MQTT binding at any time.', | ||
54 | + H = 'H: Client is reachable via the HTTP binding at any time.', | ||
55 | + T = 'T: Client is reachable via the TCP binding at any time.', | ||
56 | + S = 'S: Client is reachable via the SMS binding at any time.', | ||
57 | + N = 'N: Client MUST send the response to such a request over the Non-IP binding (is supported since LWM', | ||
58 | + UQ = 'UQ: UDP connection in queue mode (is not supported since LWM2M 1.1)', | ||
59 | + UQS = 'UQS: both UDP and SMS connections active; UDP in queue mode, SMS in standard mode (is not supported since LWM2M 1.1)', | ||
60 | + TQ = 'TQ: TCP connection in queue mode (is not supported since LWM2M 1.1)', | ||
61 | + TQS = 'TQS: both TCP and SMS connections active; TCP in queue mode, SMS in standard mode (is not supported since LWM2M 1.1)\t', | ||
62 | + SQ = 'SQ: SMS connection in queue mode (is not supported since LWM2M 1.1)', | ||
63 | +} | ||
64 | + | ||
65 | +export const FirmwareUpdateStrategyNameEnum = { | ||
66 | + 1: 'Push firmware update as binary file using Object 5 and Resource 0 (Package)', | ||
67 | + 2: 'Auto-generate unique CoAP URL to download the package and push firmware update as Object 5 and', | ||
68 | + 3: 'Push firmware update as binary file using Object 19 and Resource 0 (Data)', | ||
69 | +}; | ||
70 | + | ||
71 | +export const SoftwareUpdateStrategyNameEnum = { | ||
72 | + 1: 'Push binary file using Object 9 and Resource 2 (Package)', | ||
73 | + 2: 'Auto-generate unique CoAP URL to download the package and push software update using Object 9 and', | ||
74 | +}; | ||
75 | + | ||
76 | +export enum SNMPRangeNameEnum { | ||
77 | + TELEMETRY_QUERYING = 'Telemetry', | ||
78 | + CLIENT_ATTRIBUTES_QUERYING = 'Client attributes', | ||
79 | + SHARED_ATTRIBUTES_SETTING = 'Shared attributes', | ||
80 | + TO_DEVICE_RPC_REQUEST = 'RPC request', | ||
81 | +} | ||
82 | + | ||
83 | +export enum SNMPDataTypeEnum { | ||
84 | + STRING = '字符串', | ||
85 | + LONG = '数字', | ||
86 | + BOOLEAN = '布尔值', | ||
87 | + DOUBLE = '双精度小数', | ||
88 | + JSON = 'JSON', | ||
89 | +} |
@@ -9,17 +9,33 @@ | @@ -9,17 +9,33 @@ | ||
9 | </div> | 9 | </div> |
10 | <div class="form-item2" :style="{ height: dynamicHeight + 'vh' }"> | 10 | <div class="form-item2" :style="{ height: dynamicHeight + 'vh' }"> |
11 | <div style="margin-left: 1vw"> | 11 | <div style="margin-left: 1vw"> |
12 | - <h3 v-if="item.spec == 'TELEMETRY_QUERYING' || item.spec == 'CLIENT_ATTRIBUTES_QUERYING'" style="color: gray"> | ||
13 | - 查询频率(毫秒*)</h3> | ||
14 | - <InputNumber v-if="item.spec == 'TELEMETRY_QUERYING' || item.spec == 'CLIENT_ATTRIBUTES_QUERYING'" | ||
15 | - v-model:value="queryingFrequencyMs" :min="0" :max="99999999999999999999" style="margin-top: 0.25vh" /> | 12 | + <h3 |
13 | + v-if="item.spec == 'TELEMETRY_QUERYING' || item.spec == 'CLIENT_ATTRIBUTES_QUERYING'" | ||
14 | + style="color: gray" | ||
15 | + > | ||
16 | + 查询频率(毫秒*)</h3 | ||
17 | + > | ||
18 | + <InputNumber | ||
19 | + v-if="item.spec == 'TELEMETRY_QUERYING' || item.spec == 'CLIENT_ATTRIBUTES_QUERYING'" | ||
20 | + v-model:value="queryingFrequencyMs" | ||
21 | + :min="0" | ||
22 | + :max="99999999999999999999" | ||
23 | + style="margin-top: 0.25vh" | ||
24 | + /> | ||
16 | <div style="margin-top: 0.65vh"></div> | 25 | <div style="margin-top: 0.65vh"></div> |
17 | - <MappingsForm :value="item.mappings" @change="handleMappingsChange" @dynamicAddHeight="dynamicHeight += 4" | ||
18 | - @dynamicReduceHeight="dynamicHeight -= 4" /> | 26 | + <MappingsForm |
27 | + :value="item.mappings" | ||
28 | + @change="handleMappingsChange" | ||
29 | + @dynamicAddHeight="dynamicHeight += 4" | ||
30 | + @dynamicReduceHeight="dynamicHeight -= 4" | ||
31 | + /> | ||
19 | </div> | 32 | </div> |
20 | </div> | 33 | </div> |
21 | <div class="form-item3" :style="{ height: dynamicHeight + 'vh' }"> | 34 | <div class="form-item3" :style="{ height: dynamicHeight + 'vh' }"> |
22 | - <div style="text-align: center; line-height: 20vh" :style="{ lineHeight: dynamicHeight + 'vh' }"> | 35 | + <div |
36 | + style="text-align: center; line-height: 20vh" | ||
37 | + :style="{ lineHeight: dynamicHeight + 'vh' }" | ||
38 | + > | ||
23 | <Button size="small" type="default" @click="handleRemove(item, index)"> | 39 | <Button size="small" type="default" @click="handleRemove(item, index)"> |
24 | <template #icon> | 40 | <template #icon> |
25 | <MinusCircleOutlined /> | 41 | <MinusCircleOutlined /> |
@@ -30,105 +46,105 @@ | @@ -30,105 +46,105 @@ | ||
30 | </div> | 46 | </div> |
31 | </template> | 47 | </template> |
32 | <script setup lang="ts"> | 48 | <script setup lang="ts"> |
33 | -import { ref } from 'vue'; | ||
34 | -import { Button, InputNumber } from 'ant-design-vue'; | ||
35 | -import { MinusCircleOutlined } from '@ant-design/icons-vue'; | ||
36 | -import MappingsForm from './MappingsForm.vue'; | ||
37 | -import { useMessage } from '/@/hooks/web/useMessage'; | 49 | + import { ref } from 'vue'; |
50 | + import { Button, InputNumber } from 'ant-design-vue'; | ||
51 | + import { MinusCircleOutlined } from '@ant-design/icons-vue'; | ||
52 | + import MappingsForm from './MappingsForm.vue'; | ||
53 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
38 | 54 | ||
39 | -const props = defineProps({ | ||
40 | - item: { | ||
41 | - type: Object, | ||
42 | - default: () => { }, | ||
43 | - }, | ||
44 | - index: { | ||
45 | - type: Number, | ||
46 | - }, | ||
47 | -}); | ||
48 | -const emit = defineEmits(['removeItem']); | ||
49 | -const dynamicHeight = ref(25); | ||
50 | -const queryingFrequencyMs = ref(5000); | ||
51 | -const { createMessage } = useMessage(); | ||
52 | -const handleMappingsChange = (e) => { | ||
53 | - // eslint-disable-next-line vue/no-mutating-props | ||
54 | - props.item.mappings = e; | ||
55 | -}; | ||
56 | -const handleRemove = (item, index) => { | ||
57 | - emit('removeItem', item, index); | ||
58 | -}; | ||
59 | -//设置回显的高度 | ||
60 | -const setFieldsValueFunc = () => { | ||
61 | - dynamicHeight.value = props.item.mappings.length * 3 + props.item.mappings.length + 15; | ||
62 | - queryingFrequencyMs.value = props.item.queryingFrequencyMs; | ||
63 | -}; | ||
64 | -//获取表单的值 | ||
65 | -const getSnmpFormFunc = () => { | ||
66 | - if (!props.item.spec || props.item.spec == '' || props.item.spec == undefined) { | ||
67 | - return createMessage.error('请选择范围'); | ||
68 | - } | ||
69 | - if ( | ||
70 | - props.item.spec == 'TELEMETRY_QUERYING' || | ||
71 | - props.item.spec == 'CLIENT_ATTRIBUTES_QUERYING' | ||
72 | - ) { | ||
73 | - if (queryingFrequencyMs.value == null) { | ||
74 | - return createMessage.error('请填写查询频率'); | ||
75 | - } | ||
76 | - } | ||
77 | - let obj: any = {}; | ||
78 | - obj = { | ||
79 | - ...{ spec: props.item.spec }, | ||
80 | - ...{ mappings: props.item.mappings }, | ||
81 | - ...{ | ||
82 | - queryingFrequencyMs: | ||
83 | - props.item.spec == 'TELEMETRY_QUERYING' || props.item.spec == 'CLIENT_ATTRIBUTES_QUERYING' | ||
84 | - ? queryingFrequencyMs.value | ||
85 | - : null, | 55 | + const props = defineProps({ |
56 | + item: { | ||
57 | + type: Object, | ||
58 | + default: () => {}, | ||
86 | }, | 59 | }, |
60 | + index: { | ||
61 | + type: Number, | ||
62 | + }, | ||
63 | + }); | ||
64 | + const emit = defineEmits(['removeItem']); | ||
65 | + const dynamicHeight = ref(25); | ||
66 | + const queryingFrequencyMs = ref(5000); | ||
67 | + const { createMessage } = useMessage(); | ||
68 | + const handleMappingsChange = (e) => { | ||
69 | + // eslint-disable-next-line vue/no-mutating-props | ||
70 | + props.item.mappings = e; | ||
71 | + }; | ||
72 | + const handleRemove = (item, index) => { | ||
73 | + emit('removeItem', item, index); | ||
74 | + }; | ||
75 | + //设置回显的高度 | ||
76 | + const setFieldsValueFunc = () => { | ||
77 | + dynamicHeight.value = props.item.mappings.length * 3 + props.item.mappings.length + 15; | ||
78 | + queryingFrequencyMs.value = props.item.queryingFrequencyMs; | ||
87 | }; | 79 | }; |
88 | - return obj; | ||
89 | -}; | ||
90 | -defineExpose({ | ||
91 | - getSnmpFormFunc, | ||
92 | - setFieldsValueFunc, | ||
93 | - handleMappingsChange, | ||
94 | -}); | 80 | + //获取表单的值 |
81 | + const getSnmpFormFunc = () => { | ||
82 | + if (!props.item.spec || props.item.spec == '' || props.item.spec == undefined) { | ||
83 | + return createMessage.error('请选择范围'); | ||
84 | + } | ||
85 | + if ( | ||
86 | + props.item.spec == 'TELEMETRY_QUERYING' || | ||
87 | + props.item.spec == 'CLIENT_ATTRIBUTES_QUERYING' | ||
88 | + ) { | ||
89 | + if (queryingFrequencyMs.value == null) { | ||
90 | + return createMessage.error('请填写查询频率'); | ||
91 | + } | ||
92 | + } | ||
93 | + let obj: any = {}; | ||
94 | + obj = { | ||
95 | + ...{ spec: props.item.spec }, | ||
96 | + ...{ mappings: props.item.mappings }, | ||
97 | + ...{ | ||
98 | + queryingFrequencyMs: | ||
99 | + props.item.spec == 'TELEMETRY_QUERYING' || props.item.spec == 'CLIENT_ATTRIBUTES_QUERYING' | ||
100 | + ? queryingFrequencyMs.value | ||
101 | + : null, | ||
102 | + }, | ||
103 | + }; | ||
104 | + return obj; | ||
105 | + }; | ||
106 | + defineExpose({ | ||
107 | + getSnmpFormFunc, | ||
108 | + setFieldsValueFunc, | ||
109 | + handleMappingsChange, | ||
110 | + }); | ||
95 | </script> | 111 | </script> |
96 | <style lang="less" scoped> | 112 | <style lang="less" scoped> |
97 | -::-webkit-scrollbar { | ||
98 | - display: none; | ||
99 | - width: 0 !important; | ||
100 | - height: 0 !important; | ||
101 | - -webkit-appearance: none; | ||
102 | - background: transparent; | ||
103 | -} | ||
104 | - | ||
105 | -.snmp-form { | ||
106 | - display: flex; | ||
107 | - align-items: center; | ||
108 | - justify-content: space-between; | ||
109 | - width: 40vw; | ||
110 | - height: 20vh; | ||
111 | - border: 0.1px solid #bfbfbf; | ||
112 | - margin-top: 2vh; | ||
113 | - | ||
114 | - .form-item1 { | ||
115 | - width: 9vw; | ||
116 | - height: 20vh; | ||
117 | - border: 0.1px solid #bfbfbf; | 113 | + ::-webkit-scrollbar { |
114 | + display: none; | ||
115 | + width: 0 !important; | ||
116 | + height: 0 !important; | ||
117 | + -webkit-appearance: none; | ||
118 | + background: transparent; | ||
118 | } | 119 | } |
119 | 120 | ||
120 | - .form-item2 { | ||
121 | - width: 28vw; | 121 | + .snmp-form { |
122 | + display: flex; | ||
123 | + align-items: center; | ||
124 | + justify-content: space-between; | ||
125 | + width: 40vw; | ||
122 | height: 20vh; | 126 | height: 20vh; |
123 | border: 0.1px solid #bfbfbf; | 127 | border: 0.1px solid #bfbfbf; |
124 | - overflow: hidden; | ||
125 | - overflow-y: scroll; | ||
126 | - } | 128 | + margin-top: 2vh; |
127 | 129 | ||
128 | - .form-item3 { | ||
129 | - width: 2vw; | ||
130 | - height: 20vh; | ||
131 | - border: 0.1px solid #bfbfbf; | 130 | + .form-item1 { |
131 | + width: 9vw; | ||
132 | + height: 20vh; | ||
133 | + border: 0.1px solid #bfbfbf; | ||
134 | + } | ||
135 | + | ||
136 | + .form-item2 { | ||
137 | + width: 28vw; | ||
138 | + height: 20vh; | ||
139 | + border: 0.1px solid #bfbfbf; | ||
140 | + overflow: hidden; | ||
141 | + overflow-y: scroll; | ||
142 | + } | ||
143 | + | ||
144 | + .form-item3 { | ||
145 | + width: 2vw; | ||
146 | + height: 20vh; | ||
147 | + border: 0.1px solid #bfbfbf; | ||
148 | + } | ||
132 | } | 149 | } |
133 | -} | ||
134 | </style> | 150 | </style> |