mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 同步数据库中界面设置数据 (#4355)
This commit is contained in:
parent
0ebeeaebd6
commit
1527c63d37
@ -42,9 +42,6 @@ class RequestHttp {
|
|||||||
this.service.interceptors.response.use(
|
this.service.interceptors.response.use(
|
||||||
(response: AxiosResponse) => {
|
(response: AxiosResponse) => {
|
||||||
const { data } = response;
|
const { data } = response;
|
||||||
if (response.headers['x-csrf-token']) {
|
|
||||||
globalStore.setCsrfToken(response.headers['x-csrf-token']);
|
|
||||||
}
|
|
||||||
if (data.code == ResultEnum.OVERDUE || data.code == ResultEnum.FORBIDDEN) {
|
if (data.code == ResultEnum.OVERDUE || data.code == ResultEnum.FORBIDDEN) {
|
||||||
globalStore.setLogStatus(false);
|
globalStore.setLogStatus(false);
|
||||||
router.push({
|
router.push({
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
import { MenuStore } from '@/store';
|
||||||
const menuStore = MenuStore();
|
const menuStore = MenuStore();
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
import { MenuStore } from '@/store';
|
||||||
const menuStore = MenuStore();
|
const menuStore = MenuStore();
|
||||||
const isCollapse = computed(() => menuStore.isCollapse);
|
const isCollapse = computed(() => menuStore.isCollapse);
|
||||||
</script>
|
</script>
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { RouteRecordRaw, useRoute } from 'vue-router';
|
import { RouteRecordRaw, useRoute } from 'vue-router';
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
|
||||||
import { loadingSvg } from '@/utils/svg';
|
import { loadingSvg } from '@/utils/svg';
|
||||||
import Logo from './components/Logo.vue';
|
import Logo from './components/Logo.vue';
|
||||||
import Collapse from './components/Collapse.vue';
|
import Collapse from './components/Collapse.vue';
|
||||||
@ -42,7 +41,7 @@ import router, { menuList } from '@/routers/router';
|
|||||||
import { logOutApi } from '@/api/modules/auth';
|
import { logOutApi } from '@/api/modules/auth';
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { ElMessageBox } from 'element-plus';
|
import { ElMessageBox } from 'element-plus';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore, MenuStore } from '@/store';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { isString } from '@vueuse/core';
|
import { isString } from '@vueuse/core';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { watch, onBeforeMount, onMounted, onBeforeUnmount } from 'vue';
|
import { watch, onBeforeMount, onMounted, onBeforeUnmount } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import { GlobalStore, MenuStore } from '@/store';
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
|
||||||
import { GlobalStore } from '@/store';
|
|
||||||
import { DeviceType } from '@/enums/app';
|
import { DeviceType } from '@/enums/app';
|
||||||
/** 参考 Bootstrap 的响应式设计 WIDTH = 600 */
|
/** 参考 Bootstrap 的响应式设计 WIDTH = 600 */
|
||||||
const WIDTH = 600;
|
const WIDTH = 600;
|
||||||
|
@ -18,13 +18,12 @@
|
|||||||
import { onMounted, computed, ref, watch, onBeforeUnmount } from 'vue';
|
import { onMounted, computed, ref, watch, onBeforeUnmount } from 'vue';
|
||||||
import { Sidebar, Footer, AppMain, MobileHeader } from './components';
|
import { Sidebar, Footer, AppMain, MobileHeader } from './components';
|
||||||
import useResize from './hooks/useResize';
|
import useResize from './hooks/useResize';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore, MenuStore } from '@/store';
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
|
||||||
import { DeviceType } from '@/enums/app';
|
import { DeviceType } from '@/enums/app';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useTheme } from '@/hooks/use-theme';
|
import { useTheme } from '@/hooks/use-theme';
|
||||||
import { useLogo } from '@/hooks/use-logo';
|
|
||||||
import { getLicense, getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
|
import { getLicense, getSettingInfo, getSystemAvailable } from '@/api/modules/setting';
|
||||||
|
import { searchXSetting } from '@/xpack/api/modules/setting';
|
||||||
useResize();
|
useResize();
|
||||||
|
|
||||||
const menuStore = MenuStore();
|
const menuStore = MenuStore();
|
||||||
@ -74,10 +73,31 @@ const loadDataFromDB = async () => {
|
|||||||
switchDark();
|
switchDark();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadDataFromXDB = async () => {
|
||||||
|
const res = await searchXSetting();
|
||||||
|
localStorage.setItem('1p-favicon', res.data.logo);
|
||||||
|
globalStore.themeConfig.title = res.data.title;
|
||||||
|
globalStore.themeConfig.logo = res.data.logo;
|
||||||
|
globalStore.themeConfig.logoWithText = res.data.logoWithText;
|
||||||
|
globalStore.themeConfig.favicon = res.data.favicon;
|
||||||
|
|
||||||
|
initFavicon();
|
||||||
|
};
|
||||||
|
|
||||||
const loadProductProFromDB = async () => {
|
const loadProductProFromDB = async () => {
|
||||||
const res = await getLicense();
|
const res = await getLicense();
|
||||||
globalStore.isProductPro =
|
globalStore.isProductPro =
|
||||||
res.data.status === 'Enable' || res.data.status === 'Lost01' || res.data.status === 'Lost02';
|
res.data.status === 'Enable' || res.data.status === 'Lost01' || res.data.status === 'Lost02';
|
||||||
|
|
||||||
|
if (globalStore.isProductPro) {
|
||||||
|
loadDataFromXDB();
|
||||||
|
globalStore.productProExpires = Number(res.data.productPro);
|
||||||
|
} else {
|
||||||
|
globalStore.themeConfig.title = '';
|
||||||
|
globalStore.themeConfig.logo = '';
|
||||||
|
globalStore.themeConfig.logoWithText = '';
|
||||||
|
globalStore.themeConfig.favicon = '';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDarkMode = async (event: MediaQueryListEvent) => {
|
const updateDarkMode = async (event: MediaQueryListEvent) => {
|
||||||
@ -127,7 +147,6 @@ onMounted(() => {
|
|||||||
loadStatus();
|
loadStatus();
|
||||||
initFavicon();
|
initFavicon();
|
||||||
loadDataFromDB();
|
loadDataFromDB();
|
||||||
useLogo();
|
|
||||||
loadProductProFromDB();
|
loadProductProFromDB();
|
||||||
|
|
||||||
const mqList = window.matchMedia('(prefers-color-scheme: dark)');
|
const mqList = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
@ -1,94 +1,11 @@
|
|||||||
import { defineStore } from 'pinia';
|
|
||||||
import { GlobalState, ThemeConfigProp } from './interface';
|
|
||||||
import { createPinia } from 'pinia';
|
import { createPinia } from 'pinia';
|
||||||
import piniaPersistConfig from '@/config/pinia-persist';
|
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||||
import { DeviceType } from '@/enums/app';
|
import GlobalStore from './modules/global';
|
||||||
import i18n from '@/lang';
|
import MenuStore from './modules/menu';
|
||||||
|
|
||||||
export const GlobalStore = defineStore({
|
|
||||||
id: 'GlobalState',
|
|
||||||
state: (): GlobalState => ({
|
|
||||||
isLoading: false,
|
|
||||||
loadingText: '',
|
|
||||||
isLogin: false,
|
|
||||||
csrfToken: '',
|
|
||||||
entrance: '',
|
|
||||||
language: '',
|
|
||||||
themeConfig: {
|
|
||||||
panelName: '',
|
|
||||||
primary: '#005EEB',
|
|
||||||
theme: 'auto',
|
|
||||||
footer: true,
|
|
||||||
|
|
||||||
title: '',
|
|
||||||
logo: '',
|
|
||||||
logoWithText: '',
|
|
||||||
favicon: '',
|
|
||||||
},
|
|
||||||
isFullScreen: false,
|
|
||||||
isOnRestart: false,
|
|
||||||
agreeLicense: false,
|
|
||||||
hasNewVersion: false,
|
|
||||||
ignoreCaptcha: true,
|
|
||||||
device: DeviceType.Desktop,
|
|
||||||
lastFilePath: '',
|
|
||||||
currentDB: '',
|
|
||||||
showEntranceWarn: true,
|
|
||||||
defaultNetwork: 'all',
|
|
||||||
|
|
||||||
isProductPro: false,
|
|
||||||
}),
|
|
||||||
getters: {},
|
|
||||||
actions: {
|
|
||||||
setScreenFull() {
|
|
||||||
this.isFullScreen = !this.isFullScreen;
|
|
||||||
},
|
|
||||||
setLogStatus(login: boolean) {
|
|
||||||
this.isLogin = login;
|
|
||||||
},
|
|
||||||
setGlobalLoading(loading: boolean) {
|
|
||||||
this.isLoading = loading;
|
|
||||||
},
|
|
||||||
setLoadingText(text: string) {
|
|
||||||
this.loadingText = i18n.global.t('commons.loadingText.' + text);
|
|
||||||
},
|
|
||||||
setCsrfToken(token: string) {
|
|
||||||
this.csrfToken = token;
|
|
||||||
},
|
|
||||||
updateLanguage(language: any) {
|
|
||||||
this.language = language;
|
|
||||||
localStorage.setItem('lang', language);
|
|
||||||
},
|
|
||||||
setThemeConfig(themeConfig: ThemeConfigProp) {
|
|
||||||
this.themeConfig = themeConfig;
|
|
||||||
},
|
|
||||||
setAgreeLicense(agree: boolean) {
|
|
||||||
this.agreeLicense = agree;
|
|
||||||
},
|
|
||||||
toggleDevice(value: DeviceType) {
|
|
||||||
this.device = value;
|
|
||||||
},
|
|
||||||
isMobile() {
|
|
||||||
return this.device === DeviceType.Mobile;
|
|
||||||
},
|
|
||||||
setLastFilePath(path: string) {
|
|
||||||
this.lastFilePath = path;
|
|
||||||
},
|
|
||||||
setCurrentDB(name: string) {
|
|
||||||
this.currentDB = name;
|
|
||||||
},
|
|
||||||
setShowEntranceWarn(show: boolean) {
|
|
||||||
this.showEntranceWarn = show;
|
|
||||||
},
|
|
||||||
setDefaultNetwork(net: string) {
|
|
||||||
this.defaultNetwork = net;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
persist: piniaPersistConfig('GlobalState'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
pinia.use(piniaPluginPersistedstate);
|
pinia.use(piniaPluginPersistedstate);
|
||||||
|
|
||||||
|
export { GlobalStore, MenuStore };
|
||||||
|
|
||||||
export default pinia;
|
export default pinia;
|
||||||
|
@ -17,9 +17,7 @@ export interface GlobalState {
|
|||||||
loadingText: string;
|
loadingText: string;
|
||||||
isLogin: boolean;
|
isLogin: boolean;
|
||||||
entrance: string;
|
entrance: string;
|
||||||
csrfToken: string;
|
|
||||||
language: string; // zh | en | tw
|
language: string; // zh | en | tw
|
||||||
// assemblySize: string; // small | default | large
|
|
||||||
themeConfig: ThemeConfigProp;
|
themeConfig: ThemeConfigProp;
|
||||||
isFullScreen: boolean;
|
isFullScreen: boolean;
|
||||||
isOnRestart: boolean;
|
isOnRestart: boolean;
|
||||||
@ -33,6 +31,7 @@ export interface GlobalState {
|
|||||||
defaultNetwork: string;
|
defaultNetwork: string;
|
||||||
|
|
||||||
isProductPro: boolean;
|
isProductPro: boolean;
|
||||||
|
productProExpires: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MenuState {
|
export interface MenuState {
|
||||||
@ -40,7 +39,3 @@ export interface MenuState {
|
|||||||
menuList: RouteRecordRaw[];
|
menuList: RouteRecordRaw[];
|
||||||
withoutAnimation: boolean;
|
withoutAnimation: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuthState {
|
|
||||||
authRouter: string[];
|
|
||||||
}
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import { defineStore } from 'pinia';
|
|
||||||
import { AuthState } from '../interface';
|
|
||||||
import piniaPersistConfig from '@/config/pinia-persist';
|
|
||||||
|
|
||||||
export const AuthStore = defineStore({
|
|
||||||
id: 'AuthState',
|
|
||||||
state: (): AuthState => ({
|
|
||||||
authRouter: [],
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
dynamicRouter: (state) => {
|
|
||||||
return state.authRouter;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
async setAuthRouter(dynamicRouter: string[]) {
|
|
||||||
this.authRouter = dynamicRouter;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
persist: piniaPersistConfig('AuthState'),
|
|
||||||
});
|
|
89
frontend/src/store/modules/global.ts
Normal file
89
frontend/src/store/modules/global.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import piniaPersistConfig from '@/config/pinia-persist';
|
||||||
|
import { GlobalState, ThemeConfigProp } from '../interface';
|
||||||
|
import { DeviceType } from '@/enums/app';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
|
||||||
|
const GlobalStore = defineStore({
|
||||||
|
id: 'GlobalState',
|
||||||
|
state: (): GlobalState => ({
|
||||||
|
isLoading: false,
|
||||||
|
loadingText: '',
|
||||||
|
isLogin: false,
|
||||||
|
entrance: '',
|
||||||
|
language: '',
|
||||||
|
themeConfig: {
|
||||||
|
panelName: '',
|
||||||
|
primary: '#005EEB',
|
||||||
|
theme: 'auto',
|
||||||
|
footer: true,
|
||||||
|
|
||||||
|
title: '',
|
||||||
|
logo: '',
|
||||||
|
logoWithText: '',
|
||||||
|
favicon: '',
|
||||||
|
},
|
||||||
|
isFullScreen: false,
|
||||||
|
isOnRestart: false,
|
||||||
|
agreeLicense: false,
|
||||||
|
hasNewVersion: false,
|
||||||
|
ignoreCaptcha: true,
|
||||||
|
device: DeviceType.Desktop,
|
||||||
|
lastFilePath: '',
|
||||||
|
currentDB: '',
|
||||||
|
showEntranceWarn: true,
|
||||||
|
defaultNetwork: 'all',
|
||||||
|
|
||||||
|
isProductPro: false,
|
||||||
|
productProExpires: 0,
|
||||||
|
}),
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
setScreenFull() {
|
||||||
|
this.isFullScreen = !this.isFullScreen;
|
||||||
|
},
|
||||||
|
setLogStatus(login: boolean) {
|
||||||
|
this.isLogin = login;
|
||||||
|
},
|
||||||
|
setGlobalLoading(loading: boolean) {
|
||||||
|
this.isLoading = loading;
|
||||||
|
},
|
||||||
|
setLoadingText(text: string) {
|
||||||
|
this.loadingText = i18n.global.t('commons.loadingText.' + text);
|
||||||
|
},
|
||||||
|
setCsrfToken(token: string) {
|
||||||
|
this.csrfToken = token;
|
||||||
|
},
|
||||||
|
updateLanguage(language: any) {
|
||||||
|
this.language = language;
|
||||||
|
localStorage.setItem('lang', language);
|
||||||
|
},
|
||||||
|
setThemeConfig(themeConfig: ThemeConfigProp) {
|
||||||
|
this.themeConfig = themeConfig;
|
||||||
|
},
|
||||||
|
setAgreeLicense(agree: boolean) {
|
||||||
|
this.agreeLicense = agree;
|
||||||
|
},
|
||||||
|
toggleDevice(value: DeviceType) {
|
||||||
|
this.device = value;
|
||||||
|
},
|
||||||
|
isMobile() {
|
||||||
|
return this.device === DeviceType.Mobile;
|
||||||
|
},
|
||||||
|
setLastFilePath(path: string) {
|
||||||
|
this.lastFilePath = path;
|
||||||
|
},
|
||||||
|
setCurrentDB(name: string) {
|
||||||
|
this.currentDB = name;
|
||||||
|
},
|
||||||
|
setShowEntranceWarn(show: boolean) {
|
||||||
|
this.showEntranceWarn = show;
|
||||||
|
},
|
||||||
|
setDefaultNetwork(net: string) {
|
||||||
|
this.defaultNetwork = net;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: piniaPersistConfig('GlobalState'),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default GlobalStore;
|
@ -30,3 +30,5 @@ export const MenuStore = defineStore({
|
|||||||
},
|
},
|
||||||
persist: piniaPersistConfig('MenuStore'),
|
persist: piniaPersistConfig('MenuStore'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default MenuStore;
|
||||||
|
@ -153,8 +153,7 @@ import { ref, reactive, onMounted, computed } from 'vue';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import type { ElForm } from 'element-plus';
|
import type { ElForm } from 'element-plus';
|
||||||
import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage } from '@/api/modules/auth';
|
import { loginApi, getCaptcha, mfaLoginApi, checkIsDemo, getLanguage } from '@/api/modules/auth';
|
||||||
import { GlobalStore } from '@/store';
|
import { GlobalStore, MenuStore } from '@/store';
|
||||||
import { MenuStore } from '@/store/modules/menu';
|
|
||||||
import i18n from '@/lang';
|
import i18n from '@/lang';
|
||||||
import { MsgSuccess } from '@/utils/message';
|
import { MsgSuccess } from '@/utils/message';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
@ -168,7 +168,9 @@ const search = async () => {
|
|||||||
if (!globalStore.isProductPro || res.data.status === 'Lost03') {
|
if (!globalStore.isProductPro || res.data.status === 'Lost03') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('csdcasd');
|
if (globalStore.isProductPro) {
|
||||||
|
globalStore.productProExpires = Number(res.data.productPro);
|
||||||
|
}
|
||||||
license.licenseName = res.data.licenseName;
|
license.licenseName = res.data.licenseName;
|
||||||
license.assigneeName = res.data.assigneeName;
|
license.assigneeName = res.data.assigneeName;
|
||||||
license.trial = res.data.trial;
|
license.trial = res.data.trial;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user