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:
229
api/controllers/trainingUnitController.js
Normal file
229
api/controllers/trainingUnitController.js
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* 培训单元控制器
|
||||
* 基于high.html的最新数据结构
|
||||
*/
|
||||
|
||||
const db = require('../../config/database');
|
||||
|
||||
/**
|
||||
* 获取所有培训单元
|
||||
* GET /api/training-units
|
||||
* 支持optionalAuth
|
||||
*/
|
||||
exports.getList = async (req, res) => {
|
||||
try {
|
||||
const userId = req.user ? req.user.id : null;
|
||||
|
||||
let query, params;
|
||||
|
||||
if (userId) {
|
||||
// 已登录:查询确认状态
|
||||
query = `
|
||||
SELECT
|
||||
tu.*,
|
||||
tc.id as confirmation_id,
|
||||
tc.confirmed_at
|
||||
FROM training_units tu
|
||||
LEFT JOIN training_confirmations tc ON tu.id = tc.training_unit_id AND tc.user_id = ?
|
||||
ORDER BY tu.display_order ASC, tu.start_date ASC
|
||||
`;
|
||||
params = [userId];
|
||||
} else {
|
||||
// 未登录:仅返回单元列表
|
||||
query = `
|
||||
SELECT * FROM training_units
|
||||
ORDER BY display_order ASC, start_date ASC
|
||||
`;
|
||||
params = [];
|
||||
}
|
||||
|
||||
const [units] = await db.query(query, params);
|
||||
|
||||
// 格式化数据
|
||||
const formattedUnits = units.map(unit => ({
|
||||
id: unit.id,
|
||||
title: unit.title,
|
||||
start_date: unit.start_date,
|
||||
related_positions: unit.related_positions,
|
||||
related_companies: unit.related_companies,
|
||||
status: unit.status,
|
||||
is_confirmed: !!unit.confirmation_id,
|
||||
confirmed_at: unit.confirmed_at || null
|
||||
}));
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
data: formattedUnits
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取培训单元失败:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '获取培训单元失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 确认预招录
|
||||
* POST /api/training-units/:id/confirm
|
||||
* 需要登录
|
||||
*/
|
||||
exports.confirm = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 检查单元是否存在
|
||||
const [units] = await db.query(
|
||||
'SELECT id, title FROM training_units WHERE id = ?',
|
||||
[id]
|
||||
);
|
||||
|
||||
if (units.length === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '培训单元不存在'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查是否已确认
|
||||
const [existing] = await db.query(
|
||||
'SELECT id FROM training_confirmations WHERE user_id = ? AND training_unit_id = ?',
|
||||
[userId, id]
|
||||
);
|
||||
|
||||
if (existing.length > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '您已确认过该单元'
|
||||
});
|
||||
}
|
||||
|
||||
// 插入确认记录(设置较短的超时时间)
|
||||
try {
|
||||
await db.query(
|
||||
'INSERT INTO training_confirmations (user_id, training_unit_id) VALUES (?, ?)',
|
||||
[userId, id]
|
||||
);
|
||||
} catch (insertError) {
|
||||
// 特殊处理数据库锁定错误
|
||||
if (insertError.code === 'ER_LOCK_WAIT_TIMEOUT') {
|
||||
return res.status(503).json({
|
||||
success: false,
|
||||
message: '系统繁忙,请稍后再试',
|
||||
error: '数据库暂时无法处理请求'
|
||||
});
|
||||
}
|
||||
throw insertError;
|
||||
}
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
message: '确认成功'
|
||||
});
|
||||
} catch (error) {
|
||||
// 处理唯一键冲突
|
||||
if (error.code === 'ER_DUP_ENTRY') {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: '您已确认过该单元'
|
||||
});
|
||||
}
|
||||
|
||||
// 处理数据库锁定错误
|
||||
if (error.code === 'ER_LOCK_WAIT_TIMEOUT') {
|
||||
console.error('数据库锁定:', error.message);
|
||||
return res.status(503).json({
|
||||
success: false,
|
||||
message: '系统繁忙,请稍后再试',
|
||||
error: '数据库暂时无法处理请求'
|
||||
});
|
||||
}
|
||||
|
||||
console.error('确认预招录失败:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '确认失败,请稍后重试'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消预招录
|
||||
* DELETE /api/training-units/:id/confirm
|
||||
* 需要登录
|
||||
*/
|
||||
exports.cancelConfirm = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const userId = req.user.id;
|
||||
|
||||
const [result] = await db.query(
|
||||
'DELETE FROM training_confirmations WHERE user_id = ? AND training_unit_id = ?',
|
||||
[userId, id]
|
||||
);
|
||||
|
||||
if (result.affectedRows === 0) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: '未找到确认记录'
|
||||
});
|
||||
}
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
message: '取消成功'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('取消预招录失败:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '取消预招录失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取我的确认列表
|
||||
* GET /api/training-units/my-confirmations
|
||||
* 需要登录
|
||||
*/
|
||||
exports.getMyConfirmations = async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
|
||||
const [confirmations] = await db.query(`
|
||||
SELECT
|
||||
tu.*,
|
||||
tc.confirmed_at
|
||||
FROM training_confirmations tc
|
||||
JOIN training_units tu ON tc.training_unit_id = tu.id
|
||||
WHERE tc.user_id = ?
|
||||
ORDER BY tc.confirmed_at DESC
|
||||
`, [userId]);
|
||||
|
||||
const formattedData = confirmations.map(c => ({
|
||||
id: c.id,
|
||||
title: c.title,
|
||||
start_date: c.start_date,
|
||||
related_positions: c.related_positions,
|
||||
related_companies: c.related_companies,
|
||||
confirmed_at: c.confirmed_at
|
||||
}));
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
data: formattedData
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取确认列表失败:', error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: '获取确认列表失败',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user