import { useCallback, useState } from 'react'; import { getPasswordRuleMessage, resetPassword, validatePassword, validatePasswordConfirm, type LoginResult, } from '../api'; import type { PasswordResetPayload } from '../types'; export interface UsePasswordResetReturn { /** 重置 / 首次设置密码,成功返回登录结果(后端直接下发登录态) */ reset: (payload: PasswordResetPayload) => Promise; /** 提交进行中 */ loading: boolean; /** 失败原因(用于页面提示) */ error: Error | null; /** * 新密码规则校验:返回中文提示,null 表示通过。 * 规则本身在 API 层计算,页面只渲染结果,不写判断逻辑。 */ checkPassword: (password: string, confirm: string) => string | null; } /** * 重置 / 首次设置登录密码。 * * 覆盖两个场景:忘记密码(老用户改密)、首次设置密码(登录即注册的用户天生无密码)。 * 两条路径共用同一流程与接口,页面按来源只改文案。 * 发送验证码走独立的 useSmsCode。 */ export function usePasswordReset(): UsePasswordResetReturn { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const reset = useCallback(async (payload: PasswordResetPayload) => { setLoading(true); setError(null); try { return await resetPassword(payload); } catch (e) { const err = e instanceof Error ? e : new Error('密码设置失败,请稍后重试'); setError(err); throw err; } finally { setLoading(false); } }, []); const checkPassword = useCallback((password: string, confirm: string) => { const ruleError = validatePassword(password); if (ruleError) return getPasswordRuleMessage(ruleError); // 确认框还没开始输入时不提示不一致,避免用户刚敲第一个字符就被报错 if (confirm.length > 0) { const confirmError = validatePasswordConfirm(password, confirm); if (confirmError) return getPasswordRuleMessage(confirmError); } return null; }, []); return { reset, loading, error, checkPassword }; }