refactor(store): 重构store模块,分离全局设置与用户信息,修改项目中的使用方法

master
钟良源 5 months ago
parent 8f2980f07f
commit 053449121b

@ -11,7 +11,6 @@ import {
IconLoading
} from '@arco-design/web-react/icon';
import { useSelector, useDispatch } from 'react-redux';
import { GlobalState } from '@/store';
import { GlobalContext } from '@/context';
import useLocale from '@/utils/useLocale';
import Settings from '../Settings';
@ -20,12 +19,12 @@ import useStorage from '@/utils/useStorage';
import { generatePermission } from '@/routes';
import logoImage from '@/public/assets/logo.png';
import useUser from '@/hooks/user';
import { updateUserInfo } from '@/store';
import { updateUserInfo } from '@/store/user';
function Navbar({ show }: { show: boolean }) {
const t = useLocale();
const { logoutHooks } = useUser();
const { userInfo, userLoading } = useSelector((state: GlobalState) => state);
const { userInfo, userLoading } = useSelector((state) => state.user);
const dispatch = useDispatch();
const [_, setUserStatus] = useStorage('userStatus');

@ -1,5 +1,4 @@
import React, { useMemo } from 'react';
import { GlobalState } from '@/store';
import { useSelector } from 'react-redux';
import authentication, { AuthParams } from '@/utils/authentication';
@ -11,7 +10,7 @@ const PermissionWrapper = (
props: React.PropsWithChildren<PermissionWrapperProps>
) => {
const { backup, requiredPermissions, oneOfPerm } = props;
const userInfo = useSelector((state: GlobalState) => state.userInfo);
const userInfo = useSelector((state) => state.user);
const hasPermission = useMemo(() => {
return authentication(

@ -1,10 +1,9 @@
import React, { ReactNode } from 'react';
import { Switch, Divider, InputNumber } from '@arco-design/web-react';
import { useSelector, useDispatch } from 'react-redux';
import { GlobalState } from '../../store';
import useLocale from '../../utils/useLocale';
import styles from './style/block.module.less';
import { updateSettings } from '@/store';
import { updateSettings } from '@/store/global';
export interface BlockProps {
title?: ReactNode;
@ -15,7 +14,7 @@ export interface BlockProps {
export default function Block(props: BlockProps) {
const { title, options, children } = props;
const locale = useLocale();
const settings = useSelector((state: GlobalState) => state.settings);
const settings = useSelector((state) => state.global);
const dispatch = useDispatch();
return (

@ -3,15 +3,14 @@ import { Trigger, Typography } from '@arco-design/web-react';
import { SketchPicker } from 'react-color';
import { generate, getRgbStr } from '@arco-design/color';
import { useSelector, useDispatch } from 'react-redux';
import { GlobalState } from '../../store';
import useLocale from '@/utils/useLocale';
import styles from './style/color-panel.module.less';
import { updateSettings } from '@/store';
import { updateSettings } from '@/store/global';
function ColorPanel() {
const theme =
document.querySelector('body').getAttribute('arco-theme') || 'light';
const settings = useSelector((state: GlobalState) => state.settings);
const settings = useSelector((state) => state.global);
const locale = useLocale();
const themeColor = settings.themeColor;
const list = generate(themeColor, { list: true });

@ -3,7 +3,6 @@ import { Drawer, Alert, Message } from '@arco-design/web-react';
import { IconSettings } from '@arco-design/web-react/icon';
import copy from 'copy-to-clipboard';
import { useSelector } from 'react-redux';
import { GlobalState } from '../../store';
import Block from './block';
import ColorPanel from './color';
import IconButton from '../NavBar/IconButton';
@ -17,7 +16,7 @@ function Setting(props: SettingProps) {
const { trigger } = props;
const [visible, setVisible] = useState(false);
const locale = useLocale();
const settings = useSelector((state: GlobalState) => state.settings);
const settings = useSelector((state) => state.global);
function onCopySettings() {
copy(JSON.stringify(settings, null, 2));

@ -18,8 +18,8 @@ import Layout from './layout';
import '../mock';
import { getUserInfo } from '@/api/user';
import { setSessionUserInfo } from '@/utils/auth';
import store from '@/store'; // 只导入 store
import { updateUserInfo } from '@/store'; // 导入 action
import store from '@/store';
import { updateUserInfo } from '@/store/user';
interface RenderConfig {

@ -21,7 +21,6 @@ import Navbar from '../components/NavBar';
import Footer from '../components/Footer';
import useRoute, { IRoute } from '@/routes';
import useLocale from '@/utils/useLocale';
import { GlobalState } from '@/store';
import getUrlParams from '@/utils/getUrlParams';
import styles from '@/style/layout.module.less';
import NoAccess from '@/pages/exception/403';
@ -62,9 +61,8 @@ function PageLayout({ children }: { children: ReactNode }) {
const pathname = router.pathname;
const currentComponent = qs.parseUrl(pathname).url.slice(1);
const locale = useLocale();
const { userInfo, settings, userLoading } = useSelector(
(state: GlobalState) => state
);
const { settings } = useSelector((state) => state.global);
const { userInfo, userLoading } = useSelector((state) => state.user);
const [collapsed, setCollapsed] = useState<boolean>(false);

@ -3,7 +3,6 @@ import styles from './style/cardWrap.module.less';
import { getImageUrl } from '@/utils/pubUse';
import { Image, Popconfirm } from '@arco-design/web-react';
import { IconEdit, IconDelete } from '@arco-design/web-react/icon';
import { GlobalState } from '@/store';
import { useSelector, useDispatch } from 'react-redux';
interface CardWrapProps {
@ -14,7 +13,7 @@ interface CardWrapProps {
}
const CardWrap: React.FC<CardWrapProps> = ({ item, onEdit, onDelete, onClick }) => {
const { userInfo, userLoading } = useSelector((state: GlobalState) => state);
const { userInfo, userLoading } = useSelector((state) => state.user);
const handleEdit = (e: React.MouseEvent) => {
e.stopPropagation();
if (onEdit) {
@ -58,7 +57,7 @@ const CardWrap: React.FC<CardWrapProps> = ({ item, onEdit, onDelete, onClick })
className={styles['avatar']}
width={25}
preview={false}
src={userInfo.avatar}
src={userInfo?.avatar}
/>
<span>{item.createUser}</span>
</div>

@ -0,0 +1,25 @@
import { createSlice } from '@reduxjs/toolkit';
import defaultSettings from '../settings.json';
export interface GlobalState {
settings?: typeof defaultSettings;
}
const initialState: GlobalState = {
settings: defaultSettings
};
const globalSlice = createSlice({
name: 'global',
initialState,
reducers: {
updateSettings(state, action) {
state.settings = action.payload.settings;
}
}
});
export const { updateSettings } = globalSlice.actions;
export default globalSlice.reducer;

@ -1,47 +1,13 @@
import { createSlice, configureStore } from '@reduxjs/toolkit';
import defaultSettings from '../settings.json';
export interface GlobalState {
settings?: typeof defaultSettings;
userInfo?: {
name?: string;
avatar?: string;
job?: string;
organization?: string;
location?: string;
email?: string;
permissions: Record<string, string[]>;
};
userLoading?: boolean;
}
const initialState: GlobalState = {
settings: defaultSettings,
userInfo: {
permissions: {}
}
};
const globalSlice = createSlice({
name: 'global',
initialState,
reducers: {
updateSettings(state, action) {
state.settings = action.payload.settings;
},
updateUserInfo(state, action) {
state.userInfo = action.payload.userInfo || initialState.userInfo;
state.userLoading = action.payload.userLoading;
}
}
});
// 保持与原来相同的 action creators 导出方式
export const { updateSettings, updateUserInfo } = globalSlice.actions;
import { configureStore } from '@reduxjs/toolkit';
import globalReducer from './global';
import userReducer from './user';
// 创建 store
const store = configureStore({
reducer: globalSlice.reducer
reducer: {
global: globalReducer,
user: userReducer
}
});
export type RootState = ReturnType<typeof store.getState>;

@ -0,0 +1,36 @@
import { createSlice } from '@reduxjs/toolkit';
export interface UserState {
userInfo?: {
name?: string;
avatar?: string;
job?: string;
organization?: string;
location?: string;
email?: string;
permissions: Record<string, string[]>;
};
userLoading?: boolean;
}
const initialState: UserState = {
userInfo: {
permissions: {}
},
userLoading: false
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
updateUserInfo(state, action) {
state.userInfo = action.payload.userInfo || initialState.userInfo;
state.userLoading = action.payload.userLoading;
}
}
});
export const { updateUserInfo } = userSlice.actions;
export default userSlice.reducer;
Loading…
Cancel
Save