import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; import { isSystemAdmin } from '@/lib/department-permission'; // GET /api/admin/users - 获取用户列表 export async function GET() { try { const session = await getServerSession(authOptions); if (!session || !session.user || !isSystemAdmin((session.user as any).role)) { return NextResponse.json({ error: '无权限' }, { status: 403 }); } const users = await prisma.user.findMany({ select: { id: true, email: true, username: true, realName: true, // 真实姓名(用于搜索) role: true, isActive: true, // 保留,向后兼容 status: true, // 新增:用户状态(阶段一) canDownload: true, department: true, // 保留,向后兼容 departmentId: true, // 新增:部门ID(阶段二) managedDepartment: true, // 管理员负责的部门 createdAt: true, lastLoginAt: true, // 新增:最后登录时间(阶段一) loginCount: true, // 新增:登录次数(阶段一) archivedAt: true, // 新增:归档时间(阶段一) departmentRef: { // 新增:部门关联信息(阶段二) select: { id: true, name: true, } }, _count: { select: { materials: { where: { deletedAt: null, } as any, }, }, }, }, orderBy: { createdAt: 'desc', }, }); // 批量查询活跃绑定,附加权威部门路径(避免 N+1) // 权威人员数据:UserEmployeeBinding -> PerformanceSurveyEmployeeProfile.departmentPath const activeBindings = await prisma.userEmployeeBinding.findMany({ where: { status: 'ACTIVE' }, select: { userId: true, employeeProfile: { select: { departmentPath: true, departmentName: true, displayName: true, positionLevel: true, levelType: true, isLeadership: true, employmentState: true, }, }, }, }); const bindingMap = new Map( activeBindings .filter((b) => b.employeeProfile) .map((b) => [ b.userId, { departmentPath: b.employeeProfile!.departmentPath, departmentName: b.employeeProfile!.departmentName, displayName: b.employeeProfile!.displayName, positionLevel: b.employeeProfile!.positionLevel, levelType: b.employeeProfile!.levelType, isLeadership: b.employeeProfile!.isLeadership, employmentState: b.employeeProfile!.employmentState, }, ]), ); // 附加权威部门字段到每个用户 const enriched = users.map((u) => { const binding = bindingMap.get(u.id); return { ...u, // 权威部门路径(新组织树),如「江苏简尚品牌管理有限公司/运营中心G/运营一部(CZ)」 employeeDeptPath: binding?.departmentPath ?? null, // 权威部门名(最后一段) employeeDeptName: binding?.departmentPath ? binding.departmentPath.split('/').pop() ?? null : null, employeeDisplayName: binding?.displayName ?? null, employeePositionLevel: binding?.positionLevel ?? null, employeeLevelType: binding?.levelType ?? null, employeeIsLeadership: binding?.isLeadership ?? false, employeeEmploymentState: binding?.employmentState ?? null, // 是否有权威绑定(无绑定 = 待人工确认) hasEmployeeBinding: binding != null, }; }); return NextResponse.json(enriched); } catch (error) { console.error('Error fetching users:', error); return NextResponse.json({ error: '获取用户列表失败' }, { status: 500 }); } } // DELETE /api/admin/users - 归档用户(保留其素材和历史记录) export async function DELETE(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session || !session.user || !isSystemAdmin((session.user as any).role)) { return NextResponse.json({ error: '无权限' }, { status: 403 }); } const { searchParams } = new URL(request.url); const id = searchParams.get('id'); if (!id) { return NextResponse.json({ error: '缺少用户ID' }, { status: 400 }); } // 不能删除自己 if (id === (session.user as any).id) { return NextResponse.json({ error: '不能删除自己' }, { status: 400 }); } const existingUser = await prisma.user.findUnique({ where: { id }, select: { id: true, status: true }, }); if (!existingUser) { return NextResponse.json({ error: '用户不存在' }, { status: 404 }); } await prisma.user.update({ where: { id }, data: { status: 'archived', isActive: false, archivedAt: new Date(), statusChangedAt: new Date(), statusChangedBy: (session.user as any).id, }, }); return NextResponse.json({ message: '用户已归档,素材和历史记录已保留' }); } catch (error) { console.error('Error deleting user:', error); return NextResponse.json({ error: '归档失败' }, { status: 500 }); } }