login.route.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
  2. import { AuthService } from '../services';
  3. import { UserService } from '@d8d/user-module-mt';
  4. import { ErrorSchema } from '@d8d/shared-utils';
  5. import { AppDataSource } from '@d8d/shared-utils';
  6. import { AuthContext } from '@d8d/shared-types';
  7. import { parseWithAwait } from '@d8d/shared-utils';
  8. import { LoginSchema, TokenResponseSchema } from '../schemas';
  9. const loginRoute = createRoute({
  10. method: 'post',
  11. path: '/login',
  12. request: {
  13. body: {
  14. content: {
  15. 'application/json': {
  16. schema: LoginSchema
  17. }
  18. }
  19. }
  20. },
  21. responses: {
  22. 200: {
  23. description: '登录成功',
  24. content: {
  25. 'application/json': {
  26. schema: TokenResponseSchema
  27. }
  28. }
  29. },
  30. 401: {
  31. description: '用户名或密码错误',
  32. content: {
  33. 'application/json': {
  34. schema: ErrorSchema
  35. }
  36. }
  37. },
  38. 500: {
  39. description: '服务器内部错误',
  40. content: {
  41. 'application/json': {
  42. schema: ErrorSchema
  43. }
  44. }
  45. }
  46. }
  47. });
  48. const app = new OpenAPIHono<AuthContext>().openapi(loginRoute, async (c) => {
  49. try {
  50. // 在路由处理函数内部初始化服务
  51. const userService = new UserService(AppDataSource);
  52. const authService = new AuthService(userService);
  53. const { username, password } = c.req.valid('json');
  54. // 从请求头或查询参数中提取租户ID
  55. const tenantId = c.req.header('X-Tenant-Id') || c.req.query('tenantId');
  56. const tenantIdNumber = tenantId ? parseInt(tenantId, 10) : undefined;
  57. const result = await authService.login(username, password, tenantIdNumber);
  58. return c.json(await parseWithAwait(TokenResponseSchema, result), 200);
  59. } catch (error) {
  60. // 认证相关错误返回401
  61. if (error instanceof Error &&
  62. (error.message.includes('User not found') ||
  63. error.message.includes('Invalid password') ||
  64. error.message.includes('User account is disabled') ||
  65. error.message.includes('User does not belong to this tenant'))) {
  66. return c.json(
  67. {
  68. code: 401,
  69. message: error.message.includes('User account is disabled') ? '账户已禁用' :
  70. error.message.includes('User does not belong to this tenant') ? '用户不属于该租户' :
  71. '用户名或密码错误'
  72. },
  73. 401
  74. );
  75. }
  76. // 其他错误重新抛出,由错误处理中间件处理
  77. throw error;
  78. }
  79. });
  80. export default app;