fix: 获取验证码 UI

feature/qrcode
mackt 2 months ago
parent 2f9207a9e4
commit 482dd6f518

@ -31,6 +31,7 @@
"next": "14.1.3",
"nookies": "^2.5.2",
"qrcode": "^1.5.3",
"qrcode.react": "^3.1.0",
"qs": "^6.12.0",
"react": "^18",
"react-dom": "^18",

@ -0,0 +1,4 @@
<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="32" height="32" rx="6" fill="black" fill-opacity="0.95" stroke="white" stroke-width="2"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.787 11.4529C16.787 10.0553 17.5983 8.88086 18.8727 8.54343C19.1124 8.47992 19.3633 8.44618 19.6224 8.44618C20.6903 8.44618 21.6213 9.02185 22.148 9.87739C22.1637 9.90284 22.8865 10.9812 22.8865 12.5898C22.8865 13.0435 22.8299 13.4841 22.7244 13.9041C22.7202 13.9243 22.7182 13.945 22.7182 13.9667C22.7182 14.139 22.8559 14.2786 23.0258 14.2786C23.1201 14.2786 23.2043 14.2357 23.2604 14.1674C23.268 14.1592 23.2747 14.1504 23.2808 14.141C23.8429 13.3952 24.1764 12.4636 24.1764 11.4529C24.1764 9.00477 22.2194 7.02014 19.8054 7.02014C19.7845 7.02014 19.7636 7.02014 19.7427 7.02113C19.1965 7.02844 18.6741 7.13781 18.1938 7.33098C16.5771 7.9813 15.4345 9.58087 15.4345 11.4529C15.4345 13.5045 17.0284 15.6333 18.1494 16.7593C18.2076 16.8173 18.2657 16.8747 18.3254 16.9321C18.5947 17.1918 18.8721 17.4338 19.1557 17.6583C19.244 17.7281 19.3332 17.7964 19.4225 17.8632C19.5454 17.9562 19.6244 18.1047 19.6244 18.2718C19.6244 18.5902 19.3447 18.809 19.041 18.7756C17.8863 18.6116 16.8045 18.2164 15.8426 17.6371C15.6814 17.5399 15.5233 17.438 15.3692 17.3299H15.3688C14.3824 16.6446 13.5423 15.7575 12.9084 14.7271C12.1035 13.4195 11.6287 11.8817 11.6022 10.2327C11.6017 10.1846 11.6012 10.136 11.6012 10.0874C11.6012 9.52671 11.6532 8.9779 11.7522 8.44618C10.908 9.48999 10.296 10.7345 9.99767 12.0984C9.86298 12.7129 9.7921 13.3523 9.7921 14.0076C9.7921 15.5764 10.1981 17.049 10.9091 18.323C9.96705 17.65 9.16323 16.7909 8.55023 15.7978C8.32474 15.4332 8.12483 15.0509 7.954 14.6526C7.92387 14.9485 7.90857 15.249 7.90857 15.5531C7.90857 16.6989 8.12532 17.7933 8.51905 18.7968C8.88783 19.7356 9.41165 20.5942 10.0583 21.3411C9.78546 21.308 9.50901 21.2879 9.22907 21.2811C9.15918 21.2796 9.08928 21.2785 9.01945 21.2785C8.30586 21.2785 7.61227 21.3659 6.94922 21.5314C8.53031 21.9561 9.93336 22.8241 11.0228 23.9956C12.5805 25.6524 14.8643 26.9798 17.9204 26.9798C20.7732 26.9798 25.6992 25.2334 25.6992 21.3654C25.6992 19.9124 24.9785 18.3371 22.893 17.3866C19.4282 15.8074 16.787 13.5943 16.787 11.4529Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -144,7 +144,7 @@ export default function LoginForm({ className }: { className?: string }) {
<Button
type="white"
className={`absolute top-6px right-24px w-fit h-44px rounded-100px font-size-14px text-right leading-20px`}
className={`absolute top-15px right-24px w-fit h-fit rounded-100px font-size-14px text-right leading-20px`}
disabled={btnLoading || activeSMS}
onClick={debounce(handleSendSMS, 300)}
>

@ -1,17 +1,7 @@
'use client';
import { useContext } from 'react';
import { Dialog, DialogContent, DialogTrigger, DialogClose } from '@/components/ui/dialog';
import { LoginContext } from './LoginContext';
import LoginForm from './LoginForm';
import { IconClose } from '@/components';
export default function LoginPhone() {
const { state, dispatch } = useContext(LoginContext);
return (
<div className="flex flex-col items-center w-340px bg-#f2f3f7">
{/* title */}

@ -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<string>('');
const redirect = useLoginRedirect();
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 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 */}
<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>
);
}

@ -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;
};

@ -67,7 +67,6 @@ export const apiGetMyUserInfo = async () => {
*/
export const apiGetUUID = async () => {
const res: FetchResponse<string> = await clientHttp.get('/queyueapi/user/user/uuid');
console.log(res);
return res;
};
@ -75,7 +74,7 @@ export const apiGetUUID = async () => {
* @description uuid
*/
export const apiCheckQr = async (uuid: string) => {
const res: FetchResponse<UserInfo> = await clientHttp.get(`/queyueapi/user/user/check/qr?uuid=${uuid}`);
const res: FetchResponse<string> = await clientHttp.get(`/queyueapi/user/user/check/qr?uuid=${uuid}`);
return res;
};
@ -83,6 +82,6 @@ export const apiCheckQr = async (uuid: string) => {
* @description
*/
export const apiGetLoginQr = async (uuid: string) => {
const res: FetchResponse<UserInfo> = await clientHttp.get(`/queyueapi/user/user/getLoginQr?uuid=${uuid}`);
const res: FetchResponse<string> = await clientHttp.get(`/queyueapi/user/user/getLoginQr?uuid=${uuid}`);
return res;
};

@ -5692,6 +5692,11 @@ punycode@^2.1.0:
resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qrcode.react@^3.1.0:
version "3.1.0"
resolved "https://mirrors.cloud.tencent.com/npm/qrcode.react/-/qrcode.react-3.1.0.tgz#5c91ddc0340f768316fbdb8fff2765134c2aecd8"
integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==
qrcode@^1.5.3:
version "1.5.3"
resolved "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170"

Loading…
Cancel
Save