import { useEffect, useState } from 'react'; import type { WechatLoginResult } from '@dukang/shared-types'; import { SmsScene } from '@dukang/shared-types'; import { bindPhone, request, type SessionPayload } from '../lib/api'; import { normalizePhoneInput, validateMobilePhone } from '../lib/phone'; import { useSmsCode } from '../lib/use-sms-code'; import { useUserSession } from '../contexts/UserSessionContext'; type PhoneVerifySheetProps = { open: boolean; /** 打开时预填手机号(如收货地址中的手机号) */ defaultPhone?: string; mode?: 'bind_phone' | 'wechat_bind_phone'; wxSessionKey?: string; title?: string; description?: string; onClose: () => void; onSuccess: () => void; }; export default function PhoneVerifySheet({ open, defaultPhone, mode = 'bind_phone', wxSessionKey, title, description, onClose, onSuccess, }: PhoneVerifySheetProps) { const { applySession } = useUserSession(); const [phone, setPhone] = useState(''); const [code, setCode] = useState(''); const [loading, setLoading] = useState(false); const { sendCode, sending, codeCooldown, sentHint, error, setError, clearMessages } = useSmsCode(); useEffect(() => { if (!open) { setPhone(''); setCode(''); setError(''); clearMessages(); return; } if (defaultPhone) { const normalized = normalizePhoneInput(defaultPhone); if (validateMobilePhone(normalized).ok) { setPhone(normalized); } } }, [open, defaultPhone, clearMessages, setError]); async function onSendCode() { clearMessages(); await sendCode(phone, SmsScene.BIND_PHONE); } async function submit() { const phoneCheck = validateMobilePhone(phone); if (!phoneCheck.ok) { setError(phoneCheck.message ?? '请输入正确的手机号码'); return; } if (!code.trim()) { setError('请输入验证码'); return; } setLoading(true); setError(''); try { if (mode === 'wechat_bind_phone') { if (!wxSessionKey) { setError('微信会话已过期,请重新授权'); return; } const data = await request('USER_H5', '/auth/wechat/bind-phone', { method: 'POST', body: JSON.stringify({ wxSessionKey, phone, code }), }); if (data.accessToken) { applySession({ accessToken: data.accessToken, refreshToken: data.refreshToken ?? '', deviceKey: data.deviceKey, phoneVerified: !!data.phoneVerified, user: data.user as SessionPayload['user'], }); } } else { const session = await bindPhone(phone, code); applySession(session as SessionPayload); } onSuccess(); onClose(); } catch (e) { setError(e instanceof Error ? e.message : '验证失败'); } finally { setLoading(false); } } if (!open) return null; const sheetTitle = title ?? (mode === 'wechat_bind_phone' ? '绑定手机号' : '验证手机号'); const sheetDesc = description ?? (mode === 'wechat_bind_phone' ? '建议绑定手机号,便于订单通知与售后;关闭可跳过继续支付' : '建议绑定手机号,便于订单通知与售后;关闭可跳过继续下单'); return (
{(error || sentHint) && (

{error || sentHint}

)} ); }