From 540f089b6271d0cdbade1a815489a2532a01f5e5 Mon Sep 17 00:00:00 2001 From: ssongliu Date: Tue, 12 May 2026 11:39:39 +0800 Subject: [PATCH 1/3] fix: tighten frontend RBAC permission guards --- frontend/src/components/status/index.vue | 3 +- .../composables/useMenuManagePermission.ts | 73 ++++++++++++++++ .../src/layout/components/Sidebar/index.vue | 31 +++---- frontend/src/store/modules/global.ts | 3 + .../src/views/ai/agents/agent/add/index.vue | 14 ++- .../agents/agent/components/hermes-chat.vue | 7 +- .../config/tabs/agents/binding/index.vue | 13 ++- .../agent/config/tabs/agents/create/index.vue | 9 +- .../agent/config/tabs/agents/detail/index.vue | 9 +- .../agents/agent/config/tabs/agents/index.vue | 26 ++++-- .../tabs/channels/components/channel-bots.vue | 43 +++++++--- .../channels/components/plugin-install.vue | 21 ++++- .../config/tabs/channels/hermes/dingtalk.vue | 14 ++- .../config/tabs/channels/hermes/discord.vue | 14 ++- .../config/tabs/channels/hermes/feishu.vue | 14 ++- .../agent/config/tabs/channels/hermes/qq.vue | 14 ++- .../config/tabs/channels/hermes/telegram.vue | 14 ++- .../config/tabs/channels/hermes/wecom.vue | 14 ++- .../config/tabs/channels/hermes/weixin.vue | 6 +- .../tabs/channels/openclaw/dingtalk.vue | 10 ++- .../config/tabs/channels/openclaw/discord.vue | 4 +- .../config/tabs/channels/openclaw/feishu.vue | 9 +- .../config/tabs/channels/openclaw/qq.vue | 9 +- .../tabs/channels/openclaw/telegram.vue | 4 +- .../config/tabs/channels/openclaw/wecom.vue | 16 +++- .../config/tabs/channels/openclaw/weixin.vue | 9 +- .../ai/agents/agent/config/tabs/model.vue | 18 +++- .../config/tabs/settings/config-file.vue | 4 +- .../agent/config/tabs/settings/other.vue | 4 +- .../agent/config/tabs/settings/security.vue | 4 +- .../agent/config/tabs/skills/hermes.vue | 4 + .../agent/config/tabs/skills/openclaw.vue | 4 + .../views/ai/agents/agent/delete/index.vue | 4 +- frontend/src/views/ai/agents/agent/index.vue | 59 ++++++++++--- .../views/ai/agents/agent/website/index.vue | 4 +- .../src/views/ai/agents/model/add/index.vue | 4 +- frontend/src/views/ai/agents/model/index.vue | 8 +- .../src/views/ai/agents/model/pool/index.vue | 8 +- .../src/views/ai/mcp/server/bind/index.vue | 4 +- .../src/views/ai/mcp/server/import/index.vue | 4 +- frontend/src/views/ai/mcp/server/index.vue | 12 ++- .../src/views/ai/mcp/server/operate/index.vue | 18 +++- .../src/views/ai/mcp/server/volume/index.vue | 14 ++- .../src/views/ai/model/ollama/add/index.vue | 4 +- .../src/views/ai/model/ollama/del/index.vue | 8 +- .../views/ai/model/ollama/domain/index.vue | 4 +- frontend/src/views/ai/model/ollama/index.vue | 31 +++++-- .../src/views/ai/model/tensorrt/index.vue | 10 ++- .../views/ai/model/tensorrt/operate/index.vue | 4 +- .../src/views/app-store/apps/app/index.vue | 7 +- frontend/src/views/app-store/apps/index.vue | 10 ++- frontend/src/views/app-store/detail/index.vue | 3 + .../views/app-store/installed/app/header.vue | 27 ++++-- .../src/views/app-store/installed/index.vue | 17 +++- .../src/views/app-store/setting/index.vue | 6 ++ .../src/views/container/compose/index.vue | 42 +++++++-- .../src/views/container/container/index.vue | 74 +++++++++++----- .../container/container/operate/index.vue | 12 ++- .../src/views/container/dashboard/index.vue | 6 ++ frontend/src/views/container/image/index.vue | 18 ++-- .../src/views/container/network/index.vue | 10 ++- frontend/src/views/container/repo/index.vue | 10 ++- .../src/views/container/setting/index.vue | 85 +++++++++++++++---- .../src/views/container/template/index.vue | 19 +++-- frontend/src/views/container/volume/index.vue | 8 +- frontend/src/views/cronjob/cronjob/index.vue | 42 ++++++--- .../views/cronjob/cronjob/record/index.vue | 8 +- frontend/src/views/cronjob/library/index.vue | 28 ++++-- .../src/views/database/mongodb/conn/index.vue | 8 +- frontend/src/views/database/mongodb/index.vue | 22 +++-- .../views/database/mongodb/remote/index.vue | 6 +- .../src/views/database/mysql/conn/index.vue | 14 ++- frontend/src/views/database/mysql/index.vue | 22 +++-- .../src/views/database/mysql/remote/index.vue | 7 +- .../views/database/mysql/setting/index.vue | 11 ++- .../database/mysql/setting/slow-log/index.vue | 3 + .../mysql/setting/variables/index.vue | 8 +- .../views/database/postgresql/conn/index.vue | 8 +- .../src/views/database/postgresql/index.vue | 22 +++-- .../database/postgresql/remote/index.vue | 6 +- .../database/postgresql/setting/index.vue | 11 ++- .../views/database/redis/command/index.vue | 9 +- .../src/views/database/redis/conn/index.vue | 8 +- frontend/src/views/database/redis/index.vue | 16 +++- .../src/views/database/redis/remote/index.vue | 6 +- .../views/database/redis/setting/index.vue | 16 +++- .../redis/setting/persistence/index.vue | 40 +++++++-- frontend/src/views/home/app/index.vue | 16 +++- frontend/src/views/home/index.vue | 60 +++++++++++-- .../disk-management/components/disk-card.vue | 35 ++++++-- .../views/host/disk-management/disk/index.vue | 4 + .../host/disk-management/partition/index.vue | 15 +++- .../host/file-management/favorite/index.vue | 4 + .../src/views/host/file-management/index.vue | 53 +++++++++--- .../file-management/recycle-bin/index.vue | 23 ++++- .../host/file-management/share-list/index.vue | 4 + .../host/file-management/share/index.vue | 6 +- .../src/views/host/firewall/advance/index.vue | 16 +++- .../src/views/host/firewall/forward/index.vue | 16 +++- frontend/src/views/host/firewall/ip/index.vue | 26 ++++-- .../src/views/host/firewall/port/index.vue | 26 ++++-- .../src/views/host/firewall/status/index.vue | 45 ++++++++-- .../src/views/host/monitor/setting/index.vue | 27 ++++-- .../src/views/host/process/process/index.vue | 3 + frontend/src/views/host/ssh/log/log.vue | 6 +- frontend/src/views/host/ssh/session/index.vue | 3 + .../host/ssh/ssh/certification/index.vue | 10 ++- frontend/src/views/host/ssh/ssh/index.vue | 53 ++++++++++-- frontend/src/views/log/login/index.vue | 4 +- frontend/src/views/log/operation/index.vue | 4 +- frontend/src/views/log/website/index.vue | 6 +- frontend/src/views/toolbox/clam/index.vue | 18 +++- .../src/views/toolbox/clam/operate/index.vue | 16 +++- .../src/views/toolbox/clam/record/index.vue | 16 +++- .../src/views/toolbox/clam/setting/index.vue | 10 ++- .../src/views/toolbox/clam/status/index.vue | 36 ++++++-- frontend/src/views/toolbox/clean/index.vue | 6 +- .../src/views/toolbox/device/dns/index.vue | 4 +- .../views/toolbox/device/hostname/index.vue | 4 +- .../src/views/toolbox/device/hosts/index.vue | 6 +- frontend/src/views/toolbox/device/index.vue | 41 +++++++-- .../src/views/toolbox/device/ntp/index.vue | 28 +++++- .../src/views/toolbox/device/passwd/index.vue | 8 +- .../src/views/toolbox/device/swap/index.vue | 5 +- .../toolbox/fail2ban/ban-action/index.vue | 4 +- .../views/toolbox/fail2ban/ban-time/index.vue | 4 +- .../toolbox/fail2ban/find-time/index.vue | 4 +- frontend/src/views/toolbox/fail2ban/index.vue | 78 ++++++++++++++--- .../src/views/toolbox/fail2ban/ips/index.vue | 4 +- .../views/toolbox/fail2ban/log-path/index.vue | 6 +- .../toolbox/fail2ban/max-retry/index.vue | 4 +- .../src/views/toolbox/fail2ban/port/index.vue | 4 +- frontend/src/views/toolbox/ftp/index.vue | 30 +++++-- .../src/views/toolbox/ftp/operate/index.vue | 14 ++- frontend/src/views/toolbox/index.vue | 6 +- .../toolbox/supervisor/config/basic/index.vue | 4 +- .../supervisor/config/source/index.vue | 4 +- .../views/toolbox/supervisor/create/index.vue | 10 ++- .../views/toolbox/supervisor/file/index.vue | 4 +- .../src/views/toolbox/supervisor/index.vue | 16 +++- .../views/toolbox/supervisor/log/index.vue | 4 +- .../views/toolbox/supervisor/status/index.vue | 24 ++++-- .../toolbox/supervisor/status/init/index.vue | 4 +- .../views/website/runtime/dotnet/index.vue | 17 +++- .../src/views/website/runtime/go/index.vue | 11 ++- .../src/views/website/runtime/java/index.vue | 18 +++- .../src/views/website/runtime/node/index.vue | 18 +++- .../runtime/php/extension-template/index.vue | 7 +- .../src/views/website/runtime/php/index.vue | 18 +++- .../website/runtime/php/supervisor/index.vue | 3 +- .../views/website/runtime/python/index.vue | 18 +++- .../views/website/ssl/acme-account/index.vue | 4 +- frontend/src/views/website/ssl/ca/index.vue | 6 +- .../views/website/ssl/dns-account/index.vue | 5 +- frontend/src/views/website/ssl/index.vue | 32 ++++--- .../website/config/basic/auth-basic/index.vue | 6 +- .../config/basic/load-balance/index.vue | 5 +- .../website/config/basic/proxy/index.vue | 23 +++-- .../website/config/basic/redirect/index.vue | 9 +- frontend/src/views/website/website/index.vue | 32 +++++-- .../website/website/nginx/module/index.vue | 14 ++- 161 files changed, 1950 insertions(+), 503 deletions(-) create mode 100644 frontend/src/composables/useMenuManagePermission.ts diff --git a/frontend/src/components/status/index.vue b/frontend/src/components/status/index.vue index a297791144af..10d887d32a0e 100644 --- a/frontend/src/components/status/index.vue +++ b/frontend/src/components/status/index.vue @@ -21,7 +21,7 @@ - + {{ $t('commons.status.' + statusItem) }} @@ -39,6 +39,7 @@ const props = defineProps({ status: String, msg: String, hasIcon: Boolean, + disabled: Boolean, operate: { type: Boolean, default: false, diff --git a/frontend/src/composables/useMenuManagePermission.ts b/frontend/src/composables/useMenuManagePermission.ts new file mode 100644 index 000000000000..310f10aa1f68 --- /dev/null +++ b/frontend/src/composables/useMenuManagePermission.ts @@ -0,0 +1,73 @@ +import { computed } from 'vue'; +import { useRoute } from 'vue-router'; +import { GlobalStore } from '@/store'; + +const getRoutePermission = (route: ReturnType) => { + const metaPermission = route.meta?.permission; + if (typeof metaPermission === 'string' && metaPermission) { + return metaPermission; + } + + for (const record of [...route.matched].reverse()) { + const permission = record.meta?.permission; + if (typeof permission === 'string' && permission) { + return permission; + } + } + + return ''; +}; + +const toManagePermission = (permission: string) => { + if (!permission) { + return ''; + } + return permission.endsWith('_view') ? permission.replace(/_view$/, '_manage') : permission; +}; + +export const useMenuManagePermission = (permission?: string) => { + const route = useRoute(); + const globalStore = GlobalStore(); + + const sourcePermission = computed(() => { + if (permission) { + return permission; + } + return getRoutePermission(route); + }); + const managePermission = computed(() => { + return toManagePermission(sourcePermission.value); + }); + const hasAdminManagePermission = computed(() => globalStore.isAdmin || globalStore.isNodeAdmin); + const hasPermission = computed(() => { + if (hasAdminManagePermission.value) { + return true; + } + if (!sourcePermission.value) { + return false; + } + if (sourcePermission.value.endsWith('_view')) { + return ( + globalStore.hasPermission(sourcePermission.value) || + globalStore.hasPermission(toManagePermission(sourcePermission.value)) + ); + } + return globalStore.hasPermission(sourcePermission.value); + }); + const hasManagePermission = computed(() => { + if (hasAdminManagePermission.value) { + return true; + } + if (!managePermission.value) { + return false; + } + return globalStore.hasPermission(managePermission.value); + }); + + return { + managePermission, + hasAdminManagePermission, + hasPermission, + hasManagePermission, + }; +}; diff --git a/frontend/src/layout/components/Sidebar/index.vue b/frontend/src/layout/components/Sidebar/index.vue index b7a0c11f9b3f..ad41ff7643e7 100644 --- a/frontend/src/layout/components/Sidebar/index.vue +++ b/frontend/src/layout/components/Sidebar/index.vue @@ -96,22 +96,8 @@ const search = async () => { version.value = ''; } - if (!globalStore.isAdmin) { - menuStore.setMenuList(buildAuthVisibleMenuList(menuList)); - return; - } try { - const hideMenu = JSON.parse(settingInfo?.hideMenu || '[]'); - const showSet = new Set(); - getCheckedLabels(hideMenu, showSet); - const rstMenuList: RouteRecordRaw[] = []; - const resMenuList = adjustAndCleanMenu(hideMenu, menuList); - for (const menu of resMenuList) { - const menuItem = buildVisibleMenu(menu, showSet); - if (menuItem) { - rstMenuList.push(menuItem); - } - } + const rstMenuList = buildMenuListFromSettings(settingInfo?.hideMenu); if (!isSameMenuList(menuStore.menuList as RouteRecordRaw[], rstMenuList)) { menuStore.setMenuList(rstMenuList); } @@ -141,6 +127,21 @@ function allowMenuItem(item: RouteRecordRaw) { return allowed; } +function buildMenuListFromSettings(hideMenuValue?: string) { + const hideMenu = JSON.parse(hideMenuValue || '[]'); + const showSet = new Set(); + getCheckedLabels(hideMenu, showSet); + const rstMenuList: RouteRecordRaw[] = []; + const resMenuList = adjustAndCleanMenu(hideMenu, menuList); + for (const menu of resMenuList) { + const menuItem = buildVisibleMenu(menu, showSet); + if (menuItem) { + rstMenuList.push(menuItem); + } + } + return rstMenuList; +} + function buildAuthVisibleMenuList(source: RouteRecordRaw[]) { return source .map((item) => { diff --git a/frontend/src/store/modules/global.ts b/frontend/src/store/modules/global.ts index de23dc6ab8d1..f1306e3793af 100644 --- a/frontend/src/store/modules/global.ts +++ b/frontend/src/store/modules/global.ts @@ -78,6 +78,9 @@ const GlobalStore = defineStore({ isDarkGoldTheme: (state) => state.themeConfig.primary === '#F0BE96' && state.isProductPro, isNodeAdmin: (state) => state.nodeRoles.some((item) => item.nodeName === state.currentNode && item.roleName === 'Node Admin'), + isAdminOrNodeAdmin: (state) => + state.isAdmin || + state.nodeRoles.some((item) => item.nodeName === state.currentNode && item.roleName === 'Node Admin'), docsUrl: (state) => { if (state.docWithRegion) { return state.isIntl ? INTL_DOCS_URL : CN_DOCS_URL; diff --git a/frontend/src/views/ai/agents/agent/add/index.vue b/frontend/src/views/ai/agents/agent/add/index.vue index a25c8999cc84..483ac88b0f87 100644 --- a/frontend/src/views/ai/agents/agent/add/index.vue +++ b/frontend/src/views/ai/agents/agent/add/index.vue @@ -66,7 +66,13 @@ {{ $t('aiTools.agents.noAccountHint') }} - + {{ $t('commons.button.create') }} @@ -95,7 +101,9 @@ @@ -105,6 +113,7 @@ diff --git a/frontend/src/components/fu/FuInputRwSwitch.vue b/frontend/src/components/fu/FuInputRwSwitch.vue index d33226355ccf..fcdf8e675f08 100644 --- a/frontend/src/components/fu/FuInputRwSwitch.vue +++ b/frontend/src/components/fu/FuInputRwSwitch.vue @@ -42,6 +42,11 @@ const emit = defineEmits(['update:modelValue', 'input', 'blur', 'enter']); const inputRef = ref(); const isWrite = ref(false); +const permissionDisabled = ref(false); + +const effectiveWriteTrigger = computed(() => { + return permissionDisabled.value ? 'disabled' : props.writeTrigger; +}); const displayValue = computed(() => { return props.modelValue === '' || props.modelValue === undefined || props.modelValue === null @@ -61,13 +66,13 @@ const closeWrite = () => { }; const handleReadClick = () => { - if (props.writeTrigger === 'onClick') { + if (effectiveWriteTrigger.value === 'onClick') { openWrite(); } }; const handleReadDblClick = () => { - if (props.writeTrigger === 'onDblclick') { + if (effectiveWriteTrigger.value === 'onDblclick') { openWrite(); } }; @@ -89,4 +94,15 @@ const handleEnter = (event: KeyboardEvent) => { emit('enter', event); closeWrite(); }; + +defineExpose({ + setPermissionDisabled: (disabled: boolean) => { + permissionDisabled.value = disabled; + if (disabled) { + isWrite.value = false; + } + }, + write: openWrite, + read: closeWrite, +}); diff --git a/frontend/src/components/fu/FuReadWriteSwitch.vue b/frontend/src/components/fu/FuReadWriteSwitch.vue index e10293514e86..b03f90dbe70c 100644 --- a/frontend/src/components/fu/FuReadWriteSwitch.vue +++ b/frontend/src/components/fu/FuReadWriteSwitch.vue @@ -39,6 +39,11 @@ const props = defineProps({ const emit = defineEmits(['update:modelValue', 'change']); const isWrite = ref(false); +const permissionDisabled = ref(false); + +const effectiveWriteTrigger = computed(() => { + return permissionDisabled.value ? 'disabled' : props.writeTrigger; +}); const displayValue = computed(() => { const value = props.modelValue !== '' && props.modelValue !== undefined ? props.modelValue : props.data; @@ -58,18 +63,24 @@ const closeWrite = (value?: any) => { }; const handleReadClick = () => { - if (props.writeTrigger === 'onClick') { + if (effectiveWriteTrigger.value === 'onClick') { openWrite(); } }; const handleReadDblClick = () => { - if (props.writeTrigger === 'onDblclick') { + if (effectiveWriteTrigger.value === 'onDblclick') { openWrite(); } }; defineExpose({ + setPermissionDisabled: (disabled: boolean) => { + permissionDisabled.value = disabled; + if (disabled) { + isWrite.value = false; + } + }, write: openWrite, read: closeWrite, }); diff --git a/frontend/src/components/fu/FuSelectRwSwitch.vue b/frontend/src/components/fu/FuSelectRwSwitch.vue index 8ac5a94e64b0..b7a280df73cb 100644 --- a/frontend/src/components/fu/FuSelectRwSwitch.vue +++ b/frontend/src/components/fu/FuSelectRwSwitch.vue @@ -50,6 +50,20 @@ const emit = defineEmits(['update:modelValue', 'input', 'blur', 'change']); const selectRef = ref(); const isWrite = ref(false); +const permissionDisabled = ref(false); + +defineExpose({ + setPermissionDisabled: (disabled: boolean) => { + permissionDisabled.value = disabled; + if (disabled) { + isWrite.value = false; + } + }, +}); + +const effectiveWriteTrigger = computed(() => { + return permissionDisabled.value ? 'disabled' : props.writeTrigger; +}); const displayValue = computed(() => { return props.modelValue === '' || props.modelValue === undefined || props.modelValue === null @@ -70,13 +84,13 @@ const closeWrite = () => { }; const handleReadClick = () => { - if (props.writeTrigger === 'onClick') { + if (effectiveWriteTrigger.value === 'onClick') { openWrite(); } }; const handleReadDblClick = () => { - if (props.writeTrigger === 'onDblclick') { + if (effectiveWriteTrigger.value === 'onDblclick') { openWrite(); } }; diff --git a/frontend/src/components/fu/FuTableOperations.vue b/frontend/src/components/fu/FuTableOperations.vue index 55c9e598edcd..0dbe06f8a883 100644 --- a/frontend/src/components/fu/FuTableOperations.vue +++ b/frontend/src/components/fu/FuTableOperations.vue @@ -59,6 +59,7 @@ import { computed, type PropType } from 'vue'; import { useI18n } from 'vue-i18n'; import { resolveMaybeFn, type FuTableOperationButton } from './shared'; +import { hasManagePermissionAccess } from '@/utils/permission'; defineOptions({ name: 'FuTableOperations' }); @@ -204,7 +205,10 @@ const getMoreButtons = (row: any) => { }; const isButtonDisabled = (button: FuTableOperationButton, row: any) => { - return Boolean(resolveMaybeFn(button.disabled ?? false, row)); + const permissionDisabled = + button.permission !== undefined && + !hasManagePermissionAccess(button.permission === true ? undefined : button.permission); + return permissionDisabled || Boolean(resolveMaybeFn(button.disabled ?? false, row)); }; const handleButtonClick = (button: FuTableOperationButton, row: any) => { diff --git a/frontend/src/components/fu/index.ts b/frontend/src/components/fu/index.ts index e2ab9f74c248..0a1ebe0cc974 100644 --- a/frontend/src/components/fu/index.ts +++ b/frontend/src/components/fu/index.ts @@ -1,6 +1,7 @@ import { type App } from 'vue'; import FuInputRwSwitch from './FuInputRwSwitch.vue'; +import FuDropdownItem from './FuDropdownItem.vue'; import FuReadWriteSwitch from './FuReadWriteSwitch.vue'; import FuSelectRwSwitch from './FuSelectRwSwitch.vue'; import FuStep from './FuStep'; @@ -14,6 +15,7 @@ const components = [ FuTable, FuTableOperations, FuTablePagination, + FuDropdownItem, FuInputRwSwitch, FuReadWriteSwitch, FuSelectRwSwitch, diff --git a/frontend/src/components/fu/shared.ts b/frontend/src/components/fu/shared.ts index e612a3065ad1..c063d3ec014f 100644 --- a/frontend/src/components/fu/shared.ts +++ b/frontend/src/components/fu/shared.ts @@ -1,4 +1,5 @@ import { Comment, Fragment, Text, type VNode } from 'vue'; +import type { PermissionBindingValue } from '@/utils/permission'; export interface FuTableColumnConfig { key: string; @@ -12,6 +13,7 @@ export interface FuTableOperationButton { label?: string | number; click?: (row: any) => void; disabled?: boolean | ((row: any) => boolean); + permission?: true | PermissionBindingValue; show?: boolean | ((row: any) => boolean); type?: string; icon?: any; diff --git a/frontend/src/components/status/index.vue b/frontend/src/components/status/index.vue index 10d887d32a0e..528c245cfcc8 100644 --- a/frontend/src/components/status/index.vue +++ b/frontend/src/components/status/index.vue @@ -21,7 +21,7 @@ - + {{ $t('commons.status.' + statusItem) }} @@ -33,7 +33,7 @@ diff --git a/frontend/src/components/license-import/index.vue b/frontend/src/components/license-import/index.vue index ec9629a05893..7fefabd04b97 100644 --- a/frontend/src/components/license-import/index.vue +++ b/frontend/src/components/license-import/index.vue @@ -61,10 +61,10 @@ import { ref } from 'vue'; import { MsgSuccess } from '@/utils/message'; import { uploadLicense, uploadEnterpriseLicense } from '@/api/modules/setting'; import DockerProxy from '@/components/docker-proxy/index.vue'; -import { GlobalStore } from '@/store'; import { UploadFile, UploadFiles, UploadInstance, UploadProps, UploadRawFile, genFileId } from 'element-plus'; import { getXpackSettingForTheme, loadMasterProductProFromDB, loadProductProFromDB } from '@/utils/xpack'; -const globalStore = GlobalStore(); +import { useGlobalStore } from '@/composables/useGlobalStore'; +const { isIntl, isEnterprise, currentNode, isProductPro, isMasterProductPro, isEnterpriseLicensed } = useGlobalStore(); const em = defineEmits(['search']); @@ -112,7 +112,7 @@ const handleExceed: UploadProps['onExceed'] = (files) => { }; const toLxware = () => { - if (!globalStore.isIntl) { + if (!isIntl.value) { window.open('https://www.lxware.cn/1panel' + '', '_blank', 'noopener,noreferrer'); } else { window.open('https://1panel.pro/pricing' + '', '_blank', 'noopener,noreferrer'); @@ -126,7 +126,7 @@ const submit = async () => { const file = uploaderFiles.value[0]; const formData = new FormData(); formData.append('file', file.raw); - if (globalStore.isEnterprise) { + if (isEnterprise.value) { loading.value = true; await uploadEnterpriseLicense(formData) .then(async () => { @@ -143,7 +143,7 @@ const submit = async () => { formData.append('oldLicenseName', oldLicense.value); } if (!isImport.value) { - formData.append('currentNode', globalStore.currentNode); + formData.append('currentNode', currentNode.value); formData.append('withDockerRestart', withDockerRestart.value); } formData.append('isForce', isForce.value); @@ -166,10 +166,10 @@ const handleAfterSubmit = () => { open.value = false; MsgSuccess(i18n.global.t('commons.msg.operationSuccess')); if (!isImport.value) { - if (!globalStore.isEnterprise) globalStore.isProductPro = true; - globalStore.isMasterProductPro = true; + if (!isEnterprise.value) isProductPro.value = true; + isMasterProductPro.value = true; } else { - globalStore.isEnterpriseLicensed = true; + isEnterpriseLicensed.value = true; } if (!withoutReload.value) { loadMasterProductProFromDB(); diff --git a/frontend/src/components/log/compose/index.vue b/frontend/src/components/log/compose/index.vue index 0af49a0eb2a3..90ee7cf1845e 100644 --- a/frontend/src/components/log/compose/index.vue +++ b/frontend/src/components/log/compose/index.vue @@ -3,7 +3,7 @@ v-model="open" :header="resource" @close="handleClose" - :size="globalStore.isFullScreen ? 'full' : '60%'" + :size="isFullScreen ? 'full' : '60%'" :resource="container" > diff --git a/frontend/src/views/log/system/index.vue b/frontend/src/views/log/system/index.vue index afcec6f81e26..41face13ffe1 100644 --- a/frontend/src/views/log/system/index.vue +++ b/frontend/src/views/log/system/index.vue @@ -14,12 +14,7 @@ {{ $t('commons.button.watch') }} - + @@ -44,8 +39,8 @@ import LogFile from '@/components/log/file/index.vue'; import LogRouter from '@/views/log/router/index.vue'; import { nextTick, onMounted, reactive, ref } from 'vue'; import { getSystemFiles } from '@/api/modules/log'; -import { GlobalStore } from '@/store'; -const globalStore = GlobalStore(); +import { useGlobalStore } from '@/composables/useGlobalStore'; +const { currentNode } = useGlobalStore(); const loading = ref(); const isWatch = ref(); diff --git a/frontend/src/views/login/components/login-form.vue b/frontend/src/views/login/components/login-form.vue index 5c189d30d48e..4f5cf935320c 100644 --- a/frontend/src/views/login/components/login-form.vue +++ b/frontend/src/views/login/components/login-form.vue @@ -52,10 +52,10 @@