import UserModel from "db/models/UserModel.js" import { hashPassword, comparePassword } from "utils/bcrypt.js" import CommonError from "utils/error/CommonError.js" import { JWT_SECRET } from "@/middlewares/Auth/auth.js" import jwt from "@/middlewares/Auth/jwt.js" class UserService { // 根据ID获取用户 async getUserById(id) { try { if (!id) { throw new CommonError("用户ID不能为空") } const user = await UserModel.findById(id) if (!user) { throw new CommonError("用户不存在") } // 返回脱敏信息 const { password, ...userInfo } = user return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`获取用户失败: ${error.message}`) } } // 获取所有用户 async getAllUsers() { try { const users = await UserModel.findAll() // 返回脱敏信息 return users.map(user => { const { password, ...userInfo } = user return userInfo }) } catch (error) { throw new CommonError(`获取用户列表失败: ${error.message}`) } } // 创建新用户 async createUser(data) { try { if (!data.username || !data.password) { throw new CommonError("用户名和密码为必填字段") } // 检查用户名是否已存在 const existUser = await UserModel.findByUsername(data.username) if (existUser) { throw new CommonError(`用户名${data.username}已存在`) } // 检查邮箱是否已存在 if (data.email) { const existEmail = await UserModel.findByEmail(data.email) if (existEmail) { throw new CommonError(`邮箱${data.email}已被使用`) } } // 密码加密 const hashedPassword = await hashPassword(data.password) const user = await UserModel.create({ ...data, password: hashedPassword }) // 返回脱敏信息 const { password, ...userInfo } = Array.isArray(user) ? user[0] : user return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`创建用户失败: ${error.message}`) } } // 更新用户 async updateUser(id, data) { try { if (!id) { throw new CommonError("用户ID不能为空") } const user = await UserModel.findById(id) if (!user) { throw new CommonError("用户不存在") } // 如果要更新用户名,检查是否重复 if (data.username && data.username !== user.username) { const existUser = await UserModel.findByUsername(data.username) if (existUser) { throw new CommonError(`用户名${data.username}已存在`) } } // 如果要更新邮箱,检查是否重复 if (data.email && data.email !== user.email) { const existEmail = await UserModel.findByEmail(data.email) if (existEmail) { throw new CommonError(`邮箱${data.email}已被使用`) } } // 如果要更新密码,需要加密 if (data.password) { data.password = await hashPassword(data.password) } const updatedUser = await UserModel.update(id, data) // 返回脱敏信息 const { password, ...userInfo } = Array.isArray(updatedUser) ? updatedUser[0] : updatedUser return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`更新用户失败: ${error.message}`) } } // 删除用户 async deleteUser(id) { try { if (!id) { throw new CommonError("用户ID不能为空") } const user = await UserModel.findById(id) if (!user) { throw new CommonError("用户不存在") } return await UserModel.delete(id) } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`删除用户失败: ${error.message}`) } } // 注册新用户 async register(data) { try { if (!data.username || !data.password) { throw new CommonError("用户名和密码不能为空") } // 检查用户名是否已存在 const existUser = await UserModel.findByUsername(data.username) if (existUser) { throw new CommonError(`用户名${data.username}已存在`) } // 检查邮箱是否已存在 if (data.email) { const existEmail = await UserModel.findByEmail(data.email) if (existEmail) { throw new CommonError(`邮箱${data.email}已被使用`) } } // 密码加密 const hashed = await hashPassword(data.password) const user = await UserModel.create({ ...data, password: hashed }) // 返回脱敏信息 const { password, ...userInfo } = Array.isArray(user) ? user[0] : user return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`注册失败: ${error.message}`) } } // 登录 async login({ username, email, password }) { try { if (!password) { throw new CommonError("密码不能为空") } if (!username && !email) { throw new CommonError("用户名或邮箱不能为空") } let user if (username) { user = await UserModel.findByUsername(username) } else if (email) { user = await UserModel.findByEmail(email) } if (!user) { throw new CommonError("用户不存在") } // 校验密码 const ok = await comparePassword(password, user.password) if (!ok) { throw new CommonError("密码错误") } // 生成token const token = jwt.sign( { id: user.id, username: user.username }, JWT_SECRET, { expiresIn: "2h" } ) // 返回token和用户信息 const { password: pwd, ...userInfo } = user return { token, user: userInfo } } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`登录失败: ${error.message}`) } } // 根据用户名查找用户 async getUserByUsername(username) { try { if (!username) { throw new CommonError("用户名不能为空") } const user = await UserModel.findByUsername(username) if (!user) { throw new CommonError("用户不存在") } // 返回脱敏信息 const { password, ...userInfo } = user return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`获取用户失败: ${error.message}`) } } // 根据邮箱查找用户 async getUserByEmail(email) { try { if (!email) { throw new CommonError("邮箱不能为空") } const user = await UserModel.findByEmail(email) if (!user) { throw new CommonError("用户不存在") } // 返回脱敏信息 const { password, ...userInfo } = user return userInfo } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`获取用户失败: ${error.message}`) } } // 修改密码 async changePassword(userId, oldPassword, newPassword) { try { if (!userId || !oldPassword || !newPassword) { throw new CommonError("用户ID、旧密码和新密码不能为空") } const user = await UserModel.findById(userId) if (!user) { throw new CommonError("用户不存在") } // 验证旧密码 const isOldPasswordCorrect = await comparePassword(oldPassword, user.password) if (!isOldPasswordCorrect) { throw new CommonError("旧密码错误") } // 加密新密码 const hashedNewPassword = await hashPassword(newPassword) // 更新密码 await UserModel.update(userId, { password: hashedNewPassword }) return { message: "密码修改成功" } } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`修改密码失败: ${error.message}`) } } // 重置密码 async resetPassword(email, newPassword) { try { if (!email || !newPassword) { throw new CommonError("邮箱和新密码不能为空") } const user = await UserModel.findByEmail(email) if (!user) { throw new CommonError("用户不存在") } // 加密新密码 const hashedPassword = await hashPassword(newPassword) // 更新密码 await UserModel.update(user.id, { password: hashedPassword }) return { message: "密码重置成功" } } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`重置密码失败: ${error.message}`) } } // 获取用户统计信息 async getUserStats() { try { const users = await UserModel.findAll() const stats = { total: users.length, active: users.filter(user => user.status === 'active').length, inactive: users.filter(user => user.status === 'inactive').length, byRole: {}, byDate: {} } // 按角色分组统计 users.forEach(user => { const role = user.role || 'user' stats.byRole[role] = (stats.byRole[role] || 0) + 1 }) // 按创建时间分组统计 users.forEach(user => { const date = new Date(user.created_at).toISOString().split('T')[0] stats.byDate[date] = (stats.byDate[date] || 0) + 1 }) return stats } catch (error) { throw new CommonError(`获取用户统计失败: ${error.message}`) } } // 搜索用户 async searchUsers(keyword) { try { if (!keyword || keyword.trim() === '') { return await this.getAllUsers() } const users = await UserModel.findAll() const searchTerm = keyword.toLowerCase().trim() const filteredUsers = users.filter(user => { return ( user.username?.toLowerCase().includes(searchTerm) || user.email?.toLowerCase().includes(searchTerm) || user.name?.toLowerCase().includes(searchTerm) ) }) // 返回脱敏信息 return filteredUsers.map(user => { const { password, ...userInfo } = user return userInfo }) } catch (error) { throw new CommonError(`搜索用户失败: ${error.message}`) } } // 批量删除用户 async deleteUsers(userIds) { try { if (!Array.isArray(userIds) || userIds.length === 0) { throw new CommonError("用户ID列表不能为空") } const results = [] const errors = [] for (const id of userIds) { try { await this.deleteUser(id) results.push(id) } catch (error) { errors.push({ id, error: error.message }) } } return { success: results, errors, total: userIds.length, successCount: results.length, errorCount: errors.length } } catch (error) { if (error instanceof CommonError) throw error throw new CommonError(`批量删除用户失败: ${error.message}`) } } } export default UserService