WuYongJie f646b71813
Some checks failed
CI Check / check (push) Has been cancelled
chore: 初始化本地仓库并同步最近改动
2025-11-18 17:50:16 +08:00

157 lines
4.3 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import bcrypt from 'bcryptjs'
export async function POST(req: NextRequest) {
try {
// 检查注册功能是否开启
const settings = await prisma.systemSettings.findFirst()
if (settings && !settings.enableRegistration) {
return NextResponse.json(
{ error: '注册功能已关闭,请联系管理员' },
{ status: 403 }
)
}
const { email, username, department, password, inviteCode } = await req.json()
// Validation
if (!email || !username || !password) {
return NextResponse.json(
{ error: '所有字段都是必填的' },
{ status: 400 }
)
}
// 如果注册功能关闭,检查是否有有效的邀请码
if (settings && !settings.enableRegistration) {
if (!inviteCode) {
return NextResponse.json(
{ error: '注册功能已关闭,请使用邀请链接注册' },
{ status: 403 }
)
}
// 验证邀请码
const invitation = await prisma.invitation.findUnique({
where: { code: inviteCode },
})
if (!invitation || !invitation.isActive) {
return NextResponse.json(
{ error: '邀请码无效或已失效' },
{ status: 403 }
)
}
if (invitation.currentUses >= invitation.maxUses) {
return NextResponse.json(
{ error: '邀请码使用次数已用完' },
{ status: 403 }
)
}
if (invitation.expiresAt && new Date() > invitation.expiresAt) {
return NextResponse.json(
{ error: '邀请码已过期' },
{ status: 403 }
)
}
}
// Check if user exists
const existingUser = await prisma.user.findFirst({
where: {
OR: [{ email }, { username }],
},
})
if (existingUser) {
return NextResponse.json(
{ error: '邮箱或用户名已存在' },
{ status: 400 }
)
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10)
// 如果启用了用户激活功能,新用户默认未激活
const isActive = settings?.enableUserActivation ? false : true
// 使用事务确保首位用户判断的原子性,避免并发问题
const user = await prisma.$transaction(async (tx) => {
// 在事务中判断是否为首个注册用户(赋予最高权限)
const totalUsers = await tx.user.count()
const isFirstUser = totalUsers === 0
if (isFirstUser) {
console.log('🎉 首位用户注册,自动授予超级管理员权限:', { email, username })
}
// 如果指定了部门,查找该部门的管理员作为直属上级
let parentId: string | null = null
if (department && !isFirstUser) {
const departmentManager = await tx.user.findFirst({
where: {
managedDepartment: department,
role: 'ADMIN',
},
select: { id: true },
})
if (departmentManager) {
parentId = departmentManager.id
}
}
// Create user
const newUser = await tx.user.create({
data: {
email,
username,
department: department || '',
password: hashedPassword,
isActive,
parentId,
// 首位用户自动设为超级管理员,拥有最高权限
isSuperAdmin: isFirstUser,
role: isFirstUser ? 'ADMIN' : 'USER', // 首位用户同时设置为 ADMIN 角色
} as any,
})
// 如果使用了邀请码,更新邀请码使用记录
if (inviteCode) {
await tx.invitation.update({
where: { code: inviteCode },
data: {
currentUses: { increment: 1 },
usedBy: newUser.id,
usedAt: new Date(),
},
})
}
return newUser
})
return NextResponse.json(
{ message: '注册成功', user: {
id: user.id,
email: user.email,
username: user.username,
department: user.department,
role: user.role,
createdAt: user.createdAt,
}},
{ status: 201 }
)
} catch (error) {
console.error('Registration error:', error)
return NextResponse.json(
{ error: '注册失败,请稍后再试' },
{ status: 500 }
)
}
}