diff --git a/frontend/src/enums/tableEnum.ts b/frontend/src/enums/tableEnum.ts index cdc45ae3fb..a6e7b64e99 100644 --- a/frontend/src/enums/tableEnum.ts +++ b/frontend/src/enums/tableEnum.ts @@ -7,5 +7,6 @@ export enum TableModuleEnum { } export enum TableKeyEnum { + API_TEST = 'apiTest', USERGROUPUSER = 'userGroupUser', } diff --git a/frontend/src/router/guard/userLoginInfo.ts b/frontend/src/router/guard/userLoginInfo.ts index d4694181c5..0e4c000aca 100644 --- a/frontend/src/router/guard/userLoginInfo.ts +++ b/frontend/src/router/guard/userLoginInfo.ts @@ -1,11 +1,14 @@ import type { Router, LocationQueryRaw } from 'vue-router'; import NProgress from 'nprogress'; // progress bar -import { isLogin } from '@/utils/auth'; +import { clearToken, hasToken, isLoginExpires } from '@/utils/auth'; export default function setupUserLoginInfoGuard(router: Router) { - router.beforeEach(async (to, from, next) => { + router.beforeEach((to, from, next) => { NProgress.start(); - if (to.name !== 'login' && (await isLogin())) { + if (isLoginExpires()) { + clearToken(); + } + if (to.name !== 'login' && hasToken()) { next(); } else { // 未登录的都直接跳转至登录页,访问的页面地址缓存到 query 上 diff --git a/frontend/src/store/modules/ms-table/index.ts b/frontend/src/store/modules/ms-table/index.ts index d3eac0fcfd..3adf0c52df 100644 --- a/frontend/src/store/modules/ms-table/index.ts +++ b/frontend/src/store/modules/ms-table/index.ts @@ -1,10 +1,16 @@ import { defineStore } from 'pinia'; import { MsTableSelectorItem, MsTableState, TableOpenDetailMode } from './types'; import { MsTableColumn } from '@/components/pure/ms-table/type'; +import { parse, stringify } from '@/utils/serializeMap'; const msTableStore = defineStore('msTable', { // 开启数据持久化 - persist: true, + persist: { + serializer: { + deserialize: parse, + serialize: stringify, + }, + }, state: (): MsTableState => ({ selectorColumnMap: new Map(), }), @@ -43,7 +49,7 @@ const msTableStore = defineStore('msTable', { this.selectorColumnMap.set(key, { mode, column: columns }); }, getShowInTableColumns(key: string): MsTableColumn { - if (this.selectorColumnMap?.has(key)) { + if (this.selectorColumnMap.has(key)) { const tmpArr = this.selectorColumnMap.get(key)?.column; return tmpArr?.filter((item) => item.showInTable) || []; } diff --git a/frontend/src/utils/auth.ts b/frontend/src/utils/auth.ts index c9d65f6068..006f8a727e 100644 --- a/frontend/src/utils/auth.ts +++ b/frontend/src/utils/auth.ts @@ -26,4 +26,20 @@ const clearToken = () => { localStorage.removeItem(CSRF_TOKEN); }; -export { isLogin, getToken, setToken, clearToken }; +const hasToken = () => { + return !!localStorage.getItem(SESSION_ID) && !!localStorage.getItem(CSRF_TOKEN); +}; + +const setLoginExpires = () => { + localStorage.setItem('loginExpires', Date.now().toString()); +}; + +const isLoginExpires = () => { + const lastLoginTime = Number(localStorage.getItem('loginExpires')); + const now = Date.now(); + const diff = now - lastLoginTime; + const thirtyDay = 24 * 60 * 60 * 1000 * 30; + return diff > thirtyDay; +}; + +export { isLogin, getToken, setToken, clearToken, hasToken, setLoginExpires, isLoginExpires }; diff --git a/frontend/src/utils/serializeMap.ts b/frontend/src/utils/serializeMap.ts new file mode 100644 index 0000000000..d7535d7d6e --- /dev/null +++ b/frontend/src/utils/serializeMap.ts @@ -0,0 +1,22 @@ +export const stringify = (source: any) => { + return JSON.stringify(source, (key, value) => { + if (value instanceof Map) { + return { + __dataType__: 'Map', + val: Array.from(value.entries()), // or with spread: value: [...value] + }; + } + return value; + }); +}; + +export const parse = (source: string) => { + return JSON.parse(source, (key, value) => { + if (typeof value === 'object' && value !== null) { + if (value.__dataType__ === 'Map') { + return new Map(value.value); + } + } + return value; + }); +}; diff --git a/frontend/src/views/api-test/index.vue b/frontend/src/views/api-test/index.vue index ae15db5160..ee75aba8e2 100644 --- a/frontend/src/views/api-test/index.vue +++ b/frontend/src/views/api-test/index.vue @@ -11,6 +11,8 @@ import { BatchActionConfig, MsTableColumn } from '@/components/pure/ms-table/type'; import useTable from '@/components/pure/ms-table/useTable'; import { getTableList } from '@/api/modules/api-test/index'; + import { TableKeyEnum } from '@/enums/tableEnum'; + import { useTableStore } from '@/store'; const columns: MsTableColumn = [ { @@ -150,6 +152,10 @@ ], }; + const tableStore = useTableStore(); + + tableStore.initColumn(TableKeyEnum.API_TEST, columns, 'drawer'); + const { propsRes, propsEvent, loadList } = useTable(getTableList, { columns, scroll: { y: 750, x: 2000 }, diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 7edd23f9a8..2f3ec71dd2 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -70,6 +70,7 @@ import { useUserStore } from '@/store'; import useLoading from '@/hooks/useLoading'; import type { LoginData } from '@/models/user'; + import { setLoginExpires } from '@/utils/auth'; const router = useRouter(); const { t } = useI18n(); @@ -109,6 +110,7 @@ loginConfig.value.username = rememberPassword ? username : ''; loginConfig.value.password = rememberPassword ? password : ''; const { redirect, ...othersQuery } = router.currentRoute.value.query; + setLoginExpires(); router.push({ name: (redirect as string) || 'apiTest', query: {