|
@@ -1,7 +1,7 @@
|
|
|
import React, { useState, useEffect, useRef } from "react";
|
|
|
import http from '@src/http';
|
|
|
import { Modal, Image, message } from "antd";
|
|
|
-import { qwGetQrCode } from '@src/http/api';
|
|
|
+import { qwGetQrCode, qwCheckLogin } from '@src/http/api';
|
|
|
|
|
|
interface QrCodeData {
|
|
|
qrcode: string;
|
|
@@ -10,12 +10,18 @@ interface QrCodeData {
|
|
|
key: string;
|
|
|
}
|
|
|
|
|
|
+interface LoginStatusData {
|
|
|
+ loginStatus: number; // 0: 代表登录进行中,1: 代表成功,-1: 输入验证码
|
|
|
+ message: string;
|
|
|
+}
|
|
|
+
|
|
|
interface QrCodeModalProps {
|
|
|
visible: boolean;
|
|
|
onClose: () => void;
|
|
|
title: string;
|
|
|
vid?: string; // 可选参数,用于登录时传入
|
|
|
onSuccess?: (data: QrCodeData) => void; // 可选回调,用于处理成功获取二维码后的操作
|
|
|
+ onLoginSuccess?: () => void; // 登录成功后的回调
|
|
|
}
|
|
|
|
|
|
const QrCodeModal: React.FC<QrCodeModalProps> = ({
|
|
@@ -23,17 +29,26 @@ const QrCodeModal: React.FC<QrCodeModalProps> = ({
|
|
|
onClose,
|
|
|
title,
|
|
|
vid,
|
|
|
- onSuccess
|
|
|
+ onSuccess,
|
|
|
+ onLoginSuccess
|
|
|
}) => {
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
const [qrCodeData, setQrCodeData] = useState<QrCodeData | null>(null);
|
|
|
const [countdown, setCountdown] = useState<number>(0);
|
|
|
+ const [loginStatus, setLoginStatus] = useState<number>(0); // 登录状态
|
|
|
+ const [loginMessage, setLoginMessage] = useState<string>(""); // 登录状态描述
|
|
|
+
|
|
|
const timerRef = useRef<NodeJS.Timeout | null>(null);
|
|
|
+ const pollTimerRef = useRef<NodeJS.Timeout | null>(null); // 轮询定时器
|
|
|
|
|
|
// 获取二维码
|
|
|
const fetchQrCode = async () => {
|
|
|
try {
|
|
|
setLoading(true);
|
|
|
+ // 重置登录状态
|
|
|
+ setLoginStatus(0);
|
|
|
+ setLoginMessage("");
|
|
|
+
|
|
|
// 根据是否有 vid 参数决定是添加账号还是登录
|
|
|
const res = await http.post<QrCodeData>(qwGetQrCode, { vid });
|
|
|
|
|
@@ -45,6 +60,9 @@ const QrCodeModal: React.FC<QrCodeModalProps> = ({
|
|
|
if (onSuccess) {
|
|
|
onSuccess(res.data);
|
|
|
}
|
|
|
+
|
|
|
+ // 开始轮询登录状态
|
|
|
+ startPollingLoginStatus(res.data.uuid);
|
|
|
} else {
|
|
|
message.error(res.msg || '获取二维码失败');
|
|
|
}
|
|
@@ -55,6 +73,52 @@ const QrCodeModal: React.FC<QrCodeModalProps> = ({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ // 轮询登录状态
|
|
|
+ const startPollingLoginStatus = (uuid: string) => {
|
|
|
+ // 清除可能存在的轮询定时器
|
|
|
+ if (pollTimerRef.current) {
|
|
|
+ clearInterval(pollTimerRef.current);
|
|
|
+ pollTimerRef.current = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置轮询间隔为2秒
|
|
|
+ pollTimerRef.current = setInterval(async () => {
|
|
|
+ try {
|
|
|
+ const res = await http.post<LoginStatusData>(qwCheckLogin, { uuid });
|
|
|
+
|
|
|
+ if (res.success) {
|
|
|
+ const { loginStatus, message: loginMsg } = res.data;
|
|
|
+ setLoginStatus(loginStatus);
|
|
|
+ setLoginMessage(loginMsg || "");
|
|
|
+
|
|
|
+ // 登录成功或失败时停止轮询
|
|
|
+ if (loginStatus !== 0) {
|
|
|
+ if (pollTimerRef.current) {
|
|
|
+ clearInterval(pollTimerRef.current);
|
|
|
+ pollTimerRef.current = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 登录成功
|
|
|
+ if (loginStatus === 1) {
|
|
|
+ message.success(loginMsg || "登录成功");
|
|
|
+ if (onLoginSuccess) {
|
|
|
+ onLoginSuccess();
|
|
|
+ }
|
|
|
+ // 关闭弹窗
|
|
|
+ handleClose();
|
|
|
+ }
|
|
|
+ // 登录失败
|
|
|
+ else if (loginStatus === -1) {
|
|
|
+ message.error(loginMsg || "登录失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("轮询登录状态失败:", error);
|
|
|
+ }
|
|
|
+ }, 2000);
|
|
|
+ };
|
|
|
+
|
|
|
// 启动倒计时
|
|
|
useEffect(() => {
|
|
|
if (countdown > 0) {
|
|
@@ -90,13 +154,38 @@ const QrCodeModal: React.FC<QrCodeModalProps> = ({
|
|
|
// 关闭弹窗时清空数据和定时器
|
|
|
setQrCodeData(null);
|
|
|
setCountdown(0);
|
|
|
+ setLoginStatus(0);
|
|
|
+ setLoginMessage("");
|
|
|
+
|
|
|
+ // 清除倒计时定时器
|
|
|
if (timerRef.current) {
|
|
|
clearInterval(timerRef.current);
|
|
|
timerRef.current = null;
|
|
|
}
|
|
|
+
|
|
|
+ // 清除轮询定时器
|
|
|
+ if (pollTimerRef.current) {
|
|
|
+ clearInterval(pollTimerRef.current);
|
|
|
+ pollTimerRef.current = null;
|
|
|
+ }
|
|
|
}
|
|
|
}, [visible, vid]);
|
|
|
|
|
|
+ // 组件卸载时清除所有定时器
|
|
|
+ useEffect(() => {
|
|
|
+ return () => {
|
|
|
+ if (timerRef.current) {
|
|
|
+ clearInterval(timerRef.current);
|
|
|
+ timerRef.current = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pollTimerRef.current) {
|
|
|
+ clearInterval(pollTimerRef.current);
|
|
|
+ pollTimerRef.current = null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }, []);
|
|
|
+
|
|
|
// 处理弹窗关闭
|
|
|
const handleClose = () => {
|
|
|
onClose();
|