主要更新: - ✅ 完成主题配色从暗色到亮蓝白配色的全面转换 - ✅ 实现高薪岗位页面及后端API集成 - ✅ 完成登录注册页面及认证系统 - ✅ 实现预招录确认功能 - ✅ 添加数据库管理和维护工具脚本 - ✅ 优化错误处理和用户体验 核心功能: 1. 首页 (index.html) - 3D地球、专业分类、过渡岗位 2. 高薪岗位页面 (high.html) - 岗位详情、预招录确认、成功案例 3. 登录注册 (auth.html) - 用户认证、专业分类选择 4. 后端API - RESTful接口,JWT认证,MySQL数据库 技术栈: - 前端:Three.js, GSAP, 原生JavaScript - 后端:Node.js, Express, MySQL - 认证:JWT, bcrypt - 样式:自定义CSS,响应式设计 数据库工具: - kill-by-ids.js - 批量终止MySQL进程 - unlock-all-tables.js - 解锁数据库表 - init-db.js - 初始化数据库 - 其他管理脚本 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
192 lines
5.6 KiB
JavaScript
192 lines
5.6 KiB
JavaScript
/**
|
||
* 多多畅职大专生就业服务平台 - 后端服务器
|
||
* 基于Express框架
|
||
*/
|
||
|
||
require('dotenv').config();
|
||
const express = require('express');
|
||
const cors = require('cors');
|
||
const path = require('path');
|
||
const os = require('os');
|
||
|
||
// 导入路由
|
||
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');
|
||
|
||
// 创建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');
|
||
}
|
||
}
|
||
}));
|
||
|
||
// 处理前端路由(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: '请求的资源不存在'
|
||
});
|
||
});
|
||
|
||
// 全局错误处理
|
||
app.use((err, req, res, next) => {
|
||
console.error('服务器错误:', err);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: process.env.NODE_ENV === 'development' ? err.message : '服务器内部错误'
|
||
});
|
||
});
|
||
|
||
// ========================================
|
||
// 启动服务器
|
||
// ========================================
|
||
|
||
// 获取本机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();
|
||
|
||
const server = app.listen(PORT, '0.0.0.0', () => {
|
||
console.log('');
|
||
console.log('========================================');
|
||
console.log('🚀 多多畅职就业服务平台已启动!');
|
||
console.log('========================================');
|
||
console.log('');
|
||
console.log(`📍 本机访问: http://localhost:${PORT}`);
|
||
console.log(`📍 局域网访问: http://${localIP}:${PORT}`);
|
||
console.log('');
|
||
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('');
|
||
console.log('🌐 同一局域网内的其他设备可以通过局域网地址访问');
|
||
console.log('');
|
||
console.log('💡 提示: 按 Ctrl+C 停止服务器');
|
||
console.log('');
|
||
console.log('========================================');
|
||
console.log('');
|
||
});
|
||
|
||
// 优雅关闭
|
||
process.on('SIGINT', () => {
|
||
console.log('\n\n🔌 正在关闭服务器...');
|
||
server.close(() => {
|
||
console.log('✅ 服务器已关闭');
|
||
process.exit(0);
|
||
});
|
||
});
|
||
|
||
// 处理未捕获的Promise拒绝
|
||
process.on('unhandledRejection', (reason, promise) => {
|
||
console.error('未处理的Promise拒绝:', reason);
|
||
});
|
||
|
||
module.exports = app;
|