Commit 1734df99a14d03a6280faa279694df156d1d75da

Authored by fengwotao
1 parent 2313d44c

pref: 优化公共接口管理部分代码

Showing 20 changed files with 725 additions and 854 deletions
  1 +@table-color: #e5e7eb;
  2 +
  3 +.table-border-color {
  4 + border: 1px solid #e5e7eb;
  5 + text-align: center;
  6 +}
  7 +
  8 +.table-content {
  9 + overflow-x: auto;
  10 +
  11 + table {
  12 + border-collapse: collapse;
  13 + width: 35vw;
  14 + &:extend(.table-border-color);
  15 + }
  16 +
  17 + table thead {
  18 + white-space: nowrap;
  19 + }
  20 +
  21 + table td {
  22 + padding: 5px;
  23 + white-space: nowrap;
  24 + &:extend(.table-border-color);
  25 + }
  26 +
  27 + table th {
  28 + padding: 5px;
  29 + &:extend(.table-border-color);
  30 + }
  31 +}
... ...
  1 +@table-color: #e5e7eb;
  2 +
  3 +.table-border-color {
  4 + border: 1px solid #e5e7eb;
  5 + text-align: center;
  6 +}
  7 +
  8 +.table-content {
  9 + table {
  10 + width: 31vw;
  11 + &:extend(.table-border-color);
  12 + }
  13 +
  14 + table td {
  15 + padding: 5px;
  16 + white-space: nowrap;
  17 + &:extend(.table-border-color);
  18 + }
  19 +
  20 + table th {
  21 + padding: 5px;
  22 + &:extend(.table-border-color);
  23 + }
  24 +}
... ...
  1 +<template>
  2 + <div class="flex flex-col justify-between">
  3 + <Tag v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT" color="blue" class="tag-text-top">
  4 + <span>function</span>&nbsp;&nbsp;filter(res)&nbsp;&nbsp;{
  5 + </Tag>
  6 + <div class="mt-2 mb-2" ref="aceRef"></div>
  7 + <Tag
  8 + v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT"
  9 + color="blue"
  10 + class="mt-2 tag-text-bottom"
  11 + >}</Tag
  12 + >
  13 + <div v-if="scriptType === OnlineEditorTypeEnum.JAVASCRIPT" class="ml-2 -mt-1.5">
  14 + <Button @click="onHandleFormatter" class="mt-8 -ml-2">
  15 + <template #icon>
  16 + <CopyOutlined />
  17 + </template>
  18 + 格式化
  19 + </Button>
  20 + </div>
  21 + </div>
  22 +</template>
  23 +
  24 +<script lang="ts" setup name="aceEditor">
  25 + import { ref, computed, onMounted, nextTick, watch } from 'vue';
  26 + import ace from 'ace-builds';
  27 + import 'ace-builds/src-noconflict/theme-chrome'; // 默认设置的主题
  28 + import 'ace-builds/src-noconflict/theme-terminal'; // 默认设置的主题
  29 + import 'ace-builds/src-noconflict/mode-javascript'; // 默认设置的语言模式javascript
  30 + import 'ace-builds/src-noconflict/snippets/xml'; // 设置xmL
  31 + import { beautify } from 'ace-builds/src-noconflict/ext-beautify.js';
  32 + import { useAppStore } from '/@/store/modules/app';
  33 + import { CopyOutlined } from '@ant-design/icons-vue';
  34 + import { Button, Tag } from 'ant-design-vue';
  35 + import { OnlineEditorTypeEnum } from '../../../config/enum';
  36 +
  37 + const emits = defineEmits(['changeAceContent']);
  38 +
  39 + const props = defineProps({
  40 + restData: {
  41 + type: Object,
  42 + },
  43 + scriptType: {
  44 + type: String,
  45 + default: 'javascript',
  46 + },
  47 + });
  48 +
  49 + const aceEditor = ref();
  50 +
  51 + const aceRef = ref();
  52 +
  53 + const userStore = useAppStore();
  54 +
  55 + const getAceClass = computed((): string => userStore.getDarkMode);
  56 +
  57 + const getRestData: any = ref(null);
  58 +
  59 + watch(
  60 + () => props.restData,
  61 + (newVal) => {
  62 + getRestData.value = newVal;
  63 + onHandleFormatter();
  64 + },
  65 + { deep: true }
  66 + );
  67 +
  68 + // 初始化编辑器
  69 + const initEditor = () => {
  70 + aceEditor.value = ace.edit(aceRef.value, {
  71 + maxLines: 50, // 最大行数,超过会自动出现滚动条
  72 + minLines: props.scriptType === OnlineEditorTypeEnum.JAVASCRIPT ? 36 : 14, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
  73 + fontSize: 14, // 编辑器内字体大小
  74 + theme: 'ace/theme/chrome', // 默认设置的主题
  75 + mode:
  76 + props.scriptType === OnlineEditorTypeEnum.JAVASCRIPT
  77 + ? 'ace/mode/javascript'
  78 + : 'ace/mode/xml', // 默认设置的语言模式
  79 + tabSize: 2, // 制表符设置为 4 个空格大小
  80 + });
  81 +
  82 + aceEditor.value.setOptions({
  83 + enableBasicAutocompletion: true,
  84 + enableLiveAutocompletion: true,
  85 + enableSnippets: true,
  86 + enableEmmet: true,
  87 + theme: getAceClass.value === 'dark' ? 'ace/theme/terminal' : 'ace/theme/chrome',
  88 + });
  89 + doFilter();
  90 + beautify(aceEditor.value.session);
  91 + };
  92 +
  93 + const doFilter = () => {
  94 + aceEditor.value.getSession().on('change', async () => {
  95 + try {
  96 + await nextTick();
  97 + const jsCode = aceEditor.value.getValue();
  98 + const res = getRestData.value ?? props.restData;
  99 + const fn = new Function('data', 'res', jsCode)(res?.data, res);
  100 + emits('changeAceContent', fn);
  101 + } catch (error) {
  102 + return `过滤函数错误,日志:${error}`;
  103 + }
  104 + });
  105 + };
  106 +
  107 + const onHandleFormatter = () => {
  108 + let oldValue = aceEditor.value?.getValue() || '';
  109 + oldValue = oldValue.replaceAll(/;(\n+)?/g, ';\n');
  110 + aceEditor.value?.setValue(oldValue);
  111 + beautify(aceEditor.value.session);
  112 + };
  113 +
  114 + const getValue = () => {
  115 + return aceEditor?.value?.getValue();
  116 + };
  117 +
  118 + const setValue = (data) => {
  119 + return aceEditor?.value?.setValue(data);
  120 + };
  121 +
  122 + onMounted(() => {
  123 + initEditor();
  124 + });
  125 +
  126 + defineExpose({
  127 + getValue,
  128 + setValue,
  129 + });
  130 +</script>
  131 +
  132 +<style lang="less" scoped>
  133 + .jsoneditor {
  134 + border: none;
  135 + }
  136 +
  137 + .tag-text {
  138 + white-space: normal;
  139 + height: auto;
  140 + }
  141 +
  142 + .tag-text-top {
  143 + width: 8vw;
  144 + &:extend(.tag-text);
  145 + }
  146 +
  147 + .tag-text-bottom {
  148 + width: 1vw;
  149 + &:extend(.tag-text);
  150 + }
  151 +</style>
... ...
... ... @@ -8,30 +8,28 @@
8 8 </a-radio-group>
9 9 <div class="mt-3">
10 10 <a-textarea
11   - v-show="getRequestBody.content.requestParamsBodyType === 'none'"
  11 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.NONE"
12 12 disabled
13 13 placeholder="该接口没有 Body 体"
14   - :rows="2"
15 14 />
16 15 <BodyTable
17 16 ref="bodyCellFormDataTableRef"
18   - v-show="getRequestBody.content.requestParamsBodyType === 'form-data'"
  17 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.FORMDATA"
19 18 />
20 19 <BodyTable
21 20 ref="bodyCellXwwwTableRef"
22   - v-show="getRequestBody.content.requestParamsBodyType === 'x-www-form-urlencoded'"
  21 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.XWWW"
23 22 />
24 23 <JsonEditor
25 24 :showBtn="false"
26   - style="width: 35vw; height: 30vh"
27   - v-show="getRequestBody.content.requestParamsBodyType === 'json'"
  25 + style="width: 35vw; height: 25vh"
  26 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.JSON"
28 27 ref="jsonEditorRef"
29 28 />
30   - <a-textarea
31   - v-model:value="getRequestBody.content.xml"
32   - v-show="getRequestBody.content.requestParamsBodyType === 'xml'"
33   - placeholder="请输入xml"
34   - :rows="6"
  29 + <AceTypeXmlEditor
  30 + ref="aceEditorRef"
  31 + v-show="getRequestBody.content.requestParamsBodyType === RequestBodyTypeEnum.XML"
  32 + :scriptType="OnlineEditorTypeEnum.XML"
35 33 />
36 34 </div>
37 35 </div>
... ... @@ -39,10 +37,12 @@
39 37 <script lang="ts" setup name="body">
40 38 import { reactive, ref, nextTick } from 'vue';
41 39 import { RequestBodyTypeEnum } from '../../../config/enum';
42   - import BodyTable from './bodyTable.vue';
  40 + import BodyTable from './paramsTable.vue';
43 41 import { isEmpty } from '/@/utils/is';
44 42 import { useUtils } from '../../../hooks/useUtils';
45 43 import JsonEditor from './jsonEditor.vue';
  44 + import AceTypeXmlEditor from './aceEditor.vue';
  45 + import { OnlineEditorTypeEnum } from '../../../config/enum';
46 46
47 47 const getRequestBody = reactive({
48 48 content: {
... ... @@ -62,6 +62,8 @@
62 62
63 63 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
64 64
  65 + const aceEditorRef = ref<InstanceType<typeof AceTypeXmlEditor>>();
  66 +
65 67 const bodyCellXwwwTableRef = ref<InstanceType<typeof BodyTable>>();
66 68
67 69 const handleChange = ({ target }) => {
... ... @@ -76,9 +78,11 @@
76 78 const valuesFormData = bodyCellFormDataTableRef.value?.getValue();
77 79 const valuesXWww = bodyCellXwwwTableRef.value?.getValue();
78 80 const jsonEditorValue = jsonEditorRef.value?.getJsonValue();
79   - getRequestBody.content['form-data'] = valuesFormData as any;
80   - getRequestBody.content['x-www-form-urlencoded'] = valuesXWww as any;
81   - getRequestBody.content['json'] = jsonEditorValue as any;
  81 + const xmlEditorValue = aceEditorRef.value?.getValue();
  82 + getRequestBody.content[RequestBodyTypeEnum.FORMDATA] = valuesFormData as any;
  83 + getRequestBody.content[RequestBodyTypeEnum.XWWW] = valuesXWww as any;
  84 + getRequestBody.content[RequestBodyTypeEnum.JSON] = jsonEditorValue as any;
  85 + getRequestBody.content[RequestBodyTypeEnum.XML] = xmlEditorValue as any;
82 86 if (type === 'none') getRequestBody.content = {} as any;
83 87 return getRequestBody.content;
84 88 };
... ... @@ -90,18 +94,22 @@
90 94 getRequestBody.content.requestParamsBodyType = type;
91 95 await nextTick();
92 96 await nextTick();
93   - bodyCellFormDataTableRef.value?.setValue(isEmpty(data) ? [pushObj] : data['form-data']);
94   - bodyCellXwwwTableRef.value?.setValue(isEmpty(data) ? [pushObj] : data['x-www-form-urlencoded']);
  97 + bodyCellFormDataTableRef.value?.setValue(
  98 + isEmpty(data) ? [pushObj] : data[RequestBodyTypeEnum.FORMDATA]
  99 + );
  100 + bodyCellXwwwTableRef.value?.setValue(
  101 + isEmpty(data) ? [pushObj] : data[RequestBodyTypeEnum.XWWW]
  102 + );
95 103 jsonEditorRef.value?.setJsonValue(data['json'] || '{}');
96   - getRequestBody.content.xml = data['xml'];
  104 + aceEditorRef.value?.setValue(data['xml'] || '');
97 105 };
98 106
99 107 //重置数据
100 108 const resetValue = () => {
101 109 for (let i in getRequestBody.content) Reflect.set(getRequestBody.content, i, '');
102   - getRequestBody.content['form-data'] = {};
103   - getRequestBody.content['x-www-form-urlencoded'] = {};
104   - getRequestBody.content.requestParamsBodyType = 'none';
  110 + getRequestBody.content[RequestBodyTypeEnum.FORMDATA] = {};
  111 + getRequestBody.content[RequestBodyTypeEnum.XWWW] = {};
  112 + getRequestBody.content.requestParamsBodyType = RequestBodyTypeEnum.NONE;
105 113 nextTick(() => {
106 114 bodyCellFormDataTableRef?.value?.resetValue();
107 115 bodyCellXwwwTableRef?.value?.resetValue();
... ...
... ... @@ -42,43 +42,42 @@
42 42 import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
43 43 import { editTestCellTableTHeaderConfig } from '../../../config/config';
44 44 import { tableItems } from '../../../config/types';
45   - defineProps({
46   - method: {
47   - type: String,
48   - },
49   - });
  45 + import { useUtils } from '../../../hooks/useUtils';
  46 +
  47 + const { CommonFuncValue } = useUtils();
50 48
51 49 const tableArray = reactive<{
52 50 content: tableItems[];
53 51 }>({
54 52 content: [
55 53 {
56   - key: 'ContentType',
57   - value: 'none',
  54 + key: '',
  55 + value: '',
58 56 required: false,
59 57 },
60 58 ],
61 59 });
62 60
63   - // 新增
64 61 const add = (_, index: number) => {
65 62 tableArray.content.splice(index + 1, 0, {
66   - key: 'ContentType',
67   - value: 'none',
  63 + key: '',
  64 + value: '',
68 65 required: false,
69 66 });
70 67 };
71 68
72   - // 减少
73 69 const remove = (index: number) => {
74   - if (tableArray.content.length !== 1) {
  70 + if (tableArray.content.length > 1) {
75 71 tableArray.content.splice(index, 1);
  72 + } else {
  73 + resetValue();
76 74 }
77 75 };
78 76
79 77 //获取数据
80 78 const getValue = () => {
81   - return tableArray.content;
  79 + const newFuncValue = new CommonFuncValue(tableArray.content as tableItems[]);
  80 + return newFuncValue.get();
82 81 };
83 82
84 83 //设置数据
... ... @@ -104,35 +103,5 @@
104 103 </script>
105 104
106 105 <style scoped lang="less">
107   - @table-color: #e5e7eb;
108   -
109   - .table-border-color {
110   - border: 1px solid #e5e7eb;
111   - text-align: center;
112   - }
113   -
114   - .table-content {
115   - overflow-x: auto;
116   -
117   - table {
118   - border-collapse: collapse;
119   - width: 35vw;
120   - &:extend(.table-border-color);
121   - }
122   -
123   - table thead {
124   - white-space: nowrap;
125   - }
126   -
127   - table td {
128   - padding: 5px;
129   - white-space: nowrap;
130   - &:extend(.table-border-color);
131   - }
132   -
133   - table th {
134   - padding: 5px;
135   - &:extend(.table-border-color);
136   - }
137   - }
  106 + @import '../common/commonTable.less';
138 107 </style>
... ...
1 1 <template>
2 2 <div class="flex flex-col justify-between">
3   - <div ref="jsoneditorRef" style="height: 100%; width: 100%"></div>
  3 + <div ref="jsoneditorRef" style="height: 100%"></div>
4 4 <div class="ml-2 -mt-1.5">
5 5 <Button v-if="showBtn" @click="onHandleCopy" class="mt-8 -ml-2">
6 6 <template #icon>
... ...
... ... @@ -22,12 +22,12 @@
22 22 allowClear
23 23 />
24 24 </td>
25   - <td style="width: 12vw">
  25 + <td>
26 26 <div v-if="item.key === 'date_range'">
27   - <div>
28   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date1" />
  27 + <div class="flex">
  28 + <a-input placeholder="请输入" v-model:value="item.date1" />
29 29 <span>~</span>
30   - <a-input style="width: 6vw" placeholder="请输入" v-model:value="item.date2" />
  30 + <a-input placeholder="请输入" v-model:value="item.date2" />
31 31 </div>
32 32 <div class="flex mt-2">
33 33 <a-checkbox @change="onHandleCheck" v-model:checked="mores">更多选项</a-checkbox>
... ... @@ -42,15 +42,15 @@
42 42 />
43 43 </div>
44 44 </td>
45   - <td style="width: 4vw">
  45 + <td>
46 46 <a-switch v-model:checked="item.required" />
47 47 </td>
48   - <td style="width: 4vw">
  48 + <td>
49 49 <div>
50 50 <Button type="dashed" @click="add(item, index)">
51 51 <template #icon><PlusOutlined /></template
52 52 ></Button>
53   - <Button type="dashed" style="margin-left: 5px" @click="remove(item, index)">
  53 + <Button type="dashed" class="ml-1" @click="remove(item, index)">
54 54 <template #icon> <MinusOutlined /></template>
55 55 </Button>
56 56 </div>
... ... @@ -67,12 +67,9 @@
67 67 import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
68 68 import { editCellTableTHeadConfig } from '../../../config/config';
69 69 import { selectType, tableItems } from '../../../config/types';
  70 + import { useUtils } from '../../../hooks/useUtils';
70 71
71   - defineProps({
72   - method: {
73   - type: String,
74   - },
75   - });
  72 + const { ParamsFuncValue } = useUtils();
76 73
77 74 const selectOptions = ref<selectType[]>([]);
78 75
... ... @@ -110,7 +107,6 @@
110 107 ],
111 108 });
112 109
113   - // 新增
114 110 const add = (_, index: number) => {
115 111 tableArray.content.splice(index + 1, 0, {
116 112 key: undefined,
... ... @@ -122,7 +118,6 @@
122 118 });
123 119 };
124 120
125   - // 减少
126 121 const remove = (item, index: number) => {
127 122 if (tableArray.content.length > 1) {
128 123 selectOptions.value.forEach((ele) => {
... ... @@ -154,20 +149,21 @@
154 149 });
155 150 };
156 151
  152 + //fix 解决编辑回显下拉框已选择应禁用问题
157 153 const hanldeDropdownVisibleChange = () => handleChange();
158 154
  155 + const commonHandleChange = (tableArray) => {
  156 + nextTick(() => {
  157 + tableArray.forEach(() => {
  158 + handleChange();
  159 + });
  160 + });
  161 + };
  162 +
159 163 //获取数据
160 164 const getValue = () => {
161   - let assemblyData: any = tableArray.content.map((it) => {
162   - return {
163   - key: it.key,
164   - value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
165   - mores: it.key === 'date_range' ? mores.value : null,
166   - editDisabled: it.editDisabled,
167   - required: it.required,
168   - };
169   - });
170   - return assemblyData;
  165 + const paramsFuncValue = new ParamsFuncValue(tableArray.content as any, mores.value);
  166 + return paramsFuncValue.get();
171 167 };
172 168
173 169 //设置数据
... ... @@ -190,9 +186,7 @@
190 186 assemblyData = assemblyData.filter((item) => item?.mores == false || !item?.mores);
191 187 }
192 188 tableArray.content = assemblyData;
193   - tableArray.content.forEach(() => {
194   - handleChange();
195   - });
  189 + commonHandleChange(tableArray.content);
196 190 };
197 191
198 192 //重置数据
... ... @@ -207,11 +201,7 @@
207 201 date1: '',
208 202 date2: '',
209 203 });
210   - nextTick(() => {
211   - tableArray.content.forEach(() => {
212   - handleChange();
213   - });
214   - });
  204 + commonHandleChange(tableArray.content);
215 205 };
216 206 defineExpose({
217 207 getValue,
... ... @@ -221,35 +211,5 @@
221 211 </script>
222 212
223 213 <style scoped lang="less">
224   - @table-color: #e5e7eb;
225   -
226   - .table-border-color {
227   - border: 1px solid #e5e7eb;
228   - text-align: center;
229   - }
230   -
231   - .table-content {
232   - overflow-x: auto;
233   -
234   - table {
235   - border-collapse: collapse;
236   - width: 35vw;
237   - &:extend(.table-border-color);
238   - }
239   -
240   - table thead {
241   - white-space: nowrap;
242   - }
243   -
244   - table td {
245   - padding: 5px;
246   - white-space: nowrap;
247   - &:extend(.table-border-color);
248   - }
249   -
250   - table th {
251   - padding: 5px;
252   - &:extend(.table-border-color);
253   - }
254   - }
  214 + @import '../common/commonTable.less';
255 215 </style>
... ...
1 1 <template>
2 2 <div>
3   - <!--TODO: 待优化三者共存下的测试和是否能复用表格 -->
4   - <Tabs @change="handleChange" v-model:activeKey="activeKey">
5   - <TabPane class="tab-pane" forceRender key="Params" tab="Params">
6   - <ParamsTable ref="paramsCellTableRef" :method="method" />
7   - <ParamsTest
8   - @testParamsInterface="handleTestParamsInterface"
9   - @closeTest="onCloseTest"
10   - ref="testParamsRequestRef"
11   - :data="dataMap.mapParamsObj"
12   - :interfaceType="interfaceType"
13   - />
14   - </TabPane>
15   - <TabPane
16   - v-if="
17   - method !== RequestMethodTypeEnum.WEBSOCKET &&
18   - requestTypeAndUrl?.requestHttpType !== RequestHttpTypeEnum.GET
19   - "
20   - class="tab-pane"
21   - forceRender
22   - key="Body"
23   - tab="Body"
24   - >
25   - <Body ref="bodyRef" @resetValue="handleResetValue" />
26   - <BodyTest
27   - v-if="bodyType !== RequestBodyTypeEnum.NONE"
28   - @testBodyInterface="handleTestBodyInterface"
29   - @closeTest="onCloseTest"
30   - ref="testBodyRequestRef"
31   - :interfaceType="interfaceType"
32   - :data="dataMap.mapBodyObj"
33   - />
34   - </TabPane>
35   - <TabPane
36   - v-if="method !== RequestMethodTypeEnum.WEBSOCKET"
37   - class="tab-pane"
38   - forceRender
39   - key="Header"
40   - tab="Header"
41   - >
42   - <HeaderTable ref="editHeaderCellTableRef" :method="method" />
43   - <HeaderTest
44   - @testHeaderInterface="handleTestHeaderInterface"
45   - @closeTest="onCloseTest"
46   - ref="testHeaderRequestRef"
47   - :interfaceType="interfaceType"
48   - :data="dataMap.mapHeaderObj"
49   - />
50   - </TabPane>
51   - </Tabs>
52   - <ExcuteTest ref="excuteTestRef" @emitExcute="handleEmitExcute" :data="excuteData" />
  3 + <div>
  4 + <Tabs @change="handleChange" v-model:activeKey="activeKey">
  5 + <TabPane class="tab-pane" forceRender key="Params" tab="Params">
  6 + <ParamsTable ref="paramsCellTableRef" />
  7 + <ParamsTest
  8 + @testParamsInterface="handleTestParamsInterface"
  9 + @closeTest="onCloseTest"
  10 + ref="testParamsRequestRef"
  11 + :data="dataMap.mapParamsObj"
  12 + :interfaceType="interfaceType"
  13 + />
  14 + </TabPane>
  15 + <TabPane
  16 + v-if="
  17 + method !== RequestMethodTypeEnum.WEBSOCKET &&
  18 + requestTypeAndUrl?.requestHttpType !== RequestHttpTypeEnum.GET
  19 + "
  20 + class="tab-pane"
  21 + forceRender
  22 + key="Body"
  23 + tab="Body"
  24 + >
  25 + <Body ref="bodyRef" @resetValue="handleResetValue" />
  26 + <BodyTest
  27 + v-if="bodyType !== RequestBodyTypeEnum.NONE"
  28 + @testBodyInterface="handleTestBodyInterface"
  29 + @closeTest="onCloseTest"
  30 + ref="testBodyRequestRef"
  31 + :interfaceType="interfaceType"
  32 + :data="dataMap.mapBodyObj"
  33 + />
  34 + </TabPane>
  35 + <TabPane
  36 + v-if="method !== RequestMethodTypeEnum.WEBSOCKET"
  37 + class="tab-pane"
  38 + forceRender
  39 + key="Header"
  40 + tab="Header"
  41 + >
  42 + <HeaderTable ref="editHeaderCellTableRef" />
  43 + <HeaderTest
  44 + @testHeaderInterface="handleTestHeaderInterface"
  45 + @closeTest="onCloseTest"
  46 + ref="testHeaderRequestRef"
  47 + :interfaceType="interfaceType"
  48 + :data="dataMap.mapHeaderObj"
  49 + />
  50 + </TabPane>
  51 + </Tabs>
  52 + </div>
  53 + <div>
  54 + <ExcuteTest
  55 + ref="excuteTestRef"
  56 + @emitExcute="handleEmitExcute"
  57 + :data="excuteData"
  58 + :method="method"
  59 + />
  60 + </div>
53 61 </div>
54 62 </template>
55 63 <script lang="ts" setup name="simpleRequest">
... ... @@ -230,6 +238,11 @@
230 238 };
231 239 };
232 240
  241 + //获取编写过滤器里的数
  242 + const getFilterValue = () => {
  243 + return excuteTestRef?.value?.getFilterValue();
  244 + };
  245 +
233 246 //设置数据
234 247 const setValue = (data, flag, defaultValue) => {
235 248 if (!flag) {
... ... @@ -262,6 +275,7 @@
262 275 getValue,
263 276 setValue,
264 277 resetValue,
  278 + getFilterValue,
265 279 });
266 280 </script>
267 281
... ...
... ... @@ -27,7 +27,6 @@
27 27 </div>
28 28 <Button
29 29 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
30   - class="ml-2"
31 30 @click="handleTest(isSingleClickText)"
32 31 type="primary"
33 32 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -37,26 +36,30 @@
37 36 <a-row type="flex" justify="center">
38 37 <a-col :span="3"> 参数设置 </a-col>
39 38 <a-col :span="21">
40   - <div v-if="data?.type === 'x-www-form-urlencoded' || data?.type === 'form-data'">
  39 + <div
  40 + v-if="
  41 + data?.type === RequestBodyTypeEnum.XWWW ||
  42 + data?.type === RequestBodyTypeEnum.FORMDATA
  43 + "
  44 + >
41 45 <TestBodyCellTable :token="getToken" ref="testEditCellTableRef" />
42 46 </div>
43   - <div style="width: 30vw" v-else-if="data?.type === 'json'">
  47 + <div style="width: 30vw" v-else-if="data?.type === RequestBodyTypeEnum.JSON">
44 48 <JsonEditor :showBtn="false" style="width: 35vw; height: 30vh" ref="jsonEditorRef" />
45 49 </div>
46   - <div style="width: 30vw" v-else-if="data?.type === 'xml'">
47   - <a-textarea v-model:value="xmlContent" placeholder="请输入xml" :rows="6" />
  50 + <div style="width: 30vw" v-else-if="data?.type === RequestBodyTypeEnum.XML">
  51 + <AceTypeXmlEditor ref="aceEditorRef" :scriptType="OnlineEditorTypeEnum.XML" />
48 52 </div>
49 53 </a-col>
50 54 </a-row>
51 55 </div>
52 56 </div>
53   - <div class="mt-8"> </div>
54 57 </div>
55 58 </template>
56 59 <script lang="ts" setup name="testRequest">
57 60 import { ref, nextTick, onMounted } from 'vue';
58 61 import { Button } from 'ant-design-vue';
59   - import TestBodyCellTable from './testEditBodyCellTable.vue';
  62 + import TestBodyCellTable from '../paramsTest/testEditParamsCellTable.vue';
60 63 import moment from 'moment';
61 64 import { useUtils } from '../../../hooks/useUtils';
62 65 import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
... ... @@ -68,6 +71,12 @@
68 71 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
69 72 import { getAuthCache } from '/@/utils/auth';
70 73 import { isAdmin } from '/@/enums/roleEnum';
  74 + import AceTypeXmlEditor from '../../SimpleRequest/components/aceEditor.vue';
  75 + import {
  76 + OnlineEditorTypeEnum,
  77 + RequestBodyTypeEnum,
  78 + TableDefaultTypeEnum,
  79 + } from '../../../config/enum';
71 80
72 81 const userInfo: any = getAuthCache(USER_INFO_KEY);
73 82
... ... @@ -111,12 +120,12 @@
111 120
112 121 const selectSysTenant = ref(undefined);
113 122
114   - const xmlContent = ref('');
115   -
116 123 const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>();
117 124
118 125 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
119 126
  127 + const aceEditorRef = ref<InstanceType<typeof AceTypeXmlEditor>>();
  128 +
120 129 const testResult = ref('');
121 130
122 131 const { getMultipleKeys } = useUtils();
... ... @@ -175,8 +184,10 @@
175 184 const getValue = async () => {
176 185 await nextTick();
177 186 await nextTick(() => {
178   - console.log(props.data?.list);
179   - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  187 + if (
  188 + props.data?.type === RequestBodyTypeEnum.XWWW ||
  189 + props.data?.type === RequestBodyTypeEnum.FORMDATA
  190 + ) {
180 191 const getSingleKey = props.data?.list;
181 192 const getMuteKey = props.data?.list?.filter((it: any) => it.key.split(',').length > 1);
182 193 const getMuteKeys = getMultipleKeys(getMuteKey);
... ... @@ -184,10 +195,10 @@
184 195 (it: any) => it.key.split(',').length === 1
185 196 );
186 197 testEditCellTableRef.value?.setTableArray(mergeKeys);
187   - } else if (props.data?.type === 'json') {
  198 + } else if (props.data?.type === RequestBodyTypeEnum.JSON) {
188 199 jsonEditorRef.value?.setJsonValue(props.data?.list);
189   - } else if (props.data?.type === 'xml') {
190   - xmlContent.value = props.data?.list;
  200 + } else if (props.data?.type === RequestBodyTypeEnum.XML) {
  201 + aceEditorRef?.value?.setValue(props.data?.list);
191 202 }
192 203 });
193 204 };
... ... @@ -198,8 +209,9 @@
198 209 //把日期拆分成多个
199 210 const keyValueList: any = [];
200 211 testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
201   - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
202   - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  212 + const splitDateKey =
  213 + item?.key === TableDefaultTypeEnum.DATERANGE ? item?.value?.split(',') : [];
  214 + const splitDateValue = item?.key === TableDefaultTypeEnum.DATERANGE ? item?.dateValue : [];
203 215 for (let i in splitDateKey) {
204 216 const obj = {
205 217 key: splitDateKey[i],
... ... @@ -211,15 +223,10 @@
211 223 return testEditCellTableRef.value
212 224 ?.getValue()
213 225 .concat(keyValueList)
214   - .filter((it) => it.key !== 'date_range')
  226 + .filter((it) => it.key !== TableDefaultTypeEnum.DATERANGE)
215 227 .map((it: any) => {
216   - const value =
217   - it?.key === 'scope'
218   - ? it?.keyValue
219   - : it?.key === 'fixed_date'
220   - ? moment(it?.fixed_date_value).valueOf()
221   - : it?.value;
222   - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  228 + const value = it?.key === TableDefaultTypeEnum.SCOPE ? it?.keyValue : it?.value;
  229 + const key = it?.key === TableDefaultTypeEnum.SCOPE ? it?.value : it?.key;
223 230 return {
224 231 key,
225 232 value,
... ... @@ -231,7 +238,10 @@
231 238 //获取数据
232 239 const getTestValue = () => {
233 240 let params: any = {};
234   - if (props.data?.type === 'x-www-form-urlencoded' || props.data?.type === 'form-data') {
  241 + if (
  242 + props.data?.type === RequestBodyTypeEnum.XWWW ||
  243 + props.data?.type === RequestBodyTypeEnum.FORMDATA
  244 + ) {
235 245 const getTable = getTestTableKeyValue();
236 246 const hasRequired = getTable?.some((it) => it.required === true && !it.value);
237 247 if (hasRequired) {
... ... @@ -239,10 +249,10 @@
239 249 throw new Error('参数不能为空');
240 250 }
241 251 getTable?.map((it) => (params[it.key!] = it.value!));
242   - } else if (props.data?.type === 'json') {
  252 + } else if (props.data?.type === RequestBodyTypeEnum.JSON) {
243 253 params = jsonEditorRef.value?.getJsonValue();
244   - } else if (props.data?.type === 'xml') {
245   - params = xmlContent.value;
  254 + } else if (props.data?.type === RequestBodyTypeEnum.XML) {
  255 + params = aceEditorRef?.value?.getValue();
246 256 }
247 257 if (params['keys']) {
248 258 Reflect.set(params, 'keys', params['keys'].join(','));
... ... @@ -257,6 +267,7 @@
257 267
258 268 //设置数据
259 269 const setValue = () => {
  270 + isSingleClickText.value = 'open';
260 271 showTestEditCell.value = false;
261 272 testResult.value = '';
262 273 selectTenant.value = undefined;
... ...
1   -<!-- eslint-disable vue/valid-v-model -->
2   -<template>
3   - <div class="table-content">
4   - <!-- TODO: 待优化测试表格 -->
5   - <table align="center">
6   - <thead>
7   - <tr>
8   - <th v-for="item in editTestCellTableTHeadConfig" :key="item">
9   - <a-tooltip v-if="item === '参数值'">
10   - <template #title>当自定义为entityType,应输入DEVICE</template>
11   - <QuestionCircleOutlined :style="{ fontSize: '14px', marginLeft: '5px' }" />
12   - </a-tooltip>
13   - {{ item }}
14   - </th>
15   - </tr>
16   - </thead>
17   - <tbody>
18   - <tr v-for="(item, index) in tableTestArray.content" :key="index">
19   - <td style="width: 7.5vw">
20   - <Select
21   - :getPopupContainer="
22   - (triggerNode) => {
23   - return triggerNode.parentNode;
24   - }
25   - "
26   - :disabled="true"
27   - v-model:value="item.key"
28   - placeholder="请选择"
29   - :options="selectOptions"
30   - />
31   - </td>
32   - <td style="width: 6.5vw">
33   - <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
34   - <a-tree-select
35   - :getPopupContainer="
36   - (triggerNode) => {
37   - return triggerNode.parentNode;
38   - }
39   - "
40   - v-else-if="item.key === 'organizationId'"
41   - v-model:value="item.value"
42   - show-search
43   - :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
44   - placeholder="请选择组织"
45   - allow-clear
46   - tree-default-expand-all
47   - :tree-data="treeData"
48   - @change="handleOrgnationChange(item)"
49   - />
50   - <Select
51   - :getPopupContainer="
52   - (triggerNode) => {
53   - return triggerNode.parentNode;
54   - }
55   - "
56   - v-else-if="item.key === 'entityId'"
57   - v-model:value="item.value"
58   - placeholder="请选择"
59   - notFoundContent="请选择"
60   - :options="entityOptions"
61   - allowClear
62   - />
63   - <Select
64   - :getPopupContainer="
65   - (triggerNode) => {
66   - return triggerNode.parentNode;
67   - }
68   - "
69   - v-else-if="item.key === 'keys'"
70   - v-model:value="item.value"
71   - placeholder="请选择"
72   - notFoundContent="请选择"
73   - :options="attributeOptions"
74   - mode="multiple"
75   - allowClear
76   - />
77   - <div v-else-if="item.key === 'date_range'">
78   - <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
79   - <span>~</span>
80   - <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
81   - </div>
82   - <div v-else-if="item.key === 'fixed_date'">
83   - <a-button disabled type="primary">{{ item.value }}</a-button>
84   - </div>
85   - <Select
86   - :getPopupContainer="
87   - (triggerNode) => {
88   - return triggerNode.parentNode;
89   - }
90   - "
91   - v-else
92   - v-model:value="item.value"
93   - placeholder="请选择"
94   - notFoundContent="请选择"
95   - :options="valueOptions"
96   - allowClear
97   - @change="handleValueChange(item)"
98   - />
99   - </td>
100   - <td style="width: 6.5vw">
101   - <a-input
102   - v-if="item.key === 'scope'"
103   - placeholder="请输入"
104   - v-model:value="item.keyValue"
105   - />
106   - <a-date-picker
107   - v-else-if="item.key === 'fixed_date'"
108   - style="width: 6.5vw"
109   - v-model:value="item.keyValue"
110   - :show-time="{ format: 'HH:mm' }"
111   - format="YYYY-MM-DD HH:mm:ss"
112   - placeholder="日期时间"
113   - />
114   - <a-range-picker
115   - v-else-if="item.key == 'date_range'"
116   - style="width: 6.5vw"
117   - v-model:value="item.dateValue"
118   - :show-time="{
119   - format: 'HH:mm:ss',
120   - defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
121   - }"
122   - format="YYYY-MM-DD HH:mm:ss"
123   - :placeholder="['开始', '结束']"
124   - />
125   - <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" />
126   - </td>
127   - </tr>
128   - </tbody>
129   - </table>
130   - </div>
131   -</template>
132   -<script lang="ts" setup name="editCellTable">
133   - import { reactive, ref, onMounted } from 'vue';
134   - import { Select } from 'ant-design-vue';
135   - import { findDictItemByCode } from '/@/api/system/dict';
136   - import { useApi } from '../../../hooks/useApi';
137   - import { useUtils } from '../../../hooks/useUtils';
138   - import { cloneDeep } from 'lodash-es';
139   - import { tableItems, selectType } from '../../../config/types';
140   - import { editTestCellTableTHeadConfig } from '../../../config/config';
141   - import { QuestionCircleOutlined } from '@ant-design/icons-vue';
142   - import moment from 'moment';
143   -
144   - const props = defineProps({
145   - method: {
146   - type: String,
147   - },
148   - token: {
149   - type: String,
150   - },
151   - });
152   -
153   - onMounted(async () => {
154   - const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' });
155   - selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue }));
156   - selectOptions.value.push({
157   - label: '自定义',
158   - value: 'scope',
159   - });
160   - if (props.method === '2')
161   - selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
162   - });
163   -
164   - const { isOtherHttp } = useUtils();
165   -
166   - const selectOptions = ref<selectType[]>([]);
167   -
168   - const valueOptions = ref<selectType[]>([]);
169   -
170   - const entityOptions = ref<selectType[]>([]);
171   -
172   - const attributeOptions = ref<selectType[]>([]);
173   -
174   - const treeData = ref([]);
175   -
176   - const tableTestArray = reactive<{
177   - content: tableItems[];
178   - }>({
179   - content: [
180   - {
181   - key: undefined,
182   - value: undefined,
183   - keyValue: null,
184   - editDisabled: false,
185   - dateValue: null,
186   - },
187   - ],
188   - });
189   -
190   - //设置数据
191   - const setTableArray = (data) => {
192   - const list = cloneDeep(data);
193   - list?.forEach((it) => {
194   - if (it.key === 'keys') it.value = [];
195   - });
196   - if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);
197   - if (list.hasOwnProperty('form-data') && Array.isArray(list['form-data']))
198   - (tableTestArray.content = list['form-data']) && getApi(list['form-data']);
199   - if (
200   - list.hasOwnProperty('x-www-form-urlencoded') &&
201   - Array.isArray(list['x-www-form-urlencoded'])
202   - )
203   - (tableTestArray.content = list['x-www-form-urlencoded']) &&
204   - getApi(list['x-www-form-urlencoded']);
205   - };
206   -
207   - const getApi = (list) => {
208   - list?.forEach(async (it) => {
209   - if (it.key === 'deviceProfileId') {
210   - const { options } = await useApi(it.key, props.token);
211   - valueOptions.value = options;
212   - } else if (it.key === 'organizationId') {
213   - const { options } = await useApi(it.key, props.token);
214   - treeData.value = options as any;
215   - }
216   - });
217   - };
218   -
219   - const handleOrgnationChange = async (e) => {
220   - let deviceProfileId = '';
221   - tableTestArray.content.forEach((f: any) => {
222   - if (f.key === 'entityId') {
223   - f.value = null;
224   - }
225   - if (f.key === 'deviceProfileId') deviceProfileId = f.value;
226   - });
227   - getEntityOptions(e.value, deviceProfileId);
228   - };
229   -
230   - const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
231   - const res = await isOtherHttp('api/yt/device/list', props.token, {
232   - organizationId,
233   - deviceProfileId,
234   - });
235   - entityOptions.value = res.map((item) => ({
236   - label: item.alias || item.name,
237   - value: item.tbDeviceId,
238   - }));
239   - };
240   -
241   - const getAttributeOptions = async (params) => {
242   - const { deviceProfileId, dataType } = params;
243   - const res = await isOtherHttp(`api/yt/device/attributes/${deviceProfileId}`, props.token, {
244   - dataType,
245   - });
246   - if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0);
247   - attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
248   - };
249   -
250   - const handleValueChange = (e) => {
251   - let organizationId = '';
252   - if (e.key === 'deviceProfileId') {
253   - tableTestArray.content.forEach((f: any) => {
254   - if (f.key === 'keys') {
255   - f.value = [];
256   - }
257   - if (f.key === 'organizationId') organizationId = f.value;
258   - if (f.key === 'entityId') f.value = null;
259   - });
260   - if (e.value) {
261   - getAttributeOptions({ deviceProfileId: e.value });
262   - }
263   - if (organizationId !== '') {
264   - getEntityOptions(organizationId, e.value);
265   - }
266   - }
267   - };
268   -
269   - //获取数据
270   - const getValue = () => {
271   - return tableTestArray.content;
272   - };
273   - defineExpose({
274   - getValue,
275   - setTableArray,
276   - });
277   -</script>
278   -
279   -<style scoped lang="less">
280   - @table-color: #e5e7eb;
281   -
282   - .table-border-color {
283   - border: 1px solid #e5e7eb;
284   - text-align: center;
285   - }
286   -
287   - .table-content {
288   - table {
289   - width: 31vw;
290   - &:extend(.table-border-color);
291   - }
292   -
293   - table td {
294   - padding: 5px;
295   - white-space: nowrap;
296   - &:extend(.table-border-color);
297   - }
298   -
299   - table th {
300   - padding: 5px;
301   - &:extend(.table-border-color);
302   - }
303   - }
304   -</style>
... ... @@ -16,22 +16,32 @@
16 16 </div>
17 17 </div>
18 18 <div class="mt-8">
19   - <a-row type="flex" justify="space-between" align="middle">
20   - <a-col :span="24">
21   - <div>
22   - <JsonEditor
23   - :showBtn="true"
24   - v-if="isWebSocketType === '2'"
25   - style="width: 40vw; height: 40vh"
26   - ref="jsonWebsocketEditorRef"
27   - />
28   - <JsonEditor
29   - :showBtn="true"
30   - v-else
31   - style="width: 40vw; height: 40vh"
32   - ref="jsonEditorRef"
33   - />
34   - </div>
  19 + <a-row type="flex" align="top">
  20 + <a-col :span="method === '2' ? 11 : 6">
  21 + <p>过滤器函数编写:</p>
  22 + <AceTypeIsJsEditor
  23 + style=""
  24 + :restData="getRestData"
  25 + @changeAceContent="onHandleAceContent"
  26 + ref="aceTypeIsJsEditorRef"
  27 + />
  28 + </a-col>
  29 + <a-col :span="1">
  30 + <a-divider type="vertical" class="divider-color" />
  31 + </a-col>
  32 + <a-col
  33 + :span="method === '2' ? 12 : 17"
  34 + style="position: relative"
  35 + :style="{ left: (method === '2' ? 1.5 : 0) + 'vw' }"
  36 + >
  37 + <a-col>
  38 + <p>接口返回数据(res):</p>
  39 + <JsonEditor style="height: 35vh" :showBtn="true" ref="jsonEditorRef" />
  40 + </a-col>
  41 + <a-col class="mt-3">
  42 + <p>过滤器结果:</p>
  43 + <JsonFilterEditor style="height: 35vh" :showBtn="true" ref="jsonEditorFilterRef" />
  44 + </a-col>
35 45 </a-col>
36 46 </a-row>
37 47 </div>
... ... @@ -44,8 +54,11 @@
44 54 import { useWebSocket } from '@vueuse/core';
45 55 import { useUtils } from '../../../hooks/useUtils';
46 56 import JsonEditor from '../../SimpleRequest/components/jsonEditor.vue';
  57 + import JsonFilterEditor from '../../SimpleRequest/components/jsonEditor.vue';
  58 + import AceTypeIsJsEditor from '../../SimpleRequest/components/aceEditor.vue';
47 59 import { Tag } from 'ant-design-vue';
48 60 import { useThrottleFn } from '@vueuse/shared';
  61 + import { RequestMethodTypeEnum } from '../../../config/enum';
49 62
50 63 const emits = defineEmits(['emitExcute']);
51 64
... ... @@ -53,13 +66,22 @@
53 66 data: {
54 67 type: Object,
55 68 },
  69 + method: {
  70 + type: String,
  71 + },
56 72 });
57 73
58 74 const showTestFlag = ref(false);
59 75
  76 + const openFilterFlag = ref(false);
  77 +
60 78 const jsonEditorRef = ref<InstanceType<typeof JsonEditor>>();
61 79
62   - const jsonWebsocketEditorRef = ref<InstanceType<typeof JsonEditor>>();
  80 + const jsonEditorFilterRef = ref<InstanceType<typeof JsonFilterEditor>>();
  81 +
  82 + const aceTypeIsJsEditorRef = ref<InstanceType<typeof AceTypeIsJsEditor>>();
  83 +
  84 + const getRestData: any = ref(null);
63 85
64 86 const socketUrls = ref('');
65 87
... ... @@ -70,6 +92,12 @@
70 92 },
71 93 });
72 94
  95 + const { staticWebSocketParams, commonRest } = useUtils();
  96 +
  97 + const onHandleAceContent = (resp) => {
  98 + commonRest(resp, jsonEditorFilterRef.value?.setJsonValue);
  99 + };
  100 +
73 101 //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式"
74 102 String.prototype.restfulFormat = function (replacements) {
75 103 var formatString = function (str, replacements) {
... ... @@ -109,7 +137,7 @@
109 137 isShowTestResult.value = true;
110 138 nextTick(() => {
111 139 jsonEditorRef.value?.setJsonValue('测试结果为');
112   - jsonWebsocketEditorRef.value?.setJsonValue('测试结果为');
  140 + jsonEditorFilterRef.value?.setJsonValue('过滤结果为');
113 141 });
114 142 };
115 143
... ... @@ -121,17 +149,17 @@
121 149 await nextTick();
122 150 //获取Params和Header和Body
123 151 const Objects = props.data;
124   - isWebSocketType.value = Objects?.method;
125 152 const apiType = Objects?.apiType;
126 153 const url = Objects?.apiGetUrl;
127 154 const headers = Objects?.Header?.params;
128 155 const params = Objects?.Params?.params;
129   - isToken.value = Objects?.Params?.token;
130 156 const body = Objects?.Body?.params;
  157 + isWebSocketType.value = Objects?.method;
  158 + isToken.value = Objects?.Params?.token;
131 159 isPostToken.value = Objects?.Body?.token;
132 160 postBodyType.value = Objects?.Body?.type;
133 161 apiUrl.value = url?.restfulFormat(params);
134   - if (isWebSocketType.value === '2') {
  162 + if (isWebSocketType.value === RequestMethodTypeEnum.WEBSOCKET) {
135 163 socketUrls.value = url;
136 164 socketMessage.server = `${socketUrls.value}?token=${isToken.value}`;
137 165 const list = Object.values(params);
... ... @@ -154,19 +182,10 @@
154 182 postBodyType.value
155 183 );
156 184 if (!resp) return;
157   - if (Object.prototype.toString.call(resp) === '[object Object]') {
158   - jsonEditorRef.value?.setJsonValue(resp);
159   - } else if (typeof resp === 'string') {
160   - jsonEditorRef.value?.setJsonValue(resp);
161   - } else if (Array.isArray(resp)) {
162   - const temp = {
163   - data: resp,
164   - };
165   - jsonEditorRef.value?.setJsonValue(temp);
166   - } else {
167   - jsonEditorRef.value?.setJsonValue(JSON.stringify(resp));
168   - }
  185 + getRestData.value = resp;
  186 + commonRest(resp, jsonEditorRef.value?.setJsonValue);
169 187 } catch (e) {
  188 + console.log(e);
170 189 if (Object.prototype.toString.call(e) === '[object Object]') {
171 190 jsonEditorRef.value?.setJsonValue(e);
172 191 } else {
... ... @@ -176,50 +195,45 @@
176 195 }
177 196 };
178 197
179   - //websocket请求
  198 + //ws请求
180 199 const websocketRequest = (params, destroy = false) => {
181   - //websocket请求
182   - if (Object.prototype.toString.call(params) === '[object Object]') {
183   - Reflect.deleteProperty(params, 'deviceProfileId');
184   - Reflect.deleteProperty(params, 'organizationId');
185   - Reflect.set(params, 'cmdId', 1);
186   - Reflect.set(params, 'scope', 'LATEST_TELEMETRY');
187   - Reflect.set(params, 'entityType', 'DEVICE');
  200 + try {
  201 + let webSocketParams: any = null;
  202 + if (Object.prototype.toString.call(params) === '[object Object]') {
  203 + const { entityId, keys } = params;
  204 + webSocketParams = {
  205 + entityId,
  206 + keys,
  207 + ...staticWebSocketParams,
  208 + };
  209 + }
  210 + socketMessage.sendValue.tsSubCmds = [webSocketParams];
  211 + const { send, close } = useWebSocket(socketMessage.server, {
  212 + onConnected() {
  213 + send(JSON.stringify(socketMessage.sendValue));
  214 + },
  215 + onMessage(_, e) {
  216 + const { data } = JSON.parse(e.data);
  217 + getRestData.value = data;
  218 + commonRest(data, jsonEditorRef.value?.setJsonValue);
  219 + },
  220 + onDisconnected() {
  221 + close();
  222 + },
  223 + onError() {},
  224 + });
  225 + if (destroy) close();
  226 + } finally {
188 227 }
189   - socketMessage.sendValue.tsSubCmds = [params];
190   - const { send, close } = useWebSocket(socketMessage.server, {
191   - onConnected() {
192   - send(JSON.stringify(socketMessage.sendValue));
193   - console.log('建立连接了');
194   - },
195   - onMessage(_, e) {
196   - const { data } = JSON.parse(e.data);
197   - if (Object.prototype.toString.call(data) === '[object Object]') {
198   - jsonWebsocketEditorRef.value?.setJsonValue(data);
199   - } else if (typeof data === 'string') {
200   - jsonWebsocketEditorRef.value?.setJsonValue(data);
201   - } else if (Array.isArray(data)) {
202   - jsonWebsocketEditorRef.value?.setJsonValue(JSON.stringify(data));
203   - } else {
204   - jsonEditorRef.value?.setJsonValue(JSON.stringify(data));
205   - }
206   - },
207   - onDisconnected() {
208   - console.log('断开连接了');
209   - close();
210   - },
211   - onError() {},
212   - });
213   - if (destroy) close();
214 228 };
215 229
216 230 onUnmounted(() => {
217   - if (isWebSocketType.value === '2') {
  231 + if (isWebSocketType.value === RequestMethodTypeEnum.WEBSOCKET) {
218 232 websocketRequest(null, true);
219 233 }
220 234 });
221 235
222   - //TODO: 待优化 项目自带第三方请求
  236 + //http请求
223 237 const otherHttpRequest = async (
224 238 apiType,
225 239 apiUrl,
... ... @@ -228,69 +242,27 @@
228 242 body,
229 243 token,
230 244 postToken,
231   - postBodyType,
232   - joinPrefix = false
  245 + postBodyType
233 246 ) => {
234   - const { convertObj } = useUtils();
  247 + const { convertObj, commonHttpParams, commonParams } = useUtils();
235 248 switch (apiType) {
236 249 case 'GET':
237   - const objGet = Object.assign(
238   - {},
239   - {
240   - 'X-Authorization': `Bearer ${!token ? postToken : token}`,
241   - },
242   - headers
243   - );
244 250 return await otherHttp.get(
245   - { url: apiUrl, params, headers: objGet },
246 251 {
247   - apiUrl: '',
248   - joinPrefix,
249   - withToken: false,
250   - errorMessageMode: 'none',
251   - }
252   - );
253   - case 'POST':
254   - const objPost = Object.assign(
255   - {},
256   - {
257   - 'X-Authorization': `Bearer ${!postToken ? token : postToken}`,
  252 + url: apiUrl,
  253 + params,
  254 + headers: commonHttpParams(postToken, token, postBodyType, headers),
258 255 },
259   - {
260   - 'Content-Type':
261   - postBodyType === 'xml'
262   - ? 'text/xml'
263   - : postBodyType === 'form-data'
264   - ? 'multipart/form-data'
265   - : postBodyType === 'x-www-form-urlencoded'
266   - ? 'application/x-www-form-urlencoded'
267   - : postBodyType === 'json'
268   - ? 'application/json'
269   - : 'application/json',
270   - },
271   - headers
  256 + commonParams
272 257 );
  258 + case 'POST':
273 259 return await otherHttp.post(
274   - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPost },
275 260 {
276   - apiUrl: '',
277   - joinPrefix,
278   - withToken: false,
279   - errorMessageMode: 'none',
280   - }
281   - );
282   - case 'PUT':
283   - const objPut = Object.assign({}, headers, {
284   - 'X-Authorization': `Bearer ${!postToken ? token : postToken}`,
285   - });
286   - return await otherHttp.put(
287   - { url: `${apiUrl}?${convertObj(params)}`, data: body, headers: objPut, params },
288   - {
289   - apiUrl: '',
290   - joinPrefix,
291   - withToken: false,
292   - errorMessageMode: 'none',
293   - }
  261 + url: `${apiUrl}${`?${convertObj(params)}`}`,
  262 + data: body,
  263 + headers: commonHttpParams(postToken, token, postBodyType, headers),
  264 + },
  265 + commonParams
294 266 );
295 267 }
296 268 };
... ... @@ -298,19 +270,25 @@
298 270 const resetValue = (flag) => {
299 271 if (flag) {
300 272 showTestFlag.value = false;
  273 + openFilterFlag.value = false;
301 274 }
302 275 nextTick(() => {
303 276 jsonEditorRef.value?.setJsonValue('测试结果为');
304   - jsonWebsocketEditorRef.value?.setJsonValue('测试结果为');
  277 + jsonEditorFilterRef.value?.setJsonValue('过滤结果为');
305 278 });
306   - isWebSocketType.value = '0';
  279 + isWebSocketType.value = RequestMethodTypeEnum.COMMOM;
307 280 };
308 281
309 282 const showTest = () => (showTestFlag.value = true);
310 283
  284 + const getFilterValue = () => {
  285 + return aceTypeIsJsEditorRef?.value?.getValue();
  286 + };
  287 +
311 288 defineExpose({
312 289 resetValue,
313 290 showTest,
  291 + getFilterValue,
314 292 });
315 293 </script>
316 294
... ... @@ -318,4 +296,11 @@
318 296 :deep(.ant-input-textarea-show-count) {
319 297 width: 30vw;
320 298 }
  299 +
  300 + .divider-color {
  301 + height: 78.5vh;
  302 + background-color: #e5e7eb;
  303 + position: relative;
  304 + left: 1.16vw;
  305 + }
321 306 </style>
... ...
... ... @@ -27,7 +27,6 @@
27 27 </div>
28 28 <Button
29 29 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
30   - class="ml-2"
31 30 @click="handleTest(isSingleClickText)"
32 31 type="primary"
33 32 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -42,7 +41,6 @@
42 41 </a-row>
43 42 </div>
44 43 </div>
45   - <div class="mt-8"> </div>
46 44 </div>
47 45 </template>
48 46 <script lang="ts" setup name="testRequest">
... ...
1   -<!-- eslint-disable vue/valid-v-model -->
2 1 <template>
3 2 <div class="table-content">
4   - <!-- TODO: 待优化测试表格 -->
5 3 <table align="center">
6 4 <thead>
7 5 <tr>
... ... @@ -10,10 +8,10 @@
10 8 </thead>
11 9 <tbody>
12 10 <tr v-for="(item, index) in tableTestArray.content" :key="index">
13   - <td style="width: 7.5vw">
14   - <a-input disabled placeholder="请输入" v-model:value="item.key" />
  11 + <td>
  12 + <a-input disabled v-model:value="item.key" />
15 13 </td>
16   - <td style="width: 6.5vw">
  14 + <td>
17 15 <a-input placeholder="请输入" v-model:value="item.value" />
18 16 </td>
19 17 </tr>
... ... @@ -27,12 +25,6 @@
27 25 import { tableItems } from '../../../config/types';
28 26 import { editTestCellTableTHeadConfig } from '../../../config/config';
29 27
30   - defineProps({
31   - method: {
32   - type: String,
33   - },
34   - });
35   -
36 28 const tableTestArray = reactive<{
37 29 content: tableItems[];
38 30 }>({
... ... @@ -57,6 +49,7 @@
57 49 const getValue = () => {
58 50 return tableTestArray.content;
59 51 };
  52 +
60 53 defineExpose({
61 54 getValue,
62 55 setTableArray,
... ... @@ -64,28 +57,5 @@
64 57 </script>
65 58
66 59 <style scoped lang="less">
67   - @table-color: #e5e7eb;
68   -
69   - .table-border-color {
70   - border: 1px solid #e5e7eb;
71   - text-align: center;
72   - }
73   -
74   - .table-content {
75   - table {
76   - width: 31vw;
77   - &:extend(.table-border-color);
78   - }
79   -
80   - table td {
81   - padding: 5px;
82   - white-space: nowrap;
83   - &:extend(.table-border-color);
84   - }
85   -
86   - table th {
87   - padding: 5px;
88   - &:extend(.table-border-color);
89   - }
90   - }
  60 + @import '../../SimpleRequest/common/commonTestTable.less';
91 61 </style>
... ...
... ... @@ -27,7 +27,6 @@
27 27 </div>
28 28 <Button
29 29 :disabled="interfaceType === 'SYSTEM' && isAdmin(role) ? testDisabled : false"
30   - class="ml-2"
31 30 @click="handleTest(isSingleClickText)"
32 31 type="primary"
33 32 >{{ `${isSingleClickText === 'open' ? '打开' : '关闭'}测试接口` }}
... ... @@ -42,7 +41,6 @@
42 41 </a-row>
43 42 </div>
44 43 </div>
45   - <div class="mt-8"> </div>
46 44 </div>
47 45 </template>
48 46 <script lang="ts" setup name="testRequest">
... ... @@ -59,6 +57,8 @@
59 57 import { USER_INFO_KEY } from '/@/enums/cacheEnum';
60 58 import { getAuthCache } from '/@/utils/auth';
61 59 import { isAdmin } from '/@/enums/roleEnum';
  60 + import { TableDefaultTypeEnum } from '../../../config/enum';
  61 + import { AggregateDataEnum } from '/@/views/report/config/timeConfig';
62 62
63 63 const userInfo: any = getAuthCache(USER_INFO_KEY);
64 64
... ... @@ -159,7 +159,7 @@
159 159 const getSingleKey = props.data?.list;
160 160 let getMuteDateRangeKeys: any = null;
161 161 const findDateRange = getSingleKey.find(
162   - (item) => item?.key == 'date_range' && item?.mores === true
  162 + (item) => item?.key == TableDefaultTypeEnum.DATERANGE && item?.mores === true
163 163 );
164 164 if (findDateRange) {
165 165 getMuteDateRangeKeys = getMultipleKeys([{ key: 'agg', value: '' }]);
... ... @@ -176,14 +176,13 @@
176 176 };
177 177
178 178 //测试表格里的数据转化为 key value 数组对象形式
179   - //TODO:待优化这里的TS类型
180 179 const getTestTableKeyValue = () => {
181 180 //把日期拆分成多个
182 181 const keyValueList: any = [];
183   - console.log(testEditCellTableRef.value?.getValue());
184 182 testEditCellTableRef.value?.getValue()?.forEach((item: any) => {
185   - const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : [];
186   - const splitDateValue = item?.key === 'date_range' ? item?.dateValue : [];
  183 + const splitDateKey =
  184 + item?.key === TableDefaultTypeEnum.DATERANGE ? item?.value?.split(',') : [];
  185 + const splitDateValue = item?.key === TableDefaultTypeEnum.DATERANGE ? item?.dateValue : [];
187 186 for (let i in splitDateKey) {
188 187 const obj = {
189 188 key: splitDateKey[i],
... ... @@ -195,17 +194,11 @@
195 194 return testEditCellTableRef.value
196 195 ?.getValue()
197 196 .concat(keyValueList)
198   - .filter((it) => it.key !== 'date_range')
  197 + .filter((it) => it.key !== TableDefaultTypeEnum.DATERANGE)
199 198 .map((it: any) => {
200   - const value =
201   - it?.key === 'scope'
202   - ? it?.keyValue
203   - : it?.key === 'fixed_date'
204   - ? moment(it?.fixed_date_value).valueOf()
205   - : it?.value;
206   - const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key;
  199 + const value = it?.key === TableDefaultTypeEnum.SCOPE ? it?.keyValue : it?.value;
  200 + const key = it?.key === TableDefaultTypeEnum.SCOPE ? it?.value : it?.key;
207 201 const limit = it?.limit;
208   - console.log(limit);
209 202 return {
210 203 key,
211 204 value,
... ... @@ -225,16 +218,15 @@
225 218 }
226 219 const params: any = {};
227 220 getTable?.map((it) => {
228   - console.log(it);
229 221 params[it.key!] = it.value!;
230   - if (it.key === 'agg') {
  222 + if (it.key === TableDefaultTypeEnum.AGG) {
231 223 params.limit = it.limit;
232 224 }
233 225 });
234 226 if (params['keys']) {
235 227 Reflect.set(params, 'keys', params['keys'].join(','));
236 228 }
237   - if (params['agg'] !== 'NONE') {
  229 + if (params['agg'] !== AggregateDataEnum.NONE) {
238 230 Reflect.set(params, 'limit', null);
239 231 }
240 232 excuteData.value = {
... ... @@ -246,6 +238,7 @@
246 238
247 239 //设置数据
248 240 const setValue = () => {
  241 + isSingleClickText.value = 'open';
249 242 showTestEditCell.value = false;
250 243 testResult.value = '';
251 244 selectTenant.value = undefined;
... ...
1   -<!-- eslint-disable vue/valid-v-model -->
2 1 <template>
3   - <!-- {{ tableTestArray.content }} -->
4 2 <div class="table-content">
5   - <!-- TODO: 待优化测试表格 -->
6 3 <table align="center">
7 4 <thead>
8 5 <tr>
... ... @@ -17,30 +14,18 @@
17 14 </thead>
18 15 <tbody>
19 16 <tr v-for="(item, index) in tableTestArray.content" :key="index">
20   - <td style="width: 7.5vw">
21   - <Select
22   - :getPopupContainer="
23   - (triggerNode) => {
24   - return triggerNode.parentNode;
25   - }
26   - "
27   - :disabled="true"
28   - v-model:value="item.key"
29   - placeholder="请选择"
30   - :options="selectOptions"
31   - />
  17 + <td>
  18 + <Select :disabled="true" v-model:value="item.key" :options="selectOptions" />
32 19 </td>
33   - <td style="width: 6.5vw">
34   - <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" />
  20 + <td style="width: 10.5vw">
  21 + <a-input
  22 + v-if="item.key === TableDefaultTypeEnum.SCOPE"
  23 + placeholder="请输入"
  24 + v-model:value="item.value"
  25 + />
35 26 <a-tree-select
36   - :getPopupContainer="
37   - (triggerNode) => {
38   - return triggerNode.parentNode;
39   - }
40   - "
41   - v-else-if="item.key === 'organizationId'"
  27 + v-else-if="item.key === TableDefaultTypeEnum.ORGANIZATIONID"
42 28 v-model:value="item.value"
43   - show-search
44 29 :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
45 30 placeholder="请选择组织"
46 31 allow-clear
... ... @@ -54,10 +39,9 @@
54 39 return triggerNode.parentNode;
55 40 }
56 41 "
57   - v-else-if="item.key === 'entityId'"
  42 + v-else-if="item.key === TableDefaultTypeEnum.ENTITYID"
58 43 v-model:value="item.value"
59 44 placeholder="请选择"
60   - notFoundContent="请选择"
61 45 :options="entityOptions"
62 46 allowClear
63 47 />
... ... @@ -67,24 +51,21 @@
67 51 return triggerNode.parentNode;
68 52 }
69 53 "
70   - v-else-if="item.key === 'keys'"
  54 + v-else-if="item.key === TableDefaultTypeEnum.KEYS"
71 55 v-model:value="item.value"
72 56 placeholder="请选择"
73   - notFoundContent="请选择"
74 57 :options="attributeOptions"
75 58 mode="multiple"
76 59 allowClear
77 60 />
78   - <!-- <div v-else-if="item.value === 'NONE'">
79   - <a-input-number id="inputNumber" v-model:value="item.value" :min="7" :max="5000000" />
80   - </div> -->
81   - <div v-else-if="item.key === 'date_range'">
82   - <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button>
  61 + <div v-else-if="item.key === TableDefaultTypeEnum.DATERANGE">
  62 + <a-button disabled type="primary">{{
  63 + (item.value as any)?.split(',').at(-2)
  64 + }}</a-button>
83 65 <span>~</span>
84   - <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button>
85   - </div>
86   - <div v-else-if="item.key === 'fixed_date'">
87   - <a-button disabled type="primary">{{ item.value }}</a-button>
  66 + <a-button disabled type="primary">{{
  67 + (item.value as any)?.split(',').at(-1)
  68 + }}</a-button>
88 69 </div>
89 70 <Select
90 71 :getPopupContainer="
... ... @@ -92,11 +73,10 @@
92 73 return triggerNode.parentNode;
93 74 }
94 75 "
95   - v-else-if="item.key === 'agg'"
  76 + v-else-if="item.key === TableDefaultTypeEnum.AGG"
96 77 v-model:value="item.value"
97 78 @change="onHandleAgg"
98 79 placeholder="请选择"
99   - notFoundContent="请选择"
100 80 :options="aggOptions"
101 81 allowClear
102 82 />
... ... @@ -106,10 +86,11 @@
106 86 return triggerNode.parentNode;
107 87 }
108 88 "
109   - v-else-if="item.key === 'interval' && item.value !== 'NONE'"
  89 + v-else-if="
  90 + item.key === TableDefaultTypeEnum.INTERVAL && item.value !== AggregateDataEnum.NONE
  91 + "
110 92 v-model:value="item.value"
111 93 placeholder="请选择"
112   - notFoundContent="请选择"
113 94 :options="intervalOptions"
114 95 allowClear
115 96 />
... ... @@ -122,28 +103,19 @@
122 103 v-else
123 104 v-model:value="item.value"
124 105 placeholder="请选择"
125   - notFoundContent="请选择"
126 106 :options="valueOptions"
127 107 allowClear
128 108 @change="handleValueChange(item)"
129 109 />
130 110 </td>
131   - <td style="width: 6.5vw">
  111 + <td>
132 112 <a-input
133   - v-if="item.key === 'scope'"
  113 + v-if="item.key === TableDefaultTypeEnum.SCOPE"
134 114 placeholder="请输入"
135 115 v-model:value="item.keyValue"
136 116 />
137   - <a-date-picker
138   - v-else-if="item.key === 'fixed_date'"
139   - style="width: 6.5vw"
140   - v-model:value="item.fixed_date_value"
141   - :show-time="{ format: 'HH:mm' }"
142   - format="YYYY-MM-DD HH:mm:ss"
143   - placeholder="日期时间"
144   - />
145 117 <a-range-picker
146   - v-else-if="item.key == 'date_range'"
  118 + v-else-if="item.key == TableDefaultTypeEnum.DATERANGE"
147 119 style="width: 10vw"
148 120 v-model:value="item.dateValue"
149 121 :disabled-date="disabledDate"
... ... @@ -154,11 +126,11 @@
154 126 @calendarChange="calendarPriceRangeChange"
155 127 @change="changePriceRangeDate"
156 128 format="YYYY-MM-DD HH:mm:ss"
157   - :placeholder="['开始', '结束']"
  129 + :placeholder="['开始日期', '结束日期']"
158 130 clearable
159 131 />
160 132 <a-input-number
161   - v-else-if="item.value == 'NONE'"
  133 + v-else-if="item.value == AggregateDataEnum.NONE"
162 134 v-model:value="item.limit"
163 135 :min="7"
164 136 :max="50000"
... ... @@ -168,7 +140,6 @@
168 140 </tr>
169 141 </tbody>
170 142 </table>
171   - <!-- {{ tableTestArray.content }} -->
172 143 </div>
173 144 </template>
174 145 <script lang="ts" setup name="editCellTable">
... ... @@ -185,6 +156,7 @@
185 156 import { AggregateDataEnum } from '/@/views/report/config/timeConfig';
186 157 import { getPacketIntervalByRange } from '/@/views/device/localtion/cpns/TimePeriodForm/helper';
187 158 import { uniqBy } from 'lodash';
  159 + import { TableDefaultTypeEnum } from '../../../config/enum';
188 160
189 161 const props = defineProps({
190 162 method: {
... ... @@ -211,7 +183,9 @@
211 183 value: 'scope',
212 184 });
213 185 if (props.method === '2')
214   - selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope');
  186 + selectOptions.value = selectOptions.value.filter(
  187 + (f) => f.value !== TableDefaultTypeEnum.SCOPE
  188 + );
215 189 });
216 190
217 191 const { isOtherHttp } = useUtils();
... ... @@ -246,8 +220,15 @@
246 220 });
247 221
248 222 const onHandleAgg = (e) => {
249   - if (e === 'NONE') {
250   - tableTestArray.content = tableTestArray.content.filter((item) => item.key !== 'interval');
  223 + if (e === AggregateDataEnum.NONE) {
  224 + tableTestArray.content = tableTestArray.content.filter(
  225 + (item) => item.key !== TableDefaultTypeEnum.INTERVAL
  226 + );
  227 + tableTestArray.content.forEach((it) => {
  228 + if (it.key === TableDefaultTypeEnum.AGG && it.value === AggregateDataEnum.NONE) {
  229 + it.limit = 7;
  230 + }
  231 + });
251 232 } else {
252 233 tableTestArray.content.push({
253 234 key: 'interval',
... ... @@ -259,8 +240,6 @@
259 240
260 241 const selectPriceDate = ref('');
261 242
262   - const offsetDays = 86400000 * 365;
263   -
264 243 const calendarPriceRangeChange = (date) => {
265 244 selectPriceDate.value = date[0];
266 245 intervalOptions.value = getPacketIntervalByRange(date) as any;
... ... @@ -270,6 +249,8 @@
270 249 selectPriceDate.value = '';
271 250 };
272 251
  252 + //时间跨度小于一年
  253 + const offsetDays = 86400000 * 365;
273 254 const disabledDate = (current) => {
274 255 if (selectPriceDate.value) {
275 256 let selectV = moment(selectPriceDate.value, 'YYYY-MM-DD').valueOf();
... ... @@ -286,34 +267,38 @@
286 267 const setTableArray = (data) => {
287 268 const list = cloneDeep(data);
288 269 list?.forEach((it) => {
289   - if (it.key === 'keys') it.value = [];
  270 + if (it?.value === TableDefaultTypeEnum.ENTITYTYPE) it.keyValue = TableDefaultTypeEnum.DEVICE;
  271 + if (it.key === TableDefaultTypeEnum.KEYS) it.value = [];
290 272 });
291 273 if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list);
292 274 };
293 275
  276 + //获取组织和产品
294 277 const getApi = (list) => {
295 278 list?.forEach(async (it) => {
296   - if (it.key === 'deviceProfileId') {
  279 + if (it.key === TableDefaultTypeEnum.DEVICEPROFILEID) {
297 280 const { options } = await useApi(it.key, props.token);
298 281 valueOptions.value = options;
299   - } else if (it.key === 'organizationId') {
  282 + } else if (it.key === TableDefaultTypeEnum.ORGANIZATIONID) {
300 283 const { options } = await useApi(it.key, props.token);
301 284 treeData.value = options as any;
302 285 }
303 286 });
304 287 };
305 288
  289 + //组织Select改变
306 290 const handleOrgnationChange = async (e) => {
307 291 let deviceProfileId = '';
308 292 tableTestArray.content.forEach((f: any) => {
309   - if (f.key === 'entityId') {
  293 + if (f.key === TableDefaultTypeEnum.ENTITYID) {
310 294 f.value = null;
311 295 }
312   - if (f.key === 'deviceProfileId') deviceProfileId = f.value;
  296 + if (f.key === TableDefaultTypeEnum.DEVICEPROFILEID) deviceProfileId = f.value;
313 297 });
314 298 getEntityOptions(e.value, deviceProfileId);
315 299 };
316 300
  301 + //设备Select改变
317 302 const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => {
318 303 const res = await isOtherHttp('api/yt/device/list', props.token, {
319 304 organizationId,
... ... @@ -325,6 +310,7 @@
325 310 }));
326 311 };
327 312
  313 + //属性Select改变
328 314 const getAttributeOptions = async (params) => {
329 315 const { deviceProfileId, dataType } = params;
330 316 const res = await isOtherHttp(`api/yt/device/attributes/${deviceProfileId}`, props.token, {
... ... @@ -334,15 +320,16 @@
334 320 attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier }));
335 321 };
336 322
  323 + //产品Select改变
337 324 const handleValueChange = (e) => {
338 325 let organizationId = '';
339   - if (e.key === 'deviceProfileId') {
  326 + if (e.key === TableDefaultTypeEnum.DEVICEPROFILEID) {
340 327 tableTestArray.content.forEach((f: any) => {
341   - if (f.key === 'keys') {
  328 + if (f.key === TableDefaultTypeEnum.KEYS) {
342 329 f.value = [];
343 330 }
344   - if (f.key === 'organizationId') organizationId = f.value;
345   - if (f.key === 'entityId') f.value = null;
  331 + if (f.key === TableDefaultTypeEnum.ORGANIZATIONID) organizationId = f.value;
  332 + if (f.key === TableDefaultTypeEnum.ENTITYID) f.value = null;
346 333 });
347 334 if (e.value) {
348 335 getAttributeOptions({ deviceProfileId: e.value });
... ... @@ -357,6 +344,7 @@
357 344 const getValue = () => {
358 345 return tableTestArray.content;
359 346 };
  347 +
360 348 defineExpose({
361 349 getValue,
362 350 setTableArray,
... ... @@ -364,28 +352,5 @@
364 352 </script>
365 353
366 354 <style scoped lang="less">
367   - @table-color: #e5e7eb;
368   -
369   - .table-border-color {
370   - border: 1px solid #e5e7eb;
371   - text-align: center;
372   - }
373   -
374   - .table-content {
375   - table {
376   - width: 31vw;
377   - &:extend(.table-border-color);
378   - }
379   -
380   - table td {
381   - padding: 5px;
382   - white-space: nowrap;
383   - &:extend(.table-border-color);
384   - }
385   -
386   - table th {
387   - padding: 5px;
388   - &:extend(.table-border-color);
389   - }
390   - }
  355 + @import '../../SimpleRequest/common/commonTestTable.less';
391 356 </style>
... ...
1   -import TestSql from './index.vue';
2   -
3   -export { TestSql };
1   -<template>
2   - <div class="mt-8">
3   - <div>
4   - <Button @click="handleExcute" type="primary"> 测试SQL </Button>
5   - </div>
6   - </div>
7   - <div v-if="testResultStatus" class="mt-8">
8   - <div class="mt-8">
9   - <a-row type="flex" justify="center">
10   - <a-col :span="3"> 测试结果 </a-col>
11   - <a-col :span="21">
12   - <a-textarea
13   - allow-clear
14   - show-count
15   - v-model:value="testResult"
16   - placeholder="测试结果为:"
17   - :rows="8"
18   - />
19   - </a-col>
20   - </a-row>
21   - </div>
22   - </div>
23   -</template>
24   -<script lang="ts" setup name="testRequest">
25   - import { ref } from 'vue';
26   - import { Button } from 'ant-design-vue';
27   -
28   - defineProps({
29   - method: {
30   - type: String,
31   - },
32   - });
33   -
34   - const testResult = ref('');
35   -
36   - const testResultStatus = ref(false);
37   -
38   - const handleExcute = async () => {
39   - testResultStatus.value = true;
40   - testResult.value = '测试结果为:1234';
41   - };
42   -
43   - const resetValue = () => (testResult.value = '');
44   -
45   - defineExpose({
46   - resetValue,
47   - });
48   -</script>
49   -
50   -<style scoped lang="less"></style>
... ... @@ -288,14 +288,6 @@ export const schemas: FormSchema[] = [
288 288 colProps: { span: 24 },
289 289 ifShow: ({ values }) => values['requestContentType'] !== '1',
290 290 },
291   - {
292   - field: 'testSlot',
293   - label: '',
294   - component: 'Input',
295   - slot: 'testSql',
296   - colProps: { span: 24 },
297   - ifShow: ({ values }) => values['requestContentType'] === '1',
298   - },
299 291 ];
300 292
301 293 //表格表头配置
... ...
... ... @@ -35,3 +35,27 @@ export enum RequestHttpTypeEnum {
35 35 GET = 'GET',
36 36 POST = 'POST',
37 37 }
  38 +
  39 +/**
  40 + * @description: 在线编辑器枚举
  41 + */
  42 +export enum OnlineEditorTypeEnum {
  43 + JAVASCRIPT = 'javascript',
  44 + XML = 'xml',
  45 +}
  46 +
  47 +/**
  48 + * @description:表格内置默认属性枚举
  49 + */
  50 +export enum TableDefaultTypeEnum {
  51 + ORGANIZATIONID = 'organizationId',
  52 + SCOPE = 'scope',
  53 + ENTITYID = 'entityId',
  54 + KEYS = 'keys',
  55 + DATERANGE = 'date_range',
  56 + AGG = 'agg',
  57 + INTERVAL = 'interval',
  58 + DEVICEPROFILEID = 'deviceProfileId',
  59 + ENTITYTYPE = 'entityType',
  60 + DEVICE = 'DEVICE',
  61 +}
... ...
1 1 import { commonHttpPlaceHolder, websocketPlaceHolder } from '../config/constants';
2 2 import { RequestMethodTypeEnum } from '../config/enum';
3 3 import { otherHttp } from '/@/utils/http/axios';
  4 +import { tableItems } from '../config/types';
4 5
5 6 export const useUtils = () => {
6 7 //获取多个key
... ... @@ -46,15 +47,19 @@ export const useUtils = () => {
46 47 //对象转get params参数
47 48 const convertObj = (data: object) => {
48 49 const _result: any = [];
49   - for (const key in data) {
50   - const value = data[key];
51   - if (value.constructor == Array) {
52   - value.forEach(function (_value) {
53   - _result.push(key + '=' + _value);
54   - });
55   - } else {
56   - _result.push(key + '=' + value);
  50 + try {
  51 + for (const key in data) {
  52 + const value = data[key];
  53 + if (value.constructor == Array) {
  54 + value.forEach(function (_value) {
  55 + _result.push(key + '=' + _value);
  56 + });
  57 + } else {
  58 + _result.push(key + '=' + value);
  59 + }
57 60 }
  61 + } catch (e) {
  62 + console.log(`Post没有传递params${e}`);
58 63 }
59 64 return _result.join('&');
60 65 };
... ... @@ -104,6 +109,128 @@ export const useUtils = () => {
104 109 : ''
105 110 }`;
106 111
  112 + //动态获取post请求ContentType类型
  113 + const contentTypeStatic = [
  114 + {
  115 + key: 'xml',
  116 + value: 'text/xml',
  117 + },
  118 + {
  119 + key: 'form-data',
  120 + value: 'multipart/form-data',
  121 + },
  122 + {
  123 + key: 'x-www-form-urlencoded',
  124 + value: 'application/x-www-form-urlencoded',
  125 + },
  126 + {
  127 + key: 'json',
  128 + value: 'application/json',
  129 + },
  130 + ];
  131 +
  132 + const getContentType = (contentType) => {
  133 + const findValue = contentTypeStatic.find((it) => it.key === contentType)?.value;
  134 + if (findValue) return findValue;
  135 + return contentTypeStatic.at(-1)?.value;
  136 + };
  137 +
  138 + const commonHttpParams = (postToken, token, postBodyType, headers) => {
  139 + const mergeHeaders = Object.assign(
  140 + {},
  141 + {
  142 + 'X-Authorization': `Bearer ${!postToken ? token : postToken}`,
  143 + },
  144 + !postBodyType
  145 + ? null
  146 + : {
  147 + 'Content-Type': getContentType(postBodyType),
  148 + },
  149 + headers
  150 + );
  151 + return mergeHeaders;
  152 + };
  153 +
  154 + //websocket请求静态参数
  155 + const staticWebSocketParams = {
  156 + cmdId: 1,
  157 + scope: 'LATEST_TELEMETRY',
  158 + entityType: 'DEVICE',
  159 + };
  160 +
  161 + const commonRest = (data, fn) => {
  162 + if (Object.prototype.toString.call(data) === '[object Object]') {
  163 + fn(data);
  164 + } else if (typeof data === 'string') {
  165 + fn(data);
  166 + } else if (Array.isArray(data)) {
  167 + const temp = {
  168 + data,
  169 + };
  170 + fn(temp);
  171 + } else {
  172 + fn(JSON.stringify(data));
  173 + }
  174 + };
  175 +
  176 + const commonParams = {
  177 + apiUrl: '',
  178 + joinPrefix: false,
  179 + withToken: false,
  180 + errorMessageMode: 'none',
  181 + } as any;
  182 +
  183 + //表格基类
  184 + class CommonFuncValue {
  185 + constructor(public data: tableItems[]) {
  186 + this.data = data;
  187 + }
  188 + get(): tableItems[] {
  189 + return this.data;
  190 + }
  191 + set(outderData: tableItems[]) {
  192 + this.data = outderData;
  193 + }
  194 + reset(): void {
  195 + this.data = [];
  196 + this.data.push({
  197 + key: '',
  198 + value: '',
  199 + required: false,
  200 + });
  201 + }
  202 + }
  203 +
  204 + //paramsTable覆盖父类
  205 + class ParamsFuncValue extends CommonFuncValue {
  206 + constructor(public data: tableItems[], public mores: boolean) {
  207 + super(data);
  208 + this.mores = mores;
  209 + }
  210 + get(): tableItems[] {
  211 + return this.data.map((it) => {
  212 + return {
  213 + key: it.key,
  214 + value: it.key === 'date_range' ? `${it.date1},${it.date2}` : it.value,
  215 + mores: it.key === 'date_range' ? this.mores : null,
  216 + editDisabled: it.editDisabled,
  217 + required: it.required,
  218 + };
  219 + });
  220 + }
  221 + reset(): void {
  222 + this.data = [];
  223 + this.data.push({
  224 + key: undefined,
  225 + value: '',
  226 + editDisabled: false,
  227 + required: false,
  228 + date1: '',
  229 + date2: '',
  230 + });
  231 + }
  232 + }
  233 +
107 234 return {
108 235 getMultipleKeys,
109 236 pushObj,
... ... @@ -113,5 +240,11 @@ export const useUtils = () => {
113 240 convertObj,
114 241 isOtherHttp,
115 242 usePlaceholder,
  243 + commonHttpParams,
  244 + staticWebSocketParams,
  245 + commonRest,
  246 + commonParams,
  247 + CommonFuncValue,
  248 + ParamsFuncValue,
116 249 };
117 250 };
... ...