2025-12-22 15:40:55 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 多多畅职大专生就业服务平台 - 后端服务器
|
|
|
|
|
|
* 基于Express框架
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
require('dotenv').config();
|
|
|
|
|
|
const express = require('express');
|
|
|
|
|
|
const cors = require('cors');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
const path = require('path');
|
2025-12-22 15:40:55 +08:00
|
|
|
|
const os = require('os');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
|
2025-12-22 15:40:55 +08:00
|
|
|
|
// 导入路由
|
|
|
|
|
|
const authRoutes = require('./api/routes/auth');
|
|
|
|
|
|
const applicationRoutes = require('./api/routes/applications');
|
|
|
|
|
|
const highSalaryJobsRoutes = require('./api/routes/highSalaryJobs');
|
|
|
|
|
|
const trainingUnitsRoutes = require('./api/routes/trainingUnits');
|
|
|
|
|
|
const successStoriesRoutes = require('./api/routes/successStories');
|
|
|
|
|
|
const transitionProgressRoutes = require('./api/routes/transitionProgress');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
|
2025-12-22 15:40:55 +08:00
|
|
|
|
// 创建Express应用
|
|
|
|
|
|
const app = express();
|
|
|
|
|
|
const PORT = process.env.PORT || 8080;
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 中间件配置
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
|
|
|
|
|
|
// CORS配置
|
|
|
|
|
|
app.use(cors({
|
|
|
|
|
|
origin: '*', // 允许所有来源(生产环境应该限制)
|
|
|
|
|
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
|
|
|
|
|
allowedHeaders: ['Content-Type', 'Authorization']
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
// 解析JSON请求体
|
|
|
|
|
|
app.use(express.json({ limit: '10mb' }));
|
|
|
|
|
|
|
|
|
|
|
|
// 解析URL编码的请求体
|
|
|
|
|
|
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
|
|
|
|
|
|
|
|
|
|
|
// 请求日志
|
|
|
|
|
|
app.use((req, res, next) => {
|
|
|
|
|
|
const timestamp = new Date().toISOString();
|
|
|
|
|
|
console.log(`[${timestamp}] ${req.method} ${req.url}`);
|
|
|
|
|
|
next();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// API路由
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
|
|
|
|
|
|
// 健康检查
|
|
|
|
|
|
app.get('/api/health', (req, res) => {
|
|
|
|
|
|
res.json({
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '服务器运行正常',
|
|
|
|
|
|
timestamp: new Date().toISOString()
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 用户认证相关路由
|
|
|
|
|
|
app.use('/api/auth', authRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// 投递记录相关路由
|
|
|
|
|
|
app.use('/api/applications', applicationRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// 高薪岗位相关路由
|
|
|
|
|
|
app.use('/api/high-salary-jobs', highSalaryJobsRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// 培训单元相关路由
|
|
|
|
|
|
app.use('/api/training-units', trainingUnitsRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// 成功案例相关路由
|
|
|
|
|
|
app.use('/api/success-stories', successStoriesRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// 面试进度相关路由
|
|
|
|
|
|
app.use('/api/transition-progress', transitionProgressRoutes);
|
|
|
|
|
|
|
|
|
|
|
|
// API 404处理
|
|
|
|
|
|
app.use('/api/*', (req, res) => {
|
|
|
|
|
|
res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: 'API接口不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 静态文件服务
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
|
|
|
|
|
|
// 静态文件支持(保留原有的静态文件服务功能)
|
|
|
|
|
|
app.use(express.static('.', {
|
|
|
|
|
|
index: 'index.html',
|
|
|
|
|
|
setHeaders: (res, filePath) => {
|
|
|
|
|
|
// 设置缓存策略
|
|
|
|
|
|
if (filePath.endsWith('.html')) {
|
|
|
|
|
|
res.setHeader('Cache-Control', 'no-cache');
|
|
|
|
|
|
} else if (filePath.match(/\.(css|js|jpg|png|gif|svg|woff|woff2|ttf)$/)) {
|
|
|
|
|
|
res.setHeader('Cache-Control', 'public, max-age=31536000');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
}
|
2025-12-22 15:40:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
// 处理前端路由(SPA fallback)
|
|
|
|
|
|
app.get('*', (req, res) => {
|
|
|
|
|
|
res.sendFile(path.join(__dirname, 'index.html'));
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 错误处理
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
|
|
|
|
|
|
// 404错误处理
|
|
|
|
|
|
app.use((req, res) => {
|
|
|
|
|
|
res.status(404).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '请求的资源不存在'
|
2025-11-22 19:38:14 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-12-22 15:40:55 +08:00
|
|
|
|
// 全局错误处理
|
|
|
|
|
|
app.use((err, req, res, next) => {
|
|
|
|
|
|
console.error('服务器错误:', err);
|
|
|
|
|
|
res.status(500).json({
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: process.env.NODE_ENV === 'development' ? err.message : '服务器内部错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 启动服务器
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
|
2025-11-22 19:38:14 +08:00
|
|
|
|
// 获取本机IP地址
|
|
|
|
|
|
function getLocalIP() {
|
|
|
|
|
|
const interfaces = os.networkInterfaces();
|
|
|
|
|
|
for (const name of Object.keys(interfaces)) {
|
|
|
|
|
|
for (const iface of interfaces[name]) {
|
|
|
|
|
|
if (iface.family === 'IPv4' && !iface.internal) {
|
|
|
|
|
|
return iface.address;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return 'localhost';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const localIP = getLocalIP();
|
|
|
|
|
|
|
2025-12-22 15:40:55 +08:00
|
|
|
|
const server = app.listen(PORT, '0.0.0.0', () => {
|
2025-11-22 19:38:14 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('========================================');
|
2025-12-22 15:40:55 +08:00
|
|
|
|
console.log('🚀 多多畅职就业服务平台已启动!');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
console.log('========================================');
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log(`📍 本机访问: http://localhost:${PORT}`);
|
|
|
|
|
|
console.log(`📍 局域网访问: http://${localIP}:${PORT}`);
|
|
|
|
|
|
console.log('');
|
2025-12-22 15:40:55 +08:00
|
|
|
|
console.log('🔌 API服务:');
|
|
|
|
|
|
console.log(` - 健康检查: http://localhost:${PORT}/api/health`);
|
|
|
|
|
|
console.log(` - 用户注册: POST /api/auth/register`);
|
|
|
|
|
|
console.log(` - 用户登录: POST /api/auth/login`);
|
|
|
|
|
|
console.log(` - 获取用户: GET /api/auth/me`);
|
|
|
|
|
|
console.log(` - 投递记录: GET /api/applications`);
|
|
|
|
|
|
console.log(` - 高薪岗位: GET /api/high-salary-jobs`);
|
|
|
|
|
|
console.log(` - 培训单元: GET /api/training-units`);
|
|
|
|
|
|
console.log(` - 成功案例: GET /api/success-stories`);
|
|
|
|
|
|
console.log(` - 面试进度: GET /api/transition-progress`);
|
|
|
|
|
|
console.log('');
|
2025-11-22 19:38:14 +08:00
|
|
|
|
console.log('🌐 同一局域网内的其他设备可以通过局域网地址访问');
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('💡 提示: 按 Ctrl+C 停止服务器');
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('========================================');
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 优雅关闭
|
|
|
|
|
|
process.on('SIGINT', () => {
|
2025-12-22 15:40:55 +08:00
|
|
|
|
console.log('\n\n🔌 正在关闭服务器...');
|
|
|
|
|
|
server.close(() => {
|
|
|
|
|
|
console.log('✅ 服务器已关闭');
|
|
|
|
|
|
process.exit(0);
|
|
|
|
|
|
});
|
2025-11-22 19:38:14 +08:00
|
|
|
|
});
|
2025-12-22 15:40:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 处理未捕获的Promise拒绝
|
|
|
|
|
|
process.on('unhandledRejection', (reason, promise) => {
|
|
|
|
|
|
console.error('未处理的Promise拒绝:', reason);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = app;
|