Files
jiebanke/backend/src/app.js

205 lines
5.3 KiB
JavaScript
Raw Normal View History

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');
2025-08-30 14:33:49 +08:00
console.log('🔧 初始化Express应用...');
2025-08-30 14:33:49 +08:00
const { globalErrorHandler, notFound } = require('./utils/errors');
2025-08-30 14:33:49 +08:00
2025-09-11 15:05:23 +08:00
// 检查是否为无数据库模式
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'); // 新增管理员路由
}
2025-08-30 14:33:49 +08:00
const app = express();
2025-08-30 14:33:49 +08:00
console.log('✅ Express应用初始化完成');
2025-08-30 14:33:49 +08:00
// 安全中间件
app.use(helmet());
2025-08-30 14:33:49 +08:00
// CORS配置
app.use(cors({
origin: process.env.NODE_ENV === 'production'
? ['https://your-domain.com']
2025-09-03 13:25:08 +08:00
: ['https://www.jiebanke.com', 'https://admin.jiebanke.com', 'https://webapi.jiebanke.com'],
2025-08-30 14:33:49 +08:00
credentials: true
}));
2025-08-30 14:33:49 +08:00
// 请求日志
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
2025-08-30 14:33:49 +08:00
} else {
app.use(morgan('combined'));
2025-08-30 14:33:49 +08:00
}
// 请求频率限制
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);
2025-08-30 14:33:49 +08:00
// 请求体解析
app.use(express.json({ limit: '10kb' }));
app.use(express.urlencoded({ extended: true, limit: '10kb' }));
2025-08-30 14:33:49 +08:00
// 数据清洗
app.use(xss()); // 防止XSS攻击
2025-08-30 14:33:49 +08:00
app.use(hpp({ // 防止参数污染
whitelist: [
'page',
'pageSize',
'sort',
'fields',
'price',
'rating',
'distance'
]
}));
2025-08-30 14:33:49 +08:00
// 静态文件服务
app.use('/uploads', express.static('uploads'));
2025-08-30 14:33:49 +08:00
// Swagger文档路由
if (process.env.NODE_ENV === 'development' || process.env.ENABLE_SWAGGER === 'true') {
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
2025-09-03 13:25:08 +08:00
console.log('📚 Swagger文档已启用: https://webapi.jiebanke.com/api-docs');
}
2025-08-30 14:33:49 +08:00
// 健康检查路由
app.get('/health', (req, res) => {
res.status(200).json({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
2025-09-11 15:05:23 +08:00
environment: process.env.NODE_ENV || 'development',
noDbMode: NO_DB_MODE
});
});
2025-08-30 14:33:49 +08:00
// 系统统计路由
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,
2025-09-11 15:05:23 +08:00
architecture: process.arch,
noDbMode: NO_DB_MODE
};
res.status(200).json(stats);
});
2025-09-11 15:05:23 +08:00
// 无数据库模式下的模拟路由
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);
}
2025-08-30 14:33:49 +08:00
// 404处理
app.use('*', notFound);
2025-08-30 14:33:49 +08:00
// 全局错误处理
app.use(globalErrorHandler);
2025-08-30 14:33:49 +08:00
console.log('✅ 应用配置完成');
2025-08-30 14:33:49 +08:00
module.exports = app;