From 58be2044480d532f200e2c6373b0adfb7420b7dd Mon Sep 17 00:00:00 2001 From: XingQue Date: Mon, 6 Jul 2026 18:00:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=AE=A1=E7=90=86=E5=91=98=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AF=A6=E6=83=85=E5=BC=B9=E7=AA=97=E5=B4=A9=E6=BA=83?= =?UTF-8?q?=E4=B8=8E=E5=A4=9A=E4=BF=B1=E4=B9=90=E9=83=A8=E5=88=86=E9=85=8D?= =?UTF-8?q?UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- src/utils/club-context.js | 52 +++-- src/views/Layout.vue | 11 +- src/views/Login.vue | 3 +- src/views/admin/AdminUser.vue | 345 ++++++++++++++++++++++++++++++---- src/views/admin/DataScope.vue | 10 +- 5 files changed, 356 insertions(+), 65 deletions(-) diff --git a/src/utils/club-context.js b/src/utils/club-context.js index ec2bf25..c944eab 100644 --- a/src/utils/club-context.js +++ b/src/utils/club-context.js @@ -3,7 +3,7 @@ const CLUB_SCOPE_KEY = 'admin_club_scope'; const CLUB_CONTEXT_KEY = 'admin_club_context'; const MENU_ACCESS_KEY = 'kefu_menu_access'; const MENU_SESSION_KEY = 'kefu_menu_session_v'; -const MENU_SESSION_VERSION = '11'; +const MENU_SESSION_VERSION = '12'; const DEFAULT_CLUB_ID = 'xq'; let menuAccessInflight = null; @@ -25,27 +25,49 @@ export function setAdminClubContext(ctx) { export function mergeServerClubContext(serverCtx) { if (!serverCtx) return; + const allowedIds = new Set((serverCtx.clubs || []).map((c) => c.club_id)); const prevScope = localStorage.getItem(CLUB_SCOPE_KEY); const prevClubId = localStorage.getItem(CLUB_ID_KEY); - const merged = { ...serverCtx }; - if (prevScope) { - merged.scope = prevScope === 'all' ? 'ALL_CLUBS' : 'SINGLE_CLUB'; - merged.club_id = prevClubId || merged.club_id || DEFAULT_CLUB_ID; + + let clubId = serverCtx.club_id || DEFAULT_CLUB_ID; + let scopeKey = serverCtx.scope === 'ALL_CLUBS' ? 'all' : 'single'; + + if (prevClubId && allowedIds.has(prevClubId)) { + clubId = prevClubId; + if (prevScope === 'all' && serverCtx.is_group_admin) { + scopeKey = 'all'; + } else if (prevScope === 'single') { + scopeKey = 'single'; + } + } else if (prevScope === 'all' && serverCtx.is_group_admin) { + scopeKey = 'all'; } - localStorage.setItem(CLUB_CONTEXT_KEY, JSON.stringify(merged)); - if (prevClubId) { - localStorage.setItem(CLUB_ID_KEY, prevClubId); - } else { - localStorage.setItem(CLUB_ID_KEY, merged.club_id || DEFAULT_CLUB_ID); - } - if (prevScope) { - localStorage.setItem(CLUB_SCOPE_KEY, prevScope); - } else { - localStorage.setItem(CLUB_SCOPE_KEY, merged.scope === 'ALL_CLUBS' ? 'all' : 'single'); + + const merged = { + ...serverCtx, + club_id: clubId, + scope: scopeKey === 'all' ? 'ALL_CLUBS' : 'SINGLE_CLUB', + }; + + if (scopeKey === 'single' && merged.assignments?.length) { + const hit = merged.assignments.find((a) => a.club_id === clubId); + if (hit) { + merged.role_code = hit.role_code; + merged.role_name = hit.role_name; + } } + + setAdminClubContext(merged); return merged; } +export function resetAdminClubContextOnLogin() { + localStorage.removeItem(CLUB_ID_KEY); + localStorage.removeItem(CLUB_SCOPE_KEY); + localStorage.removeItem(CLUB_CONTEXT_KEY); + clearMenuAccess(); +} + export function getAdminClubContext() { try { const raw = localStorage.getItem(CLUB_CONTEXT_KEY); diff --git a/src/views/Layout.vue b/src/views/Layout.vue index 08d886c..3eefd4a 100644 --- a/src/views/Layout.vue +++ b/src/views/Layout.vue @@ -268,6 +268,7 @@ import { canSwitchClubByMenu, ensureMenuAccess, canShowMenuPage, + clearMenuAccess, } from '@/utils/club-context' const menuAccessState = ref(getMenuAccess()) @@ -359,14 +360,18 @@ const onScopeSelectChange = (val) => { }) ElMessage.success('已切换至:集团汇总(全部子公司)') } else { + const assign = (ctx.assignments || []).find((a) => a.club_id === val) setAdminClubContext({ ...ctx, scope: 'SINGLE_CLUB', club_id: val, + role_code: assign?.role_code || ctx.role_code, + role_name: assign?.role_name || ctx.role_name, }) const hit = clubOptions.value.find((c) => c.club_id === val) ElMessage.success(`已切换至:${hit?.name || val}`) } + clearMenuAccess() window.location.reload() } @@ -523,9 +528,9 @@ provide('permPrefixMap', permPrefixMap) provide('goeasyAppkey', goeasyAppkey) provide('hasAnyChatPerm', hasAnyChatPerm) -onMounted(() => { - loadMenuAccess() - loadClubContext() +onMounted(async () => { + await loadClubContext() + await loadMenuAccess() fetchStats() fetchKefuPermission() proxy.$emitter?.on('refresh-stats', fetchStats) diff --git a/src/views/Login.vue b/src/views/Login.vue index 055c253..54a448c 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -65,7 +65,7 @@ import { useRouter } from 'vue-router' import { ElMessage } from 'element-plus' import { User, Lock, Key } from '@element-plus/icons-vue' import axios from 'axios' // 直接使用 axios,不经过封装的 request -import { JITUAN_API, getDefaultLandingPath, setAdminClubContext, setMenuAccess } from '@/utils/club-context' +import { JITUAN_API, getDefaultLandingPath, setAdminClubContext, setMenuAccess, resetAdminClubContextOnLogin } from '@/utils/club-context' const router = useRouter() const loading = ref(false) @@ -90,6 +90,7 @@ const handleLogin = async () => { } loading.value = true + resetAdminClubContextOnLogin() try { // 直接使用 axios 发送请求,baseURL 从 window.$baseURL 获取 const response = await axios.post( diff --git a/src/views/admin/AdminUser.vue b/src/views/admin/AdminUser.vue index 76059ad..50da913 100644 --- a/src/views/admin/AdminUser.vue +++ b/src/views/admin/AdminUser.vue @@ -35,8 +35,8 @@ @@ -53,12 +53,31 @@ - + + + + @@ -91,13 +110,15 @@ - +
@@ -140,10 +161,36 @@
+ +
+
+ 俱乐部任职(切换范围) + + 添加俱乐部 + +
+
+
+ + {{ a.club_label }}{{ a.is_primary ? '(主任职)' : '' }} + + {{ a.role_name }} + 移除 +
+
+ 暂未分配俱乐部,添加后该用户顶栏可切换;无角色则看不到菜单 +
+
+
+
- 所属角色 + 功能角色(按俱乐部) 添加角色 @@ -151,10 +198,10 @@
- {{ role.role_name }} + {{ roleClubLabel(role) }} @@ -176,14 +223,28 @@ + + + + + + +
@@ -191,6 +252,8 @@
+
请先选择俱乐部
+
该俱乐部下无可选角色
+ + + + + + + + + + + + + + + + + + + + + +
添加后用户顶栏可切到该俱乐部;再为该俱乐部绑功能角色才有菜单。
+ +
+
@@ -235,11 +332,11 @@
- {{ role.role_name }} + {{ roleClubLabel(role) }}
@@ -249,20 +346,35 @@