From d2cd80be731566d51383d6aadd1d006ab588daa1 Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 18 Nov 2025 23:46:10 +0800 Subject: [PATCH] hide pagetype and workspace menus for non-System User in menu management --- .../src/views/settings/MenuManager.vue | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/apps/jingrow/frontend/src/views/settings/MenuManager.vue b/apps/jingrow/frontend/src/views/settings/MenuManager.vue index 3191cb9..8bc247e 100644 --- a/apps/jingrow/frontend/src/views/settings/MenuManager.vue +++ b/apps/jingrow/frontend/src/views/settings/MenuManager.vue @@ -126,11 +126,13 @@ import { ref, h, computed } from 'vue' import { NButton, NSpace, NDataTable, NModal, NForm, NFormItem, NInput, NSelect, NInputNumber, NSwitch, NText, useDialog, type FormInst, type FormRules } from 'naive-ui' import { useMenuStore, type AppMenuItem } from '../../shared/stores/menu' +import { useAuthStore } from '../../shared/stores/auth' import { pageTypeToSlug } from '../../shared/utils/slug' import IconPicker from '../../core/components/IconPicker.vue' import { t } from '../../shared/i18n' const menuStore = useMenuStore() +const authStore = useAuthStore() // 将扁平 items 构造成树形(不修改原数据) function buildTree(items: AppMenuItem[]) { const byId: Record = {} @@ -156,7 +158,21 @@ function buildTree(items: AppMenuItem[]) { return roots } -const displayItems = computed(() => (draggedItem.value ? previewItems.value : menuStore.items)) +// 根据用户类型过滤菜单项 +const filteredItems = computed(() => { + const userType = authStore.user?.user_type + const isSystemUser = userType === 'System User' + + return menuStore.items.filter(m => { + // 非 System User 过滤掉 pagetype 和 workspace 类型 + if (!isSystemUser && (m.type === 'pagetype' || m.type === 'workspace')) { + return false + } + return true + }) +}) + +const displayItems = computed(() => (draggedItem.value ? previewItems.value : filteredItems.value)) const tableData = computed(() => buildTree(displayItems.value)) const dialog = useDialog() @@ -209,18 +225,31 @@ const rules: FormRules = { type: [{ required: true, message: t('Please select menu type') }], } -const typeOptions = [ - { label: t('PageType'), value: 'pagetype' }, - { label: t('Route'), value: 'route' }, - { label: t('URL'), value: 'url' }, - { label: t('Workspace'), value: 'workspace' }, - { label: t('Group'), value: 'group' } -] +const typeOptions = computed(() => { + const userType = authStore.user?.user_type + const isSystemUser = userType === 'System User' + + const allOptions = [ + { label: t('PageType'), value: 'pagetype' }, + { label: t('Route'), value: 'route' }, + { label: t('URL'), value: 'url' }, + { label: t('Workspace'), value: 'workspace' }, + { label: t('Group'), value: 'group' } + ] + + // 非 System User 过滤掉 pagetype 和 workspace 选项 + if (!isSystemUser) { + return allOptions.filter(opt => opt.value !== 'pagetype' && opt.value !== 'workspace') + } + + return allOptions +}) const parentMenuOptions = computed(() => { - const opts = menuStore.items.map(m => ({ label: m.label, value: m.id })) + // 使用过滤后的菜单项作为父菜单选项 + const opts = filteredItems.value.map(m => ({ label: m.label, value: m.id })) return [{ label: t('None'), value: null as any }].concat(opts) }) @@ -235,12 +264,15 @@ const previewUrl = computed(() => { function openCreate() { editing.value = null + const userType = authStore.user?.user_type + const isSystemUser = userType === 'System User' + form.value = { id: '', key: '', label: '', icon: '', - type: 'pagetype', // 默认选择页面类型 + type: isSystemUser ? 'pagetype' : 'route', // 根据用户类型设置默认类型 pagetype: '', routeName: '', url: '', @@ -278,6 +310,18 @@ function onPageTypeChange() { function save() { const data = { ...form.value } + // 验证:非 System User 不允许保存 pagetype 和 workspace 类型 + const userType = authStore.user?.user_type + const isSystemUser = userType === 'System User' + if (!isSystemUser && (data.type === 'pagetype' || data.type === 'workspace')) { + dialog.error({ + title: t('Permission Denied'), + content: t('Non-System User cannot create or edit pagetype and workspace menu items'), + positiveText: t('OK') + }) + return + } + // 根据类型设置key if (data.type === 'pagetype' && data.pagetype) { data.key = pageTypeToSlug(data.pagetype)