diff --git a/src/components/NavBar/index.tsx b/src/components/NavBar/index.tsx index e687ae7..40d8615 100644 --- a/src/components/NavBar/index.tsx +++ b/src/components/NavBar/index.tsx @@ -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'); diff --git a/src/components/PermissionWrapper/index.tsx b/src/components/PermissionWrapper/index.tsx index a9edbae..6aa0c38 100644 --- a/src/components/PermissionWrapper/index.tsx +++ b/src/components/PermissionWrapper/index.tsx @@ -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 ) => { const { backup, requiredPermissions, oneOfPerm } = props; - const userInfo = useSelector((state: GlobalState) => state.userInfo); + const userInfo = useSelector((state) => state.user); const hasPermission = useMemo(() => { return authentication( diff --git a/src/components/Settings/block.tsx b/src/components/Settings/block.tsx index 17955f1..1f8b9e9 100644 --- a/src/components/Settings/block.tsx +++ b/src/components/Settings/block.tsx @@ -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 ( diff --git a/src/components/Settings/color.tsx b/src/components/Settings/color.tsx index 4aaaedc..d16b225 100644 --- a/src/components/Settings/color.tsx +++ b/src/components/Settings/color.tsx @@ -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 }); diff --git a/src/components/Settings/index.tsx b/src/components/Settings/index.tsx index 17628c1..1d91211 100644 --- a/src/components/Settings/index.tsx +++ b/src/components/Settings/index.tsx @@ -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)); diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 08fe5f9..a05d996 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -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 { diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx index 7db0797..28204ed 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -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(false); diff --git a/src/pages/scene/cardWrap.tsx b/src/pages/scene/cardWrap.tsx index 7dfbdb2..f9bb3af 100644 --- a/src/pages/scene/cardWrap.tsx +++ b/src/pages/scene/cardWrap.tsx @@ -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 = ({ 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 = ({ item, onEdit, onDelete, onClick }) className={styles['avatar']} width={25} preview={false} - src={userInfo.avatar} + src={userInfo?.avatar} /> {item.createUser} diff --git a/src/store/global.ts b/src/store/global.ts new file mode 100644 index 0000000..3a0a085 --- /dev/null +++ b/src/store/global.ts @@ -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; + diff --git a/src/store/index.ts b/src/store/index.ts index 925cc62..2cf52a5 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -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; - }; - 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; diff --git a/src/store/user.ts b/src/store/user.ts new file mode 100644 index 0000000..849b4ba --- /dev/null +++ b/src/store/user.ts @@ -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; + }; + 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;