mirror of
https://github.com/oiov/wr.do.git
synced 2026-06-05 03:03:15 +08:00
239 lines
5.2 KiB
TypeScript
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 },
|
|
});
|
|
}
|