Commit 122b41a07227ca3ab1fc2897fb2d61777c9bc060

Authored by ww
1 parent f471ce6c

perf: DEFECT-1219 优化命令下发界面

... ... @@ -3,24 +3,32 @@ import { Rule } from '/@/components/Form';
3 3 export { default as JSONEditor } from './index.vue';
4 4
5 5 export const parseStringToJSON = <T = Recordable>(value: string) => {
  6 + let valid = false;
6 7 try {
7 8 const json = JSON.parse(value) as T;
8   - return { json, valid: true };
  9 + typeof json === 'object' ? (valid = true) : (valid = false);
  10 + return { json, valid };
9 11 } catch (error) {
10   - return { json: null, valid: false };
  12 + return { json: null, valid };
11 13 }
12 14 };
13 15
14   -export const JSONEditorValidator = (message = 'json格式校验失败'): Rule[] => {
  16 +export const JSONEditorValidator = (
  17 + message = 'JSON格式校验失败',
  18 + noEmpty = false,
  19 + emptyMessage = 'JSON不能为空对象'
  20 +): Rule[] => {
15 21 return [
16 22 {
17 23 validateTrigger: 'blur',
18 24 validator(_rule: Rule, value: any, _callback: Fn) {
19   - const { valid } = parseStringToJSON(value);
  25 + const { valid, json } = parseStringToJSON(value);
20 26 if (valid) {
  27 + if (noEmpty && json && !Object.keys(json).length) return Promise.reject(emptyMessage);
21 28 return Promise.resolve();
  29 + } else {
  30 + return Promise.reject(message);
22 31 }
23   - return Promise.reject(message);
24 32 },
25 33 },
26 34 ];
... ...
... ... @@ -18,6 +18,7 @@
18 18 defineProps<{
19 19 value?: string;
20 20 options?: JSONEditorOptions;
  21 + height?: number;
21 22 }>(),
22 23 {
23 24 options: () =>
... ... @@ -26,6 +27,7 @@
26 27 mainMenuBar: false,
27 28 statusBar: false,
28 29 } as JSONEditorOptions),
  30 + height: 150,
29 31 }
30 32 );
31 33
... ... @@ -106,7 +108,7 @@
106 108 </script>
107 109
108 110 <template>
109   - <div class="p-2 bg-gray-200">
  111 + <div class="p-2 bg-gray-200" :style="{ height: `${height - 16}px` }">
110 112 <div ref="jsonEditorElRef" class="jsoneditor"></div>
111 113 </div>
112 114 </template>
... ...
1   -import { FormSchema } from '/@/components/Form';
  1 +import { FormSchema, useComponentRegister } from '/@/components/Form';
2 2 import { findDictItemByCode } from '/@/api/system/dict';
3 3 import { deviceProfile, getGatewayDevice } from '/@/api/device/deviceManager';
4 4 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
5 5 import { TransportTypeEnum } from '../../profiles/components/TransportDescript/const';
  6 +import { JSONEditorValidator } from '/@/components/CodeEditor/src/JSONEditor';
  7 +import { JSONEditor } from '/@/components/CodeEditor';
  8 +useComponentRegister('JSONEditor', JSONEditor);
6 9
7 10 export enum TypeEnum {
8 11 IS_GATEWAY = 'GATEWAY',
... ... @@ -762,6 +765,7 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] =
762 765 minRows: 6,
763 766 },
764 767 },
  768 + colProps: { span: 20 },
765 769 dynamicRules: () => {
766 770 return [
767 771 {
... ... @@ -781,11 +785,17 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] =
781 785 {
782 786 field: 'commandValue',
783 787 label: '请输入命令内容',
784   - slot: 'commandSlot',
785   - component: 'InputTextArea',
786   - show: ({ model }) => {
  788 + component: 'JSONEditor',
  789 + colProps: { span: 20 },
  790 + changeEvent: 'update:value',
  791 + valueField: 'value',
  792 + rules: [...JSONEditorValidator()],
  793 + ifShow: ({ model }) => {
787 794 return model['valueType'] === 'json';
788 795 },
  796 + componentProps: {
  797 + height: 250,
  798 + },
789 799 },
790 800 ];
791 801 };
... ...
1 1 <template>
2 2 <div class="tabs-detail">
3   - <div class="mt-4">
4   - <BasicForm @register="registerForm">
5   - <template #commandSlot>
6   - <div class="flex">
7   - <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
8   - <a-button style="margin: -5px 0" type="text" @click="handlePremitter">格式化</a-button>
9   - <Tooltip title='{"method":"methodThingskit","params":{"pin":7,"value":1}}' class="ml-2">
10   - <QuestionCircleOutlined style="font-size: 1rem" />
11   - </Tooltip>
12   - </div>
13   - </template>
14   - </BasicForm>
15   - <Space class="w-full justify-end" justify="end">
16   - <Button :disabled="disable" type="primary" @click="handleOk" class="mr-2">确定</Button>
  3 + <div>
  4 + <BasicForm @register="registerForm" />
  5 + <Space class="w-full justify-end py-2" justify="end">
  6 + <Button :loading="loading" type="primary" @click="handleOk" class="mr-2">确定</Button>
17 7 <Button type="default" @click="handleCancel" class="mr-2">重置</Button>
18 8 </Space>
19 9 </div>
20 10 </div>
21 11 </template>
22 12 <script lang="ts">
23   - import { defineComponent, ref, onMounted, unref, nextTick } from 'vue';
  13 + import { defineComponent, ref } from 'vue';
24 14 import { BasicForm, useForm } from '/@/components/Form';
25 15 import { CommandSchemas } from '../../config/data';
26 16 import { commandIssuanceApi } from '/@/api/device/deviceManager';
27 17 import { useMessage } from '/@/hooks/web/useMessage';
28 18 import { Button } from '/@/components/Button';
29   - import jsoneditor from 'jsoneditor';
30   - import 'jsoneditor/dist/jsoneditor.min.css';
31   - import { QuestionCircleOutlined } from '@ant-design/icons-vue';
32   - import { Space, Tooltip } from 'ant-design-vue';
  19 + import { Space } from 'ant-design-vue';
33 20 import { DeviceRecord } from '/@/api/device/model/deviceModel';
34 21 import { TransportTypeEnum } from '../../../profiles/components/TransportDescript/const';
35   -
36   - interface CommandParams {
37   - additionalInfo: Recordable;
38   - cmdType: string;
39   - method: string;
40   - params: string | Recordable;
41   - persistent: boolean;
42   - }
  22 + import { parseStringToJSON } from '/@/components/CodeEditor/src/JSONEditor';
43 23
44 24 export default defineComponent({
45   - components: { BasicForm, Button, QuestionCircleOutlined, Tooltip, Space },
  25 + components: { BasicForm, Button, Space },
46 26 props: {
47 27 deviceDetail: {
48 28 type: Object as PropType<DeviceRecord>,
... ... @@ -52,8 +32,7 @@
52 32 emits: ['register'],
53 33 setup(props) {
54 34 const { createMessage } = useMessage();
55   - const jsonData = ref<CommandParams>({} as unknown as CommandParams);
56   - const disable = ref(false);
  35 + const loading = ref(false);
57 36
58 37 const [registerForm, { getFieldsValue, validate, resetFields }] = useForm({
59 38 labelWidth: 120,
... ... @@ -63,78 +42,35 @@
63 42 labelAlign: 'right',
64 43 showSubmitButton: false,
65 44 showResetButton: false,
66   - wrapperCol: {
67   - span: 12,
68   - },
69 45 });
70   - // json 以及初始化JSON
71   - const jsoneditorRef = ref();
72   - const jsonValue = ref({});
73   - const jsonInstance = ref();
74   - onMounted(() => {
75   - nextTick(() => {
76   - let options = {
77   - mode: 'code',
78   - mainMenuBar: false,
79   - statusBar: false,
80   - };
81   - let editor = new jsoneditor(jsoneditorRef.value, options);
82   - editor.set(jsonValue.value);
83   - jsonInstance.value = editor;
84   - });
85   - });
86   - const handlePremitter = () => {
87   - const value = unref(jsonInstance).get();
88   - if (!value) return;
89   - return unref(jsonInstance).set(value);
90   - };
  46 +
91 47 const handleCancel = () => {
92 48 resetFields();
93   - unref(jsonInstance).set({});
94 49 };
  50 +
95 51 const handleOk = async () => {
96   - disable.value = true;
  52 + loading.value = true;
97 53 try {
98 54 // 验证
99 55 const valid = await validate();
100 56 if (!valid) return;
101 57 // 收集表单数据
102 58 const field = getFieldsValue();
103   - let passStatus = false;
  59 + let command = {
  60 + persistent: true,
  61 + method: 'methodThingskit',
  62 + params: field.commandText,
  63 + };
104 64 if (field.valueType === 'json') {
105   - const getJson = unref(jsonInstance).get();
106   - if (Object.prototype.isPrototypeOf(getJson) && Object.keys(getJson).length === 0) {
107   - createMessage.error('命令内容不能为空');
108   - passStatus = true;
109   - }
110   - if (getJson === '') {
111   - passStatus = true;
112   - createMessage.error('命令内容不能为空');
113   - }
114   - jsonData.value.params = getJson;
115   - } else {
116   - jsonData.value.params = field.commandText;
117   - if (!jsonData.value.params) {
118   - createMessage.error('命令内容不能为空');
119   - passStatus = true;
120   - }
121   - if (
122   - jsonData.value.params == '""' ||
123   - jsonData.value.params == "''" ||
124   - jsonData.value.params == '“”'
125   - ) {
126   - createMessage.error('命令内容不能为空');
127   - passStatus = true;
128   - }
  65 + const { json } = parseStringToJSON(field.commandValue);
  66 + command.params = json;
129 67 }
130   - jsonData.value.persistent = true;
131   - jsonData.value.method = 'methodThingskit';
132   - if (passStatus) return;
133   - commandIssuanceApi(field.commandType, props.deviceDetail.tbDeviceId, jsonData.value)
  68 +
  69 + commandIssuanceApi(field.commandType, props.deviceDetail.tbDeviceId, command)
134 70 .then((res) => {
135 71 if (!res) return;
136 72 createMessage.success('命令下发成功');
137   - disable.value = true;
  73 + loading.value = true;
138 74 // 请求
139 75 handleCancel();
140 76 })
... ... @@ -146,25 +82,20 @@
146 82 })
147 83 .finally(() => {
148 84 setTimeout(() => {
149   - disable.value = false;
  85 + loading.value = false;
150 86 }, 300);
151 87 });
152 88 } catch (e) {
  89 + throw e;
153 90 } finally {
154   - //这里捕获json插件的错误
155   - disable.value = false;
  91 + loading.value = false;
156 92 }
157 93 };
158 94 return {
159 95 registerForm,
160 96 handleCancel,
161 97 handleOk,
162   - disable,
163   - jsonData,
164   - jsoneditorRef,
165   - jsonValue,
166   - jsonInstance,
167   - handlePremitter,
  98 + loading,
168 99 };
169 100 },
170 101 });
... ...
... ... @@ -21,11 +21,11 @@
21 21
22 22 <BasicModal
23 23 @register="registerCommandIssuanceModal"
24   - width="600px"
  24 + width="700px"
25 25 title="命令下发"
26 26 :showOkBtn="false"
27 27 cancelText="关闭"
28   - :footer="h('div')"
  28 + :footer="null"
29 29 >
30 30 <CommandIssuance :deviceDetail="deviceDetail" />
31 31 </BasicModal>
... ...