Files
huihuiSquare/frontend/src/views/AIModels.vue
yuqianqian10204095yu cebc0a288f 1.0.0初始化源代码
2026-03-23 15:40:36 +08:00

276 lines
8.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="ai-models">
<el-card>
<template #header>
<div class="card-header">
<span>AI 模型配置</span>
<el-button type="primary" @click="showAddDialog = true">
<el-icon><Plus /></el-icon>
添加模型
</el-button>
</div>
</template>
<el-table :data="modelList" v-loading="loading">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="display_name" label="名称" width="150" />
<el-table-column prop="model_name" label="模型" width="150" />
<el-table-column prop="provider" label="提供商" width="120">
<template #default="{ row }">
<el-tag size="small">{{ getProviderLabel(row.provider) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="temperature" label="温度" width="100" />
<el-table-column prop="max_tokens" label="最大 Token" width="100" />
<el-table-column prop="is_default" label="默认" width="80">
<template #default="{ row }">
<el-tag size="small" :type="row.is_default ? 'success' : 'info'">
{{ row.is_default ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="is_active" label="状态" width="80">
<template #default="{ row }">
<el-tag size="small" :type="row.is_active ? 'success' : 'info'">
{{ row.is_active ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="250">
<template #default="{ row }">
<el-button size="small" @click="handleTest(row)">测试</el-button>
<el-button size="small" @click="handleEdit(row)">编辑</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 添加/编辑对话框 -->
<el-dialog
v-model="showModelDialog"
:title="isEdit ? '编辑模型' : '添加模型'"
width="600px"
>
<el-form :model="modelForm" label-width="120px">
<el-form-item label="显示名称">
<el-input v-model="modelForm.display_name" placeholder="如GPT-3.5" />
</el-form-item>
<el-form-item label="模型名称">
<el-input v-model="modelForm.model_name" placeholder="如gpt-3.5-turbo" :disabled="isEdit" />
</el-form-item>
<el-form-item label="提供商">
<el-select v-model="modelForm.provider" placeholder="请选择" :disabled="isEdit">
<el-option label="OpenAI" value="openai" />
<el-option label="智谱 AI" value="zhipu" />
<el-option label="百度文心" value="baidu" />
<el-option label="阿里通义" value="aliyun" />
</el-select>
</el-form-item>
<el-form-item label="API 地址">
<el-input v-model="modelForm.api_url" placeholder="https://api.openai.com/v1" />
</el-form-item>
<el-form-item label="API Key">
<el-input v-model="modelForm.api_key" type="password" show-password placeholder="sk-..." />
</el-form-item>
<el-form-item label="温度">
<el-slider v-model="modelForm.temperature" :min="0" :max="1" :step="0.1" />
</el-form-item>
<el-form-item label="最大 Token 数">
<el-input-number v-model="modelForm.max_tokens" :min="1" :max="4096" />
</el-form-item>
<el-form-item label="设为默认">
<el-switch v-model="modelForm.is_default" />
</el-form-item>
<el-form-item label="启用">
<el-switch v-model="modelForm.is_active" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showModelDialog = false">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="saving">保存</el-button>
</template>
</el-dialog>
<!-- 测试对话框 -->
<el-dialog
v-model="showTestDialog"
title="测试模型"
width="500px"
>
<el-form>
<el-form-item label="测试提示词">
<el-input
v-model="testPrompt"
type="textarea"
:rows="4"
placeholder="请输入测试内容,如:请写一条关于春天的评论"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showTestDialog = false">取消</el-button>
<el-button type="primary" @click="handleRunTest" :loading="testing">测试</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { aiModelApi } from '@/api'
import { ElMessage, ElMessageBox } from 'element-plus'
const loading = ref(false)
const saving = ref(false)
const testing = ref(false)
const modelList = ref([])
const showAddDialog = ref(false)
const showModelDialog = ref(false)
const showTestDialog = ref(false)
const isEdit = ref(false)
const currentModelId = ref(null)
const testPrompt = ref('')
const modelForm = ref({
display_name: '',
model_name: '',
provider: '',
api_url: '',
api_key: '',
temperature: 0.7,
max_tokens: 1000,
is_default: false,
is_active: true
})
const testData = ref({})
// 加载数据
const loadData = async () => {
loading.value = true
try {
const res = await aiModelApi.getList()
modelList.value = res || []
} catch (error) {
console.error('Load AI models error:', error)
} finally {
loading.value = false
}
}
// 添加/编辑
const handleAdd = () => {
isEdit.value = false
modelForm.value = {
display_name: '',
model_name: '',
provider: '',
api_url: '',
api_key: '',
temperature: 0.7,
max_tokens: 1000,
is_default: false,
is_active: true
}
showModelDialog.value = true
}
const handleEdit = (row) => {
isEdit.value = true
currentModelId.value = row.id
modelForm.value = { ...row }
showModelDialog.value = true
}
// 提交
const handleSubmit = async () => {
saving.value = true
try {
if (isEdit.value) {
await aiModelApi.update(currentModelId.value, modelForm.value)
ElMessage.success('更新成功')
} else {
await aiModelApi.create(modelForm.value)
ElMessage.success('创建成功')
}
showModelDialog.value = false
loadData()
} catch (error) {
console.error('Save model error:', error)
} finally {
saving.value = false
}
}
// 删除
const handleDelete = (row) => {
ElMessageBox.confirm('确定要删除此模型配置吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
await aiModelApi.delete(row.id)
ElMessage.success('删除成功')
loadData()
} catch (error) {
console.error('Delete model error:', error)
}
})
}
// 测试
const handleTest = (row) => {
currentModelId.value = row.id
testPrompt.value = '请写一条简短的评论'
showTestDialog.value = true
}
const handleRunTest = async () => {
testing.value = true
try {
const res = await aiModelApi.test({
model_id: currentModelId.value,
test_prompt: testPrompt.value
})
testData.value = res
if (res.success) {
ElMessage.success(`测试成功!消耗 ${res.tokens_used} tokens`)
console.log('Test result:', res.content)
} else {
ElMessage.error(`测试失败:${res.error_message}`)
}
} catch (error) {
console.error('Test model error:', error)
} finally {
testing.value = false
}
}
const getProviderLabel = (provider) => {
const map = { openai: 'OpenAI', zhipu: '智谱 AI', baidu: '百度文心', aliyun: '阿里通义' }
return map[provider] || provider
}
onMounted(() => {
loadData()
})
</script>
<style scoped>
.ai-models {
padding: 20px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>