Some checks failed
CI Check / check (push) Has been cancelled
- 创建统一UI三层架构系统(基础层、颜色层、组合层) - 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等) - 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等) - 提取工具函数(validators、formatters、api等) - 创建统一弹窗组件(Modal)和useModal Hook - 添加错误边界和统一状态组件 - 完善类型定义和可访问性支持 - 更新文档(优化记录、优化计划、更新日志)
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
'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 currentRole = (sessionUser?.role ?? currentUserRecord?.role) as
|
|
| 'ADMIN'
|
|
| 'USER'
|
|
| undefined
|
|
|
|
const currentIsAdminRole = useMemo(
|
|
() => currentIsSuperAdmin || currentRole === 'ADMIN' || currentUserRecord?.role === 'ADMIN',
|
|
[currentIsSuperAdmin, currentRole, currentUserRecord?.role],
|
|
)
|
|
|
|
const currentManagedDepartment = useMemo(
|
|
() => currentUserRecord?.managedDepartment ?? sessionUser?.managedDepartment,
|
|
[currentUserRecord?.managedDepartment, sessionUser?.managedDepartment],
|
|
)
|
|
|
|
const currentDepartmentScope = useMemo(() => {
|
|
const fallback = (currentUserRecord?.department || '').trim() || undefined
|
|
return currentManagedDepartment || fallback
|
|
}, [currentManagedDepartment, currentUserRecord?.department])
|
|
|
|
const departmentDescendantsMap = useMemo(
|
|
() => buildDepartmentDescendants(departments),
|
|
[departments],
|
|
)
|
|
|
|
const canManageUser = useCallback(
|
|
(target: User) => {
|
|
if (!currentUserId) return false
|
|
if (currentIsSuperAdmin) return true
|
|
if (target.isSuperAdmin) return false
|
|
|
|
const targetDept = (target.department || '').trim()
|
|
if (!targetDept && currentIsAdminRole) {
|
|
return true
|
|
}
|
|
|
|
if (currentDepartmentScope) {
|
|
return isDepartmentWithinScope(
|
|
currentDepartmentScope,
|
|
target.department,
|
|
departmentDescendantsMap,
|
|
)
|
|
}
|
|
|
|
return target.id === currentUserId
|
|
},
|
|
[
|
|
currentDepartmentScope,
|
|
currentIsAdminRole,
|
|
currentIsSuperAdmin,
|
|
currentUserId,
|
|
departmentDescendantsMap,
|
|
],
|
|
)
|
|
|
|
return {
|
|
currentUserId,
|
|
currentIsSuperAdmin,
|
|
canManageUser,
|
|
}
|
|
}
|
|
|
|
|