diff --git a/src/api/apiClient.ts b/src/api/apiClient.ts index 603524c..05e3a9e 100644 --- a/src/api/apiClient.ts +++ b/src/api/apiClient.ts @@ -1,20 +1,15 @@ import type { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"; -import type { ResultData } from "#/api"; +import type { ResultData } from "./types"; import axios from "axios"; import { toast } from "sonner"; import { t } from "@/locales/i18n"; import userStore from "@/store/userStore"; - import { isProd } from "@/utils"; -// import { useRouter } from '@/router/hooks'; -// import { ResultEnum } from '#/enum'; -// const router = useRouter(); const { VITE_API_PROD_BASE_URL, VITE_API_VERSIONS, VITE_PORT, VITE_API_DEV_BASE_URL } = import.meta .env as ImportMetaEnv; -// const isProd = MODE === "production"; const baseURL = isProd() ? `${VITE_API_PROD_BASE_URL}${VITE_API_VERSIONS}` : `${VITE_API_DEV_BASE_URL}:${VITE_PORT}${VITE_API_VERSIONS}`; @@ -38,9 +33,8 @@ axiosInstance.interceptors.request.use( (error) => { // 请求错误时做些什么 console.log("请求拦截器 erro:", error); - // return Promise.reject(error); - const { response } = error || {}; - const errMsg = (response?.data as ResultData)?.message || t("sys.api.errorMessage"); + const { response } = error ?? {}; + const errMsg = (response?.data as ResultData)?.message ?? t("sys.api.errorMessage"); toast.error(errMsg, { position: "top-center", @@ -61,7 +55,7 @@ axiosInstance.interceptors.response.use( const { code, data, message } = res.data; // 错误处理 if (code !== 200) { - toast.error(message || t("sys.api.apiRequestFailed"), { + toast.error(message ?? t("sys.api.apiRequestFailed"), { position: "top-center", }); // token 无效 或者 过期 @@ -69,15 +63,15 @@ axiosInstance.interceptors.response.use( userStore.getState().actions.clearUserInfoAndToken(); window.location.href = "/#/login"; } - throw new Error(message || t("sys.api.apiRequestFailed")); + throw new Error(message ?? t("sys.api.apiRequestFailed")); } return data; }, (error: AxiosError) => { console.log("响应拦截器 error:", error); - const { response } = error || {}; - const errMsg = (response?.data as ResultData)?.message || t("sys.api.errorMessage"); + const { response } = error ?? {}; + const errMsg = (response?.data as ResultData)?.message ?? t("sys.api.errorMessage"); toast.error(errMsg, { position: "top-center", diff --git a/src/api/types.ts b/src/api/types.ts index 79d91dd..8a66adc 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -11,20 +11,6 @@ export interface ResultData extends Result { data?: T; } -// * 分页响应参数 -export interface ResPage { - datalist: T[]; - pageNum: number; - pageSize: number; - total: number; -} - -// * 分页请求参数 -export interface ReqPage { - pageNum: number; - pageSize: number; -} - // 定义一个接口来描述 data 的结构 export interface ResponseData { code: number; @@ -82,10 +68,6 @@ export interface UserListResponse { pageSize: number; } -export interface ResAuthButtons { - [propName: string]: any; -} - export interface MenuOptions { id?: number; parentId: number | null; diff --git a/src/layouts/dashboard/header.tsx b/src/layouts/dashboard/header/index.tsx similarity index 87% rename from src/layouts/dashboard/header.tsx rename to src/layouts/dashboard/header/index.tsx index 93427c3..8ff85e0 100644 --- a/src/layouts/dashboard/header.tsx +++ b/src/layouts/dashboard/header/index.tsx @@ -8,18 +8,18 @@ import weathersService from "@/api/services/weathersService"; import { IconButton, Iconify, SvgIcon } from "@/components/icon"; import LocalePicker from "@/components/locale-picker"; import Logo from "@/components/logo"; +import AccountDropdown from "@/layouts/components/account-dropdown"; +import BreadCrumb from "@/layouts/components/bread-crumb"; +import NoticeButton from "@/layouts/components/notice"; +import SearchBar from "@/layouts/components/search-bar"; +import SettingButton from "@/layouts/components/setting-button"; +import { HEADER_HEIGHT, NAV_COLLAPSED_WIDTH, NAV_WIDTH } from "@/layouts/dashboard/config"; +import NavVertical from "@/layouts/dashboard/nav/nav-vertical"; import { useSettings } from "@/store/settingStore"; import { themeVars } from "@/theme/theme.css"; import { cn } from "@/utils"; import { rgbAlpha } from "@/utils/theme"; import { ThemeLayout } from "#/enum"; -import AccountDropdown from "../components/account-dropdown"; -import BreadCrumb from "../components/bread-crumb"; -import NoticeButton from "../components/notice"; -import SearchBar from "../components/search-bar"; -import SettingButton from "../components/setting-button"; -import { HEADER_HEIGHT, NAV_COLLAPSED_WIDTH, NAV_WIDTH } from "./config"; -import NavVertical from "./nav/nav-vertical"; export default function Header() { const [drawerOpen, setDrawerOpen] = useState(false); diff --git a/src/layouts/dashboard/main.tsx b/src/layouts/dashboard/main/index.tsx similarity index 87% rename from src/layouts/dashboard/main.tsx rename to src/layouts/dashboard/main/index.tsx index de880c9..6564351 100644 --- a/src/layouts/dashboard/main.tsx +++ b/src/layouts/dashboard/main/index.tsx @@ -7,9 +7,9 @@ import { useSettings } from "@/store/settingStore"; import { themeVars } from "@/theme/theme.css"; import { cn } from "@/utils"; import { ThemeLayout } from "#/enum"; -import { MULTI_TABS_HEIGHT } from "./config"; -import MultiTabs from "./multi-tabs"; -import { MultiTabsProvider } from "./multi-tabs/providers/multi-tabs-provider"; +import { MULTI_TABS_HEIGHT } from "../config"; +import MultiTabs from "../multi-tabs"; +import { MultiTabsProvider } from "../multi-tabs/providers/multi-tabs-provider"; const Main = () => { const { Content } = Layout; const { themeStretch, themeLayout, multiTab } = useSettings(); diff --git a/src/locales/lang/en_US/sys.json b/src/locales/lang/en_US/sys.json index 1fdb314..4b17be8 100644 --- a/src/locales/lang/en_US/sys.json +++ b/src/locales/lang/en_US/sys.json @@ -135,7 +135,7 @@ } } }, - "disabled": "Item Disabled", + "disabled": "Menu Disabled", "label": "Item Label", "frame": "Item External", "external_link": "External Link", diff --git a/src/locales/lang/zh_CN/sys.json b/src/locales/lang/zh_CN/sys.json index 86d5147..10e5293 100644 --- a/src/locales/lang/zh_CN/sys.json +++ b/src/locales/lang/zh_CN/sys.json @@ -87,7 +87,7 @@ "clipboard": "剪贴板", "components": "组件", "dashboard": "仪表", - "disabled": "项目禁用", + "disabled": "菜单禁用", "editor": "富文本", "error": { "403": "403", diff --git a/src/pages/management/system/role/role-modal.tsx b/src/pages/management/system/role/role-modal.tsx index 721821e..4d44ee7 100644 --- a/src/pages/management/system/role/role-modal.tsx +++ b/src/pages/management/system/role/role-modal.tsx @@ -103,7 +103,7 @@ export const RoleModal = forwardRef(function RoleM } return ( - +
{ - // console.log("check token", token); - // const timer = setTimeout(() => { - // if (!token) { - // toast.info(t("common.reLogin") || "login success!", { - // position: "top-center", - // }); - // router.replace("/login"); - // } - // }, 200); - - // return () => clearTimeout(timer); - // }, [router, token]); - - if (!token) { - // 直接跳转,无需延迟 - return ; - } - - return ( - { - console.error("ErrorBoundary 捕获的错误:", error, info); - }} - > - {children} - - ); -} diff --git a/src/router/index.tsx b/src/router/index.tsx index 320fd71..ade7358 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -8,8 +8,8 @@ import { RouterProvider } from "react-router/dom"; import DashboardLayout from "@/layouts/dashboard"; import PageError from "@/pages/sys/error/PageError"; import Login from "@/pages/sys/login/Login"; -import ProtectedRoute from "@/router/components/protected-route"; import { usePermissionRoutes } from "@/router/hooks"; +import ProtectedRoute from "@/router/protected-route"; import { ERROR_ROUTE } from "@/router/routes/error-routes"; const { VITE_APP_HOMEPAGE: HOMEPAGE } = import.meta.env; diff --git a/src/router/protected-route.tsx b/src/router/protected-route.tsx new file mode 100644 index 0000000..02b31a4 --- /dev/null +++ b/src/router/protected-route.tsx @@ -0,0 +1,27 @@ +import { ErrorBoundary } from "react-error-boundary"; +import { Navigate } from "react-router"; + +import PageError from "@/pages/sys/error/PageError"; +import { useUserToken } from "@/store/userStore"; + +type Props = { + children: React.ReactNode; +}; + +export default function ProtectedRoute({ children }: Props) { + const token = useUserToken(); + if (!token) { + return ; + } + + return ( + { + console.error("ErrorBoundary 捕获的错误:", error, info); + }} + > + {children} + + ); +} diff --git a/src/router/routes/error-routes.tsx b/src/router/routes/error-routes.tsx index 0921a01..5bea453 100644 --- a/src/router/routes/error-routes.tsx +++ b/src/router/routes/error-routes.tsx @@ -6,7 +6,7 @@ import { Outlet } from "react-router"; import { CircleLoading } from "@/components/loading"; import SimpleLayout from "@/layouts/simple"; -import ProtectedRoute from "../components/protected-route"; +import ProtectedRoute from "@/router/protected-route"; const Page403 = lazy(() => import("@/pages/sys/error/Page403")); const Page404 = lazy(() => import("@/pages/sys/error/Page404")); diff --git a/src/store/userStore.ts b/src/store/userStore.ts index 879fcb0..1b41ffd 100644 --- a/src/store/userStore.ts +++ b/src/store/userStore.ts @@ -1,7 +1,6 @@ import type { LoginParams, MenuOptions, UserInfoType } from "@/api/types"; import { useMutation } from "@tanstack/react-query"; -// import { useNavigate } from 'react-router'; import { toast } from "sonner"; import { create } from "zustand"; import { createJSONStorage, persist } from "zustand/middleware"; @@ -10,7 +9,6 @@ import roleService from "@/api/services/roleService"; import userService from "@/api/services/userService"; import { t } from "@/locales/i18n"; import { StorageEnum } from "#/enum"; -// const { VITE_APP_HOMEPAGE: HOMEPAGE } = import.meta.env; type UserStore = { userInfo: Partial; @@ -65,7 +63,6 @@ export const useUserActions = () => useUserStore((state) => state.actions); * @description 登录 */ export const useLogin = () => { - // const navigatge = useNavigate(); const { setUserToken, setUserInfo } = useUserActions(); const loginMutation = useMutation({ mutationFn: userService.login, @@ -80,7 +77,6 @@ export const useLogin = () => { position: "top-center", }); return res; - // navigatge(HOMEPAGE, { replace: true }); } catch (err) { throw new Error(err ?? t("sys.api.apiRequestFailed")); } @@ -91,27 +87,6 @@ export const useLogin = () => { /** * @description 获取菜单列表 */ -// export const useMenus = () => { -// const { setUserMenus } = useUserActions(); -// // const navigate = useNavigate(); - -// const getMenusMutation = useMutation({ -// mutationFn: userService.getMenus, -// }); -// const getMenus = async () => { -// try { -// const data = await getMenusMutation.mutateAsync(); -// if (data) { -// setUserMenus(data); -// } -// // navigate(HOMEPAGE, { replace: true }); -// } catch (err) { -// throw new Error(err || t("sys.api.apiRequestFailed")); -// } -// }; -// return getMenus; -// }; - export const useMenus = () => { const { setUserMenus } = useUserActions(); const getMenus = async (roleId: number) => { diff --git a/types/api.ts b/types/api.ts deleted file mode 100644 index 909f507..0000000 --- a/types/api.ts +++ /dev/null @@ -1,86 +0,0 @@ -// export interface Result { -// status?: number; -// message: string; -// data: T; -// code: number; -// } - -// * 请求响应参数(不包含data) -export interface Result { - code: number; - message: string; - status?: boolean; -} - -// * 请求响应参数(包含data) -export interface ResultData extends Result { - data?: T; -} - -// * 分页响应参数 -export interface ResPage { - datalist: T[]; - pageNum: number; - pageSize: number; - total: number; -} - -// * 分页请求参数 -export interface ReqPage { - pageNum: number; - pageSize: number; -} - -// 定义一个接口来描述 data 的结构 -export interface ResponseData { - code: number; - message: string; - data: T; - status?: boolean; -} - -export interface UserInfoType { - id?: string; - username: string; - password?: string; - create_time: string; - update_time: string; - email: string; - mobile: string; - role: string; - role_name: string; - avatar: string; - nickName: string; - status: boolean; -} - -// * 登录 -export namespace Login { - export interface LoginParams { - username: string; - password: string; - } - export interface LoginResponse { - token: string; - userInfo: UserInfoType; - } - export interface ResAuthButtons { - [propName: string]: any; - } -} - -export namespace Weathers { - export interface WeathersResponseType { - province: string; - city: string; - adcode: string; - weather: string; - temperature: string; - winddirection: string; - windpower: string; - humidity: string; - reporttime: string; - temperature_float: string; - humidity_float: string; - } -}