fix: 租户模型列表问题未解决,待进一步调试
This commit is contained in:
parent
b5fa1b0d63
commit
f52f3b27aa
28
api/app.py
28
api/app.py
@ -1,5 +1,6 @@
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import List
|
||||
from fastapi import FastAPI, Depends, HTTPException, status, Request, Body, Response, UploadFile, File
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||
@ -116,7 +117,9 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
||||
# 打印接收到的token用于调试
|
||||
logger.info(f"Received token: {token[:10]}...{token[-10:]}")
|
||||
|
||||
print(f"Full token: {token}") # 调试日志
|
||||
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||
print(f"Decoded payload: {payload}") # 调试日志
|
||||
username: str = payload.get("sub")
|
||||
if username is None:
|
||||
raise credentials_exception
|
||||
@ -424,19 +427,21 @@ async def create_tenant(tenant: TenantCreate, current_user: dict = Depends(get_c
|
||||
logger.error(f"创建租户失败: {e}")
|
||||
raise HTTPException(status_code=400, detail="创建租户失败")
|
||||
|
||||
@app.get("/api/tenants/")
|
||||
async def list_tenants(current_user: dict = Depends(get_current_user)):
|
||||
@app.get("/api/tenants/", response_model=List[TenantResponse])
|
||||
async def list_tenants(
|
||||
search: str = None,
|
||||
current_user: dict = Depends(get_current_user)
|
||||
):
|
||||
"""查询租户列表"""
|
||||
try:
|
||||
tenants = TenantManager.get_all_tenants()
|
||||
return {
|
||||
"tenants": [{
|
||||
"id": str(t["id"]),
|
||||
"name": t["name"],
|
||||
"description": t.get("description", ""),
|
||||
"created_at": t.get("created_at", datetime.now(timezone.utc))
|
||||
} for t in tenants]
|
||||
}
|
||||
logger.info(f"Current user accessing tenants: {current_user['username']}")
|
||||
tenants = TenantManager.search_tenants(search) if search else TenantManager.get_all_tenants()
|
||||
if not tenants:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="未找到匹配的租户"
|
||||
)
|
||||
return tenants
|
||||
except Exception as e:
|
||||
logger.error(f"查询租户列表失败: {e}")
|
||||
raise HTTPException(status_code=400, detail="查询租户列表失败")
|
||||
@ -445,6 +450,7 @@ async def list_tenants(current_user: dict = Depends(get_current_user)):
|
||||
async def get_tenant(name: str, current_user: dict = Depends(get_current_user)):
|
||||
"""查询特定租户"""
|
||||
try:
|
||||
logger.info(f"Current user accessing tenant {name}: {current_user['username']}")
|
||||
tenant = TenantManager.get_tenant_by_name(name)
|
||||
if not tenant:
|
||||
raise HTTPException(
|
||||
|
||||
@ -61,16 +61,19 @@ class ModelManager:
|
||||
cursor.execute(query, (tenant_id,))
|
||||
models = cursor.fetchall()
|
||||
|
||||
return [{
|
||||
"id": str(model[0]),
|
||||
"provider_name": model[1],
|
||||
"model_name": model[2],
|
||||
"model_type": model[3],
|
||||
"encrypted_config": json.loads(model[4]),
|
||||
"is_valid": model[5],
|
||||
"created_at": model[6],
|
||||
"updated_at": model[7]
|
||||
} for model in models]
|
||||
return {
|
||||
"tenant_id": tenant_id,
|
||||
"models": [{
|
||||
"id": str(model[0]),
|
||||
"provider_name": model[1],
|
||||
"model_name": model[2],
|
||||
"model_type": model[3],
|
||||
"encrypted_config": json.loads(model[4]),
|
||||
"is_valid": model[5],
|
||||
"created_at": model[6],
|
||||
"updated_at": model[7]
|
||||
} for model in models]
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"获取租户模型失败: {e}")
|
||||
raise
|
||||
|
||||
@ -54,5 +54,5 @@ class TenantResponse(BaseModel):
|
||||
"""租户响应模型"""
|
||||
id: str
|
||||
name: str
|
||||
description: str
|
||||
description: Optional[str] = None
|
||||
created_at: datetime
|
||||
|
||||
@ -107,9 +107,42 @@ class TenantManager:
|
||||
def get_all_tenants():
|
||||
"""获取所有租户信息"""
|
||||
try:
|
||||
query = "SELECT id, encrypt_public_key FROM tenants;"
|
||||
query = """
|
||||
SELECT
|
||||
id::text,
|
||||
name,
|
||||
encrypt_public_key,
|
||||
created_at
|
||||
FROM tenants;
|
||||
"""
|
||||
tenants = execute_query(query, cursor_factory=RealDictCursor)
|
||||
if not tenants:
|
||||
return []
|
||||
|
||||
# 确保返回字段名正确
|
||||
return tenants
|
||||
except Exception as e:
|
||||
logger.error(f"获取所有租户信息失败: {e}")
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def search_tenants(search_term: str):
|
||||
"""根据名称搜索租户"""
|
||||
try:
|
||||
query = """
|
||||
SELECT
|
||||
id::text,
|
||||
name,
|
||||
encrypt_public_key,
|
||||
created_at
|
||||
FROM tenants
|
||||
WHERE name ILIKE %s;
|
||||
"""
|
||||
tenants = execute_query(query, (f"%{search_term}%",), cursor_factory=RealDictCursor)
|
||||
if not tenants:
|
||||
return []
|
||||
|
||||
return tenants
|
||||
except Exception as e:
|
||||
logger.error(f"搜索租户失败: {e}")
|
||||
return []
|
||||
|
||||
@ -29,6 +29,7 @@ export function assignModelToTenant(
|
||||
}
|
||||
|
||||
export function getTenantModels(tenantId: string): Promise<ApiResponse<TenantModelResponse>> {
|
||||
console.log('请求模型列表API,路径:', `/api/models/${tenantId}`)
|
||||
return request({
|
||||
url: `/api/models/${tenantId}`,
|
||||
method: 'get'
|
||||
|
||||
@ -23,8 +23,31 @@ export interface ModelResponse {
|
||||
created_at: string
|
||||
}
|
||||
|
||||
export interface ModelItem {
|
||||
id: string
|
||||
model_name: string
|
||||
provider_name: string
|
||||
model_type: string
|
||||
encrypted_config: any
|
||||
is_valid: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface ModelItem {
|
||||
id: string
|
||||
provider_name: string
|
||||
model_name: string
|
||||
model_type: string
|
||||
encrypted_config: any
|
||||
is_valid: boolean
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface TenantModelResponse {
|
||||
tenant_id: string
|
||||
tenant_name: string
|
||||
models: ModelResponse[]
|
||||
models: {
|
||||
models: ModelItem[]
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,17 +7,15 @@ import type {
|
||||
CreateTenantResponse
|
||||
} from './types'
|
||||
|
||||
export const fetchTenants = (params: { page?: number; pageSize?: number }) =>
|
||||
export const fetchTenants = (params: { search?: string; page?: number; pageSize?: number }) =>
|
||||
request<{
|
||||
tenants: {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
createdAt: string
|
||||
}[]
|
||||
}>({
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
createdAt: string
|
||||
}[]>({
|
||||
method: 'GET',
|
||||
url: '/api/tenants',
|
||||
url: '/api/tenants/',
|
||||
params
|
||||
})
|
||||
|
||||
|
||||
@ -8,11 +8,14 @@ const service = createAxios()
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = localStorage.getItem('access_token')
|
||||
console.log('Request interceptor - token:', token) // 调试日志
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
console.log('Authorization header set:', config.headers.Authorization) // 调试日志
|
||||
}
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
config.withCredentials = true
|
||||
console.log('Final request config:', config) // 调试日志
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
|
||||
@ -107,7 +107,7 @@ import {
|
||||
} from '@/api/model'
|
||||
import { fetchTenants } from '@/api/tenant'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { ModelResponse } from '@/api/model/types'
|
||||
import type { ModelResponse, ModelItem } from '@/api/model/types'
|
||||
|
||||
interface Tenant {
|
||||
id: string
|
||||
@ -130,27 +130,67 @@ const assignForm = ref({
|
||||
|
||||
const searchTenants = async () => {
|
||||
try {
|
||||
const res = await fetchTenants({ search: searchQuery.value })
|
||||
searchedTenants.value = res.tenants
|
||||
} catch (error) {
|
||||
ElMessage.error('查询租户失败')
|
||||
const tenants = await fetchTenants({ search: searchQuery.value })
|
||||
searchedTenants.value = tenants
|
||||
if (tenants.length === 0) {
|
||||
ElMessage.warning('未找到匹配的租户')
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error.response?.status === 404) {
|
||||
searchedTenants.value = []
|
||||
ElMessage.warning('未找到匹配的租户')
|
||||
} else {
|
||||
ElMessage.error('查询租户失败')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const showTenantModels = async (tenantId: string) => {
|
||||
try {
|
||||
const res = await getTenantModels(tenantId)
|
||||
models.value = res.data.models
|
||||
modelDialogVisible.value = true
|
||||
} catch (error) {
|
||||
ElMessage.error('加载模型列表失败')
|
||||
console.log('开始请求模型列表,租户ID:', tenantId)
|
||||
const res = await getTenantModels(tenantId).catch(err => {
|
||||
console.error('获取模型列表失败:', err)
|
||||
console.error('错误详情:', err.response?.data || err.message)
|
||||
throw err
|
||||
})
|
||||
console.log('完整API响应:', JSON.stringify(res, null, 2))
|
||||
console.log('响应数据:', res.data)
|
||||
console.log('响应数据.models:', res.data?.models)
|
||||
if (res?.data?.models?.models) {
|
||||
models.value = res.data.models.models.map((m: ModelItem) => ({
|
||||
id: m.id,
|
||||
model_name: m.model_name,
|
||||
provider_name: m.provider_name,
|
||||
model_type: m.model_type,
|
||||
created_at: m.created_at,
|
||||
updated_at: m.updated_at
|
||||
}))
|
||||
modelDialogVisible.value = true
|
||||
} else {
|
||||
ElMessage.error('获取模型列表失败: 返回数据格式不正确')
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error('加载模型列表失败: ' +
|
||||
(error.response?.data?.message ||
|
||||
error.message ||
|
||||
'未知错误'))
|
||||
}
|
||||
}
|
||||
|
||||
const handleTenantChange = async (tenantId: string) => {
|
||||
try {
|
||||
const res = await getTenantModels(tenantId)
|
||||
models.value = res.data.models
|
||||
if (res?.data?.models?.models) {
|
||||
models.value = res.data.models.models.map((m: ModelItem) => ({
|
||||
id: m.id,
|
||||
model_name: m.model_name,
|
||||
provider_name: m.provider_name,
|
||||
model_type: m.model_type,
|
||||
created_at: m.created_at
|
||||
}))
|
||||
} else {
|
||||
ElMessage.error('获取模型列表失败: 返回数据格式不正确')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('加载模型列表失败')
|
||||
}
|
||||
@ -182,7 +222,17 @@ const loadModels = async () => {
|
||||
return
|
||||
}
|
||||
const res = await getTenantModels(currentTenantId)
|
||||
models.value = res.data.models
|
||||
if (res?.data?.models?.models) {
|
||||
models.value = res.data.models.models.map((m: ModelItem) => ({
|
||||
id: m.id,
|
||||
model_name: m.model_name,
|
||||
provider_name: m.provider_name,
|
||||
model_type: m.model_type,
|
||||
created_at: m.created_at
|
||||
}))
|
||||
} else {
|
||||
ElMessage.error('获取模型列表失败: 返回数据格式不正确')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('加载模型列表失败')
|
||||
}
|
||||
@ -190,8 +240,7 @@ const loadModels = async () => {
|
||||
|
||||
const loadTenants = async () => {
|
||||
try {
|
||||
const res = await fetchTenants({})
|
||||
tenants.value = res.tenants
|
||||
tenants.value = await fetchTenants({})
|
||||
} catch (error) {
|
||||
ElMessage.error('加载租户列表失败')
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user