2025-09-29 22:01:20 +08:00

321 lines
8.5 KiB
Vue

<template>
<div class="ai-model-test">
<n-card title="AI模型字典API测试">
<n-space vertical size="large">
<!-- 操作按钮 -->
<n-card title="操作" size="small">
<n-space>
<n-button
@click="handleLoadModels"
:loading="loading"
type="primary"
>
加载AI模型列表
</n-button>
<n-button
@click="handleDirectRequest"
:loading="loading"
type="info"
>
直接请求测试
</n-button>
<n-button @click="handleClearModels">
清空数据
</n-button>
</n-space>
</n-card>
<!-- 状态信息 -->
<n-card title="状态信息" size="small">
<n-descriptions :column="2" bordered>
<n-descriptions-item label="加载状态">
<n-tag :type="loading ? 'warning' : 'success'">
{{ loading ? '加载中' : '已完成' }}
</n-tag>
</n-descriptions-item>
<n-descriptions-item label="错误信息">
<n-tag v-if="error" type="error">
{{ error }}
</n-tag>
<n-tag v-else type="success">无错误</n-tag>
</n-descriptions-item>
<n-descriptions-item label="模型数量">
{{ modelList.length }}
</n-descriptions-item>
<n-descriptions-item label="API地址">
<n-code>/sys/dict/getDictItems/airag_model where model_type = 'LLM',name,id</n-code>
</n-descriptions-item>
<n-descriptions-item label="用户Token">
<n-tag v-if="userStore.token" type="success">已登录</n-tag>
<n-tag v-else type="warning">未登录</n-tag>
</n-descriptions-item>
<n-descriptions-item label="Base URL">
<n-code>{{ baseURL }}</n-code>
</n-descriptions-item>
</n-descriptions>
</n-card>
<!-- 模型列表 -->
<n-card title="AI模型列表" size="small">
<n-data-table
:columns="modelColumns"
:data="modelList"
:pagination="false"
size="small"
/>
</n-card>
<!-- 选择器测试 -->
<n-card title="选择器测试" size="small">
<n-form-item label="选择AI模型">
<n-select
v-model:value="selectedModel"
placeholder="请选择AI模型"
:options="modelOptions"
:loading="loading"
@update:value="handleModelSelect"
/>
</n-form-item>
<n-form-item label="当前选择">
<n-tag v-if="selectedModel" type="info">
{{ getSelectedModelText() }}
</n-tag>
<span v-else>未选择</span>
</n-form-item>
</n-card>
<!-- 原始数据 -->
<n-card title="原始API响应数据" size="small">
<n-code
:code="JSON.stringify(rawData, null, 2)"
language="json"
show-line-numbers
/>
</n-card>
</n-space>
</n-card>
</div>
</template>
<script setup lang="ts">
import { ref, computed, h } from 'vue'
import {
NCard,
NSpace,
NDescriptions,
NDescriptionsItem,
NTag,
NButton,
NDataTable,
NCode,
NFormItem,
NSelect,
useMessage
} from 'naive-ui'
import type { DataTableColumns } from 'naive-ui'
import { SystemApi, type DictItem } from '@/api'
import axios from 'axios'
import { useUserStore } from '@/stores/user'
const message = useMessage()
const userStore = useUserStore()
// 状态
const loading = ref(false)
const error = ref<string | null>(null)
const modelList = ref<DictItem[]>([])
const rawData = ref<any>(null)
const selectedModel = ref<string>('')
// 计算属性
const baseURL = computed(() => import.meta.env.VITE_API_BASE_URL || '/jeecgboot')
// 计算属性
const modelOptions = computed(() =>
modelList.value.map(item => ({
label: item.text,
value: item.value
}))
)
// 表格列定义
const modelColumns: DataTableColumns<DictItem> = [
{
title: 'Value',
key: 'value',
width: 200,
render: (row) => {
return h('code', {
style: 'background: #f5f5f5; padding: 2px 4px; border-radius: 3px;'
}, row.value)
}
},
{
title: 'Text',
key: 'text',
width: 120,
},
{
title: 'Label',
key: 'label',
width: 120,
},
{
title: 'Title',
key: 'title',
width: 120,
},
{
title: 'Color',
key: 'color',
width: 100,
render: (row) => {
return row.color ? h(NTag, { type: 'info' }, () => row.color) : '无'
}
}
]
// 加载AI模型列表
const handleLoadModels = async () => {
loading.value = true
error.value = null
try {
console.log('🚀 开始加载AI模型列表...')
console.log('🔍 当前时间戳:', Date.now())
console.log('🔍 请求URL:', '/sys/dict/getDictItems/airag_model%20where%20model_type%20=%20\'LLM\',name,id')
const response = await SystemApi.getAiModelDict()
console.log('📦 完整API响应:', response)
console.log('📦 响应数据:', response.data)
rawData.value = response
if (response.code === 200 || response.code === 0) {
modelList.value = response.data || []
message.success(`加载成功,共${modelList.value.length}个模型`)
console.log('✅ AI模型列表加载成功:', modelList.value)
} else {
throw new Error(response.message || '获取模型列表失败')
}
} catch (err: any) {
error.value = err.message || '加载失败'
message.error(error.value || '未知错误')
console.error('❌ 加载AI模型列表失败:', err)
console.error('❌ 错误详情:', {
message: err.message,
response: err.response,
config: err.config,
stack: err.stack
})
// 保存错误信息到rawData以便查看
rawData.value = {
error: err.message,
response: err.response?.data,
config: err.config
}
} finally {
loading.value = false
}
}
// 直接请求测试
const handleDirectRequest = async () => {
loading.value = true
error.value = null
try {
console.log('🚀 开始直接请求测试...')
const baseURL = import.meta.env.VITE_API_BASE_URL || '/jeecgboot'
const timestamp = Date.now()
const token = userStore.token || localStorage.getItem('X-Access-Token') || ''
const url = `${baseURL}/sys/dict/getDictItems/airag_model%20where%20model_type%20=%20'LLM',name,id?_t=${timestamp}`
console.log('🔍 请求信息:', {
url,
timestamp,
token: token ? '***' : '无',
baseURL
})
const headers: any = {
'Content-Type': 'application/json',
'X-Request-Time': timestamp.toString(),
'timestamp': timestamp.toString(),
'X-Timestamp': timestamp.toString(),
}
if (token) {
headers['X-Access-Token'] = token
}
console.log('🔍 请求头:', headers)
const response = await axios.get(url, { headers })
console.log('📦 直接请求响应:', response)
rawData.value = response.data
if (response.data.code === 200 || response.data.code === 0) {
modelList.value = response.data.result || response.data.data || []
message.success(`直接请求成功,共${modelList.value.length}个模型`)
} else {
throw new Error(response.data.message || '直接请求失败')
}
} catch (err: any) {
error.value = err.message || '直接请求失败'
message.error(error.value || '未知错误')
console.error('❌ 直接请求失败:', err)
rawData.value = {
error: err.message,
response: err.response?.data,
status: err.response?.status,
headers: err.response?.headers
}
} finally {
loading.value = false
}
}
// 清空数据
const handleClearModels = () => {
modelList.value = []
rawData.value = null
selectedModel.value = ''
error.value = null
message.info('数据已清空')
}
// 模型选择
const handleModelSelect = (value: string) => {
const model = modelList.value.find(item => item.value === value)
if (model) {
message.info(`已选择: ${model.text}`)
}
}
// 获取选择的模型文本
const getSelectedModelText = () => {
const model = modelList.value.find(item => item.value === selectedModel.value)
return model ? model.text : selectedModel.value
}
</script>
<style scoped>
.ai-model-test {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
:deep(.n-code) {
max-height: 300px;
overflow-y: auto;
}
</style>