import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { Prisma } from '@prisma/client' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { isCurrentSuperAdmin } from '@/lib/admin-permissions' import { planDepartmentScopeWithPaidCore } from '@/lib/license' // Get all users (admin only) - 支持分页 export async function GET(request: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || (session.user as any).role !== 'ADMIN') { return NextResponse.json( { error: '无权限' }, { status: 403 } ) } const currentUser = await prisma.user.findUnique({ where: { id: (session.user as any).id }, select: { id: true, role: true, department: true, managedDepartment: true, isSuperAdmin: true, }, }) if (!currentUser || (currentUser.role !== 'ADMIN' && !currentUser.isSuperAdmin)) { return NextResponse.json( { error: '无权限' }, { status: 403 } ) } const { searchParams } = new URL(request.url) const page = parseInt(searchParams.get('page') || '1', 10) const pageSize = Math.min(parseInt(searchParams.get('pageSize') || '20', 10), 100) // 最大100条 const skip = (page - 1) * pageSize const keyword = searchParams.get('search')?.trim() || '' const keywordWhere: Prisma.UserWhereInput | undefined = keyword ? { OR: [ { username: { contains: keyword, mode: 'insensitive' as const } }, { email: { contains: keyword, mode: 'insensitive' as const } }, { department: { contains: keyword, mode: 'insensitive' as const } }, ], } : undefined let scopeWhere: Prisma.UserWhereInput | undefined if (!currentUser.isSuperAdmin) { const scopeDepartment = (currentUser.managedDepartment || '').trim() if (scopeDepartment) { const departments = await prisma.department.findMany({ select: { name: true } }) const scopePlan = await planDepartmentScopeWithPaidCore({ scopeDepartment, departments, }) scopeWhere = scopePlan.valid && scopePlan.scopedDepartments.length > 0 ? { OR: [ { id: currentUser.id }, { department: { in: scopePlan.scopedDepartments } }, { department: { startsWith: `${scopeDepartment}-` } }, ], } : { id: currentUser.id } } else { scopeWhere = { id: currentUser.id } } } // 并行查询总数和数据 const filters = [scopeWhere, keywordWhere].filter((filter): filter is Prisma.UserWhereInput => Boolean(filter)) const where: Prisma.UserWhereInput = filters.length ? { AND: filters } : {} const [total, users] = await Promise.all([ prisma.user.count({ where }), prisma.user.findMany({ where, select: { id: true, email: true, username: true, parentId: true, role: true, isActive: true, canDownload: true, department: true, managedDepartment: true, isSuperAdmin: true, createdAt: true, _count: { select: { materials: true, }, }, }, orderBy: { createdAt: 'asc', // 按创建时间升序,第一个用户就是最高权限账号 }, skip, take: pageSize, }) ]) return NextResponse.json({ users, pagination: { page, pageSize, total, totalPages: Math.ceil(total / pageSize) } }) } catch (error) { console.error('[AdminUsers] Get error:', error) return NextResponse.json( { error: '获取用户列表失败' }, { status: 500 } ) } } // Delete user (super admin only) export async function DELETE(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json( { error: '仅最高权限账号可删除用户' }, { status: 403 } ) } const { searchParams } = new URL(req.url) const id = searchParams.get('id') if (!id) { return NextResponse.json( { error: '缺少用户ID' }, { status: 400 } ) } // Don't allow deleting self if (id === (session.user as any).id) { return NextResponse.json( { error: '不能删除自己' }, { status: 400 } ) } const targetUser = await prisma.user.findUnique({ where: { id }, select: { isSuperAdmin: true }, }) if (!targetUser) { return NextResponse.json( { error: '用户不存在' }, { status: 404 } ) } if (targetUser.isSuperAdmin) { return NextResponse.json( { error: '不能删除最高权限账号' }, { status: 403 } ) } await prisma.user.delete({ where: { id }, }) return NextResponse.json({ message: '删除成功' }) } catch (error) { console.error('Error deleting user:', error) return NextResponse.json( { error: '删除失败' }, { status: 500 } ) } }