import { createError, defineEventHandler, getRouterParam, readBody } from 'h3' import { db } from '~/drizzle/db' import { users, userStatusLogs } from '~/drizzle/schema' import { eq } from 'drizzle-orm' import { getBeijingTime } from '~/utils/timeUtils' import { getStatusText } from '~~/server/utils/user' import { createApiError } from '~~/server/utils/apiError' import { SERVER_ERROR_CODES } from '~~/server/config/constants' export default defineEventHandler(async (event) => { try { // 检查认证和权限 const user = event.context.user if (!user || !['ADMIN', 'SUPER_ADMIN'].includes(user.role)) { throw createError({ statusCode: 403, message: '没有权限访问' }) } const userId = getRouterParam(event, 'id') const body = await readBody(event) const { status, reason } = body // 验证必填字段 if (!status || !['active', 'withdrawn', 'graduate'].includes(status)) { throw createError({ statusCode: 400, message: '状态必须为 active, withdrawn 或 graduate' }) } if (!reason || reason.trim().length === 0) { throw createError({ statusCode: 400, message: '变更原因为必填项' }) } // 检查用户是否存在 const existingUser = await db .select({ id: users.id, name: users.name, username: users.username, status: users.status, role: users.role }) .from(users) .where(eq(users.id, parseInt(userId))) .limit(1) if (existingUser.length === 0) { throw createError({ statusCode: 404, message: '用户不存在' }) } const targetUser = existingUser[0] // 待审核用户不得通过状态接口直接置为 active(须走注册审核流程) if (targetUser.status === 'pending' && status === 'active') { throw createApiError(400, SERVER_ERROR_CODES.USER_NOT_PENDING, '待审核用户需通过注册审核流程处理') } // 检查是否为学生用户 if (targetUser.role !== 'USER') { throw createError({ statusCode: 400, message: '只能修改学生用户的状态' }) } // 检查状态是否有变化 if (targetUser.status === status) { throw createError({ statusCode: 400, message: '用户状态未发生变化' }) } const currentTime = getBeijingTime() const oldStatus = targetUser.status // 开始事务 await db.transaction(async (tx) => { // 更新用户状态 await tx .update(users) .set({ status: status, statusChangedAt: currentTime, statusChangedBy: user.id }) .where(eq(users.id, parseInt(userId))) // 记录状态变更日志 await tx.insert(userStatusLogs).values({ userId: parseInt(userId), oldStatus: oldStatus, newStatus: status, reason: reason.trim(), operatorId: user.id, createdAt: currentTime }) }) return { success: true, message: `用户状态已更新为${getStatusText(status)}`, data: { userId: parseInt(userId), oldStatus, newStatus: status, changedAt: currentTime, changedBy: user.name } } } catch (error) { console.error('更新用户状态失败:', error) if (error.statusCode) { throw error } throw createError({ statusCode: 500, message: '更新用户状态失败: ' + error.message }) } })