import bcrypt from 'bcryptjs' import { isValidPersonName, isValidUsername, NAME_RULE_MESSAGE, USERNAME_RULE_MESSAGE } from '~~/server/utils/username' import { db } from '~/drizzle/db' import { users } from '~/drizzle/schema' import { eq } from 'drizzle-orm' import { getRoleLevel, isRoleHigher, canManageUserRole } from '~~/server/utils/permissions' export default defineEventHandler(async (event) => { // 检查认证和权限 const user = event.context.user if (!user || !['ADMIN', 'SUPER_ADMIN'].includes(user.role)) { throw createError({ statusCode: 403, message: '没有权限访问' }) } const body = await readBody(event) // 验证必填字段 if (!body.name || !body.username || !body.password) { throw createError({ statusCode: 400, message: '姓名、账号名和密码不能为空' }) } // 账号名必须是纯中文(唯一例外是管理员账号 admin —— 规则见 utils/username.ts) if (!isValidPersonName(body.name, body.username) || !isValidUsername(body.username)) { throw createError({ statusCode: 400, message: NAME_RULE_MESSAGE + ';' + USERNAME_RULE_MESSAGE }) } try { // 检查用户名是否已存在 const existingUserResult = await db .select() .from(users) .where(eq(users.username, body.username)) .limit(1) const existingUser = existingUserResult[0] if (existingUser) { throw createError({ statusCode: 400, message: '账号名已存在' }) } // 加密密码 const hashedPassword = await bcrypt.hash(body.password, 10) // 角色权限控制(统一使用 canManageUserRole 数值化级别检查) let validRole = 'USER' const requestedRole = body.role if (requestedRole) { if (!canManageUserRole(user, requestedRole)) { const currentLevel = getRoleLevel(user.role) const targetLevel = getRoleLevel(requestedRole) throw createError({ statusCode: 403, message: isRoleHigher(requestedRole, user.role) || currentLevel <= targetLevel ? `权限不足:${user.role} 无法创建级别高于或等于自身的角色(${requestedRole})` : `没有权限创建 ${requestedRole} 角色的用户` }) } validRole = requestedRole } // 状态验证 let validStatus = 'active' if (body.status && ['active', 'withdrawn', 'graduate'].includes(body.status)) { validStatus = body.status } // 创建用户 const newUserResult = await db .insert(users) .values({ name: body.name, username: body.username, password: hashedPassword, role: validRole, status: validStatus as 'active' | 'withdrawn' | 'graduate', grade: body.grade, class: body.class }) .returning({ id: users.id, name: users.name, username: users.username, role: users.role, status: users.status, grade: users.grade, class: users.class, createdAt: users.createdAt, updatedAt: users.updatedAt }) const newUser = newUserResult[0] // 清除相关缓存 try { const { cache } = await import('~~/server/utils/cache-helpers') await cache.deletePattern('songs:*') await cache.deletePattern('stats:*') console.log('[Cache] 歌曲和统计缓存已清除(用户创建)') } catch (cacheError) { console.warn('[Cache] 清除缓存失败:', cacheError) } return { success: true, user: newUser, message: '用户创建成功' } } catch (error) { console.error('创建用户失败:', error) throw createError({ statusCode: 500, message: '创建用户失败' }) } })