Files
jiebanke/backend/src/app.js

205 lines
5.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 NO_DB_MODE = process.env.NO_DB_MODE === 'true';
let authRoutes, userRoutes, travelRoutes, animalRoutes, orderRoutes, adminRoutes;
// 路由导入 - 根据是否为无数据库模式决定是否导入实际路由
if (NO_DB_MODE) {
console.log('⚠️ 无数据库模式:将使用模拟路由');
} else {
// 路由导入
authRoutes = require('./routes/auth');
userRoutes = require('./routes/user');
travelRoutes = require('./routes/travel');
animalRoutes = require('./routes/animal');
orderRoutes = require('./routes/order');
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',
noDbMode: NO_DB_MODE
});
});
// 系统统计路由
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,
noDbMode: NO_DB_MODE
};
res.status(200).json(stats);
});
// 无数据库模式下的模拟路由
if (NO_DB_MODE) {
// 认证路由
app.use('/api/v1/auth', (req, res) => {
if (req.method === 'POST' && req.path === '/login') {
// 模拟登录响应
res.status(200).json({
success: true,
message: '模拟登录成功',
data: {
token: 'mock-jwt-token',
user: {
id: 1,
username: 'mockuser',
email: 'mock@example.com',
role: 'user'
}
}
});
} else {
res.status(503).json({
success: false,
message: '当前为无数据库模式,该功能不可用'
});
}
});
// 其他路由的通用响应
app.use('/api/v1/users', (req, res) => {
res.status(503).json({
success: false,
message: '当前为无数据库模式,用户管理功能不可用'
});
});
app.use('/api/v1/travel', (req, res) => {
res.status(503).json({
success: false,
message: '当前为无数据库模式,旅行相关功能不可用'
});
});
app.use('/api/v1/animals', (req, res) => {
res.status(503).json({
success: false,
message: '当前为无数据库模式,动物相关功能不可用'
});
});
app.use('/api/v1/orders', (req, res) => {
res.status(503).json({
success: false,
message: '当前为无数据库模式,订单相关功能不可用'
});
});
app.use('/api/v1/admin', (req, res) => {
res.status(503).json({
success: false,
message: '当前为无数据库模式,管理员功能不可用'
});
});
} else {
// 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;