Files
record-app-next/lib/services/user.service.ts
2025-07-31 17:05:07 +08:00

159 lines
3.1 KiB
TypeScript

import { prisma } from '../database'
import { User, Prisma } from '@prisma/client'
import bcrypt from 'bcrypt'
export interface CreateUserData {
email: string
name?: string
password?: string
image?: string
}
export interface UpdateUserData {
name?: string
email?: string
image?: string
}
export interface UserProfile {
id: string
name: string | null
email: string | null
image: string | null
createdAt: Date
updatedAt: Date
}
export class UserService {
/**
* 创建新用户
*/
static async createUser(data: CreateUserData): Promise<User> {
const { email, name, password, image } = data
// 验证邮箱格式
if (!this.isValidEmail(email)) {
throw new Error('邮箱格式不正确')
}
// 检查邮箱是否已存在
const existingUser = await prisma.user.findUnique({
where: { email }
})
if (existingUser) {
throw new Error('邮箱已被注册')
}
// 哈希密码(如果提供)
let hashedPassword: string | undefined
if (password) {
if (password.length < 6) {
throw new Error('密码长度至少6位')
}
hashedPassword = await bcrypt.hash(password, 12)
}
return prisma.user.create({
data: {
email,
name,
image,
hashedPassword
}
})
}
/**
* 根据ID获取用户
*/
static async getUserById(id: string): Promise<UserProfile | null> {
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
name: true,
email: true,
image: true,
createdAt: true,
updatedAt: true
}
})
return user
}
/**
* 根据邮箱获取用户
*/
static async getUserByEmail(email: string): Promise<User | null> {
return prisma.user.findUnique({
where: { email }
})
}
/**
* 更新用户信息
*/
static async updateUser(id: string, data: UpdateUserData): Promise<UserProfile> {
const updateData: Prisma.UserUpdateInput = {}
if (data.name !== undefined) {
updateData.name = data.name
}
if (data.email !== undefined) {
if (!this.isValidEmail(data.email)) {
throw new Error('邮箱格式不正确')
}
updateData.email = data.email
}
if (data.image !== undefined) {
updateData.image = data.image
}
const user = await prisma.user.update({
where: { id },
data: updateData,
select: {
id: true,
name: true,
email: true,
image: true,
createdAt: true,
updatedAt: true
}
})
return user
}
/**
* 验证用户密码
*/
static async verifyPassword(user: User, password: string): Promise<boolean> {
if (!user.hashedPassword) {
return false
}
return bcrypt.compare(password, user.hashedPassword)
}
/**
* 删除用户
*/
static async deleteUser(id: string): Promise<void> {
await prisma.user.delete({
where: { id }
})
}
/**
* 验证邮箱格式
*/
private static isValidEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
}