diff --git a/src/auth/permissions.ts b/src/auth/permissions.ts index e7e60b5..0c73a2e 100644 --- a/src/auth/permissions.ts +++ b/src/auth/permissions.ts @@ -46,7 +46,7 @@ export const PERM = { PERMISSION_READ: 'auth:permission:read', PERMISSION_MANAGE: 'auth:permission:manage', USER_READ: 'admin:user:read', - USER_MANAGE: 'admin:user:manage', + USER_UPDATE: 'admin:user:update', } as const export type Permission = (typeof PERM)[keyof typeof PERM] diff --git a/src/components/layout/nav.ts b/src/components/layout/nav.ts index 68535db..6d90c63 100644 --- a/src/components/layout/nav.ts +++ b/src/components/layout/nav.ts @@ -107,7 +107,7 @@ export const NAV_GROUPS: NavGroup[] = [ { label: '用户与系统', items: [ - { label: '用户列表', to: '/users', icon: Users, permission: 'auth:role:assign' }, + { label: '用户列表', to: '/users', icon: Users, permission: 'admin:user:read' }, { label: '角色管理', to: '/roles', icon: Shield, permission: 'auth:role:read' }, { label: '用户角色', to: '/admin-users', icon: Users, permission: 'auth:role:assign' }, { label: 'SID 管理', to: '/sid', icon: Hash, permission: 'admin:sid:manage' }, diff --git a/src/routes/_authed/users/index.tsx b/src/routes/_authed/users/index.tsx index fb15300..316901b 100644 --- a/src/routes/_authed/users/index.tsx +++ b/src/routes/_authed/users/index.tsx @@ -8,7 +8,7 @@ import type { ColumnDef } from '@tanstack/react-table' import type { PlatformUser } from '@/api/types' import { fetchUsers, updateUserStatus } from '@/api/modules/users' import { fetchRoles, syncUserRoles } from '@/api/modules/roles' -import { useAuthStore } from '@/auth/store' +import { useCan, useAuthStore } from '@/auth/store' import { handleApiError } from '@/lib/errors' import { DataTable } from '@/components/data-table/data-table' import { PageHeader } from '@/components/page-header' @@ -45,13 +45,18 @@ import { Switch } from '@/components/ui/switch' import { UserDetailSheet } from '@/features/users/user-detail-sheet' export const Route = createFileRoute('/_authed/users/')({ - beforeLoad: () => requirePermission(PERM.ROLE_ASSIGN), + beforeLoad: () => requirePermission(PERM.USER_READ), component: UsersPage, }) function UsersPage() { const queryClient = useQueryClient() const myUid = useAuthStore((s) => s.user?.uid) + const isSuperAdmin = useAuthStore((s) => s.roles.includes('super-admin')) + const canUpdateUsers = useCan(PERM.USER_UPDATE) + const canReadRoles = useCan(PERM.ROLE_READ) + const canAssignRoles = useCan(PERM.ROLE_ASSIGN) + const canManageRoles = canReadRoles && canAssignRoles // Filter state const [searchInput, setSearchInput] = useState('') @@ -68,7 +73,11 @@ function UsersPage() { const [togglingUser, setTogglingUser] = useState<{ user: PlatformUser; targetStatus: boolean } | null>(null) // Available roles query for filter dropdown - const rolesQuery = useQuery({ queryKey: ['roles'], queryFn: fetchRoles }) + const rolesQuery = useQuery({ + queryKey: ['roles'], + queryFn: fetchRoles, + enabled: canReadRoles, + }) // Users listing query const usersQuery = useQuery({ @@ -172,11 +181,12 @@ function UsersPage() { cell: ({ row }) => { const u = row.original const isSelf = u.uid === myUid + const isProtectedSuperAdmin = u.roles.includes('super-admin') && !isSuperAdmin return (