// 登录 / 购买窗口四步流:扫码登录 → 时长包 → 支付二维码 → 完成 // 规格见 doc/frontend-design.html 4.2;二维码内容来自后端,轮询自动推进。 import { useEffect, useRef, useState } from 'react'; import { createRoot } from 'react-dom/client'; import '@dudu/design/styles.css'; import { Button } from '@dudu/design/components/core/Button'; import { Badge } from '@dudu/design/components/core/Badge'; import { invoke } from '../shared/tauri'; function Center({ children }) { return (
{children}
); } // 简易二维码占位:真实渲染由 qr 内容字符串绘制(接入 qrcode 库或后端返图)。 function QrBox({ value }) { return (
{value || '加载中'}
); } function LoginApp() { const [step, setStep] = useState('login'); // login | plans | pay | done const [qr, setQr] = useState(null); const [packs, setPacks] = useState([]); const [sel, setSel] = useState('pack_500'); const [order, setOrder] = useState(null); const [me, setMe] = useState(null); const timer = useRef(null); // 扫码登录:创建二维码 + 轮询 useEffect(() => { if (step !== 'login') return undefined; let stop = false; invoke('login_qr_create').then((r) => { if (!r || stop) return; setQr(r); timer.current = setInterval(async () => { const st = await invoke('login_qr_poll', { state: r.state }); if (st && st.status === 'confirmed') { clearInterval(timer.current); const m = await invoke('fetch_me'); setMe(m); const ps = await invoke('fetch_packs'); setPacks(ps || []); setStep('plans'); } }, 1000); }); return () => { stop = true; clearInterval(timer.current); }; }, [step]); // 支付轮询 useEffect(() => { if (step !== 'pay' || !order) return undefined; const t = setInterval(async () => { const st = await invoke('order_status', { orderId: order.order_id }); if (st && st.status === 'paid') { clearInterval(t); setMe(await invoke('fetch_me')); setStep('done'); } }, 1000); return () => clearInterval(t); }, [step, order]); const pack = packs.find((p) => p.id === sel); if (step === 'login') { return (
微信扫码登录
打开微信扫一扫,确认后自动登录
); } if (step === 'plans') { return (
购买时长 {me && {me.nickname_masked} {me.account_state === 'ok' ? '余额充足' : '试用中'} }
{packs.map((p) => { const active = sel === p.id; return ( ); })}
时长不过期 · 每天另有 3 分钟免费试用
); } if (step === 'pay') { return (
微信扫码支付
¥{pack.price_cents / 100} · {pack.minutes} 分钟时长包
支付完成后自动开通
); } return (
已到账 {pack.minutes} 分钟
时长余额 {me ? Math.floor(me.balance_seconds / 60) : '—'} 分钟 · 不过期 · 现在就按住 ⌘⇧Space 试试
); } createRoot(document.getElementById('root')).render();