mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
Merge branch 'main' of github.com:maxkb-dev/maxkb
This commit is contained in:
commit
6e31965976
|
|
@ -0,0 +1,63 @@
|
|||
import { Result } from '@/request/Result'
|
||||
import { get, post, postStream, del, put } from '@/request/index'
|
||||
|
||||
import { type Ref } from 'vue'
|
||||
|
||||
const prefix = '/application'
|
||||
|
||||
/**
|
||||
* API_KEY列表
|
||||
* @param 参数 applicaiton_id
|
||||
*/
|
||||
const getAPIKey: (applicaiton_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
applicaiton_id,
|
||||
loading
|
||||
) => {
|
||||
return get(`${prefix}/${applicaiton_id}/api_key`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增API_KEY
|
||||
* @param 参数 applicaiton_id
|
||||
*/
|
||||
const postAPIKey: (applicaiton_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
applicaiton_id,
|
||||
loading
|
||||
) => {
|
||||
return post(`${prefix}/${applicaiton_id}/api_key`, {}, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除API_KEY
|
||||
* @param 参数 applicaiton_id api_key_id
|
||||
*/
|
||||
const delAPIKey: (
|
||||
applicaiton_id: String,
|
||||
api_key_id: String,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<boolean>> = (applicaiton_id, api_key_id, loading) => {
|
||||
return del(`${prefix}/${applicaiton_id}/api_key/${api_key_id}`, undefined, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改API_KEY
|
||||
* @param 参数 applicaiton_id,api_key_id
|
||||
* data {
|
||||
* is_active: boolean
|
||||
* }
|
||||
*/
|
||||
const putAPIKey: (
|
||||
applicaiton_id: string,
|
||||
api_key_id: String,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (applicaiton_id, api_key_id, data, loading) => {
|
||||
return put(`${prefix}/${applicaiton_id}/api_key/${api_key_id}`, data, undefined, loading)
|
||||
}
|
||||
|
||||
export default {
|
||||
getAPIKey,
|
||||
postAPIKey,
|
||||
delAPIKey,
|
||||
putAPIKey
|
||||
}
|
||||
|
|
@ -111,17 +111,6 @@ const getApplicationDataset: (
|
|||
return get(`${prefix}/${applicaiton_id}/list_dataset`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* API_KEY列表
|
||||
* @param 参数 applicaiton_id
|
||||
*/
|
||||
const getAPIKey: (applicaiton_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||
applicaiton_id,
|
||||
loading
|
||||
) => {
|
||||
return get(`${prefix}/${applicaiton_id}/api_key`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AccessToken
|
||||
* @param 参数 applicaiton_id
|
||||
|
|
@ -133,6 +122,21 @@ const getAccessToken: (applicaiton_id: string, loading?: Ref<boolean>) => Promis
|
|||
return get(`${prefix}/${applicaiton_id}/access_token`, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改AccessToken
|
||||
* @param 参数 applicaiton_id
|
||||
* data {
|
||||
* "is_active": true
|
||||
* }
|
||||
*/
|
||||
const putAccessToken: (
|
||||
applicaiton_id: string,
|
||||
data: any,
|
||||
loading?: Ref<boolean>
|
||||
) => Promise<Result<any>> = (applicaiton_id, data, loading) => {
|
||||
return put(`${prefix}/${applicaiton_id}/access_token`, data, undefined, loading)
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用认证
|
||||
* @param 参数
|
||||
|
|
@ -235,8 +239,8 @@ export default {
|
|||
delApplication,
|
||||
getApplicationDetail,
|
||||
getApplicationDataset,
|
||||
getAPIKey,
|
||||
getAccessToken,
|
||||
putAccessToken,
|
||||
postAppAuthentication,
|
||||
getProfile,
|
||||
putChatVote
|
||||
|
|
|
|||
|
|
@ -141,8 +141,8 @@ export const post: (
|
|||
*/
|
||||
export const put: (
|
||||
url: string,
|
||||
params?: unknown,
|
||||
data?: unknown,
|
||||
params?: unknown,
|
||||
loading?: NProgress | Ref<boolean>
|
||||
) => Promise<Result<any>> = (url, data, params, loading) => {
|
||||
return promise(request({ url: url, method: 'put', data, params }), loading)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const applicationRouter = {
|
|||
parentPath: '/application/:id',
|
||||
parentName: 'ApplicationDetail'
|
||||
},
|
||||
component: () => import('@/views/application/AppOverview.vue')
|
||||
component: () => import('@/views/applicaiton-overview/index.vue')
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<el-dialog title="API Key" v-model="dialogVisible" width="800">
|
||||
<el-button type="primary" class="mb-16" @click="createApiKey"> 创建 </el-button>
|
||||
<el-table :data="apiKey" class="mb-16" :loading="loading">
|
||||
<el-table-column prop="secret_key" label="API Key">
|
||||
<template #default="{ row }">
|
||||
<span class="vertical-middle lighter break-all">
|
||||
{{ row.secret_key }}
|
||||
</span>
|
||||
<el-button type="primary" text @click="copyClick(row.secret_key)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<div @click.stop>
|
||||
<el-switch size="small" v-model="row.is_active" @change="changeState($event, row)" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="创建日期" width="170">
|
||||
<template #default="{ row }">
|
||||
{{ datetimeFormat(row.create_time) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-tooltip effect="dark" content="删除" placement="top">
|
||||
<el-button type="primary" text @click="deleteApiKey(row)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import overviewApi from '@/api/application-overview'
|
||||
import { datetimeFormat } from '@/utils/time'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import useStore from '@/stores'
|
||||
const route = useRoute()
|
||||
const {
|
||||
params: { id }
|
||||
} = route
|
||||
const { application } = useStore()
|
||||
|
||||
const emit = defineEmits(['addData'])
|
||||
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
const loading = ref(false)
|
||||
const apiKey = ref<any>(null)
|
||||
|
||||
watch(dialogVisible, (bool) => {
|
||||
if (!bool) {
|
||||
apiKey.value = null
|
||||
}
|
||||
})
|
||||
|
||||
function deleteApiKey(row: any) {
|
||||
MsgConfirm(
|
||||
`是否删除API Key:${row.secret_key} ?`,
|
||||
`删除后无法使用该 API Key 调用接口,请谨慎操作`,
|
||||
{
|
||||
confirmButtonText: '删除',
|
||||
confirmButtonClass: 'danger'
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
overviewApi.delAPIKey(id as string, row.id, loading).then(() => {
|
||||
MsgSuccess('删除成功')
|
||||
getApiKeyList()
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
function changeState(bool: Boolean, row: any) {
|
||||
const obj = {
|
||||
is_active: bool
|
||||
}
|
||||
const str = bool ? '启用成功' : '禁用成功'
|
||||
overviewApi.putAPIKey(id as string, row.id, obj, loading).then((res) => {
|
||||
MsgSuccess(str)
|
||||
getApiKeyList()
|
||||
})
|
||||
}
|
||||
|
||||
function createApiKey() {
|
||||
overviewApi.postAPIKey(id as string, loading).then((res) => {
|
||||
getApiKeyList()
|
||||
})
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
getApiKeyList()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function getApiKeyList() {
|
||||
overviewApi.getAPIKey(id as string, loading).then((res) => {
|
||||
apiKey.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.embed-dialog {
|
||||
.code {
|
||||
color: var(--app-text-color) !important;
|
||||
background: var(--app-layout-bg-color);
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
white-space: pre;
|
||||
height: 180px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<LayoutContainer header="概览">
|
||||
<div class="main-calc-height p-24">
|
||||
<h4 class="title-decoration-1 mb-16">应用信息</h4>
|
||||
<el-card shadow="never" class="overview-card">
|
||||
<el-card shadow="never" class="overview-card" v-loading="loading">
|
||||
<div class="title flex align-center">
|
||||
<AppAvatar
|
||||
v-if="detail?.name"
|
||||
|
|
@ -20,15 +20,17 @@
|
|||
<div class="flex">
|
||||
<el-text type="info">公开访问链接</el-text>
|
||||
<el-switch
|
||||
v-model="accessToken.is_active"
|
||||
class="ml-8"
|
||||
size="small"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
@change="changeState"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="mt-4 url-height">
|
||||
<span class="vertical-middle lighter break-all">
|
||||
{{ shareUrl }}
|
||||
</span>
|
||||
|
|
@ -36,40 +38,46 @@
|
|||
<el-button type="primary" text @click="copyClick(shareUrl)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
<el-button @click="getAccessToken" type="primary" text style="margin-left: 1px">
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-16">
|
||||
<el-button type="primary"><a :href="shareUrl" target="_blank">演示</a></el-button>
|
||||
<el-button @click="openDialog"> 嵌入第三方 </el-button>
|
||||
<div>
|
||||
<el-button :disabled="!accessToken?.is_active" type="primary"><a :href="shareUrl" target="_blank">演示</a></el-button>
|
||||
<el-button :disabled="!accessToken?.is_active" @click="openDialog"> 嵌入第三方 </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" class="mt-16">
|
||||
<div class="flex">
|
||||
<el-text type="info">API访问凭据</el-text>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<div class="mt-4 url-height">
|
||||
<span class="vertical-middle lighter break-all">
|
||||
API Key: OGZmZThlZjYyYzU2MWE1OTlkYTVjZTBi
|
||||
{{ apiUrl }}
|
||||
</span>
|
||||
|
||||
<el-button type="primary" text>
|
||||
<el-button type="primary" text @click="copyClick(apiUrl)">
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-16">
|
||||
<el-button @click="openDialog"> 获取密钥 </el-button>
|
||||
<div>
|
||||
<el-button @click="openAPIKeyDialog"> API Key </el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
<EmbedDialog ref="EmbedDialogRef" />
|
||||
<APIKeyDialog ref="APIKeyDialogRef" />
|
||||
</LayoutContainer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import EmbedDialog from './component/EmbedDialog.vue'
|
||||
import APIKeyDialog from './component/APIKeyDialog.vue'
|
||||
import applicationApi from '@/api/application'
|
||||
import EmbedDialog from './components/EmbedDialog.vue'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { copyClick } from '@/utils/clipboard'
|
||||
import useStore from '@/stores'
|
||||
const { application } = useStore()
|
||||
|
|
@ -79,27 +87,37 @@ const {
|
|||
params: { id }
|
||||
} = route as any
|
||||
|
||||
const apiUrl = window.location.origin + '/doc'
|
||||
|
||||
const APIKeyDialogRef = ref()
|
||||
const EmbedDialogRef = ref()
|
||||
const shareUrl = ref('')
|
||||
const accessToken = ref('')
|
||||
const accessToken = ref<any>({})
|
||||
const detail = ref<any>(null)
|
||||
const apiKey = ref<any>(null)
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
function openDialog() {
|
||||
EmbedDialogRef.value.open(accessToken.value)
|
||||
}
|
||||
function getAccessToken() {
|
||||
application.asyncGetAccessToken(id, loading).then((res: any) => {
|
||||
accessToken.value = res?.data?.access_token
|
||||
shareUrl.value = application.location + res?.data?.access_token
|
||||
function changeState(bool: Boolean) {
|
||||
const obj = {
|
||||
is_active: bool
|
||||
}
|
||||
const str = bool ? '启用成功' : '禁用成功'
|
||||
applicationApi.putAccessToken(id as string, obj, loading).then((res) => {
|
||||
MsgSuccess(str)
|
||||
getDetail()
|
||||
})
|
||||
}
|
||||
|
||||
function getApiKey() {
|
||||
applicationApi.getAPIKey(id, loading).then((res) => {
|
||||
apiKey.value = res.data
|
||||
function openAPIKeyDialog() {
|
||||
APIKeyDialogRef.value.open()
|
||||
}
|
||||
function openDialog() {
|
||||
EmbedDialogRef.value.open(accessToken.value?.access_token)
|
||||
}
|
||||
function getAccessToken() {
|
||||
application.asyncGetAccessToken(id, loading).then((res: any) => {
|
||||
accessToken.value = res?.data
|
||||
shareUrl.value = application.location + res?.data?.access_token
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +128,6 @@ function getDetail() {
|
|||
}
|
||||
onMounted(() => {
|
||||
getDetail()
|
||||
getApiKey()
|
||||
getAccessToken()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -122,5 +139,8 @@ onMounted(() => {
|
|||
right: 16px;
|
||||
top: 21px;
|
||||
}
|
||||
.url-height {
|
||||
min-height: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="启用状态">
|
||||
<el-table-column label="启用状态">
|
||||
<template #default="{ row }">
|
||||
<div @click.stop>
|
||||
<el-switch
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
{{ datetimeFormat(row.update_time) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="操作" align="center">
|
||||
<el-table-column label="操作" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.status === 2">
|
||||
<el-tooltip effect="dark" content="刷新" placement="top">
|
||||
|
|
|
|||
|
|
@ -1,50 +1,56 @@
|
|||
<template>
|
||||
<el-input v-model="filterText" placeholder="搜索" prefix-icon="Search" class="mb-16" />
|
||||
|
||||
<el-table :data="data" :max-height="tableHeight">
|
||||
<el-table-column prop="name" :label="isApplication ? '应用名称' : '数据集名称'">
|
||||
<template #default="{ row }">
|
||||
<div class="flex align-center">
|
||||
<AppAvatar
|
||||
v-if="isApplication"
|
||||
:name="row.name"
|
||||
pinyinColor
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
:size="24"
|
||||
/>
|
||||
<AppAvatar v-else-if="isDataset" class="mr-12" shape="square" :size="24">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
<span class="ellipsis-1"> {{ row?.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="管理" align="center" width="60">
|
||||
<!-- <template #header>
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="搜索"
|
||||
prefix-icon="Search"
|
||||
class="p-24 pt-0 pb-0 mb-16 mt-4"
|
||||
/>
|
||||
<div class="p-24 pt-0">
|
||||
<el-table :data="data" :max-height="tableHeight">
|
||||
<el-table-column prop="name" :label="isApplication ? '应用名称' : '数据集名称'">
|
||||
<template #default="{ row }">
|
||||
<div class="flex align-center">
|
||||
<AppAvatar
|
||||
v-if="isApplication"
|
||||
:name="row.name"
|
||||
pinyinColor
|
||||
class="mr-12"
|
||||
shape="square"
|
||||
:size="24"
|
||||
/>
|
||||
<AppAvatar v-else-if="isDataset" class="mr-12" shape="square" :size="24">
|
||||
<img src="@/assets/icon_document.svg" style="width: 58%" alt="" />
|
||||
</AppAvatar>
|
||||
<span class="ellipsis-1"> {{ row?.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="管理" align="center" width="60">
|
||||
<!-- <template #header>
|
||||
<el-checkbox
|
||||
v-model="allChecked[MANAGE]"
|
||||
label="管理"
|
||||
@change="handleCheckAllChange($event, MANAGE)"
|
||||
/>
|
||||
</template> -->
|
||||
<template #default="{ row }">
|
||||
<el-checkbox v-model="row.operate[MANAGE]" @change="checkedOperateChange(MANAGE, row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用" align="center" width="60">
|
||||
<!-- <template #header>
|
||||
<template #default="{ row }">
|
||||
<el-checkbox v-model="row.operate[MANAGE]" @change="checkedOperateChange(MANAGE, row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用" align="center" width="60">
|
||||
<!-- <template #header>
|
||||
<el-checkbox
|
||||
v-model="allChecked[USE]"
|
||||
label="使用"
|
||||
@change="handleCheckAllChange($event, USE)"
|
||||
/>
|
||||
</template> -->
|
||||
<template #default="{ row }">
|
||||
<el-checkbox v-model="row.operate[USE]" @change="checkedOperateChange(USE, row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #default="{ row }">
|
||||
<el-checkbox v-model="row.operate[USE]" @change="checkedOperateChange(USE, row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, computed } from 'vue'
|
||||
|
|
@ -56,7 +62,8 @@ const props = defineProps({
|
|||
default: () => []
|
||||
},
|
||||
id: String,
|
||||
type: String
|
||||
type: String,
|
||||
tableHeight: Number
|
||||
})
|
||||
|
||||
const isDataset = computed(() => props.type === DATASET)
|
||||
|
|
@ -68,8 +75,6 @@ const allChecked: any = ref({
|
|||
[USE]: false
|
||||
})
|
||||
|
||||
const tableHeight = ref(0)
|
||||
|
||||
const filterText = ref('')
|
||||
|
||||
watch(
|
||||
|
|
@ -113,12 +118,6 @@ function compare(attrs: string | number) {
|
|||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableHeight.value = window.innerHeight - 300
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
tableHeight.value = window.innerHeight - 300
|
||||
})()
|
||||
}
|
||||
Object.keys(allChecked.value).map((item) => {
|
||||
allChecked.value[item] = compare(item)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -40,21 +40,26 @@
|
|||
</common-list>
|
||||
</div>
|
||||
<div class="permission-setting flex" v-loading="rLoading">
|
||||
<div class="team-manage__table p-24">
|
||||
<h4>权限设置</h4>
|
||||
<div class="team-manage__table">
|
||||
<h4 class="p-24 pb-0 mb-4">权限设置</h4>
|
||||
<el-tabs v-model="activeName" class="team-manage__tabs">
|
||||
<el-tab-pane
|
||||
v-for="item in settingTags"
|
||||
v-for="(item, index) in settingTags"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:name="item.value"
|
||||
>
|
||||
<PermissionSetting :data="item.data" :type="item.value"></PermissionSetting>
|
||||
<PermissionSetting
|
||||
:key="index"
|
||||
:data="item.data"
|
||||
:type="item.value"
|
||||
:tableHeight="tableHeight"
|
||||
></PermissionSetting>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<div class="team-manage__footer border-t p-16 flex">
|
||||
<div class="submit-button">
|
||||
<el-button type="primary" @click="submitPermissions">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -81,6 +86,7 @@ const currentUser = ref<String>('')
|
|||
const filterText = ref('')
|
||||
|
||||
const activeName = ref(DATASET)
|
||||
const tableHeight = ref(0)
|
||||
|
||||
const settingTags = reactive([
|
||||
{
|
||||
|
|
@ -201,6 +207,12 @@ function refresh() {
|
|||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableHeight.value = window.innerHeight - 330
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
tableHeight.value = window.innerHeight - 330
|
||||
})()
|
||||
}
|
||||
getMember()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -223,17 +235,28 @@ onMounted(() => {
|
|||
box-sizing: border-box;
|
||||
width: calc(100% - var(--setting-left-width));
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.submit-button {
|
||||
position: absolute;
|
||||
top: 54px;
|
||||
right: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
margin-top: 10px;
|
||||
:deep(.el-tabs__nav-wrap::after) {
|
||||
height: 1px;
|
||||
}
|
||||
:deep(.el-tabs__nav-scroll) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
:deep(.el-tabs__active-bar) {
|
||||
height: 3px;
|
||||
}
|
||||
}
|
||||
&__table {
|
||||
flex: 1;
|
||||
}
|
||||
&__footer {
|
||||
flex: 0 0 auto;
|
||||
justify-content: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue