user.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import bcrypt from 'bcryptjs';
  2. import { executeQuery } from '../config/database';
  3. // 用户角色类型
  4. export type UserRole = 'admin' | 'user' | 'viewer';
  5. // 用户模型接口
  6. export interface User {
  7. id: string;
  8. username: string;
  9. password: string;
  10. email?: string;
  11. role: UserRole;
  12. created_at: Date;
  13. updated_at: Date;
  14. }
  15. // 用户创建参数接口
  16. export interface UserCreateParams {
  17. username: string;
  18. password: string;
  19. role?: UserRole;
  20. email?: string;
  21. }
  22. /**
  23. * 用户模型
  24. * 处理用户数据的CRUD操作
  25. */
  26. export class UserModel {
  27. /**
  28. * 创建用户
  29. */
  30. static async create(params: UserCreateParams): Promise<User> {
  31. try {
  32. const { username, password, role = 'user', email } = params;
  33. // 生成密码哈希
  34. const salt = await bcrypt.genSalt(10);
  35. const hashedPassword = await bcrypt.hash(password, salt);
  36. // 确保email为null而不是undefined
  37. const emailValue = email || null;
  38. // 生成UUID作为id
  39. const uuidResult = await executeQuery('SELECT UUID() as uuid');
  40. const id = uuidResult[0].uuid;
  41. // 插入用户数据
  42. const query = `
  43. INSERT INTO users (id, username, password, email, role, created_at, updated_at)
  44. VALUES (?, ?, ?, ?, ?, NOW(), NOW())
  45. `;
  46. await executeQuery(query, [id, username, hashedPassword, emailValue, role]);
  47. // 返回创建的用户
  48. const user = await this.getById(id);
  49. if (!user) {
  50. throw new Error('创建用户失败,无法获取创建的用户信息');
  51. }
  52. return user;
  53. } catch (error) {
  54. console.error('创建用户失败:', error);
  55. throw error;
  56. }
  57. }
  58. /**
  59. * 根据ID获取用户
  60. */
  61. static async getById(id: any): Promise<User | null> {
  62. try {
  63. const query = `
  64. SELECT id, username, password, email, role, created_at, updated_at
  65. FROM users
  66. WHERE id = ?
  67. `;
  68. const result = await executeQuery(query, [id]);
  69. if (result.length === 0) {
  70. return null;
  71. }
  72. return result[0] as User;
  73. } catch (error) {
  74. console.error('根据ID获取用户失败:', error);
  75. throw error;
  76. }
  77. }
  78. /**
  79. * 根据用户名获取用户
  80. */
  81. static async getByUsername(username: string): Promise<User | null> {
  82. try {
  83. const query = `
  84. SELECT id, username, password, email, role, created_at, updated_at
  85. FROM users
  86. WHERE username = ?
  87. `;
  88. const result = await executeQuery(query, [username]);
  89. if (result.length === 0) {
  90. return null;
  91. }
  92. return result[0] as User;
  93. } catch (error) {
  94. console.error('根据用户名获取用户失败:', error);
  95. throw error;
  96. }
  97. }
  98. /**
  99. * 更新用户
  100. */
  101. static async update(id: any, updates: Partial<Omit<User, 'id' | 'created_at' | 'password'>>): Promise<User | null> {
  102. try {
  103. // 构建更新字段和参数
  104. const updateFields: string[] = [];
  105. const params: any[] = [];
  106. if (updates.username) {
  107. updateFields.push('username = ?');
  108. params.push(updates.username);
  109. }
  110. if (updates.role) {
  111. updateFields.push('role = ?');
  112. params.push(updates.role);
  113. }
  114. if (updates.email) {
  115. updateFields.push('email = ?');
  116. params.push(updates.email);
  117. }
  118. // 总是更新updated_at字段
  119. updateFields.push('updated_at = NOW()');
  120. if (updateFields.length === 1) {
  121. // 只有updated_at字段更新,直接返回当前用户
  122. return await this.getById(id);
  123. }
  124. params.push(id);
  125. // 执行更新
  126. const query = `
  127. UPDATE users
  128. SET ${updateFields.join(', ')}
  129. WHERE id = ?
  130. `;
  131. await executeQuery(query, params);
  132. // 返回更新后的用户
  133. return await this.getById(id);
  134. } catch (error) {
  135. console.error('更新用户失败:', error);
  136. throw error;
  137. }
  138. }
  139. /**
  140. * 更新用户密码
  141. */
  142. static async updatePassword(id: any, newPassword: string): Promise<void> {
  143. try {
  144. // 生成新的密码哈希
  145. const salt = await bcrypt.genSalt(10);
  146. const hashedPassword = await bcrypt.hash(newPassword, salt);
  147. // 更新密码
  148. const query = `
  149. UPDATE users
  150. SET password = ?, updated_at = NOW()
  151. WHERE id = ?
  152. `;
  153. await executeQuery(query, [hashedPassword, id]);
  154. } catch (error) {
  155. console.error('更新用户密码失败:', error);
  156. throw error;
  157. }
  158. }
  159. /**
  160. * 删除用户
  161. */
  162. static async delete(id: number): Promise<boolean> {
  163. try {
  164. const query = 'DELETE FROM users WHERE id = ?';
  165. const result = await executeQuery(query, [id]);
  166. return result.affectedRows > 0;
  167. } catch (error) {
  168. console.error('删除用户失败:', error);
  169. throw error;
  170. }
  171. }
  172. /**
  173. * 获取所有用户
  174. */
  175. static async getAll(limit?: number, offset?: number): Promise<User[]> {
  176. try {
  177. let query = `
  178. SELECT id, username, password, email, role, created_at, updated_at
  179. FROM users
  180. ORDER BY created_at DESC
  181. `;
  182. const params: any[] = [];
  183. if (limit !== undefined) {
  184. query += ' LIMIT ?';
  185. params.push(limit);
  186. if (offset !== undefined) {
  187. query += ' OFFSET ?';
  188. params.push(offset);
  189. }
  190. }
  191. const result = await executeQuery(query, params);
  192. return result as User[];
  193. } catch (error) {
  194. console.error('获取所有用户失败:', error);
  195. throw error;
  196. }
  197. }
  198. }