Showing
9 changed files
with
539 additions
and
51 deletions
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | <!--TODO: 待优化三者共存下的测试和是否能复用表格 --> | 3 | <!--TODO: 待优化三者共存下的测试和是否能复用表格 --> |
4 | - <Tabs @change="handleTabsChange" v-model:activeKey="activeKey"> | 4 | + <Tabs @change="handleChange" v-model:activeKey="activeKey"> |
5 | <TabPane class="tab-pane" forceRender key="Params" tab="Params"> | 5 | <TabPane class="tab-pane" forceRender key="Params" tab="Params"> |
6 | <ParamsTable ref="paramsCellTableRef" :method="method" /> | 6 | <ParamsTable ref="paramsCellTableRef" :method="method" /> |
7 | <ParamsTest | 7 | <ParamsTest |
@@ -16,10 +16,11 @@ | @@ -16,10 +16,11 @@ | ||
16 | forceRender | 16 | forceRender |
17 | key="Body" | 17 | key="Body" |
18 | tab="Body" | 18 | tab="Body" |
19 | + disabled | ||
19 | > | 20 | > |
20 | <Body ref="bodyRef" /> | 21 | <Body ref="bodyRef" /> |
21 | - <ParamsTest | ||
22 | - @testInterface="handleTestBodyInterface" | 22 | + <BodyTest |
23 | + @testBodyInterface="handleTestBodyInterface" | ||
23 | ref="testBodyRequestRef" | 24 | ref="testBodyRequestRef" |
24 | :data="dataMap.mapBodyObj" | 25 | :data="dataMap.mapBodyObj" |
25 | /> | 26 | /> |
@@ -40,7 +41,7 @@ | @@ -40,7 +41,7 @@ | ||
40 | import { ref, nextTick, reactive } from 'vue'; | 41 | import { ref, nextTick, reactive } from 'vue'; |
41 | import { Tabs, TabPane } from 'ant-design-vue'; | 42 | import { Tabs, TabPane } from 'ant-design-vue'; |
42 | import Body from './components/body.vue'; | 43 | import Body from './components/body.vue'; |
43 | - import { ParamsTest, HeaderTest } from '../TestInterface/index'; | 44 | + import { ParamsTest, HeaderTest, BodyTest } from '../TestInterface/index'; |
44 | import HeaderTable from './components/headerTable.vue'; | 45 | import HeaderTable from './components/headerTable.vue'; |
45 | import ParamsTable from './components/paramsTable.vue'; | 46 | import ParamsTable from './components/paramsTable.vue'; |
46 | import { isEmpty } from '/@/utils/is'; | 47 | import { isEmpty } from '/@/utils/is'; |
@@ -87,10 +88,15 @@ | @@ -87,10 +88,15 @@ | ||
87 | mapHeaderObj: {}, | 88 | mapHeaderObj: {}, |
88 | }); | 89 | }); |
89 | 90 | ||
90 | - const handleTabsChange = () => { | ||
91 | - // testParamsRequestRef.value?.setValue(); | ||
92 | - // testBodyRequestRef.value?.setValue(); | ||
93 | - // testHeaderRequestRef.value?.setValue(); | 91 | + const handleChange = () => { |
92 | + // excuteTestRef.value?.resetValue(); | ||
93 | + }; | ||
94 | + | ||
95 | + const handleClickReset = () => { | ||
96 | + testParamsRequestRef.value?.setValue(); | ||
97 | + testHeaderRequestRef.value?.setValue(); | ||
98 | + testBodyRequestRef.value?.setValue(); | ||
99 | + excuteTestRef.value?.resetValue(); | ||
94 | }; | 100 | }; |
95 | 101 | ||
96 | //if-else-if-else分支优化 | 102 | //if-else-if-else分支优化 |
@@ -104,14 +110,12 @@ | @@ -104,14 +110,12 @@ | ||
104 | excuteData.value = { | 110 | excuteData.value = { |
105 | Params: testParamsRequestRef.value?.getTestValue(), | 111 | Params: testParamsRequestRef.value?.getTestValue(), |
106 | Header: testHeaderRequestRef.value?.getTestValue(), | 112 | Header: testHeaderRequestRef.value?.getTestValue(), |
113 | + Body: testBodyRequestRef.value?.getTestValue(), | ||
107 | }; | 114 | }; |
108 | }; | 115 | }; |
109 | 116 | ||
110 | - //TODO: 待优化这里测试接口 | ||
111 | - const handleTestParamsInterface = () => { | ||
112 | - let value = getValue(false) as any; | ||
113 | - dataMap.mapParamsObj = { | ||
114 | - list: value?.Params, | 117 | + const getCompose = () => { |
118 | + return { | ||
115 | requestOriginUrl: props.requestOriginUrl, | 119 | requestOriginUrl: props.requestOriginUrl, |
116 | requestTypeAndUrl: props.requestTypeAndUrl, | 120 | requestTypeAndUrl: props.requestTypeAndUrl, |
117 | method: props.method, | 121 | method: props.method, |
@@ -119,25 +123,35 @@ | @@ -119,25 +123,35 @@ | ||
119 | }; | 123 | }; |
120 | }; | 124 | }; |
121 | 125 | ||
126 | + const handleTestParamsInterface = () => { | ||
127 | + excuteTestRef.value?.showTest(); | ||
128 | + let value = getValue(false) as any; | ||
129 | + dataMap.mapParamsObj = { | ||
130 | + list: value?.Params, | ||
131 | + ...getCompose(), | ||
132 | + }; | ||
133 | + }; | ||
134 | + | ||
122 | const handleTestBodyInterface = () => { | 135 | const handleTestBodyInterface = () => { |
136 | + excuteTestRef.value?.showTest(); | ||
123 | let value = getValue(false) as any; | 137 | let value = getValue(false) as any; |
138 | + const type = value?.Body?.requestParamsBodyType; | ||
139 | + console.log(type); | ||
140 | + console.log(value?.Body); | ||
141 | + //取出对应的类型 | ||
142 | + | ||
124 | dataMap.mapBodyObj = { | 143 | dataMap.mapBodyObj = { |
125 | list: value?.Body, | 144 | list: value?.Body, |
126 | - requestOriginUrl: props.requestOriginUrl, | ||
127 | - requestTypeAndUrl: props.requestTypeAndUrl, | ||
128 | - method: props.method, | ||
129 | - activeKey: activeKey.value, | 145 | + ...getCompose(), |
130 | }; | 146 | }; |
131 | }; | 147 | }; |
132 | 148 | ||
133 | const handleTestHeaderInterface = () => { | 149 | const handleTestHeaderInterface = () => { |
150 | + excuteTestRef.value?.showTest(); | ||
134 | let value = getValue(false) as any; | 151 | let value = getValue(false) as any; |
135 | dataMap.mapHeaderObj = { | 152 | dataMap.mapHeaderObj = { |
136 | list: value?.Header, | 153 | list: value?.Header, |
137 | - requestOriginUrl: props.requestOriginUrl, | ||
138 | - requestTypeAndUrl: props.requestTypeAndUrl, | ||
139 | - method: props.method, | ||
140 | - activeKey: activeKey.value, | 154 | + ...getCompose(), |
141 | }; | 155 | }; |
142 | }; | 156 | }; |
143 | 157 | ||
@@ -173,7 +187,7 @@ | @@ -173,7 +187,7 @@ | ||
173 | paramsCellTableRef.value?.resetValue(); | 187 | paramsCellTableRef.value?.resetValue(); |
174 | editHeaderCellTableRef.value?.resetValue(); | 188 | editHeaderCellTableRef.value?.resetValue(); |
175 | bodyRef.value?.resetValue(); | 189 | bodyRef.value?.resetValue(); |
176 | - handleTabsChange(); | 190 | + handleClickReset(); |
177 | }); | 191 | }); |
178 | }; | 192 | }; |
179 | 193 |
1 | +<template> | ||
2 | + <div> | ||
3 | + <div class="mt-8"> | ||
4 | + <div> | ||
5 | + <Button @click="handleTest" type="primary"> 测试接口 </Button> | ||
6 | + </div> | ||
7 | + <div v-if="showTestEditCell" class="mt-8"> | ||
8 | + <a-row type="flex" justify="center"> | ||
9 | + <a-col :span="3"> 参数设置 </a-col> | ||
10 | + <a-col :span="21"> | ||
11 | + <TestBodyCellTable ref="testEditCellTableRef" /> | ||
12 | + </a-col> | ||
13 | + </a-row> | ||
14 | + </div> | ||
15 | + </div> | ||
16 | + <div class="mt-8"> </div> | ||
17 | + </div> | ||
18 | +</template> | ||
19 | +<script lang="ts" setup name="testRequest"> | ||
20 | + import { ref, nextTick } from 'vue'; | ||
21 | + import { Button } from 'ant-design-vue'; | ||
22 | + import TestBodyCellTable from './testEditBodyCellTable.vue'; | ||
23 | + import moment from 'moment'; | ||
24 | + import { useUtils } from '../../../hooks/useUtils'; | ||
25 | + | ||
26 | + const emits = defineEmits(['testBodyInterface']); | ||
27 | + | ||
28 | + const props = defineProps({ | ||
29 | + data: { | ||
30 | + type: Object, | ||
31 | + }, | ||
32 | + }); | ||
33 | + | ||
34 | + const showTestEditCell = ref(false); | ||
35 | + | ||
36 | + const excuteData = ref({}); | ||
37 | + | ||
38 | + const testEditCellTableRef = ref<InstanceType<typeof TestBodyCellTable>>(); | ||
39 | + | ||
40 | + const testResult = ref(''); | ||
41 | + | ||
42 | + const { getMultipleKeys } = useUtils(); | ||
43 | + | ||
44 | + const handleTest = () => { | ||
45 | + showTestEditCell.value = true; | ||
46 | + emits('testBodyInterface'); | ||
47 | + getValue(); | ||
48 | + }; | ||
49 | + | ||
50 | + const getValue = async () => { | ||
51 | + await nextTick(); | ||
52 | + await nextTick(() => { | ||
53 | + //拆分"xx,xx,xx"多个 | ||
54 | + const getSingleKey = props.data?.list; | ||
55 | + const getMuteKey = props.data?.list?.filter((it: any) => it.key.split(',').length > 1); | ||
56 | + const getMuteKeys = getMultipleKeys(getMuteKey); | ||
57 | + const mergeKeys = [...getSingleKey, ...getMuteKeys]?.filter( | ||
58 | + (it: any) => it.key.split(',').length === 1 | ||
59 | + ); | ||
60 | + testEditCellTableRef.value?.setTableArray(mergeKeys); | ||
61 | + }); | ||
62 | + }; | ||
63 | + | ||
64 | + //测试表格里的数据转化为 key value 数组对象形式 | ||
65 | + //TODO:待优化这里的TS类型 | ||
66 | + const getTestTableKeyValue = () => { | ||
67 | + //把日期拆分成多个 | ||
68 | + const keyValueList: any = []; | ||
69 | + testEditCellTableRef.value?.getValue()?.forEach((item: any) => { | ||
70 | + const splitDateKey = item?.key === 'date_range' ? item?.value?.split(',') : []; | ||
71 | + const splitDateValue = item?.key === 'date_range' ? item?.dateValue : []; | ||
72 | + for (let i in splitDateKey) { | ||
73 | + const obj = { | ||
74 | + key: splitDateKey[i], | ||
75 | + value: moment(splitDateValue[i]).valueOf(), | ||
76 | + }; | ||
77 | + keyValueList.push(obj); | ||
78 | + } | ||
79 | + }); | ||
80 | + return testEditCellTableRef.value | ||
81 | + ?.getValue() | ||
82 | + .concat(keyValueList) | ||
83 | + .filter((it) => it.key !== 'date_range') | ||
84 | + .map((it: any) => { | ||
85 | + const value = | ||
86 | + it?.key === 'scope' | ||
87 | + ? it?.keyValue | ||
88 | + : it?.key === 'fixed_date' | ||
89 | + ? moment(it?.fixed_date_value).valueOf() | ||
90 | + : it?.value; | ||
91 | + const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key; | ||
92 | + return { | ||
93 | + key, | ||
94 | + value, | ||
95 | + }; | ||
96 | + }); | ||
97 | + }; | ||
98 | + | ||
99 | + //获取数据 | ||
100 | + const getTestValue = () => { | ||
101 | + const getTable = getTestTableKeyValue(); | ||
102 | + //源地址 | ||
103 | + const apiGetUrl = `${props.data?.requestOriginUrl}${props.data?.requestTypeAndUrl?.requestUrl}`; | ||
104 | + //请求类型 | ||
105 | + const apiType = props.data?.requestTypeAndUrl?.requestHttpType; | ||
106 | + //替换key value | ||
107 | + const params: any = {}; | ||
108 | + getTable?.map((it) => (params[it.key!] = it.value!)); | ||
109 | + excuteData.value = { | ||
110 | + apiGetUrl, | ||
111 | + apiType, | ||
112 | + params, | ||
113 | + activeKey: props.data?.activeKey, | ||
114 | + }; | ||
115 | + return excuteData.value; | ||
116 | + }; | ||
117 | + | ||
118 | + //设置数据 | ||
119 | + const setValue = () => { | ||
120 | + showTestEditCell.value = false; | ||
121 | + testResult.value = ''; | ||
122 | + }; | ||
123 | + | ||
124 | + defineExpose({ | ||
125 | + setValue, | ||
126 | + handleTest, | ||
127 | + getTestValue, | ||
128 | + }); | ||
129 | +</script> | ||
130 | + | ||
131 | +<style scoped lang="less"></style> |
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">{{ item }}</th> | ||
9 | + </tr> | ||
10 | + </thead> | ||
11 | + <tbody> | ||
12 | + <tr v-for="(item, index) in tableTestArray.content" :key="index"> | ||
13 | + <td style="width: 7.5vw"> | ||
14 | + <Select | ||
15 | + :disabled="true" | ||
16 | + v-model:value="item.key" | ||
17 | + placeholder="请选择" | ||
18 | + :options="selectOptions" | ||
19 | + /> | ||
20 | + </td> | ||
21 | + <td style="width: 6.5vw"> | ||
22 | + <a-input v-if="item.key === 'scope'" placeholder="请输入" v-model:value="item.value" /> | ||
23 | + <a-tree-select | ||
24 | + v-else-if="item.key === 'organizationId'" | ||
25 | + v-model:value="item.value" | ||
26 | + show-search | ||
27 | + :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" | ||
28 | + placeholder="请选择组织" | ||
29 | + allow-clear | ||
30 | + tree-default-expand-all | ||
31 | + :tree-data="treeData" | ||
32 | + @change="handleOrgnationChange(item)" | ||
33 | + /> | ||
34 | + <Select | ||
35 | + v-else-if="item.key === 'entityId'" | ||
36 | + v-model:value="item.value" | ||
37 | + placeholder="请选择" | ||
38 | + notFoundContent="请选择" | ||
39 | + :options="entityOptions" | ||
40 | + allowClear | ||
41 | + /> | ||
42 | + <Select | ||
43 | + v-else-if="item.key === 'keys'" | ||
44 | + v-model:value="item.value" | ||
45 | + placeholder="请选择" | ||
46 | + notFoundContent="请选择" | ||
47 | + :options="attributeOptions" | ||
48 | + allowClear | ||
49 | + /> | ||
50 | + <div v-else-if="item.key === 'date_range'"> | ||
51 | + <a-button disabled type="primary">{{ item.value?.split(',').at(-2) }}</a-button> | ||
52 | + <span>~</span> | ||
53 | + <a-button disabled type="primary">{{ item.value?.split(',').at(-1) }}</a-button> | ||
54 | + </div> | ||
55 | + <div v-else-if="item.key === 'fixed_date'"> | ||
56 | + <a-button disabled type="primary">{{ item.value }}</a-button> | ||
57 | + </div> | ||
58 | + <Select | ||
59 | + v-else | ||
60 | + v-model:value="item.value" | ||
61 | + placeholder="请选择" | ||
62 | + notFoundContent="请选择" | ||
63 | + :options="valueOptions" | ||
64 | + allowClear | ||
65 | + @change="handleValueChange(item)" | ||
66 | + /> | ||
67 | + </td> | ||
68 | + <td style="width: 6.5vw"> | ||
69 | + <a-input | ||
70 | + v-if="item.key === 'scope'" | ||
71 | + placeholder="请输入" | ||
72 | + v-model:value="item.keyValue" | ||
73 | + /> | ||
74 | + <a-date-picker | ||
75 | + v-else-if="item.key === 'fixed_date'" | ||
76 | + style="width: 6.5vw" | ||
77 | + v-model:value="item.keyValue" | ||
78 | + :show-time="{ format: 'HH:mm' }" | ||
79 | + format="YYYY-MM-DD HH:mm:ss" | ||
80 | + placeholder="日期时间" | ||
81 | + /> | ||
82 | + <a-range-picker | ||
83 | + v-else-if="item.key == 'date_range'" | ||
84 | + style="width: 6.5vw" | ||
85 | + v-model:value="item.dateValue" | ||
86 | + :show-time="{ format: 'HH:mm' }" | ||
87 | + format="YYYY-MM-DD HH:mm" | ||
88 | + :placeholder="['开始', '结束']" | ||
89 | + /> | ||
90 | + <a-input v-else disabled placeholder="请输入" v-model:value="item.keyValue" /> | ||
91 | + </td> | ||
92 | + </tr> | ||
93 | + </tbody> | ||
94 | + </table> | ||
95 | + </div> | ||
96 | +</template> | ||
97 | +<script lang="ts" setup name="editCellTable"> | ||
98 | + import { reactive, ref, onMounted } from 'vue'; | ||
99 | + import { Select } from 'ant-design-vue'; | ||
100 | + import { findDictItemByCode } from '/@/api/system/dict'; | ||
101 | + import { getAllDeviceByOrg } from '/@/api/dataBoard'; | ||
102 | + import { getDeviceAttributes } from '/@/api/dataBoard'; | ||
103 | + import { useApi } from '../../../hooks/useApi'; | ||
104 | + import { cloneDeep } from 'lodash-es'; | ||
105 | + import { tableItems, selectType } from '../../../types'; | ||
106 | + import { editTestCellTableTHeadConfig } from '../../../config'; | ||
107 | + | ||
108 | + const props = defineProps({ | ||
109 | + method: { | ||
110 | + type: String, | ||
111 | + }, | ||
112 | + }); | ||
113 | + | ||
114 | + onMounted(async () => { | ||
115 | + const res = await findDictItemByCode({ dictCode: 'dataview_builtin_params' }); | ||
116 | + selectOptions.value = res.map((m) => ({ label: m.itemText, value: m.itemValue })); | ||
117 | + selectOptions.value.push({ | ||
118 | + label: '自定义', | ||
119 | + value: 'scope', | ||
120 | + }); | ||
121 | + if (props.method === '2') | ||
122 | + selectOptions.value = selectOptions.value.filter((f) => f.value !== 'scope'); | ||
123 | + }); | ||
124 | + | ||
125 | + const selectOptions = ref<selectType[]>([]); | ||
126 | + | ||
127 | + const valueOptions = ref<selectType[]>([]); | ||
128 | + | ||
129 | + const entityOptions = ref<selectType[]>([]); | ||
130 | + | ||
131 | + const attributeOptions = ref<selectType[]>([]); | ||
132 | + | ||
133 | + const treeData = ref([]); | ||
134 | + | ||
135 | + const tableTestArray = reactive<{ | ||
136 | + content: tableItems[]; | ||
137 | + }>({ | ||
138 | + content: [ | ||
139 | + { | ||
140 | + key: undefined, | ||
141 | + value: undefined, | ||
142 | + keyValue: null, | ||
143 | + editDisabled: false, | ||
144 | + dateValue: null, | ||
145 | + }, | ||
146 | + ], | ||
147 | + }); | ||
148 | + | ||
149 | + //设置数据 | ||
150 | + const setTableArray = (data) => { | ||
151 | + const list = cloneDeep(data); | ||
152 | + if (Array.isArray(list)) (tableTestArray.content = list) && getApi(list); | ||
153 | + if (list.hasOwnProperty('form-data') && Array.isArray(list['form-data'])) | ||
154 | + (tableTestArray.content = list['form-data']) && getApi(list['form-data']); | ||
155 | + if ( | ||
156 | + list.hasOwnProperty('x-www-form-urlencoded') && | ||
157 | + Array.isArray(list['x-www-form-urlencoded']) | ||
158 | + ) | ||
159 | + (tableTestArray.content = list['x-www-form-urlencoded']) && | ||
160 | + getApi(list['x-www-form-urlencoded']); | ||
161 | + }; | ||
162 | + | ||
163 | + const getApi = (list) => { | ||
164 | + list?.forEach(async (it) => { | ||
165 | + if (it.key === 'deviceProfileId') { | ||
166 | + const { options } = await useApi(it.key); | ||
167 | + valueOptions.value = options; | ||
168 | + } else if (it.key === 'organizationId') { | ||
169 | + const { options } = await useApi(it.key); | ||
170 | + treeData.value = options as any; | ||
171 | + } | ||
172 | + }); | ||
173 | + }; | ||
174 | + | ||
175 | + const handleOrgnationChange = async (e) => { | ||
176 | + let deviceProfileId = ''; | ||
177 | + tableTestArray.content.forEach((f: any) => { | ||
178 | + if (f.key === 'entityId') { | ||
179 | + f.value = null; | ||
180 | + } | ||
181 | + if (f.key === 'deviceProfileId') deviceProfileId = f.value; | ||
182 | + }); | ||
183 | + getEntityOptions(e.value, deviceProfileId); | ||
184 | + }; | ||
185 | + | ||
186 | + const getEntityOptions = async (organizationId: string, deviceProfileId?: string) => { | ||
187 | + const res = await getAllDeviceByOrg(organizationId, deviceProfileId); | ||
188 | + entityOptions.value = res.map((item) => ({ | ||
189 | + label: item.name, | ||
190 | + value: item.tbDeviceId, | ||
191 | + })); | ||
192 | + }; | ||
193 | + | ||
194 | + const getAttributeOptions = async (params) => { | ||
195 | + const res = await getDeviceAttributes(params); | ||
196 | + if (Object.keys(res).length === 0) return (attributeOptions.value.length = 0); | ||
197 | + attributeOptions.value = res?.map((item) => ({ label: item.name, value: item.identifier })); | ||
198 | + }; | ||
199 | + | ||
200 | + const handleValueChange = (e) => { | ||
201 | + let organizationId = ''; | ||
202 | + if (e.key === 'deviceProfileId') { | ||
203 | + tableTestArray.content.forEach((f: any) => { | ||
204 | + if (f.key === 'keys') { | ||
205 | + f.value = null; | ||
206 | + } | ||
207 | + if (f.key === 'organizationId') organizationId = f.value; | ||
208 | + if (f.key === 'entityId') f.value = null; | ||
209 | + }); | ||
210 | + getAttributeOptions({ deviceProfileId: e.value }); | ||
211 | + if (organizationId !== '') { | ||
212 | + getEntityOptions(organizationId, e.value); | ||
213 | + } | ||
214 | + } | ||
215 | + }; | ||
216 | + | ||
217 | + //获取数据 | ||
218 | + const getValue = () => { | ||
219 | + return tableTestArray.content; | ||
220 | + }; | ||
221 | + defineExpose({ | ||
222 | + getValue, | ||
223 | + setTableArray, | ||
224 | + }); | ||
225 | +</script> | ||
226 | + | ||
227 | +<style scoped lang="less"> | ||
228 | + @table-color: #e5e7eb; | ||
229 | + | ||
230 | + .table-border-color { | ||
231 | + border: 1px solid #e5e7eb; | ||
232 | + text-align: center; | ||
233 | + } | ||
234 | + | ||
235 | + .table-content { | ||
236 | + table { | ||
237 | + width: 31vw; | ||
238 | + &:extend(.table-border-color); | ||
239 | + } | ||
240 | + | ||
241 | + table td { | ||
242 | + padding: 5px; | ||
243 | + white-space: nowrap; | ||
244 | + &:extend(.table-border-color); | ||
245 | + } | ||
246 | + | ||
247 | + table th { | ||
248 | + padding: 5px; | ||
249 | + &:extend(.table-border-color); | ||
250 | + } | ||
251 | + } | ||
252 | +</style> |
1 | <template> | 1 | <template> |
2 | - <div class="mt-8"> | 2 | + <div v-if="showTestFlag" class="mt-8"> |
3 | <div> | 3 | <div> |
4 | - <Button disabled @click="handleExcute" type="primary"> 执行测试请求 </Button> | 4 | + <Button @click="handleExcute" type="primary"> 执行测试请求 </Button> |
5 | </div> | 5 | </div> |
6 | - <!-- <div class="mt-8"> | 6 | + <div class="mt-8"> |
7 | <a-row type="flex" justify="center"> | 7 | <a-row type="flex" justify="center"> |
8 | - <a-col :span="3"> 测试结果 </a-col> | ||
9 | - <a-col :span="21"> | 8 | + <a-col :span="2"> 测试结果 </a-col> |
9 | + <a-col :span="22"> | ||
10 | <a-textarea | 10 | <a-textarea |
11 | allow-clear | 11 | allow-clear |
12 | show-count | 12 | show-count |
@@ -16,13 +16,18 @@ | @@ -16,13 +16,18 @@ | ||
16 | /> | 16 | /> |
17 | </a-col> | 17 | </a-col> |
18 | </a-row> | 18 | </a-row> |
19 | - </div> --> | 19 | + </div> |
20 | </div> | 20 | </div> |
21 | </template> | 21 | </template> |
22 | <script lang="ts" setup name="testRequest"> | 22 | <script lang="ts" setup name="testRequest"> |
23 | - import { nextTick } from 'vue'; | 23 | + import { nextTick, ref, reactive } from 'vue'; |
24 | import { Button } from 'ant-design-vue'; | 24 | import { Button } from 'ant-design-vue'; |
25 | - // import { otherHttp } from '/@/utils/http/axios'; | 25 | + import { otherHttp } from '/@/utils/http/axios'; |
26 | + import { useWebSocket } from '@vueuse/core'; | ||
27 | + import { JWT_TOKEN_KEY } from '/@/enums/cacheEnum'; | ||
28 | + import { getAuthCache } from '/@/utils/auth'; | ||
29 | + import { useMessage } from '/@/hooks/web/useMessage'; | ||
30 | + import { useGlobSetting } from '/@/hooks/setting'; | ||
26 | 31 | ||
27 | const emits = defineEmits(['emitExcute']); | 32 | const emits = defineEmits(['emitExcute']); |
28 | 33 | ||
@@ -32,6 +37,21 @@ | @@ -32,6 +37,21 @@ | ||
32 | }, | 37 | }, |
33 | }); | 38 | }); |
34 | 39 | ||
40 | + const showTestFlag = ref(false); | ||
41 | + | ||
42 | + const { createMessage } = useMessage(); | ||
43 | + | ||
44 | + const token = getAuthCache(JWT_TOKEN_KEY); | ||
45 | + | ||
46 | + const { socketUrl } = useGlobSetting(); | ||
47 | + | ||
48 | + const socketMessage: any = reactive({ | ||
49 | + server: `${socketUrl}${token}`, | ||
50 | + sendValue: { | ||
51 | + tsSubCmds: [], | ||
52 | + }, | ||
53 | + }); | ||
54 | + | ||
35 | //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式" | 55 | //格式化替换像"http:xxxx/api/xx/{xx}/{xx}/{xx}这种格式" |
36 | String.prototype.restfulFormat = function (replacements) { | 56 | String.prototype.restfulFormat = function (replacements) { |
37 | var formatString = function (str, replacements) { | 57 | var formatString = function (str, replacements) { |
@@ -52,7 +72,7 @@ | @@ -52,7 +72,7 @@ | ||
52 | return formatString(this, replacements); | 72 | return formatString(this, replacements); |
53 | }; | 73 | }; |
54 | 74 | ||
55 | - // const testResult = ref(''); | 75 | + const testResult = ref(''); |
56 | 76 | ||
57 | //执行测试接口 | 77 | //执行测试接口 |
58 | const handleExcute = () => { | 78 | const handleExcute = () => { |
@@ -62,22 +82,86 @@ | @@ -62,22 +82,86 @@ | ||
62 | 82 | ||
63 | const getValue = async () => { | 83 | const getValue = async () => { |
64 | await nextTick(); | 84 | await nextTick(); |
65 | - console.log(props.data); | 85 | + //获取Params和Header和Body |
86 | + const Objects = props.data; | ||
87 | + console.log(Objects); | ||
88 | + const apiType = Objects?.Params?.apiType; | ||
89 | + const url = Objects?.Params?.apiGetUrl; | ||
90 | + const headers = Objects?.Header?.params; | ||
91 | + const params = Objects?.Params?.params; | ||
92 | + const apiUrl = url.restfulFormat(params); | ||
93 | + if (url.startsWith('ws') || url.startsWith('wss')) { | ||
94 | + websocketRequest(params); | ||
95 | + } else { | ||
96 | + const resp = await otherHttpRequest(apiType, apiUrl.split('{?')[0], headers, params); | ||
97 | + if (!resp) return; | ||
98 | + testResult.value = JSON.stringify(resp); | ||
99 | + } | ||
66 | }; | 100 | }; |
67 | 101 | ||
68 | - // //TODO: 待优化 项目自带第三方请求 | ||
69 | - // const otherHttpRequest = async (apiType, params = {}, api, joinPrefix = false) => { | ||
70 | - // switch (apiType) { | ||
71 | - // case 'GET': | ||
72 | - // return await otherHttp.get( | ||
73 | - // { url: api, params }, | ||
74 | - // { | ||
75 | - // apiUrl: '', | ||
76 | - // joinPrefix, | ||
77 | - // } | ||
78 | - // ); | ||
79 | - // } | ||
80 | - // }; | 102 | + //websocket请求 |
103 | + const websocketRequest = (params) => { | ||
104 | + //websocket请求 | ||
105 | + Reflect.deleteProperty(params, 'deviceProfileId'); | ||
106 | + Reflect.deleteProperty(params, 'organizationId'); | ||
107 | + Reflect.set(params, 'cmdId', 1); | ||
108 | + Reflect.set(params, 'scope', 'LATEST_TELEMETRY'); | ||
109 | + Reflect.set(params, 'entityType', 'DEVICE'); | ||
110 | + socketMessage.sendValue.tsSubCmds.push(params); | ||
111 | + const { send, close } = useWebSocket(socketMessage.server, { | ||
112 | + onConnected() { | ||
113 | + send(JSON.stringify(socketMessage.sendValue)); | ||
114 | + console.log('建立连接了'); | ||
115 | + }, | ||
116 | + onMessage(_, e) { | ||
117 | + const { data } = JSON.parse(e.data); | ||
118 | + testResult.value = JSON.stringify(data); | ||
119 | + }, | ||
120 | + onDisconnected() { | ||
121 | + console.log('断开连接了'); | ||
122 | + close(); | ||
123 | + }, | ||
124 | + onError() { | ||
125 | + createMessage.error('webSocket连接超时,请联系管理员'); | ||
126 | + }, | ||
127 | + }); | ||
128 | + }; | ||
129 | + | ||
130 | + //TODO: 待优化 项目自带第三方请求 | ||
131 | + const otherHttpRequest = async ( | ||
132 | + apiType, | ||
133 | + apiUrl, | ||
134 | + headers = {}, | ||
135 | + params = {}, | ||
136 | + joinPrefix = false | ||
137 | + ) => { | ||
138 | + switch (apiType) { | ||
139 | + case 'GET': | ||
140 | + return await otherHttp.get( | ||
141 | + { url: apiUrl, params, headers }, | ||
142 | + { | ||
143 | + apiUrl: '', | ||
144 | + joinPrefix, | ||
145 | + } | ||
146 | + ); | ||
147 | + } | ||
148 | + }; | ||
149 | + | ||
150 | + const resetValue = () => { | ||
151 | + showTestFlag.value = false; | ||
152 | + testResult.value = '测试结果为:'; | ||
153 | + }; | ||
154 | + | ||
155 | + const showTest = () => (showTestFlag.value = true); | ||
156 | + | ||
157 | + defineExpose({ | ||
158 | + resetValue, | ||
159 | + showTest, | ||
160 | + }); | ||
81 | </script> | 161 | </script> |
82 | 162 | ||
83 | -<style scoped lang="less"></style> | 163 | +<style scoped lang="less"> |
164 | + :deep(.ant-input-textarea-show-count) { | ||
165 | + width: 30vw; | ||
166 | + } | ||
167 | +</style> |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | <div> | 2 | <div> |
3 | <div class="mt-8"> | 3 | <div class="mt-8"> |
4 | <div> | 4 | <div> |
5 | - <Button disabled @click="handleTest" type="primary"> 测试接口 </Button> | 5 | + <Button @click="handleTest" type="primary"> 测试接口 </Button> |
6 | </div> | 6 | </div> |
7 | <div v-if="showTestEditCell" class="mt-8"> | 7 | <div v-if="showTestEditCell" class="mt-8"> |
8 | <a-row type="flex" justify="center"> | 8 | <a-row type="flex" justify="center"> |
1 | import ParamsTest from './paramsTest/index.vue'; | 1 | import ParamsTest from './paramsTest/index.vue'; |
2 | import HeaderTest from './headerTest/index.vue'; | 2 | import HeaderTest from './headerTest/index.vue'; |
3 | +import BodyTest from './bodyTest/index.vue'; | ||
3 | 4 | ||
4 | -export { ParamsTest, HeaderTest }; | 5 | +export { ParamsTest, HeaderTest, BodyTest }; |
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | <div> | 2 | <div> |
3 | <div class="mt-8"> | 3 | <div class="mt-8"> |
4 | <div> | 4 | <div> |
5 | - <Button disabled @click="handleTest" type="primary"> 测试接口 </Button> | 5 | + <Button @click="handleTest" type="primary"> 测试接口 </Button> |
6 | </div> | 6 | </div> |
7 | <div v-if="showTestEditCell" class="mt-8"> | 7 | <div v-if="showTestEditCell" class="mt-8"> |
8 | <a-row type="flex" justify="center"> | 8 | <a-row type="flex" justify="center"> |
@@ -82,7 +82,12 @@ | @@ -82,7 +82,12 @@ | ||
82 | .concat(keyValueList) | 82 | .concat(keyValueList) |
83 | .filter((it) => it.key !== 'date_range') | 83 | .filter((it) => it.key !== 'date_range') |
84 | .map((it: any) => { | 84 | .map((it: any) => { |
85 | - const value = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.keyValue : it?.value; | 85 | + const value = |
86 | + it?.key === 'scope' | ||
87 | + ? it?.keyValue | ||
88 | + : it?.key === 'fixed_date' | ||
89 | + ? moment(it?.fixed_date_value).valueOf() | ||
90 | + : it?.value; | ||
86 | const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key; | 91 | const key = it?.key === 'scope' || it?.key === 'fixed_date' ? it?.value : it?.key; |
87 | return { | 92 | return { |
88 | key, | 93 | key, |
@@ -74,7 +74,7 @@ | @@ -74,7 +74,7 @@ | ||
74 | <a-date-picker | 74 | <a-date-picker |
75 | v-else-if="item.key === 'fixed_date'" | 75 | v-else-if="item.key === 'fixed_date'" |
76 | style="width: 6.5vw" | 76 | style="width: 6.5vw" |
77 | - v-model:value="item.keyValue" | 77 | + v-model:value="item.fixed_date_value" |
78 | :show-time="{ format: 'HH:mm' }" | 78 | :show-time="{ format: 'HH:mm' }" |
79 | format="YYYY-MM-DD HH:mm:ss" | 79 | format="YYYY-MM-DD HH:mm:ss" |
80 | placeholder="日期时间" | 80 | placeholder="日期时间" |
@@ -11,6 +11,7 @@ export type selectType = { label: string; value: string; disabled?: boolean }; | @@ -11,6 +11,7 @@ export type selectType = { label: string; value: string; disabled?: boolean }; | ||
11 | export type tableItems = { | 11 | export type tableItems = { |
12 | key: SelectValue | undefined; | 12 | key: SelectValue | undefined; |
13 | value: string | SelectValue | undefined; | 13 | value: string | SelectValue | undefined; |
14 | + fixed_date_value?: string; | ||
14 | editDisabled?: boolean; | 15 | editDisabled?: boolean; |
15 | required?: boolean; | 16 | required?: boolean; |
16 | date1?: string; | 17 | date1?: string; |