diff --git a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java index 2f2bdb3a67..a35c4062b1 100644 --- a/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java +++ b/dinky-admin/src/main/java/org/dinky/configure/AppConfig.java @@ -85,7 +85,8 @@ public void addInterceptors(InterceptorRegistry registry) { } })) .addPathPatterns("/api/**", "/openapi/**") - .excludePathPatterns("/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**"); + .excludePathPatterns( + "/api/login", "/api/ldap/ldapEnableStatus", "/download/**", "/druid/**", "/api/version"); registry.addInterceptor(new TenantInterceptor()) .addPathPatterns("/api/**") diff --git a/dinky-web/package.json b/dinky-web/package.json index fa4fa66e7e..0bc183dca4 100644 --- a/dinky-web/package.json +++ b/dinky-web/package.json @@ -95,6 +95,7 @@ "@types/history": "^5.0.0", "@types/lodash": "^4.17.5", "@types/react": "^18.2.39", + "@types/js-cookie": "^3.0.5", "@types/react-dom": "^18.2.17", "@types/react-grid-layout": "^1.3.5", "@types/react-helmet": "^6.1.9", diff --git a/dinky-web/src/components/RightContent/AvatarDropdown.tsx b/dinky-web/src/components/RightContent/AvatarDropdown.tsx index 9b62e4f98b..af6106020c 100644 --- a/dinky-web/src/components/RightContent/AvatarDropdown.tsx +++ b/dinky-web/src/components/RightContent/AvatarDropdown.tsx @@ -18,9 +18,10 @@ */ import { chooseTenantSubmit, outLogin } from '@/services/BusinessCrud'; -import { ENABLE_MODEL_TIP } from '@/services/constants'; +import { ENABLE_MODEL_TIP, TOKEN_KEY } from '@/services/constants'; import { getValueFromLocalStorage, + removeKeyFromLocalStorage, setKeyToLocalStorage, setTenantStorageAndCookie } from '@/utils/function'; @@ -47,6 +48,7 @@ import HeaderDropdown from '../HeaderDropdown'; export const loginOut = async () => { await outLogin(); + removeKeyFromLocalStorage(TOKEN_KEY); const { search, pathname } = window.location; const urlParams = new URL(window.location.href).searchParams; /** 此方法会跳转到 redirect 参数所在的位置 */ diff --git a/dinky-web/src/components/RightContent/index.tsx b/dinky-web/src/components/RightContent/index.tsx index 43ee2b4b5d..9e4b571d37 100644 --- a/dinky-web/src/components/RightContent/index.tsx +++ b/dinky-web/src/components/RightContent/index.tsx @@ -18,9 +18,7 @@ */ import { ThemeCloud, ThemeStar } from '@/components/ThemeSvg/ThemeSvg'; -import { queryDataByParams } from '@/services/BusinessCrud'; -import { LANGUAGE_KEY, LANGUAGE_ZH, STORY_LANGUAGE } from '@/services/constants'; -import { API_CONSTANTS } from '@/services/endpoints'; +import { LANGUAGE_KEY, LANGUAGE_ZH, SERVER_VERSION, STORY_LANGUAGE } from '@/services/constants'; import { THEME } from '@/types/Public/data'; import { useLocalStorage } from '@/utils/hook/useLocalStorage'; import { l } from '@/utils/intl'; @@ -31,6 +29,7 @@ import React, { useEffect, useState } from 'react'; import useCookie from 'react-use-cookie'; import screenfull from 'screenfull'; import Avatar from './AvatarDropdown'; +import { getValueFromLocalStorage } from '@/utils/function'; const GlobalHeaderRight: React.FC = () => { /** @@ -41,7 +40,6 @@ const GlobalHeaderRight: React.FC = () => { const [theme, setTheme] = useLocalStorage(THEME.NAV_THEME, initialState?.settings?.navTheme); const [language, setLanguage] = useLocalStorage(LANGUAGE_KEY, LANGUAGE_ZH); const [langCache, setLangCache] = useCookie(STORY_LANGUAGE, language); - const [serviceVersion, setServiceVersion] = useState(''); useEffect(() => { setLangCache(language); @@ -63,12 +61,6 @@ const GlobalHeaderRight: React.FC = () => { })))(); }, [theme, language]); - useEffect(() => { - queryDataByParams(API_CONSTANTS.GET_SERVICE_VERSION).then((res) => { - if (res) setServiceVersion(res); - }); - }, []); - if (!initialState || !initialState.settings) { return null; } @@ -123,7 +115,7 @@ const GlobalHeaderRight: React.FC = () => { style: fullScreenClassName }; - const menuVersion = l('menu.version', '', { version: serviceVersion }); + const menuVersion = l('menu.version', '', { version: getValueFromLocalStorage(SERVER_VERSION) }); return ( <> { @@ -36,7 +39,7 @@ export const gotoRedirectUrl = () => { }; export const redirectToLogin = (tipMsg: string) => { - //todo: 使用模态框提示, 但是目前会重复弹出,原因是接口每次都会调用,所以会出现重复弹出 + //todo: Using modal box prompts, but currently it will pop up repeatedly because the interface is called every time, so there will be repeated pop ups WarningMessageAsync(tipMsg); window.location.href = '/#/user/login'; }; @@ -44,6 +47,16 @@ export const redirectToLogin = (tipMsg: string) => { export const initSomeThing = () => { // initialize setting theme setLocalThemeToStorage(); + queryDataByParams(API_CONSTANTS.GET_SERVICE_VERSION).then((result) => { + if (result && result != getValueFromLocalStorage(SERVER_VERSION)) { + console.log('current version:', getValueFromLocalStorage(SERVER_VERSION)); + console.log('update server version:', result); + setKeyToLocalStorage(SERVER_VERSION, result); + console.log('clean dva cache'); + window.localStorage.removeItem('persist:root'); + } + }); + // Retrieve the key for enabling message prompts from the local storage, and if not, set it accordingly if (hasKeyofLocalStorage(ENABLE_MODEL_TIP)) { setKeyToLocalStorage(ENABLE_MODEL_TIP, 'false'); diff --git a/dinky-web/src/pages/Other/Login/index.tsx b/dinky-web/src/pages/Other/Login/index.tsx index e93cab91cd..190ff172bc 100644 --- a/dinky-web/src/pages/Other/Login/index.tsx +++ b/dinky-web/src/pages/Other/Login/index.tsx @@ -34,6 +34,7 @@ import { useModel } from '@umijs/max'; import React, { useEffect, useState } from 'react'; import HelmetTitle from './HelmetTitle'; import LoginForm from './LoginForm'; +import { TOKEN_KEY } from '@/services/constants'; const Login: React.FC = () => { const [submitting, setSubmitting] = useState(false); @@ -41,7 +42,7 @@ const Login: React.FC = () => { const [tenantVisible, handleTenantVisible] = useState(false); const [tenant, setTenant] = useState([]); - const [localStorageOfToken, setLocalStorageOfToken] = useLocalStorage('token', ''); + const [localStorageOfToken, setLocalStorageOfToken] = useLocalStorage(TOKEN_KEY, ''); const containerClassName = useEmotionCss(() => { return { diff --git a/dinky-web/src/services/constants.tsx b/dinky-web/src/services/constants.tsx index 23b6f412a6..c1dadc54e2 100644 --- a/dinky-web/src/services/constants.tsx +++ b/dinky-web/src/services/constants.tsx @@ -33,6 +33,10 @@ export const LANGUAGE_KEY = 'umi_locale'; export const LANGUAGE_ZH = 'zh-CN'; export const LANGUAGE_EN = 'en-US'; +export const SERVER_VERSION = 'dinky_server_version'; + +export const TOKEN_KEY = 'token'; + export const DATE_FORMAT = 'YYYY-MM-DD'; export const DATETIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; diff --git a/dinky-web/src/utils/function.tsx b/dinky-web/src/utils/function.tsx index 20f8b4ce63..e98e5dd53a 100644 --- a/dinky-web/src/utils/function.tsx +++ b/dinky-web/src/utils/function.tsx @@ -67,6 +67,14 @@ export function setKeyToLocalStorage(key: string, value: string) { localStorage.setItem(key, value); } +/** + * remove key from localStorage + * @param key + */ +export function removeKeyFromLocalStorage(key: string) { + localStorage.removeItem(key); +} + export function hasKeyofLocalStorage(key: string): boolean { return localStorage.getItem(key) === undefined || localStorage.getItem(key) === null; }