|
|
@ -1,45 +1,107 @@
|
|
|
|
'use client';
|
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
|
|
import { useContext, useEffect, useState } from 'react';
|
|
|
|
import { useEffect, useRef, useState } from 'react';
|
|
|
|
|
|
|
|
|
|
|
|
import { Dialog, DialogContent, DialogTrigger, DialogClose } from '@/components/ui/dialog';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
|
|
|
|
import { QRCodeSVG } from 'qrcode.react';
|
|
|
|
|
|
|
|
import { useShallow } from 'zustand/react/shallow';
|
|
|
|
|
|
|
|
|
|
|
|
import { LoginContext } from './LoginContext';
|
|
|
|
import { useToast } from '@/components/ui/use-toast';
|
|
|
|
import LoginForm from './LoginForm';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { IconClose } from '@/components';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { saveToken, useLoginRedirect } from '@/hooks';
|
|
|
|
import { apiGetUUID, apiCheckQr, apiGetLoginQr } from '@/services';
|
|
|
|
import { apiGetUUID, apiCheckQr, apiGetLoginQr } from '@/services';
|
|
|
|
|
|
|
|
import { useUserStore } from '@/store';
|
|
|
|
|
|
|
|
|
|
|
|
export default function LoginQrcode() {
|
|
|
|
export default function LoginQrcode() {
|
|
|
|
const { state, dispatch } = useContext(LoginContext);
|
|
|
|
const redirect = useLoginRedirect();
|
|
|
|
const { uuid, setUuid } = useState<string>('');
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
const uuidRef = useRef<string>('');
|
|
|
|
|
|
|
|
const { toast } = useToast();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [qrCodeState, setQrCodeState] = useState<0 | 1 | 2>(0); // 0-未扫码 1-已扫码 2-已过期
|
|
|
|
|
|
|
|
const [qrCodeValue, setQrCodeValue] = useState<string>('');
|
|
|
|
|
|
|
|
const intervalIdRef = useRef<number | null>(null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { setShowLogin, getUserInfo } = useUserStore(
|
|
|
|
|
|
|
|
useShallow((state) => ({
|
|
|
|
|
|
|
|
setShowLogin: state.setShowLogin,
|
|
|
|
|
|
|
|
getUserInfo: state.getUserInfo,
|
|
|
|
|
|
|
|
})),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const getUUID = async () => {
|
|
|
|
const getUUID = async () => {
|
|
|
|
const result = await apiGetUUID();
|
|
|
|
const result = await apiGetUUID();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.code === 200) {
|
|
|
|
if (result.code === 200) {
|
|
|
|
setUuid(result.data);
|
|
|
|
uuidRef.current = result.data;
|
|
|
|
getQrcode(result.data);
|
|
|
|
getQrcode(result.data);
|
|
|
|
return;
|
|
|
|
return result.data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const getQrcode = async (id: string) => {
|
|
|
|
const getQrcode = async (id: string) => {
|
|
|
|
const res = await apiGetLoginQr(id);
|
|
|
|
const res = await apiGetLoginQr(id);
|
|
|
|
const qrCode = await res.data;
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
|
|
setQrCodeState(0);
|
|
|
|
|
|
|
|
setQrCodeValue(res.data);
|
|
|
|
|
|
|
|
handleCountDown();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleCountDown = () => {
|
|
|
|
|
|
|
|
intervalIdRef.current = window.setInterval(() => {
|
|
|
|
|
|
|
|
checkLoginStatus();
|
|
|
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleResetQrcode = () => {
|
|
|
|
|
|
|
|
setQrCodeValue('');
|
|
|
|
|
|
|
|
setQrCodeState(0);
|
|
|
|
|
|
|
|
uuidRef.current = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getUUID();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const checkLoginStatus = async () => {
|
|
|
|
const checkLoginStatus = async () => {
|
|
|
|
const res = await apiCheckQr(uuid);
|
|
|
|
const res = await apiCheckQr(uuidRef.current);
|
|
|
|
console.log(res);
|
|
|
|
if (res.code === 10000) {
|
|
|
|
|
|
|
|
// 过期
|
|
|
|
|
|
|
|
setQrCodeState(2);
|
|
|
|
|
|
|
|
intervalIdRef.current !== null && window.clearInterval(intervalIdRef.current);
|
|
|
|
|
|
|
|
} else if (res.code !== 200) {
|
|
|
|
|
|
|
|
// 请求出错
|
|
|
|
|
|
|
|
uuidRef.current = '';
|
|
|
|
|
|
|
|
setQrCodeValue('');
|
|
|
|
|
|
|
|
uuidRef.current = '';
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else if (res.data === '0') {
|
|
|
|
|
|
|
|
// 未扫码
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
} else if (res.data === '1') {
|
|
|
|
|
|
|
|
setQrCodeState(1);
|
|
|
|
|
|
|
|
intervalIdRef.current !== null && window.clearInterval(intervalIdRef.current);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 扫码成功
|
|
|
|
|
|
|
|
saveToken(res.data);
|
|
|
|
|
|
|
|
setShowLogin(false);
|
|
|
|
|
|
|
|
await getUserInfo();
|
|
|
|
|
|
|
|
toast({
|
|
|
|
|
|
|
|
description: '登录成功',
|
|
|
|
|
|
|
|
duration: 1500,
|
|
|
|
|
|
|
|
type: 'background',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (redirect) router.replace(redirect);
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
const intervalId = setInterval(checkLoginStatus, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return () => clearInterval(intervalId);
|
|
|
|
|
|
|
|
getUUID();
|
|
|
|
getUUID();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
if (intervalIdRef.current !== null) {
|
|
|
|
|
|
|
|
window.clearInterval(intervalIdRef.current);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
@ -47,7 +109,27 @@ export default function LoginQrcode() {
|
|
|
|
{/* title */}
|
|
|
|
{/* title */}
|
|
|
|
<div className="mt-9px text-13px leading-18px text-#000/70 text-center">通过雀乐APP扫码登录</div>
|
|
|
|
<div className="mt-9px text-13px leading-18px text-#000/70 text-center">通过雀乐APP扫码登录</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="w-200px h-200px rounded-6px mt-15px bg-#fff overflow-hidden shadow-black-[0px_8px_30px_0px]"></div>
|
|
|
|
<div className="flex items-center justify-center w-200px h-200px rounded-6px mt-15px bg-#fff overflow-hidden shadow-black-[0px_8px_30px_0px] ">
|
|
|
|
|
|
|
|
{!qrCodeValue && <div>加载中...</div>}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{!!qrCodeValue && qrCodeState !== 2 && (
|
|
|
|
|
|
|
|
<QRCodeSVG
|
|
|
|
|
|
|
|
className="w-90% h-90% rounded-6px overflow-hidden"
|
|
|
|
|
|
|
|
size={200}
|
|
|
|
|
|
|
|
value={qrCodeValue}
|
|
|
|
|
|
|
|
imageSettings={{ src: '/img/logo_qrcode.svg', height: 32, width: 32, excavate: true }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{!!qrCodeValue && qrCodeState === 2 && (
|
|
|
|
|
|
|
|
<div className="flex flex-col items-center justify-center">
|
|
|
|
|
|
|
|
<div>二维码已过期</div>
|
|
|
|
|
|
|
|
<div className="cursor-pointer mt-5px text-blue" onClick={handleResetQrcode}>
|
|
|
|
|
|
|
|
重新获取
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|