{/* title */}
diff --git a/src/components/Login/LoginQrcode.tsx b/src/components/Login/LoginQrcode.tsx
index 1260145..7f1a80b 100644
--- a/src/components/Login/LoginQrcode.tsx
+++ b/src/components/Login/LoginQrcode.tsx
@@ -1,45 +1,107 @@
'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 LoginForm from './LoginForm';
-
-import { IconClose } from '@/components';
+import { useToast } from '@/components/ui/use-toast';
+import { saveToken, useLoginRedirect } from '@/hooks';
import { apiGetUUID, apiCheckQr, apiGetLoginQr } from '@/services';
+import { useUserStore } from '@/store';
export default function LoginQrcode() {
- const { state, dispatch } = useContext(LoginContext);
- const { uuid, setUuid } = useState
('');
+ const redirect = useLoginRedirect();
+ const router = useRouter();
+ const uuidRef = useRef('');
+ const { toast } = useToast();
+
+ const [qrCodeState, setQrCodeState] = useState<0 | 1 | 2>(0); // 0-未扫码 1-已扫码 2-已过期
+ const [qrCodeValue, setQrCodeValue] = useState('');
+ const intervalIdRef = useRef(null);
+
+ const { setShowLogin, getUserInfo } = useUserStore(
+ useShallow((state) => ({
+ setShowLogin: state.setShowLogin,
+ getUserInfo: state.getUserInfo,
+ })),
+ );
const getUUID = async () => {
const result = await apiGetUUID();
if (result.code === 200) {
- setUuid(result.data);
+ uuidRef.current = result.data;
getQrcode(result.data);
- return;
+ return result.data;
}
};
const getQrcode = async (id: string) => {
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 res = await apiCheckQr(uuid);
- console.log(res);
+ const res = await apiCheckQr(uuidRef.current);
+ 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(() => {
- const intervalId = setInterval(checkLoginStatus, 1000);
-
- return () => clearInterval(intervalId);
getUUID();
+
+ return () => {
+ if (intervalIdRef.current !== null) {
+ window.clearInterval(intervalIdRef.current);
+ }
+ };
}, []);
return (
@@ -47,7 +109,27 @@ export default function LoginQrcode() {
{/* title */}
通过雀乐APP扫码登录
-
+
+ {!qrCodeValue &&
加载中...
}
+
+ {!!qrCodeValue && qrCodeState !== 2 && (
+
+ )}
+
+ {!!qrCodeValue && qrCodeState === 2 && (
+
+ )}
+
);
}
diff --git a/src/hooks/useLogin.ts b/src/hooks/useLogin.ts
index 5199f73..c3748db 100644
--- a/src/hooks/useLogin.ts
+++ b/src/hooks/useLogin.ts
@@ -3,6 +3,11 @@ import { jwtDecode } from 'jwt-decode';
import { apiUserLogin, apiAutoLogin } from '@/services';
import { setAccessToken, getAuthorization, clearAccessToken, getDeviceId } from '@/utils';
+export const saveToken = async (token: string) => {
+ const { exp } = parseJWT(token);
+ setAccessToken({ token, expires: exp.toString() });
+};
+
export const SmsLogin = async ({
phone,
authCode,
@@ -15,9 +20,7 @@ export const SmsLogin = async ({
// 登录成功后,将token存入localStorage
const result = await apiUserLogin({ mobile: phone, mobileCheckCode: authCode, deviceId });
if (result.code === 200) {
- const jwt = result.data;
- const { exp } = parseJWT(jwt);
- setAccessToken({ token: jwt, expires: exp.toString() });
+ saveToken(result.data);
}
return result;
};
diff --git a/src/services/client/user.ts b/src/services/client/user.ts
index 10aba7b..759f1eb 100644
--- a/src/services/client/user.ts
+++ b/src/services/client/user.ts
@@ -67,7 +67,6 @@ export const apiGetMyUserInfo = async () => {
*/
export const apiGetUUID = async () => {
const res: FetchResponse