From 0cccfe3373557f833be1eec2fb6a85831b768e2b Mon Sep 17 00:00:00 2001 From: cll <931958862@qq.com> Date: Tue, 29 Jul 2025 17:30:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=99=BD=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/hooks/useDeviceFingerprint.ts | 33 +++++++++++++++++++++++++++++++ src/pages/Login/index.tsx | 27 ++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/hooks/useDeviceFingerprint.ts diff --git a/package.json b/package.json index 3b39c6f..970b7b7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@ant-design/charts": "^2.2.6", "@ant-design/icons": "^5.0.1", "@ant-design/pro-components": "^2.4.4", + "@fingerprintjs/fingerprintjs": "^4.6.2", "@umijs/max": "^4.4.4", "@umijs/max-plugin-openapi": "^2.0.3", "@umijs/plugin-openapi": "^1.3.3", diff --git a/src/hooks/useDeviceFingerprint.ts b/src/hooks/useDeviceFingerprint.ts new file mode 100644 index 0000000..f51f6df --- /dev/null +++ b/src/hooks/useDeviceFingerprint.ts @@ -0,0 +1,33 @@ +import { useEffect, useState } from 'react'; +import FingerprintJS from '@fingerprintjs/fingerprintjs'; + +/** + * Hook: 获取设备指纹(visitorId) + */ +export function useDeviceFingerprint() { + const [fingerprint, setFingerprint] = useState(null); + + useEffect(() => { + let isMounted = true; + + async function loadFingerprint() { + try { + const fp = await FingerprintJS.load(); + const result = await fp.get(); + if (isMounted) { + setFingerprint(result.visitorId); + } + } catch (err) { + console.error('获取设备指纹失败:', err); + } + } + + loadFingerprint(); + + return () => { + isMounted = false; + }; + }, []); + + return fingerprint; // 初始为 null,加载后返回指纹 ID +} diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index 14bc2e3..7edac3b 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -7,22 +7,37 @@ import { } from '@ant-design/pro-components'; import { history, useModel } from '@umijs/max'; import { App, theme } from 'antd'; +import {useDeviceFingerprint} from '@/hooks/useDeviceFingerprint'; +import { useState } from 'react'; const Page = () => { const { setInitialState } = useModel('@@initialState'); const { token } = theme.useToken(); const { message } = App.useApp(); + const deviceId = useDeviceFingerprint(); + const [ isAuth, setIsAuth ] = useState(false) + + console.log(deviceId) ; const onFinish = async (values: { username: string; password: string }) => { try { - const { data, success } = await usercontrollerLogin(values); + const { data, success, code, message: msg } = await usercontrollerLogin({...values, deviceId}); if (success) { + message.success('登录成功'); localStorage.setItem('token', data?.token as string); const { data: user } = await usercontrollerGetuser(); setInitialState({ user }); history.push('/'); + return } + if(code === 10001){ + message.info("验证码已发送至管理邮箱") + setIsAuth(true); + return; + } + message.error(msg); + } catch { message.error('登录失败'); } @@ -86,6 +101,16 @@ const Page = () => { }, ]} /> + { + isAuth? + :<> + } {/*