feat: 完成自定义请求功能

This commit is contained in:
奔跑的面条 2022-07-20 12:19:24 +08:00
parent 2abbac8b52
commit ca587c9ee3
10 changed files with 198 additions and 59 deletions

View File

@ -10,7 +10,6 @@ const axiosInstance = axios.create({
axiosInstance.interceptors.request.use( axiosInstance.interceptors.request.use(
(config: AxiosRequestConfig) => { (config: AxiosRequestConfig) => {
config.headers = {}
return config return config
}, },
(error: AxiosRequestConfig) => { (error: AxiosRequestConfig) => {

View File

@ -1,5 +1,12 @@
import axiosInstance from './axios' import axiosInstance from './axios'
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum' import {
RequestHttpEnum,
ContentTypeEnum,
RequestBodyEnum,
RequestDataTypeEnum,
RequestContentTypeEnum,
RequestParamsObjType
} from '@/enums/httpEnum'
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d' import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
export const get = (url: string, params?: object) => { export const get = (url: string, params?: object) => {
@ -74,7 +81,110 @@ export const http = (type?: RequestHttpEnum) => {
} }
} }
// 自定义请求 /**
export const customizeHttp = (comParams: RequestConfigType, globalParams: RequestGlobalConfigType) => { * *
* @param targetParams
* @param globalParams
*/
export const customizeHttp = (targetParams: RequestConfigType, globalParams: RequestGlobalConfigType) => {
if(!targetParams || !globalParams) {
return
}
// 全局
const {
// 全局请求源地址
requestOriginUrl,
// 全局请求内容
requestParams: globalRequestParams
} = globalParams
// 目标组件(优先级 > 全局组件)
const {
// 请求地址
requestUrl,
// 普通 / sql
requestContentType,
// 获取数据的方式
requestDataType,
// 请求方式 get/post/del/put/patch
requestHttpType,
// 请求体类型 none / form-data / x-www-form-urlencoded / json /xml
requestParamsBodyType,
// SQL 请求对象
requestSQLContent,
// 请求内容 params / cookie / header / body: 同 requestParamsBodyType
requestParams: targetRequestParams
} = targetParams
// 静态排除
if (requestDataType === RequestDataTypeEnum.STATIC) return
if (!requestUrl) {
return
}
// 处理头部
const headers: RequestParamsObjType = {
...globalRequestParams.Header,
...targetRequestParams.Header,
}
// data 参数
let data: RequestParamsObjType | FormData | string = {}
// params 参数
let params: RequestParamsObjType = targetRequestParams.Params
// form 类型处理
let formData: FormData = new FormData()
formData.set('default', 'defaultData')
// 类型处理
switch (requestParamsBodyType) {
case RequestBodyEnum.NONE:
break
case RequestBodyEnum.JSON:
headers['Content-Type'] = ContentTypeEnum.JSON
data = JSON.parse(targetRequestParams.Body['json'])
// json 赋值给 data
break
case RequestBodyEnum.XML:
headers['Content-Type'] = ContentTypeEnum.XML
// xml 字符串赋值给 data
data = targetRequestParams.Body['xml']
break
case RequestBodyEnum.X_WWW_FORM_URLENCODED:
headers['Content-Type'] = ContentTypeEnum.FORM_URLENCODED
const bodyFormData = targetRequestParams.Body['x-www-form-urlencoded']
for (const i in bodyFormData) formData.set(i, bodyFormData[i])
// FormData 赋值给 data
data = formData
break
case RequestBodyEnum.FORM_DATA:
headers['Content-Type'] = ContentTypeEnum.FORM_DATA
const bodyFormUrlencoded = targetRequestParams.Body['form-data']
for (const i in bodyFormUrlencoded) {
formData.set(i, bodyFormUrlencoded[i])
}
// FormData 赋值给 data
data = formData
break
}
// sql 处理
if (requestContentType === RequestContentTypeEnum.SQL) {
headers['Content-Type'] = ContentTypeEnum.JSON
data = requestSQLContent
}
return axiosInstance({
url: `${requestOriginUrl}${requestUrl}`,
method: requestHttpType,
data,
params,
headers
})
} }

View File

@ -90,7 +90,6 @@ export enum RequestParamsTypeEnum {
PARAMS = 'Params', PARAMS = 'Params',
BODY = 'Body', BODY = 'Body',
HEADER = 'Header', HEADER = 'Header',
COOKIE = 'Cookie'
} }
/** /**
@ -101,7 +100,6 @@ export type RequestParamsObjType = {
} }
export type RequestParams = { export type RequestParams = {
[RequestParamsTypeEnum.PARAMS]: RequestParamsObjType [RequestParamsTypeEnum.PARAMS]: RequestParamsObjType
[RequestParamsTypeEnum.COOKIE]: RequestParamsObjType
[RequestParamsTypeEnum.HEADER]: RequestParamsObjType [RequestParamsTypeEnum.HEADER]: RequestParamsObjType
[RequestParamsTypeEnum.BODY]: { [RequestParamsTypeEnum.BODY]: {
[RequestBodyEnum.FORM_DATA]: RequestParamsObjType [RequestBodyEnum.FORM_DATA]: RequestParamsObjType
@ -117,9 +115,11 @@ export type RequestParams = {
export enum ContentTypeEnum { export enum ContentTypeEnum {
// json // json
JSON = 'application/json;charset=UTF-8', JSON = 'application/json;charset=UTF-8',
// json // text
TEXT = 'text/plain;charset=UTF-8', TEXT = 'text/plain;charset=UTF-8',
// form-data 一般配合qs // xml
XML = 'application/xml;charset=UTF-8',
// application/x-www-form-urlencoded 一般配合qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8', FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data 上传 // form-data 上传
FORM_DATA = 'multipart/form-data;charset=UTF-8' FORM_DATA = 'multipart/form-data;charset=UTF-8'

View File

@ -28,7 +28,6 @@ const requestConfig: RequestConfigType = {
json: '', json: '',
xml: '' xml: ''
}, },
Cookie: {},
Header: {}, Header: {},
Params: {} Params: {}
} }

View File

@ -119,7 +119,6 @@ export const useChartEditStore = defineStore({
json: '', json: '',
xml: '' xml: ''
}, },
Cookie: {},
Header: {}, Header: {},
Params: {} Params: {}
} }

View File

@ -7,7 +7,7 @@ import html2canvas from 'html2canvas'
import { downloadByA } from './file' import { downloadByA } from './file'
import { toString } from './type' import { toString } from './type'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
import { RequestHttpIntervalEnum } from '@/enums/httpEnum' import { RequestHttpIntervalEnum, RequestParamsObjType } from '@/enums/httpEnum'
/** /**
* * * *
@ -240,3 +240,18 @@ export const intervalUnitHandle = (num: number, unit: RequestHttpIntervalEnum) =
return num * 1000 return num * 1000
} }
} }
/**
* * cookie
* @param obj
* @returns string
*/
export const objToCookie = (obj: RequestParamsObjType) => {
if(!obj) return ''
let str = ''
for (const key in obj) {
str += key + '=' + obj[key] + ';'
}
return str.substr(0, str.length - 1)
}

View File

@ -1,16 +1,28 @@
<template> <template>
<div class="go-chart-configurations-data-ajax"> <div class="go-chart-configurations-data-ajax">
<n-card class="n-card-shallow"> <n-card class="n-card-shallow">
<setting-item-box name="基础配置"> <setting-item-box name="请求配置">
<setting-item name="请求方式"> <setting-item name="类型">
<n-tag :bordered="false" type="primary">
{{ requestContentType === RequestContentTypeEnum.DEFAULT ? '普通请求' : 'SQL请求' }}
</n-tag>
</setting-item>
<setting-item name="方式">
<n-input size="small" :placeholder="requestHttpType || '暂无'" :disabled="true"></n-input> <n-input size="small" :placeholder="requestHttpType || '暂无'" :disabled="true"></n-input>
</setting-item> </setting-item>
<setting-item name="请求间隔"> <setting-item name="组件间隔(高级)">
<n-input size="small" :placeholder="requestInterval || '暂无'" :disabled="true"> <n-input size="small" :placeholder="`${requestInterval}` || '暂无'" :disabled="true">
<template #suffix> {{ SelectHttpTimeNameObj[requestIntervalUnit] }} </template> <template #suffix> {{ SelectHttpTimeNameObj[requestIntervalUnit] }} </template>
</n-input> </n-input>
</setting-item> </setting-item>
<setting-item name="全局间隔(默认)">
<n-input size="small" :placeholder="`${GlobalRequestInterval}` || '暂无'" :disabled="true">
<template #suffix> {{ SelectHttpTimeNameObj[GlobalRequestIntervalUnit] }} </template>
</n-input>
</setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="源地址" :alone="true"> <setting-item-box name="源地址" :alone="true">
@ -35,7 +47,7 @@
<div class="edit-text" @click="requestModelHandle"> <div class="edit-text" @click="requestModelHandle">
<div class="go-absolute-center"> <div class="go-absolute-center">
<n-button type="primary" secondary>点击配置</n-button> <n-button type="primary" secondary>查看更多</n-button>
</div> </div>
</div> </div>
</n-card> </n-card>
@ -72,14 +84,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRefs, onBeforeUnmount, watchEffect } from 'vue' import { ref, toRefs, onBeforeUnmount, watchEffect, toRaw } from 'vue'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { useDesignStore } from '@/store/modules/designStore/designStore' import { useDesignStore } from '@/store/modules/designStore/designStore'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { ChartDataRequest } from '../ChartDataRequest/index' import { ChartDataRequest } from '../ChartDataRequest/index'
import { RequestHttpEnum, ResultEnum, SelectHttpTimeNameObj } from '@/enums/httpEnum' import { RequestHttpEnum, ResultEnum, SelectHttpTimeNameObj, RequestContentTypeEnum } from '@/enums/httpEnum'
import { chartDataUrl, rankListUrl, scrollBoardUrl, numberFloatUrl, numberIntUrl, textUrl, imageUrl } from '@/api/mock' import { chartDataUrl, rankListUrl, scrollBoardUrl, numberFloatUrl, numberIntUrl, textUrl, imageUrl } from '@/api/mock'
import { http } from '@/api/http' import { http, customizeHttp } from '@/api/http'
import { SelectHttpType } from '../../index.d' import { SelectHttpType } from '../../index.d'
import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow' import { ChartDataMatchingAndShow } from '../ChartDataMatchingAndShow'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
@ -87,8 +99,14 @@ import { isDev, newFunctionHandle } from '@/utils'
const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5 const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5
const { targetData, chartEditStore } = useTargetData() const { targetData, chartEditStore } = useTargetData()
const { requestUrl, requestHttpType, requestInterval, requestIntervalUnit } = toRefs(targetData.value.request) const { requestUrl, requestHttpType, requestInterval, requestIntervalUnit, requestContentType } = toRefs(
const { requestOriginUrl } = toRefs(chartEditStore.getRequestGlobalConfig) targetData.value.request
)
const {
requestOriginUrl,
requestInterval: GlobalRequestInterval,
requestIntervalUnit: GlobalRequestIntervalUnit
} = toRefs(chartEditStore.getRequestGlobalConfig)
const designStore = useDesignStore() const designStore = useDesignStore()
const themeColor = ref(designStore.getAppTheme) const themeColor = ref(designStore.getAppTheme)
@ -106,21 +124,19 @@ const requestModelHandle = () => {
// //
const sendHandle = async () => { const sendHandle = async () => {
loading.value = true loading.value = true
if (!targetData.value) return try {
const { requestUrl, requestHttpType } = targetData.value.request const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.requestGlobalConfig))
if (!requestUrl) {
window['$message'].warning('请求参数不正确,请检查!')
return
}
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl
const res = await http(requestHttpType)(completePath || '', {})
loading.value = false loading.value = false
if (res.status === ResultEnum.SUCCESS) { if (res && res.status === ResultEnum.SUCCESS) {
targetData.value.option.dataset = newFunctionHandle(res.data, targetData.value.filter) targetData.value.option.dataset = newFunctionHandle(res.data, targetData.value.filter)
showMatching.value = true showMatching.value = true
return return
} }
window['$message'].warning('数据异常,请检查接口数据!') window['$message'].warning('数据异常,请检查参数!')
} catch (error) {
loading.value = false
window['$message'].warning('数据异常,请检查参数!')
}
} }
watchEffect(() => { watchEffect(() => {
@ -152,7 +168,7 @@ onBeforeUnmount(() => {
top: 0px; top: 0px;
left: 0px; left: 0px;
width: 325px; width: 325px;
height: 235px; height: 292px;
cursor: pointer; cursor: pointer;
opacity: 0; opacity: 0;
transition: all 0.3s; transition: all 0.3s;

View File

@ -97,13 +97,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch, toRefs } from 'vue' import { ref, computed, watch, toRefs, toRaw } from 'vue'
import { MonacoEditor } from '@/components/Pages/MonacoEditor' import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
import { RequestHttpEnum, RequestDataTypeEnum, ResultEnum } from '@/enums/httpEnum' import { RequestHttpEnum, RequestDataTypeEnum, ResultEnum } from '@/enums/httpEnum'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { goDialog, toString } from '@/utils' import { goDialog, toString } from '@/utils'
import { http } from '@/api/http' import { http, customizeHttp } from '@/api/http'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
const { DocumentTextIcon } = icon.ionicons5 const { DocumentTextIcon } = icon.ionicons5
@ -124,19 +124,14 @@ const sourceData = ref<any>('')
// //
const fetchTargetData = async () => { const fetchTargetData = async () => {
try { try {
const { requestUrl, requestHttpType } = targetData.value.request const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.requestGlobalConfig))
if (!requestUrl) { if (res && res.status === ResultEnum.SUCCESS) {
sourceData.value = '请求参数不正确,请检查!'
return
}
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl
const res = await http(requestHttpType)(completePath || '', {})
if (res.status === ResultEnum.SUCCESS) {
sourceData.value = res.data sourceData.value = res.data
return return
} }
window['$message'].warning('数据异常,请检查参数!')
} catch (error) { } catch (error) {
window['$message'].warning('数据异常,请检查接口数据') window['$message'].warning('数据异常,请检查参数!')
} }
} }

View File

@ -19,11 +19,11 @@ const { chartEditStore } = useTargetData()
const { requestParams } = toRefs(chartEditStore.getRequestGlobalConfig) const { requestParams } = toRefs(chartEditStore.getRequestGlobalConfig)
const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.HEADER) const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.HEADER)
const tabs = [RequestParamsTypeEnum.HEADER, RequestParamsTypeEnum.COOKIE] const tabs = [RequestParamsTypeEnum.HEADER]
// //
const updateRequestParams = (paramsObj: RequestParamsObjType) => { const updateRequestParams = (paramsObj: RequestParamsObjType) => {
if (tabValue.value === RequestParamsTypeEnum.HEADER || tabValue.value === RequestParamsTypeEnum.COOKIE) { if (tabValue.value === RequestParamsTypeEnum.HEADER) {
requestParams.value[tabValue.value] = paramsObj requestParams.value[tabValue.value] = paramsObj
} }
} }

View File

@ -28,7 +28,7 @@
</n-radio-group> </n-radio-group>
<!-- none --> <!-- none -->
<n-card class="go-mt-3" v-if="requestParamsBodyType === RequestBodyEnum['NONE']"> <n-card class="go-mt-3 go-pb-3" v-if="requestParamsBodyType === RequestBodyEnum['NONE']">
<n-text depth="3">该请求没有 Body </n-text> <n-text depth="3">该请求没有 Body </n-text>
</n-card> </n-card>
@ -69,12 +69,17 @@
</div> </div>
</div> </div>
<div v-show="requestContentType === RequestContentTypeEnum.SQL"> <div v-show="requestContentType === RequestContentTypeEnum.SQL">
<template v-if="requestHttpType === RequestHttpEnum.GET">
<n-text>SQL 类型不支持 Get 请求请使用其它方式</n-text>
</template>
<template v-else>
<setting-item-box name="键名"> <setting-item-box name="键名">
<n-tag type="primary" :bordered="false" style="width: 40px; font-size: 16px"> sql </n-tag> <n-tag type="primary" :bordered="false" style="width: 40px; font-size: 16px"> sql </n-tag>
</setting-item-box> </setting-item-box>
<setting-item-box name="键值"> <setting-item-box name="键值">
<monaco-editor v-model:modelValue="requestSQLContent['sql']" width="600px" height="200px" language="sql" /> <monaco-editor v-model:modelValue="requestSQLContent['sql']" width="600px" height="200px" language="sql" />
</setting-item-box> </setting-item-box>
</template>
</div> </div>
</n-space> </n-space>
</template> </template>
@ -92,12 +97,13 @@ import {
RequestContentTypeEnum, RequestContentTypeEnum,
RequestParamsObjType, RequestParamsObjType,
RequestBodyEnumList, RequestBodyEnumList,
RequestBodyEnum RequestBodyEnum,
RequestHttpEnum
} from '@/enums/httpEnum' } from '@/enums/httpEnum'
const { targetData } = useTargetData() const { targetData } = useTargetData()
const { requestContentType, requestSQLContent, requestParams, requestParamsBodyType } = toRefs(targetData.value.request) const { requestHttpType, requestContentType, requestSQLContent, requestParams, requestParamsBodyType } = toRefs(targetData.value.request)
const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS) const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.PARAMS)