import { DataSource } from 'typeorm'; import { UserEntityMt } from '../entities/user.entity.mt'; import { RoleServiceMt } from './role.service.mt'; import { ConcreteCrudService } from '@d8d/shared-crud'; import * as bcrypt from 'bcrypt'; const SALT_ROUNDS = 10; export class UserServiceMt extends ConcreteCrudService { private roleService: RoleServiceMt; constructor(dataSource: DataSource) { super(UserEntityMt, { userTracking: { createdByField: 'createdBy', updatedByField: 'updatedBy' }, tenantOptions: { tenantIdField: 'tenantId', autoExtractFromContext: true } }); this.roleService = new RoleServiceMt(dataSource); } /** * 创建用户,自动设置租户ID并加密密码 */ async createUser(userData: Partial, tenantId?: number): Promise { try { // 检查用户名是否已存在(租户内唯一) if (userData.username) { const existingUser = await this.getUserByUsername(userData.username, tenantId); if (existingUser) { throw new Error('用户名已存在'); } } if (userData.password) { userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS); } // 如果提供了租户ID,自动设置 if (tenantId !== undefined) { userData.tenantId = tenantId; } else { // 如果没有提供租户ID,设置默认租户ID为1 userData.tenantId = 1; } 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, tenantId?: number): Promise { try { const where: any = { username }; // 如果提供了租户ID,添加租户过滤 if (tenantId !== undefined) { where.tenantId = tenantId; } 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, tenantId?: number): Promise { try { const where: any = { phone }; // 如果提供了租户ID,添加租户过滤 if (tenantId !== undefined) { where.tenantId = tenantId; } 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, tenantId?: number): Promise { try { const where: any = [ { username: account }, { email: account } ]; // 如果提供了租户ID,添加租户过滤 if (tenantId !== undefined) { where.forEach((condition: any) => { condition.tenantId = tenantId; }); } 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: UserEntityMt, password: string): Promise { return password === user.password || bcrypt.compare(password, user.password); } /** * 为用户分配角色 */ async assignRoles(userId: number, roleIds: number[], tenantId?: number): Promise { try { const user = await this.getById(userId, ['roles']); if (!user) return null; // 验证租户一致性 if (tenantId !== undefined && user.tenantId !== tenantId) { throw new Error('无权操作该用户'); } // 获取角色实体 const roles = []; for (const roleId of roleIds) { const role = await this.roleService.getById(roleId); if (role) { // 验证角色租户一致性 if (tenantId !== undefined && role.tenantId !== tenantId) { throw new Error(`无权操作角色ID: ${roleId}`); } 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, tenantId?: number): Promise { try { const where: any = { id }; // 如果提供了租户ID,添加租户过滤 if (tenantId !== undefined) { where.tenantId = tenantId; } 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, tenantId?: number): Promise { try { // 首先验证用户是否存在且属于指定租户 const existingUser = await this.getUserById(id, tenantId); 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, tenantId?: number): Promise { try { // 首先验证用户是否存在且属于指定租户 const existingUser = await this.getUserById(id, tenantId); 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(tenantId?: number): Promise { try { const where: any = {}; // 如果提供了租户ID,添加租户过滤 if (tenantId !== undefined) { where.tenantId = tenantId; } 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)}`); } } }