diff --git a/examples/antdp-base/.eslintrc.js b/examples/antdp-base/.eslintrc.js index d26d222ce..1dac7d516 100755 --- a/examples/antdp-base/.eslintrc.js +++ b/examples/antdp-base/.eslintrc.js @@ -5,6 +5,7 @@ module.exports = { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true, page: true, REACT_APP_ENV: true, + ANTD_IS_STORAGE: true, }, plugins: ['prettier'], rules: { diff --git a/examples/antdp-base/config/config.js b/examples/antdp-base/config/config.js index c5f0f9c22..850cf28dd 100644 --- a/examples/antdp-base/config/config.js +++ b/examples/antdp-base/config/config.js @@ -13,6 +13,8 @@ export default config(router, { ANTD_IS_TABS: true, // 是否展示面包屑 ANTD_IS_BREADCRUMB: false, + // 默认 sessionStorage 存储,如果需要使用 localStorage 存储,设置为 `false` + // ANTD_IS_STORAGE: false, ANTD_AUTH_CONF: { auth_menu: 'authMenu', auth_btn: 'authBtn', diff --git a/examples/antdp-base/package.json b/examples/antdp-base/package.json index e3e2970ed..2fdeba72c 100644 --- a/examples/antdp-base/package.json +++ b/examples/antdp-base/package.json @@ -17,10 +17,10 @@ }, "dependencies": { "@ant-design/pro-components": "^2.4.14", - "@antdp/authorized": "2.0.21", - "@antdp/basic-layouts": "2.0.21", - "@antdp/hooks": "2.0.21", - "@antdp/request": "2.0.21", + "@antdp/authorized": "2.0.24", + "@antdp/basic-layouts": "2.0.24", + "@antdp/hooks": "2.0.24", + "@antdp/request": "2.0.24", "ahooks": "~3.7.2", "antd": "5.6.1", "react": "^18.2.0", @@ -35,15 +35,15 @@ "antd": "5.6.1" }, "devDependencies": { - "@antdp/config": "2.0.21", - "@antdp/dependencies": "2.0.21", + "@antdp/config": "2.0.24", + "@antdp/dependencies": "2.0.24", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", - "@umijs/fabric": "~2.14.1", + "@umijs/fabric": "~3.0.0", "@umijs/max": "~4.0.47", "@umijs/plugin-model": "~2.6.2", "eslint-plugin-jest": "^27.2.1", - "eslint-plugin-prettier": "~4.2.1", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-unicorn": "^47.0.0", "husky": "~8.0.3", "lint-staged": "~13.2.2" diff --git a/examples/antdp-base/src/layouts/BasicLayout.jsx b/examples/antdp-base/src/layouts/BasicLayout.jsx index 4a42ac4f4..36bc001aa 100644 --- a/examples/antdp-base/src/layouts/BasicLayout.jsx +++ b/examples/antdp-base/src/layouts/BasicLayout.jsx @@ -99,9 +99,10 @@ const Layout = () => { title: '退出登录', icon: , onClick: async () => { - await sessionStorage.removeItem('token'); - await sessionStorage.removeItem('refresh_token'); - await sessionStorage.removeItem('userDate'); + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + await store.removeItem('token'); + await store.removeItem('refresh_token'); + await store.removeItem('userDate'); update({ token: '' }); history.push('/login'); }, diff --git a/examples/antdp-base/src/layouts/UserLayout.jsx b/examples/antdp-base/src/layouts/UserLayout.jsx index 5d54631de..d85acf0a7 100644 --- a/examples/antdp-base/src/layouts/UserLayout.jsx +++ b/examples/antdp-base/src/layouts/UserLayout.jsx @@ -47,9 +47,10 @@ const UserLayout = () => { url: '/api/users/login', onSuccess: async ({ code, data, token }) => { if (code === 1) { - await sessionStorage.setItem('token', token); - await sessionStorage.setItem('authBtn', JSON.stringify(data.btns)); - await sessionStorage.setItem('authMenu', JSON.stringify(data.menus)); + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + await store.setItem('token', token); + await store.setItem('authBtn', JSON.stringify(data.btns)); + await store.setItem('authMenu', JSON.stringify(data.menus)); update({ token: token }); history.push('/'); } diff --git a/examples/antdp-base/src/models/user.js b/examples/antdp-base/src/models/user.js index 48ece4468..94b180706 100644 --- a/examples/antdp-base/src/models/user.js +++ b/examples/antdp-base/src/models/user.js @@ -1,4 +1,7 @@ -const getToken = () => sessionStorage.getItem('token'); +const getToken = () => { + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + return store.getItem('token'); +}; export default { namespace: 'user', state: { diff --git a/examples/website/.dumi/tsconfig.json b/examples/website/.dumi/tsconfig.json new file mode 100644 index 000000000..a32dd4f23 --- /dev/null +++ b/examples/website/.dumi/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "include": ["**/*"] +} diff --git a/examples/website/docs/guide/config.md b/examples/website/docs/guide/config.md index b4e2791c5..b360a319a 100644 --- a/examples/website/docs/guide/config.md +++ b/examples/website/docs/guide/config.md @@ -87,6 +87,22 @@ export default config(router, { ); ``` +### ANTD_IS_STORAGE + +默认 `sessionStorage` 存储,如果需要使用 `localStorage` 存储,设置为 `false` + +```diff +import config from '@antdp/config'; +import proxy from './proxy'; +import router from './router.json'; +export default config(router, { + proxy, + define: { ++ ANTD_IS_STORAGE: false + }, +); +``` + ### ANTD_IS_BREADCRUMB 是否展示面包屑, Tab 选项卡优先级大于面包屑 diff --git a/examples/website/tsconfig.json b/examples/website/tsconfig.json index 3ea66c2c5..6193caaae 100644 --- a/examples/website/tsconfig.json +++ b/examples/website/tsconfig.json @@ -8,5 +8,5 @@ "@@/*": [".dumi/tmp/*"] } }, - "include": [".dumi/**/*", ".dumirc.ts"] + "include": [".dumirc.ts"] } diff --git a/packages/authorized/README.md b/packages/authorized/README.md index 882d7a34e..e32d91c62 100644 --- a/packages/authorized/README.md +++ b/packages/authorized/README.md @@ -15,7 +15,9 @@ $ npm i @antdp/authorized # yarn add @antdp/authorized ``` ## 启用方式 + 配置开启。同时需要 config/config.ts 提供权限配置。 + ```diff import config from '@antdp/config'; import proxy from './proxy'; @@ -41,7 +43,9 @@ export default config(router, { ## 路由菜单权限 + 这是你的路由菜单(config/router.json) + ```json [ { @@ -92,11 +96,12 @@ const menus = ['/', '/welcome', '/404', '/403']; - 1.当你登陆成功后,你需将其保存于你的sessionStorage中,储存的字段为你`ANTD_AUTH_CONF`中配的`auth_menu`字段,并在登陆后存储在`sessionStorage`中,如`sessionStorage.setItem('authMenu', JSON.stringify([]))` - 2.当你跳转至页面时,会根据sessionStorage中`authMenu`进行权限匹配,如果没有权限则会跳往404或403页面 -请保证403 和 404页面存在 - +**请保证403 和 404页面存在** ## 页面权限重定向 -如果你想根据 `token`判断是否重定向回登陆页,可在layouts/BasicLayout.ts中添加`Authorized` + +如果你想根据 `token`判断是否重定向回登陆页,可在 `layouts/BasicLayout.ts` 中添加`Authorized` + ```ts import Authorized from '@antdp/authorized'; import BasicLayouts from '@antdp/basic-layouts'; diff --git a/packages/authorized/src/AuthButton.tsx b/packages/authorized/src/AuthButton.tsx index e2b41adbb..0d3a8503b 100644 --- a/packages/authorized/src/AuthButton.tsx +++ b/packages/authorized/src/AuthButton.tsx @@ -1,6 +1,8 @@ import { useAuthorizedonfig } from "./hooks" import React, { useMemo } from "react"; import { AuthList } from "./interface" +import { store } from "./utils"; + export interface AuthButtonProps { path?: string children?: React.ReactNode; @@ -10,7 +12,7 @@ export const AuthButton = (props: AuthButtonProps) => { const { auth_btn, auth_check_url, isCheckAuth } = useAuthorizedonfig() const authBtns: AuthList = useMemo(() => { - const authBtnStr = sessionStorage.getItem(auth_btn || "") + const authBtnStr = store.getItem(auth_btn || "") if (authBtnStr) { return JSON.parse(authBtnStr) } @@ -48,7 +50,7 @@ export const getAuthButton = (path: string, other: { auth_btn?: string, auth_che newAuthBtn = (ANTD_AUTH_CONF as any).auth_btn } } - const authBtnStr = sessionStorage.getItem(newAuthBtn || "") + const authBtnStr = store.getItem(newAuthBtn || "") if (authBtnStr) { return JSON.parse(authBtnStr) } diff --git a/packages/authorized/src/format.ts b/packages/authorized/src/format.ts index 449b56b88..727b264bb 100644 --- a/packages/authorized/src/format.ts +++ b/packages/authorized/src/format.ts @@ -1,5 +1,6 @@ import { AuthList, GetAuthorizedPageProps } from '.'; import { IRoute } from '@umijs/max'; +import { store } from "./utils"; declare const ANTD_AUTH_CONF: { auth_menu: 'authMenu'; @@ -19,8 +20,8 @@ declare const ANTD_AUTH_CONF: { // } // if (!!ANTD_AUTH_CONF) { // const authBtns: AuthList = -// (sessionStorage.getItem(ANTD_AUTH_CONF.auth_btn) && -// JSON.parse(sessionStorage.getItem(ANTD_AUTH_CONF.auth_btn) || '[]')) || +// (store.getItem(ANTD_AUTH_CONF.auth_btn) && +// JSON.parse(store.getItem(ANTD_AUTH_CONF.auth_btn) || '[]')) || // []; // let finx = -1; // if (ANTD_AUTH_CONF.auth_check_url) { @@ -80,8 +81,8 @@ export const getFormatPage: GetAuthorizedPageProps = (allRouters, pathname) => { // 4. 无权限 无页面 404 // 5. 其他 if (!!ANTD_AUTH_CONF) { - const allMenu = !!sessionStorage.getItem(ANTD_AUTH_CONF.auth_menu) - ? JSON.parse(sessionStorage.getItem(ANTD_AUTH_CONF.auth_menu) || '[]') + const allMenu = !!store.getItem(ANTD_AUTH_CONF.auth_menu) + ? JSON.parse(store.getItem(ANTD_AUTH_CONF.auth_menu) || '[]') : []; const check = mapRouterCheck(allRouters, pathname).length > 0 ? true : false; diff --git a/packages/authorized/src/react-app-env.d.ts b/packages/authorized/src/react-app-env.d.ts index de37b110c..264b60b60 100644 --- a/packages/authorized/src/react-app-env.d.ts +++ b/packages/authorized/src/react-app-env.d.ts @@ -2,3 +2,4 @@ declare var ANTD_AUTH_CONF: boolean | undefined; declare var ANTD_HEAD_IS_SHOW: boolean | undefined; declare var ANTD_MENU_IS_SHOW: boolean | undefined; declare var ANTD_IS_BREADCRUMB: boolean | undefined; +declare var ANTD_IS_STORAGE: boolean | undefined; diff --git a/packages/authorized/src/utils.ts b/packages/authorized/src/utils.ts new file mode 100644 index 000000000..3f9189fe4 --- /dev/null +++ b/packages/authorized/src/utils.ts @@ -0,0 +1,2 @@ + +export const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; \ No newline at end of file diff --git a/packages/basic-layouts/src/react-app-env.d.ts b/packages/basic-layouts/src/react-app-env.d.ts index 1f42c7eb3..272d7441a 100644 --- a/packages/basic-layouts/src/react-app-env.d.ts +++ b/packages/basic-layouts/src/react-app-env.d.ts @@ -3,3 +3,4 @@ declare var ANTD_HEAD_IS_SHOW: boolean | undefined; declare var ANTD_MENU_IS_SHOW: boolean | undefined; declare var ANTD_IS_BREADCRUMB: boolean | undefined; declare var ANTD_MENU_SEARCH_IS_SHOW: boolean | undefined; +declare var ANTD_IS_STORAGE: boolean | undefined; diff --git a/packages/basic-layouts/src/utils.tsx b/packages/basic-layouts/src/utils.tsx index a1fa3ce6d..a2319a8d7 100644 --- a/packages/basic-layouts/src/utils.tsx +++ b/packages/basic-layouts/src/utils.tsx @@ -47,8 +47,9 @@ export class HandleMenu { prePath?: string = ''; constructor(props: HandleMenuProps) { + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; // 所有的 权限菜单 - const auth_menus = sessionStorage.getItem('authMenu'); + const auth_menus = store.getItem('authMenu'); if (auth_menus) { this.authMenus = JSON.parse(auth_menus); } else { diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 03d18bfc9..1c7b003e3 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -14,6 +14,7 @@ export default (routes: IRoute[] = [], options: OptionsProps = {}) => { const defineObj = options.define || {}; // 是否开启路由面包屑 const ANTD_IS_BREADCRUMB = !!defineObj.ANTD_IS_BREADCRUMB; + const ANTD_IS_STORAGE = defineObj.ANTD_IS_STORAGE ?? true; // 权限配置参数 let ANTD_AUTH_CONF = defineObj.ANTD_AUTH_CONF || false; if (typeof ANTD_AUTH_CONF === 'boolean' && ANTD_AUTH_CONF) { @@ -31,6 +32,7 @@ export default (routes: IRoute[] = [], options: OptionsProps = {}) => { ...(ANTD_AUTH_CONF || {}), }; } + console.log("ANTD_IS_STORAGE:", ANTD_IS_STORAGE) return defineConfig({ hash: true, @@ -85,6 +87,8 @@ export default (routes: IRoute[] = [], options: OptionsProps = {}) => { /** 是否开启菜单栏搜索 */ ANTD_MENU_SEARCH_IS_SHOW: false, ...(options.define || {}), + /** 默认 sessionStorage 存储,如果需要使用 localStorage 存储,设置为 `false` */ + ANTD_IS_STORAGE, /** 是否开启父子路由面包屑 */ ANTD_IS_BREADCRUMB, /** 是否开启权限验证 */ diff --git a/packages/hooks/src/react-app-env.d.ts b/packages/hooks/src/react-app-env.d.ts new file mode 100644 index 000000000..d968065ef --- /dev/null +++ b/packages/hooks/src/react-app-env.d.ts @@ -0,0 +1 @@ +declare var ANTD_IS_STORAGE: boolean | undefined; diff --git a/packages/hooks/src/react-query/fetch.ts b/packages/hooks/src/react-query/fetch.ts index 157361a6f..ff5646bbb 100644 --- a/packages/hooks/src/react-query/fetch.ts +++ b/packages/hooks/src/react-query/fetch.ts @@ -17,7 +17,8 @@ function getFetchOption(type: ReactQueryOptions['contentType'] = 'json', option: }; } option.headers = new Headers({ ...option.headers || {} }); - const token = sessionStorage.getItem("token"); + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + const token = store.getItem("token"); if (token && !option.headers.get('Authorization')) { option.headers.set('Authorization', `Bearer ${token}`); } diff --git a/packages/request/src/index.tsx b/packages/request/src/index.tsx index ad96c08bd..67301f35d 100644 --- a/packages/request/src/index.tsx +++ b/packages/request/src/index.tsx @@ -60,7 +60,8 @@ request.interceptors.request.use((url: string, options: any) => { request.interceptors.response.use(async (response) => { let token = getToken(); if (token) { - sessionStorage.setItem('token', token); + const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + store.setItem('token', token); } const data = await response.clone().json(); if ((data && data?.code)) { diff --git a/packages/request/src/react-app-env.d.ts b/packages/request/src/react-app-env.d.ts new file mode 100644 index 000000000..d968065ef --- /dev/null +++ b/packages/request/src/react-app-env.d.ts @@ -0,0 +1 @@ +declare var ANTD_IS_STORAGE: boolean | undefined; diff --git a/packages/request/src/utils/index.tsx b/packages/request/src/utils/index.tsx index 54d7ed8ee..045ec32e4 100644 --- a/packages/request/src/utils/index.tsx +++ b/packages/request/src/utils/index.tsx @@ -1,7 +1,9 @@ import { message } from 'antd'; +const store = ANTD_IS_STORAGE ? sessionStorage : localStorage; + export const getToken = () => { - const token = sessionStorage.getItem("token") + const token = store.getItem("token") return token } @@ -11,7 +13,7 @@ export const setToken = () => { } export const saveToken = (value: string) => { - sessionStorage.setItem('token', value) + store.setItem('token', value) } export const codeMessage: Record = {