// src/hooks/useProfileCompleteness.js // 用户资料完整性管理自定义 Hook import { useState, useCallback, useRef, useEffect } from 'react'; import { logger } from '../utils/logger'; import { getApiBase } from '../utils/apiConfig'; /** * 用户资料完整性管理 Hook * 检查并管理用户资料完整度状态 * * @param {Object} options * @param {boolean} options.isAuthenticated - 是否已登录 * @param {Object} options.user - 用户对象 * @returns {{ * profileCompleteness: Object|null, * showAlert: boolean, * setShowAlert: Function, * isChecking: boolean, * checkProfileCompleteness: Function * }} */ export const useProfileCompleteness = ({ isAuthenticated, user }) => { const [profileCompleteness, setProfileCompleteness] = useState(null); const [showAlert, setShowAlert] = useState(false); const [isChecking, setIsChecking] = useState(false); // 添加标志位:追踪是否已经检查过资料完整性(避免重复请求) const hasCheckedCompleteness = useRef(false); // ⚡ 提取 userId 为独立变量,避免 user 对象引用变化导致无限循环 const userId = user?.id; const prevUserIdRef = useRef(userId); const prevIsAuthenticatedRef = useRef(isAuthenticated); // 检查用户资料完整性 const checkProfileCompleteness = useCallback(async () => { if (!isAuthenticated || !user) return; // 如果已经检查过,跳过(避免重复请求) if (hasCheckedCompleteness.current) { logger.debug('useProfileCompleteness', '已检查过资料完整性,跳过重复请求', { userId: user?.id }); return; } try { setIsChecking(true); logger.debug('useProfileCompleteness', '开始检查资料完整性', { userId: user?.id }); const base = getApiBase(); const resp = await fetch(base + '/api/account/profile-completeness', { credentials: 'include' }); if (resp.ok) { const data = await resp.json(); if (data.success) { setProfileCompleteness(data.data); // 只有微信用户且资料不完整时才显示提醒 setShowAlert(data.data.needsAttention); // 标记为已检查 hasCheckedCompleteness.current = true; logger.debug('useProfileCompleteness', '资料完整性检查完成', { userId: user?.id, completeness: data.data.completenessPercentage }); } } } catch (error) { logger.warn('useProfileCompleteness', '检查资料完整性失败', { userId: user?.id, error: error.message }); } finally { setIsChecking(false); } }, [isAuthenticated, userId, user]); // 监听用户变化,重置检查标志(用户切换或退出登录时) useEffect(() => { const userIdChanged = prevUserIdRef.current !== userId; const authChanged = prevIsAuthenticatedRef.current !== isAuthenticated; if (userIdChanged || authChanged) { prevUserIdRef.current = userId; prevIsAuthenticatedRef.current = isAuthenticated; if (!isAuthenticated || !user) { // 用户退出登录,重置标志 hasCheckedCompleteness.current = false; setProfileCompleteness(null); setShowAlert(false); } } }, [isAuthenticated, userId, user]); // 用户登录后检查资料完整性 useEffect(() => { const userIdChanged = prevUserIdRef.current !== userId; const authChanged = prevIsAuthenticatedRef.current !== isAuthenticated; if ((userIdChanged || authChanged) && isAuthenticated && user) { // 延迟检查,避免过于频繁 const timer = setTimeout(checkProfileCompleteness, 1000); return () => clearTimeout(timer); } }, [isAuthenticated, userId, checkProfileCompleteness, user]); // 提供重置函数,用于登出时清理 const resetCompleteness = useCallback(() => { hasCheckedCompleteness.current = false; setProfileCompleteness(null); setShowAlert(false); }, []); return { profileCompleteness, showAlert, setShowAlert, isChecking, checkProfileCompleteness, resetCompleteness }; };