Files
nxxmdata/bank-backend/server.js
2025-09-17 18:04:28 +08:00

223 lines
5.6 KiB
JavaScript

/**
* 银行管理后台服务器
* @file server.js
* @description 银行系统后端API服务器主入口
*/
const express = require('express');
const http = require('http');
const cors = require('cors');
const dotenv = require('dotenv');
const helmet = require('helmet');
const compression = require('compression');
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./config/swagger');
const { sequelize } = require('./config/database');
const logger = require('./utils/logger');
const {
apiRateLimiter,
loginRateLimiter,
inputSanitizer,
sessionTimeoutCheck,
securityHeaders
} = require('./middleware/security');
// 加载环境变量
dotenv.config();
// 创建Express应用和HTTP服务器
const app = express();
const server = http.createServer(app);
const PORT = process.env.PORT || 5351;
// 安全中间件
app.use(securityHeaders);
app.use(helmet());
app.use(compression());
// CORS配置
app.use(cors({
origin: process.env.CORS_ORIGIN || '*',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With']
}));
// 请求解析中间件
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// 安全中间件
app.use(inputSanitizer);
app.use(apiRateLimiter);
// 静态文件服务
app.use('/uploads', express.static('uploads'));
// API文档
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
// 健康检查端点
app.get('/health', (req, res) => {
res.json({
success: true,
message: '银行系统运行正常',
timestamp: new Date().toISOString(),
version: '1.0.0'
});
});
// API路由
app.use('/api/users', require('./routes/users'));
app.use('/api/accounts', require('./routes/accounts'));
app.use('/api/transactions', require('./routes/transactions'));
// 根路径
app.get('/', (req, res) => {
res.json({
success: true,
message: '银行管理后台API服务',
version: '1.0.0',
documentation: '/api-docs',
health: '/health'
});
});
// 404处理
app.use('*', (req, res) => {
res.status(404).json({
success: false,
message: '请求的资源不存在',
path: req.originalUrl
});
});
// 全局错误处理中间件
app.use((error, req, res, next) => {
logger.error('服务器错误:', error);
// 数据库连接错误
if (error.name === 'SequelizeConnectionError') {
return res.status(503).json({
success: false,
message: '数据库连接失败,请稍后重试'
});
}
// 数据库验证错误
if (error.name === 'SequelizeValidationError') {
return res.status(400).json({
success: false,
message: '数据验证失败',
errors: error.errors.map(err => ({
field: err.path,
message: err.message
}))
});
}
// 数据库唯一约束错误
if (error.name === 'SequelizeUniqueConstraintError') {
return res.status(400).json({
success: false,
message: '数据已存在,请检查输入'
});
}
// JWT错误
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
success: false,
message: '无效的访问令牌'
});
}
if (error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '访问令牌已过期'
});
}
// 默认错误响应
res.status(error.status || 500).json({
success: false,
message: process.env.NODE_ENV === 'production'
? '服务器内部错误'
: error.message,
...(process.env.NODE_ENV !== 'production' && { stack: error.stack })
});
});
// 优雅关闭处理
const gracefulShutdown = (signal) => {
logger.info(`收到 ${signal} 信号,开始优雅关闭...`);
server.close(async () => {
logger.info('HTTP服务器已关闭');
try {
await sequelize.close();
logger.info('数据库连接已关闭');
} catch (error) {
logger.error('关闭数据库连接时出错:', error);
}
logger.info('银行系统已安全关闭');
process.exit(0);
});
// 强制关闭超时
setTimeout(() => {
logger.error('强制关闭服务器');
process.exit(1);
}, 10000);
};
// 监听关闭信号
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
// 未捕获的异常处理
process.on('uncaughtException', (error) => {
logger.error('未捕获的异常:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
logger.error('未处理的Promise拒绝:', reason);
process.exit(1);
});
// 启动服务器
const startServer = async () => {
try {
// 测试数据库连接
await sequelize.authenticate();
logger.info('✅ 数据库连接成功');
// 同步数据库模型(开发环境)
// 按用户要求:不要初始化数据库(不自动建表/同步)
// if (process.env.NODE_ENV === 'development') {
// await sequelize.sync({ alter: true });
// logger.info('✅ 数据库模型同步完成');
// }
// 启动HTTP服务器
server.listen(PORT, () => {
logger.info(`🚀 银行管理后台服务器启动成功`);
logger.info(`📡 服务地址: http://localhost:${PORT}`);
logger.info(`📚 API文档: http://localhost:${PORT}/api-docs`);
logger.info(`🏥 健康检查: http://localhost:${PORT}/health`);
logger.info(`🌍 环境: ${process.env.NODE_ENV || 'development'}`);
});
} catch (error) {
logger.error('❌ 服务器启动失败:', error);
process.exit(1);
}
};
// 启动服务器
startServer();
module.exports = app;