From f20951fb9277f80016b0e4dc7ad83c93a29ab70f Mon Sep 17 00:00:00 2001
From: gaoziman <2942894660@qq.com>
Date: Tue, 18 Nov 2025 20:46:40 +0800
Subject: [PATCH] =?UTF-8?q?refactor(=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86):?=
=?UTF-8?q?=20=E8=BF=81=E7=A7=BB=E5=88=B0=20Zustand=20=E5=B9=B6=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=E5=B8=83=E5=B1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 Zustand 用户状态管理(userStore.ts)
- 集成 persist 中间件实现自动持久化
- 简化 layout.tsx 用户状态管理逻辑
- 更新 Redux store 配置
- 优化主入口和国际化配置
---
src/layout.tsx | 172 +++++++++++++++++++++++++++++++++++------
src/locale/index.ts | 2 +
src/main.tsx | 16 +++-
src/store/index.ts | 7 ++
src/store/userStore.ts | 91 ++++++++++++++++++++++
5 files changed, 264 insertions(+), 24 deletions(-)
create mode 100644 src/store/userStore.ts
diff --git a/src/layout.tsx b/src/layout.tsx
index 7f9dfcb..2208909 100644
--- a/src/layout.tsx
+++ b/src/layout.tsx
@@ -1,11 +1,15 @@
import React, { useState, useMemo, useRef, useEffect } from 'react';
import { Switch, Route, Redirect, useHistory } from 'react-router-dom';
-import { Layout, Menu, Breadcrumb, Spin } from '@arco-design/web-react';
+import { Layout, Menu, Spin, Button } from '@arco-design/web-react';
import cs from 'classnames';
import {
IconUser,
IconMenuFold,
IconMenuUnfold,
+ IconApps,
+ IconHome,
+ IconRefresh,
+ IconQuestionCircle,
} from '@arco-design/web-react/icon';
import { useSelector, useDispatch } from 'react-redux';
import qs from 'query-string';
@@ -19,7 +23,9 @@ import useLocale from './utils/useLocale';
import getUrlParams from './utils/getUrlParams';
import lazyload from './utils/lazyload';
import { GlobalState } from './store';
+import { useUserStore } from './store/userStore';
import { TabItem } from './types/tabs';
+import { getUserInfo as fetchUserInfoAPI } from '@/api/auth';
import styles from './style/layout.module.less';
const MenuItem = Menu.Item;
@@ -28,6 +34,21 @@ const SubMenu = Menu.SubMenu;
const Sider = Layout.Sider;
const Content = Layout.Content;
+function findRouteByKey(key: string, routeList: IRoute[] = []): IRoute | null {
+ for (const route of routeList) {
+ if (route.key === key) {
+ return route;
+ }
+ if (route.children?.length) {
+ const child = findRouteByKey(key, route.children);
+ if (child) {
+ return child;
+ }
+ }
+ }
+ return null;
+}
+
// 简单的404页面组件
function NotFound() {
return (
@@ -54,7 +75,7 @@ function getIconFromKey(key) {
case 'user-management':
return ;
default:
- return
;
+ return ;
}
}
@@ -92,22 +113,65 @@ function PageLayout() {
const pathname = history.location.pathname;
const currentComponent = qs.parseUrl(pathname).url.slice(1);
const locale = useLocale();
- const { settings, userLoading, userInfo } = useSelector(
- (state: GlobalState) => state
- );
+
+ // 从 Redux 获取 settings 和 tabs
+ const { settings } = useSelector((state: GlobalState) => state);
+
+ // 从 Zustand 获取用户信息
+ const { userInfo, userLoading, setUserInfo, updateUserInfo, setUserLoading } =
+ useUserStore();
const [routes, defaultRoute] = useRoute(userInfo?.permissions);
const defaultSelectedKeys = [currentComponent || defaultRoute];
const paths = (currentComponent || defaultRoute).split('/');
const defaultOpenKeys = paths.slice(0, paths.length - 1);
- const [breadcrumb, setBreadCrumb] = useState([]);
+ const [breadcrumb, setBreadCrumb] = useState([]);
const [collapsed, setCollapsed] = useState(false);
const [selectedKeys, setSelectedKeys] =
useState(defaultSelectedKeys);
const [openKeys, setOpenKeys] = useState(defaultOpenKeys);
- const routeMap = useRef