feat: 新增全局请求数据处理

This commit is contained in:
奔跑的面条 2022-07-16 19:01:05 +08:00
parent d4bfdd1e91
commit f178b0e0ca
13 changed files with 231 additions and 109 deletions

View File

@ -4,7 +4,7 @@ import { http } from '@/api/http'
import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestDataTypeEnum } from '@/enums/httpEnum'
import { isPreview, newFunctionHandle } from '@/utils'
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
// 获取类型
type ChartEditStoreType = typeof useChartEditStore
@ -25,7 +25,7 @@ export const useChartDataFetch = (
const requestIntervalFn = () => {
const chartEditStore = useChartEditStore()
const { requestOriginUrl, requestInterval } = toRefs(chartEditStore.getRequestGlobalConfig)
const { requestOriginUrl, requestInterval, requestIntervalUnit } = toRefs(chartEditStore.getRequestGlobalConfig)
// 组件类型
const { chartFrame } = targetComponent.chartConfig
// 请求配置
@ -35,45 +35,52 @@ export const useChartDataFetch = (
requestUrl,
requestInterval: targetInterval
} = toRefs(targetComponent.request)
// 非请求类型
if (requestDataType.value !== RequestDataTypeEnum.AJAX) return
// 处理地址
if (requestUrl?.value && requestInterval.value > 0) {
// requestOriginUrl 允许为空
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
if (!completePath) return
if (requestDataType.value !== RequestDataTypeEnum.AJAX || !requestInterval) return
try {
// 处理地址
// @ts-ignore
if (requestUrl?.value && requestInterval && requestInterval.value > 0) {
// requestOriginUrl 允许为空
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
if (!completePath) return
clearInterval(fetchInterval)
clearInterval(fetchInterval)
const fetchFn = async () => {
const res: any = await http(requestHttpType.value)(completePath || '', {})
if (res.data) {
try {
const filter = targetComponent.filter
// 更新回调函数
if (updateCallback) {
updateCallback(newFunctionHandle(res.data, filter))
} else {
// eCharts 组件配合 vChart 库更新方式
if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) {
vChartRef.value.setOption({ dataset: newFunctionHandle(res.data, filter) })
const fetchFn = async () => {
const res: any = await http(requestHttpType.value)(completePath || '', {})
if (res.data) {
try {
const filter = targetComponent.filter
// 更新回调函数
if (updateCallback) {
updateCallback(newFunctionHandle(res.data, filter))
} else {
// eCharts 组件配合 vChart 库更新方式
if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) {
vChartRef.value.setOption({ dataset: newFunctionHandle(res.data, filter) })
}
}
}
} catch (error) {
console.error(error)
}
} catch (error) {
console.error(error)
}
}
// 立即调用
fetchFn()
// 开启定时
const time = targetInterval && targetInterval.value ? targetInterval.value : requestInterval.value
// 处理单位时间
fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, requestIntervalUnit.value))
}
// 立即调用
fetchFn()
// 开启定时
const time = targetInterval && targetInterval.value ? targetInterval.value : requestInterval.value
fetchInterval = setInterval(fetchFn, time * 1000)
}
} catch (error) {}
}
isPreview() && requestIntervalFn()

View File

@ -53,6 +53,8 @@ import {
ArrowForward as ArrowForwardIcon,
Planet as PawIcon,
Search as SearchIcon,
ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon
} from '@vicons/ionicons5'
import {
@ -194,7 +196,11 @@ const ionicons5 = {
// 搜索(放大镜)
SearchIcon,
// 过滤器
FilterIcon
FilterIcon,
// 向上
ChevronUpOutlineIcon,
// 向下
ChevronDownOutlineIcon
}
const carbon = {

View File

@ -137,24 +137,24 @@ export enum ChartEditStoreEnum {
// 请求公共类型
type RequestPublicConfigType = {
// 组件定制轮询时间
requestInterval?: number
// 时间单位(时分秒)
requestIntervalUnit: RequestHttpIntervalEnum
// 请求内容
requestParams: RequestParams
// 请求体类型
requestParamsBodyType: RequestBodyEnum
}
// 全局的图表请求配置
export interface RequestGlobalConfigType extends RequestPublicConfigType {
// 组件定制轮询时间
requestInterval: number
// 请求源地址
requestOriginUrl?: string
}
// 单个图表请求配置
export interface RequestConfigType extends RequestPublicConfigType {
// 组件定制轮询时间
requestInterval?: number
// 获取数据的方式
requestDataType: RequestDataTypeEnum
// 请求方式 get/post/del/put/patch
@ -163,6 +163,8 @@ export interface RequestConfigType extends RequestPublicConfigType {
requestUrl?: string
// 请求内容主体方式 普通/sql
requestContentType: RequestContentTypeEnum
// 请求体类型
requestParamsBodyType: RequestBodyEnum
// SQL 请求对象
requestSQLContent: {
sql: string

View File

@ -112,7 +112,6 @@ export const useChartEditStore = defineStore({
requestOriginUrl: '',
requestInterval: requestInterval,
requestIntervalUnit: requestIntervalUnit,
requestParamsBodyType: RequestBodyEnum.NONE,
requestParams: {
Body: {
"form-data": {},

View File

@ -6,7 +6,8 @@ import Image_404 from '../assets/images/exception/image-404.png'
import html2canvas from 'html2canvas'
import { downloadByA } from './file'
import { toString } from './type'
import cloneDeep from 'lodash/cloneDeep';
import cloneDeep from 'lodash/cloneDeep'
import { RequestHttpIntervalEnum } from '@/enums/httpEnum'
/**
* *
@ -203,7 +204,7 @@ export const newFunctionHandle = (
try {
if (!funcStr) return data
const fn = new Function('data', funcStr)
const fnRes = fn( cloneDeep(data))
const fnRes = fn(cloneDeep(data))
const resHandle = isToString ? toString(fnRes) : fnRes
// 成功回调
successCallBack && successCallBack(resHandle)
@ -214,3 +215,28 @@ export const newFunctionHandle = (
return '函数执行错误'
}
}
/**
* *
* @param num
* @param unit RequestHttpIntervalEnum
* @return number
*/
export const intervalUnitHandle = (num: number, unit: RequestHttpIntervalEnum) => {
switch (unit) {
// 秒
case RequestHttpIntervalEnum.SECOND:
return num * 1000
// 分
case RequestHttpIntervalEnum.MINUTE:
return num * 1000 * 60
// 时
case RequestHttpIntervalEnum.HOUR:
return num * 1000 * 60 * 60
// 天
case RequestHttpIntervalEnum.DAY:
return num * 1000 * 60 * 60 * 24
default:
return num * 1000
}
}

View File

@ -126,7 +126,6 @@ const fetchTargetData = async () => {
try {
const { requestUrl, requestHttpType } = targetData.value.request
if (!requestUrl) {
window['$message'].warning('请求参数不正确,请检查!')
sourceData.value = '请求参数不正确,请检查!'
return
}

View File

@ -10,7 +10,7 @@
>
<!-- 源地址 -->
<setting-item name="前置 URL">
<n-input v-model:value.trim="requestOriginUrl" :disabled="disabled" placeholder="http://127.0.0.1/"></n-input>
<n-input v-model:value.trim="requestOriginUrl" :disabled="editDisabled" placeholder="http://127.0.0.1/"></n-input>
</setting-item>
<setting-item name="更新间隔(为 0 表示不更新)">
<n-input-group>
@ -19,7 +19,7 @@
v-model:value.trim="requestInterval"
min="0"
:show-button="false"
:disabled="disabled"
:disabled="editDisabled"
placeholder="请输入数字"
>
</n-input-number>
@ -28,11 +28,11 @@
class="select-time-options"
v-model:value="requestIntervalUnit"
:options="selectTimeOptions"
:disabled="disabled"
:disabled="editDisabled"
/>
</n-input-group>
</setting-item>
<n-button v-show="disabled" type="primary" secondary @click="disabled = false">
<n-button v-show="editDisabled" type="primary" secondary @click="editDisabled = false">
<template #icon>
<n-icon>
<pencil-icon />
@ -41,23 +41,61 @@
编辑配置
</n-button>
</setting-item-box>
<!-- table 内容体 -->
<n-collapse-transition :show="showTable">
<request-global-header-table :editDisabled="editDisabled"></request-global-header-table>
</n-collapse-transition>
<!-- 箭头 -->
<div v-if="showTable" class="go-flex-center go-mt-3 down" @click="showTable = false">
<n-icon size="32">
<chevron-up-outline-icon />
</n-icon>
</div>
<div v-else class="go-flex-center go-mt-3 down" @click="showTable = true">
<n-tooltip trigger="hover" placement="top" :keep-alive-on-hover="false">
<template #trigger>
<n-icon size="32">
<chevron-down-outline-icon />
</n-icon>
</template>
展开
</n-tooltip>
</div>
</n-card>
</template>
<script setup lang="ts">
import { ref, toRefs } from 'vue'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { selectTypeOptions, selectTimeOptions } from '@/views/chart/ContentConfigurations/components/ChartData/index.d'
import { RequestGlobalHeaderTable } from '../RequestGlobalHeaderTable'
import { icon } from '@/plugins'
const { PencilIcon } = icon.ionicons5
const { targetData, chartEditStore } = useTargetData()
const { PencilIcon, ChevronDownOutlineIcon, ChevronUpOutlineIcon } = icon.ionicons5
const { chartEditStore } = useTargetData()
const { requestOriginUrl, requestInterval, requestIntervalUnit } = toRefs(chartEditStore.getRequestGlobalConfig)
const disabled = ref(true)
const editDisabled = ref(true)
const designStore = useDesignStore()
const themeColor = ref(designStore.getAppTheme)
const showTable = ref(true)
</script>
<style lang="scss" scoped>
.n-card-shallow {
&:hover {
border-color: v-bind('themeColor');
}
}
.down {
cursor: pointer;
&:hover {
color: v-bind('themeColor');
}
}
.select-time-number {
width: 100%;
}

View File

@ -0,0 +1,3 @@
import RequestGlobalHeaderTable from './index.vue'
export { RequestGlobalHeaderTable }

View File

@ -0,0 +1,32 @@
<template>
<div>
<n-tabs type="line" animated v-model:value="tabValue">
<n-tab v-for="item in tabs" :key="item" :name="item" :tab="item"> {{ item }} </n-tab>
</n-tabs>
<div class="go-mt-3">
<request-header-table :editDisabled="$attrs.editDisabled" :target="requestParams[tabValue]" @update="updateRequestParams"></request-header-table>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, toRefs } from 'vue'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { RequestHeaderTable } from '../RequestHeaderTable'
import { RequestParamsTypeEnum, RequestParamsObjType } from '@/enums/httpEnum'
const { chartEditStore } = useTargetData()
const { requestParams } = toRefs(chartEditStore.getRequestGlobalConfig)
const tabValue = ref<RequestParamsTypeEnum>(RequestParamsTypeEnum.HEADER)
const tabs = [RequestParamsTypeEnum.HEADER, RequestParamsTypeEnum.COOKIE]
//
const updateRequestParams = (paramsObj: RequestParamsObjType) => {
if (tabValue.value === RequestParamsTypeEnum.HEADER || tabValue.value === RequestParamsTypeEnum.COOKIE) {
requestParams.value[tabValue.value] = paramsObj
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -12,7 +12,7 @@
</n-tabs>
<!-- 各个页面 -->
<div class="tabs-content go-mt-3">
<div class="go-mt-3">
<div v-if="tabValue !== RequestParamsTypeEnum.BODY">
<request-header-table :target="requestParams[tabValue]" @update="updateRequestParams"></request-header-table>
</div>
@ -80,7 +80,7 @@
</template>
<script setup lang="ts">
import { reactive, ref, toRefs } from 'vue'
import { ref, toRefs } from 'vue'
import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'

View File

@ -1,55 +1,54 @@
<template>
<n-scrollbar style="max-height: 250px">
<n-table class="go-request-header-table-box" :single-line="false" size="small">
<thead>
<tr>
<th></th>
<th>Key</th>
<th>Value</th>
<th>操作</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableArray.content" :key="index">
<td>
{{ index + 1 }}
</td>
<td>
<n-input v-model:value="item.key" type="text" size="small" @blur="blur" />
</td>
<td>
<n-input v-model:value="item.value" type="text" size="small" @blur="blur" />
</td>
<td>
<div style="width: 80px">
<n-button class="go-ml-2" type="primary" size="small" ghost @click="add(index)">+</n-button>
<n-button
class="go-ml-2"
type="warning"
size="small"
ghost
:disabled="index === 0"
@click="remove(index)"
>
-
</n-button>
</div>
</td>
<td>
<n-button v-if="item.error" class="go-ml-2" text type="error"> 格式错误 </n-button>
<n-button v-else class="go-ml-2" text type="success"> 格式通过 </n-button>
</td>
</tr>
</tbody>
</n-table>
</n-scrollbar>
<n-table class="go-request-header-table-box" :single-line="false" size="small">
<thead>
<tr>
<th></th>
<th>Key</th>
<th>Value</th>
<th>操作</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableArray.content" :key="index">
<td>
{{ index + 1 }}
</td>
<td>
<n-input v-model:value="item.key" :disabled="editDisabled" type="text" size="small" @blur="blur" />
</td>
<td>
<n-input v-model:value="item.value" :disabled="editDisabled" type="text" size="small" @blur="blur" />
</td>
<td>
<div style="width: 80px">
<n-button class="go-ml-2" type="primary" size="small" ghost :disabled="editDisabled" @click="add(index)"
>+</n-button
>
<n-button
class="go-ml-2"
type="warning"
size="small"
ghost
:disabled="index === 0 && editDisabled"
@click="remove(index)"
>
-
</n-button>
</div>
</td>
<td>
<n-button v-if="item.error" class="go-ml-2" text type="error"> 格式错误 </n-button>
<n-button v-else class="go-ml-2" text type="primary"> 格式通过 </n-button>
</td>
</tr>
</tbody>
</n-table>
</template>
<script setup lang="ts">
import { PropType, reactive, ref, toRefs, watch } from 'vue'
import { RequestBodyEnum, RequestParamsObjType } from '@/enums/httpEnum'
import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook'
import { RequestParamsObjType } from '@/enums/httpEnum'
const emits = defineEmits(['update'])
@ -58,12 +57,14 @@ const props = defineProps({
type: Object as PropType<RequestParamsObjType>,
required: true,
default: () => {}
},
editDisabled: {
type: Boolean,
required: false,
default: false
}
})
const { targetData } = useTargetData()
const { requestParams } = toRefs(targetData.value.request)
//
const error = ref(false)

View File

@ -24,7 +24,7 @@
<n-input-number
v-model:value.trim="requestInterval"
class="select-time-number"
min="5"
min="1"
:show-button="false"
placeholder="可以为空"
>

View File

@ -3,19 +3,23 @@
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 800px">
<template #header></template>
<template #header-extra> </template>
<n-space vertical>
<request-global-config></request-global-config>
<request-target-config></request-target-config>
</n-space>
<n-scrollbar style="max-height: 718px">
<div class="go-pr-3">
<n-space vertical>
<request-global-config></request-global-config>
<request-target-config></request-target-config>
</n-space>
</div>
</n-scrollbar>
<!-- 底部 -->
<template #action>
<n-space justify="space-between">
<div>
<n-text> {{chartConfig.categoryName ||rename}} </n-text>
<n-text> {{ chartConfig.categoryName || rename }} </n-text>
<n-text> </n-text>
<n-tag type="primary" :bordered="false"> {{requestContentTypeObj[requestContentType]}} </n-tag>
<n-tag type="primary" :bordered="false"> {{ requestContentTypeObj[requestContentType] }} </n-tag>
</div>
<n-button type="primary" ghost @click="closeHandle">关闭</n-button>
<n-button type="primary" ghost @click="closeHandle">确认</n-button>
</n-space>
</template>
</n-card>
@ -38,7 +42,7 @@ const { requestContentType } = toRefs(targetData.value.request)
const requestContentTypeObj = {
[RequestContentTypeEnum.DEFAULT]: '普通请求',
[RequestContentTypeEnum.SQL]: 'SQL 请求',
[RequestContentTypeEnum.SQL]: 'SQL 请求'
}
defineProps({
@ -59,5 +63,10 @@ const closeHandle = () => {
.n-card-shallow {
background-color: rgba(0, 0, 0, 0) !important;
}
@include deep() {
& > .n-card__content {
padding-right: 0;
}
}
}
</style>