user.service.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import { DataSource } from 'typeorm';
  2. import { UserEntity } from '../entities/user.entity';
  3. import { RoleService } from './role.service';
  4. import { ConcreteCrudService } from '@d8d/shared-crud';
  5. import * as bcrypt from 'bcrypt';
  6. const SALT_ROUNDS = 10;
  7. export class UserService extends ConcreteCrudService<UserEntity> {
  8. private roleService: RoleService;
  9. constructor(dataSource: DataSource) {
  10. super(UserEntity, {
  11. userTracking: {
  12. createdByField: 'createdBy',
  13. updatedByField: 'updatedBy'
  14. }
  15. });
  16. this.roleService = new RoleService(dataSource);
  17. }
  18. /**
  19. * 创建用户并加密密码
  20. */
  21. async createUser(userData: Partial<UserEntity>): Promise<UserEntity> {
  22. try {
  23. // 检查用户名是否已存在
  24. if (userData.username) {
  25. const existingUser = await this.getUserByUsername(userData.username);
  26. if (existingUser) {
  27. throw new Error('用户名已存在');
  28. }
  29. }
  30. if (userData.password) {
  31. userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
  32. }
  33. return await this.create(userData);
  34. } catch (error) {
  35. console.error('Error creating user:', error);
  36. throw new Error(`Failed to create user: ${error instanceof Error ? error.message : String(error)}`);
  37. }
  38. }
  39. /**
  40. * 根据用户名获取用户(自动添加租户过滤)
  41. */
  42. async getUserByUsername(username: string): Promise<UserEntity | null> {
  43. try {
  44. const where: any = { username };
  45. return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
  46. } catch (error) {
  47. console.error('Error getting user by username:', error);
  48. throw new Error('Failed to get user by username');
  49. }
  50. }
  51. /**
  52. * 根据手机号获取用户(自动添加租户过滤)
  53. */
  54. async getUserByPhone(phone: string): Promise<UserEntity | null> {
  55. try {
  56. const where: any = { phone };
  57. return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
  58. } catch (error) {
  59. console.error('Error getting user by phone:', error);
  60. throw new Error('Failed to get user by phone');
  61. }
  62. }
  63. /**
  64. * 根据账号(用户名或邮箱)获取用户(自动添加租户过滤)
  65. */
  66. async getUserByAccount(account: string): Promise<UserEntity | null> {
  67. try {
  68. const where: any = [
  69. { username: account },
  70. { email: account }
  71. ];
  72. return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
  73. } catch (error) {
  74. console.error('Error getting user by account:', error);
  75. throw new Error('Failed to get user by account');
  76. }
  77. }
  78. /**
  79. * 验证密码
  80. */
  81. async verifyPassword(user: UserEntity, password: string): Promise<boolean> {
  82. return password === user.password || bcrypt.compare(password, user.password);
  83. }
  84. /**
  85. * 为用户分配角色
  86. */
  87. async assignRoles(userId: number, roleIds: number[]): Promise<UserEntity | null> {
  88. try {
  89. const user = await this.getById(userId, ['roles']);
  90. if (!user) return null;
  91. // 获取角色实体
  92. const roles = [];
  93. for (const roleId of roleIds) {
  94. const role = await this.roleService.getById(roleId);
  95. if (role) {
  96. roles.push(role);
  97. }
  98. }
  99. // 分配角色
  100. user.roles = roles;
  101. return await this.repository.save(user);
  102. } catch (error) {
  103. console.error('Error assigning roles:', error);
  104. throw new Error('Failed to assign roles');
  105. }
  106. }
  107. /**
  108. * 根据ID获取用户(自动添加租户过滤)
  109. */
  110. async getUserById(id: number): Promise<UserEntity | null> {
  111. try {
  112. const where: any = { id };
  113. return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
  114. } catch (error) {
  115. console.error('Error getting user by id:', error);
  116. throw new Error('Failed to get user by id');
  117. }
  118. }
  119. /**
  120. * 更新用户信息(自动添加租户过滤)
  121. */
  122. async updateUser(id: number, userData: Partial<UserEntity>): Promise<UserEntity | null> {
  123. try {
  124. // 首先验证用户是否存在
  125. const existingUser = await this.getUserById(id);
  126. if (!existingUser) return null;
  127. // 如果更新密码,需要加密
  128. if (userData.password) {
  129. userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
  130. }
  131. return await this.update(id, userData);
  132. } catch (error) {
  133. console.error('Error updating user:', error);
  134. throw new Error('Failed to update user');
  135. }
  136. }
  137. /**
  138. * 删除用户(自动添加租户过滤)
  139. */
  140. async deleteUser(id: number): Promise<boolean> {
  141. try {
  142. // 首先验证用户是否存在
  143. const existingUser = await this.getUserById(id);
  144. if (!existingUser) return false;
  145. return await this.delete(id);
  146. } catch (error) {
  147. console.error('Error deleting user:', error);
  148. throw new Error('Failed to delete user');
  149. }
  150. }
  151. /**
  152. * 获取所有用户(自动添加租户过滤)
  153. */
  154. async getUsers(): Promise<UserEntity[]> {
  155. try {
  156. const where: any = {};
  157. const [users] = await this.getList(1, 100, undefined, undefined, where, ['roles', 'avatarFile']);
  158. return users;
  159. } catch (error) {
  160. console.error('Error getting users:', error);
  161. throw new Error(`Failed to get users: ${error instanceof Error ? error.message : String(error)}`);
  162. }
  163. }
  164. }