feat: 完成多多畅职就业服务平台核心功能开发
主要更新: - ✅ 完成主题配色从暗色到亮蓝白配色的全面转换 - ✅ 实现高薪岗位页面及后端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>
This commit is contained in:
200
server.js
200
server.js
@@ -1,60 +1,137 @@
|
||||
const http = require('http');
|
||||
const fs = require('fs');
|
||||
/**
|
||||
* 多多畅职大专生就业服务平台 - 后端服务器
|
||||
* 基于Express框架
|
||||
*/
|
||||
|
||||
require('dotenv').config();
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const PORT = 8080;
|
||||
// 导入路由
|
||||
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');
|
||||
|
||||
// MIME类型映射
|
||||
const mimeTypes = {
|
||||
'.html': 'text/html',
|
||||
'.css': 'text/css',
|
||||
'.js': 'application/javascript',
|
||||
'.json': 'application/json',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.ico': 'image/x-icon',
|
||||
'.woff': 'font/woff',
|
||||
'.woff2': 'font/woff2',
|
||||
'.ttf': 'font/ttf',
|
||||
'.csv': 'text/csv'
|
||||
};
|
||||
// 创建Express应用
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 8080;
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
// 解析请求的URL并解码(支持中文文件名)
|
||||
let filePath = '.' + decodeURIComponent(req.url);
|
||||
if (filePath === './') {
|
||||
filePath = './index.html';
|
||||
}
|
||||
// ========================================
|
||||
// 中间件配置
|
||||
// ========================================
|
||||
|
||||
// 获取文件扩展名
|
||||
const extname = String(path.extname(filePath)).toLowerCase();
|
||||
const contentType = mimeTypes[extname] || 'application/octet-stream';
|
||||
// CORS配置
|
||||
app.use(cors({
|
||||
origin: '*', // 允许所有来源(生产环境应该限制)
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization']
|
||||
}));
|
||||
|
||||
// 读取文件
|
||||
fs.readFile(filePath, (error, content) => {
|
||||
if (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
// 文件不存在
|
||||
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||
res.end('<h1>404 - 文件未找到</h1>', 'utf-8');
|
||||
} else {
|
||||
// 服务器错误
|
||||
res.writeHead(500);
|
||||
res.end('服务器错误: ' + error.code, 'utf-8');
|
||||
}
|
||||
} else {
|
||||
// 成功返回文件
|
||||
res.writeHead(200, { 'Content-Type': contentType });
|
||||
res.end(content, 'utf-8');
|
||||
}
|
||||
// 解析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地址
|
||||
const os = require('os');
|
||||
function getLocalIP() {
|
||||
const interfaces = os.networkInterfaces();
|
||||
for (const name of Object.keys(interfaces)) {
|
||||
@@ -69,15 +146,26 @@ function getLocalIP() {
|
||||
|
||||
const localIP = getLocalIP();
|
||||
|
||||
server.listen(PORT, '0.0.0.0', () => {
|
||||
const server = app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log('');
|
||||
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 停止服务器');
|
||||
@@ -88,6 +176,16 @@ server.listen(PORT, '0.0.0.0', () => {
|
||||
|
||||
// 优雅关闭
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n\n服务器已关闭');
|
||||
process.exit(0);
|
||||
console.log('\n\n🔌 正在关闭服务器...');
|
||||
server.close(() => {
|
||||
console.log('✅ 服务器已关闭');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
// 处理未捕获的Promise拒绝
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error('未处理的Promise拒绝:', reason);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
|
||||
Reference in New Issue
Block a user