Merge branch 'master-fetch-dev' into master-fetch

This commit is contained in:
奔跑的面条 2023-04-23 21:09:40 +08:00
commit 03be42b910
5 changed files with 539 additions and 534 deletions

View File

@ -55,7 +55,7 @@ axiosInstance.interceptors.response.use(
} }
const { code } = res.data as { code: number } const { code } = res.data as { code: number }
if (code === undefined || code === null) return Promise.resolve(res) if (code === undefined || code === null) return Promise.resolve(res.data)
// 成功 // 成功
if (code === ResultEnum.SUCCESS) { if (code === ResultEnum.SUCCESS) {

View File

@ -1,122 +1,123 @@
import { ref, toRefs, toRaw, watch } from 'vue' import { ref, toRefs, toRaw, watch } from 'vue'
import type VChart from 'vue-echarts' import type VChart from 'vue-echarts'
import { customizeHttp } from '@/api/http' import { customizeHttp } from '@/api/http'
import { useChartDataPondFetch } from '@/hooks/' import { useChartDataPondFetch } from '@/hooks/'
import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d' import { CreateComponentType, ChartFrameEnum } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { RequestDataTypeEnum } from '@/enums/httpEnum' import { RequestDataTypeEnum } from '@/enums/httpEnum'
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils' import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
import { setOption } from '@/packages/public/chart' import { setOption } from '@/packages/public/chart'
// 获取类型 // 获取类型
type ChartEditStoreType = typeof useChartEditStore type ChartEditStoreType = typeof useChartEditStore
/** /**
* setdata * setdata
* @param targetComponent * @param targetComponent
* @param useChartEditStore * @param useChartEditStore
* @param updateCallback * @param updateCallback
*/ */
export const useChartDataFetch = ( export const useChartDataFetch = (
targetComponent: CreateComponentType, targetComponent: CreateComponentType,
useChartEditStore: ChartEditStoreType, useChartEditStore: ChartEditStoreType,
updateCallback?: (...args: any) => any updateCallback?: (...args: any) => any
) => { ) => {
const vChartRef = ref<typeof VChart | null>(null) const vChartRef = ref<typeof VChart | null>(null)
let fetchInterval: any = 0 let fetchInterval: any = 0
// 数据池 // 数据池
const { addGlobalDataInterface } = useChartDataPondFetch() const { addGlobalDataInterface } = useChartDataPondFetch()
// 组件类型 // 组件类型
const { chartFrame } = targetComponent.chartConfig const { chartFrame } = targetComponent.chartConfig
// eCharts 组件配合 vChart 库更新方式 // eCharts 组件配合 vChart 库更新方式
const echartsUpdateHandle = (dataset: any) => { const echartsUpdateHandle = (dataset: any) => {
if (chartFrame === ChartFrameEnum.ECHARTS) { if (chartFrame === ChartFrameEnum.ECHARTS) {
if (vChartRef.value) { if (vChartRef.value) {
setOption(vChartRef.value, { dataset: dataset }) setOption(vChartRef.value, { dataset: dataset })
} }
} }
} }
const requestIntervalFn = () => { const requestIntervalFn = () => {
const chartEditStore = useChartEditStore() const chartEditStore = useChartEditStore()
// 全局数据 // 全局数据
const { const {
requestOriginUrl, requestOriginUrl,
requestIntervalUnit: globalUnit, requestIntervalUnit: globalUnit,
requestInterval: globalRequestInterval requestInterval: globalRequestInterval
} = toRefs(chartEditStore.getRequestGlobalConfig) } = toRefs(chartEditStore.getRequestGlobalConfig)
// 目标组件 // 目标组件
const { const {
requestDataType, requestDataType,
requestUrl, requestUrl,
requestIntervalUnit: targetUnit, requestIntervalUnit: targetUnit,
requestInterval: targetInterval requestInterval: targetInterval
} = toRefs(targetComponent.request) } = toRefs(targetComponent.request)
// 非请求类型 // 非请求类型
if (requestDataType.value !== RequestDataTypeEnum.AJAX) return if (requestDataType.value !== RequestDataTypeEnum.AJAX) return
try { try {
// 处理地址 // 处理地址
// @ts-ignore // @ts-ignore
if (requestUrl?.value) { if (requestUrl?.value) {
// requestOriginUrl 允许为空 // requestOriginUrl 允许为空
const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value const completePath = requestOriginUrl && requestOriginUrl.value + requestUrl.value
if (!completePath) return if (!completePath) return
clearInterval(fetchInterval) clearInterval(fetchInterval)
const fetchFn = async () => { const fetchFn = async () => {
const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig)) const res = await customizeHttp(toRaw(targetComponent.request), toRaw(chartEditStore.getRequestGlobalConfig))
if (res) { if (res) {
try { try {
const filter = targetComponent.filter const filter = targetComponent.filter
echartsUpdateHandle(newFunctionHandle(res?.data, res, filter)) const { data } = res
// 更新回调函数 echartsUpdateHandle(newFunctionHandle(data, res, filter))
if (updateCallback) { // 更新回调函数
updateCallback(newFunctionHandle(res?.data, res, filter)) if (updateCallback) {
} updateCallback(newFunctionHandle(data, res, filter))
} catch (error) { }
console.error(error) } catch (error) {
} console.error(error)
} }
} }
}
// 普通初始化与组件交互处理监听
watch( // 普通初始化与组件交互处理监听
() => targetComponent.request, watch(
() => { () => targetComponent.request,
fetchFn() () => {
}, fetchFn()
{ },
immediate: true, {
deep: true immediate: true,
} deep: true
) }
)
// 定时时间
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value // 定时时间
// 单位 const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value // 单位
// 开启轮询 const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit)) // 开启轮询
} if (time) fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
// eslint-disable-next-line no-empty }
} catch (error) { // eslint-disable-next-line no-empty
console.log(error) } catch (error) {
} console.log(error)
} }
}
if (isPreview()) {
// 判断是否是数据池类型 if (isPreview()) {
targetComponent.request.requestDataType === RequestDataTypeEnum.Pond // 判断是否是数据池类型
? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle) targetComponent.request.requestDataType === RequestDataTypeEnum.Pond
: requestIntervalFn() ? addGlobalDataInterface(targetComponent, useChartEditStore, updateCallback || echartsUpdateHandle)
} : requestIntervalFn()
return { vChartRef } }
} return { vChartRef }
}

View File

@ -1,196 +1,197 @@
<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" style="border-radius: 5px"> <n-tag :bordered="false" type="primary" style="border-radius: 5px">
{{ targetData.request.requestContentType === RequestContentTypeEnum.DEFAULT ? '普通请求' : 'SQL请求' }} {{ targetData.request.requestContentType === RequestContentTypeEnum.DEFAULT ? '普通请求' : 'SQL请求' }}
</n-tag> </n-tag>
</setting-item> </setting-item>
<setting-item name="方式"> <setting-item name="方式">
<n-input size="small" :placeholder="targetData.request.requestHttpType || '暂无'" :disabled="true"></n-input> <n-input size="small" :placeholder="targetData.request.requestHttpType || '暂无'" :disabled="true"></n-input>
</setting-item> </setting-item>
<setting-item name="组件间隔"> <setting-item name="组件间隔">
<n-input size="small" :placeholder="`${targetData.request.requestInterval || '暂无'}`" :disabled="true"> <n-input size="small" :placeholder="`${targetData.request.requestInterval || '暂无'}`" :disabled="true">
<template #suffix> {{ SelectHttpTimeNameObj[targetData.request.requestIntervalUnit] }} </template> <template #suffix> {{ SelectHttpTimeNameObj[targetData.request.requestIntervalUnit] }} </template>
</n-input> </n-input>
</setting-item> </setting-item>
<setting-item name="全局间隔(默认)"> <setting-item name="全局间隔(默认)">
<n-input size="small" :placeholder="`${GlobalRequestInterval || '暂无'} `" :disabled="true"> <n-input size="small" :placeholder="`${GlobalRequestInterval || '暂无'} `" :disabled="true">
<template #suffix> {{ SelectHttpTimeNameObj[GlobalRequestIntervalUnit] }} </template> <template #suffix> {{ SelectHttpTimeNameObj[GlobalRequestIntervalUnit] }} </template>
</n-input> </n-input>
</setting-item> </setting-item>
</setting-item-box> </setting-item-box>
<setting-item-box name="源地址" :alone="true"> <setting-item-box name="源地址" :alone="true">
<n-input size="small" :placeholder="requestOriginUrl || '暂无'" :disabled="true"> <n-input size="small" :placeholder="requestOriginUrl || '暂无'" :disabled="true">
<template #prefix> <template #prefix>
<n-icon :component="PulseIcon" /> <n-icon :component="PulseIcon" />
</template> </template>
</n-input> </n-input>
</setting-item-box> </setting-item-box>
<setting-item-box name="组件地址" :alone="true"> <setting-item-box name="组件地址" :alone="true">
<n-input size="small" :placeholder="targetData.request.requestUrl || '暂无'" :disabled="true"> <n-input size="small" :placeholder="targetData.request.requestUrl || '暂无'" :disabled="true">
<template #prefix> <template #prefix>
<n-icon :component="FlashIcon" /> <n-icon :component="FlashIcon" />
</template> </template>
</n-input> </n-input>
</setting-item-box> </setting-item-box>
<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>
<setting-item-box :alone="true"> <setting-item-box :alone="true">
<template #name> <template #name>
测试 测试
<n-tooltip trigger="hover"> <n-tooltip trigger="hover">
<template #trigger> <template #trigger>
<n-icon size="21" :depth="3"> <n-icon size="21" :depth="3">
<help-outline-icon></help-outline-icon> <help-outline-icon></help-outline-icon>
</n-icon> </n-icon>
</template> </template>
默认赋值给 dataset 字段 默认赋值给 dataset 字段
</n-tooltip> </n-tooltip>
</template> </template>
<n-button type="primary" ghost @click="sendHandle"> <n-button type="primary" ghost @click="sendHandle">
<template #icon> <template #icon>
<n-icon> <n-icon>
<flash-icon /> <flash-icon />
</n-icon> </n-icon>
</template> </template>
发送请求 发送请求
</n-button> </n-button>
</setting-item-box> </setting-item-box>
<!-- 底部数据展示 --> <!-- 底部数据展示 -->
<chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show> <chart-data-matching-and-show :show="showMatching && !loading" :ajax="true"></chart-data-matching-and-show>
<!-- 骨架图 --> <!-- 骨架图 -->
<go-skeleton :load="loading" :repeat="3"></go-skeleton> <go-skeleton :load="loading" :repeat="3"></go-skeleton>
<!-- 请求配置model --> <!-- 请求配置model -->
<chart-data-request <chart-data-request
v-model:modelShow="requestShow" v-model:modelShow="requestShow"
:targetData="targetData" :targetData="targetData"
@sendHandle="sendHandle" @sendHandle="sendHandle"
></chart-data-request> ></chart-data-request>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRefs, computed, onBeforeUnmount, watchEffect, toRaw } from 'vue' import { ref, toRefs, computed, 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, RequestContentTypeEnum } 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, customizeHttp } 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'
import { newFunctionHandle } from '@/utils' import { newFunctionHandle } from '@/utils'
const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5 const { HelpOutlineIcon, FlashIcon, PulseIcon } = icon.ionicons5
const { targetData, chartEditStore } = useTargetData() const { targetData, chartEditStore } = useTargetData()
const { const {
requestOriginUrl, requestOriginUrl,
requestInterval: GlobalRequestInterval, requestInterval: GlobalRequestInterval,
requestIntervalUnit: GlobalRequestIntervalUnit requestIntervalUnit: GlobalRequestIntervalUnit
} = toRefs(chartEditStore.getRequestGlobalConfig) } = toRefs(chartEditStore.getRequestGlobalConfig)
const designStore = useDesignStore() const designStore = useDesignStore()
// //
const loading = ref(false) const loading = ref(false)
const requestShow = ref(false) const requestShow = ref(false)
const showMatching = ref(false) const showMatching = ref(false)
let firstFocus = 0 let firstFocus = 0
let lastFilter: any = undefined let lastFilter: any = undefined
// model // model
const requestModelHandle = () => { const requestModelHandle = () => {
requestShow.value = true requestShow.value = true
} }
// //
const sendHandle = async () => { const sendHandle = async () => {
if (!targetData.value?.request) return if (!targetData.value?.request) return
loading.value = true loading.value = true
try { try {
const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig)) const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
loading.value = false loading.value = false
if (res) { if (res) {
if (!res?.data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!') const { data } = res
targetData.value.option.dataset = newFunctionHandle(res?.data, res, targetData.value.filter) if (!data && !targetData.value.filter) window['$message'].warning('您的数据不符合默认格式,请配置过滤器!')
showMatching.value = true targetData.value.option.dataset = newFunctionHandle(data, res, targetData.value.filter)
return showMatching.value = true
} return
window['$message'].warning('没有拿到返回值,请检查接口!') }
} catch (error) { window['$message'].warning('没有拿到返回值,请检查接口!')
console.error(error); } catch (error) {
loading.value = false console.error(error);
window['$message'].warning('数据异常,请检查参数!') loading.value = false
} window['$message'].warning('数据异常,请检查参数!')
} }
}
//
const themeColor = computed(() => { //
return designStore.getAppTheme const themeColor = computed(() => {
}) return designStore.getAppTheme
})
watchEffect(() => {
const filter = targetData.value?.filter watchEffect(() => {
if (lastFilter !== filter && firstFocus) { const filter = targetData.value?.filter
lastFilter = filter if (lastFilter !== filter && firstFocus) {
sendHandle() lastFilter = filter
} sendHandle()
firstFocus++ }
}) firstFocus++
})
onBeforeUnmount(() => {
lastFilter = null onBeforeUnmount(() => {
}) lastFilter = null
</script> })
</script>
<style lang="scss" scoped>
@include go('chart-configurations-data-ajax') { <style lang="scss" scoped>
.n-card-shallow { @include go('chart-configurations-data-ajax') {
&.n-card { .n-card-shallow {
@extend .go-background-filter; &.n-card {
@include deep() { @extend .go-background-filter;
.n-card__content { @include deep() {
padding: 10px; .n-card__content {
} padding: 10px;
} }
} }
.edit-text { }
position: absolute; .edit-text {
top: 0px; position: absolute;
left: 0px; top: 0px;
width: 325px; left: 0px;
height: 270px; width: 325px;
cursor: pointer; height: 270px;
opacity: 0; cursor: pointer;
transition: all 0.3s; opacity: 0;
@extend .go-background-filter; transition: all 0.3s;
backdrop-filter: blur(2px) !important; @extend .go-background-filter;
} backdrop-filter: blur(2px) !important;
&:hover { }
border-color: v-bind('themeColor'); &:hover {
.edit-text { border-color: v-bind('themeColor');
opacity: 1; .edit-text {
} opacity: 1;
} }
} }
} }
</style> }
</style>

View File

@ -1,215 +1,215 @@
<template> <template>
<template v-if="targetData.filter"> <template v-if="targetData.filter">
<n-card> <n-card>
<p><span class="func-keyword">function</span>&nbsp;&nbsp;filter(data, res)&nbsp;&nbsp;{</p> <p><span class="func-keyword">function</span>&nbsp;&nbsp;filter(data, res)&nbsp;&nbsp;{</p>
<!-- 函数体 --> <!-- 函数体 -->
<div class="go-ml-4"> <div class="go-ml-4">
<n-code :code="targetData.filter" language="typescript"></n-code> <n-code :code="targetData.filter" language="typescript"></n-code>
</div> </div>
<p>}</p> <p>}</p>
<template #footer> <template #footer>
<n-space justify="end"> <n-space justify="end">
<n-button type="primary" tertiary size="small" @click="addFilter"> <n-button type="primary" tertiary size="small" @click="addFilter">
<template #icon> <template #icon>
<n-icon> <n-icon>
<filter-edit-icon /> <filter-edit-icon />
</n-icon> </n-icon>
</template> </template>
编辑 编辑
</n-button> </n-button>
<n-button tertiary size="small" @click="delFilter"> 删除 </n-button> <n-button tertiary size="small" @click="delFilter"> 删除 </n-button>
</n-space> </n-space>
</template> </template>
</n-card> </n-card>
</template> </template>
<template v-else> <template v-else>
<n-button class="go-ml-3" @click="addFilter"> <n-button class="go-ml-3" @click="addFilter">
<template #icon> <template #icon>
<n-icon> <n-icon>
<filter-icon /> <filter-icon />
</n-icon> </n-icon>
</template> </template>
新增过滤器 新增过滤器
</n-button> </n-button>
</template> </template>
<!-- 弹窗 --> <!-- 弹窗 -->
<n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false" :closeOnEsc="false"> <n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false" :closeOnEsc="false">
<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 600px"> <n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1000px; height: 600px">
<template #header> <template #header>
<n-space> <n-space>
<n-text>过滤器函数编辑器</n-text> <n-text>过滤器函数编辑器</n-text>
</n-space> </n-space>
</template> </template>
<template #header-extra> </template> <template #header-extra> </template>
<n-space size="small" vertical> <n-space size="small" vertical>
<n-space justify="space-between"> <n-space justify="space-between">
<div> <div>
<n-space vertical> <n-space vertical>
<n-tag type="info"> <n-tag type="info">
<span class="func-keyword">function</span>&nbsp;&nbsp;filter(data, res)&nbsp;&nbsp;{ <span class="func-keyword">function</span>&nbsp;&nbsp;filter(data, res)&nbsp;&nbsp;{
</n-tag> </n-tag>
<monaco-editor v-model:modelValue="filter" width="460px" height="380px" language="javascript" /> <monaco-editor v-model:modelValue="filter" width="460px" height="380px" language="javascript" />
<n-tag type="info">}</n-tag> <n-tag type="info">}</n-tag>
</n-space> </n-space>
</div> </div>
<n-divider vertical style="height: 480px" /> <n-divider vertical style="height: 480px" />
<n-scrollbar style="max-height: 480px"> <n-scrollbar style="max-height: 480px">
<n-space :size="15" vertical> <n-space :size="15" vertical>
<div class="editor-data-show"> <div class="editor-data-show">
<n-space> <n-space>
<n-text depth="3">默认过滤数据(data)</n-text> <n-text depth="3">默认过滤数据(data)</n-text>
<n-code :code="toString(sourceData?.data) || '暂无'" language="json" :word-wrap="true"></n-code> <n-code :code="toString(sourceData?.data) || '暂无'" language="json" :word-wrap="true"></n-code>
</n-space> </n-space>
</div> </div>
<div class="editor-data-show"> <div class="editor-data-show">
<n-space> <n-space>
<n-text depth="3">接口返回数据(res)</n-text> <n-text depth="3">接口返回数据(res)</n-text>
<n-code :code="toString(sourceData) || '暂无'" language="json" :word-wrap="true"></n-code> <n-code :code="toString(sourceData) || '暂无'" language="json" :word-wrap="true"></n-code>
</n-space> </n-space>
</div> </div>
<div class="editor-data-show"> <div class="editor-data-show">
<n-space> <n-space>
<n-text depth="3">过滤器结果</n-text> <n-text depth="3">过滤器结果</n-text>
<n-code :code="filterRes || '暂无'" language="json" :word-wrap="true"></n-code> <n-code :code="filterRes || '暂无'" language="json" :word-wrap="true"></n-code>
</n-space> </n-space>
</div> </div>
</n-space> </n-space>
</n-scrollbar> </n-scrollbar>
</n-space> </n-space>
</n-space> </n-space>
<template #action> <template #action>
<n-space justify="space-between"> <n-space justify="space-between">
<div class="go-flex-items-center"> <div class="go-flex-items-center">
<n-tag :bordered="false" type="primary"> <n-tag :bordered="false" type="primary">
<template #icon> <template #icon>
<n-icon :component="DocumentTextIcon" /> <n-icon :component="DocumentTextIcon" />
</template> </template>
规则 规则
</n-tag> </n-tag>
<n-text class="go-ml-2" depth="2">过滤器默认处理接口返回值的data字段</n-text> <n-text class="go-ml-2" depth="2">过滤器默认处理接口返回值的data字段</n-text>
</div> </div>
<n-space> <n-space>
<n-button size="medium" @click="closeFilter">取消</n-button> <n-button size="medium" @click="closeFilter">取消</n-button>
<n-button size="medium" type="primary" @click="saveFilter">保存</n-button> <n-button size="medium" type="primary" @click="saveFilter">保存</n-button>
</n-space> </n-space>
</n-space> </n-space>
</template> </template>
</n-card> </n-card>
</n-modal> </n-modal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch, toRef, toRefs, toRaw, reactive } from 'vue' import { ref, computed, watch, toRef, toRefs, toRaw, reactive } from 'vue'
import { useTargetData } from '../../../hooks/useTargetData.hook' import { useTargetData } from '../../../hooks/useTargetData.hook'
import { MonacoEditor } from '@/components/Pages/MonacoEditor' import { MonacoEditor } from '@/components/Pages/MonacoEditor'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { goDialog, toString } from '@/utils' import { goDialog, toString } from '@/utils'
import { customizeHttp } from '@/api/http' import { customizeHttp } from '@/api/http'
import cloneDeep from 'lodash/cloneDeep' import cloneDeep from 'lodash/cloneDeep'
const { DocumentTextIcon } = icon.ionicons5 const { DocumentTextIcon } = icon.ionicons5
const { FilterIcon, FilterEditIcon } = icon.carbon const { FilterIcon, FilterEditIcon } = icon.carbon
const { targetData, chartEditStore } = useTargetData() const { targetData, chartEditStore } = useTargetData()
const { requestDataType } = toRefs(targetData.value.request) const { requestDataType } = toRefs(targetData.value.request)
const { requestOriginUrl } = toRefs(chartEditStore.getRequestGlobalConfig) const { requestOriginUrl } = toRefs(chartEditStore.getRequestGlobalConfig)
// //
const showModal = ref(false) const showModal = ref(false)
// filter // filter
const filter = ref(targetData.value.filter || `return data`) const filter = ref(targetData.value.filter || `return data`)
// //
const errorFlag = ref(false) const errorFlag = ref(false)
// / // /
const sourceData = ref<any>('') const sourceData = ref<any>('')
// //
const fetchTargetData = async () => { const fetchTargetData = async () => {
try { try {
const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig)) const res = await customizeHttp(toRaw(targetData.value.request), toRaw(chartEditStore.getRequestGlobalConfig))
if (res) { if (res) {
sourceData.value = res sourceData.value = res
return return
} }
window['$message'].warning('没有拿到返回值,请检查接口!') window['$message'].warning('没有拿到返回值,请检查接口!')
} catch (error) { } catch (error) {
console.error(error); console.error(error);
window['$message'].warning('数据异常,请检查参数!') window['$message'].warning('数据异常,请检查参数!')
} }
} }
// //
const filterRes = computed(() => { const filterRes = computed(() => {
try { try {
const fn = new Function('data', 'res', filter.value) const fn = new Function('data', 'res', filter.value)
const response = cloneDeep(sourceData.value) const response = cloneDeep(sourceData.value)
const res = fn(response?.data, response) const res = fn(response?.data, response)
// eslint-disable-next-line vue/no-side-effects-in-computed-properties // eslint-disable-next-line vue/no-side-effects-in-computed-properties
errorFlag.value = false errorFlag.value = false
return toString(res) return toString(res)
} catch (error) { } catch (error) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties // eslint-disable-next-line vue/no-side-effects-in-computed-properties
errorFlag.value = true errorFlag.value = true
return `过滤函数错误,日志:${error}` return `过滤函数错误,日志:${error}`
} }
}) })
// //
const addFilter = () => { const addFilter = () => {
showModal.value = true showModal.value = true
} }
// //
const delFilter = () => { const delFilter = () => {
goDialog({ goDialog({
message: '是否删除过滤器', message: '是否删除过滤器',
onPositiveCallback: () => { onPositiveCallback: () => {
targetData.value.filter = undefined targetData.value.filter = undefined
} }
}) })
} }
// //
const closeFilter = () => { const closeFilter = () => {
showModal.value = false showModal.value = false
} }
// //
const saveFilter = () => { const saveFilter = () => {
if (errorFlag.value) { if (errorFlag.value) {
window['$message'].error('过滤函数错误,无法进行保存') window['$message'].error('过滤函数错误,无法进行保存')
return return
} }
targetData.value.filter = filter.value targetData.value.filter = filter.value
closeFilter() closeFilter()
} }
watch( watch(
() => showModal.value, () => showModal.value,
(newData: boolean) => { (newData: boolean) => {
if (newData) { if (newData) {
fetchTargetData() fetchTargetData()
filter.value = targetData.value.filter || `return data` filter.value = targetData.value.filter || `return data`
} }
} }
) )
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.func-keyword { .func-keyword {
color: #b478cf; color: #b478cf;
} }
@include go('chart-data-monaco-editor') { @include go('chart-data-monaco-editor') {
&.n-card.n-modal, &.n-card.n-modal,
.n-card { .n-card {
@extend .go-background-filter; @extend .go-background-filter;
} }
.editor-data-show { .editor-data-show {
@include fetch-bg-color('filter-color'); @include fetch-bg-color('filter-color');
width: 420px; width: 420px;
padding: 20px; padding: 20px;
border-radius: 5px; border-radius: 5px;
} }
} }
</style> </style>

View File

@ -59,6 +59,8 @@
<n-form-item path="username"> <n-form-item path="username">
<n-input <n-input
v-model:value="formInline.username" v-model:value="formInline.username"
type="text"
maxlength="16"
:placeholder="$t('global.form_account')" :placeholder="$t('global.form_account')"
> >
<template #prefix> <template #prefix>
@ -72,6 +74,7 @@
<n-input <n-input
v-model:value="formInline.password" v-model:value="formInline.password"
type="password" type="password"
maxlength="16"
show-password-on="click" show-password-on="click"
:placeholder="$t('global.form_password')" :placeholder="$t('global.form_password')"
> >