Commit eb168301ca143225e5c8f906be2314a2d0e985f4

Authored by fengtao
2 parents c83d9492 b9fd638c

Merge branch 'main' into local_dev_ft

@@ -5,7 +5,14 @@ @@ -5,7 +5,14 @@
5 "public/resource/tinymce/langs" 5 "public/resource/tinymce/langs"
6 ], 6 ],
7 "cSpell.words": [ 7 "cSpell.words": [
  8 + "COAP",
  9 + "edrx",
  10 + "EFENTO",
8 "inited", 11 "inited",
  12 + "MQTT",
  13 + "notif",
  14 + "PROTOBUF",
  15 + "SNMP",
9 "unref", 16 "unref",
10 "VITE" 17 "VITE"
11 ] 18 ]
@@ -3,6 +3,7 @@ import { @@ -3,6 +3,7 @@ import {
3 TDeviceConfigParams, 3 TDeviceConfigParams,
4 IDeviceConfigAddOrEditModel, 4 IDeviceConfigAddOrEditModel,
5 ProfileRecord, 5 ProfileRecord,
  6 + RuleChainRecord,
6 } from '/@/api/device/model/deviceConfigModel'; 7 } from '/@/api/device/model/deviceConfigModel';
7 import { PaginationResult } from '/#/axios'; 8 import { PaginationResult } from '/#/axios';
8 9
@@ -36,7 +37,7 @@ export const deviceConfigGetDetail = (id: string) => { @@ -36,7 +37,7 @@ export const deviceConfigGetDetail = (id: string) => {
36 * 获取规则链 37 * 获取规则链
37 */ 38 */
38 export const deviceConfigGetRuleChain = () => { 39 export const deviceConfigGetRuleChain = () => {
39 - return defHttp.get({ 40 + return defHttp.get<RuleChainRecord[]>({
40 url: EDeviceConfigApi.DEVICE_CONFIG_GET_RULECHAIN, 41 url: EDeviceConfigApi.DEVICE_CONFIG_GET_RULECHAIN,
41 }); 42 });
42 }; 43 };
@@ -241,3 +241,21 @@ export interface ProfileRecord { @@ -241,3 +241,21 @@ export interface ProfileRecord {
241 241
242 checked?: boolean; 242 checked?: boolean;
243 } 243 }
  244 +
  245 +export interface IDRecord {
  246 + entityType: string;
  247 + id: string;
  248 +}
  249 +
  250 +export interface RuleChainRecord {
  251 + id: IDRecord;
  252 + createdTime: number;
  253 + additionalInfo?: any;
  254 + tenantId: IDRecord;
  255 + name: string;
  256 + type: string;
  257 + firstRuleNodeId: IDRecord;
  258 + root: boolean;
  259 + debugMode: boolean;
  260 + configuration?: any;
  261 +}
@@ -54,8 +54,84 @@ export interface Configuration { @@ -54,8 +54,84 @@ export interface Configuration {
54 type: string; 54 type: string;
55 } 55 }
56 56
  57 +export interface TransportPayloadTypeConfiguration {
  58 + transportPayloadType: string;
  59 + deviceTelemetryProtoSchema: string;
  60 + deviceAttributesProtoSchema: string;
  61 + deviceRpcRequestProtoSchema: string;
  62 + deviceRpcResponseProtoSchema: string;
  63 + enableCompatibilityWithJsonPayloadFormat: boolean;
  64 + useJsonPayloadFormatForDefaultDownlinkTopics: boolean;
  65 +}
  66 +
  67 +export interface ClientSettings {
  68 + edrxCycle: string;
  69 + pagingTransmissionWindow: string;
  70 + powerMode: string;
  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;
  106 +}
  107 +
57 export interface TransportConfiguration { 108 export interface TransportConfiguration {
58 type: string; 109 type: string;
  110 + deviceTelemetryTopic: string;
  111 + deviceAttributesTopic: string;
  112 +
  113 + // MQTT
  114 + transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration;
  115 +
  116 + // COAP
  117 + clientSettings: ClientSettings;
  118 + coapDeviceTypeConfiguration: {
  119 + coapDeviceType: string;
  120 + transportPayloadTypeConfiguration: TransportPayloadTypeConfiguration;
  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;
59 } 135 }
60 136
61 export interface ProvisionConfiguration { 137 export interface ProvisionConfiguration {
@@ -85,6 +161,7 @@ export interface DeviceRecord { @@ -85,6 +161,7 @@ export interface DeviceRecord {
85 image: string; 161 image: string;
86 type: string; 162 type: string;
87 default: boolean; 163 default: boolean;
  164 + defaultRuleChainId: string;
88 } 165 }
89 166
90 export interface DeviceModelOfMatterAttrs { 167 export interface DeviceModelOfMatterAttrs {
  1 +import { ProfileRecord } from '../device/model/deviceConfigModel';
1 import { 2 import {
2 CreateOtaPackageParams, 3 CreateOtaPackageParams,
3 DefaultDeviceProfileInfo, 4 DefaultDeviceProfileInfo,
@@ -129,7 +130,7 @@ export const getDeviceProfileInfos = (params: GetDeviceProfileInfosParams) => { @@ -129,7 +130,7 @@ export const getDeviceProfileInfos = (params: GetDeviceProfileInfosParams) => {
129 }; 130 };
130 131
131 export const getDeviceProfileInfoById = (id: string) => { 132 export const getDeviceProfileInfoById = (id: string) => {
132 - return defHttp.get<DeviceProfileRecord>( 133 + return defHttp.get<ProfileRecord>(
133 { 134 {
134 url: `${Api.GET_DEVICE_PROFILE_INFO_BY_ID}/${id}`, 135 url: `${Api.GET_DEVICE_PROFILE_INFO_BY_ID}/${id}`,
135 }, 136 },
@@ -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 };
  1 +<script lang="ts" setup></script>
  2 +
  3 +<template> <div></div></template>
@@ -619,6 +619,7 @@ export const TokenSchemas: FormSchema[] = [ @@ -619,6 +619,7 @@ export const TokenSchemas: FormSchema[] = [
619 field: 'clientId', 619 field: 'clientId',
620 required: true, 620 required: true,
621 ifShow: false, 621 ifShow: false,
  622 + slot: 'clientId',
622 componentProps: { 623 componentProps: {
623 maxLength: 36, 624 maxLength: 36,
624 placeholder: '请输入客户端ID', 625 placeholder: '请输入客户端ID',
@@ -8,7 +8,14 @@ @@ -8,7 +8,14 @@
8 centered 8 centered
9 :canFullscreen="false" 9 :canFullscreen="false"
10 > 10 >
11 - <BasicForm @register="registerForm" /> 11 + <BasicForm @register="registerForm">
  12 + <template #clientId="{ field, model }">
  13 + <div class="flex items-center">
  14 + <Input v-model:value="model[field]" placeholder="请输入客户端ID" />
  15 + <ReloadOutlined class="ml-3 !text-blue-600" @click="handleCreateUUID" />
  16 + </div>
  17 + </template>
  18 + </BasicForm>
12 </BasicModal> 19 </BasicModal>
13 </template> 20 </template>
14 21
@@ -19,10 +26,15 @@ @@ -19,10 +26,15 @@
19 import { TokenSchemas, credentialTypeEnum } from '../../config/data'; 26 import { TokenSchemas, credentialTypeEnum } from '../../config/data';
20 import { saveDeviceToken } from '/@/api/device/deviceManager'; 27 import { saveDeviceToken } from '/@/api/device/deviceManager';
21 import { useMessage } from '/@/hooks/web/useMessage'; 28 import { useMessage } from '/@/hooks/web/useMessage';
  29 + import { Input } from 'ant-design-vue';
  30 + import { buildUUID } from '/@/utils/uuid';
  31 + import { ReloadOutlined } from '@ant-design/icons-vue';
22 export default defineComponent({ 32 export default defineComponent({
23 components: { 33 components: {
24 BasicModal, 34 BasicModal,
25 BasicForm, 35 BasicForm,
  36 + Input,
  37 + ReloadOutlined,
26 }, 38 },
27 emits: ['register'], 39 emits: ['register'],
28 setup() { 40 setup() {
@@ -36,7 +48,7 @@ @@ -36,7 +48,7 @@
36 showSubmitButton: false, 48 showSubmitButton: false,
37 showResetButton: false, 49 showResetButton: false,
38 wrapperCol: { 50 wrapperCol: {
39 - span: 12, 51 + span: 16,
40 }, 52 },
41 }); 53 });
42 const [registerModal, { closeModal }] = useModalInner(async (data) => { 54 const [registerModal, { closeModal }] = useModalInner(async (data) => {
@@ -208,12 +220,17 @@ @@ -208,12 +220,17 @@
208 }) 220 })
209 .catch(() => {}); 221 .catch(() => {});
210 }; 222 };
  223 +
  224 + const handleCreateUUID = () => {
  225 + setFieldsValue({ clientId: buildUUID() });
  226 + };
211 return { 227 return {
212 registerModal, 228 registerModal,
213 registerForm, 229 registerForm,
214 checkedChange, 230 checkedChange,
215 handleCancel, 231 handleCancel,
216 handleOk, 232 handleOk,
  233 + handleCreateUUID,
217 }; 234 };
218 }, 235 },
219 }); 236 });
@@ -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,14 +3,13 @@ @@ -3,14 +3,13 @@
3 <Tabs v-model:activeKey="activeKey" @change="handlePanelChange"> 3 <Tabs v-model:activeKey="activeKey" @change="handlePanelChange">
4 <Tabs.TabPane key="product" tab="产品"> 4 <Tabs.TabPane key="product" tab="产品">
5 <div class="relative"> 5 <div class="relative">
6 - <DeviceConfigurationStep :ifShowBtn="false" ref="DevConStRef" />  
7 - <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> 6 + <ProductDescription ref="DevConStRef" :record="record" />
8 </div> 7 </div>
9 </Tabs.TabPane> 8 </Tabs.TabPane>
10 <Tabs.TabPane key="transport" tab="传输配置"> 9 <Tabs.TabPane key="transport" tab="传输配置">
11 - <div class="relative">  
12 - <TransportConfigurationStep :ifShowBtn="false" ref="TransConStRef" />  
13 - <div class="absolute w-full h-full top-0 cursor-not-allowed"></div> 10 + <div>
  11 + <TransportDescription :record="record" />
  12 + <!-- <TransportConfigurationStep :ifShowBtn="false" ref="TransConStRef" /> -->
14 </div> 13 </div>
15 </Tabs.TabPane> 14 </Tabs.TabPane>
16 <Tabs.TabPane key="topic" tab="Topic"> 15 <Tabs.TabPane key="topic" tab="Topic">
@@ -25,13 +24,14 @@ @@ -25,13 +24,14 @@
25 <script lang="ts" setup> 24 <script lang="ts" setup>
26 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; 25 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
27 import { Tabs } from 'ant-design-vue'; 26 import { Tabs } from 'ant-design-vue';
28 - import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue';  
29 import TransportConfigurationStep from './step/TransportConfigurationStep.vue'; 27 import TransportConfigurationStep from './step/TransportConfigurationStep.vue';
30 import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue'; 28 import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue';
31 import { nextTick, ref, unref } from 'vue'; 29 import { nextTick, ref, unref } from 'vue';
32 import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi'; 30 import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi';
33 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 31 import { DeviceRecord } from '/@/api/device/model/deviceModel';
34 import TopicPanel from './step/TopicPanel.vue'; 32 import TopicPanel from './step/TopicPanel.vue';
  33 + import ProductDescription from './components/ProductDescription.vue';
  34 + import { TransportDescription } from './components/TransportDescript';
35 35
36 defineEmits(['register']); 36 defineEmits(['register']);
37 37
@@ -41,12 +41,11 @@ @@ -41,12 +41,11 @@
41 41
42 const record = ref<DeviceRecord>({} as unknown as DeviceRecord); 42 const record = ref<DeviceRecord>({} as unknown as DeviceRecord);
43 43
44 - const DevConStRef = ref<InstanceType<typeof DeviceConfigurationStep>>(); 44 + const DevConStRef = ref<InstanceType<typeof ProductDescription>>();
45 const TransConStRef = ref<InstanceType<typeof TransportConfigurationStep>>(); 45 const TransConStRef = ref<InstanceType<typeof TransportConfigurationStep>>();
46 - // const PhysicalModManRef = ref<InstanceType<typeof PhysicalModelManagementStep>>();  
47 46
48 - const setDeviceConfFormData = async (res: Recordable) => {  
49 - unref(DevConStRef)?.setFormData(res); 47 + const setDeviceConfFormData = async () => {
  48 + unref(DevConStRef)?.renderProductInfo();
50 }; 49 };
51 const setTransConfFormData = async (res: Recordable) => { 50 const setTransConfFormData = async (res: Recordable) => {
52 await nextTick(); 51 await nextTick();
@@ -57,7 +56,7 @@ @@ -57,7 +56,7 @@
57 activeKey.value = 'product'; 56 activeKey.value = 'product';
58 record.value = data.record; 57 record.value = data.record;
59 record.value = await deviceConfigGetDetail(data.record.id); 58 record.value = await deviceConfigGetDetail(data.record.id);
60 - setDeviceConfFormData(unref(record)); 59 + setDeviceConfFormData();
61 }); 60 });
62 61
63 const handlePanelChange = (activeKey: ActiveKey) => { 62 const handlePanelChange = (activeKey: ActiveKey) => {
  1 +<script lang="ts" setup>
  2 + import { Spin, Image } from 'ant-design-vue';
  3 + import { ref, unref, h } from 'vue';
  4 + import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi';
  5 + import { RuleChainRecord } from '/@/api/device/model/deviceConfigModel';
  6 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  7 + import { findDictItemByCode } from '/@/api/system/dict';
  8 + import { SysDictItemResult } from '/@/api/system/model/dictModel';
  9 + import { Description, useDescription } from '/@/components/Description';
  10 + import { to } from '/@/utils/to';
  11 + import productDefaultImage from '/@/assets/icons/product-default.svg';
  12 +
  13 + const loading = ref(false);
  14 +
  15 + const props = defineProps<{
  16 + record: DeviceRecord;
  17 + }>();
  18 +
  19 + const data = ref<DeviceRecord>({} as unknown as DeviceRecord);
  20 +
  21 + const [register, { setDescProps }] = useDescription({
  22 + layout: 'vertical',
  23 + column: 2,
  24 + schema: [
  25 + {
  26 + field: 'image',
  27 + label: '图片',
  28 + span: 2,
  29 + render: (val) => {
  30 + return h(Image, { src: val || productDefaultImage, height: 200 });
  31 + },
  32 + },
  33 + {
  34 + field: 'deviceType',
  35 + label: '设备类型',
  36 + },
  37 + {
  38 + field: 'name',
  39 + label: '产品名称',
  40 + },
  41 + {
  42 + field: 'ruleChain',
  43 + label: '规则链',
  44 + },
  45 + {
  46 + field: 'queueName',
  47 + label: '处理队列',
  48 + },
  49 + {
  50 + field: 'description',
  51 + label: '描述',
  52 + render(val) {
  53 + return h('div', { class: 'min-h-6' }, val);
  54 + },
  55 + },
  56 + ],
  57 + });
  58 +
  59 + const findDeviceType = async (deviceType: string) => {
  60 + const [error, data] = await to<SysDictItemResult[]>(
  61 + findDictItemByCode({ dictCode: 'device_type' })
  62 + );
  63 + if (!error) {
  64 + const record = data.find((item) => item.itemValue === deviceType);
  65 + return { deviceType: record?.itemText };
  66 + }
  67 + return {};
  68 + };
  69 +
  70 + const findHandleQueue = async (defaultQueueName: string) => {
  71 + const [error, data] = await to<SysDictItemResult[]>(
  72 + findDictItemByCode({ dictCode: 'queen_execute_sequence' })
  73 + );
  74 + if (!error) {
  75 + const record = data.find((item) => item.itemValue === defaultQueueName);
  76 + return { queueName: record?.itemText };
  77 + }
  78 + return {};
  79 + };
  80 +
  81 + const findRuleChain = async (ruleChain: string) => {
  82 + const [error, data] = await to<RuleChainRecord[]>(deviceConfigGetRuleChain());
  83 + if (!error) {
  84 + const record = data.find((item) => item.id.id === ruleChain);
  85 + return { ruleChain: record?.name };
  86 + }
  87 + return {};
  88 + };
  89 +
  90 + const renderProductInfo = async () => {
  91 + try {
  92 + data.value = {} as unknown as DeviceRecord;
  93 + loading.value = true;
  94 + const { defaultRuleChainId, deviceType, defaultQueueName } = props.record;
  95 + data.value = props.record;
  96 + const values = await Promise.all([
  97 + findDeviceType(deviceType),
  98 + findHandleQueue(defaultQueueName),
  99 + findRuleChain(defaultRuleChainId),
  100 + ]);
  101 + const value = values.reduce((prev, next) => ({ ...prev, ...next }), {});
  102 + data.value = Object.assign(unref(data), value);
  103 + setDescProps({ data: unref(data) });
  104 + } catch (error) {
  105 + throw error;
  106 + } finally {
  107 + loading.value = false;
  108 + }
  109 + };
  110 +
  111 + defineExpose({
  112 + renderProductInfo,
  113 + });
  114 +</script>
  115 +
  116 +<template>
  117 + <Spin :spinning="loading">
  118 + <Description class="product-description" @register="register" />
  119 + </Spin>
  120 +</template>
  121 +
  122 +<style lang="less" scoped>
  123 + .product-description:deep(.ant-image-img) {
  124 + height: 200px !important;
  125 + }
  126 +</style>
  1 +<script lang="ts" setup>
  2 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  3 + import { useDescription, Description } from '/@/components/Description';
  4 + import { Input } from 'ant-design-vue';
  5 + import { h } from 'vue';
  6 + import {
  7 + COAPDeviceTypeEnum,
  8 + PowerModeEnum,
  9 + PowerModeNameEnum,
  10 + TransportPayloadTypeEnum,
  11 + } from './const';
  12 +
  13 + type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration'];
  14 + const props = defineProps<{
  15 + record: TransportConfiguration;
  16 + }>();
  17 +
  18 + const showProtoSchema = (data: TransportConfiguration) => {
  19 + return (
  20 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType ===
  21 + TransportPayloadTypeEnum.PROTOBUF &&
  22 + data.coapDeviceTypeConfiguration.coapDeviceType === COAPDeviceTypeEnum.DEFAULT
  23 + );
  24 + };
  25 +
  26 + const showPowerModeIsPSM = (data: TransportConfiguration) => {
  27 + return data.clientSettings.powerMode === PowerModeNameEnum.PSM;
  28 + };
  29 +
  30 + const showPowerModeIsEDRX = (data: TransportConfiguration) => {
  31 + return data.clientSettings.powerMode === PowerModeEnum.E_DRX;
  32 + };
  33 +
  34 + const [register] = useDescription({
  35 + layout: 'vertical',
  36 + column: 2,
  37 + data: props.record,
  38 + schema: [
  39 + {
  40 + field: 'type',
  41 + label: '接入协议',
  42 + },
  43 + {
  44 + field: 'coapDeviceType',
  45 + label: 'COAP设备类型',
  46 + render: (_, data: TransportConfiguration) =>
  47 + data.coapDeviceTypeConfiguration.coapDeviceType,
  48 + },
  49 + {
  50 + field: 'coapDeviceType',
  51 + label: 'COAP设备消息Payload',
  52 + render: (_, data: TransportConfiguration) =>
  53 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType,
  54 + },
  55 + {
  56 + field: 'powerMode',
  57 + label: '节能模式',
  58 + render: (_, data: TransportConfiguration) =>
  59 + PowerModeNameEnum[data.clientSettings.powerMode],
  60 + },
  61 + {
  62 + field: 'psmActivityTimer',
  63 + label: 'PSM活动计时器',
  64 + show: showPowerModeIsPSM,
  65 + render: (_, data: TransportConfiguration) => data.clientSettings.psmActivityTimer,
  66 + },
  67 + {
  68 + field: 'edrxCycle',
  69 + label: 'eDRX循环',
  70 + show: showPowerModeIsEDRX,
  71 + render: (_, data: TransportConfiguration) => data.clientSettings.edrxCycle,
  72 + },
  73 + {
  74 + field: 'edrxCycleTime',
  75 + label: 'eDRX循环时间单位',
  76 + show: showPowerModeIsEDRX,
  77 + render: () => '秒',
  78 + },
  79 + {
  80 + field: 'pagingTransmissionWindow',
  81 + label: '寻呼传输窗口',
  82 + show: showPowerModeIsEDRX,
  83 + render: (_, data: TransportConfiguration) => data.clientSettings.pagingTransmissionWindow,
  84 + },
  85 + {
  86 + field: 'pagingTransmissionWindowTime',
  87 + label: '寻呼传输窗口时间单位',
  88 + show: showPowerModeIsEDRX,
  89 + render: () => '秒',
  90 + },
  91 + {
  92 + field: 'unit',
  93 + label: '时间单位',
  94 + show: showPowerModeIsPSM,
  95 + render: () => '秒',
  96 + },
  97 + {
  98 + field: 'deviceTelemetryProtoSchema',
  99 + label: '遥测数据 proto schema',
  100 + span: 2,
  101 + show: showProtoSchema,
  102 + render(_, data: TransportConfiguration) {
  103 + return h(Input.TextArea, {
  104 + autoSize: true,
  105 + value:
  106 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration
  107 + .deviceTelemetryProtoSchema,
  108 + });
  109 + },
  110 + },
  111 + {
  112 + field: 'deviceAttributesProtoSchema',
  113 + label: 'Attributes proto schema',
  114 + span: 2,
  115 + show: showProtoSchema,
  116 + render(_, data: TransportConfiguration) {
  117 + return h(Input.TextArea, {
  118 + autoSize: true,
  119 + value:
  120 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration
  121 + .deviceAttributesProtoSchema,
  122 + });
  123 + },
  124 + },
  125 + {
  126 + field: 'deviceRpcRequestProtoSchema',
  127 + label: 'RPC 请求 proto schema',
  128 + span: 2,
  129 + show: showProtoSchema,
  130 + render(_, data: TransportConfiguration) {
  131 + return h(Input.TextArea, {
  132 + autoSize: true,
  133 + value:
  134 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration
  135 + .deviceRpcRequestProtoSchema,
  136 + });
  137 + },
  138 + },
  139 + {
  140 + field: 'deviceRpcResponseProtoSchema',
  141 + label: 'RPC 响应 proto schema',
  142 + span: 2,
  143 + show: showProtoSchema,
  144 + render(_, data: TransportConfiguration) {
  145 + return h(Input.TextArea, {
  146 + autoSize: true,
  147 + value:
  148 + data.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration
  149 + .deviceRpcResponseProtoSchema,
  150 + });
  151 + },
  152 + },
  153 + ],
  154 + });
  155 +</script>
  156 +
  157 +<template>
  158 + <Description @register="register" />
  159 +</template>
  1 +<script lang="ts" setup>
  2 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  3 + import { useDescription, Description } from '/@/components/Description';
  4 +
  5 + const props = defineProps<{
  6 + record: DeviceRecord['profileData']['transportConfiguration'];
  7 + }>();
  8 +
  9 + const [register] = useDescription({
  10 + layout: 'vertical',
  11 + column: 2,
  12 + schema: [
  13 + {
  14 + field: 'type',
  15 + label: '接入协议',
  16 + },
  17 + ],
  18 + data: props.record,
  19 + });
  20 +</script>
  21 +
  22 +<template>
  23 + <Description @register="register" />
  24 +</template>
  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 { DeviceRecord } from '/@/api/device/model/deviceModel';
  3 + import { useDescription, Description } from '/@/components/Description';
  4 + import { Input } from 'ant-design-vue';
  5 + import { h } from 'vue';
  6 + import { TransportPayloadTypeEnum } from './const';
  7 +
  8 + type TransportConfiguration = DeviceRecord['profileData']['transportConfiguration'];
  9 + const props = defineProps<{
  10 + record: TransportConfiguration;
  11 + }>();
  12 +
  13 + const [register] = useDescription({
  14 + layout: 'vertical',
  15 + column: 2,
  16 + data: props.record,
  17 + schema: [
  18 + {
  19 + field: 'type',
  20 + label: '接入协议',
  21 + span: 2,
  22 + },
  23 + {
  24 + field: 'deviceTelemetryTopic',
  25 + label: '遥测数据主题筛选器',
  26 + },
  27 + {
  28 + field: 'deviceAttributesTopic',
  29 + label: '属性主题过滤器',
  30 + },
  31 + {
  32 + field: 'transportPayloadType',
  33 + label: 'MQTT设备Payload',
  34 + render(_, data: TransportConfiguration) {
  35 + return data.transportPayloadTypeConfiguration.transportPayloadType;
  36 + },
  37 + },
  38 + {
  39 + field: 'enableCompatibilityWithJsonPayloadFormat',
  40 + label: '启用与其他有效负载格式的兼容性',
  41 + render(_, data: TransportConfiguration) {
  42 + return data.transportPayloadTypeConfiguration.enableCompatibilityWithJsonPayloadFormat
  43 + ? '启用'
  44 + : '关闭';
  45 + },
  46 + },
  47 + {
  48 + field: 'deviceTelemetryProtoSchema',
  49 + label: '遥测数据 proto schema',
  50 + span: 2,
  51 + show: (data: TransportConfiguration) =>
  52 + data.transportPayloadTypeConfiguration.transportPayloadType ===
  53 + TransportPayloadTypeEnum.PROTOBUF,
  54 + render(_, data: TransportConfiguration) {
  55 + return h(Input.TextArea, {
  56 + autoSize: true,
  57 + value: data.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema,
  58 + });
  59 + },
  60 + },
  61 + {
  62 + field: 'deviceAttributesProtoSchema',
  63 + label: 'Attributes proto schema',
  64 + span: 2,
  65 + show: (data: TransportConfiguration) =>
  66 + data.transportPayloadTypeConfiguration.transportPayloadType ===
  67 + TransportPayloadTypeEnum.PROTOBUF,
  68 + render(_, data: TransportConfiguration) {
  69 + return h(Input.TextArea, {
  70 + autoSize: true,
  71 + value: data.transportPayloadTypeConfiguration.deviceAttributesProtoSchema,
  72 + });
  73 + },
  74 + },
  75 + {
  76 + field: 'deviceRpcRequestProtoSchema',
  77 + label: 'RPC 请求 proto schema',
  78 + span: 2,
  79 + show: (data: TransportConfiguration) =>
  80 + data.transportPayloadTypeConfiguration.transportPayloadType ===
  81 + TransportPayloadTypeEnum.PROTOBUF,
  82 + render(_, data: TransportConfiguration) {
  83 + return h(Input.TextArea, {
  84 + autoSize: true,
  85 + value: data.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema,
  86 + });
  87 + },
  88 + },
  89 + {
  90 + field: 'deviceRpcResponseProtoSchema',
  91 + label: 'RPC 响应 proto schema',
  92 + span: 2,
  93 + show: (data: TransportConfiguration) =>
  94 + data.transportPayloadTypeConfiguration.transportPayloadType ===
  95 + TransportPayloadTypeEnum.PROTOBUF,
  96 + render(_, data: TransportConfiguration) {
  97 + return h(Input.TextArea, {
  98 + autoSize: true,
  99 + value: data.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema,
  100 + });
  101 + },
  102 + },
  103 + ],
  104 + });
  105 +</script>
  106 +
  107 +<template>
  108 + <Description @register="register" />
  109 +</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>
  1 +<script lang="ts" setup>
  2 + import { computed } from 'vue';
  3 + import COAPDescription from './COAPDescription.vue';
  4 + import { TransportTypeEnum } from './const';
  5 + import DefaultConfiguration from './DefaultConfiguration.vue';
  6 + import LWM2MDescription from './LWM2MDescription.vue';
  7 + import MQTTConfiguration from './MQTTConfiguration.vue';
  8 + import SNMPDescription from './SNMPDescription.vue';
  9 + import TCPDescription from './TCPDescription.vue';
  10 + import { DeviceRecord } from '/@/api/device/model/deviceModel';
  11 +
  12 + const props = defineProps<{
  13 + record: DeviceRecord;
  14 + }>();
  15 +
  16 + const getTransportInfo = computed(() => {
  17 + const { record } = props;
  18 + return record.profileData.transportConfiguration;
  19 + });
  20 +</script>
  21 +
  22 +<template>
  23 + <section>
  24 + <DefaultConfiguration
  25 + :record="getTransportInfo"
  26 + v-if="getTransportInfo.type === TransportTypeEnum.DEFAULT"
  27 + />
  28 +
  29 + <MQTTConfiguration
  30 + :record="getTransportInfo"
  31 + v-if="getTransportInfo.type === TransportTypeEnum.MQTT"
  32 + />
  33 +
  34 + <COAPDescription
  35 + :record="getTransportInfo"
  36 + v-if="getTransportInfo.type === TransportTypeEnum.COAP"
  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 + />
  53 + </section>
  54 +</template>
  1 +export enum TransportTypeEnum {
  2 + DEFAULT = 'DEFAULT',
  3 + MQTT = 'MQTT',
  4 + COAP = 'COAP',
  5 + LWM2M = 'LWM2M',
  6 + SNMP = 'SNMP',
  7 + TCP = 'TCP',
  8 +}
  9 +
  10 +export enum TransportPayloadTypeEnum {
  11 + PROTOBUF = 'PROTOBUF',
  12 + JSON = 'JSON',
  13 +}
  14 +
  15 +export enum COAPDeviceTypeEnum {
  16 + DEFAULT = 'DEFAULT',
  17 + EFENTO = 'EFENTO',
  18 +}
  19 +
  20 +export enum COAPDeviceTypeNameEnum {
  21 + DEFAULT = '默认',
  22 + EFENTO = 'Efento NB-IoT',
  23 +}
  24 +
  25 +export enum PowerModeEnum {
  26 + PSM = 'PSM',
  27 + DRX = 'DRX',
  28 + E_DRX = 'E_DRX',
  29 +}
  30 +
  31 +export enum PowerModeNameEnum {
  32 + PSM = 'Power Saving Mode (PSM)',
  33 + DRX = 'Discontinuous Reception (DRX)',
  34 + E_DRX = 'Extended Discontinuous Reception (eDRX)',
  35 +}
  36 +
  37 +export enum TimeUnitEnum {
  38 + MILLISECONDS = 'milliseconds',
  39 + SECOND = 'second',
  40 + MINUTE = 'minute',
  41 + HOUR = 'hour',
  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 +}
  1 +export { default as TransportDescription } from './TransportDescription.vue';
@@ -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>
@@ -86,6 +86,7 @@ @@ -86,6 +86,7 @@
86 isTitle: 'add', 86 isTitle: 'add',
87 }); 87 });
88 } else { 88 } else {
  89 + console.log(selectScript);
89 openModal(true, { 90 openModal(true, {
90 isUpdate: false, 91 isUpdate: false,
91 isTest: true, 92 isTest: true,