147 lines
5.8 KiB
TypeScript
147 lines
5.8 KiB
TypeScript
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
|
import type {
|
|
CreateMaterialRequest,
|
|
Material,
|
|
MaterialListResponse,
|
|
MaterialResponse,
|
|
MaterialStatus,
|
|
} from "../../../shared/api";
|
|
|
|
import { handleResponse, handleVoidResponse } from "../utils/api";
|
|
import { createConsoleLogger } from "../utils/logger";
|
|
|
|
const MATERIALS_KEY = ["materials"] as const;
|
|
const logger = createConsoleLogger();
|
|
|
|
export function createMaterial(args: { body: CreateMaterialRequest; projectId: string }): Promise<Material> {
|
|
const response = fetch(`/api/projects/${args.projectId}/materials`, {
|
|
body: JSON.stringify(args.body),
|
|
headers: { "Content-Type": "application/json" },
|
|
method: "POST",
|
|
});
|
|
return response.then((r) => handleResponse(r, (data) => (data as MaterialResponse).material));
|
|
}
|
|
|
|
export function approveMaterial(args: { materialId: string; projectId: string }): Promise<Material> {
|
|
const response = fetch(`/api/projects/${args.projectId}/materials/${args.materialId}/approve`, { method: "POST" });
|
|
return response.then((r) => handleResponse(r, (data) => (data as MaterialResponse).material));
|
|
}
|
|
|
|
export function deleteMaterial(args: { materialId: string; projectId: string }): Promise<void> {
|
|
const response = fetch(`/api/projects/${args.projectId}/materials/${args.materialId}`, { method: "DELETE" });
|
|
return response.then(handleVoidResponse);
|
|
}
|
|
|
|
export function discardMaterial(args: { materialId: string; projectId: string }): Promise<Material> {
|
|
const response = fetch(`/api/projects/${args.projectId}/materials/${args.materialId}/discard`, { method: "POST" });
|
|
return response.then((r) => handleResponse(r, (data) => (data as MaterialResponse).material));
|
|
}
|
|
|
|
export function retryMaterial(args: { materialId: string; projectId: string }): Promise<Material> {
|
|
const response = fetch(`/api/projects/${args.projectId}/materials/${args.materialId}/retry`, { method: "POST" });
|
|
return response.then((r) => handleResponse(r, (data) => (data as MaterialResponse).material));
|
|
}
|
|
|
|
export async function fetchMaterial(args: { materialId: string; projectId: string }): Promise<Material> {
|
|
const response = await fetch(`/api/projects/${args.projectId}/materials/${args.materialId}`);
|
|
return handleResponse(response, (data) => (data as MaterialResponse).material);
|
|
}
|
|
|
|
export function fetchMaterials(
|
|
projectId: string,
|
|
params?: { page?: number; pageSize?: number; status?: MaterialStatus },
|
|
): Promise<MaterialListResponse> {
|
|
const searchParams = new URLSearchParams();
|
|
if (params?.page) searchParams.set("page", String(params.page));
|
|
if (params?.pageSize) searchParams.set("pageSize", String(params.pageSize));
|
|
if (params?.status) searchParams.set("status", params.status);
|
|
const qs = searchParams.toString();
|
|
const url = `/api/projects/${projectId}/materials${qs ? `?${qs}` : ""}`;
|
|
const response = fetch(url);
|
|
return response.then((r) => {
|
|
if (!r.ok) {
|
|
return r.json().then((body: null | { error?: string }) => {
|
|
throw new Error(body?.error ?? `HTTP ${r.status}`);
|
|
});
|
|
}
|
|
return r.json() as Promise<MaterialListResponse>;
|
|
});
|
|
}
|
|
|
|
export function useCreateMaterial(projectId: string) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: createMaterial,
|
|
onSuccess: (data) => {
|
|
logger.info("素材创建成功", { materialId: data.id, projectId });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "list", projectId] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useApproveMaterial(projectId: string) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: approveMaterial,
|
|
onSuccess: (data) => {
|
|
logger.info("素材通过成功", { materialId: data.id, projectId });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "list", projectId] });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "detail", projectId, data.id] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useDeleteMaterial(projectId: string) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: deleteMaterial,
|
|
onSuccess: (_data, variables) => {
|
|
logger.info("素材删除成功", { materialId: variables.materialId, projectId });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "list", projectId] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useDiscardMaterial(projectId: string) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: discardMaterial,
|
|
onSuccess: (data) => {
|
|
logger.info("素材放弃成功", { materialId: data.id, projectId });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "list", projectId] });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "detail", projectId, data.id] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useRetryMaterial(projectId: string) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: retryMaterial,
|
|
onSuccess: (data) => {
|
|
logger.info("素材重试成功", { materialId: data.id, projectId });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "list", projectId] });
|
|
void queryClient.invalidateQueries({ queryKey: [...MATERIALS_KEY, "detail", projectId, data.id] });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useMaterial(args: { materialId: null | string; projectId: string }) {
|
|
return useQuery({
|
|
enabled: !!args.materialId,
|
|
queryFn: () => fetchMaterial({ materialId: args.materialId!, projectId: args.projectId }),
|
|
queryKey: [...MATERIALS_KEY, "detail", args.projectId, args.materialId],
|
|
});
|
|
}
|
|
|
|
export function useMaterialList(
|
|
projectId: string,
|
|
params?: { page?: number; pageSize?: number; status?: MaterialStatus },
|
|
) {
|
|
return useQuery({
|
|
queryFn: () => fetchMaterials(projectId, params),
|
|
queryKey: [...MATERIALS_KEY, "list", projectId, params],
|
|
});
|
|
}
|