| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- 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<UserEntityMt> {
- 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<UserEntityMt>, tenantId?: number): Promise<UserEntityMt> {
- 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<UserEntityMt | null> {
- 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<UserEntityMt | null> {
- 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<UserEntityMt | null> {
- 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<boolean> {
- return password === user.password || bcrypt.compare(password, user.password);
- }
- /**
- * 为用户分配角色
- */
- async assignRoles(userId: number, roleIds: number[], tenantId?: number): Promise<UserEntityMt | null> {
- 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<UserEntityMt | null> {
- 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<UserEntityMt>, tenantId?: number): Promise<UserEntityMt | null> {
- 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<boolean> {
- 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<UserEntityMt[]> {
- 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)}`);
- }
- }
- }
|