import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { CursorPage, DownloaderInstance, DownloaderInstanceCreate, DownloaderInstanceUpdate, InstanceTestResult, LibraryRoot, LibraryRootCreate, LibraryRootUpdate, MediaServerInstance, MediaServerInstanceCreate, MediaServerInstanceUpdate, PathMapping, PathMappingCreate, PathMappingUpdate, Site, SiteAccount, SiteCredentialsPut, SiteCredentialsResult, } from "@umt/contracts"; import { apiData } from "~/lib/api.ts"; import { type QueryArea, qk } from "~/lib/query-keys.ts"; /** 实例类资源的标准 CRUD 钩子(列表取前 200 条,首版实例数量很少) */ function crudHooks(area: QueryArea, base: string) { return { useList: () => useQuery({ queryKey: qk.list(area), queryFn: ({ signal }) => apiData>(base, { params: { limit: 200 }, signal }), }), useCreate: () => { const qc = useQueryClient(); return useMutation({ mutationFn: (body: Create) => apiData(base, { method: "POST", body }), onSuccess: () => qc.invalidateQueries({ queryKey: qk.all(area) }), }); }, useUpdate: () => { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, body }: { id: string; body: Update }) => apiData(`${base}/{id}`, { method: "PATCH", pathParams: { id }, body }), onSuccess: () => qc.invalidateQueries({ queryKey: qk.all(area) }), }); }, useRemove: () => { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiData(`${base}/{id}`, { method: "DELETE", pathParams: { id } }), onSuccess: () => qc.invalidateQueries({ queryKey: qk.all(area) }), }); }, }; } /** 连接测试 / 校验类动作(结果写回 health,完成后刷新列表) */ function actionHook(area: QueryArea, path: string) { return () => { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiData(path, { method: "POST", pathParams: { id }, body: {} }), onSettled: () => qc.invalidateQueries({ queryKey: qk.all(area) }), }); }; } export const downloaders = { ...crudHooks( "downloader-instances", "/downloader-instances", ), useTest: actionHook("downloader-instances", "/downloader-instances/{id}/test"), }; export const mediaServers = { ...crudHooks( "media-server-instances", "/media-server-instances", ), useTest: actionHook("media-server-instances", "/media-server-instances/{id}/test"), }; export const libraryRoots = { ...crudHooks("library-roots", "/library-roots"), useTest: actionHook("library-roots", "/library-roots/{id}/test"), }; export const pathMappings = { ...crudHooks("path-mappings", "/path-mappings"), useVerify: actionHook("path-mappings", "/path-mappings/{id}/verify"), }; // ─── 站点账号凭证(设置页录入;站点本身由站点工作台管理) ─── export function useSiteOptions() { return useQuery({ queryKey: qk.list("sites", { limit: 200 }), queryFn: ({ signal }) => apiData>("/sites", { params: { limit: 200 }, signal }), }); } export function useSiteAccounts() { return useQuery({ queryKey: qk.list("site-accounts"), queryFn: ({ signal }) => apiData>("/site-accounts", { params: { limit: 200 }, signal }), }); } export function usePutSiteCredentials() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ siteId, body }: { siteId: string; body: SiteCredentialsPut }) => apiData("/sites/{id}/credentials", { method: "PUT", pathParams: { id: siteId }, body }), onSuccess: () => { qc.invalidateQueries({ queryKey: qk.all("site-accounts") }); }, }); }