Files
wr.do/lib/dto/user.ts
2025-07-04 16:44:05 +08:00

239 lines
5.2 KiB
TypeScript

import { User, UserRole } from "@prisma/client";
import { prisma } from "@/lib/db";
import { hashPassword, verifyPassword } from "../utils";
export interface UpdateUserForm
extends Omit<User, "id" | "createdAt" | "updatedAt" | "emailVerified"> {}
export const getUserByEmail = async (email: string) => {
try {
const user = await prisma.user.findUnique({
where: {
email: email,
},
select: {
id: true,
name: true,
emailVerified: true,
active: true,
team: true,
},
});
return user;
} catch {
return null;
}
};
export const getUserById = async (id: string) => {
try {
const user = await prisma.user.findUnique({ where: { id } });
return user;
} catch {
return null;
}
};
export const getAllUsers = async (
page: number,
size: number,
email?: string,
userName?: string,
) => {
try {
let options;
if (email) {
options = { where: { email: { contains: email } } };
}
if (userName) {
options = { where: { name: { contains: userName } } };
}
if (email && userName) {
options = {
where: { email: { contains: email }, name: { contains: userName } },
};
}
const [total, list] = await prisma.$transaction([
prisma.user.count(options),
prisma.user.findMany({
skip: (page - 1) * size,
take: size,
orderBy: {
createdAt: "desc",
},
...options,
}),
]);
return {
total,
list,
};
} catch (error) {
console.error(error);
return null;
}
};
export async function getAllUsersCount() {
try {
return await prisma.user.count();
} catch (error) {
return -1;
}
}
export async function setFirstUserAsAdmin(userId: string) {
try {
return await prisma.user.update({
where: { id: userId },
data: { role: UserRole.ADMIN },
});
} catch (error) {
return null;
}
}
export async function getAllUsersActiveApiKeyCount() {
try {
return await prisma.user.count({ where: { apiKey: { not: null } } });
} catch (error) {
return -1;
}
}
export const updateUser = async (userId: string, data: UpdateUserForm) => {
try {
// 1. 验证用户是否存在
const existingUser = await prisma.user.findUnique({
where: { id: userId },
select: {
id: true,
password: true,
email: true,
},
});
if (!existingUser) {
throw new Error("用户不存在");
}
// 2. 准备更新数据
const updateData: Partial<UpdateUserForm> = {};
// 3. 处理基础字段
if (data.name !== undefined) updateData.name = data.name;
if (data.email !== undefined) {
// 检查邮箱是否已被其他用户使用
if (data.email !== existingUser.email) {
const emailExists = await prisma.user.findFirst({
where: {
email: data.email,
id: { not: userId },
},
});
if (emailExists) {
throw new Error("邮箱已被使用");
}
}
updateData.email = data.email;
}
if (data.role !== undefined) updateData.role = data.role;
if (data.active !== undefined) updateData.active = data.active;
if (data.team !== undefined) updateData.team = data.team;
if (data.image !== undefined) updateData.image = data.image;
if (data.apiKey !== undefined) updateData.apiKey = data.apiKey;
// 4. 处理密码更新
if (data.password) {
const trimmedPassword = data.password.trim();
// 检查新密码是否与当前密码相同
const isSamePassword = verifyPassword(
trimmedPassword,
existingUser.password || "",
);
if (!isSamePassword) {
updateData.password = hashPassword(trimmedPassword);
}
}
if (Object.keys(updateData).length === 0) {
return existingUser;
}
const updatedUser = await prisma.user.update({
where: { id: userId },
data: {
...updateData,
updatedAt: new Date(),
},
select: {
id: true,
name: true,
email: true,
role: true,
active: true,
team: true,
image: true,
apiKey: true,
createdAt: true,
updatedAt: true,
},
});
return updatedUser;
} catch (error) {
console.error("更新用户失败:", error);
if (error instanceof Error) {
throw error;
}
throw new Error("更新用户时发生未知错误");
}
};
export const deleteUserById = async (userId: string) => {
try {
const session = await prisma.user.update({
where: {
id: userId,
},
data: {
active: 0,
},
});
return session;
} catch (error) {
return null;
}
};
export function checkUserStatus(user: any) {
if (!user?.id) {
throw new Response("Unauthorized", {
status: 401,
statusText: "Unauthorized",
});
}
if (user.active === 0) {
throw new Response("Forbidden", {
status: 403,
statusText: "Forbidden",
});
}
return user;
}
export function getFirstAdminUser() {
return prisma.user.findFirst({
where: { role: UserRole.ADMIN, email: { not: "admin@admin.com" } },
select: { email: true },
});
}