diff --git a/nkebao/src/App.tsx b/nkebao/src/App.tsx
index fa7a4541..bfee5515 100644
--- a/nkebao/src/App.tsx
+++ b/nkebao/src/App.tsx
@@ -1,8 +1,11 @@
import React from "react";
import AppRouter from "@/router";
-
function App() {
- return ;
+ return (
+ <>
+
+ >
+ );
}
export default App;
diff --git a/nkebao/src/components/DeviceGuard/index.tsx b/nkebao/src/components/DeviceGuard/index.tsx
deleted file mode 100644
index 9335ddfe..00000000
--- a/nkebao/src/components/DeviceGuard/index.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import React, { useEffect, useState, useMemo } from "react";
-import { useNavigate, useLocation } from "react-router-dom";
-import { useDeviceStore } from "@/store/module/device";
-import { useUserStore } from "@/store/module/user";
-import { updateDeviceCount } from "@/utils/device";
-
-interface DeviceGuardProps {
- children: React.ReactNode;
-}
-
-const DeviceGuard: React.FC = ({ children }) => {
- const navigate = useNavigate();
- const location = useLocation();
- const { isLoggedIn } = useUserStore();
- const { setDeviceCount } = useDeviceStore();
- const [isChecking, setIsChecking] = useState(true);
-
- // 不需要设备检查的路径
- const EXEMPT_PATHS = useMemo(
- () => ["/login", "/guide", "/register", "/forgot-password"],
- [],
- );
-
- useEffect(() => {
- const checkDeviceStatus = async () => {
- // 如果用户未登录,不需要检查设备状态
- if (!isLoggedIn) {
- setIsChecking(false);
- return;
- }
-
- // 如果当前路径是豁免路径,不需要检查设备状态
- if (EXEMPT_PATHS.includes(location.pathname)) {
- setIsChecking(false);
- return;
- }
-
- try {
- // 从API获取最新的设备数量并更新到store
- const currentDeviceCount = await updateDeviceCount(setDeviceCount);
-
- // 如果设备数量为0且不在guide页面,跳转到guide页面
- if (currentDeviceCount === 0 && location.pathname !== "/guide") {
- navigate("/guide");
- return;
- }
-
- // 如果设备数量大于0且在guide页面,跳转到首页
- if (currentDeviceCount > 0 && location.pathname === "/guide") {
- navigate("/");
- return;
- }
- } catch (error) {
- console.error("检查设备状态失败:", error);
- // 如果检查失败,默认跳转到guide页面
- if (location.pathname !== "/guide") {
- navigate("/guide");
- return;
- }
- } finally {
- setIsChecking(false);
- }
- };
-
- checkDeviceStatus();
- }, [isLoggedIn, location.pathname, navigate, setDeviceCount, EXEMPT_PATHS]);
-
- // 如果正在检查,显示加载状态
- if (isChecking) {
- return (
-
- );
- }
-
- return <>{children}>;
-};
-
-export default DeviceGuard;
diff --git a/nkebao/src/pages/guide/index.tsx b/nkebao/src/pages/guide/index.tsx
index 27c8aed8..8e1e1ea8 100644
--- a/nkebao/src/pages/guide/index.tsx
+++ b/nkebao/src/pages/guide/index.tsx
@@ -8,15 +8,16 @@ import {
QrcodeOutlined,
} from "@ant-design/icons";
import Layout from "@/components/Layout/Layout";
-import { fetchDeviceQRCode, addDeviceByImei, fetchDeviceList } from "./api";
-import { useUserStore, useDeviceStore } from "@/store";
+import { getDashboard } from "@/pages/mobile/home/api";
+import { fetchDeviceQRCode, addDeviceByImei } from "./api";
+import { useUserStore } from "@/store/module/user";
import styles from "./index.module.scss";
const Guide: React.FC = () => {
const navigate = useNavigate();
const { user } = useUserStore();
- const { deviceCount, setDeviceCount } = useDeviceStore();
const [loading, setLoading] = useState(true);
+ const [deviceCount, setDeviceCount] = useState(0);
// 添加设备弹窗状态
const [addVisible, setAddVisible] = useState(false);
@@ -36,10 +37,8 @@ const Guide: React.FC = () => {
const checkDeviceStatus = useCallback(async () => {
try {
setLoading(true);
- const dashboardData = await fetchDeviceList({
- accountId: user.s2_accountId,
- });
- const deviceNum = dashboardData.added ? 1 : 0;
+ const dashboardData = await getDashboard();
+ const deviceNum = dashboardData?.deviceNum || 0;
setDeviceCount(deviceNum);
@@ -49,6 +48,7 @@ const Guide: React.FC = () => {
return;
}
} catch (error) {
+ console.error("检查设备状态失败:", error);
Toast.show({
content: "检查设备状态失败,请重试",
position: "top",
@@ -56,7 +56,7 @@ const Guide: React.FC = () => {
} finally {
setLoading(false);
}
- }, [navigate, setDeviceCount]);
+ }, []);
useEffect(() => {
checkDeviceStatus();
@@ -71,9 +71,7 @@ const Guide: React.FC = () => {
const pollDeviceStatus = async () => {
try {
- const dashboardData = await fetchDeviceList({
- accountId: user.s2_accountId,
- });
+ const dashboardData = await getDashboard();
const currentDeviceCount = dashboardData?.deviceNum || 0;
// 如果设备数量增加了,说明有新设备添加成功
@@ -97,7 +95,7 @@ const Guide: React.FC = () => {
// 每3秒检查一次设备状态
pollingRef.current = setInterval(pollDeviceStatus, 3000);
- }, [isPolling, deviceCount, setDeviceCount]);
+ }, [isPolling, deviceCount]);
// 停止轮询
const stopPolling = useCallback(() => {
diff --git a/nkebao/src/pages/login/api.ts b/nkebao/src/pages/login/api.ts
index 617d0bed..9c1f6e6c 100644
--- a/nkebao/src/pages/login/api.ts
+++ b/nkebao/src/pages/login/api.ts
@@ -11,6 +11,7 @@ export interface LoginResponse {
data: {
token: string;
token_expired: string;
+ deviceTotal: number; // 设备总数
member: {
id: string;
name: string;
diff --git a/nkebao/src/pages/login/login.tsx b/nkebao/src/pages/login/login.tsx
index 5a91a67c..c1b52807 100644
--- a/nkebao/src/pages/login/login.tsx
+++ b/nkebao/src/pages/login/login.tsx
@@ -1,14 +1,13 @@
import React, { useState, useEffect } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
-import { Form, Input, Button, Toast, Tabs, Checkbox } from "antd-mobile";
+import { Form, Input, Button, Toast, Checkbox } from "antd-mobile";
import {
EyeInvisibleOutline,
EyeOutline,
UserOutline,
} from "antd-mobile-icons";
-import { useUserStore, useDeviceStore } from "@/store";
+import { useUserStore } from "@/store/module/user";
import { loginWithPassword, loginWithCode, sendVerificationCode } from "./api";
-import { updateDeviceCount } from "@/utils/device";
import style from "./login.module.scss";
const Login: React.FC = () => {
@@ -22,7 +21,6 @@ const Login: React.FC = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { login } = useUserStore();
- const { setDeviceCount } = useDeviceStore();
// 倒计时效果
useEffect(() => {
@@ -44,17 +42,33 @@ const Login: React.FC = () => {
// 发送验证码
const handleSendVerificationCode = async () => {
+ const account = form.getFieldValue("account");
+
+ if (!account) {
+ Toast.show({ content: "请输入手机号", position: "top" });
+ return;
+ }
+
+ // 手机号格式验证
+ const phoneRegex = /^1[3-9]\d{9}$/;
+ if (!phoneRegex.test(account)) {
+ Toast.show({ content: "请输入正确的11位手机号", position: "top" });
+ return;
+ }
+
try {
- const phone = form.getFieldValue("phone");
- if (!phone) {
- Toast.show({ content: "请输入手机号", position: "top" });
- return;
- }
- await sendVerificationCode(phone);
- setCountdown(60);
+ setLoading(true);
+ await sendVerificationCode({
+ mobile: account,
+ type: "login",
+ });
+
Toast.show({ content: "验证码已发送", position: "top" });
- } catch (error: any) {
- // 错误已在request中处理
+ setCountdown(60);
+ } catch (error) {
+ // 错误已在request中处理,这里不需要额外处理
+ } finally {
+ setLoading(false);
}
};
@@ -81,40 +95,32 @@ const Login: React.FC = () => {
}
console.log(response, "response");
+ // 获取设备总数
+ const deviceTotal = response.deviceTotal || 0;
+ console.log(deviceTotal, "deviceTotal");
+
// 更新状态管理(token会自动存储到localStorage,用户信息存储在状态管理中)
- login(response.token, response.member);
+ login(response.token, response.member, deviceTotal);
Toast.show({ content: "登录成功", position: "top" });
- // 检查设备绑定状态并更新到store
- try {
- const deviceNum = await updateDeviceCount(setDeviceCount);
- console.log(deviceNum, "deviceNum");
-
- // 如果没有绑定设备,跳转到引导页面
- if (deviceNum === 0) {
- navigate("/guide");
- return;
- }
- } catch (error) {
- console.error("检查设备状态失败:", error);
- // 如果检查失败,设置设备数量为0并跳转到guide页面
- setDeviceCount(0);
- navigate("/guide");
- return;
- }
-
- // 跳转到首页或重定向URL
- const returnUrl = searchParams.get("returnUrl");
- if (returnUrl) {
- const decodedUrl = decodeURIComponent(returnUrl);
- if (isLoginPage(decodedUrl)) {
- navigate("/");
+ // 根据设备数量判断跳转
+ if (deviceTotal > 0) {
+ // 有设备,跳转到首页或重定向URL
+ const returnUrl = searchParams.get("returnUrl");
+ if (returnUrl) {
+ const decodedUrl = decodeURIComponent(returnUrl);
+ if (isLoginPage(decodedUrl)) {
+ navigate("/");
+ } else {
+ window.location.href = decodedUrl;
+ }
} else {
- window.location.href = decodedUrl;
+ navigate("/");
}
} else {
- navigate("/");
+ // 没有设备,跳转到引导页面
+ navigate("/guide");
}
} catch (error: any) {
// 错误已在request中处理,这里不需要额外处理
diff --git a/nkebao/src/router/index.tsx b/nkebao/src/router/index.tsx
index 7ff448cc..117681a7 100644
--- a/nkebao/src/router/index.tsx
+++ b/nkebao/src/router/index.tsx
@@ -1,7 +1,6 @@
import React from "react";
import { BrowserRouter, useRoutes, RouteObject } from "react-router-dom";
import PermissionRoute from "./permissionRoute";
-import DeviceGuard from "@/components/DeviceGuard";
// 动态导入所有 module 下的 ts/tsx 路由模块
const modules = import.meta.glob("./module/*.{ts,tsx}", { eager: true });
@@ -43,9 +42,7 @@ const AppRouter: React.FC = () => (
v7_relativeSplatPath: true,
}}
>
-
-
-
+
);
diff --git a/nkebao/src/store/index.ts b/nkebao/src/store/index.ts
index c74f8ad2..4eca24e3 100644
--- a/nkebao/src/store/index.ts
+++ b/nkebao/src/store/index.ts
@@ -1,3 +1,2 @@
export * from "./module/user";
-export * from "./module/device";
// 未来可继续合并其他模块
diff --git a/nkebao/src/store/module/device.ts b/nkebao/src/store/module/device.ts
deleted file mode 100644
index 53477263..00000000
--- a/nkebao/src/store/module/device.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { createPersistStore } from "@/store/createPersistStore";
-
-export interface DeviceState {
- deviceCount: number;
- setDeviceCount: (count: number) => void;
- updateDeviceCount: () => Promise;
- resetDeviceCount: () => void;
-}
-
-export const useDeviceStore = createPersistStore(
- (set, get) => ({
- deviceCount: 0,
- setDeviceCount: (count: number) => set({ deviceCount: count }),
- updateDeviceCount: async () => {
- try {
- // 这里需要导入getDashboard,但为了避免循环依赖,我们通过参数传入
- // 实际使用时会在组件中调用并传入API函数
- set({ deviceCount: 0 }); // 默认设置为0,实际值由调用方设置
- } catch (error) {
- console.error("更新设备数量失败:", error);
- set({ deviceCount: 0 });
- }
- },
- resetDeviceCount: () => set({ deviceCount: 0 }),
- }),
- "device-store",
- state => ({
- deviceCount: state.deviceCount,
- }),
-);
diff --git a/nkebao/src/store/module/user.ts b/nkebao/src/store/module/user.ts
index a26c3e58..bee4f4c6 100644
--- a/nkebao/src/store/module/user.ts
+++ b/nkebao/src/store/module/user.ts
@@ -15,6 +15,7 @@ export interface User {
updateTime: string | null;
lastLoginIp: string;
lastLoginTime: number;
+ deviceTotal: number; // 设备总数
}
interface UserState {
@@ -24,7 +25,7 @@ interface UserState {
setUser: (user: User) => void;
setToken: (token: string) => void;
clearUser: () => void;
- login: (token: string, userInfo: User) => void;
+ login: (token: string, userInfo: User, deviceTotal: number) => void;
logout: () => void;
}
@@ -36,7 +37,7 @@ export const useUserStore = createPersistStore(
setUser: user => set({ user, isLoggedIn: true }),
setToken: token => set({ token }),
clearUser: () => set({ user: null, token: null, isLoggedIn: false }),
- login: (token, userInfo) => {
+ login: (token, userInfo, deviceTotal) => {
// 只将token存储到localStorage
localStorage.setItem("token", token);
@@ -56,6 +57,7 @@ export const useUserStore = createPersistStore(
updateTime: userInfo.updateTime,
lastLoginIp: userInfo.lastLoginIp,
lastLoginTime: userInfo.lastLoginTime,
+ deviceTotal: deviceTotal,
};
set({ user, token, isLoggedIn: true });
},
diff --git a/nkebao/src/utils/device.ts b/nkebao/src/utils/device.ts
deleted file mode 100644
index 8b5c5b8c..00000000
--- a/nkebao/src/utils/device.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { getDashboard } from "@/pages/mobile/home/api";
-
-/**
- * 更新设备数量到store
- * @param setDeviceCount store中的setDeviceCount函数
- * @returns 更新后的设备数量
- */
-export const updateDeviceCount = async (
- setDeviceCount: (count: number) => void,
-): Promise => {
- try {
- const dashboardData = await getDashboard();
- const deviceCount = dashboardData?.deviceNum || 0;
- setDeviceCount(deviceCount);
- return deviceCount;
- } catch (error) {
- console.error("更新设备数量失败:", error);
- setDeviceCount(0);
- return 0;
- }
-};
-
-/**
- * 检查是否需要设备绑定
- * @param deviceCount 设备数量
- * @returns 是否需要设备绑定
- */
-export const needsDeviceBinding = (deviceCount: number): boolean => {
- return deviceCount === 0;
-};