Commit eb168301ca143225e5c8f906be2314a2d0e985f4

Authored by fengtao
2 parents c83d9492 b9fd638c

Merge branch 'main' into local_dev_ft

... ... @@ -5,7 +5,14 @@
5 5 "public/resource/tinymce/langs"
6 6 ],
7 7 "cSpell.words": [
  8 + "COAP",
  9 + "edrx",
  10 + "EFENTO",
8 11 "inited",
  12 + "MQTT",
  13 + "notif",
  14 + "PROTOBUF",
  15 + "SNMP",
9 16 "unref",
10 17 "VITE"
11 18 ]
... ...
... ... @@ -3,6 +3,7 @@ import {
3 3 TDeviceConfigParams,
4 4 IDeviceConfigAddOrEditModel,
5 5 ProfileRecord,
  6 + RuleChainRecord,
6 7 } from '/@/api/device/model/deviceConfigModel';
7 8 import { PaginationResult } from '/#/axios';
8 9
... ... @@ -36,7 +37,7 @@ export const deviceConfigGetDetail = (id: string) => {
36 37 * 获取规则链
37 38 */
38 39 export const deviceConfigGetRuleChain = () => {
39   - return defHttp.get({
  40 + return defHttp.get<RuleChainRecord[]>({
40 41 url: EDeviceConfigApi.DEVICE_CONFIG_GET_RULECHAIN,
41 42 });
42 43 };
... ...
... ... @@ -241,3 +241,21 @@ export interface ProfileRecord {
241 241
242 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 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 108 export interface TransportConfiguration {
58 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 137 export interface ProvisionConfiguration {
... ... @@ -85,6 +161,7 @@ export interface DeviceRecord {
85 161 image: string;
86 162 type: string;
87 163 default: boolean;
  164 + defaultRuleChainId: string;
88 165 }
89 166
90 167 export interface DeviceModelOfMatterAttrs {
... ...
  1 +import { ProfileRecord } from '../device/model/deviceConfigModel';
1 2 import {
2 3 CreateOtaPackageParams,
3 4 DefaultDeviceProfileInfo,
... ... @@ -129,7 +130,7 @@ export const getDeviceProfileInfos = (params: GetDeviceProfileInfosParams) => {
129 130 };
130 131
131 132 export const getDeviceProfileInfoById = (id: string) => {
132   - return defHttp.get<DeviceProfileRecord>(
  133 + return defHttp.get<ProfileRecord>(
133 134 {
134 135 url: `${Api.GET_DEVICE_PROFILE_INFO_BY_ID}/${id}`,
135 136 },
... ...
... ... @@ -24,12 +24,11 @@ export interface ScriptRecord {
24 24 id: string;
25 25 creator: string;
26 26 createTime: string;
27   - updater: string;
28   - updateTime: string;
29 27 name: string;
30   - convertJs: string;
31   - enabled: boolean;
32 28 tenantId: string;
33 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 54
55 55 // 获取脚本选项列表
56 56 export const getScriptManageMeList = () => {
57   - return defHttp.get({
  57 + return defHttp.get<ScriptRecord[]>({
58 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 619 field: 'clientId',
620 620 required: true,
621 621 ifShow: false,
  622 + slot: 'clientId',
622 623 componentProps: {
623 624 maxLength: 36,
624 625 placeholder: '请输入客户端ID',
... ...
... ... @@ -8,7 +8,14 @@
8 8 centered
9 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 19 </BasicModal>
13 20 </template>
14 21
... ... @@ -19,10 +26,15 @@
19 26 import { TokenSchemas, credentialTypeEnum } from '../../config/data';
20 27 import { saveDeviceToken } from '/@/api/device/deviceManager';
21 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 32 export default defineComponent({
23 33 components: {
24 34 BasicModal,
25 35 BasicForm,
  36 + Input,
  37 + ReloadOutlined,
26 38 },
27 39 emits: ['register'],
28 40 setup() {
... ... @@ -36,7 +48,7 @@
36 48 showSubmitButton: false,
37 49 showResetButton: false,
38 50 wrapperCol: {
39   - span: 12,
  51 + span: 16,
40 52 },
41 53 });
42 54 const [registerModal, { closeModal }] = useModalInner(async (data) => {
... ... @@ -208,12 +220,17 @@
208 220 })
209 221 .catch(() => {});
210 222 };
  223 +
  224 + const handleCreateUUID = () => {
  225 + setFieldsValue({ clientId: buildUUID() });
  226 + };
211 227 return {
212 228 registerModal,
213 229 registerForm,
214 230 checkedChange,
215 231 handleCancel,
216 232 handleOk,
  233 + handleCreateUUID,
217 234 };
218 235 },
219 236 });
... ...
... ... @@ -27,6 +27,7 @@
27 27 import { useDrawer } from '/@/components/Drawer';
28 28 import productDefault from '/@/assets/icons/product-default.svg';
29 29 import { usePermission } from '/@/hooks/web/usePermission';
  30 + import { useRoute } from 'vue-router';
30 31
31 32 defineProps<{
32 33 mode: EnumTableCardMode;
... ... @@ -43,7 +44,7 @@
43 44 const { createMessage } = useMessage();
44 45 const { createSyncConfirm } = useSyncConfirm();
45 46
46   - const [register, { getFieldsValue }] = useForm({
  47 + const [register, { getFieldsValue, setFieldsValue }] = useForm({
47 48 showAdvancedButton: true,
48 49 labelWidth: 100,
49 50 compact: true,
... ... @@ -83,14 +84,18 @@
83 84 .map((item) => item.id);
84 85 });
85 86
86   - const getDataSource = async () => {
  87 + const getDataSource = async (otherParams: Recordable = {}) => {
87 88 try {
88 89 loading.value = true;
  90 + if (otherParams) {
  91 + setFieldsValue(otherParams);
  92 + }
89 93 const params = getFieldsValue();
90 94 const { items, total } = await deviceConfigGetQuery({
91 95 page: pagination.current,
92 96 pageSize: unref(colNumber) * 2,
93 97 ...params,
  98 + ...otherParams,
94 99 });
95 100 pagination.total = total;
96 101 dataSource.value = items.map((item) => ({ ...item, checked: false }));
... ... @@ -192,9 +197,9 @@
192 197 throw error;
193 198 }
194 199 };
195   -
  200 + const { query: routeParams } = useRoute();
196 201 onMounted(() => {
197   - getDataSource();
  202 + getDataSource(routeParams);
198 203 });
199 204 </script>
200 205
... ... @@ -255,7 +260,7 @@
255 260 <Image
256 261 @click.stop
257 262 :height="144"
258   - :src="item.image"
  263 + :src="item.image || IMAGE_FALLBACK"
259 264 placeholder
260 265 :fallback="IMAGE_FALLBACK"
261 266 />
... ...
... ... @@ -3,14 +3,13 @@
3 3 <Tabs v-model:activeKey="activeKey" @change="handlePanelChange">
4 4 <Tabs.TabPane key="product" tab="产品">
5 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 7 </div>
9 8 </Tabs.TabPane>
10 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 13 </div>
15 14 </Tabs.TabPane>
16 15 <Tabs.TabPane key="topic" tab="Topic">
... ... @@ -25,13 +24,14 @@
25 24 <script lang="ts" setup>
26 25 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
27 26 import { Tabs } from 'ant-design-vue';
28   - import DeviceConfigurationStep from './step/DeviceConfigurationStep.vue';
29 27 import TransportConfigurationStep from './step/TransportConfigurationStep.vue';
30 28 import PhysicalModelManagementStep from './step/PhysicalModelManagementStep.vue';
31 29 import { nextTick, ref, unref } from 'vue';
32 30 import { deviceConfigGetDetail } from '/@/api/device/deviceConfigApi';
33 31 import { DeviceRecord } from '/@/api/device/model/deviceModel';
34 32 import TopicPanel from './step/TopicPanel.vue';
  33 + import ProductDescription from './components/ProductDescription.vue';
  34 + import { TransportDescription } from './components/TransportDescript';
35 35
36 36 defineEmits(['register']);
37 37
... ... @@ -41,12 +41,11 @@
41 41
42 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 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 50 const setTransConfFormData = async (res: Recordable) => {
52 51 await nextTick();
... ... @@ -57,7 +56,7 @@
57 56 activeKey.value = 'product';
58 57 record.value = data.record;
59 58 record.value = await deviceConfigGetDetail(data.record.id);
60   - setDeviceConfFormData(unref(record));
  59 + setDeviceConfFormData();
61 60 });
62 61
63 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 9 </div>
10 10 <div class="form-item2" :style="{ height: dynamicHeight + 'vh' }">
11 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 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 32 </div>
20 33 </div>
21 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 39 <Button size="small" type="default" @click="handleRemove(item, index)">
24 40 <template #icon>
25 41 <MinusCircleOutlined />
... ... @@ -30,105 +46,105 @@
30 46 </div>
31 47 </template>
32 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 111 </script>
96 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 126 height: 20vh;
123 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 150 </style>
... ...
... ... @@ -86,6 +86,7 @@
86 86 isTitle: 'add',
87 87 });
88 88 } else {
  89 + console.log(selectScript);
89 90 openModal(true, {
90 91 isUpdate: false,
91 92 isTest: true,
... ...