import { useRef, useState, type RefObject } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { getLastPhone, getPartnerProfile, request, saveRememberedSession, type PartnerSessionPayload, } from '../lib/api'; import { usePartnerSession } from '../contexts/PartnerSessionContext'; import { partnerHomePath } from '../lib/partnerAccess'; const REMEMBER_PHONE_KEY = 'partner_remember_phone'; const REMEMBER_FLAG_KEY = 'partner_remember_account'; function AgreementCheckbox({ agreed, onChange, inputRef, }: { agreed: boolean; onChange: (next: boolean) => void; inputRef?: RefObject; }) { return ( ); } function loadRememberedPhone(): { phone: string; remember: boolean } { try { const remember = localStorage.getItem(REMEMBER_FLAG_KEY) === '1'; const phone = remember ? localStorage.getItem(REMEMBER_PHONE_KEY) || '' : ''; return { phone, remember }; } catch { return { phone: '', remember: false }; } } function formatPartnerError(e: unknown): string { const text = e instanceof Error ? e.message : '操作失败'; if (text.includes('合伙人账号不存在') || text.includes('未找到合伙人账号')) { return '未找到合伙人账号'; } if (text.includes('合伙人账号已停用')) { return '合伙人账号已停用'; } return text; } export default function LoginPage() { const navigate = useNavigate(); const { applySession, refresh, account } = usePartnerSession(); const savedProfile = getPartnerProfile(); const remembered = loadRememberedPhone(); const [phone, setPhone] = useState(remembered.phone || getLastPhone()); const [code, setCode] = useState(''); const [rememberAccount, setRememberAccount] = useState(remembered.remember); const [agreed, setAgreed] = useState(false); const [loading, setLoading] = useState(false); const [msg, setMsg] = useState(''); const [codeCooldown, setCodeCooldown] = useState(0); const agreementRef = useRef(null); function ensureAgreed() { if (!agreed) { setMsg('请先勾选并同意用户协议'); agreementRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }); return false; } return true; } function persistRememberAccount(nextPhone: string) { try { if (rememberAccount) { localStorage.setItem(REMEMBER_FLAG_KEY, '1'); localStorage.setItem(REMEMBER_PHONE_KEY, nextPhone); } else { localStorage.removeItem(REMEMBER_FLAG_KEY); localStorage.removeItem(REMEMBER_PHONE_KEY); } } catch { /* ignore */ } } async function sendCode() { if (!ensureAgreed()) return; setMsg(''); try { await request('PARTNER_H5', '/partner/auth/sms/send', { method: 'POST', body: JSON.stringify({ phone, scene: 'PARTNER_LOGIN' }), silent: true, }); setMsg('验证码已发送'); setCodeCooldown(60); const timer = setInterval(() => { setCodeCooldown((s) => { if (s <= 1) { clearInterval(timer); return 0; } return s - 1; }); }, 1000); } catch (e) { setMsg(formatPartnerError(e)); } } async function finishLoginNavigate() { const me = await refresh(); navigate(partnerHomePath(me ?? account ?? savedProfile)); } async function login() { if (!ensureAgreed()) return; setLoading(true); setMsg(''); try { const data = await request('PARTNER_H5', '/partner/auth/login/sms', { method: 'POST', body: JSON.stringify({ phone, code }), silent: true, }); saveRememberedSession(data); applySession(data); persistRememberAccount(phone); await finishLoginNavigate(); } catch (e) { setMsg(formatPartnerError(e)); } finally { setLoading(false); } } return (
wine_bar

杜康好客

城市合伙人端

城市合伙人登录

smartphone { setPhone(e.target.value); setMsg(''); }} />
shield setCode(e.target.value)} />
{msg &&

{msg}

}

手机号验证成功后,7 天内无需再次输入验证码

); }