Files
BYW-VoiceHub/server/api/admin/users/index.post.ts
T
Henry_Du 1106aeea6c feat: 迁移自定义功能至 1.5.9.9 版本
包含音乐源限制、CI 防 OOM 优化、数据库连接池优化、管理端权限及 UI 细节定制等功能
2026-09-12 19:26:42 +08:00

126 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import bcrypt from 'bcryptjs'
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: '姓名、账号名和密码不能为空'
})
}
// 验证姓名和用户名只能包含汉字
const chineseRegex = /^[\u4e00-\u9fa5]+$/
if (!chineseRegex.test(body.name) || !chineseRegex.test(body.username)) {
throw createError({
statusCode: 400,
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: '创建用户失败'
})
}
})