feat(i18n): 全局将「专家」文案改为「智能体」 统一智能体功能的 UI 文案:侧边栏、智能体页、新建/保存流程、 审批卡片、登录提示及后端审批消息中的「专家」均改为「智能体」。 保留 prompt 人设、QA 子应用等非该功能语义的「专家」表述。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> @
111 lines
2.9 KiB
TypeScript
111 lines
2.9 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react';
|
|
|
|
export interface LlmItem {
|
|
id: string;
|
|
name: string;
|
|
}
|
|
|
|
export interface CurrentUser {
|
|
id: string;
|
|
email: string;
|
|
is_active: boolean;
|
|
is_superuser: boolean;
|
|
is_verified: boolean;
|
|
pages_limit: number;
|
|
pages_used: number;
|
|
}
|
|
|
|
type RequestInfoLike = Parameters<typeof fetch>[0];
|
|
type RequestInitLike = Parameters<typeof fetch>[1];
|
|
|
|
const LOGIN_URL = 'http://47.88.25.99:8000/auth/jwt/login';
|
|
const LLMS_URL = 'http://47.88.25.99:8000/api/v1/expert-agents/llms';
|
|
const ME_URL = 'http://47.88.25.99:8000/users/me';
|
|
|
|
export function useExpertAuthBootstrap() {
|
|
const [llmList, setLlmList] = useState<LlmItem[]>([]);
|
|
const [currentUser, setCurrentUser] = useState<CurrentUser | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const authedFetch = useCallback(async (input: RequestInfoLike, init?: RequestInitLike) => {
|
|
const token = localStorage.getItem('access_token');
|
|
const headers = new Headers(init?.headers);
|
|
if (token) {
|
|
headers.set('Authorization', `Bearer ${token}`);
|
|
}
|
|
return fetch(input, { ...init, headers });
|
|
}, []);
|
|
|
|
const login = useCallback(async () => {
|
|
const formData = new FormData();
|
|
formData.append('username', 'dhk@qq.com');
|
|
formData.append('password', '1qaz@WSX');
|
|
formData.append('grant_type', 'password');
|
|
|
|
const res = await fetch(LOGIN_URL, {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`登录失败: ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
const data = await res.json();
|
|
if (data?.access_token) {
|
|
localStorage.setItem('access_token', data.access_token);
|
|
}
|
|
}, []);
|
|
|
|
const fetchLlmList = useCallback(async () => {
|
|
const res = await authedFetch(LLMS_URL, { method: 'GET' });
|
|
if (!res.ok) {
|
|
throw new Error(`llms 接口失败: ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
const data: unknown = await res.json();
|
|
const list = Array.isArray(data) ? (data as LlmItem[]) : [];
|
|
setLlmList(list);
|
|
return list;
|
|
}, [authedFetch]);
|
|
|
|
const fetchCurrentUser = useCallback(async () => {
|
|
const res = await authedFetch(ME_URL, { method: 'GET' });
|
|
if (!res.ok) {
|
|
throw new Error(`users/me 接口失败: ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
const data: unknown = await res.json();
|
|
const user = (data as CurrentUser) ?? null;
|
|
setCurrentUser(user);
|
|
return user;
|
|
}, [authedFetch]);
|
|
|
|
const bootstrap = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
await login();
|
|
await Promise.all([fetchLlmList(), fetchCurrentUser()]);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [fetchCurrentUser, fetchLlmList, login]);
|
|
|
|
useEffect(() => {
|
|
void bootstrap().catch((error) => {
|
|
console.error('智能体中心初始化失败:', error);
|
|
});
|
|
}, [bootstrap]);
|
|
|
|
return {
|
|
llmList,
|
|
currentUser,
|
|
loading,
|
|
authedFetch,
|
|
login,
|
|
fetchLlmList,
|
|
fetchCurrentUser,
|
|
bootstrap,
|
|
};
|
|
}
|