Files
jiebanke/backend/src/app.js
2025-09-03 13:25:08 +08:00

129 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const xss = require('xss-clean');
const hpp = require('hpp');
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./config/swagger');
console.log('🔧 初始化Express应用...');
const { globalErrorHandler, notFound } = require('./utils/errors');
// 路由导入
const authRoutes = require('./routes/auth');
const userRoutes = require('./routes/user');
const travelRoutes = require('./routes/travel');
const animalRoutes = require('./routes/animal');
const orderRoutes = require('./routes/order');
const adminRoutes = require('./routes/admin'); // 新增管理员路由
const app = express();
console.log('✅ Express应用初始化完成');
// 安全中间件
app.use(helmet());
// CORS配置
app.use(cors({
origin: process.env.NODE_ENV === 'production'
? ['https://your-domain.com']
: ['https://www.jiebanke.com', 'https://admin.jiebanke.com', 'https://webapi.jiebanke.com'],
credentials: true
}));
// 请求日志
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
} else {
app.use(morgan('combined'));
}
// 请求频率限制
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: process.env.NODE_ENV === 'production' ? 100 : 1000, // 生产环境100次开发环境1000次
message: {
success: false,
code: 429,
message: '请求过于频繁,请稍后再试',
timestamp: new Date().toISOString()
}
});
app.use('/api', limiter);
// 请求体解析
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
// 数据清洗
app.use(xss()); // 防止XSS攻击
app.use(hpp({ // 防止参数污染
whitelist: [
'page',
'pageSize',
'sort',
'fields',
'price',
'rating',
'distance'
]
}));
// 静态文件服务
app.use('/uploads', express.static('uploads'));
// Swagger文档路由
if (process.env.NODE_ENV === 'development' || process.env.ENABLE_SWAGGER === 'true') {
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
console.log('📚 Swagger文档已启用: https://webapi.jiebanke.com/api-docs');
}
// 健康检查路由
app.get('/health', (req, res) => {
res.status(200).json({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env.NODE_ENV || 'development'
});
});
// 系统统计路由
app.get('/system-stats', (req, res) => {
const stats = {
status: 'OK',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development',
nodeVersion: process.version,
memoryUsage: process.memoryUsage(),
uptime: process.uptime(),
cpuCount: require('os').cpus().length,
platform: process.platform,
architecture: process.arch
};
res.status(200).json(stats);
});
// API路由
app.use('/api/v1/auth', authRoutes);
app.use('/api/v1/users', userRoutes);
app.use('/api/v1/travel', travelRoutes);
app.use('/api/v1/animals', animalRoutes);
app.use('/api/v1/orders', orderRoutes);
// 管理员路由
app.use('/api/v1/admin', adminRoutes);
// 404处理
app.use('*', notFound);
// 全局错误处理
app.use(globalErrorHandler);
console.log('✅ 应用配置完成');
module.exports = app;