import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Image, ActivityIndicator, Alert, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import { useRoute, useNavigation, RouteProp } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { RootStackParamList } from '../../navigation/types'; import { qrcodeApi } from '../../services/authService'; import { colors, spacing, fontSizes, borderRadius } from '../../theme'; type QRCodeConfirmRouteProp = RouteProp; type NavigationProp = NativeStackNavigationProp; export const QRCodeConfirmScreen: React.FC = () => { const route = useRoute(); const navigation = useNavigation(); const { sessionId } = route.params; const [loading, setLoading] = useState(false); const [userInfo, setUserInfo] = useState<{ id: string; nickname: string; avatar: string } | null>(null); const [error, setError] = useState(null); useEffect(() => { // 扫码 handleScan(); }, []); const handleScan = async () => { try { setLoading(true); const response = await qrcodeApi.scan(sessionId); setUserInfo(response.user); } catch (err: any) { const errorMsg = err.response?.data?.message || '扫码失败'; setError(errorMsg); Alert.alert('扫码失败', errorMsg, [ { text: '确定', onPress: () => navigation.goBack() } ]); } finally { setLoading(false); } }; const handleConfirm = async () => { try { setLoading(true); await qrcodeApi.confirm(sessionId); Alert.alert('登录成功', '网页端已登录', [ { text: '确定', onPress: () => navigation.goBack() } ]); } catch (err: any) { const errorMsg = err.response?.data?.message || '确认登录失败'; Alert.alert('登录失败', errorMsg); } finally { setLoading(false); } }; const handleCancel = async () => { try { await qrcodeApi.cancel(sessionId); } catch (err) { // 忽略取消错误 } navigation.goBack(); }; if (loading && !userInfo) { return ( 正在扫码... ); } if (error) { return ( {error} navigation.goBack()}> 返回 ); } return ( 确认登录 您正在登录网页端 {userInfo && ( {userInfo.avatar ? ( ) : ( )} {userInfo.nickname} )} {loading ? ( ) : ( 确认登录 )} 取消 ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: spacing.md, paddingVertical: spacing.sm, backgroundColor: '#fff', borderBottomWidth: 1, borderBottomColor: '#eee', }, closeButton: { padding: spacing.sm, }, headerTitle: { fontSize: fontSizes.lg, fontWeight: '600', color: '#333', }, placeholder: { width: 40, }, content: { flex: 1, padding: spacing.lg, justifyContent: 'center', }, infoCard: { backgroundColor: '#fff', borderRadius: borderRadius.lg, padding: spacing.xl, alignItems: 'center', marginBottom: spacing.xl, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, infoText: { fontSize: fontSizes.md, color: '#666', marginBottom: spacing.lg, }, userInfo: { alignItems: 'center', }, avatar: { width: 80, height: 80, borderRadius: 40, marginBottom: spacing.md, }, avatarPlaceholder: { width: 80, height: 80, borderRadius: 40, backgroundColor: '#f0f0f0', justifyContent: 'center', alignItems: 'center', marginBottom: spacing.md, }, nickname: { fontSize: fontSizes.lg, fontWeight: '600', color: '#333', }, buttonContainer: { gap: spacing.md, }, button: { paddingVertical: spacing.md, paddingHorizontal: spacing.xl, borderRadius: borderRadius.md, alignItems: 'center', }, confirmButton: { backgroundColor: colors.primary.main, }, confirmButtonText: { color: '#fff', fontSize: fontSizes.md, fontWeight: '600', }, cancelButton: { backgroundColor: '#fff', borderWidth: 1, borderColor: '#ddd', }, cancelButtonText: { color: '#666', fontSize: fontSizes.md, }, loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, loadingText: { marginTop: spacing.md, fontSize: fontSizes.md, color: '#666', }, errorContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: spacing.xl, }, errorText: { marginTop: spacing.md, fontSize: fontSizes.md, color: '#666', textAlign: 'center', }, backButton: { marginTop: spacing.xl, paddingVertical: spacing.md, paddingHorizontal: spacing.xl, backgroundColor: colors.primary.main, borderRadius: borderRadius.md, }, backButtonText: { color: '#fff', fontSize: fontSizes.md, fontWeight: '600', }, }); export default QRCodeConfirmScreen;