/** * 新用户引导页面数据获取 Hook * * 封装引导状态检查的 SWR 请求 + 品牌创建的 mutation,替代手动 useState + useEffect 模式。 * - 引导状态检查:mount 时自动获取 * - 品牌创建:mutation(由用户交互触发) */ import { useCallback } from "react"; import { useApi, useApiMutation } from "./use-api"; import type { SWRConfiguration } from "swr"; import { getSession } from "next-auth/react"; import type { Session } from "next-auth"; import { monitoringApi } from "@/lib/api/monitoring"; interface OnboardingStatusResponse { completed: boolean; } interface CreateBrandResponse { brand_id: string; } export interface CreateBrandPayload { name: string; competitors: string[]; platforms: string[]; frequency: "daily" | "weekly" | "monthly"; } export interface UseOnboardingDataReturn { /** 引导状态数据 */ onboardingStatus: OnboardingStatusResponse | undefined; /** 是否已完成引导 */ isCompleted: boolean; /** 是否正在加载 */ isLoading: boolean; /** 错误信息 */ error: Error | undefined; /** 刷新引导状态 */ refresh: () => void; /** 创建品牌 */ createBrand: (data: CreateBrandPayload) => Promise; /** 是否正在创建品牌 */ isCreatingBrand: boolean; /** 创建品牌错误 */ mutationError: Error | undefined; /** 创建监控任务 */ createMonitoringTask: ( brandId: string, platforms: string[], frequency: string ) => Promise; } export interface UseOnboardingDataOptions { /** SWR 配置(用于测试时禁用重试等) */ swrOptions?: SWRConfiguration; } export function useOnboardingData( options?: UseOnboardingDataOptions ): UseOnboardingDataReturn { const swrOptions = options?.swrOptions; // 引导状态检查 const { data: onboardingStatus, isLoading, error, refresh, } = useApi("/api/v1/onboarding/status", swrOptions); const isCompleted = onboardingStatus?.completed ?? false; // 创建品牌(mutation) const { trigger: createBrandTrigger, isMutating: isCreatingBrand, error: mutationError, } = useApiMutation( "/api/v1/onboarding/brand", "POST" ); const createBrand = useCallback( async (data: CreateBrandPayload): Promise => { const result = await createBrandTrigger(data); return result?.brand_id ?? null; }, [createBrandTrigger] ); const createMonitoringTask = useCallback( async ( brandId: string, platforms: string[], frequency: string ): Promise => { try { const session = await getSession(); const token = (session as Session)?.accessToken; if (!token) return; for (const platform of platforms) { await monitoringApi.createTask(token, { brand_id: brandId, platform, query_keywords: frequency, }); } } catch { // silent } }, [] ); return { onboardingStatus, isCompleted, isLoading, error, refresh, createBrand, isCreatingBrand, mutationError, createMonitoringTask, }; }