import type { AdminProfile, AdminUser, AgentDebugResult, AiLogRecord, ApiResponse, ChatDetail, ChatRecord, ChatRecordQuery, DashboardStats, KnowledgeItem, ModelItem, SystemConfigItem, UserImportResult, } from "../types/api"; const API_BASE = import.meta.env.VITE_API_BASE_URL ?? "/api"; const TOKEN_KEY = "ai-kb-admin-token"; export function getToken() { return window.localStorage.getItem(TOKEN_KEY); } export function saveToken(token: string) { window.localStorage.setItem(TOKEN_KEY, token); } export function clearToken() { window.localStorage.removeItem(TOKEN_KEY); } async function request(path: string, init: RequestInit = {}): Promise { const headers = new Headers(init.headers); headers.set("Content-Type", "application/json"); const token = getToken(); if (token) headers.set("Authorization", `Bearer ${token}`); const response = await fetch(`${API_BASE}${path}`, { ...init, headers }); const body = (await response.json()) as ApiResponse; if (!response.ok || body.code !== 0) { throw new Error(body.message || `${response.status} ${response.statusText}`); } return body.data; } async function download(path: string, filename: string) { const headers = new Headers(); const token = getToken(); if (token) headers.set("Authorization", `Bearer ${token}`); const response = await fetch(`${API_BASE}${path}`, { headers }); if (!response.ok) throw new Error("导出失败"); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const anchor = document.createElement("a"); anchor.href = url; anchor.download = filename; anchor.click(); window.URL.revokeObjectURL(url); } async function upload(path: string, formData: FormData): Promise { const headers = new Headers(); const token = getToken(); if (token) headers.set("Authorization", `Bearer ${token}`); const response = await fetch(`${API_BASE}${path}`, { method: "POST", body: formData, headers }); const body = (await response.json()) as ApiResponse & { detail?: string }; if (!response.ok || body.code !== 0) { throw new Error(body.message || body.detail || `${response.status} ${response.statusText}`); } return body.data; } function queryString(query: object) { const params = new URLSearchParams(); Object.entries(query).forEach(([key, value]) => { if (value !== undefined && value !== null && value !== "") params.set(key, String(value)); }); const text = params.toString(); return text ? `?${text}` : ""; } export const api = { login: (username: string, password: string) => request<{ token: string; admin: AdminProfile }>("/admin/login", { method: "POST", body: JSON.stringify({ username, password }), }), profile: () => request("/admin/profile"), dashboard: (start?: string, end?: string) => { const params = new URLSearchParams(); if (start) params.set("start", start); if (end) params.set("end", end); const qs = params.toString(); return request(`/admin/dashboard${qs ? "?" + qs : ""}`); }, users: (keyword = "") => request(`/admin/user/list?keyword=${encodeURIComponent(keyword)}`), createUser: (payload: Record) => request("/admin/user", { method: "POST", body: JSON.stringify(payload) }), importUsers: (students: Record[]) => request("/admin/user/import", { method: "POST", body: JSON.stringify({ students }) }), downloadStudentTemplate: () => download("/admin/user/import/template", "学员导入模板.xlsx"), importUsersExcel: (file: File) => { const formData = new FormData(); formData.append("file", file); return upload("/admin/user/import/excel", formData); }, updateUser: (id: number, payload: Record) => request(`/admin/user/${id}`, { method: "PUT", body: JSON.stringify(payload) }), deleteUser: (id: number) => request(`/admin/user/${id}`, { method: "DELETE" }), knowledge: () => request("/admin/knowledge/list"), createKnowledge: (payload: Record) => request("/admin/knowledge", { method: "POST", body: JSON.stringify(payload) }), updateKnowledge: (id: number, payload: Record) => request(`/admin/knowledge/${id}`, { method: "PUT", body: JSON.stringify(payload) }), deleteKnowledge: (id: number) => request(`/admin/knowledge/${id}`, { method: "DELETE" }), importKnowledgeFromSpace: (body: { node_token: string }) => request<{ imported: number; skipped: number; id: number; name: string }>( "/admin/knowledge/import", { method: "POST", body: JSON.stringify(body) }, ), prompt: () => request<{ promptContent: string }>("/admin/prompt"), savePrompt: (promptContent: string) => request<{ promptContent: string }>("/admin/prompt", { method: "PUT", body: JSON.stringify({ promptContent }) }), resetPrompt: () => request<{ promptContent: string }>("/admin/prompt/reset", { method: "POST", body: "{}" }), debugAgent: (payload: Record) => request("/admin/agent/debug", { method: "POST", body: JSON.stringify(payload) }), models: () => request("/admin/model/list"), createModel: (payload: Record) => request("/admin/model", { method: "POST", body: JSON.stringify(payload) }), updateModel: (id: number, payload: Record) => request(`/admin/model/${id}`, { method: "PUT", body: JSON.stringify(payload) }), enableModel: (modelId: number) => request("/admin/model/enable", { method: "POST", body: JSON.stringify({ modelId }) }), deleteModel: (modelId: number) => request(`/admin/model/${modelId}`, { method: "DELETE" }), testModel: (modelId: number) => request<{ ok: boolean; message: string; answer: string }>(`/admin/model/${modelId}/test`, { method: "POST", body: "{}", }), configs: () => request("/admin/config"), saveConfig: (payload: Record) => request("/admin/config", { method: "PUT", body: JSON.stringify(payload) }), chats: (query: ChatRecordQuery = {}) => request(`/admin/chat/list${queryString(query)}`), chatDetail: (sessionId: number) => request(`/admin/chat/${sessionId}`), exportChats: (query: ChatRecordQuery = {}) => download(`/admin/chat/export${queryString(query)}`, "chat_records.csv"), aiLogs: (query: { sessionId?: number; userId?: number; status?: string } = {}) => request(`/admin/ai-log/list${queryString(query)}`), aiLogDetail: (id: number) => request(`/admin/ai-log/${id}`), operationLogs: () => request[]>("/admin/log/list"), clearFeishuCache: () => request<{ cleared: number; message: string }>("/admin/feishu/cache/clear", { method: "POST", body: "{}" }), };