import { useCallback, useEffect, useRef, useState } from 'react'; import type { SmsScene } from '@dukang/shared-types'; import { request } from './api'; import { fetchClientConfig } from './pay-wechat'; import { validateMobilePhone } from './phone'; export function useSmsCode() { const [codeCooldown, setCodeCooldown] = useState(0); const [sending, setSending] = useState(false); const [sentHint, setSentHint] = useState(''); const [error, setError] = useState(''); const [mockSms, setMockSms] = useState(true); const timerRef = useRef | null>(null); useEffect(() => { fetchClientConfig() .then((cfg) => setMockSms(cfg.mockSms)) .catch(() => {}); return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, []); const startCooldown = useCallback(() => { setCodeCooldown(60); if (timerRef.current) clearInterval(timerRef.current); timerRef.current = setInterval(() => { setCodeCooldown((c) => { if (c <= 1) { if (timerRef.current) clearInterval(timerRef.current); return 0; } return c - 1; }); }, 1000); }, []); const sendCode = useCallback( async (phone: string, scene: SmsScene) => { const phoneCheck = validateMobilePhone(phone); if (!phoneCheck.ok) { setError(phoneCheck.message ?? '请输入正确的手机号码'); return false; } setSending(true); setError(''); setSentHint(''); try { await request('USER_H5', '/auth/sms/send', { method: 'POST', body: JSON.stringify({ phone, scene }), }); setSentHint(mockSms ? '验证码已发送(开发模式)' : '验证码已发送,请注意查收'); startCooldown(); return true; } catch (e) { setError(e instanceof Error ? e.message : '发送失败'); return false; } finally { setSending(false); } }, [mockSms, startCooldown], ); const clearMessages = useCallback(() => { setError(''); setSentHint(''); }, []); return { sendCode, sending, codeCooldown, sentHint, error, setError, clearMessages, mockSms, }; }