flnxi-Wu/app/admin/_hooks/usePermissions.ts
2026-05-28 23:27:15 +08:00

88 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* usePermissions Hook
*
* 权限检查Hook
* 统一管理用户权限检查逻辑
* 包括:是否可管理用户、是否超级管理员等
*
* @created 2025-01-XX(从 page.tsx 提取)
* @hook
*/
'use client'
import { useCallback, useMemo } from 'react'
import { buildDepartmentDescendants, isDepartmentWithinScope } from '@/lib/departments'
import type { Department, User } from '../_components/types'
interface UsePermissionsOptions {
sessionUser?: Record<string, any> | null
users: User[]
departments: Department[]
}
export default function usePermissions({
sessionUser,
users,
departments,
}: UsePermissionsOptions) {
const currentUserId = sessionUser?.id as string | undefined
const currentUserRecord = useMemo(
() => (currentUserId ? users.find((user) => user.id === currentUserId) : undefined),
[currentUserId, users],
)
const currentIsSuperAdmin = useMemo(
() => Boolean(currentUserRecord?.isSuperAdmin ?? sessionUser?.isSuperAdmin),
[currentUserRecord, sessionUser],
)
const currentManagedDepartment = useMemo(
() => currentUserRecord?.managedDepartment ?? sessionUser?.managedDepartment,
[currentUserRecord?.managedDepartment, sessionUser?.managedDepartment],
)
const currentDepartmentScope = useMemo(() => {
const trimmed = (currentManagedDepartment || '').trim()
return trimmed || undefined
}, [currentManagedDepartment])
const departmentDescendantsMap = useMemo(
() => buildDepartmentDescendants(departments),
[departments],
)
const canManageUser = useCallback(
(target: User) => {
if (!currentUserId) return false
if (currentIsSuperAdmin) return true
if (target.isSuperAdmin) return false
if (currentDepartmentScope) {
return isDepartmentWithinScope(
currentDepartmentScope,
target.department,
departmentDescendantsMap,
)
}
return target.id === currentUserId
},
[
currentDepartmentScope,
currentIsSuperAdmin,
currentUserId,
departmentDescendantsMap,
],
)
return {
currentUserId,
currentIsSuperAdmin,
canManageUser,
}
}