Commit 660727b48dacc7fb23725e06263a5e58e551f6cb

Authored by fengtao
1 parent e01b08be

feat:新增告警配置功能,refractor:重构设备配值第二步,feat:新增设备列表跳转设备配置分页查询

  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;
... ...
  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>
... ...
  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 +];
... ...
  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 133 }
134 134 current.value++;
135 135 if (isUpdate.value == 2) {
136   - proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc(
137   - editData.value?.profileData.transportConfiguration
138   - );
  136 + proxy.$refs.DeviceProfileStep2Ref?.setStepTwoFieldsValueFunc(editData.value);
139 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 141 const handleSubmit = async () => {
... ...
... ... @@ -19,7 +19,7 @@
19 19 <TableAction
20 20 :actions="[
21 21 {
22   - label: '设置默认',
  22 + label: '设置默认',
23 23 icon: 'ant-design:profile-outlined',
24 24 onClick: handleSetDefault.bind(null, record),
25 25 ifShow: () => {
... ... @@ -62,7 +62,7 @@
62 62 </div>
63 63 </template>
64 64 <script lang="ts">
65   - import { defineComponent, ref, reactive } from 'vue';
  65 + import { defineComponent, ref, reactive, nextTick, onUnmounted } from 'vue';
66 66 import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table';
67 67 import { columns, searchFormSchema } from './device.profile.data';
68 68 import { useMessage } from '/@/hooks/web/useMessage';
... ... @@ -85,11 +85,12 @@
85 85 const getPathUrl = ref('');
86 86 const getPathUrlName = ref('');
87 87 const disabled = ref(true);
  88 + const onCloseVal = ref(0);
88 89
89 90 const { createMessage } = useMessage();
90 91 const [registerModal, { openModal }] = useModal();
91 92 const [registerModalDetail] = useModal();
92   - const [registerTable, { reload, getSelectRowKeys }] = useTable({
  93 + const [registerTable, { reload, getSelectRowKeys, setTableData, getForm }] = useTable({
93 94 title: '设备配置列表',
94 95 clickToRowSelect: false,
95 96 api: deviceConfigGetQuery,
... ... @@ -131,12 +132,33 @@
131 132 const getName = getParam(getPathUrl.value, name);
132 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 162 const tableListRef = ref<
141 163 {
142 164 title: string;
... ... @@ -263,7 +285,6 @@
263 285 handleSetDefault,
264 286 disabled,
265 287 deviceDetailRef,
266   - // setRowClassName,
267 288 registerModalDetail,
268 289 // register1,
269 290 // defaultHeader,
... ...
1 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 26 </div>
23 27 </div>
24 28 </div>
25 29 </div>
26 30 </template>
27 31 <script lang="ts">
28   - import { defineComponent, reactive } from 'vue';
  32 + import { defineComponent, watch, reactive, ref, getCurrentInstance } from 'vue';
29 33 import { BasicForm, useForm } from '/@/components/Form';
30   - import { step2Schemas } from './data';
  34 + import { step2Schemas, isChangeType } from './data';
31 35 import { Alert, Divider, Descriptions } from 'ant-design-vue';
32 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 40 export default defineComponent({
35 41 components: {
... ... @@ -39,36 +45,19 @@
39 45 [Descriptions.name]: Descriptions,
40 46 [Descriptions.Item.name]: Descriptions.Item,
41 47 Button,
  48 + MqttCpns,
  49 + CoapCpns,
42 50 },
43 51 emits: ['next', 'prev', 'register'],
44 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 61 labelWidth: 80,
73 62 schemas: step2Schemas,
74 63 actionColOptions: {
... ... @@ -76,69 +65,35 @@
76 65 },
77 66 });
78 67 const setStepTwoFieldsValueFunc = (v) => {
79   - console.log(v);
80 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 77 const customClearStepTwoValueFunc = () => {
  78 + isMqttType.value = 'other';
107 79 resetFields();
108 80 };
109 81 async function customResetFunc() {
110 82 emit('prev');
111 83 }
  84 + watch(isChangeType, async (v) => {
  85 + isMqttType.value = v;
  86 + });
112 87 const getStep2DataFunc = async () => {
113 88 const val = await validate();
114 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 98 return {
144 99 customResetFunc,
... ... @@ -146,21 +101,19 @@
146 101 setStepTwoFieldsValueFunc,
147 102 customClearStepTwoValueFunc,
148 103 getStep2DataFunc,
  104 + isMqttType,
  105 + mqttRef,
  106 + coapRef,
149 107 };
150 108 },
151 109 });
152 110 </script>
153 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 117 ::-webkit-scrollbar {
165 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 1 import { FormSchema } from '/@/components/Form';
2 2 import { deviceConfigGetRuleChain } from '/@/api/device/deviceConfigApi';
3 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 6 export const step1Schemas: FormSchema[] = [
41 7 {
... ... @@ -100,6 +66,7 @@ export const step1Schemas: FormSchema[] = [
100 66 },
101 67 ];
102 68
  69 +export const isChangeType = ref('');
103 70 export const step2Schemas: FormSchema[] = [
104 71 {
105 72 field: 'transportType',
... ... @@ -112,304 +79,10 @@ export const step2Schemas: FormSchema[] = [
112 79 { label: 'MQTT', value: 'MQTT' },
113 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 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 ];
... ...