Files
jurong_circle_agent_black/server.js
2025-09-15 17:28:12 +08:00

165 lines
4.8 KiB
JavaScript
Raw Permalink 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.

// 加载环境变量配置
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const path = require('path');
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');
const {initDB, getDB, dbConfig} = require('./database');
const {logger} = require('./config/logger');
const {errorHandler, notFound} = require('./middleware/errorHandler');
const fs = require('fs');
const app = express();
const PORT = process.env.AGENT_PORT || 3002;
// 确保日志目录存在
const logDir = path.join(__dirname, 'logs');
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, {recursive: true});
}
// 安全中间件
app.use(helmet({
contentSecurityPolicy: false, // 为了支持前端应用
crossOriginEmbedderPolicy: false,
crossOriginOpenerPolicy: false, // 禁用 COOP 头部以避免非 HTTPS 环境的警告
originAgentCluster: false // 禁用Origin-Agent-Cluster头部
}));
// 中间件配置
// CORS配置 - 允许代理前端访问
app.use(cors({
origin: [
'http://192.168.1.43:5175',
'http://localhost:5173',
'http://localhost:5176',
'http://localhost:5175',
'http://localhost:5174',
'http://localhost:3002',
'https://agent.zrbjr.com',
'https://www.zrbjr.com',
'https://zrbjr.com'
],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With']
}));
app.use(bodyParser.json({limit: '10mb'}));
app.use(bodyParser.urlencoded({extended: true, limit: '10mb'}));
// 请求日志中间件
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
// 只记录非正常状态码的请求日志过滤掉200、304等正常返回
if (res.statusCode >= 400 || res.statusCode < 200) {
logger.info('HTTP Request', {
method: req.method,
url: req.originalUrl,
statusCode: res.statusCode,
duration: `${duration}ms`,
ip: req.ip,
userAgent: req.get('User-Agent')
});
}
});
next();
});
// 限流中间件
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 1000, // 限制每个IP 15分钟内最多1000个请求
message: {
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: '请求过于频繁,请稍后再试'
}
}
});
app.use('/api', limiter);
// 上传文件静态服务
app.use('/uploads', express.static(path.join(__dirname, 'uploads'), {
setHeaders: (res, filePath) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
}));
// API路由 - 代理专用路由
app.use('/api/auth', require('./routes/auth'));
// 添加代理认证路由别名,兼容前端请求
app.use('/api/agents/auth', require('./routes/auth'));
app.use('/api/agent', require('./routes/agent'));
app.use('/api/users', require('./routes/users'));
app.use('/api/transfers', require('./routes/transfers'));
app.use('/api/commissions', require('./routes/commissions'));
app.use('/api/upload', require('./routes/upload'));
app.use('/api/captcha', require('./routes/captcha')); // 验证码路由
// 404处理
app.use(notFound);
// 错误处理
app.use(errorHandler);
// 导出app供测试使用
module.exports = {
app, getDB
};
// 初始化全局验证码存储
global.captchaStore = new Map();
// 启动服务器
app.listen(PORT, async () => {
try {
// 初始化数据库连接
await initDB();
console.log(`代理后台API服务器运行在端口 ${PORT}`);
} catch (error) {
console.error('服务器启动失败:', error);
process.exit(1);
}
});
// 优雅关闭处理
process.on('SIGTERM', async () => {
console.log('收到SIGTERM信号正在关闭服务器...');
try {
await closeDB();
console.log('数据库连接已关闭');
} catch (error) {
console.error('关闭数据库连接时出错:', error);
}
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('收到SIGINT信号正在关闭服务器...');
try {
await closeDB();
console.log('数据库连接已关闭');
} catch (error) {
console.error('关闭数据库连接时出错:', error);
}
process.exit(0);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的Promise拒绝:', reason);
});
process.on('uncaughtException', (error) => {
console.error('未捕获的异常:', error);
process.exit(1);
});