import React, { useState } from 'react' import { View, Text } from '@tarojs/components' import { Button, Loading } from '@nutui/nutui-react-taro' import { Failure, Scan, Success } from '@nutui/icons-react-taro' import Taro from '@tarojs/taro' import { confirmWechatQRLogin, parseQRContent } from '@/api/passport/qr-login' export interface QRLoginScannerProps { onSuccess?: (result: any) => void onError?: (error: string) => void className?: string buttonText?: string showStatus?: boolean } type ScanState = 'idle' | 'scanning' | 'confirming' | 'success' | 'error' const QRLoginScanner: React.FC = ({ onSuccess, onError, className = '', buttonText = '开始扫码登录', showStatus = true, }) => { const [state, setState] = useState('idle') const [error, setError] = useState('') const [result, setResult] = useState(null) const reset = () => { setState('idle') setError('') setResult(null) } const startScan = async () => { try { setState('scanning') setError('') const scanRes = await Taro.scanCode({ onlyFromCamera: false, scanType: ['qrCode'] }) const rawContent = scanRes.result || '' const token = parseQRContent(rawContent) const userId = Number(Taro.getStorageSync('UserId')) if (!token) { throw new Error('未识别到有效的登录二维码') } if (!userId) { throw new Error('当前用户未登录') } setState('confirming') const confirmRes = await confirmWechatQRLogin(token, userId) setResult(confirmRes) setState('success') onSuccess?.(confirmRes) } catch (err: any) { const message = err?.errMsg?.includes('cancel') ? '已取消扫码' : err?.message || '扫码登录失败' setError(message) setState('error') onError?.(message) } } const renderStatus = () => { switch (state) { case 'scanning': return ( 请扫描登录二维码... ) case 'confirming': return ( 正在确认登录... ) case 'success': return ( 登录确认成功 ) case 'error': return ( {error || '扫码登录失败'} ) default: return null } } const loading = state === 'scanning' || state === 'confirming' return ( {showStatus && {renderStatus()}} {state === 'success' && result && ( 扫码登录已确认,请返回网页端查看登录结果。 )} {state === 'idle' && ( 扫描网页端展示的登录二维码,即可完成登录确认。 )} ) } export default QRLoginScanner