- 新建 frontend-v2/lib/api-client.ts - 用于与 Novel Platform 后端交互的认证功能 - 包含登录、注册、登出等 API 方法 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
144 lines
4.0 KiB
TypeScript
144 lines
4.0 KiB
TypeScript
/**
|
||
* API 客户端 - 用于与 Novel Platform 后端交互
|
||
*
|
||
* 注意:此文件仅用于认证功能(useAuth hook)
|
||
* 聊天功能已迁移到官方 useChatUI + /api/chat 路由
|
||
*/
|
||
|
||
// ============================================================================
|
||
// 类型定义
|
||
// ============================================================================
|
||
|
||
export type UserRole = 'user' | 'admin' | 'author';
|
||
|
||
export interface UserInfo {
|
||
username: string;
|
||
role: UserRole;
|
||
}
|
||
|
||
export interface LoginResponse {
|
||
success?: boolean;
|
||
session_id?: string;
|
||
username?: string;
|
||
role?: UserRole;
|
||
message?: string;
|
||
}
|
||
|
||
export interface RegisterResponse {
|
||
success: boolean;
|
||
message?: string;
|
||
}
|
||
|
||
export interface AuthStatusResponse {
|
||
authenticated: boolean;
|
||
username?: string;
|
||
role?: UserRole;
|
||
}
|
||
|
||
export interface McpToolsResponse {
|
||
tools: Array<{ name: string; description: string }>;
|
||
}
|
||
|
||
// ============================================================================
|
||
// API 客户端类
|
||
// ============================================================================
|
||
|
||
class ApiClient {
|
||
private sessionId: string | null = null;
|
||
private userInfo: UserInfo | null = null;
|
||
|
||
// Novel Platform 后端 URL(从环境变量读取,默认使用内网地址)
|
||
private baseUrl: string;
|
||
|
||
constructor() {
|
||
this.baseUrl = process.env.NEXT_PUBLIC_PLATFORM_URL || 'http://localhost:8082';
|
||
}
|
||
|
||
setSession(sessionId: string): void {
|
||
this.sessionId = sessionId;
|
||
}
|
||
|
||
setUserInfo(userInfo: UserInfo): void {
|
||
this.userInfo = userInfo;
|
||
}
|
||
|
||
getMcpUrl(): string {
|
||
// 根据用户角色返回不同的 MCP URL
|
||
if (this.userInfo?.role === 'admin') {
|
||
return process.env.NEXT_PUBLIC_MCP_ADMIN_URL || 'https://d8d-ai-vscode-8080-223-238-template-6-group.dev.d8d.fun/admin-mcp/';
|
||
}
|
||
return process.env.NEXT_PUBLIC_MCP_USER_URL || 'https://d8d-ai-vscode-8080-223-238-template-6-group.dev.d8d.fun/mcp/';
|
||
}
|
||
|
||
private async request<T>(
|
||
endpoint: string,
|
||
options: RequestInit = {}
|
||
): Promise<T> {
|
||
const url = `${this.baseUrl}${endpoint}`;
|
||
const headers: Record<string, string> = {
|
||
'Content-Type': 'application/json',
|
||
...(options.headers as Record<string, string> || {}),
|
||
};
|
||
|
||
if (this.sessionId) {
|
||
headers['Authorization'] = `Bearer ${this.sessionId}`;
|
||
}
|
||
|
||
const response = await fetch(url, {
|
||
...options,
|
||
headers,
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const error = await response.text();
|
||
throw new Error(`HTTP ${response.status}: ${error}`);
|
||
}
|
||
|
||
return response.json();
|
||
}
|
||
|
||
// ============================================================================
|
||
// 认证 API
|
||
// ============================================================================
|
||
|
||
async login(email: string, password: string): Promise<LoginResponse> {
|
||
return this.request<LoginResponse>('/api/v1/auth/login', {
|
||
method: 'POST',
|
||
body: JSON.stringify({ email, password }),
|
||
});
|
||
}
|
||
|
||
async register(email: string, username: string, password: string): Promise<RegisterResponse> {
|
||
return this.request<RegisterResponse>('/api/v1/auth/register', {
|
||
method: 'POST',
|
||
body: JSON.stringify({ email, username, password }),
|
||
});
|
||
}
|
||
|
||
async logout(): Promise<void> {
|
||
if (this.sessionId) {
|
||
await this.request('/api/v1/auth/logout', { method: 'POST' });
|
||
}
|
||
this.sessionId = null;
|
||
this.userInfo = null;
|
||
}
|
||
|
||
async authStatus(): Promise<AuthStatusResponse> {
|
||
return this.request<AuthStatusResponse>('/api/v1/auth/status');
|
||
}
|
||
|
||
// ============================================================================
|
||
// MCP 工具 API
|
||
// ============================================================================
|
||
|
||
async listMcpTools(): Promise<McpToolsResponse> {
|
||
return this.request<McpToolsResponse>('/api/v1/mcp/tools');
|
||
}
|
||
}
|
||
|
||
// ============================================================================
|
||
// 导出单例
|
||
// ============================================================================
|
||
|
||
export const apiClient = new ApiClient();
|