diff --git a/src/views/admin/AdminUser.vue b/src/views/admin/AdminUser.vue index 50da913..6b9a738 100644 --- a/src/views/admin/AdminUser.vue +++ b/src/views/admin/AdminUser.vue @@ -110,26 +110,26 @@ - + -
+
基本信息
- {{ currentUser?.yonghuid }} + {{ currentUser?.yonghuid }} - {{ currentUser?.phone }} + {{ currentUser?.phone }} @@ -164,11 +164,20 @@
- 俱乐部任职(切换范围) - + 俱乐部任职(顶栏切换范围) + 添加俱乐部
+
{{ a.club_label }}{{ a.is_primary ? '(主任职)' : '' }} - {{ a.role_name }} - 移除 + 任职:{{ a.role_name }} + 移除
- 暂未分配俱乐部,添加后该用户顶栏可切换;无角色则看不到菜单 + 暂未分配俱乐部;需集团高层添加后,用户顶栏才可切换
- +
- 功能角色(按俱乐部) - - 添加角色 - + 各俱乐部功能角色
-
-
- {{ roleClubLabel(role) }} - - - +
+
+
+ {{ block.club_label }} + 已绑 {{ block.roles.length }} 个 · 可选 {{ block.catalogRoles.length }} 个 +
+ + + 添加角色 +
-
- 暂无角色,点击上方按钮添加 +
+
+ {{ role.role_name || role.role_code }} + + + +
+
该俱乐部暂无功能角色
+
+ 可选角色:{{ block.catalogRoles.map(r => r.role_name).join('、') }} +
+
+
+ 请由集团高层先分配俱乐部任职;再点击各俱乐部「添加角色」绑定菜单权限
@@ -222,9 +253,9 @@ @@ -232,7 +263,7 @@ {{ role.role_name }} + {{ role.role_code }}
@@ -262,7 +294,7 @@ - + @@ -299,7 +331,7 @@ v-model="addUserDialogVisible" title="添加后台用户" width="600px" - class="user-dialog" + class="admin-user-dialog" append-to-body align-center > @@ -377,6 +409,7 @@ const roleClubLabel = (role) => { // 权限状态 const hasPermission = ref(true) +const canManageClubAssignments = ref(false) // 角色列表(用于筛选和添加) const roleList = ref([]) @@ -440,6 +473,53 @@ const availableRolesForUser = computed(() => { ) }) +const roleBindClubOptions = computed(() => { + const fromAssign = (currentUserAssignments.value || []) + .filter((a) => a.club_id) + .map((a) => ({ + club_id: a.club_id, + name: a.club_label || clubNameMap.value[a.club_id] || a.club_id, + })) + if (fromAssign.length) return fromAssign + return clubOptions.value +}) + +const clubRoleBlocks = computed(() => { + const blocks = [] + const assignments = currentUserAssignments.value || [] + const roles = currentUserRoles.value || [] + + const pushBlock = (clubId, clubLabel) => { + const cid = clubId || '' + if (blocks.some((b) => (b.club_id || '') === cid)) return + blocks.push({ + club_id: cid, + club_label: clubLabel || (cid ? (clubNameMap.value[cid] || cid) : '全局角色'), + roles: roles.filter((r) => (r.club_id || '') === cid), + catalogRoles: roleList.value.filter((r) => (r.club_id || '') === cid), + }) + } + + for (const a of assignments) { + if (a.club_id) { + pushBlock(a.club_id, a.club_label) + } + } + + const globalRoles = roles.filter((r) => !r.club_id) + if (globalRoles.length) { + pushBlock('', '全局角色') + } + + if (!assignments.length) { + for (const r of roles) { + pushBlock(r.club_id || '', clubNameMap.value[r.club_id] || r.club_id) + } + } + + return blocks +}) + // 添加用户弹窗 const addUserDialogVisible = ref(false) const newUserForm = ref({ @@ -510,6 +590,7 @@ const fetchUserList = async () => { if (res.code === 0) { userList.value = res.data.list || [] total.value = res.data.total || 0 + canManageClubAssignments.value = !!res.data.can_manage_club_assignments } else { ElMessage.error(res.msg || '获取用户列表失败') } @@ -581,12 +662,16 @@ const saveUserInfo = async () => { } // 为用户添加角色(打开弹窗) -const openAddRoleForUser = () => { +const openAddRoleForClub = (clubId) => { selectedRoleCodes.value = [] - roleBindClubId.value = currentUserAssignments.value[0]?.club_id || clubOptions.value[0]?.club_id || '' + roleBindClubId.value = clubId || roleBindClubOptions.value[0]?.club_id || '' addRoleForUserVisible.value = true } +const openAddRoleForUser = () => { + openAddRoleForClub(roleBindClubOptions.value[0]?.club_id || clubOptions.value[0]?.club_id || '') +} + const openAddClubDialog = () => { clubAssignForm.value = { club_id: availableClubsForAssign.value[0]?.club_id || '', @@ -678,6 +763,7 @@ const confirmAddUserRoles = async () => { const updated = userList.value.find((u) => u.yonghuid === currentUser.value.yonghuid) if (updated) { currentUserRoles.value = [...(updated.roles || [])] + currentUserAssignments.value = [...(updated.assignments || [])] } } else { ElMessage.error(res.msg || '添加失败') @@ -855,28 +941,6 @@ onMounted(async () => { display: flex; justify-content: flex-end; } -:deep(.el-dialog) { - background: rgba(6,12,20,0.95); - backdrop-filter: blur(20px); - border: 1px solid rgba(0,242,255,0.3); - border-radius: 20px; -} -:deep(.el-dialog__title) { - color: #00f2ff; -} -:deep(.el-form-item__label) { - color: rgba(255,255,255,0.8); -} -:deep(.el-input__wrapper) { - background: rgba(0,0,0,0.5); - border-color: rgba(0,242,255,0.3); -} -:deep(.el-input__inner) { - color: #fff; -} -:deep(.el-input__inner::placeholder) { - color: rgba(255,255,255,0.4); -} .section-title { font-size: 18px; font-weight: bold; @@ -913,6 +977,10 @@ onMounted(async () => { padding: 20px 0; text-align: center; } +.empty-role.inline-empty { + padding: 8px 0; + text-align: left; +} .muted-text { color: rgba(255,255,255,0.45); font-size: 13px; @@ -935,6 +1003,37 @@ onMounted(async () => { color: rgba(255,255,255,0.65); font-size: 13px; } +.club-role-block { + margin-bottom: 16px; + padding: 14px; + background: rgba(0, 0, 0, 0.25); + border: 1px solid rgba(0, 242, 255, 0.18); + border-radius: 10px; +} +.club-block-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} +.club-block-title { + color: #00f2ff; + font-size: 15px; +} +.club-block-meta { + margin-left: 10px; + color: rgba(255, 255, 255, 0.45); + font-size: 12px; +} +.catalog-hint { + margin-top: 8px; + font-size: 12px; + color: rgba(255, 255, 255, 0.5); + line-height: 1.5; +} +.scope-hint { + margin-bottom: 12px; +} .role-select-list { max-height: 400px; overflow-y: auto; @@ -945,9 +1044,95 @@ onMounted(async () => { background: rgba(255,255,255,0.05); border-radius: 8px; } +.role-code-tag { + margin-left: 8px; + font-size: 12px; + color: rgba(255, 255, 255, 0.45); +} .form-hint { font-size: 12px; color: rgba(255,255,255,0.5); margin-top: 4px; } + + + + \ No newline at end of file