import { DataSource } from 'typeorm'; import { UserEntity } from '../entities/user.entity'; import { RoleService } from './role.service'; import { ConcreteCrudService } from '@d8d/shared-crud'; import * as bcrypt from 'bcrypt'; const SALT_ROUNDS = 10; export class UserService extends ConcreteCrudService { private roleService: RoleService; constructor(dataSource: DataSource) { super(UserEntity, { userTracking: { createdByField: 'createdBy', updatedByField: 'updatedBy' } }); this.roleService = new RoleService(dataSource); } /** * 创建用户并加密密码 */ async createUser(userData: Partial): Promise { try { // 检查用户名是否已存在 if (userData.username) { const existingUser = await this.getUserByUsername(userData.username); if (existingUser) { throw new Error('用户名已存在'); } } if (userData.password) { userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS); } return await this.create(userData); } catch (error) { console.error('Error creating user:', error); throw new Error(`Failed to create user: ${error instanceof Error ? error.message : String(error)}`); } } /** * 根据用户名获取用户(自动添加租户过滤) */ async getUserByUsername(username: string): Promise { try { const where: any = { username }; return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] }); } catch (error) { console.error('Error getting user by username:', error); throw new Error('Failed to get user by username'); } } /** * 根据手机号获取用户(自动添加租户过滤) */ async getUserByPhone(phone: string): Promise { try { const where: any = { phone }; return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] }); } catch (error) { console.error('Error getting user by phone:', error); throw new Error('Failed to get user by phone'); } } /** * 根据账号(用户名或邮箱)获取用户(自动添加租户过滤) */ async getUserByAccount(account: string): Promise { try { const where: any = [ { username: account }, { email: account } ]; return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] }); } catch (error) { console.error('Error getting user by account:', error); throw new Error('Failed to get user by account'); } } /** * 验证密码 */ async verifyPassword(user: UserEntity, password: string): Promise { return password === user.password || bcrypt.compare(password, user.password); } /** * 为用户分配角色 */ async assignRoles(userId: number, roleIds: number[]): Promise { try { const user = await this.getById(userId, ['roles']); if (!user) return null; // 获取角色实体 const roles = []; for (const roleId of roleIds) { const role = await this.roleService.getById(roleId); if (role) { roles.push(role); } } // 分配角色 user.roles = roles; return await this.repository.save(user); } catch (error) { console.error('Error assigning roles:', error); throw new Error('Failed to assign roles'); } } /** * 根据ID获取用户(自动添加租户过滤) */ async getUserById(id: number): Promise { try { const where: any = { id }; return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] }); } catch (error) { console.error('Error getting user by id:', error); throw new Error('Failed to get user by id'); } } /** * 更新用户信息(自动添加租户过滤) */ async updateUser(id: number, userData: Partial): Promise { try { // 首先验证用户是否存在 const existingUser = await this.getUserById(id); if (!existingUser) return null; // 如果更新密码,需要加密 if (userData.password) { userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS); } return await this.update(id, userData); } catch (error) { console.error('Error updating user:', error); throw new Error('Failed to update user'); } } /** * 删除用户(自动添加租户过滤) */ async deleteUser(id: number): Promise { try { // 首先验证用户是否存在 const existingUser = await this.getUserById(id); if (!existingUser) return false; return await this.delete(id); } catch (error) { console.error('Error deleting user:', error); throw new Error('Failed to delete user'); } } /** * 获取所有用户(自动添加租户过滤) */ async getUsers(): Promise { try { const where: any = {}; const [users] = await this.getList(1, 100, undefined, undefined, where, ['roles', 'avatarFile']); return users; } catch (error) { console.error('Error getting users:', error); throw new Error(`Failed to get users: ${error instanceof Error ? error.message : String(error)}`); } } }