/** * 优化建议页面数据获取 Hook * * 封装建议列表的 SWR 请求 + 重新生成/更新状态的 mutation,替代手动 useState + useEffect 模式。 * - 建议列表:依赖 brandId + 筛选条件 * - 重新生成:mutation * - 更新状态:mutation */ import { useCallback } from "react"; import { useApi, useApiMutation } from "./use-api"; import { fetchWithAuth } from "@/lib/api/client"; import type { SWRConfiguration } from "swr"; import type { SuggestionListResponse, SuggestionStatus } from "@/types/suggestion"; export interface SuggestionsFilters { type?: string; priority?: string; status?: string; } export interface UseSuggestionsDataOptions { brandId?: string; filters?: SuggestionsFilters; /** SWR 配置(用于测试时禁用重试等) */ swrOptions?: SWRConfiguration; } export interface UseSuggestionsDataReturn { /** 建议列表 */ suggestions: SuggestionListResponse["suggestions"] | undefined; /** 是否正在加载 */ isLoading: boolean; /** 错误信息 */ error: Error | undefined; /** 刷新建议列表 */ refresh: () => void; /** 重新生成建议 */ regenerate: () => Promise; /** 是否正在重新生成 */ isRegenerating: boolean; /** 重新生成错误 */ regenerateError: Error | undefined; /** 更新建议状态 */ updateStatus: (suggestionId: string, newStatus: string) => Promise; /** 是否正在更新状态 */ isUpdatingStatus: boolean; } function buildSuggestionsUrl(brandId: string, filters?: SuggestionsFilters): string | null { if (!brandId) return null; const params = new URLSearchParams(); if (filters?.type && filters.type !== "all") params.set("type", filters.type); if (filters?.priority && filters.priority !== "all") params.set("priority", filters.priority); if (filters?.status && filters.status !== "all") params.set("status", filters.status); const qs = params.toString(); return `/api/v1/brands/${brandId}/suggestions${qs ? `?${qs}` : ""}`; } export function useSuggestionsData( options?: UseSuggestionsDataOptions ): UseSuggestionsDataReturn { const brandId = options?.brandId ?? ""; const filters = options?.filters; const swrOptions = options?.swrOptions; // 建议列表 const suggestionsUrl = buildSuggestionsUrl(brandId, filters); const { data: suggestionsResponse, isLoading, error, refresh, mutate, } = useApi(suggestionsUrl, swrOptions); const suggestions = suggestionsResponse?.suggestions; // 重新生成建议(mutation) const { trigger: regenerateTrigger, isMutating: isRegenerating, error: regenerateError, } = useApiMutation( brandId ? `/api/v1/brands/${brandId}/suggestions/regenerate` : "", "POST" ); const regenerate = useCallback(async (): Promise => { const result = await regenerateTrigger(); if (result) { // 用新数据更新 SWR 缓存 mutate(result); } return result; }, [regenerateTrigger, mutate]); // 更新建议状态(mutation) const { isMutating: isUpdatingStatus, } = useApiMutation( brandId ? `/api/v1/brands/${brandId}/suggestions` : "", "PUT" ); const updateStatus = useCallback( async (suggestionId: string, newStatus: string) => { await fetchWithAuth( `/api/v1/brands/${brandId}/suggestions/${suggestionId}/status`, { method: "PUT", body: JSON.stringify({ status: newStatus }), } ); // 乐观更新:直接修改本地缓存 mutate( (current) => { if (!current) return current; return { ...current, suggestions: current.suggestions.map((s) => s.id === suggestionId ? { ...s, status: newStatus as SuggestionStatus } : s ), }; }, { revalidate: false } ); }, [brandId, mutate] ); return { suggestions, isLoading, error, refresh, regenerate, isRegenerating, regenerateError, updateStatus, isUpdatingStatus, }; }