AI分析功能:LLM Key 改为数据库管理,支持管理员后台配置
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
updateUser,
|
||||
type AdminUser,
|
||||
} from '@/api/users'
|
||||
import { getLLMConfig, saveLLMConfig, type LLMConfig } from '@/api/admin'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const auth = useAuthStore()
|
||||
@@ -27,6 +28,52 @@ const resetDialog = reactive({
|
||||
password: '',
|
||||
})
|
||||
|
||||
// LLM 配置
|
||||
const llmCfg = reactive({
|
||||
base_url: 'https://api.deepseek.com/v1',
|
||||
api_key: '',
|
||||
model: 'deepseek-chat',
|
||||
has_api_key: false,
|
||||
saving: false,
|
||||
loading: false,
|
||||
})
|
||||
|
||||
async function loadLLMConfig() {
|
||||
llmCfg.loading = true
|
||||
try {
|
||||
const cfg = await getLLMConfig()
|
||||
llmCfg.base_url = cfg.base_url
|
||||
llmCfg.api_key = cfg.api_key || ''
|
||||
llmCfg.model = cfg.model
|
||||
llmCfg.has_api_key = cfg.has_api_key
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
llmCfg.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function submitLLMConfig() {
|
||||
if (!llmCfg.base_url.trim()) {
|
||||
ElMessage.warning('API 地址不能为空')
|
||||
return
|
||||
}
|
||||
llmCfg.saving = true
|
||||
try {
|
||||
await saveLLMConfig({
|
||||
base_url: llmCfg.base_url.trim(),
|
||||
api_key: llmCfg.api_key.trim(),
|
||||
model: llmCfg.model.trim(),
|
||||
})
|
||||
ElMessage.success('LLM 配置已保存')
|
||||
await loadLLMConfig()
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.response?.data?.error || '保存失败')
|
||||
} finally {
|
||||
llmCfg.saving = false
|
||||
}
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -91,7 +138,10 @@ async function remove(u: AdminUser) {
|
||||
await reload()
|
||||
}
|
||||
|
||||
onMounted(reload)
|
||||
onMounted(() => {
|
||||
reload()
|
||||
loadLLMConfig()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -145,6 +195,38 @@ onMounted(reload)
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>🤖 LLM 配置</span>
|
||||
<el-tag :type="llmCfg.has_api_key ? 'success' : 'warning'" size="small">
|
||||
{{ llmCfg.has_api_key ? '已配置' : '未配置' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<el-form label-width="100px" v-loading="llmCfg.loading" @submit.prevent>
|
||||
<el-form-item label="API 地址">
|
||||
<el-input v-model="llmCfg.base_url" placeholder="https://api.deepseek.com/v1" />
|
||||
</el-form-item>
|
||||
<el-form-item label="API Key">
|
||||
<el-input
|
||||
v-model="llmCfg.api_key"
|
||||
type="password"
|
||||
show-password
|
||||
placeholder="sk-..."
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="模型">
|
||||
<el-input v-model="llmCfg.model" placeholder="deepseek-chat" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="llmCfg.saving" @click="submitLLMConfig">
|
||||
保存配置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="createDialog.visible" title="新建账号" width="420px">
|
||||
<el-form label-width="80px">
|
||||
<el-form-item label="用户名">
|
||||
@@ -197,6 +279,11 @@ onMounted(reload)
|
||||
align-items: center;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.table-wrapper {
|
||||
background: var(--el-bg-color);
|
||||
border-radius: 4px;
|
||||
|
||||
Reference in New Issue
Block a user