feat(webui): WebUI 管理后台新增 AII 管理栏目
在 WebUI NyaHome 管理后台中实现 AII 管理栏目,用于在线修改模型设置。 同时在后端补全了两个路由端点。
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
<script setup lang="ts">
|
||||
import { type SelectOption, useMessage } from 'naive-ui'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import AiiProviderAddModal from '@/components/aii/AiiProviderAddModal.vue'
|
||||
import { aiiModelRules, check_remote_model } from '@/tools/avaliable-check.ts'
|
||||
import { api } from '@/tools/web.js'
|
||||
import type { AiiModelPublic, AiiProviderPublicWithoutKey } from '@/types/aii.js'
|
||||
import type { ReturnDto } from '@/types/response.js'
|
||||
|
||||
const MESSAGE = useMessage()
|
||||
|
||||
const showModal = defineModel<boolean>('showModal', { required: true })
|
||||
|
||||
const { reload } = defineProps<{
|
||||
noAddProvider?: boolean
|
||||
reload?: () => void
|
||||
}>()
|
||||
|
||||
const showAddProviderModal = ref(false)
|
||||
const selectProvider = ref<number | null>(null)
|
||||
const providers = ref<AiiProviderPublicWithoutKey[]>([])
|
||||
const remoteModels = ref<string[]>([])
|
||||
|
||||
const addModelForm = ref({
|
||||
id: 0,
|
||||
model_name: '',
|
||||
max_context_length: 0,
|
||||
reasonable: false,
|
||||
aii_provider_id: selectProvider.value,
|
||||
})
|
||||
|
||||
watch(selectProvider, (newValue) => {
|
||||
addModelForm.value.aii_provider_id = newValue
|
||||
})
|
||||
|
||||
function loadProviders() {
|
||||
api
|
||||
.get('/aii/provider/')
|
||||
.then((res) => res.data as AiiProviderPublicWithoutKey[])
|
||||
.then((result) => {
|
||||
providers.value = result
|
||||
MESSAGE.success(`成功加载了 ${result.length} 个模型提供商。`)
|
||||
})
|
||||
.catch((err) => {
|
||||
MESSAGE.error(`获取模型提供商列表失败:${err}`)
|
||||
})
|
||||
}
|
||||
|
||||
const providerOptions = computed<SelectOption[]>(() => {
|
||||
const options = [] as SelectOption[]
|
||||
for (const ap of providers.value) {
|
||||
options.push({
|
||||
label: `[${ap.id}] [ ${ap.name} ] ( ${ap.base_url} )`,
|
||||
value: ap.id,
|
||||
})
|
||||
}
|
||||
return options
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadProviders()
|
||||
})
|
||||
|
||||
function onGetRemoteModels() {
|
||||
api
|
||||
.get(`/aii/provider/${selectProvider.value}/remote/models/`)
|
||||
.then((res) => res.data as ReturnDto)
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
return data.result as string[]
|
||||
} else {
|
||||
throw TypeError('由于未知原因,后端业务错误。')
|
||||
}
|
||||
})
|
||||
.then((models) => {
|
||||
remoteModels.value = models
|
||||
MESSAGE.success(`成功获取模型提供商 ${selectProvider.value} 的 ${models.length} 个模型。`)
|
||||
})
|
||||
.catch((err) => {
|
||||
MESSAGE.error(`获取提供商的模型列表失败:${err}`)
|
||||
})
|
||||
}
|
||||
|
||||
async function onCheck() {
|
||||
if (selectProvider.value) {
|
||||
if (await check_remote_model(selectProvider.value, addModelForm.value.model_name)) {
|
||||
MESSAGE.success(`提供商的模型 ${addModelForm.value.model_name} 可用。`)
|
||||
} else {
|
||||
MESSAGE.warning(`提供商的模型 ${addModelForm.value.model_name} 不可用。`)
|
||||
}
|
||||
} else {
|
||||
MESSAGE.warning('请选择模型提供商。')
|
||||
}
|
||||
}
|
||||
|
||||
function onConfirm() {
|
||||
api
|
||||
.post('/aii/model/', JSON.stringify(addModelForm.value))
|
||||
.then((res) => res.data as AiiModelPublic)
|
||||
.then(() => {
|
||||
MESSAGE.success(`模型 ${addModelForm.value.model_name} 成功添加。`)
|
||||
showModal.value = false
|
||||
if (reload) reload()
|
||||
})
|
||||
.catch((err) => {
|
||||
MESSAGE.error(`添加模型失败:${err}`)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-modal v-model:show="showModal" preset="card" title="添加模型">
|
||||
<n-form
|
||||
:model="addModelForm"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
label-align="right"
|
||||
:rules="aiiModelRules"
|
||||
>
|
||||
<n-form-item label="模型提供商" path="aii_provider_id">
|
||||
<n-flex style="width: 100%" justify="right" align="center">
|
||||
<n-select v-model:value="selectProvider" :options="providerOptions" />
|
||||
<n-tag round type="info" v-if="!noAddProvider">修改已添加的提供商?请前往管理中心</n-tag>
|
||||
<n-button
|
||||
secondary
|
||||
type="success"
|
||||
size="small"
|
||||
round
|
||||
@click="loadProviders()"
|
||||
v-if="!noAddProvider"
|
||||
>
|
||||
刷新
|
||||
</n-button>
|
||||
<n-button
|
||||
secondary
|
||||
type="warning"
|
||||
size="small"
|
||||
round
|
||||
@click="showAddProviderModal = true"
|
||||
v-if="!noAddProvider"
|
||||
>
|
||||
添加
|
||||
</n-button>
|
||||
</n-flex>
|
||||
</n-form-item>
|
||||
<n-form-item label="模型名称" path="model_name">
|
||||
<n-flex style="width: 100%" justify="right" align="center">
|
||||
<n-input v-model:value="addModelForm.model_name" />
|
||||
<n-flex style="overflow: auto">
|
||||
<n-button
|
||||
secondary
|
||||
type="info"
|
||||
size="small"
|
||||
round
|
||||
v-for="m in remoteModels"
|
||||
v-bind:key="m"
|
||||
@click="addModelForm.model_name = m"
|
||||
>{{ m }}
|
||||
</n-button>
|
||||
</n-flex>
|
||||
<n-button secondary type="success" size="small" round @click="onGetRemoteModels()"
|
||||
>获取模型列表
|
||||
</n-button>
|
||||
</n-flex>
|
||||
</n-form-item>
|
||||
<n-form-item label="最大上下文" path="max_context_length">
|
||||
<n-input-number v-model:value="addModelForm.max_context_length">
|
||||
<template #suffix>K</template>
|
||||
</n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item label="支持思考">
|
||||
<n-switch v-model:value="addModelForm.reasonable" />
|
||||
</n-form-item>
|
||||
<n-form-item label="添加完成">
|
||||
<n-flex>
|
||||
<n-button secondary type="info" @click="onCheck()">检测</n-button>
|
||||
<n-button secondary type="primary" @click="onConfirm()">确认</n-button>
|
||||
</n-flex>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<aii-provider-add-modal v-model:show-modal="showAddProviderModal" />
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user