Files
2026-04-25 11:26:33 +08:00

88 lines
2.6 KiB
TypeScript

import { NextResponse, type NextRequest } from "next/server";
import { requireApiAdmin } from "@/lib/api-auth";
import { getUserById, updateUserRecord } from "@/lib/db";
import { hashPassword, toPublicUser } from "@/lib/auth";
import { getQuotaSnapshotForUser } from "@/lib/quota";
import { jsonError, normalizeError } from "@/lib/http";
export const runtime = "nodejs";
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> },
) {
try {
const adminUser = requireApiAdmin(request);
const body = (await request.json()) as {
role?: unknown;
monthlyQuota?: unknown;
isActive?: unknown;
password?: unknown;
};
const { id } = await params;
const targetUser = getUserById(id);
const monthlyQuota =
typeof body?.monthlyQuota === "number" ||
typeof body?.monthlyQuota === "string"
? body.monthlyQuota
: undefined;
const password = typeof body?.password === "string" ? body.password : "";
if (!targetUser) {
return jsonError("用户不存在。", 404);
}
if (targetUser.id === adminUser.id) {
if (body?.role && body.role !== "admin") {
return jsonError("不能移除当前管理员自己的 admin 身份。", 400);
}
if (body?.isActive === false) {
return jsonError("不能禁用当前管理员自己的账号。", 400);
}
}
const updatedUser = updateUserRecord(targetUser.id, {
role: body?.role === "admin" ? "admin" : "user",
monthlyQuota:
body?.role === "admin"
? null
: monthlyQuota === null || monthlyQuota === ""
? null
: monthlyQuota,
isActive:
body?.isActive === undefined
? targetUser.isActive
: Boolean(body.isActive),
passwordHash:
password.trim().length >= 8 ? hashPassword(password) : undefined,
});
if (!updatedUser) {
return jsonError("用户不存在。", 404);
}
const publicUser = toPublicUser(updatedUser);
if (!publicUser) {
return jsonError("保存用户失败。", 500);
}
const quota = getQuotaSnapshotForUser(publicUser);
return NextResponse.json({
ok: true,
user: {
...publicUser,
usedThisPeriod: quota.used,
remaining: quota.remaining,
limit: quota.limit,
isUnlimited: quota.isUnlimited,
},
});
} catch (error) {
const normalizedError = normalizeError(error, "保存用户失败。");
return jsonError(normalizedError.message, normalizedError.statusCode);
}
}