Initial commit
This commit is contained in:
159
lib/services/user.service.ts
Normal file
159
lib/services/user.service.ts
Normal file
@ -0,0 +1,159 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user