server.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import 'reflect-metadata';
  2. import express, { Express } from 'express';
  3. import cors from 'cors';
  4. import helmet from 'helmet';
  5. import compression from 'compression';
  6. import rateLimit from 'express-rate-limit';
  7. import * as dotenv from 'dotenv';
  8. import { initializeDatabase, closeDatabase } from './config/database';
  9. import routes from './routes';
  10. import { loggerMiddleware } from './middlewares/logger.middleware';
  11. import { errorMiddleware, notFoundMiddleware } from './middlewares/error.middleware';
  12. // 加载环境变量
  13. dotenv.config();
  14. const app: Express = express();
  15. const PORT = process.env.PORT || 3000;
  16. const API_PREFIX = process.env.API_PREFIX || '/api';
  17. // ========================================
  18. // 中间件配置
  19. // ========================================
  20. // 安全头部
  21. app.use(helmet());
  22. // 压缩响应
  23. app.use(compression());
  24. // CORS配置
  25. app.use(cors({
  26. origin: process.env.CORS_ORIGIN || 'http://localhost:4200',
  27. credentials: true
  28. }));
  29. // 请求体解析
  30. app.use(express.json({ limit: '10mb' }));
  31. app.use(express.urlencoded({ extended: true, limit: '10mb' }));
  32. // 请求日志
  33. app.use(loggerMiddleware);
  34. // 限流配置
  35. const limiter = rateLimit({
  36. windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000'), // 15分钟
  37. max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS || '100'), // 最多100个请求
  38. message: {
  39. success: false,
  40. message: '请求过于频繁,请稍后再试'
  41. }
  42. });
  43. app.use(API_PREFIX, limiter);
  44. // ========================================
  45. // 路由配置
  46. // ========================================
  47. app.use(API_PREFIX, routes);
  48. // ========================================
  49. // 错误处理
  50. // ========================================
  51. app.use(notFoundMiddleware);
  52. app.use(errorMiddleware);
  53. // ========================================
  54. // 启动服务器
  55. // ========================================
  56. const startServer = async () => {
  57. try {
  58. // 初始化数据库连接
  59. await initializeDatabase();
  60. // 启动HTTP服务器
  61. app.listen(PORT, () => {
  62. console.log('========================================');
  63. console.log('🚀 数智健调系统后端API启动成功');
  64. console.log('========================================');
  65. console.log(`📡 服务器地址: http://localhost:${PORT}`);
  66. console.log(`🔗 API地址: http://localhost:${PORT}${API_PREFIX}`);
  67. console.log(`🌍 环境: ${process.env.NODE_ENV || 'development'}`);
  68. console.log(`📊 数据库: ${process.env.DB_DATABASE}`);
  69. console.log('========================================');
  70. });
  71. // 优雅关闭
  72. process.on('SIGTERM', gracefulShutdown);
  73. process.on('SIGINT', gracefulShutdown);
  74. } catch (error) {
  75. console.error('❌ 服务器启动失败:', error);
  76. process.exit(1);
  77. }
  78. };
  79. /**
  80. * 优雅关闭
  81. */
  82. const gracefulShutdown = async () => {
  83. console.log('\n正在关闭服务器...');
  84. try {
  85. await closeDatabase();
  86. console.log('✅ 服务器已安全关闭');
  87. process.exit(0);
  88. } catch (error) {
  89. console.error('❌ 关闭服务器时发生错误:', error);
  90. process.exit(1);
  91. }
  92. };
  93. // 启动服务器
  94. startServer();
  95. export default app;