fix(数据源): v2版本API数据源 能否支持Token认证 #9189

This commit is contained in:
dataeaseShu 2024-06-21 16:19:46 +08:00
parent 92917afb7a
commit 3b2457a383
7 changed files with 364 additions and 19 deletions

View File

@ -94,6 +94,7 @@ export const selectKey = ['textAlign', 'borderStyle', 'verticalAlign']
export const horizontalPosition = ['headHorizontalPosition']
export const fieldType = ['text', 'time', 'value', 'value', 'value', 'location']
export const fieldTypeText = ['文本', '时间', '数值', '数值(小数)', '数值', '地理位置']
export const optionMap = {
textAlign: textAlignOptions,

View File

@ -64,7 +64,7 @@ const showValueFormatter = computed<boolean>(() => {
})
watch(
[() => props.dimensionData, () => props.item],
[() => props.dimensionData, () => props.item, () => props.chart.type],
() => {
getItemTagType()
},
@ -210,7 +210,7 @@ onMounted(() => {
<span class="item-span-style">
<span class="item-name"
>{{ item.chartShowName ? item.chartShowName : item.name
}}{{ item.desensitized && '(已脱敏)' }}</span
}}{{ item.desensitized ? '(已脱敏)' : '' }}</span
>
</span>
</el-tooltip>

View File

@ -45,7 +45,7 @@ const emit = defineEmits(['onDimensionItemRemove'])
const { item } = toRefs(props)
watch(
[() => props.dimensionData, () => props.item],
[() => props.dimensionData, () => props.item, () => props.chart.type],
() => {
getItemTagType()
},
@ -102,7 +102,7 @@ onMounted(() => {
</el-icon>
</span>
<span class="item-span-style" :title="item.name"
>{{ item.name }}{{ item.desensitized && '(已脱敏)' }}</span
>{{ item.name }}{{ item.desensitized ? '(已脱敏)' : '' }}</span
>
<el-icon class="child remove-icon" size="14px">
<Icon name="icon_delete-trash_outlined" class-name="inner-class" @click="removeItem" />

View File

@ -68,7 +68,7 @@ const toolTip = computed(() => {
return props.themes === 'dark' ? 'ndark' : 'dark'
})
watch(
[() => props.quotaData, () => props.item],
[() => props.quotaData, () => props.item, () => props.chart.type],
() => {
getItemTagType()
},
@ -310,7 +310,7 @@ onMounted(() => {
<span class="item-span-style">
<span class="item-name"
>{{ item.chartShowName ? item.chartShowName : item.name
}}{{ item.desensitized && '(已脱敏)' }}</span
}}{{ item.desensitized ? '(已脱敏)' : '' }}</span
>
<span v-if="item.summary !== ''" class="item-right-summary">
({{ t('chart.' + item.summary) }})

View File

@ -1,5 +1,5 @@
<script lang="tsx" setup>
import { nextTick, reactive, ref, shallowRef } from 'vue'
import { nextTick, reactive, ref, shallowRef, provide } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import type { FormInstance, FormRules } from 'element-plus-secondary'
import { ElIcon, ElMessage } from 'element-plus-secondary'
@ -150,8 +150,10 @@ const rule = reactive<FormRules>({
}
]
})
const initApiItem = (val: ApiItem, apiList) => {
const activeName = ref('third')
provide('api-active-name', activeName)
const initApiItem = (val: ApiItem, apiList, name) => {
activeName.value = name
apiItemList = apiList
Object.assign(apiItem, val)
edit_api_item.value = true
@ -406,7 +408,9 @@ defineExpose({
<span class="icon">
{{ active <= 1 ? '2' : '' }}
</span>
<span class="title">{{ t('datasource.api_step_2') }}</span>
<span class="title">{{
activeName === 'third' ? t('datasource.api_step_2') : '提取参数'
}}</span>
</div>
</template>
</el-step>

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
import { computed, onBeforeMount, PropType, toRefs } from 'vue'
import { computed, onBeforeMount, PropType, toRefs, inject, ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { KeyValue } from './ApiTestModel.js'
import draggable from 'vuedraggable'
@ -44,6 +44,8 @@ onBeforeMount(() => {
}
})
const activeName = inject('api-active-name')
const remove = (index: number) => {
if (isDisable()) return
//
@ -66,6 +68,18 @@ const createFilter = (queryString: string) => {
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
}
}
const options = [
{
label: '参数',
value: 'params'
},
{
label: '固定值',
value: 'fixed'
}
]
const value = ref('')
</script>
<template>
@ -77,7 +91,7 @@ const createFilter = (queryString: string) => {
<el-icon class="drag handle">
<Icon name="icon_drag_outlined"></Icon>
</el-icon>
<el-col :span="8" v-if="!unShowSelect">
<el-col :span="activeName === 'third' ? 8 : 6" v-if="!unShowSelect">
<el-input
v-if="!suggestions"
v-model="element.name"
@ -96,7 +110,16 @@ const createFilter = (queryString: string) => {
show-word-limit
/>
</el-col>
<el-col :span="3" v-if="activeName === 'fourth'">
<el-select v-model="value">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
<el-col :span="8" v-if="unShowSelect">
<el-input
v-if="!!suggestions.length"
@ -108,14 +131,21 @@ const createFilter = (queryString: string) => {
/>
</el-col>
<el-col :span="7">
<el-col :span="activeName === 'third' ? 7 : 6">
<el-input
v-if="!needMock"
v-if="!needMock && activeName === 'third'"
v-model="element.value"
:disabled="isReadOnly"
:placeholder="unShowSelect ? t('common.description') : valueText"
show-word-limit
/>
<el-input
v-if="!needMock && activeName === 'fourth'"
v-model="element.value"
:disabled="isReadOnly"
:placeholder="value === 'params' ? '参数名称' : '值'"
show-word-limit
/>
</el-col>
<el-col :span="7" v-if="showDesc">

View File

@ -6,11 +6,12 @@ import EmptyBackground from '@/components/empty-background/src/EmptyBackground.v
import { cloneDeep } from 'lodash-es'
import ApiHttpRequestDraw from './ApiHttpRequestDraw.vue'
import type { Configuration, ApiConfiguration, SyncSetting } from './option'
import { fieldType, fieldTypeText } from '@/utils/attr'
import { Icon } from '@/components/icon-custom'
import { getSchema } from '@/api/datasource'
import { Base64 } from 'js-base64'
import { CustomPassword } from '@/components/custom-password'
import { ElForm, ElMessage } from 'element-plus-secondary'
import { ElForm, ElMessage, ElMessageBox } from 'element-plus-secondary'
import Cron from '@/components/cron/src/Cron.vue'
import { ComponentPublicInstance } from 'vue'
const { t } = useI18n()
@ -324,9 +325,11 @@ const addApiItem = item => {
: 0
}
nextTick(() => {
editApiItem.value.initApiItem(apiItem, form.value.apiConfiguration)
editApiItem.value.initApiItem(apiItem, form.value.apiConfiguration, activeName.value)
})
}
const activeName = ref('third')
const showPriority = ref(false)
const deleteItem = (item, idx) => {
@ -470,7 +473,149 @@ const apiRule = {
}
]
}
const dialogEditParams = ref(false)
const dialogRenameApi = ref(false)
const activeParamsName = ref('')
const apiParams = ref([
{
id: 1,
name: '接口1'
}
])
const paramsObj = ref({
name: '',
id: 1,
deType: 0
})
const apiObj = ref({
name: '',
id: 1
})
const paramsObjRules = {
name: [
{
required: true,
message: '请输入参数名称',
trigger: 'change'
},
{
min: 2,
max: 64,
message: '参数名称限制264字符',
trigger: 'blur'
}
]
}
const apiObjRules = {
name: [
{
required: true,
message: '请输入接口名称',
trigger: 'change'
},
{
min: 2,
max: 64,
message: '接口名称限制264字符',
trigger: 'blur'
}
]
}
const setActiveName = val => {
activeParamsName.value = val.name
}
const paramsObjRef = ref()
const apiObjRef = ref()
const saveParamsObj = () => {
paramsObjRef.value.validate(result => {
if (result) {
gridData.value.forEach(ele => {
if (ele.id === paramsObj.value.id) {
ele.name = paramsObj.value.name
}
})
}
})
}
const saveApiObj = () => {
apiObjRef.value.validate(result => {
if (result) {
apiParams.value.forEach(ele => {
if (ele.id === apiObj.value.id) {
ele.name = apiObj.value.name
}
})
}
})
}
const paramsResetForm = () => {
dialogEditParams.value = false
}
const apiResetForm = () => {
dialogRenameApi.value = false
}
const gridData = ref([
{
name: 'name',
deType: 0,
id: 0
}
])
const handleApiParams = (cmd: string, data) => {
if (cmd === 'rename') {
dialogRenameApi.value = true
paramsObj.value.name = data.name
}
if (cmd === 'delete') {
ElMessageBox.confirm('确定删除吗?', {
confirmButtonType: 'danger',
type: 'warning',
autofocus: false,
showClose: false
}).then(() => {
apiParams.value.splice(0, 1)
})
}
if (cmd === 'edit') {
addApiItem(data)
}
}
const editParams = data => {
dialogEditParams.value = true
}
const delParams = data => {
ElMessageBox.confirm('确定删除吗?', {
confirmButtonType: 'danger',
type: 'warning',
autofocus: false,
showClose: false
}).then(() => {
apiParams.value.splice(0, 1)
})
}
const datasetTypeList = [
{
label: '重命名',
svgName: 'icon_rename_outlined',
command: 'rename'
},
{
label: '删除',
svgName: 'icon_delete-trash_outlined',
command: 'delete'
}
]
defineExpose({
submitForm,
resetForm,
@ -522,7 +667,10 @@ defineExpose({
</el-form-item>
<template v-if="form.type === 'API'">
<div class="title-form_primary flex-space table-info-mr" v-show="activeStep !== 2">
<span>{{ t('datasource.data_table') }}</span>
<el-tabs v-model="activeName" class="api-tabs">
<el-tab-pane :label="t('datasource.data_table')" name="third"></el-tab-pane>
<el-tab-pane label="接口参数" name="fourth"></el-tab-pane>
</el-tabs>
<el-button type="primary" style="margin-left: auto" @click="() => addApiItem(null)">
<template #icon>
<Icon name="icon_add_outlined"></Icon>
@ -536,7 +684,7 @@ defineExpose({
:description="t('datasource.no_data_table')"
img-type="noneWhite"
/>
<template v-if="form.type === 'API' && activeStep === 1">
<template v-if="form.type === 'API' && activeStep === 1 && activeName === 'third'">
<div class="api-card-content">
<div
v-for="(api, idx) in form.apiConfiguration"
@ -609,6 +757,77 @@ defineExpose({
</div>
</div>
</template>
<div
style="display: flex"
v-if="form.type === 'API' && activeStep === 1 && activeName === 'fourth'"
>
<div class="left-api_params">
<div
v-for="ele in apiParams"
:class="[{ active: activeParamsName === ele.name }]"
class="list-item_primary"
:title="ele.name"
:key="ele.id"
@click="setActiveName(ele)"
>
<span class="label">{{ ele.name }}</span>
<span class="name-copy">
<el-icon class="hover-icon" @click.stop="handleApiParams('edit', ele)">
<icon name="icon_edit_outlined"></icon>
</el-icon>
<handle-more
icon-size="24px"
@handle-command="cmd => handleApiParams(cmd, ele)"
:menu-list="datasetTypeList"
placement="bottom-start"
></handle-more>
</span>
</div>
</div>
<div class="right-api_params">
<el-table
height="300"
style="width: 100%"
header-cell-class-name="header-cell"
:data="gridData"
>
<el-table-column :label="t('visualization.param_name')">
<template #default="scope">
{{ scope.row.name || '-' }}
</template>
</el-table-column>
<el-table-column :label="t('deDataset.parameter_type')">
<template #default="scope">
<div class="flex-align-center icon">
<el-icon>
<Icon
:className="`field-icon-${fieldType[scope.row.deType]}`"
:name="`field_${fieldType[scope.row.deType]}`"
></Icon>
</el-icon>
{{ fieldTypeText[scope.row.deType] }}
</div>
</template>
</el-table-column>
<el-table-column :label="t('common.operate')">
<template #default="scope">
<el-button text @click.stop="editParams(scope.row)">
<template #icon>
<Icon name="icon_edit_outlined"></Icon>
</template>
</el-button>
<el-button text @click.stop="delParams(scope.row)">
<template #icon>
<Icon name="icon_delete-trash_outlined"></Icon>
</template>
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<template v-if="notapiexcelconfig">
<el-form-item label="连接方式" prop="type">
@ -957,6 +1176,61 @@ defineExpose({
</el-form-item>
</div>
</el-form>
<el-dialog
title="编辑参数"
v-model="dialogEditParams"
width="420px"
class="create-dialog"
:before-close="paramsResetForm"
>
<el-form
label-position="top"
require-asterisk-position="right"
ref="paramsObjRef"
@keydown.stop.prevent.enter
:model="paramsObj"
:rules="paramsObjRules"
>
<el-form-item :label="t('visualization.param_name')" prop="name">
<el-input placeholder="请输入参数名称" v-model="paramsObj.name" />
</el-form-item>
<el-form-item :label="t('deDataset.parameter_type')" prop="deType">
<el-radio-group v-model="paramsObj.deType">
<el-radio :value="0" label="文本"></el-radio>
<el-radio :value="2" label="数值"></el-radio>
<el-radio :value="3" label="数值(小数)"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<el-button secondary @click="paramsResetForm">{{ t('dataset.cancel') }} </el-button>
<el-button type="primary" @click="saveParamsObj">{{ t('dataset.confirm') }} </el-button>
</template>
</el-dialog>
<el-dialog
title="重命名"
v-model="dialogRenameApi"
width="420px"
class="create-dialog"
:before-close="apiResetForm"
>
<el-form
label-position="top"
require-asterisk-position="right"
ref="paramsObjRef"
@keydown.stop.prevent.enter
:model="apiObj"
:rules="apiObjRules"
>
<el-form-item label="接口名称" prop="name">
<el-input placeholder="请输入接口名称" v-model="apiObj.name" />
</el-form-item>
</el-form>
<template #footer>
<el-button secondary @click="apiResetForm">{{ t('dataset.cancel') }} </el-button>
<el-button type="primary" @click="saveApiObj">{{ t('dataset.confirm') }} </el-button>
</template>
</el-dialog>
<api-http-request-draw @return-item="returnItem" ref="editApiItem"></api-http-request-draw>
</div>
@ -1037,8 +1311,44 @@ defineExpose({
margin: 24px 0 16px 0;
}
.left-api_params {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border: 1px solid #bbbfc4;
width: 300px;
padding: 16px;
.name-copy {
display: none;
line-height: 24px;
margin-left: 4px;
}
.list-item_primary:hover {
.name-copy {
display: inline;
}
.label {
width: 74% !important;
}
}
}
.right-api_params {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
border: 1px solid #bbbfc4;
border-left: none;
width: calc(100% - 200px);
}
.table-info-mr {
margin: 28px 0 12px 0;
.api-tabs {
:deep(.ed-tabs__nav-wrap::after) {
display: none;
}
}
}
.info-update {