2
0

user.service.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { DataSource } from 'typeorm';
  2. import { UserEntity as User } from './user.entity';
  3. import * as bcrypt from 'bcrypt';
  4. import { Repository } from 'typeorm';
  5. import { Role } from './role.entity';
  6. const SALT_ROUNDS = 10;
  7. export class UserService {
  8. private userRepository: Repository<User>;
  9. private roleRepository: Repository<Role>;
  10. private readonly dataSource: DataSource;
  11. constructor(dataSource: DataSource) {
  12. this.dataSource = dataSource;
  13. this.userRepository = this.dataSource.getRepository(User);
  14. this.roleRepository = this.dataSource.getRepository(Role);
  15. }
  16. async createUser(userData: Partial<User>): Promise<User> {
  17. try {
  18. if (userData.password) {
  19. userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
  20. }
  21. const user = this.userRepository.create(userData);
  22. return await this.userRepository.save(user);
  23. } catch (error) {
  24. console.error('Error creating user:', error);
  25. throw new Error(`Failed to create user: ${error instanceof Error ? error.message : String(error)}`)
  26. }
  27. }
  28. async getUserById(id: number): Promise<User | null> {
  29. try {
  30. return await this.userRepository.findOne({
  31. where: { id },
  32. relations: ['roles']
  33. });
  34. } catch (error) {
  35. console.error('Error getting user:', error);
  36. throw new Error('Failed to get user');
  37. }
  38. }
  39. async getUserByUsername(username: string): Promise<User | null> {
  40. try {
  41. return await this.userRepository.findOne({
  42. where: { username },
  43. relations: ['roles']
  44. });
  45. } catch (error) {
  46. console.error('Error getting user:', error);
  47. throw new Error('Failed to get user');
  48. }
  49. }
  50. async getUserByPhone(phone: string): Promise<User | null> {
  51. try {
  52. return await this.userRepository.findOne({
  53. where: { phone: phone },
  54. relations: ['roles']
  55. });
  56. } catch (error) {
  57. console.error('Error getting user by phone:', error);
  58. throw new Error('Failed to get user by phone');
  59. }
  60. }
  61. async updateUser(id: number, updateData: Partial<User>): Promise<User | null> {
  62. try {
  63. if (updateData.password) {
  64. updateData.password = await bcrypt.hash(updateData.password, SALT_ROUNDS);
  65. }
  66. await this.userRepository.update(id, updateData);
  67. return this.getUserById(id);
  68. } catch (error) {
  69. console.error('Error updating user:', error);
  70. throw new Error('Failed to update user');
  71. }
  72. }
  73. async deleteUser(id: number): Promise<void> {
  74. try {
  75. await this.userRepository.delete(id);
  76. } catch (error) {
  77. console.error('Error deleting user:', error);
  78. throw new Error('Failed to delete user');
  79. }
  80. }
  81. async getUsersWithPagination(params: {
  82. page: number;
  83. pageSize: number;
  84. keyword?: string;
  85. }): Promise<[User[], number]> {
  86. try {
  87. const { page, pageSize, keyword } = params;
  88. const skip = (page - 1) * pageSize;
  89. const queryBuilder = this.userRepository
  90. .createQueryBuilder('user')
  91. .leftJoinAndSelect('user.roles', 'roles')
  92. .skip(skip)
  93. .take(pageSize);
  94. if (keyword) {
  95. queryBuilder.where(
  96. 'user.username LIKE :keyword OR user.nickname LIKE :keyword OR user.phone LIKE :keyword',
  97. { keyword: `%${keyword}%` }
  98. );
  99. }
  100. return await queryBuilder.getManyAndCount();
  101. } catch (error) {
  102. console.error('Error getting users with pagination:', error);
  103. throw new Error('Failed to get users');
  104. }
  105. }
  106. async verifyPassword(user: User, password: string): Promise<boolean> {
  107. return password === user.password || bcrypt.compare(password, user.password)
  108. }
  109. async assignRoles(userId: number, roleIds: number[]): Promise<User | null> {
  110. try {
  111. const user = await this.getUserById(userId);
  112. if (!user) return null;
  113. const roles = await this.roleRepository.findByIds(roleIds);
  114. user.roles = roles;
  115. return await this.userRepository.save(user);
  116. } catch (error) {
  117. console.error('Error assigning roles:', error);
  118. throw new Error('Failed to assign roles');
  119. }
  120. }
  121. async getUsers(): Promise<User[]> {
  122. try {
  123. const users = await this.userRepository.find({
  124. relations: ['roles']
  125. });
  126. return users;
  127. } catch (error) {
  128. console.error('Error getting users:', error);
  129. throw new Error(`Failed to get users: ${error instanceof Error ? error.message : String(error)}`)
  130. }
  131. }
  132. getUserRepository(): Repository<User> {
  133. return this.userRepository;
  134. }
  135. async getUserByAccount(account: string): Promise<User | null> {
  136. try {
  137. return await this.userRepository.findOne({
  138. where: [{ username: account }, { email: account }],
  139. relations: ['roles']
  140. });
  141. } catch (error) {
  142. console.error('Error getting user by account:', error);
  143. throw new Error('Failed to get user by account');
  144. }
  145. }
  146. }