|
@@ -14,6 +14,47 @@ const safeParseJSON = (data) => {
|
|
|
}
|
|
|
return data;
|
|
|
};
|
|
|
+router.put('/jobs/:id', async (req, res) => {
|
|
|
+ const { id } = req.params;
|
|
|
+ const updates = req.body;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 构建动态更新语句
|
|
|
+ const updateFields = [];
|
|
|
+ const values = [];
|
|
|
+
|
|
|
+ for (const [key, value] of Object.entries(updates)) {
|
|
|
+ updateFields.push(`${key} = ?`);
|
|
|
+ values.push(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (updateFields.length === 0) {
|
|
|
+ return res.status(400).json({ error: 'No fields to update' });
|
|
|
+ }
|
|
|
+
|
|
|
+ values.push(id);
|
|
|
+
|
|
|
+ const query = `
|
|
|
+ UPDATE jobs
|
|
|
+ SET ${updateFields.join(', ')}, updated_at = NOW()
|
|
|
+ WHERE id = ?
|
|
|
+ `;
|
|
|
+
|
|
|
+ const [result] = await pool.query(query, values);
|
|
|
+
|
|
|
+ if (result.affectedRows === 0) {
|
|
|
+ return res.status(404).json({ error: 'Job not found' });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回更新后的职位信息
|
|
|
+ const [updatedJob] = await pool.query('SELECT * FROM jobs WHERE id = ?', [id]);
|
|
|
+ res.json(updatedJob[0]);
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Update job error:', error);
|
|
|
+ res.status(500).json({ error: 'Database error' });
|
|
|
+ }
|
|
|
+});
|
|
|
|
|
|
// 获取所有职位
|
|
|
router.get('/', async (req, res) => {
|
|
@@ -43,6 +84,79 @@ router.get('/', async (req, res) => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+// 更新职位信息
|
|
|
+router.put('/:id', async (req, res) => {
|
|
|
+ const { id } = req.params;
|
|
|
+ const updates = req.body;
|
|
|
+
|
|
|
+ // 验证必要字段
|
|
|
+ if (!updates || Object.keys(updates).length === 0) {
|
|
|
+ return res.status(400).json({
|
|
|
+ error: '请求体不能为空',
|
|
|
+ example: {
|
|
|
+ title: "新职位标题",
|
|
|
+ description: "职位描述"
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 只允许更新特定字段
|
|
|
+ const allowedFields = ['title', 'description', 'department', 'location', 'status'];
|
|
|
+ const updateFields = [];
|
|
|
+ const values = [];
|
|
|
+
|
|
|
+ for (const [key, value] of Object.entries(updates)) {
|
|
|
+ if (allowedFields.includes(key)) {
|
|
|
+ updateFields.push(`${key} = ?`);
|
|
|
+ values.push(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (updateFields.length === 0) {
|
|
|
+ return res.status(400).json({
|
|
|
+ error: '没有有效的字段可更新',
|
|
|
+ allowedFields
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ values.push(id);
|
|
|
+
|
|
|
+ const query = `
|
|
|
+ UPDATE jobs
|
|
|
+ SET ${updateFields.join(', ')}, updated_at = NOW()
|
|
|
+ WHERE id = ?
|
|
|
+ `;
|
|
|
+
|
|
|
+ const [result] = await pool.query(query, values);
|
|
|
+
|
|
|
+ if (result.affectedRows === 0) {
|
|
|
+ return res.status(404).json({
|
|
|
+ error: '职位不存在或未更改',
|
|
|
+ jobId: id
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回更新后的数据
|
|
|
+ const [updatedJob] = await pool.query(
|
|
|
+ 'SELECT * FROM jobs WHERE id = ?',
|
|
|
+ [id]
|
|
|
+ );
|
|
|
+
|
|
|
+ res.json({
|
|
|
+ success: true,
|
|
|
+ data: updatedJob[0]
|
|
|
+ });
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('数据库更新错误:', error);
|
|
|
+ res.status(500).json({
|
|
|
+ error: '更新职位信息失败',
|
|
|
+ details: process.env.NODE_ENV === 'development' ? error.message : null
|
|
|
+ });
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
// 创建新职位(修正版)
|
|
|
router.post('/', async (req, res) => {
|
|
|
const connection = await pool.getConnection();
|
|
@@ -113,83 +227,74 @@ router.post('/', async (req, res) => {
|
|
|
connection.release();
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
-// 更新职位
|
|
|
-router.put('/:id', async (req, res) => {
|
|
|
+router.delete('/:id', async (req, res) => {
|
|
|
+ const { id } = req.params;
|
|
|
+
|
|
|
try {
|
|
|
- const { id } = req.params;
|
|
|
- const updates = req.body;
|
|
|
-
|
|
|
- const updateFields = [];
|
|
|
- const queryParams = [];
|
|
|
-
|
|
|
- // 动态构建更新语句
|
|
|
- for (const [key, value] of Object.entries(updates)) {
|
|
|
- if (key === 'aiCriteria') {
|
|
|
- updateFields.push('ai_criteria = ?');
|
|
|
- queryParams.push(JSON.stringify(value));
|
|
|
- } else {
|
|
|
- updateFields.push(`${key} = ?`);
|
|
|
- queryParams.push(value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (updateFields.length === 0) {
|
|
|
- return res.status(400).json({ error: 'No fields to update' });
|
|
|
- }
|
|
|
-
|
|
|
- queryParams.push(id);
|
|
|
-
|
|
|
- await pool.query(
|
|
|
- `UPDATE jobs
|
|
|
- SET ${updateFields.join(', ')}, updated_at = ?
|
|
|
- WHERE id = ?`,
|
|
|
- [...queryParams, new Date()]
|
|
|
- );
|
|
|
-
|
|
|
- const [updatedJob] = await pool.query(
|
|
|
- 'SELECT * FROM jobs WHERE id = ?',
|
|
|
+ // 使用软删除,将状态标记为deleted
|
|
|
+ const [result] = await pool.query(
|
|
|
+ `UPDATE jobs SET status = 'deleted', updated_at = NOW() WHERE id = ? AND status != 'deleted'`,
|
|
|
[id]
|
|
|
);
|
|
|
|
|
|
- if (updatedJob.length === 0) {
|
|
|
- return res.status(404).json({ error: 'Job not found' });
|
|
|
+ if (result.affectedRows === 0) {
|
|
|
+ return res.status(404).json({
|
|
|
+ success: false,
|
|
|
+ error: '职位不存在或已被删除'
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- res.json({
|
|
|
- ...updatedJob[0],
|
|
|
- pendingResumes: updatedJob[0].pending_resumes,
|
|
|
- passedResumes: updatedJob[0].passed_resumes,
|
|
|
- aiCriteria: safeParseJSON(updatedJob[0].ai_criteria),
|
|
|
- createdAt: updatedJob[0].created_at,
|
|
|
- updatedAt: updatedJob[0].updated_at
|
|
|
- });
|
|
|
+ // 成功删除返回204 No Content
|
|
|
+ res.status(204).end();
|
|
|
|
|
|
} catch (error) {
|
|
|
- console.error('Update job error:', error);
|
|
|
- res.status(500).json({ error: 'Server error' });
|
|
|
+ console.error('删除职位失败:', error);
|
|
|
+ res.status(500).json({
|
|
|
+ success: false,
|
|
|
+ error: '删除职位失败',
|
|
|
+ details: process.env.NODE_ENV === 'development' ? error.message : undefined
|
|
|
+ });
|
|
|
}
|
|
|
});
|
|
|
+// 更新职位
|
|
|
+router.put('/:id/status', async (req, res) => {
|
|
|
+ const { id } = req.params;
|
|
|
+ const { status } = req.body;
|
|
|
+
|
|
|
+ // 验证状态值
|
|
|
+ if (!['active', 'paused'].includes(status)) {
|
|
|
+ return res.status(400).json({
|
|
|
+ success: false,
|
|
|
+ error: '无效的状态值',
|
|
|
+ allowed: ['active', 'paused']
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
-// 删除职位
|
|
|
-router.delete('/:id', async (req, res) => {
|
|
|
try {
|
|
|
- const { id } = req.params;
|
|
|
-
|
|
|
- // 软删除
|
|
|
- await pool.query(
|
|
|
- `UPDATE jobs SET status = 'deleted', updated_at = ?
|
|
|
- WHERE id = ?`,
|
|
|
- [new Date(), id]
|
|
|
+ const [result] = await pool.query(
|
|
|
+ `UPDATE jobs SET status = ?, updated_at = NOW() WHERE id = ?`,
|
|
|
+ [status, id]
|
|
|
);
|
|
|
|
|
|
- res.status(204).end();
|
|
|
+ if (result.affectedRows === 0) {
|
|
|
+ return res.status(404).json({
|
|
|
+ success: false,
|
|
|
+ error: '职位不存在'
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ res.json({
|
|
|
+ success: true,
|
|
|
+ message: '状态更新成功'
|
|
|
+ });
|
|
|
} catch (error) {
|
|
|
- console.error('Delete job error:', error);
|
|
|
- res.status(500).json({ error: 'Server error' });
|
|
|
+ console.error('状态更新失败:', error);
|
|
|
+ res.status(500).json({
|
|
|
+ success: false,
|
|
|
+ error: '服务器错误'
|
|
|
+ });
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
// 触发职位筛选
|
|
|
router.post('/:id/screen', async (req, res) => {
|
|
|
try {
|