You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.5 KiB
239 lines
7.5 KiB
import React, { useState, useEffect } from 'react';
|
|
import { View, Text } from '@tarojs/components';
|
|
import { Button, Loading, Card } from '@nutui/nutui-react-taro';
|
|
import { Success, Failure, Tips, User } from '@nutui/icons-react-taro';
|
|
import Taro, { useRouter } from '@tarojs/taro';
|
|
import { confirmQRLogin } from '@/api/qr-login';
|
|
import { useUser } from '@/hooks/useUser';
|
|
|
|
/**
|
|
* 扫码登录确认页面
|
|
* 用于处理从二维码跳转过来的登录确认
|
|
*/
|
|
const QRConfirmPage: React.FC = () => {
|
|
const router = useRouter();
|
|
const { user, getDisplayName } = useUser();
|
|
const [loading, setLoading] = useState(false);
|
|
const [confirmed, setConfirmed] = useState(false);
|
|
const [error, setError] = useState<string>('');
|
|
const [token, setToken] = useState<string>('');
|
|
|
|
useEffect(() => {
|
|
// 从URL参数中获取token
|
|
const { qrCodeKey, token: urlToken } = router.params;
|
|
const loginToken = qrCodeKey || urlToken;
|
|
|
|
if (loginToken) {
|
|
setToken(loginToken);
|
|
} else {
|
|
setError('无效的登录链接');
|
|
}
|
|
}, [router.params]);
|
|
|
|
// 确认登录
|
|
const handleConfirmLogin = async () => {
|
|
if (!token) {
|
|
setError('缺少登录token');
|
|
return;
|
|
}
|
|
|
|
if (!user?.userId) {
|
|
setError('请先登录小程序');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
setError('');
|
|
|
|
const result = await confirmQRLogin({
|
|
token,
|
|
userId: user.userId,
|
|
platform: 'wechat',
|
|
wechatInfo: {
|
|
nickname: user.nickname,
|
|
avatar: user.avatar
|
|
}
|
|
});
|
|
|
|
if (result.success) {
|
|
setConfirmed(true);
|
|
Taro.showToast({
|
|
title: '登录确认成功',
|
|
icon: 'success',
|
|
duration: 2000
|
|
});
|
|
|
|
// 3秒后自动返回
|
|
setTimeout(() => {
|
|
Taro.navigateBack();
|
|
}, 3000);
|
|
} else {
|
|
setError(result.message || '登录确认失败');
|
|
}
|
|
} catch (err: any) {
|
|
setError(err.message || '登录确认失败');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 取消登录
|
|
const handleCancel = () => {
|
|
Taro.navigateBack();
|
|
};
|
|
|
|
// 重试
|
|
const handleRetry = () => {
|
|
setError('');
|
|
setConfirmed(false);
|
|
handleConfirmLogin();
|
|
};
|
|
|
|
return (
|
|
<View className="qr-confirm-page min-h-screen bg-gray-50">
|
|
<View className="p-4">
|
|
{/* 主要内容卡片 */}
|
|
<Card className="bg-white rounded-lg shadow-sm">
|
|
<View className="p-6 text-center">
|
|
{/* 图标 */}
|
|
<View className="mb-6">
|
|
{loading ? (
|
|
<View className="w-16 h-16 mx-auto flex items-center justify-center">
|
|
<Loading className="text-blue-500" />
|
|
</View>
|
|
) : confirmed ? (
|
|
<View className="w-16 h-16 mx-auto bg-green-100 rounded-full flex items-center justify-center">
|
|
<Success className="text-green-500" />
|
|
</View>
|
|
) : error ? (
|
|
<View className="w-16 h-16 mx-auto bg-red-100 rounded-full flex items-center justify-center">
|
|
<Failure className="text-red-500" />
|
|
</View>
|
|
) : (
|
|
<View className="w-16 h-16 mx-auto bg-blue-100 rounded-full flex items-center justify-center">
|
|
<User size="32" className="text-blue-500" />
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
{/* 标题 */}
|
|
<Text className="text-xl font-bold text-gray-800 mb-2 block">
|
|
{loading ? '正在确认登录...' :
|
|
confirmed ? '登录确认成功' :
|
|
error ? '登录确认失败' : '确认登录'}
|
|
</Text>
|
|
|
|
{/* 描述 */}
|
|
<Text className="text-gray-600 mb-6 block">
|
|
{loading ? '请稍候,正在为您确认登录' :
|
|
confirmed ? '您已成功确认登录,网页端将自动登录' :
|
|
error ? error :
|
|
`确认使用 ${getDisplayName()} 登录网页端?`}
|
|
</Text>
|
|
|
|
{/* 用户信息 */}
|
|
{!loading && !confirmed && !error && user && (
|
|
<View className="bg-gray-50 rounded-lg p-4 mb-6">
|
|
<View className="flex items-center justify-center">
|
|
<View className="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-3">
|
|
<User className="text-blue-500" size="20" />
|
|
</View>
|
|
<View className="text-left">
|
|
<Text className="text-sm font-medium text-gray-800 block">
|
|
{user.nickname || user.username || '用户'}
|
|
</Text>
|
|
<Text className="text-xs text-gray-500 block">
|
|
ID: {user.userId}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
)}
|
|
|
|
{/* 操作按钮 */}
|
|
<View className="space-y-3">
|
|
{loading ? (
|
|
<Button
|
|
type="default"
|
|
size="large"
|
|
disabled
|
|
className="w-full"
|
|
>
|
|
确认中...
|
|
</Button>
|
|
) : confirmed ? (
|
|
<Button
|
|
type="success"
|
|
size="large"
|
|
onClick={handleCancel}
|
|
className="w-full"
|
|
>
|
|
完成
|
|
</Button>
|
|
) : error ? (
|
|
<View className="space-y-2">
|
|
<Button
|
|
type="primary"
|
|
size="large"
|
|
onClick={handleRetry}
|
|
className="w-full"
|
|
>
|
|
重试
|
|
</Button>
|
|
<Button
|
|
type="default"
|
|
size="large"
|
|
onClick={handleCancel}
|
|
className="w-full"
|
|
>
|
|
取消
|
|
</Button>
|
|
</View>
|
|
) : (
|
|
<View className="space-y-2">
|
|
<Button
|
|
type="primary"
|
|
size="large"
|
|
onClick={handleConfirmLogin}
|
|
className="w-full"
|
|
disabled={!token || !user?.userId}
|
|
>
|
|
确认登录
|
|
</Button>
|
|
<Button
|
|
type="default"
|
|
size="large"
|
|
onClick={handleCancel}
|
|
className="w-full"
|
|
>
|
|
取消
|
|
</Button>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</Card>
|
|
|
|
{/* 安全提示 */}
|
|
<Card className="bg-yellow-50 border border-yellow-200 rounded-lg mt-4">
|
|
<View className="p-4">
|
|
<View className="flex items-start">
|
|
<Tips className="text-yellow-600 mr-2 mt-1" size="16" />
|
|
<View>
|
|
<Text className="text-sm font-medium text-yellow-800 mb-1 block">
|
|
安全提示
|
|
</Text>
|
|
<Text className="text-xs text-yellow-700 block">
|
|
请确认这是您本人的登录操作。如果不是,请点击取消并检查账户安全。
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Card>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default QRConfirmPage;
|