Commit 122b41a07227ca3ab1fc2897fb2d61777c9bc060

Authored by ww
1 parent f471ce6c

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

@@ -3,24 +3,32 @@ import { Rule } from '/@/components/Form'; @@ -3,24 +3,32 @@ import { Rule } from '/@/components/Form';
3 export { default as JSONEditor } from './index.vue'; 3 export { default as JSONEditor } from './index.vue';
4 4
5 export const parseStringToJSON = <T = Recordable>(value: string) => { 5 export const parseStringToJSON = <T = Recordable>(value: string) => {
  6 + let valid = false;
6 try { 7 try {
7 const json = JSON.parse(value) as T; 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 } catch (error) { 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 return [ 21 return [
16 { 22 {
17 validateTrigger: 'blur', 23 validateTrigger: 'blur',
18 validator(_rule: Rule, value: any, _callback: Fn) { 24 validator(_rule: Rule, value: any, _callback: Fn) {
19 - const { valid } = parseStringToJSON(value); 25 + const { valid, json } = parseStringToJSON(value);
20 if (valid) { 26 if (valid) {
  27 + if (noEmpty && json && !Object.keys(json).length) return Promise.reject(emptyMessage);
21 return Promise.resolve(); 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,6 +18,7 @@
18 defineProps<{ 18 defineProps<{
19 value?: string; 19 value?: string;
20 options?: JSONEditorOptions; 20 options?: JSONEditorOptions;
  21 + height?: number;
21 }>(), 22 }>(),
22 { 23 {
23 options: () => 24 options: () =>
@@ -26,6 +27,7 @@ @@ -26,6 +27,7 @@
26 mainMenuBar: false, 27 mainMenuBar: false,
27 statusBar: false, 28 statusBar: false,
28 } as JSONEditorOptions), 29 } as JSONEditorOptions),
  30 + height: 150,
29 } 31 }
30 ); 32 );
31 33
@@ -106,7 +108,7 @@ @@ -106,7 +108,7 @@
106 </script> 108 </script>
107 109
108 <template> 110 <template>
109 - <div class="p-2 bg-gray-200"> 111 + <div class="p-2 bg-gray-200" :style="{ height: `${height - 16}px` }">
110 <div ref="jsonEditorElRef" class="jsoneditor"></div> 112 <div ref="jsonEditorElRef" class="jsoneditor"></div>
111 </div> 113 </div>
112 </template> 114 </template>
1 -import { FormSchema } from '/@/components/Form'; 1 +import { FormSchema, useComponentRegister } from '/@/components/Form';
2 import { findDictItemByCode } from '/@/api/system/dict'; 2 import { findDictItemByCode } from '/@/api/system/dict';
3 import { deviceProfile, getGatewayDevice } from '/@/api/device/deviceManager'; 3 import { deviceProfile, getGatewayDevice } from '/@/api/device/deviceManager';
4 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel'; 4 import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
5 import { TransportTypeEnum } from '../../profiles/components/TransportDescript/const'; 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 export enum TypeEnum { 10 export enum TypeEnum {
8 IS_GATEWAY = 'GATEWAY', 11 IS_GATEWAY = 'GATEWAY',
@@ -762,6 +765,7 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] = @@ -762,6 +765,7 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] =
762 minRows: 6, 765 minRows: 6,
763 }, 766 },
764 }, 767 },
  768 + colProps: { span: 20 },
765 dynamicRules: () => { 769 dynamicRules: () => {
766 return [ 770 return [
767 { 771 {
@@ -781,11 +785,17 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] = @@ -781,11 +785,17 @@ export const CommandSchemas = (transportType: TransportTypeEnum): FormSchema[] =
781 { 785 {
782 field: 'commandValue', 786 field: 'commandValue',
783 label: '请输入命令内容', 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 return model['valueType'] === 'json'; 794 return model['valueType'] === 'json';
788 }, 795 },
  796 + componentProps: {
  797 + height: 250,
  798 + },
789 }, 799 },
790 ]; 800 ];
791 }; 801 };
1 <template> 1 <template>
2 <div class="tabs-detail"> 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 <Button type="default" @click="handleCancel" class="mr-2">重置</Button> 7 <Button type="default" @click="handleCancel" class="mr-2">重置</Button>
18 </Space> 8 </Space>
19 </div> 9 </div>
20 </div> 10 </div>
21 </template> 11 </template>
22 <script lang="ts"> 12 <script lang="ts">
23 - import { defineComponent, ref, onMounted, unref, nextTick } from 'vue'; 13 + import { defineComponent, ref } from 'vue';
24 import { BasicForm, useForm } from '/@/components/Form'; 14 import { BasicForm, useForm } from '/@/components/Form';
25 import { CommandSchemas } from '../../config/data'; 15 import { CommandSchemas } from '../../config/data';
26 import { commandIssuanceApi } from '/@/api/device/deviceManager'; 16 import { commandIssuanceApi } from '/@/api/device/deviceManager';
27 import { useMessage } from '/@/hooks/web/useMessage'; 17 import { useMessage } from '/@/hooks/web/useMessage';
28 import { Button } from '/@/components/Button'; 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 import { DeviceRecord } from '/@/api/device/model/deviceModel'; 20 import { DeviceRecord } from '/@/api/device/model/deviceModel';
34 import { TransportTypeEnum } from '../../../profiles/components/TransportDescript/const'; 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 export default defineComponent({ 24 export default defineComponent({
45 - components: { BasicForm, Button, QuestionCircleOutlined, Tooltip, Space }, 25 + components: { BasicForm, Button, Space },
46 props: { 26 props: {
47 deviceDetail: { 27 deviceDetail: {
48 type: Object as PropType<DeviceRecord>, 28 type: Object as PropType<DeviceRecord>,
@@ -52,8 +32,7 @@ @@ -52,8 +32,7 @@
52 emits: ['register'], 32 emits: ['register'],
53 setup(props) { 33 setup(props) {
54 const { createMessage } = useMessage(); 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 const [registerForm, { getFieldsValue, validate, resetFields }] = useForm({ 37 const [registerForm, { getFieldsValue, validate, resetFields }] = useForm({
59 labelWidth: 120, 38 labelWidth: 120,
@@ -63,78 +42,35 @@ @@ -63,78 +42,35 @@
63 labelAlign: 'right', 42 labelAlign: 'right',
64 showSubmitButton: false, 43 showSubmitButton: false,
65 showResetButton: false, 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 const handleCancel = () => { 47 const handleCancel = () => {
92 resetFields(); 48 resetFields();
93 - unref(jsonInstance).set({});  
94 }; 49 };
  50 +
95 const handleOk = async () => { 51 const handleOk = async () => {
96 - disable.value = true; 52 + loading.value = true;
97 try { 53 try {
98 // 验证 54 // 验证
99 const valid = await validate(); 55 const valid = await validate();
100 if (!valid) return; 56 if (!valid) return;
101 // 收集表单数据 57 // 收集表单数据
102 const field = getFieldsValue(); 58 const field = getFieldsValue();
103 - let passStatus = false; 59 + let command = {
  60 + persistent: true,
  61 + method: 'methodThingskit',
  62 + params: field.commandText,
  63 + };
104 if (field.valueType === 'json') { 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 .then((res) => { 70 .then((res) => {
135 if (!res) return; 71 if (!res) return;
136 createMessage.success('命令下发成功'); 72 createMessage.success('命令下发成功');
137 - disable.value = true; 73 + loading.value = true;
138 // 请求 74 // 请求
139 handleCancel(); 75 handleCancel();
140 }) 76 })
@@ -146,25 +82,20 @@ @@ -146,25 +82,20 @@
146 }) 82 })
147 .finally(() => { 83 .finally(() => {
148 setTimeout(() => { 84 setTimeout(() => {
149 - disable.value = false; 85 + loading.value = false;
150 }, 300); 86 }, 300);
151 }); 87 });
152 } catch (e) { 88 } catch (e) {
  89 + throw e;
153 } finally { 90 } finally {
154 - //这里捕获json插件的错误  
155 - disable.value = false; 91 + loading.value = false;
156 } 92 }
157 }; 93 };
158 return { 94 return {
159 registerForm, 95 registerForm,
160 handleCancel, 96 handleCancel,
161 handleOk, 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,11 +21,11 @@
21 21
22 <BasicModal 22 <BasicModal
23 @register="registerCommandIssuanceModal" 23 @register="registerCommandIssuanceModal"
24 - width="600px" 24 + width="700px"
25 title="命令下发" 25 title="命令下发"
26 :showOkBtn="false" 26 :showOkBtn="false"
27 cancelText="关闭" 27 cancelText="关闭"
28 - :footer="h('div')" 28 + :footer="null"
29 > 29 >
30 <CommandIssuance :deviceDetail="deviceDetail" /> 30 <CommandIssuance :deviceDetail="deviceDetail" />
31 </BasicModal> 31 </BasicModal>