flnxi-Wu/app/admin/_hooks/usePermissions.ts
WuYongJie e4dcb6260a
Some checks failed
CI Check / check (push) Has been cancelled
feat: Admin页面重构 & UI三层架构系统
- 创建统一UI三层架构系统(基础层、颜色层、组合层)
- 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等)
- 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等)
- 提取工具函数(validators、formatters、api等)
- 创建统一弹窗组件(Modal)和useModal Hook
- 添加错误边界和统一状态组件
- 完善类型定义和可访问性支持
- 更新文档(优化记录、优化计划、更新日志)
2025-11-22 15:17:10 +08:00

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,
}
}