import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { CreateModelRequest, Model, ModelListResponse, ModelResponse, ModelTestResponse, ModelTestResultResponse, TestModelRequest, UpdateModelRequest, } from "../../../shared/api"; import { handleResponse, handleVoidResponse } from "../utils/api"; import { createConsoleLogger } from "../utils/logger"; const MODELS_KEY = ["models"] as const; const logger = createConsoleLogger(); export async function createModel(data: CreateModelRequest): Promise { const response = await fetch("/api/models", { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "POST", }); return handleResponse(response, (data) => (data as ModelResponse).model); } export async function deleteModel(id: string): Promise { const response = await fetch(`/api/models/${id}`, { method: "DELETE" }); return handleVoidResponse(response); } export async function fetchModel(id: string): Promise { const response = await fetch(`/api/models/${id}`); return handleResponse(response, (data) => (data as ModelResponse).model); } export async function fetchModelList(params: { capabilities?: string; keyword?: string; page?: number; pageSize?: number; providerId?: string; sortBy?: string; sortOrder?: string; }): Promise { const searchParams = new URLSearchParams(); if (params.page) searchParams.set("page", String(params.page)); if (params.pageSize) searchParams.set("pageSize", String(params.pageSize)); if (params.keyword) searchParams.set("keyword", params.keyword); if (params.providerId) searchParams.set("providerId", params.providerId); if (params.sortBy) searchParams.set("sortBy", params.sortBy); if (params.sortOrder) searchParams.set("sortOrder", params.sortOrder); if (params.capabilities) searchParams.set("capabilities", params.capabilities); const qs = searchParams.toString(); const url = `/api/models${qs ? `?${qs}` : ""}`; const response = await fetch(url); if (!response.ok) { const body = (await response.json().catch(() => null)) as null | { error?: string }; throw new Error(body?.error ?? `HTTP ${response.status}`); } return response.json() as Promise; } export async function testModelConnection(data: TestModelRequest): Promise { const response = await fetch("/api/models/test", { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "POST", }); if (!response.ok) { const body = (await response.json().catch(() => null)) as null | { error?: string }; throw new Error(body?.error ?? `HTTP ${response.status}`); } const result = (await response.json()) as ModelTestResultResponse; return result.modelTestResponse; } export async function updateModel(id: string, data: UpdateModelRequest): Promise { const response = await fetch(`/api/models/${id}`, { body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, method: "PATCH", }); return handleResponse(response, (data) => (data as ModelResponse).model); } export function useCreateModel() { const queryClient = useQueryClient(); return useMutation({ mutationFn: createModel, onSuccess: (data) => { logger.info("模型创建成功", { externalId: data.externalId, providerId: data.providerId }); void queryClient.invalidateQueries({ queryKey: MODELS_KEY }); }, }); } export function useDeleteModel() { const queryClient = useQueryClient(); return useMutation({ mutationFn: deleteModel, onSuccess: (_data, variables) => { logger.info("模型删除成功", { modelId: variables }); void queryClient.invalidateQueries({ queryKey: MODELS_KEY }); }, }); } export function useModel(id: string) { return useQuery({ enabled: !!id, queryFn: () => fetchModel(id), queryKey: [...MODELS_KEY, "detail", id], }); } export function useModelList(params: { capabilities?: string; keyword?: string; page?: number; pageSize?: number; providerId?: string; sortBy?: string; sortOrder?: string; }) { return useQuery({ queryFn: () => fetchModelList(params), queryKey: [...MODELS_KEY, "list", params], }); } export function useTestModelConnection() { return useMutation({ mutationFn: testModelConnection, }); } export function useUpdateModel() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (args: { data: UpdateModelRequest; id: string }) => updateModel(args.id, args.data), onSuccess: (data) => { logger.info("模型更新成功", { externalId: data.externalId, providerId: data.providerId }); void queryClient.invalidateQueries({ queryKey: MODELS_KEY }); }, }); }