Commit 660727b48dacc7fb23725e06263a5e58e551f6cb
1 parent
e01b08be
feat:新增告警配置功能,refractor:重构设备配值第二步,feat:新增设备列表跳转设备配置分页查询
Showing
13 changed files
with
1410 additions
and
454 deletions
src/api/alarm/config/alarmConfig.ts
0 → 100644
| 1 | +import { defHttp } from '/@/utils/http/axios'; | ||
| 2 | +import type { | ||
| 3 | + ContactPageParams, | ||
| 4 | + ContactModal, | ||
| 5 | + ContactParams, | ||
| 6 | + ContactInfo, | ||
| 7 | + ConfigPageParams, | ||
| 8 | +} from './model/alarmContactModal'; | ||
| 9 | +import { getPageData } from '../../base'; | ||
| 10 | +import { DeviceModel, DeviceQueryParam } from '../../device/model/deviceModel'; | ||
| 11 | +enum API { | ||
| 12 | + alarmContact = '/alarmContact', | ||
| 13 | + updateAlarmContact = '/alarm/profile', | ||
| 14 | + devicePage = '/device', | ||
| 15 | + deleteAlarmConfig = '/alarm/profile', | ||
| 16 | + getAlarmConfig = '/alarm/profile', | ||
| 17 | + getAlarmConfigStatus = '/alarm/profile', | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +// 获取 | ||
| 21 | +export const getAlarmContact = (params: ContactPageParams) => { | ||
| 22 | + return getPageData<ContactModal>(params, API.alarmContact); | ||
| 23 | +}; | ||
| 24 | + | ||
| 25 | +// 新增 | ||
| 26 | +export const addAlarmContact = (params: ContactParams) => { | ||
| 27 | + return defHttp.post({ | ||
| 28 | + url: API.alarmContact, | ||
| 29 | + data: params, | ||
| 30 | + }); | ||
| 31 | +}; | ||
| 32 | + | ||
| 33 | +// 更新 | ||
| 34 | +export const updateAlarmContact = (params: ContactParams) => { | ||
| 35 | + return defHttp.post({ | ||
| 36 | + url: API.updateAlarmContact, | ||
| 37 | + data: params, | ||
| 38 | + }); | ||
| 39 | +}; | ||
| 40 | + | ||
| 41 | +// 删除 | ||
| 42 | +export const deleteAlarmContact = (ids: string[]) => { | ||
| 43 | + return defHttp.delete({ | ||
| 44 | + url: API.alarmContact, | ||
| 45 | + data: ids, | ||
| 46 | + }); | ||
| 47 | +}; | ||
| 48 | + | ||
| 49 | +// 查询设备分页数据 | ||
| 50 | +export const devicePage = (params: DeviceQueryParam) => { | ||
| 51 | + return defHttp.get<DeviceModel>({ | ||
| 52 | + url: API.devicePage, | ||
| 53 | + params, | ||
| 54 | + }); | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +// 新增或者编辑告警配置 | ||
| 58 | +export const saveOrEditAlarmConfig = (params: ContactInfo) => { | ||
| 59 | + return defHttp.post({ | ||
| 60 | + url: API.updateAlarmContact, | ||
| 61 | + data: params, | ||
| 62 | + }); | ||
| 63 | +}; | ||
| 64 | + | ||
| 65 | +/** | ||
| 66 | + * 删除告警配置 | ||
| 67 | + */ | ||
| 68 | +export const deleteAlarmConfig = (ids: string[]) => { | ||
| 69 | + return defHttp.delete({ | ||
| 70 | + url: API.deleteAlarmConfig, | ||
| 71 | + data: { | ||
| 72 | + ids: ids, | ||
| 73 | + }, | ||
| 74 | + }); | ||
| 75 | +}; | ||
| 76 | + | ||
| 77 | +/** | ||
| 78 | + * 告警配置分页 | ||
| 79 | + */ | ||
| 80 | + | ||
| 81 | +export const queryAlarmConfig = (params: ConfigPageParams) => { | ||
| 82 | + return defHttp.get<ConfigPageParams>({ | ||
| 83 | + url: API.getAlarmConfig, | ||
| 84 | + params, | ||
| 85 | + }); | ||
| 86 | +}; | ||
| 87 | + | ||
| 88 | +/** | ||
| 89 | + * 告警配置状态 | ||
| 90 | + */ | ||
| 91 | +export const putAlarmConfigStatus = (status?: number, alarmProfileId?: string) => | ||
| 92 | + defHttp.get({ | ||
| 93 | + url: API.getAlarmConfigStatus + '/' + alarmProfileId + '/' + status, | ||
| 94 | + }); | 
| 1 | +import { BasicPageParams } from '/@/api/model/baseModel'; | ||
| 2 | + | ||
| 3 | +interface ContactItemsModal { | ||
| 4 | + id: string; | ||
| 5 | + createTime: string; | ||
| 6 | + enabled: boolean; | ||
| 7 | + username: string; | ||
| 8 | + department: string; | ||
| 9 | + phone: string; | ||
| 10 | +} | ||
| 11 | +export type ContactPageParams = BasicPageParams & { username: string; organizationId: string }; | ||
| 12 | +export type ConfigPageParams = BasicPageParams & { | ||
| 13 | + status: number; | ||
| 14 | + organizationId: string; | ||
| 15 | + name: string; | ||
| 16 | + orderFiled: string; | ||
| 17 | + orderType: string; | ||
| 18 | +}; | ||
| 19 | + | ||
| 20 | +export interface ContactModal { | ||
| 21 | + items: ContactItemsModal[]; | ||
| 22 | + total: number; | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +export interface ContactParams { | ||
| 26 | + alarmContactId: string; | ||
| 27 | + messageMode: string; | ||
| 28 | + name: string; | ||
| 29 | + organizationId: string; | ||
| 30 | + remark?: string; | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +export type ContactInfo = ContactParams; | 
src/views/alarm/config/ContactDrawer.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <BasicDrawer | ||
| 3 | + v-bind="$attrs" | ||
| 4 | + @register="registerDrawer" | ||
| 5 | + showFooter | ||
| 6 | + :title="getTitle" | ||
| 7 | + width="30%" | ||
| 8 | + @ok="handleSubmit" | ||
| 9 | + > | ||
| 10 | + <BasicForm @register="registerForm" /> | ||
| 11 | + </BasicDrawer> | ||
| 12 | +</template> | ||
| 13 | +<script lang="ts"> | ||
| 14 | + import { defineComponent, ref, computed, unref, reactive } from 'vue'; | ||
| 15 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 16 | + import { formSchema } from './config.data'; | ||
| 17 | + import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'; | ||
| 18 | + import { saveOrEditAlarmConfig } from '/@/api/alarm/config/alarmConfig'; | ||
| 19 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 20 | + | ||
| 21 | + export default defineComponent({ | ||
| 22 | + name: 'ContactDrawer', | ||
| 23 | + components: { BasicDrawer, BasicForm }, | ||
| 24 | + emits: ['success', 'register'], | ||
| 25 | + setup(_, { emit }) { | ||
| 26 | + const isUpdate = ref(true); | ||
| 27 | + let allData: any = reactive({}); | ||
| 28 | + const editId = ref(''); | ||
| 29 | + | ||
| 30 | + const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({ | ||
| 31 | + labelWidth: 120, | ||
| 32 | + schemas: formSchema, | ||
| 33 | + showActionButtonGroup: false, | ||
| 34 | + }); | ||
| 35 | + | ||
| 36 | + const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => { | ||
| 37 | + await resetFields(); | ||
| 38 | + setDrawerProps({ confirmLoading: false }); | ||
| 39 | + isUpdate.value = !!data?.isUpdate; | ||
| 40 | + if (data.record?.id) { | ||
| 41 | + editId.value = data.record?.id; | ||
| 42 | + } | ||
| 43 | + if (unref(isUpdate)) { | ||
| 44 | + if (data.record.organizationDTO) { | ||
| 45 | + await setFieldsValue(data.record); | ||
| 46 | + } else { | ||
| 47 | + await setFieldsValue(data.record); | ||
| 48 | + await setFieldsValue({ | ||
| 49 | + alarmContactId: data.record?.alarmContactId.split(','), | ||
| 50 | + messageMode: data.record?.messageMode.split(','), | ||
| 51 | + }); | ||
| 52 | + } | ||
| 53 | + } else { | ||
| 54 | + } | ||
| 55 | + }); | ||
| 56 | + | ||
| 57 | + const getTitle = computed(() => (!unref(isUpdate) ? '新增告警配置' : '编辑告警配置')); | ||
| 58 | + | ||
| 59 | + async function handleSubmit() { | ||
| 60 | + try { | ||
| 61 | + const { createMessage } = useMessage(); | ||
| 62 | + const values = await validate(); | ||
| 63 | + if (!values) return; | ||
| 64 | + const alarmContactIdD = { | ||
| 65 | + alarmContactId: values.alarmContactId.join(','), | ||
| 66 | + }; | ||
| 67 | + const messageModeD = { | ||
| 68 | + messageMode: values.messageMode.join(','), | ||
| 69 | + }; | ||
| 70 | + const editIdVal = !unref(isUpdate) ? '' : editId.value; | ||
| 71 | + | ||
| 72 | + allData = { | ||
| 73 | + ...{ id: editIdVal }, | ||
| 74 | + ...values, | ||
| 75 | + ...alarmContactIdD, | ||
| 76 | + ...messageModeD, | ||
| 77 | + }; | ||
| 78 | + if (!unref(isUpdate)) { | ||
| 79 | + delete allData.id; | ||
| 80 | + } | ||
| 81 | + setDrawerProps({ confirmLoading: true }); | ||
| 82 | + let saveMessage = '添加成功'; | ||
| 83 | + let updateMessage = '修改成功'; | ||
| 84 | + await saveOrEditAlarmConfig(allData); | ||
| 85 | + closeDrawer(); | ||
| 86 | + emit('success'); | ||
| 87 | + createMessage.success(unref(isUpdate) ? updateMessage : saveMessage); | ||
| 88 | + } finally { | ||
| 89 | + setDrawerProps({ confirmLoading: false }); | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + return { | ||
| 94 | + getTitle, | ||
| 95 | + registerDrawer, | ||
| 96 | + registerForm, | ||
| 97 | + handleSubmit, | ||
| 98 | + }; | ||
| 99 | + }, | ||
| 100 | + }); | ||
| 101 | +</script> | 
src/views/alarm/config/config.data.ts
0 → 100644
| 1 | +import { BasicColumn, FormSchema } from '/@/components/Table'; | ||
| 2 | +import { getOrganizationList } from '/@/api/system/system'; | ||
| 3 | +import { copyTransFun } from '/@/utils/fnUtils'; | ||
| 4 | +import { findDictItemByCode } from '/@/api/system/dict'; | ||
| 5 | +import { alarmContactGetPage } from '/@/api/device/deviceConfigApi'; | ||
| 6 | +import { Switch } from 'ant-design-vue'; | ||
| 7 | +import { h } from 'vue'; | ||
| 8 | +import { putAlarmConfigStatus } from '/@/api/alarm/config/alarmConfig'; | ||
| 9 | +import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 10 | + | ||
| 11 | +// 表格列数据 | ||
| 12 | +export const columns: BasicColumn[] = [ | ||
| 13 | + { | ||
| 14 | + title: '告警配置名称', | ||
| 15 | + dataIndex: 'name', | ||
| 16 | + width: 120, | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + title: '所属组织', | ||
| 20 | + dataIndex: 'organizationName', | ||
| 21 | + width: 160, | ||
| 22 | + }, | ||
| 23 | + { | ||
| 24 | + title: '告警通知联系人', | ||
| 25 | + dataIndex: 'alarmContactId', | ||
| 26 | + width: 160, | ||
| 27 | + slots: { customRender: 'alarmContact' }, | ||
| 28 | + }, | ||
| 29 | + { | ||
| 30 | + title: '告警联系方式', | ||
| 31 | + dataIndex: 'messageMode', | ||
| 32 | + width: 160, | ||
| 33 | + slots: { customRender: 'messageMode' }, | ||
| 34 | + }, | ||
| 35 | + { | ||
| 36 | + title: '状态', | ||
| 37 | + dataIndex: 'status', | ||
| 38 | + width: 120, | ||
| 39 | + customRender: ({ record }) => { | ||
| 40 | + if (!Reflect.has(record, 'pendingStatus')) { | ||
| 41 | + record.pendingStatus = false; | ||
| 42 | + } | ||
| 43 | + return h(Switch, { | ||
| 44 | + checked: record.status === 1, | ||
| 45 | + checkedChildren: '配置', | ||
| 46 | + unCheckedChildren: '未配置', | ||
| 47 | + loading: record.pendingStatus, | ||
| 48 | + onChange(checked: boolean) { | ||
| 49 | + record.pendingStatus = true; | ||
| 50 | + const newStatus = checked ? 1 : 0; | ||
| 51 | + const { createMessage } = useMessage(); | ||
| 52 | + putAlarmConfigStatus(newStatus, record.id) | ||
| 53 | + .then(() => { | ||
| 54 | + record.status = newStatus; | ||
| 55 | + if (record.status == 1) { | ||
| 56 | + createMessage.success(`配置成功`); | ||
| 57 | + } else { | ||
| 58 | + createMessage.error('未配置成功'); | ||
| 59 | + } | ||
| 60 | + }) | ||
| 61 | + .finally(() => { | ||
| 62 | + record.pendingStatus = false; | ||
| 63 | + }); | ||
| 64 | + }, | ||
| 65 | + }); | ||
| 66 | + }, | ||
| 67 | + }, | ||
| 68 | + { | ||
| 69 | + title: '备注', | ||
| 70 | + dataIndex: 'remark', | ||
| 71 | + width: 120, | ||
| 72 | + }, | ||
| 73 | + { | ||
| 74 | + title: '创建时间', | ||
| 75 | + dataIndex: 'createTime', | ||
| 76 | + width: 180, | ||
| 77 | + }, | ||
| 78 | + { | ||
| 79 | + title: '更新时间', | ||
| 80 | + dataIndex: 'updateTime', | ||
| 81 | + width: 180, | ||
| 82 | + }, | ||
| 83 | +]; | ||
| 84 | + | ||
| 85 | +// 查询字段 | ||
| 86 | +export const searchFormSchema: FormSchema[] = [ | ||
| 87 | + { | ||
| 88 | + field: 'name', | ||
| 89 | + label: '告警配置名称', | ||
| 90 | + component: 'Input', | ||
| 91 | + colProps: { span: 8 }, | ||
| 92 | + componentProps: { | ||
| 93 | + maxLength: 36, | ||
| 94 | + placeholder: '请输入告警配置名称', | ||
| 95 | + }, | ||
| 96 | + }, | ||
| 97 | + { | ||
| 98 | + field: 'status', | ||
| 99 | + label: '告警配置状态', | ||
| 100 | + component: 'Select', | ||
| 101 | + colProps: { span: 8 }, | ||
| 102 | + componentProps: { | ||
| 103 | + options: [ | ||
| 104 | + { | ||
| 105 | + label: '已配置', | ||
| 106 | + value: 1, | ||
| 107 | + }, | ||
| 108 | + { | ||
| 109 | + label: '未配置', | ||
| 110 | + value: 0, | ||
| 111 | + }, | ||
| 112 | + ], | ||
| 113 | + placeholder: '请选择告警配置状态', | ||
| 114 | + }, | ||
| 115 | + }, | ||
| 116 | +]; | ||
| 117 | + | ||
| 118 | +// 弹框配置项 | ||
| 119 | +export const formSchema: FormSchema[] = [ | ||
| 120 | + { | ||
| 121 | + field: 'name', | ||
| 122 | + label: '告警配置名称', | ||
| 123 | + required: true, | ||
| 124 | + component: 'Input', | ||
| 125 | + componentProps: { | ||
| 126 | + placeholder: '请输入告警配置名称', | ||
| 127 | + maxLength: 30, | ||
| 128 | + }, | ||
| 129 | + }, | ||
| 130 | + { | ||
| 131 | + field: 'organizationId', | ||
| 132 | + label: '所属组织', | ||
| 133 | + component: 'ApiTreeSelect', | ||
| 134 | + // required: true, | ||
| 135 | + componentProps: { | ||
| 136 | + api: async () => { | ||
| 137 | + const data = await getOrganizationList(); | ||
| 138 | + copyTransFun(data as any as any[]); | ||
| 139 | + return data; | ||
| 140 | + }, | ||
| 141 | + }, | ||
| 142 | + }, | ||
| 143 | + { | ||
| 144 | + field: 'alarmContactId', | ||
| 145 | + label: '告警通知联系人', | ||
| 146 | + component: 'ApiSelect', | ||
| 147 | + required: true, | ||
| 148 | + componentProps: { | ||
| 149 | + mode: 'multiple', | ||
| 150 | + placeholder: '请选择告警通知联系人', | ||
| 151 | + api: alarmContactGetPage, | ||
| 152 | + labelField: 'username', | ||
| 153 | + valueField: 'id', | ||
| 154 | + resultField: 'items', | ||
| 155 | + }, | ||
| 156 | + }, | ||
| 157 | + { | ||
| 158 | + field: 'messageMode', | ||
| 159 | + label: '告警通知方式', | ||
| 160 | + component: 'ApiSelect', | ||
| 161 | + required: true, | ||
| 162 | + componentProps: { | ||
| 163 | + mode: 'multiple', | ||
| 164 | + placeholder: '请选择告警通知方式', | ||
| 165 | + api: findDictItemByCode, | ||
| 166 | + params: { | ||
| 167 | + dictCode: 'message_type', | ||
| 168 | + }, | ||
| 169 | + labelField: 'itemText', | ||
| 170 | + valueField: 'itemValue', | ||
| 171 | + }, | ||
| 172 | + }, | ||
| 173 | + { | ||
| 174 | + field: 'remark', | ||
| 175 | + label: '备注', | ||
| 176 | + component: 'InputTextArea', | ||
| 177 | + componentProps: { | ||
| 178 | + placeholder: '请输入备注', | ||
| 179 | + maxLength: 255, | ||
| 180 | + }, | ||
| 181 | + }, | ||
| 182 | +]; | 
src/views/alarm/config/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <PageWrapper dense contentFullHeight contentClass="flex"> | ||
| 4 | + <OrganizationIdTree | ||
| 5 | + class="w-1/4 xl:w-1/5" | ||
| 6 | + @select="handleSelect" | ||
| 7 | + ref="organizationIdTreeRef" | ||
| 8 | + /> | ||
| 9 | + <BasicTable @register="registerTable" :searchInfo="searchInfo" class="w-3/4 xl:w-4/5"> | ||
| 10 | + <template #toolbar> | ||
| 11 | + <a-button type="primary" @click="handleCreateOrEdit(null)"> 新增告警配置 </a-button> | ||
| 12 | + <a-button | ||
| 13 | + type="primary" | ||
| 14 | + color="error" | ||
| 15 | + @click="handleDeleteOrBatchDelete(null)" | ||
| 16 | + :disabled="hasBatchDelete" | ||
| 17 | + > | ||
| 18 | + 批量删除 | ||
| 19 | + </a-button> | ||
| 20 | + </template> | ||
| 21 | + <template #alarmContact="{ record }"> | ||
| 22 | + <a-button type="link" class="ml-2" @click="showAlarmContact(record)"> | ||
| 23 | + 查看告警联系人 | ||
| 24 | + </a-button> | ||
| 25 | + </template> | ||
| 26 | + <template #messageMode="{ record }"> | ||
| 27 | + <a-button type="link" class="ml-2" @click="showMessageMode(record)"> | ||
| 28 | + 查看告警联系方式 | ||
| 29 | + </a-button> | ||
| 30 | + </template> | ||
| 31 | + <template #action="{ record }"> | ||
| 32 | + <TableAction | ||
| 33 | + :actions="[ | ||
| 34 | + { | ||
| 35 | + label: '编辑', | ||
| 36 | + icon: 'clarity:note-edit-line', | ||
| 37 | + onClick: handleCreateOrEdit.bind(null, record), | ||
| 38 | + }, | ||
| 39 | + { | ||
| 40 | + label: '删除', | ||
| 41 | + icon: 'ant-design:delete-outlined', | ||
| 42 | + color: 'error', | ||
| 43 | + popConfirm: { | ||
| 44 | + title: '是否确认删除', | ||
| 45 | + confirm: handleDeleteOrBatchDelete.bind(null, record), | ||
| 46 | + }, | ||
| 47 | + }, | ||
| 48 | + ]" | ||
| 49 | + /> | ||
| 50 | + </template> | ||
| 51 | + </BasicTable> | ||
| 52 | + </PageWrapper> | ||
| 53 | + <ContactDrawer @register="registerDrawer" @success="handleSuccess" /> | ||
| 54 | + </div> | ||
| 55 | +</template> | ||
| 56 | + | ||
| 57 | +<script lang="ts"> | ||
| 58 | + import { defineComponent, reactive, ref, computed, h } from 'vue'; | ||
| 59 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | ||
| 60 | + import { PageWrapper } from '/@/components/Page'; | ||
| 61 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
| 62 | + import { useDrawer } from '/@/components/Drawer'; | ||
| 63 | + import ContactDrawer from './ContactDrawer.vue'; | ||
| 64 | + import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; | ||
| 65 | + import { deleteAlarmConfig, queryAlarmConfig } from '/@/api/alarm/config/alarmConfig'; | ||
| 66 | + import { searchFormSchema, columns } from './config.data'; | ||
| 67 | + import { Modal } from 'ant-design-vue'; | ||
| 68 | + import { JsonPreview } from '/@/components/CodeEditor'; | ||
| 69 | + import { findDictItemByCode } from '/@/api/system/dict'; | ||
| 70 | + import { alarmContactGetPage } from '/@/api/device/deviceConfigApi'; | ||
| 71 | + | ||
| 72 | + export default defineComponent({ | ||
| 73 | + components: { | ||
| 74 | + PageWrapper, | ||
| 75 | + OrganizationIdTree, | ||
| 76 | + BasicTable, | ||
| 77 | + TableAction, | ||
| 78 | + ContactDrawer, | ||
| 79 | + }, | ||
| 80 | + setup() { | ||
| 81 | + let selectedRowIds = ref<string[]>([]); | ||
| 82 | + const hasBatchDelete = computed(() => selectedRowIds.value.length <= 0); | ||
| 83 | + // 复选框事件 | ||
| 84 | + const onSelectRowChange = (selectedRowKeys: string[]) => { | ||
| 85 | + selectedRowIds.value = selectedRowKeys; | ||
| 86 | + }; | ||
| 87 | + const searchInfo = reactive<Recordable>({}); | ||
| 88 | + const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | ||
| 89 | + // 表格hooks | ||
| 90 | + const [registerTable, { reload }] = useTable({ | ||
| 91 | + title: '告警配置列表', | ||
| 92 | + api: queryAlarmConfig, | ||
| 93 | + columns, | ||
| 94 | + clickToRowSelect: false, | ||
| 95 | + formConfig: { | ||
| 96 | + labelWidth: 120, | ||
| 97 | + schemas: searchFormSchema, | ||
| 98 | + resetFunc: resetFn, | ||
| 99 | + }, | ||
| 100 | + useSearchForm: true, | ||
| 101 | + showTableSetting: true, | ||
| 102 | + bordered: true, | ||
| 103 | + rowSelection: { | ||
| 104 | + onChange: onSelectRowChange, | ||
| 105 | + type: 'checkbox', | ||
| 106 | + }, | ||
| 107 | + rowKey: 'id', | ||
| 108 | + actionColumn: { | ||
| 109 | + width: 200, | ||
| 110 | + title: '操作', | ||
| 111 | + dataIndex: 'action', | ||
| 112 | + slots: { customRender: 'action' }, | ||
| 113 | + fixed: 'right', | ||
| 114 | + }, | ||
| 115 | + }); | ||
| 116 | + // 弹框 | ||
| 117 | + const [registerDrawer, { openDrawer }] = useDrawer(); | ||
| 118 | + const { createMessage } = useMessage(); | ||
| 119 | + | ||
| 120 | + // 刷新 | ||
| 121 | + const handleSuccess = () => { | ||
| 122 | + reload(); | ||
| 123 | + }; | ||
| 124 | + // 新增或编辑 | ||
| 125 | + const handleCreateOrEdit = (record: Recordable | null) => { | ||
| 126 | + if (record) { | ||
| 127 | + openDrawer(true, { | ||
| 128 | + isUpdate: true, | ||
| 129 | + record, | ||
| 130 | + }); | ||
| 131 | + } else { | ||
| 132 | + openDrawer(true, { | ||
| 133 | + isUpdate: false, | ||
| 134 | + }); | ||
| 135 | + } | ||
| 136 | + }; | ||
| 137 | + // 删除或批量删除 | ||
| 138 | + const handleDeleteOrBatchDelete = async (record: Recordable | null) => { | ||
| 139 | + if (record) { | ||
| 140 | + try { | ||
| 141 | + await deleteAlarmConfig([record.id]); | ||
| 142 | + createMessage.success('删除成功'); | ||
| 143 | + handleSuccess(); | ||
| 144 | + } catch (e) { | ||
| 145 | + createMessage.error('删除失败'); | ||
| 146 | + } | ||
| 147 | + } else { | ||
| 148 | + try { | ||
| 149 | + await deleteAlarmConfig(selectedRowIds.value); | ||
| 150 | + createMessage.success('批量删除成功'); | ||
| 151 | + selectedRowIds.value = []; | ||
| 152 | + handleSuccess(); | ||
| 153 | + } catch (e) { | ||
| 154 | + createMessage.info('删除失败'); | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + }; | ||
| 158 | + | ||
| 159 | + // 树形选择器 | ||
| 160 | + const handleSelect = (organizationId: string) => { | ||
| 161 | + searchInfo.organizationId = organizationId; | ||
| 162 | + handleSuccess(); | ||
| 163 | + }; | ||
| 164 | + const showAlarmContact = async (record) => { | ||
| 165 | + const { items } = await alarmContactGetPage(); | ||
| 166 | + const joinArray = record.alarmContactId.split(','); | ||
| 167 | + let findName = []; | ||
| 168 | + findName = items.map((m) => { | ||
| 169 | + return { | ||
| 170 | + username: m.username, | ||
| 171 | + id: m.id, | ||
| 172 | + }; | ||
| 173 | + }); | ||
| 174 | + let arr3 = findName.filter((obj: any) => joinArray.some((obj1) => obj1 == obj.id)); | ||
| 175 | + let arr4 = arr3 | ||
| 176 | + .map((m: any) => { | ||
| 177 | + return m.username; | ||
| 178 | + }) | ||
| 179 | + .join(); | ||
| 180 | + Modal.info({ | ||
| 181 | + title: '当前告警通知联系人', | ||
| 182 | + width: 600, | ||
| 183 | + content: h(JsonPreview, { data: JSON.parse(JSON.stringify(arr4)) }), | ||
| 184 | + }); | ||
| 185 | + }; | ||
| 186 | + const showMessageMode = async (record) => { | ||
| 187 | + const data1: any = await findDictItemByCode({ dictCode: 'message_type' }); | ||
| 188 | + const joinArray = record.messageMode.split(','); | ||
| 189 | + let findName = []; | ||
| 190 | + findName = data1.map((m: any) => { | ||
| 191 | + return { | ||
| 192 | + itemValue: m.itemValue, | ||
| 193 | + itemText: m.itemText, | ||
| 194 | + }; | ||
| 195 | + }); | ||
| 196 | + let arr3 = findName.filter((obj: any) => joinArray.some((obj1) => obj1 == obj.itemValue)); | ||
| 197 | + let arr4 = arr3 | ||
| 198 | + .map((m: any) => { | ||
| 199 | + return m.itemText; | ||
| 200 | + }) | ||
| 201 | + .join(); | ||
| 202 | + Modal.info({ | ||
| 203 | + title: '当前告警联系方式', | ||
| 204 | + width: 600, | ||
| 205 | + content: h(JsonPreview, { data: JSON.parse(JSON.stringify(arr4)) }), | ||
| 206 | + }); | ||
| 207 | + }; | ||
| 208 | + return { | ||
| 209 | + searchInfo, | ||
| 210 | + hasBatchDelete, | ||
| 211 | + handleCreateOrEdit, | ||
| 212 | + handleDeleteOrBatchDelete, | ||
| 213 | + handleSelect, | ||
| 214 | + handleSuccess, | ||
| 215 | + registerTable, | ||
| 216 | + registerDrawer, | ||
| 217 | + organizationIdTreeRef, | ||
| 218 | + showAlarmContact, | ||
| 219 | + showMessageMode, | ||
| 220 | + }; | ||
| 221 | + }, | ||
| 222 | + }); | ||
| 223 | +</script> | 
| @@ -133,13 +133,9 @@ | @@ -133,13 +133,9 @@ | ||
| 133 | } | 133 | } | 
| 134 | current.value++; | 134 | current.value++; | 
| 135 | if (isUpdate.value == 2) { | 135 | if (isUpdate.value == 2) { | 
| 136 | - proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc( | ||
| 137 | - editData.value?.profileData.transportConfiguration | ||
| 138 | - ); | 136 | + proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc(editData.value); | 
| 139 | } else if (isUpdate.value == 3) { | 137 | } else if (isUpdate.value == 3) { | 
| 140 | - proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc( | ||
| 141 | - editData.value?.profileData.transportConfiguration | ||
| 142 | - ); | 138 | + proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc(editData.value); | 
| 143 | } | 139 | } | 
| 144 | } | 140 | } | 
| 145 | const handleSubmit = async () => { | 141 | const handleSubmit = async () => { | 
| @@ -19,7 +19,7 @@ | @@ -19,7 +19,7 @@ | ||
| 19 | <TableAction | 19 | <TableAction | 
| 20 | :actions="[ | 20 | :actions="[ | 
| 21 | { | 21 | { | 
| 22 | - label: '设置为默认', | 22 | + label: '设置默认', | 
| 23 | icon: 'ant-design:profile-outlined', | 23 | icon: 'ant-design:profile-outlined', | 
| 24 | onClick: handleSetDefault.bind(null, record), | 24 | onClick: handleSetDefault.bind(null, record), | 
| 25 | ifShow: () => { | 25 | ifShow: () => { | 
| @@ -62,7 +62,7 @@ | @@ -62,7 +62,7 @@ | ||
| 62 | </div> | 62 | </div> | 
| 63 | </template> | 63 | </template> | 
| 64 | <script lang="ts"> | 64 | <script lang="ts"> | 
| 65 | - import { defineComponent, ref, reactive } from 'vue'; | 65 | + import { defineComponent, ref, reactive, nextTick, onUnmounted } from 'vue'; | 
| 66 | import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table'; | 66 | import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table'; | 
| 67 | import { columns, searchFormSchema } from './device.profile.data'; | 67 | import { columns, searchFormSchema } from './device.profile.data'; | 
| 68 | import { useMessage } from '/@/hooks/web/useMessage'; | 68 | import { useMessage } from '/@/hooks/web/useMessage'; | 
| @@ -85,11 +85,12 @@ | @@ -85,11 +85,12 @@ | ||
| 85 | const getPathUrl = ref(''); | 85 | const getPathUrl = ref(''); | 
| 86 | const getPathUrlName = ref(''); | 86 | const getPathUrlName = ref(''); | 
| 87 | const disabled = ref(true); | 87 | const disabled = ref(true); | 
| 88 | + const onCloseVal = ref(0); | ||
| 88 | 89 | ||
| 89 | const { createMessage } = useMessage(); | 90 | const { createMessage } = useMessage(); | 
| 90 | const [registerModal, { openModal }] = useModal(); | 91 | const [registerModal, { openModal }] = useModal(); | 
| 91 | const [registerModalDetail] = useModal(); | 92 | const [registerModalDetail] = useModal(); | 
| 92 | - const [registerTable, { reload, getSelectRowKeys }] = useTable({ | 93 | + const [registerTable, { reload, getSelectRowKeys, setTableData, getForm }] = useTable({ | 
| 93 | title: '设备配置列表', | 94 | title: '设备配置列表', | 
| 94 | clickToRowSelect: false, | 95 | clickToRowSelect: false, | 
| 95 | api: deviceConfigGetQuery, | 96 | api: deviceConfigGetQuery, | 
| @@ -131,12 +132,33 @@ | @@ -131,12 +132,33 @@ | ||
| 131 | const getName = getParam(getPathUrl.value, name); | 132 | const getName = getParam(getPathUrl.value, name); | 
| 132 | getPathUrlName.value = decodeURIComponent(getName); | 133 | getPathUrlName.value = decodeURIComponent(getName); | 
| 133 | 134 | ||
| 134 | - // const setRowClassName = (record) => { | ||
| 135 | - // if (record.name === getPathUrlName.value) { | ||
| 136 | - // return 'rowcolor2'; | ||
| 137 | - // } | ||
| 138 | - // }; | 135 | + const setRowClassName = async () => { | 
| 136 | + if (getPathUrlName.value !== '') { | ||
| 137 | + const { items } = await deviceConfigGetQuery({ | ||
| 138 | + page: 1, | ||
| 139 | + pageSize: 10, | ||
| 140 | + name: getPathUrlName.value, | ||
| 141 | + }); | ||
| 142 | + nextTick(() => { | ||
| 143 | + setTableData(items); | ||
| 144 | + const { setFieldsValue, resetFields } = getForm(); | ||
| 145 | + setFieldsValue({ | ||
| 146 | + name: getPathUrlName.value, | ||
| 147 | + }); | ||
| 148 | + if (onCloseVal.value == 1) { | ||
| 149 | + resetFields(); | ||
| 150 | + } | ||
| 151 | + }); | ||
| 152 | + } | ||
| 153 | + }; | ||
| 154 | + setTimeout(() => { | ||
| 155 | + setRowClassName(); | ||
| 156 | + }, 500); | ||
| 139 | 157 | ||
| 158 | + onUnmounted(() => { | ||
| 159 | + getPathUrlName.value = ''; | ||
| 160 | + onCloseVal.value = 1; | ||
| 161 | + }); | ||
| 140 | const tableListRef = ref< | 162 | const tableListRef = ref< | 
| 141 | { | 163 | { | 
| 142 | title: string; | 164 | title: string; | 
| @@ -263,7 +285,6 @@ | @@ -263,7 +285,6 @@ | ||
| 263 | handleSetDefault, | 285 | handleSetDefault, | 
| 264 | disabled, | 286 | disabled, | 
| 265 | deviceDetailRef, | 287 | deviceDetailRef, | 
| 266 | - // setRowClassName, | ||
| 267 | registerModalDetail, | 288 | registerModalDetail, | 
| 268 | // register1, | 289 | // register1, | 
| 269 | // defaultHeader, | 290 | // defaultHeader, | 
| 1 | <template> | 1 | <template> | 
| 2 | - <div class="step2"> | ||
| 3 | - <div class="step2-style"> | ||
| 4 | - <div style="margin-top: 0.8vh; margin-left: 2.8vw; overflow: scroll"> | ||
| 5 | - <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register" /> | ||
| 6 | - <div | ||
| 7 | - style=" | ||
| 8 | - display: flex; | ||
| 9 | - width: 11vw; | ||
| 10 | - height: 8vh; | ||
| 11 | - flex-direction: row; | ||
| 12 | - justify-content: space-between; | ||
| 13 | - margin-left: 17vw; | ||
| 14 | - margin-top: -4vh; | ||
| 15 | - " | ||
| 16 | - > | ||
| 17 | - <div style="display: flex; width: 4vw; height: 4vh; margin-top: -2.35vh"> | ||
| 18 | - <Button type="default" style="border-radius: 2px" class="mt-5" @click="customResetFunc" | ||
| 19 | - >上一步</Button | ||
| 20 | - > | ||
| 21 | - </div> | 2 | + <div class="step2-style"> | 
| 3 | + <div style="margin-top: 0.1vh; overflow: scroll"> | ||
| 4 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register" /> | ||
| 5 | + <div v-if="isMqttType == 'MQTT'"> | ||
| 6 | + <MqttCpns ref="mqttRef" /> | ||
| 7 | + </div> | ||
| 8 | + <div v-else-if="isMqttType == 'COAP'"> | ||
| 9 | + <CoapCpns ref="coapRef" /> | ||
| 10 | + </div> | ||
| 11 | + <div | ||
| 12 | + style=" | ||
| 13 | + display: flex; | ||
| 14 | + width: 11vw; | ||
| 15 | + height: 8vh; | ||
| 16 | + flex-direction: row; | ||
| 17 | + justify-content: space-between; | ||
| 18 | + margin-left: 19vw; | ||
| 19 | + margin-top: -0.35vh; | ||
| 20 | + " | ||
| 21 | + > | ||
| 22 | + <div style="display: flex; width: 4vw; height: 4vh; margin-top: 1.65vh"> | ||
| 23 | + <Button type="default" style="border-radius: 2px" class="mt-5" @click="customResetFunc" | ||
| 24 | + >上一步</Button | ||
| 25 | + > | ||
| 22 | </div> | 26 | </div> | 
| 23 | </div> | 27 | </div> | 
| 24 | </div> | 28 | </div> | 
| 25 | </div> | 29 | </div> | 
| 26 | </template> | 30 | </template> | 
| 27 | <script lang="ts"> | 31 | <script lang="ts"> | 
| 28 | - import { defineComponent, reactive } from 'vue'; | 32 | + import { defineComponent, watch, reactive, ref, getCurrentInstance } from 'vue'; | 
| 29 | import { BasicForm, useForm } from '/@/components/Form'; | 33 | import { BasicForm, useForm } from '/@/components/Form'; | 
| 30 | - import { step2Schemas } from './data'; | 34 | + import { step2Schemas, isChangeType } from './data'; | 
| 31 | import { Alert, Divider, Descriptions } from 'ant-design-vue'; | 35 | import { Alert, Divider, Descriptions } from 'ant-design-vue'; | 
| 32 | import { Button } from '/@/components/Button'; | 36 | import { Button } from '/@/components/Button'; | 
| 37 | + import MqttCpns from '../step/cpns/mqtt/Mqtt.vue'; | ||
| 38 | + import CoapCpns from '../step/cpns/coap/Coap.vue'; | ||
| 33 | 39 | ||
| 34 | export default defineComponent({ | 40 | export default defineComponent({ | 
| 35 | components: { | 41 | components: { | 
| @@ -39,36 +45,19 @@ | @@ -39,36 +45,19 @@ | ||
| 39 | [Descriptions.name]: Descriptions, | 45 | [Descriptions.name]: Descriptions, | 
| 40 | [Descriptions.Item.name]: Descriptions.Item, | 46 | [Descriptions.Item.name]: Descriptions.Item, | 
| 41 | Button, | 47 | Button, | 
| 48 | + MqttCpns, | ||
| 49 | + CoapCpns, | ||
| 42 | }, | 50 | }, | 
| 43 | emits: ['next', 'prev', 'register'], | 51 | emits: ['next', 'prev', 'register'], | 
| 44 | setup(_, { emit }) { | 52 | setup(_, { emit }) { | 
| 45 | - const transportData: any = reactive({ | ||
| 46 | - transportConfiguration: { | ||
| 47 | - clientSettings: { | ||
| 48 | - powerMode: null, | ||
| 49 | - edrxCycle: null, | ||
| 50 | - pagingTransmissionWindow: null, | ||
| 51 | - psmActivityTimer: null, | ||
| 52 | - }, | ||
| 53 | - coapDeviceTypeConfiguration: { | ||
| 54 | - coapDeviceType: null, | ||
| 55 | - }, | ||
| 56 | - deviceTelemetryTopic: null, | ||
| 57 | - deviceAttributesTopic: null, | ||
| 58 | - transportPayloadTypeConfiguration: { | ||
| 59 | - transportPayloadType: null, | ||
| 60 | - enableCompatibilityWithJsonPayloadFormat: false, | ||
| 61 | - useJsonPayloadFormatForDefaultDownlinkTopics: false, | ||
| 62 | - deviceAttributesProtoSchema: null, | ||
| 63 | - deviceRpcRequestProtoSchema: null, | ||
| 64 | - deviceRpcResponseProtoSchema: null, | ||
| 65 | - deviceTelemetryProtoSchema: null, | ||
| 66 | - }, | ||
| 67 | - type: null, | ||
| 68 | - }, | 53 | + const { proxy } = getCurrentInstance() as any; | 
| 54 | + const mqttRef = ref(null); | ||
| 55 | + const coapRef = ref(null); | ||
| 56 | + const isMqttType = ref(''); | ||
| 57 | + let step2Data = reactive({ | ||
| 58 | + transportConfiguration: {}, | ||
| 69 | }); | 59 | }); | 
| 70 | - | ||
| 71 | - const [register, { validate, setFieldsValue, resetFields }] = useForm({ | 60 | + const [register, { validate, resetFields, setFieldsValue }] = useForm({ | 
| 72 | labelWidth: 80, | 61 | labelWidth: 80, | 
| 73 | schemas: step2Schemas, | 62 | schemas: step2Schemas, | 
| 74 | actionColOptions: { | 63 | actionColOptions: { | 
| @@ -76,69 +65,35 @@ | @@ -76,69 +65,35 @@ | ||
| 76 | }, | 65 | }, | 
| 77 | }); | 66 | }); | 
| 78 | const setStepTwoFieldsValueFunc = (v) => { | 67 | const setStepTwoFieldsValueFunc = (v) => { | 
| 79 | - console.log(v); | ||
| 80 | setFieldsValue({ | 68 | setFieldsValue({ | 
| 81 | - transportType: v?.type || v?.transportConfiguration.type, | ||
| 82 | - transportPayloadType: | ||
| 83 | - v?.transportPayloadTypeConfiguration?.transportPayloadType || | ||
| 84 | - v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration?.transportPayloadType, | ||
| 85 | - deviceTelemetryTopic: v?.deviceTelemetryTopic, | ||
| 86 | - deviceAttributesTopic: v?.deviceAttributesTopic, | ||
| 87 | - enableCompatibilityWithJsonPayloadFormat: | ||
| 88 | - v?.transportPayloadTypeConfiguration?.enableCompatibilityWithJsonPayloadFormat, | ||
| 89 | - useJsonPayloadFormatForDefaultDownlinkTopics: | ||
| 90 | - v?.transportPayloadTypeConfiguration?.useJsonPayloadFormatForDefaultDownlinkTopics, | ||
| 91 | - deviceAttributesProtoSchema: | ||
| 92 | - v?.transportPayloadTypeConfiguration?.deviceAttributesProtoSchema, | ||
| 93 | - deviceRpcRequestProtoSchema: | ||
| 94 | - v?.transportPayloadTypeConfiguration?.deviceRpcRequestProtoSchema, | ||
| 95 | - deviceRpcResponseProtoSchema: | ||
| 96 | - v?.transportPayloadTypeConfiguration?.deviceRpcResponseProtoSchema, | ||
| 97 | - deviceTelemetryProtoSchema: | ||
| 98 | - v?.transportPayloadTypeConfiguration?.deviceTelemetryProtoSchema, | ||
| 99 | - powerMode: v?.clientSettings?.powerMode, | ||
| 100 | - edrxCycle: v?.clientSettings?.edrxCycle, | ||
| 101 | - pagingTransmissionWindow: v?.clientSettings?.pagingTransmissionWindow, | ||
| 102 | - psmActivityTimer: v?.clientSettings?.psmActivityTimer, | ||
| 103 | - coapDeviceType: v?.coapDeviceTypeConfiguration?.coapDeviceType, | 69 | + transportType: v?.profileData?.transportConfiguration?.type, | 
| 104 | }); | 70 | }); | 
| 71 | + isMqttType.value = v?.profileData?.transportConfiguration?.type; | ||
| 72 | + setTimeout(() => { | ||
| 73 | + proxy.$refs.mqttRef?.setStepFieldsValueFunc(v?.profileData?.transportConfiguration); | ||
| 74 | + proxy.$refs.coapRef?.setStepFieldsValueFunc(v?.profileData?.transportConfiguration); | ||
| 75 | + }, 100); | ||
| 105 | }; | 76 | }; | 
| 106 | const customClearStepTwoValueFunc = () => { | 77 | const customClearStepTwoValueFunc = () => { | 
| 78 | + isMqttType.value = 'other'; | ||
| 107 | resetFields(); | 79 | resetFields(); | 
| 108 | }; | 80 | }; | 
| 109 | async function customResetFunc() { | 81 | async function customResetFunc() { | 
| 110 | emit('prev'); | 82 | emit('prev'); | 
| 111 | } | 83 | } | 
| 84 | + watch(isChangeType, async (v) => { | ||
| 85 | + isMqttType.value = v; | ||
| 86 | + }); | ||
| 112 | const getStep2DataFunc = async () => { | 87 | const getStep2DataFunc = async () => { | 
| 113 | const val = await validate(); | 88 | const val = await validate(); | 
| 114 | if (!val) return; | 89 | if (!val) return; | 
| 115 | - transportData.transportConfiguration.deviceTelemetryTopic = val.deviceTelemetryTopic; | ||
| 116 | - transportData.transportConfiguration.deviceAttributesTopic = val.deviceAttributesTopic; | ||
| 117 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.transportPayloadType = | ||
| 118 | - val.transportPayloadType; | ||
| 119 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.enableCompatibilityWithJsonPayloadFormat = | ||
| 120 | - val.enableCompatibilityWithJsonPayloadFormat; | ||
| 121 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.useJsonPayloadFormatForDefaultDownlinkTopics = | ||
| 122 | - val.useJsonPayloadFormatForDefaultDownlinkTopics; | ||
| 123 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.enableCompatibilityWithJsonPayloadFormat = | ||
| 124 | - val.enableCompatibilityWithJsonPayloadFormat; | ||
| 125 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.deviceAttributesProtoSchema = | ||
| 126 | - val.deviceAttributesProtoSchema; | ||
| 127 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema = | ||
| 128 | - val.deviceRpcRequestProtoSchema; | ||
| 129 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema = | ||
| 130 | - val.deviceRpcResponseProtoSchema; | ||
| 131 | - transportData.transportConfiguration.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema = | ||
| 132 | - val.deviceTelemetryProtoSchema; | ||
| 133 | - transportData.transportConfiguration.type = val.transportType; | ||
| 134 | - transportData.transportConfiguration.clientSettings.powerMode = val.powerMode; | ||
| 135 | - transportData.transportConfiguration.clientSettings.edrxCycle = val.edrxCycle; | ||
| 136 | - transportData.transportConfiguration.clientSettings.psmActivityTimer = val.psmActivityTimer; | ||
| 137 | - transportData.transportConfiguration.clientSettings.pagingTransmissionWindow = | ||
| 138 | - val.pagingTransmissionWindow; | ||
| 139 | - transportData.transportConfiguration.coapDeviceTypeConfiguration.coapDeviceType = | ||
| 140 | - val.coapDeviceType; | ||
| 141 | - return transportData; | 90 | + const getMqttVal = await proxy.$refs.mqttRef?.getDataFunc(); | 
| 91 | + const getCoapVal = await proxy.$refs.coapRef?.getDataFunc(); | ||
| 92 | + step2Data.transportConfiguration = { | ||
| 93 | + ...getMqttVal, | ||
| 94 | + ...getCoapVal, | ||
| 95 | + }; | ||
| 96 | + return step2Data; | ||
| 142 | }; | 97 | }; | 
| 143 | return { | 98 | return { | 
| 144 | customResetFunc, | 99 | customResetFunc, | 
| @@ -146,21 +101,19 @@ | @@ -146,21 +101,19 @@ | ||
| 146 | setStepTwoFieldsValueFunc, | 101 | setStepTwoFieldsValueFunc, | 
| 147 | customClearStepTwoValueFunc, | 102 | customClearStepTwoValueFunc, | 
| 148 | getStep2DataFunc, | 103 | getStep2DataFunc, | 
| 104 | + isMqttType, | ||
| 105 | + mqttRef, | ||
| 106 | + coapRef, | ||
| 149 | }; | 107 | }; | 
| 150 | }, | 108 | }, | 
| 151 | }); | 109 | }); | 
| 152 | </script> | 110 | </script> | 
| 153 | <style lang="less" scoped> | 111 | <style lang="less" scoped> | 
| 154 | - .step2 { | ||
| 155 | - width: 100%; | ||
| 156 | - .step2-style { | ||
| 157 | - width: 43vw; | ||
| 158 | - // height: 50vh; | ||
| 159 | - border: 1px solid gray; | ||
| 160 | - margin: 0vh 0.6vw; | ||
| 161 | - border-radius: 4px; | ||
| 162 | - } | 112 | + .step2-style { | 
| 113 | + margin: 0vh 0.6vw; | ||
| 114 | + border-radius: 4px; | ||
| 163 | } | 115 | } | 
| 116 | + | ||
| 164 | ::-webkit-scrollbar { | 117 | ::-webkit-scrollbar { | 
| 165 | display: none; | 118 | display: none; | 
| 166 | } | 119 | } | 
| 1 | +import { FormSchema } from '/@/components/Form'; | ||
| 2 | + | ||
| 3 | +enum EnumType { | ||
| 4 | + IS_DEFAULT = 'DEFAULT', | ||
| 5 | + IS_MQTT = 'MQTT', | ||
| 6 | + IS_PROTOBUF = 'PROTOBUF', | ||
| 7 | + IS_COAP = 'COAP', | ||
| 8 | + IS_LWM2M = 'LWM2M', | ||
| 9 | + IS_SNMP = 'SNMP', | ||
| 10 | + IS_PSM = 'PSM', | ||
| 11 | + IS_DRX = 'E_DRX', | ||
| 12 | + IS_EFENTO_NBIOT = 'EFENTO', | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +const isProtobuf = (type: string) => { | ||
| 16 | + return type === EnumType.IS_PROTOBUF; | ||
| 17 | +}; | ||
| 18 | + | ||
| 19 | +const isPsm = (type: string) => { | ||
| 20 | + return type === EnumType.IS_PSM; | ||
| 21 | +}; | ||
| 22 | + | ||
| 23 | +const isDrx = (type: string) => { | ||
| 24 | + return type === EnumType.IS_DRX; | ||
| 25 | +}; | ||
| 26 | + | ||
| 27 | +const isEfentoNb = (type: string) => { | ||
| 28 | + return type === EnumType.IS_EFENTO_NBIOT; | ||
| 29 | +}; | ||
| 30 | + | ||
| 31 | +export const CoapSchemas: FormSchema[] = [ | ||
| 32 | + { | ||
| 33 | + field: 'coapDeviceType', | ||
| 34 | + component: 'Select', | ||
| 35 | + label: 'CoAP类型', | ||
| 36 | + defaultValue: 'DEFAULT', | ||
| 37 | + componentProps: { | ||
| 38 | + options: [ | ||
| 39 | + { label: '默认', value: 'DEFAULT' }, | ||
| 40 | + { label: 'Efento NB-IoT', value: 'EFENTO' }, | ||
| 41 | + ], | ||
| 42 | + }, | ||
| 43 | + colProps: { span: 11 }, | ||
| 44 | + }, | ||
| 45 | + { | ||
| 46 | + field: 'transportPayloadType', | ||
| 47 | + component: 'Select', | ||
| 48 | + label: '设备消息', | ||
| 49 | + defaultValue: 'JSON', | ||
| 50 | + componentProps: { | ||
| 51 | + options: [ | ||
| 52 | + { label: 'JSON', value: 'JSON' }, | ||
| 53 | + { label: 'PROTOBUF', value: 'PROTOBUF' }, | ||
| 54 | + ], | ||
| 55 | + }, | ||
| 56 | + colProps: { span: 11 }, | ||
| 57 | + ifShow: ({ values }) => !isEfentoNb(values.coapDeviceType), | ||
| 58 | + }, | ||
| 59 | + { | ||
| 60 | + field: 'powerMode', | ||
| 61 | + component: 'Select', | ||
| 62 | + label: 'Power Mode', | ||
| 63 | + defaultValue: 'DRX', | ||
| 64 | + componentProps: { | ||
| 65 | + options: [ | ||
| 66 | + { label: 'Power Saving Mode', value: 'PSM' }, | ||
| 67 | + { label: 'Discontinuous Reception', value: 'DRX' }, | ||
| 68 | + { | ||
| 69 | + label: 'Extended Discontinuous Reception', | ||
| 70 | + value: 'E_DRX', | ||
| 71 | + }, | ||
| 72 | + ], | ||
| 73 | + }, | ||
| 74 | + colProps: { span: 22 }, | ||
| 75 | + }, | ||
| 76 | + { | ||
| 77 | + field: 'psmActivityTimer', | ||
| 78 | + component: 'InputNumber', | ||
| 79 | + label: 'Timer', | ||
| 80 | + required: true, | ||
| 81 | + defaultValue: '10', | ||
| 82 | + componentProps: { | ||
| 83 | + placeholder: '请输入PSM Activity Timer', | ||
| 84 | + }, | ||
| 85 | + colProps: { span: 11 }, | ||
| 86 | + ifShow: ({ values }) => isPsm(values.powerMode), | ||
| 87 | + }, | ||
| 88 | + { | ||
| 89 | + field: 'unit1', | ||
| 90 | + component: 'Select', | ||
| 91 | + label: '时间单位', | ||
| 92 | + defaultValue: 'second', | ||
| 93 | + componentProps: { | ||
| 94 | + options: [ | ||
| 95 | + { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 96 | + { label: '秒', value: 'second' }, | ||
| 97 | + { label: '分钟', value: 'minute' }, | ||
| 98 | + { label: '小时', value: 'hour' }, | ||
| 99 | + ], | ||
| 100 | + }, | ||
| 101 | + colProps: { span: 11 }, | ||
| 102 | + ifShow: ({ values }) => isPsm(values.powerMode), | ||
| 103 | + }, | ||
| 104 | + { | ||
| 105 | + field: 'edrxCycle', | ||
| 106 | + component: 'InputNumber', | ||
| 107 | + label: 'eDRX cycle', | ||
| 108 | + required: true, | ||
| 109 | + defaultValue: '81', | ||
| 110 | + componentProps: { | ||
| 111 | + placeholder: '请输入PSM Activity Timer', | ||
| 112 | + }, | ||
| 113 | + colProps: { span: 11 }, | ||
| 114 | + ifShow: ({ values }) => isDrx(values.powerMode), | ||
| 115 | + }, | ||
| 116 | + { | ||
| 117 | + field: 'unit2', | ||
| 118 | + component: 'Select', | ||
| 119 | + label: '时间单位', | ||
| 120 | + defaultValue: 'second', | ||
| 121 | + componentProps: { | ||
| 122 | + options: [ | ||
| 123 | + { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 124 | + { label: '秒', value: 'second' }, | ||
| 125 | + { label: '分钟', value: 'minute' }, | ||
| 126 | + { label: '小时', value: 'hour' }, | ||
| 127 | + ], | ||
| 128 | + }, | ||
| 129 | + colProps: { span: 11 }, | ||
| 130 | + ifShow: ({ values }) => isDrx(values.powerMode), | ||
| 131 | + }, | ||
| 132 | + { | ||
| 133 | + field: 'pagingTransmissionWindow', | ||
| 134 | + component: 'InputNumber', | ||
| 135 | + label: 'Paging', | ||
| 136 | + required: true, | ||
| 137 | + defaultValue: '10', | ||
| 138 | + componentProps: { | ||
| 139 | + placeholder: '请输入Paging Transmission Window', | ||
| 140 | + }, | ||
| 141 | + colProps: { span: 11 }, | ||
| 142 | + ifShow: ({ values }) => isDrx(values.powerMode), | ||
| 143 | + }, | ||
| 144 | + { | ||
| 145 | + field: 'unit', | ||
| 146 | + component: 'Select', | ||
| 147 | + label: '时间单位', | ||
| 148 | + defaultValue: 'second', | ||
| 149 | + componentProps: { | ||
| 150 | + options: [ | ||
| 151 | + { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 152 | + { label: '秒', value: 'second' }, | ||
| 153 | + { label: '分钟', value: 'minute' }, | ||
| 154 | + { label: '小时', value: 'hour' }, | ||
| 155 | + ], | ||
| 156 | + }, | ||
| 157 | + colProps: { span: 11 }, | ||
| 158 | + ifShow: ({ values }) => isDrx(values.powerMode), | ||
| 159 | + }, | ||
| 160 | + { | ||
| 161 | + field: 'deviceTelemetryProtoSchema', | ||
| 162 | + label: '遥测数据', | ||
| 163 | + colProps: { span: 22 }, | ||
| 164 | + component: 'InputTextArea', | ||
| 165 | + componentProps: { | ||
| 166 | + autoSize: { | ||
| 167 | + maxRows: 10, | ||
| 168 | + }, | ||
| 169 | + }, | ||
| 170 | + defaultValue: ` | ||
| 171 | + syntax ="proto3"; | ||
| 172 | + package telemetry; | ||
| 173 | + | ||
| 174 | + message SensorDataReading { | ||
| 175 | + optional double temperature = 1; | ||
| 176 | + optional double humidity = 2; | ||
| 177 | + InnerObject innerObject = 3; | ||
| 178 | + message InnerObject { | ||
| 179 | + optional string key1 = 1; | ||
| 180 | + optional bool key2 = 2; | ||
| 181 | + optional double key3 = 3; | ||
| 182 | + optional int32 key4 = 4; | ||
| 183 | + optional string key5 = 5; | ||
| 184 | + } | ||
| 185 | + } | ||
| 186 | + `, | ||
| 187 | + ifShow: ({ values }) => | ||
| 188 | + isProtobuf(values.transportPayloadType) && !isEfentoNb(values.coapDeviceType), | ||
| 189 | + }, | ||
| 190 | + { | ||
| 191 | + field: 'deviceAttributesProtoSchema', | ||
| 192 | + label: 'Attributes', | ||
| 193 | + colProps: { span: 22 }, | ||
| 194 | + component: 'InputTextArea', | ||
| 195 | + componentProps: { | ||
| 196 | + autoSize: { | ||
| 197 | + maxRows: 10, | ||
| 198 | + }, | ||
| 199 | + }, | ||
| 200 | + defaultValue: ` | ||
| 201 | + syntax ="proto3"; | ||
| 202 | + package attributes; | ||
| 203 | + | ||
| 204 | + message SensorConfiguration { | ||
| 205 | + optional string firmwareVersion = 1; | ||
| 206 | + optional string serialNumber = 2; | ||
| 207 | + } | ||
| 208 | + `, | ||
| 209 | + ifShow: ({ values }) => | ||
| 210 | + isProtobuf(values.transportPayloadType) && !isEfentoNb(values.coapDeviceType), | ||
| 211 | + }, | ||
| 212 | + { | ||
| 213 | + field: 'deviceRpcRequestProtoSchema', | ||
| 214 | + label: 'RPC 请求 ', | ||
| 215 | + colProps: { span: 22 }, | ||
| 216 | + component: 'InputTextArea', | ||
| 217 | + componentProps: { | ||
| 218 | + autoSize: { | ||
| 219 | + maxRows: 10, | ||
| 220 | + }, | ||
| 221 | + }, | ||
| 222 | + defaultValue: ` | ||
| 223 | + syntax ="proto3"; | ||
| 224 | + package rpc; | ||
| 225 | + | ||
| 226 | + message RpcRequestMsg { | ||
| 227 | + optional string method = 1; | ||
| 228 | + optional int32 requestId = 2; | ||
| 229 | + optional string params = 3; | ||
| 230 | + } | ||
| 231 | + `, | ||
| 232 | + ifShow: ({ values }) => | ||
| 233 | + isProtobuf(values.transportPayloadType) && !isEfentoNb(values.coapDeviceType), | ||
| 234 | + }, | ||
| 235 | + { | ||
| 236 | + field: 'deviceRpcResponseProtoSchema', | ||
| 237 | + label: 'RPC 响应', | ||
| 238 | + colProps: { span: 22 }, | ||
| 239 | + component: 'InputTextArea', | ||
| 240 | + componentProps: { | ||
| 241 | + autoSize: { | ||
| 242 | + maxRows: 10, | ||
| 243 | + }, | ||
| 244 | + }, | ||
| 245 | + defaultValue: ` | ||
| 246 | + syntax ="proto3"; | ||
| 247 | + package rpc; | ||
| 248 | + | ||
| 249 | + message RpcResponseMsg { | ||
| 250 | + optional string payload = 1; | ||
| 251 | + } | ||
| 252 | + `, | ||
| 253 | + ifShow: ({ values }) => | ||
| 254 | + isProtobuf(values.transportPayloadType) && !isEfentoNb(values.coapDeviceType), | ||
| 255 | + }, | ||
| 256 | +]; | 
| 1 | +<template> | ||
| 2 | + <div | ||
| 3 | + style=" | ||
| 4 | + margin-top: -5vh; | ||
| 5 | + padding-left: 1.5vw; | ||
| 6 | + border: 1px solid gray; | ||
| 7 | + margin-left: 0.1vw; | ||
| 8 | + border-radius: 5px; | ||
| 9 | + " | ||
| 10 | + > | ||
| 11 | + <div style="margin-top: 1.2vh"> | ||
| 12 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register" /> | ||
| 13 | + </div> | ||
| 14 | + </div> | ||
| 15 | +</template> | ||
| 16 | +<script lang="ts"> | ||
| 17 | + import { defineComponent, reactive } from 'vue'; | ||
| 18 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 19 | + import { CoapSchemas } from './Coap'; | ||
| 20 | + import { Alert, Divider, Descriptions } from 'ant-design-vue'; | ||
| 21 | + | ||
| 22 | + export default defineComponent({ | ||
| 23 | + components: { | ||
| 24 | + BasicForm, | ||
| 25 | + [Alert.name]: Alert, | ||
| 26 | + [Divider.name]: Divider, | ||
| 27 | + [Descriptions.name]: Descriptions, | ||
| 28 | + [Descriptions.Item.name]: Descriptions.Item, | ||
| 29 | + }, | ||
| 30 | + | ||
| 31 | + emits: ['next', 'prev', 'register'], | ||
| 32 | + setup(_, { emit }) { | ||
| 33 | + let coapAllData = reactive({}); | ||
| 34 | + const transportCoapData: any = reactive({ | ||
| 35 | + coapDeviceTypeConfiguration: { | ||
| 36 | + coapDeviceType: null, | ||
| 37 | + transportPayloadTypeConfiguration: { | ||
| 38 | + transportPayloadType: null, | ||
| 39 | + deviceTelemetryProtoSchema: null, | ||
| 40 | + deviceAttributesProtoSchema: null, | ||
| 41 | + deviceRpcRequestProtoSchema: null, | ||
| 42 | + deviceRpcResponseProtoSchema: null, | ||
| 43 | + }, | ||
| 44 | + }, | ||
| 45 | + clientSettings: { | ||
| 46 | + powerMode: null, | ||
| 47 | + edrxCycle: null, | ||
| 48 | + pagingTransmissionWindow: null, | ||
| 49 | + psmActivityTimer: null, | ||
| 50 | + }, | ||
| 51 | + type: 'COAP', | ||
| 52 | + }); | ||
| 53 | + | ||
| 54 | + const [register, { validate, resetFields, setFieldsValue }] = useForm({ | ||
| 55 | + labelWidth: 80, | ||
| 56 | + schemas: CoapSchemas, | ||
| 57 | + actionColOptions: { | ||
| 58 | + span: 14, | ||
| 59 | + }, | ||
| 60 | + }); | ||
| 61 | + const setStepFieldsValueFunc = (v) => { | ||
| 62 | + setFieldsValue({ | ||
| 63 | + coapDeviceType: v?.coapDeviceTypeConfiguration?.coapDeviceType, | ||
| 64 | + transportPayloadType: | ||
| 65 | + v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration?.transportPayloadType, | ||
| 66 | + powerMode: v?.clientSettings.powerMode, | ||
| 67 | + psmActivityTimer: v.clientSettings?.psmActivityTimer, | ||
| 68 | + edrxCycle: v?.clientSettings.edrxCycle, | ||
| 69 | + pagingTransmissionWindow: v.clientSettings?.pagingTransmissionWindow, | ||
| 70 | + deviceTelemetryProtoSchema: | ||
| 71 | + v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration | ||
| 72 | + ?.deviceTelemetryProtoSchema, | ||
| 73 | + deviceAttributesProtoSchema: | ||
| 74 | + v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration | ||
| 75 | + ?.deviceAttributesProtoSchema, | ||
| 76 | + deviceRpcRequestProtoSchema: | ||
| 77 | + v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration | ||
| 78 | + ?.deviceRpcRequestProtoSchema, | ||
| 79 | + deviceRpcResponseProtoSchema: | ||
| 80 | + v?.coapDeviceTypeConfiguration?.transportPayloadTypeConfiguration | ||
| 81 | + ?.deviceRpcResponseProtoSchema, | ||
| 82 | + }); | ||
| 83 | + }; | ||
| 84 | + const customClearStepTwoValueFunc = () => { | ||
| 85 | + resetFields(); | ||
| 86 | + }; | ||
| 87 | + async function customResetFunc() { | ||
| 88 | + emit('prev'); | ||
| 89 | + } | ||
| 90 | + const getDataFunc = async () => { | ||
| 91 | + const val = await validate(); | ||
| 92 | + if (!val) return; | ||
| 93 | + transportCoapData.coapDeviceTypeConfiguration.coapDeviceType = val.coapDeviceType; | ||
| 94 | + transportCoapData.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType = | ||
| 95 | + val.transportPayloadType; | ||
| 96 | + transportCoapData.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema = | ||
| 97 | + val.deviceTelemetryProtoSchema; | ||
| 98 | + transportCoapData.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceAttributesProtoSchema = | ||
| 99 | + val.deviceAttributesProtoSchema; | ||
| 100 | + transportCoapData.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema = | ||
| 101 | + val.deviceRpcRequestProtoSchema; | ||
| 102 | + transportCoapData.coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema = | ||
| 103 | + val.deviceRpcResponseProtoSchema; | ||
| 104 | + transportCoapData.clientSettings.powerMode = val.powerMode; | ||
| 105 | + transportCoapData.clientSettings.edrxCycle = val.edrxCycle; | ||
| 106 | + transportCoapData.clientSettings.pagingTransmissionWindow = val.pagingTransmissionWindow; | ||
| 107 | + transportCoapData.clientSettings.psmActivityTimer = val.psmActivityTimer; | ||
| 108 | + coapAllData = { | ||
| 109 | + ...transportCoapData, | ||
| 110 | + }; | ||
| 111 | + return coapAllData; | ||
| 112 | + }; | ||
| 113 | + return { | ||
| 114 | + customResetFunc, | ||
| 115 | + register, | ||
| 116 | + customClearStepTwoValueFunc, | ||
| 117 | + getDataFunc, | ||
| 118 | + setStepFieldsValueFunc, | ||
| 119 | + }; | ||
| 120 | + }, | ||
| 121 | + }); | ||
| 122 | +</script> | ||
| 123 | +<style lang="less" scoped></style> | 
| 1 | +import { FormSchema } from '/@/components/Form'; | ||
| 2 | + | ||
| 3 | +enum EnumMQTT { | ||
| 4 | + IS_DEFAULT = 'DEFAULT', | ||
| 5 | + IS_MQTT = 'MQTT', | ||
| 6 | + IS_PROTOBUF = 'PROTOBUF', | ||
| 7 | + IS_COAP = 'COAP', | ||
| 8 | + IS_LWM2M = 'LWM2M', | ||
| 9 | + IS_SNMP = 'SNMP', | ||
| 10 | + IS_PSM = 'PSM', | ||
| 11 | + IS_DRX = 'E_DRX', | ||
| 12 | + IS_EFENTO_NBIOT = 'EFENTO', | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +const isProtobuf = (type: string) => { | ||
| 16 | + return type === EnumMQTT.IS_PROTOBUF; | ||
| 17 | +}; | ||
| 18 | + | ||
| 19 | +export const MqttSchemas: FormSchema[] = [ | ||
| 20 | + { | ||
| 21 | + field: 'deviceTelemetryTopic', | ||
| 22 | + component: 'Input', | ||
| 23 | + label: '筛选器', | ||
| 24 | + required: true, | ||
| 25 | + defaultValue: 'v1/devices/me/telemetry', | ||
| 26 | + componentProps: { | ||
| 27 | + placeholder: '请输入遥测数据 topic 筛选器', | ||
| 28 | + }, | ||
| 29 | + colProps: { span: 11 }, | ||
| 30 | + }, | ||
| 31 | + { | ||
| 32 | + field: 'deviceAttributesTopic', | ||
| 33 | + component: 'Input', | ||
| 34 | + required: true, | ||
| 35 | + label: 'topic filter', | ||
| 36 | + defaultValue: 'v1/devices/me/attributes', | ||
| 37 | + componentProps: { | ||
| 38 | + placeholder: '请输入Attributes topic 筛选器', | ||
| 39 | + }, | ||
| 40 | + colProps: { span: 11 }, | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + field: 'desc', | ||
| 44 | + component: 'InputTextArea', | ||
| 45 | + label: '描述', | ||
| 46 | + defaultValue: `支持单[+]和多级[#]通配符。[+] is suitable for any topic filter level。例如: | ||
| 47 | + v1/devices/+/telemetry or | ||
| 48 | + +/devices/+/attributes。[#]可以替换 topic filter 本身,并且必须是 topic 的最后一个符号。例如:# or v1/devices/me/#。 | ||
| 49 | + `, | ||
| 50 | + componentProps: { | ||
| 51 | + autoSize: { | ||
| 52 | + maxRows: 10, | ||
| 53 | + }, | ||
| 54 | + }, | ||
| 55 | + colProps: { span: 22 }, | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + field: 'transportPayloadType', | ||
| 59 | + component: 'Select', | ||
| 60 | + label: '设备Payload', | ||
| 61 | + defaultValue: 'JSON', | ||
| 62 | + componentProps: { | ||
| 63 | + options: [ | ||
| 64 | + { label: 'JSON', value: 'JSON' }, | ||
| 65 | + { label: 'PROTOBUF', value: 'PROTOBUF' }, | ||
| 66 | + ], | ||
| 67 | + }, | ||
| 68 | + colProps: { span: 11 }, | ||
| 69 | + }, | ||
| 70 | + { | ||
| 71 | + field: 'useJsonPayloadFormatForDefaultDownlinkTopics', | ||
| 72 | + label: '', | ||
| 73 | + colProps: { span: 22 }, | ||
| 74 | + defaultValue: false, | ||
| 75 | + component: 'Checkbox', | ||
| 76 | + renderComponentContent: `启用后,平台将默认使用Protobuf有效载荷格式。如果解析失败,平台将尝试使用JSON有效负载格式。用于固件更新期间的向后兼容性。例如,固件的初始版本使用Json,而新版本使用Protobuf。在设备组的固件更新过程中,需要同时支持Protobuf和JSON。兼容性模式会导致性能轻微下降,因此建议在所有设备更新后禁用此模式。`, | ||
| 77 | + ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 78 | + }, | ||
| 79 | + { | ||
| 80 | + field: 'enableCompatibilityWithJsonPayloadFormat', | ||
| 81 | + label: '', | ||
| 82 | + colProps: { span: 22 }, | ||
| 83 | + defaultValue: false, | ||
| 84 | + component: 'Checkbox', | ||
| 85 | + renderComponentContent: `启用后,平台将使用Json有效负载格式通过以下主题推送属性和RPC:v1/devices/me/attributes/response/$request_id, v1/devices/me/attributes, v1/devices/me/rpc/request/$request_id,v1/devices/me/rpc/response/$request_id.此设置不会影响使用新(v2)主题发送的属性和rpc订阅:v2/a/res/$request_id, v2/a, v2/r/req/$request_id, v2/r/res/$request_id. Where $request_id是一个整数请求标识符。`, | ||
| 86 | + ifShow: ({ values }) => | ||
| 87 | + isProtobuf(values.transportPayloadType) && | ||
| 88 | + !!values.useJsonPayloadFormatForDefaultDownlinkTopics, | ||
| 89 | + }, | ||
| 90 | + { | ||
| 91 | + field: 'deviceTelemetryProtoSchema', | ||
| 92 | + label: '遥测数据', | ||
| 93 | + colProps: { span: 22 }, | ||
| 94 | + component: 'InputTextArea', | ||
| 95 | + componentProps: { | ||
| 96 | + autoSize: { | ||
| 97 | + maxRows: 10, | ||
| 98 | + }, | ||
| 99 | + }, | ||
| 100 | + defaultValue: ` | ||
| 101 | + syntax ="proto3"; | ||
| 102 | + package telemetry; | ||
| 103 | + | ||
| 104 | + message SensorDataReading { | ||
| 105 | + optional double temperature = 1; | ||
| 106 | + optional double humidity = 2; | ||
| 107 | + InnerObject innerObject = 3; | ||
| 108 | + message InnerObject { | ||
| 109 | + optional string key1 = 1; | ||
| 110 | + optional bool key2 = 2; | ||
| 111 | + optional double key3 = 3; | ||
| 112 | + optional int32 key4 = 4; | ||
| 113 | + optional string key5 = 5; | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + `, | ||
| 117 | + ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 118 | + }, | ||
| 119 | + { | ||
| 120 | + field: 'deviceAttributesProtoSchema', | ||
| 121 | + label: 'Attributes', | ||
| 122 | + colProps: { span: 22 }, | ||
| 123 | + component: 'InputTextArea', | ||
| 124 | + componentProps: { | ||
| 125 | + autoSize: { | ||
| 126 | + maxRows: 10, | ||
| 127 | + }, | ||
| 128 | + }, | ||
| 129 | + defaultValue: ` | ||
| 130 | + syntax ="proto3"; | ||
| 131 | + package attributes; | ||
| 132 | + | ||
| 133 | + message SensorConfiguration { | ||
| 134 | + optional string firmwareVersion = 1; | ||
| 135 | + optional string serialNumber = 2; | ||
| 136 | + } | ||
| 137 | + `, | ||
| 138 | + ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 139 | + }, | ||
| 140 | + { | ||
| 141 | + field: 'deviceRpcRequestProtoSchema', | ||
| 142 | + label: 'RPC 请求 ', | ||
| 143 | + colProps: { span: 22 }, | ||
| 144 | + component: 'InputTextArea', | ||
| 145 | + componentProps: { | ||
| 146 | + autoSize: { | ||
| 147 | + maxRows: 10, | ||
| 148 | + }, | ||
| 149 | + }, | ||
| 150 | + defaultValue: ` | ||
| 151 | + syntax ="proto3"; | ||
| 152 | + package rpc; | ||
| 153 | + | ||
| 154 | + message RpcRequestMsg { | ||
| 155 | + optional string method = 1; | ||
| 156 | + optional int32 requestId = 2; | ||
| 157 | + optional string params = 3; | ||
| 158 | + } | ||
| 159 | + `, | ||
| 160 | + ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 161 | + }, | ||
| 162 | + { | ||
| 163 | + field: 'deviceRpcResponseProtoSchema', | ||
| 164 | + label: 'RPC 响应', | ||
| 165 | + colProps: { span: 22 }, | ||
| 166 | + component: 'InputTextArea', | ||
| 167 | + componentProps: { | ||
| 168 | + autoSize: { | ||
| 169 | + maxRows: 10, | ||
| 170 | + }, | ||
| 171 | + }, | ||
| 172 | + defaultValue: ` | ||
| 173 | + syntax ="proto3"; | ||
| 174 | + package rpc; | ||
| 175 | + | ||
| 176 | + message RpcResponseMsg { | ||
| 177 | + optional string payload = 1; | ||
| 178 | + } | ||
| 179 | + `, | ||
| 180 | + ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 181 | + }, | ||
| 182 | +]; | 
| 1 | +<template> | ||
| 2 | + <div | ||
| 3 | + style=" | ||
| 4 | + margin-top: -5vh; | ||
| 5 | + border: 1px solid gray; | ||
| 6 | + margin-left: 0.1vw; | ||
| 7 | + border-radius: 5px; | ||
| 8 | + padding-left: 1.5vw; | ||
| 9 | + " | ||
| 10 | + > | ||
| 11 | + <div style="margin-top: 1.2vh"> | ||
| 12 | + <BasicForm :showResetButton="false" :showSubmitButton="false" @register="register" /> | ||
| 13 | + </div> | ||
| 14 | + </div> | ||
| 15 | +</template> | ||
| 16 | +<script lang="ts"> | ||
| 17 | + import { defineComponent, reactive } from 'vue'; | ||
| 18 | + import { BasicForm, useForm } from '/@/components/Form'; | ||
| 19 | + import { MqttSchemas } from './Mqtt'; | ||
| 20 | + import { Alert, Divider, Descriptions } from 'ant-design-vue'; | ||
| 21 | + | ||
| 22 | + export default defineComponent({ | ||
| 23 | + components: { | ||
| 24 | + BasicForm, | ||
| 25 | + [Alert.name]: Alert, | ||
| 26 | + [Divider.name]: Divider, | ||
| 27 | + [Descriptions.name]: Descriptions, | ||
| 28 | + [Descriptions.Item.name]: Descriptions.Item, | ||
| 29 | + }, | ||
| 30 | + | ||
| 31 | + emits: ['next', 'prev', 'register'], | ||
| 32 | + setup(_, { emit }) { | ||
| 33 | + let allMqttData: any = reactive({}); | ||
| 34 | + const transportMqttData: any = reactive({ | ||
| 35 | + transportPayloadTypeConfiguration: { | ||
| 36 | + transportPayloadType: null, | ||
| 37 | + enableCompatibilityWithJsonPayloadFormat: false, | ||
| 38 | + useJsonPayloadFormatForDefaultDownlinkTopics: false, | ||
| 39 | + deviceAttributesProtoSchema: null, | ||
| 40 | + deviceRpcRequestProtoSchema: null, | ||
| 41 | + deviceRpcResponseProtoSchema: null, | ||
| 42 | + deviceTelemetryProtoSchema: null, | ||
| 43 | + }, | ||
| 44 | + type: 'MQTT', | ||
| 45 | + }); | ||
| 46 | + | ||
| 47 | + const [register, { validate, resetFields, setFieldsValue }] = useForm({ | ||
| 48 | + labelWidth: 80, | ||
| 49 | + schemas: MqttSchemas, | ||
| 50 | + actionColOptions: { | ||
| 51 | + span: 14, | ||
| 52 | + }, | ||
| 53 | + }); | ||
| 54 | + const setStepFieldsValueFunc = (v) => { | ||
| 55 | + setFieldsValue(v); | ||
| 56 | + setFieldsValue({ | ||
| 57 | + transportPayloadType: v?.transportPayloadTypeConfiguration?.transportPayloadType, | ||
| 58 | + deviceTelemetryProtoSchema: | ||
| 59 | + v?.transportPayloadTypeConfiguration?.deviceTelemetryProtoSchema, | ||
| 60 | + deviceAttributesProtoSchema: | ||
| 61 | + v?.transportPayloadTypeConfiguration?.deviceAttributesProtoSchema, | ||
| 62 | + deviceRpcRequestProtoSchema: | ||
| 63 | + v?.transportPayloadTypeConfiguration?.deviceRpcRequestProtoSchema, | ||
| 64 | + deviceRpcResponseProtoSchema: | ||
| 65 | + v?.transportPayloadTypeConfiguration?.deviceRpcResponseProtoSchema, | ||
| 66 | + enableCompatibilityWithJsonPayloadFormat: | ||
| 67 | + v?.transportPayloadTypeConfiguration?.enableCompatibilityWithJsonPayloadFormat, | ||
| 68 | + useJsonPayloadFormatForDefaultDownlinkTopics: | ||
| 69 | + v?.transportPayloadTypeConfiguration?.useJsonPayloadFormatForDefaultDownlinkTopics, | ||
| 70 | + }); | ||
| 71 | + }; | ||
| 72 | + const customClearStepTwoValueFunc = () => { | ||
| 73 | + resetFields(); | ||
| 74 | + }; | ||
| 75 | + async function customResetFunc() { | ||
| 76 | + emit('prev'); | ||
| 77 | + } | ||
| 78 | + const getDataFunc = async () => { | ||
| 79 | + let val = await validate(); | ||
| 80 | + if (!val) return; | ||
| 81 | + delete val.desc; | ||
| 82 | + transportMqttData.transportPayloadTypeConfiguration.transportPayloadType = | ||
| 83 | + val.transportPayloadType; | ||
| 84 | + transportMqttData.transportPayloadTypeConfiguration.enableCompatibilityWithJsonPayloadFormat = | ||
| 85 | + val.enableCompatibilityWithJsonPayloadFormat; | ||
| 86 | + transportMqttData.transportPayloadTypeConfiguration.useJsonPayloadFormatForDefaultDownlinkTopics = | ||
| 87 | + val.useJsonPayloadFormatForDefaultDownlinkTopics; | ||
| 88 | + transportMqttData.transportPayloadTypeConfiguration.deviceAttributesProtoSchema = | ||
| 89 | + val.deviceAttributesProtoSchema; | ||
| 90 | + transportMqttData.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema = | ||
| 91 | + val.deviceRpcRequestProtoSchema; | ||
| 92 | + transportMqttData.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema = | ||
| 93 | + val.deviceRpcResponseProtoSchema; | ||
| 94 | + transportMqttData.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema = | ||
| 95 | + val.deviceTelemetryProtoSchema; | ||
| 96 | + allMqttData = { | ||
| 97 | + ...val, | ||
| 98 | + ...transportMqttData, | ||
| 99 | + }; | ||
| 100 | + delete allMqttData.deviceTelemetryProtoSchema; | ||
| 101 | + delete allMqttData.deviceAttributesProtoSchema; | ||
| 102 | + delete allMqttData.deviceRpcRequestProtoSchema; | ||
| 103 | + delete allMqttData.deviceRpcResponseProtoSchema; | ||
| 104 | + delete allMqttData.useJsonPayloadFormatForDefaultDownlinkTopics; | ||
| 105 | + delete allMqttData.enableCompatibilityWithJsonPayloadFormat; | ||
| 106 | + delete allMqttData.transportPayloadType; | ||
| 107 | + return allMqttData; | ||
| 108 | + }; | ||
| 109 | + return { | ||
| 110 | + customResetFunc, | ||
| 111 | + register, | ||
| 112 | + customClearStepTwoValueFunc, | ||
| 113 | + getDataFunc, | ||
| 114 | + setStepFieldsValueFunc, | ||
| 115 | + }; | ||
| 116 | + }, | ||
| 117 | + }); | ||
| 118 | +</script> | ||
| 119 | +<style lang="less" scoped></style> | 
| 1 | import { FormSchema } from '/@/components/Form'; | 1 | import { FormSchema } from '/@/components/Form'; | 
| 2 | import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; | 2 | import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi'; | 
| 3 | import { findDictItemByCode } from '/@/api/system/dict'; | 3 | import { findDictItemByCode } from '/@/api/system/dict'; | 
| 4 | - | ||
| 5 | -enum EnumMQTT { | ||
| 6 | - IS_DEFAULT = 'DEFAULT', | ||
| 7 | - IS_MQTT = 'MQTT', | ||
| 8 | - IS_PROTOBUF = 'PROTOBUF', | ||
| 9 | - IS_COAP = 'COAP', | ||
| 10 | - IS_LWM2M = 'LWM2M', | ||
| 11 | - IS_SNMP = 'SNMP', | ||
| 12 | - IS_PSM = 'PSM', | ||
| 13 | - IS_DRX = 'E_DRX', | ||
| 14 | - IS_EFENTO_NBIOT = 'EFENTO', | ||
| 15 | -} | ||
| 16 | - | ||
| 17 | -const isMqtt = (type: string) => { | ||
| 18 | - return type === EnumMQTT.IS_MQTT; | ||
| 19 | -}; | ||
| 20 | -const isProtobuf = (type: string) => { | ||
| 21 | - return type === EnumMQTT.IS_PROTOBUF; | ||
| 22 | -}; | ||
| 23 | - | ||
| 24 | -const isNBIOt = (type: string) => { | ||
| 25 | - return type === EnumMQTT.IS_COAP; | ||
| 26 | -}; | ||
| 27 | - | ||
| 28 | -const isPsm = (type: string) => { | ||
| 29 | - return type === EnumMQTT.IS_PSM; | ||
| 30 | -}; | ||
| 31 | - | ||
| 32 | -const isDrx = (type: string) => { | ||
| 33 | - return type === EnumMQTT.IS_DRX; | ||
| 34 | -}; | ||
| 35 | - | ||
| 36 | -const isEfentoNb = (type: string) => { | ||
| 37 | - return type === EnumMQTT.IS_EFENTO_NBIOT; | ||
| 38 | -}; | 4 | +import { ref } from 'vue'; | 
| 39 | 5 | ||
| 40 | export const step1Schemas: FormSchema[] = [ | 6 | export const step1Schemas: FormSchema[] = [ | 
| 41 | { | 7 | { | 
| @@ -100,6 +66,7 @@ export const step1Schemas: FormSchema[] = [ | @@ -100,6 +66,7 @@ export const step1Schemas: FormSchema[] = [ | ||
| 100 | }, | 66 | }, | 
| 101 | ]; | 67 | ]; | 
| 102 | 68 | ||
| 69 | +export const isChangeType = ref(''); | ||
| 103 | export const step2Schemas: FormSchema[] = [ | 70 | export const step2Schemas: FormSchema[] = [ | 
| 104 | { | 71 | { | 
| 105 | field: 'transportType', | 72 | field: 'transportType', | 
| @@ -112,304 +79,10 @@ export const step2Schemas: FormSchema[] = [ | @@ -112,304 +79,10 @@ export const step2Schemas: FormSchema[] = [ | ||
| 112 | { label: 'MQTT', value: 'MQTT' }, | 79 | { label: 'MQTT', value: 'MQTT' }, | 
| 113 | { label: 'CoAP', value: 'COAP' }, | 80 | { label: 'CoAP', value: 'COAP' }, | 
| 114 | ], | 81 | ], | 
| 115 | - }, | ||
| 116 | - colProps: { span: 11 }, | ||
| 117 | - }, | ||
| 118 | - { | ||
| 119 | - field: 'deviceTelemetryTopic', | ||
| 120 | - component: 'Input', | ||
| 121 | - label: '筛选器', | ||
| 122 | - required: true, | ||
| 123 | - defaultValue: 'v1/devices/me/telemetry', | ||
| 124 | - componentProps: { | ||
| 125 | - placeholder: '请输入遥测数据 topic 筛选器', | ||
| 126 | - }, | ||
| 127 | - colProps: { span: 11 }, | ||
| 128 | - ifShow: ({ values }) => isMqtt(values.transportType), | ||
| 129 | - }, | ||
| 130 | - { | ||
| 131 | - field: 'deviceAttributesTopic', | ||
| 132 | - component: 'Input', | ||
| 133 | - required: true, | ||
| 134 | - label: 'topic filter', | ||
| 135 | - defaultValue: 'v1/devices/me/attributes', | ||
| 136 | - componentProps: { | ||
| 137 | - placeholder: '请输入Attributes topic 筛选器', | ||
| 138 | - }, | ||
| 139 | - colProps: { span: 11 }, | ||
| 140 | - ifShow: ({ values }) => isMqtt(values.transportType), | ||
| 141 | - }, | ||
| 142 | - { | ||
| 143 | - field: 'desc', | ||
| 144 | - component: 'InputTextArea', | ||
| 145 | - label: '描述', | ||
| 146 | - defaultValue: `支持单[+]和多级[#]通配符。[+] is suitable for any topic filter level。例如:v1/devices/+/telemetry or +/devices/+/attributes。[#]可以替换 topic filter 本身,并且必须是 topic 的最后一个符号。例如:# or v1/devices/me/#。 | ||
| 147 | - `, | ||
| 148 | - componentProps: { | ||
| 149 | - autoSize: { | ||
| 150 | - maxRows: 10, | 82 | + onChange(e) { | 
| 83 | + isChangeType.value = e; | ||
| 151 | }, | 84 | }, | 
| 152 | - placeholder: '请输入Attributes topic 筛选器', | ||
| 153 | - }, | ||
| 154 | - colProps: { span: 24 }, | ||
| 155 | - ifShow: ({ values }) => isMqtt(values.transportType), | ||
| 156 | - }, | ||
| 157 | - { | ||
| 158 | - field: 'transportPayloadType', | ||
| 159 | - component: 'Select', | ||
| 160 | - label: '设备Payload', | ||
| 161 | - defaultValue: 'JSON', | ||
| 162 | - componentProps: { | ||
| 163 | - options: [ | ||
| 164 | - { label: 'JSON', value: 'JSON' }, | ||
| 165 | - { label: 'PROTOBUF', value: 'PROTOBUF' }, | ||
| 166 | - ], | ||
| 167 | - }, | ||
| 168 | - colProps: { span: 11 }, | ||
| 169 | - ifShow: ({ values }) => isMqtt(values.transportType), | ||
| 170 | - }, | ||
| 171 | - { | ||
| 172 | - field: 'useJsonPayloadFormatForDefaultDownlinkTopics', | ||
| 173 | - label: '', | ||
| 174 | - colProps: { span: 14 }, | ||
| 175 | - defaultValue: false, | ||
| 176 | - component: 'Checkbox', | ||
| 177 | - renderComponentContent: `启用后,平台将默认使用Protobuf有效载荷格式。如果解析失败,平台将尝试使用JSON有效负载格式。用于固件更新期间的向后兼容性。例如,固件的初始版本使用Json,而新版本使用Protobuf。在设备组的固件更新过程中,需要同时支持Protobuf和JSON。兼容性模式会导致性能轻微下降,因此建议在所有设备更新后禁用此模式。`, | ||
| 178 | - ifShow: ({ values }) => | ||
| 179 | - isProtobuf(values.transportPayloadType) && !isNBIOt(values.transportType), | ||
| 180 | - }, | ||
| 181 | - { | ||
| 182 | - field: 'enableCompatibilityWithJsonPayloadFormat', | ||
| 183 | - label: '', | ||
| 184 | - colProps: { span: 14 }, | ||
| 185 | - defaultValue: false, | ||
| 186 | - component: 'Checkbox', | ||
| 187 | - renderComponentContent: `启用后,平台将使用Json有效负载格式通过以下主题推送属性和RPC:v1/devices/me/attributes/response/$request_id、v1/devices/me/attributes、v1/devices/me/RPC/request/$request_id、,v1/devices/me/rpc/response/$request id。此设置不影响使用新(v2)主题发送的属性和rpc订阅:v2/a/res/$request id、v2/a、v2/r/req/$request id、v2/r/res/$request id。其中,$request id是整数请求标识符。`, | ||
| 188 | - ifShow: ({ values }) => | ||
| 189 | - isProtobuf(values.transportPayloadType) && | ||
| 190 | - !!values.useJsonPayloadFormatForDefaultDownlinkTopics && | ||
| 191 | - !isNBIOt(values.transportType), | ||
| 192 | - }, | ||
| 193 | - { | ||
| 194 | - field: 'coapDeviceType', | ||
| 195 | - component: 'Select', | ||
| 196 | - label: 'CoAP类型', | ||
| 197 | - defaultValue: 'DEFAULT', | ||
| 198 | - componentProps: { | ||
| 199 | - options: [ | ||
| 200 | - { label: '默认', value: 'DEFAULT' }, | ||
| 201 | - { label: 'Efento NB-IoT', value: 'EFENTO' }, | ||
| 202 | - ], | ||
| 203 | - }, | ||
| 204 | - colProps: { span: 11 }, | ||
| 205 | - ifShow: ({ values }) => isNBIOt(values.transportType), | ||
| 206 | - }, | ||
| 207 | - { | ||
| 208 | - field: 'transportPayloadType', | ||
| 209 | - component: 'Select', | ||
| 210 | - label: 'Payload', | ||
| 211 | - defaultValue: 'JSON', | ||
| 212 | - componentProps: { | ||
| 213 | - options: [ | ||
| 214 | - { label: 'JSON', value: 'JSON' }, | ||
| 215 | - { label: 'PROTOBUF', value: 'PROTOBUF' }, | ||
| 216 | - ], | ||
| 217 | - }, | ||
| 218 | - colProps: { span: 11 }, | ||
| 219 | - ifShow: ({ values }) => isNBIOt(values.transportType) && !isEfentoNb(values.coapDeviceType), | ||
| 220 | - }, | ||
| 221 | - { | ||
| 222 | - field: 'powerMode', | ||
| 223 | - component: 'Select', | ||
| 224 | - label: 'Power Mode', | ||
| 225 | - defaultValue: 'DRX', | ||
| 226 | - componentProps: { | ||
| 227 | - options: [ | ||
| 228 | - { label: 'Power Saving Mode', value: 'PSM' }, | ||
| 229 | - { label: 'Discontinuous Reception', value: 'DRX' }, | ||
| 230 | - { | ||
| 231 | - label: 'Extended Discontinuous Reception', | ||
| 232 | - value: 'E_DRX', | ||
| 233 | - }, | ||
| 234 | - ], | ||
| 235 | - }, | ||
| 236 | - colProps: { span: 11 }, | ||
| 237 | - ifShow: ({ values }) => isNBIOt(values.transportType), | ||
| 238 | - }, | ||
| 239 | - { | ||
| 240 | - field: 'psmActivityTimer', | ||
| 241 | - component: 'InputNumber', | ||
| 242 | - label: 'Timer', | ||
| 243 | - required: true, | ||
| 244 | - defaultValue: '10', | ||
| 245 | - componentProps: { | ||
| 246 | - placeholder: '请输入PSM Activity Timer', | ||
| 247 | - }, | ||
| 248 | - colProps: { span: 11 }, | ||
| 249 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isPsm(values.powerMode), | ||
| 250 | - }, | ||
| 251 | - { | ||
| 252 | - field: 'unit', | ||
| 253 | - component: 'Select', | ||
| 254 | - label: '时间单位', | ||
| 255 | - defaultValue: 'second', | ||
| 256 | - componentProps: { | ||
| 257 | - options: [ | ||
| 258 | - { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 259 | - { label: '秒', value: 'second' }, | ||
| 260 | - { label: '分钟', value: 'minute' }, | ||
| 261 | - { label: '小时', value: 'hour' }, | ||
| 262 | - ], | ||
| 263 | - }, | ||
| 264 | - colProps: { span: 11 }, | ||
| 265 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isPsm(values.powerMode), | ||
| 266 | - }, | ||
| 267 | - { | ||
| 268 | - field: 'edrxCycle', | ||
| 269 | - component: 'InputNumber', | ||
| 270 | - label: 'eDRX cycle', | ||
| 271 | - required: true, | ||
| 272 | - defaultValue: '81', | ||
| 273 | - componentProps: { | ||
| 274 | - placeholder: '请输入PSM Activity Timer', | ||
| 275 | - }, | ||
| 276 | - colProps: { span: 11 }, | ||
| 277 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isDrx(values.powerMode), | ||
| 278 | - }, | ||
| 279 | - { | ||
| 280 | - field: 'unit', | ||
| 281 | - component: 'Select', | ||
| 282 | - label: '时间单位', | ||
| 283 | - defaultValue: 'second', | ||
| 284 | - componentProps: { | ||
| 285 | - options: [ | ||
| 286 | - { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 287 | - { label: '秒', value: 'second' }, | ||
| 288 | - { label: '分钟', value: 'minute' }, | ||
| 289 | - { label: '小时', value: 'hour' }, | ||
| 290 | - ], | ||
| 291 | - }, | ||
| 292 | - colProps: { span: 11 }, | ||
| 293 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isDrx(values.powerMode), | ||
| 294 | - }, | ||
| 295 | - { | ||
| 296 | - field: 'pagingTransmissionWindow', | ||
| 297 | - component: 'InputNumber', | ||
| 298 | - label: 'Paging', | ||
| 299 | - required: true, | ||
| 300 | - defaultValue: '10', | ||
| 301 | - componentProps: { | ||
| 302 | - placeholder: '请输入Paging Transmission Window', | ||
| 303 | - }, | ||
| 304 | - colProps: { span: 11 }, | ||
| 305 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isDrx(values.powerMode), | ||
| 306 | - }, | ||
| 307 | - { | ||
| 308 | - field: 'unit', | ||
| 309 | - component: 'Select', | ||
| 310 | - label: '时间单位', | ||
| 311 | - defaultValue: 'second', | ||
| 312 | - componentProps: { | ||
| 313 | - options: [ | ||
| 314 | - { label: 'Milliseconds', value: 'Milliseconds' }, | ||
| 315 | - { label: '秒', value: 'second' }, | ||
| 316 | - { label: '分钟', value: 'minute' }, | ||
| 317 | - { label: '小时', value: 'hour' }, | ||
| 318 | - ], | ||
| 319 | }, | 85 | }, | 
| 320 | colProps: { span: 11 }, | 86 | colProps: { span: 11 }, | 
| 321 | - ifShow: ({ values }) => isNBIOt(values.transportType) && isDrx(values.powerMode), | ||
| 322 | - }, | ||
| 323 | - { | ||
| 324 | - field: 'deviceTelemetryProtoSchema', | ||
| 325 | - label: '遥测数据', | ||
| 326 | - colProps: { span: 22 }, | ||
| 327 | - component: 'InputTextArea', | ||
| 328 | - componentProps: { | ||
| 329 | - autoSize: { | ||
| 330 | - maxRows: 10, | ||
| 331 | - }, | ||
| 332 | - }, | ||
| 333 | - defaultValue: ` | ||
| 334 | - syntax ="proto3"; | ||
| 335 | - package telemetry; | ||
| 336 | - | ||
| 337 | - message SensorDataReading { | ||
| 338 | - optional double temperature = 1; | ||
| 339 | - optional double humidity = 2; | ||
| 340 | - InnerObject innerObject = 3; | ||
| 341 | - message InnerObject { | ||
| 342 | - optional string key1 = 1; | ||
| 343 | - optional bool key2 = 2; | ||
| 344 | - optional double key3 = 3; | ||
| 345 | - optional int32 key4 = 4; | ||
| 346 | - optional string key5 = 5; | ||
| 347 | - } | ||
| 348 | - } | ||
| 349 | - `, | ||
| 350 | - ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 351 | - }, | ||
| 352 | - { | ||
| 353 | - field: 'deviceAttributesProtoSchema', | ||
| 354 | - label: 'Attributes', | ||
| 355 | - colProps: { span: 22 }, | ||
| 356 | - component: 'InputTextArea', | ||
| 357 | - componentProps: { | ||
| 358 | - autoSize: { | ||
| 359 | - maxRows: 10, | ||
| 360 | - }, | ||
| 361 | - }, | ||
| 362 | - defaultValue: ` | ||
| 363 | - syntax ="proto3"; | ||
| 364 | - package attributes; | ||
| 365 | - | ||
| 366 | - message SensorConfiguration { | ||
| 367 | - optional string firmwareVersion = 1; | ||
| 368 | - optional string serialNumber = 2; | ||
| 369 | - } | ||
| 370 | - `, | ||
| 371 | - ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 372 | - }, | ||
| 373 | - { | ||
| 374 | - field: 'deviceRpcRequestProtoSchema', | ||
| 375 | - label: 'RPC 请求 ', | ||
| 376 | - colProps: { span: 22 }, | ||
| 377 | - component: 'InputTextArea', | ||
| 378 | - componentProps: { | ||
| 379 | - autoSize: { | ||
| 380 | - maxRows: 10, | ||
| 381 | - }, | ||
| 382 | - }, | ||
| 383 | - defaultValue: ` | ||
| 384 | - syntax ="proto3"; | ||
| 385 | - package rpc; | ||
| 386 | - | ||
| 387 | - message RpcRequestMsg { | ||
| 388 | - optional string method = 1; | ||
| 389 | - optional int32 requestId = 2; | ||
| 390 | - optional string params = 3; | ||
| 391 | - } | ||
| 392 | - `, | ||
| 393 | - ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 394 | - }, | ||
| 395 | - { | ||
| 396 | - field: 'deviceRpcResponseProtoSchema', | ||
| 397 | - label: 'RPC 响应', | ||
| 398 | - colProps: { span: 22 }, | ||
| 399 | - component: 'InputTextArea', | ||
| 400 | - componentProps: { | ||
| 401 | - autoSize: { | ||
| 402 | - maxRows: 10, | ||
| 403 | - }, | ||
| 404 | - }, | ||
| 405 | - defaultValue: ` | ||
| 406 | - syntax ="proto3"; | ||
| 407 | - package rpc; | ||
| 408 | - | ||
| 409 | - message RpcResponseMsg { | ||
| 410 | - optional string payload = 1; | ||
| 411 | - } | ||
| 412 | - `, | ||
| 413 | - ifShow: ({ values }) => isProtobuf(values.transportPayloadType), | ||
| 414 | }, | 87 | }, | 
| 415 | ]; | 88 | ]; |