合伙人端登录页面调整
This commit is contained in:
@@ -28,6 +28,9 @@ function formatPartnerError(e: unknown): string {
|
|||||||
if (text.includes('合伙人账号不存在') || text.includes('未找到合伙人账号')) {
|
if (text.includes('合伙人账号不存在') || text.includes('未找到合伙人账号')) {
|
||||||
return '未找到合伙人账号';
|
return '未找到合伙人账号';
|
||||||
}
|
}
|
||||||
|
if (text.includes('合伙人账号已停用')) {
|
||||||
|
return '合伙人账号已停用';
|
||||||
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,14 +39,8 @@ export default function LoginPage() {
|
|||||||
const [params] = useSearchParams();
|
const [params] = useSearchParams();
|
||||||
const quick = params.get('quick') === '1';
|
const quick = params.get('quick') === '1';
|
||||||
const remembered = loadRememberedPhone();
|
const remembered = loadRememberedPhone();
|
||||||
const [step, setStep] = useState<'phone' | 'code'>('phone');
|
|
||||||
const [phone, setPhone] = useState(remembered.phone || '13700000001');
|
const [phone, setPhone] = useState(remembered.phone || '13700000001');
|
||||||
const [confirmedProfile, setConfirmedProfile] = useState<{
|
const [code, setCode] = useState('');
|
||||||
maskedPhone: string;
|
|
||||||
name?: string;
|
|
||||||
companyName?: string;
|
|
||||||
} | null>(null);
|
|
||||||
const [code, setCode] = useState('123456');
|
|
||||||
const [rememberAccount, setRememberAccount] = useState(remembered.remember);
|
const [rememberAccount, setRememberAccount] = useState(remembered.remember);
|
||||||
const [agreed, setAgreed] = useState(true);
|
const [agreed, setAgreed] = useState(true);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -91,37 +88,6 @@ export default function LoginPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function backToPhoneStep() {
|
|
||||||
setStep('phone');
|
|
||||||
setConfirmedProfile(null);
|
|
||||||
setCode('');
|
|
||||||
setMsg('');
|
|
||||||
setCodeCooldown(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function confirmPhone() {
|
|
||||||
if (!ensureAgreed()) return;
|
|
||||||
setLoading(true);
|
|
||||||
setMsg('');
|
|
||||||
try {
|
|
||||||
const data = await request<{ ok: boolean; maskedPhone: string; name?: string; companyName?: string }>(
|
|
||||||
'PARTNER_H5',
|
|
||||||
'/partner/auth/phone/check',
|
|
||||||
{ method: 'POST', body: JSON.stringify({ phone }) },
|
|
||||||
);
|
|
||||||
setConfirmedProfile({
|
|
||||||
maskedPhone: data.maskedPhone,
|
|
||||||
name: data.name,
|
|
||||||
companyName: data.companyName,
|
|
||||||
});
|
|
||||||
setStep('code');
|
|
||||||
} catch (e) {
|
|
||||||
setMsg(formatPartnerError(e));
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendCode() {
|
async function sendCode() {
|
||||||
if (!ensureAgreed()) return;
|
if (!ensureAgreed()) return;
|
||||||
setMsg('');
|
setMsg('');
|
||||||
@@ -130,7 +96,7 @@ export default function LoginPage() {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ phone, scene: 'PARTNER_LOGIN' }),
|
body: JSON.stringify({ phone, scene: 'PARTNER_LOGIN' }),
|
||||||
});
|
});
|
||||||
setMsg('验证码已发送(Mock: 123456)');
|
setMsg('验证码已发送');
|
||||||
setCodeCooldown(60);
|
setCodeCooldown(60);
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
setCodeCooldown((s) => {
|
setCodeCooldown((s) => {
|
||||||
@@ -146,11 +112,17 @@ export default function LoginPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login() {
|
async function login(options?: { quick?: boolean }) {
|
||||||
if (!ensureAgreed()) return;
|
if (!options?.quick && !ensureAgreed()) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setMsg('');
|
setMsg('');
|
||||||
try {
|
try {
|
||||||
|
if (options?.quick) {
|
||||||
|
await request('PARTNER_H5', '/partner/auth/sms/send', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ phone, scene: 'PARTNER_LOGIN' }),
|
||||||
|
});
|
||||||
|
}
|
||||||
const data = await request<{ accessToken: string }>('PARTNER_H5', '/partner/auth/login/sms', {
|
const data = await request<{ accessToken: string }>('PARTNER_H5', '/partner/auth/login/sms', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ phone, code }),
|
body: JSON.stringify({ phone, code }),
|
||||||
@@ -214,7 +186,7 @@ export default function LoginPage() {
|
|||||||
|
|
||||||
<nav style={{ width: '100%', maxWidth: 384, marginTop: 16 }}>
|
<nav style={{ width: '100%', maxWidth: 384, marginTop: 16 }}>
|
||||||
{msg && <p className="partner-auth-msg" style={{ color: 'var(--color-error, #d33)', fontSize: 13, textAlign: 'center', marginBottom: 12 }}>{msg}</p>}
|
{msg && <p className="partner-auth-msg" style={{ color: 'var(--color-error, #d33)', fontSize: 13, textAlign: 'center', marginBottom: 12 }}>{msg}</p>}
|
||||||
<button type="button" className="partner-btn-primary" onClick={login} disabled={loading}>
|
<button type="button" className="partner-btn-primary" onClick={() => void login({ quick: true })} disabled={loading}>
|
||||||
<span>{loading ? '登录中...' : '一键登录'}</span>
|
<span>{loading ? '登录中...' : '一键登录'}</span>
|
||||||
{!loading && <span className="material-symbols-outlined">arrow_forward</span>}
|
{!loading && <span className="material-symbols-outlined">arrow_forward</span>}
|
||||||
</button>
|
</button>
|
||||||
@@ -244,13 +216,12 @@ export default function LoginPage() {
|
|||||||
<main className="partner-auth-card">
|
<main className="partner-auth-card">
|
||||||
<h2 className="partner-auth-card-title">城市合伙人登录</h2>
|
<h2 className="partner-auth-card-title">城市合伙人登录</h2>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||||
{step === 'phone' ? (
|
|
||||||
<>
|
|
||||||
<div className="partner-input-wrap">
|
<div className="partner-input-wrap">
|
||||||
<span className="material-symbols-outlined partner-input-icon">smartphone</span>
|
<span className="material-symbols-outlined partner-input-icon">smartphone</span>
|
||||||
<input
|
<input
|
||||||
className="partner-input"
|
className="partner-input"
|
||||||
type="tel"
|
type="tel"
|
||||||
|
maxLength={11}
|
||||||
placeholder="请输入手机号"
|
placeholder="请输入手机号"
|
||||||
value={phone}
|
value={phone}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@@ -259,42 +230,24 @@ export default function LoginPage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" className="partner-btn-primary" onClick={confirmPhone} disabled={loading}>
|
|
||||||
<span>{loading ? '校验中...' : '下一步'}</span>
|
|
||||||
{!loading && <span className="material-symbols-outlined">arrow_forward</span>}
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="partner-glass-card" style={{ padding: '12px 16px' }}>
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
|
|
||||||
<div>
|
|
||||||
<div style={{ fontWeight: 600 }}>
|
|
||||||
{confirmedProfile?.name || '合伙人账号'}
|
|
||||||
{confirmedProfile?.companyName ? (
|
|
||||||
<span className="text-muted body-md" style={{ fontWeight: 400, marginLeft: 8 }}>
|
|
||||||
{confirmedProfile.companyName}
|
|
||||||
</span>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
<div className="text-muted body-md" style={{ marginTop: 4 }}>
|
|
||||||
{confirmedProfile?.maskedPhone || phone}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button type="button" className="partner-link" onClick={backToPhoneStep} style={{ flexShrink: 0 }}>
|
|
||||||
修改
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="partner-input-row">
|
<div className="partner-input-row">
|
||||||
<div className="partner-input-wrap">
|
<div className="partner-input-wrap">
|
||||||
<span className="material-symbols-outlined partner-input-icon">shield</span>
|
<span className="material-symbols-outlined partner-input-icon">shield</span>
|
||||||
<input className="partner-input" type="text" placeholder="验证码" value={code} onChange={(e) => setCode(e.target.value)} />
|
<input
|
||||||
|
className="partner-input"
|
||||||
|
type="text"
|
||||||
|
maxLength={6}
|
||||||
|
placeholder="验证码"
|
||||||
|
value={code}
|
||||||
|
onChange={(e) => setCode(e.target.value)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" className="partner-code-btn" onClick={sendCode} disabled={codeCooldown > 0}>
|
<button type="button" className="partner-code-btn" onClick={sendCode} disabled={codeCooldown > 0}>
|
||||||
{codeCooldown > 0 ? `${codeCooldown}s 后重发` : '获取验证码'}
|
{codeCooldown > 0 ? `${codeCooldown}s` : '获取验证码'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label className="partner-remember-row">
|
<label className="partner-remember-row">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -303,15 +256,14 @@ export default function LoginPage() {
|
|||||||
/>
|
/>
|
||||||
<span>记住账号</span>
|
<span>记住账号</span>
|
||||||
</label>
|
</label>
|
||||||
<button type="button" className="partner-btn-primary" onClick={login} disabled={loading}>
|
|
||||||
|
{msg && <p className="partner-auth-msg" style={{ color: 'var(--color-error, #d33)', fontSize: 13, textAlign: 'center' }}>{msg}</p>}
|
||||||
|
|
||||||
|
<button type="button" className="partner-btn-primary" onClick={() => void login()} disabled={loading}>
|
||||||
<span>{loading ? '登录中...' : '登录'}</span>
|
<span>{loading ? '登录中...' : '登录'}</span>
|
||||||
{!loading && <span className="material-symbols-outlined">arrow_forward</span>}
|
{!loading && <span className="material-symbols-outlined">arrow_forward</span>}
|
||||||
</button>
|
</button>
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{msg && <p className="partner-auth-msg" style={{ color: 'var(--color-error, #d33)', fontSize: 13, textAlign: 'center' }}>{msg}</p>}
|
|
||||||
{step === 'phone' && (
|
|
||||||
<>
|
|
||||||
<div className="partner-auth-divider"><span>其他登录方式</span></div>
|
<div className="partner-auth-divider"><span>其他登录方式</span></div>
|
||||||
<button type="button" className="partner-btn-wechat" onClick={wechatLogin} disabled={wxLoading}>
|
<button type="button" className="partner-btn-wechat" onClick={wechatLogin} disabled={wxLoading}>
|
||||||
<svg viewBox="0 0 24 24" fill="#07C160" aria-hidden>
|
<svg viewBox="0 0 24 24" fill="#07C160" aria-hidden>
|
||||||
@@ -319,8 +271,7 @@ export default function LoginPage() {
|
|||||||
</svg>
|
</svg>
|
||||||
<span>{wxLoading ? '登录中...' : '微信一键授权'}</span>
|
<span>{wxLoading ? '登录中...' : '微信一键授权'}</span>
|
||||||
</button>
|
</button>
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<label className="partner-checkbox-row">
|
<label className="partner-checkbox-row">
|
||||||
<input type="checkbox" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
|
<input type="checkbox" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -45,13 +45,7 @@ async function main() {
|
|||||||
});
|
});
|
||||||
if (!unknownSms.includes('未找到合伙人账号')) throw new Error(`unexpected: ${unknownSms}`);
|
if (!unknownSms.includes('未找到合伙人账号')) throw new Error(`unexpected: ${unknownSms}`);
|
||||||
|
|
||||||
console.log('3. PARTNER phone/check + login bound phone');
|
console.log('3. PARTNER sms/login bound phone');
|
||||||
const check = await req('PARTNER_H5', '/partner/auth/phone/check', {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({ phone: '13700000001' }),
|
|
||||||
});
|
|
||||||
if (!check.ok || !check.maskedPhone) throw new Error('phone check failed');
|
|
||||||
|
|
||||||
const login = await loginWithSms(
|
const login = await loginWithSms(
|
||||||
'PARTNER_H5',
|
'PARTNER_H5',
|
||||||
'13700000001',
|
'13700000001',
|
||||||
|
|||||||
Reference in New Issue
Block a user