import { NextRequest, NextResponse } from 'next/server' import { Prisma } from '@prisma/client' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { isSuperAdmin } from '@/lib/department-permission' import { BINDING_STATUS } from '@/lib/employee-directory' import { findNearestGroupMemberships } from '@/lib/organization-material-permissions' import { ensureDefaultPermissionPacks } from '@/lib/user-permission-inherit' async function requireSuperAdmin() { const session = await getServerSession(authOptions) const userId = (session?.user as { id?: string } | undefined)?.id if (!session || !(await isSuperAdmin(userId))) return null return session } export async function GET(request: NextRequest) { try { if (!(await requireSuperAdmin())) { return NextResponse.json({ error: '需要超级管理员权限' }, { status: 403 }) } await ensureDefaultPermissionPacks() const keyword = String(new URL(request.url).searchParams.get('q') || '').trim() if (keyword.length < 1) { return NextResponse.json({ people: [], groups: [] }) } const [bindings, packs] = await Promise.all([ prisma.userEmployeeBinding.findMany({ where: { status: BINDING_STATUS.ACTIVE, user: { isActive: true, dingtalkUserId: { not: null } }, OR: [ { user: { username: { contains: keyword, mode: 'insensitive' } } }, { user: { realName: { contains: keyword, mode: 'insensitive' } } }, { employeeProfile: { displayName: { contains: keyword, mode: 'insensitive' } } }, { employeeProfile: { jobNumber: { contains: keyword, mode: 'insensitive' } } }, ], }, take: 20, select: { userId: true, user: { select: { username: true, realName: true, permissionInherits: { select: { pack: { select: { slug: true, name: true } } }, }, }, }, employeeProfile: { select: { displayName: true, departmentPath: true, departmentName: true, jobNumber: true }, }, }, }), prisma.materialPermissionPack.findMany({ orderBy: { name: 'asc' }, select: { id: true, slug: true, name: true }, }), ]) const departmentRows = await prisma.materialPermissionPackDepartment .findMany({ select: { packId: true, departmentPath: true }, }) .catch((error) => { if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2021') { return [] as Array<{ packId: string; departmentPath: string }> } throw error }) const memberships = departmentRows.flatMap((row) => { const pack = packs.find((item) => item.id === row.packId) if (!pack) return [] return [{ departmentPath: row.departmentPath, slug: pack.slug, name: pack.name }] }) return NextResponse.json({ groups: packs.map((pack) => ({ slug: pack.slug, name: pack.name })), people: bindings.map((binding) => { const path = binding.employeeProfile.departmentPath const nearest = path ? findNearestGroupMemberships(path, memberships) : null const personalGroups = binding.user.permissionInherits.map((row) => ({ slug: row.pack.slug, name: row.pack.name, })) return { userId: binding.userId, username: binding.user.username, displayName: binding.employeeProfile.displayName || binding.user.realName || binding.user.username, jobNumber: binding.employeeProfile.jobNumber, departmentPath: path, departmentName: binding.employeeProfile.departmentName, departmentGroups: nearest ? nearest.items.map((item) => ({ slug: item.slug, name: item.name, attachedPath: nearest.attachedPath, source: nearest.attachedPath === path ? 'own' : 'inherit', })) : [], personalGroups, } }), }) } catch (error) { console.error('[user-permissions] GET failed', error) return NextResponse.json({ error: '搜索人员权限失败' }, { status: 500 }) } } export async function PUT(request: NextRequest) { try { if (!(await requireSuperAdmin())) { return NextResponse.json({ error: '需要超级管理员权限' }, { status: 403 }) } const body = await request.json() const action = String(body?.action || '').trim() const userId = String(body?.userId || '').trim() const slug = String(body?.slug || '').trim() if (!userId) return NextResponse.json({ error: '请选择人员' }, { status: 400 }) if (!slug) return NextResponse.json({ error: '缺少权限组' }, { status: 400 }) const [user, pack] = await Promise.all([ prisma.user.findUnique({ where: { id: userId }, select: { id: true, dingtalkUserId: true }, }), prisma.materialPermissionPack.findUnique({ where: { slug }, select: { id: true }, }), ]) if (!user) return NextResponse.json({ error: '没有这个账号' }, { status: 400 }) if (!user.dingtalkUserId) { return NextResponse.json({ error: '这个账号没有钉钉绑定,不能进权限组' }, { status: 400 }) } if (!pack) return NextResponse.json({ error: '没有这个权限组' }, { status: 400 }) if (action === 'remove-member') { await prisma.userPermissionInherit.deleteMany({ where: { userId, packId: pack.id }, }) return NextResponse.json({ ok: true }) } if (action === 'add-member') { await prisma.userPermissionInherit.upsert({ where: { userId_packId: { userId, packId: pack.id } }, update: {}, create: { userId, packId: pack.id }, }) return NextResponse.json({ ok: true }) } return NextResponse.json({ error: '不认识这个操作' }, { status: 400 }) } catch (error) { console.error('[user-permissions] PUT failed', error) return NextResponse.json({ error: '保存人员权限失败' }, { status: 500 }) } }