2
2

interviews.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. const express = require('express');
  2. const router = express.Router();
  3. const { pool } = require('../config/db');
  4. // 获取所有面试
  5. router.get('/', async (req, res) => {
  6. try {
  7. const [interviews] = await pool.query(`
  8. SELECT
  9. id, title, description, questions, duration,
  10. created_at AS createdAt
  11. FROM interviews
  12. ORDER BY created_at DESC
  13. `);
  14. // 解析questions字段
  15. interviews.forEach(interview => {
  16. interview.questions = JSON.parse(interview.questions);
  17. });
  18. res.json(interviews);
  19. } catch (error) {
  20. console.error('Get interviews error:', error);
  21. res.status(500).json({ error: 'Server error' });
  22. }
  23. });
  24. // 创建新面试
  25. router.post('/', async (req, res) => {
  26. try {
  27. const {
  28. title,
  29. description,
  30. questions,
  31. duration
  32. } = req.body;
  33. const id = require('crypto').randomUUID();
  34. await pool.query(
  35. `INSERT INTO interviews (
  36. id, title, description, questions, duration, created_at
  37. ) VALUES (?, ?, ?, ?, ?, ?)`,
  38. [
  39. id, title, description,
  40. JSON.stringify(questions || []),
  41. duration,
  42. new Date()
  43. ]
  44. );
  45. const [newInterview] = await pool.query(
  46. 'SELECT * FROM interviews WHERE id = ?',
  47. [id]
  48. );
  49. res.status(201).json(formatInterview(newInterview[0]));
  50. } catch (error) {
  51. console.error('Create interview error:', error);
  52. res.status(500).json({ error: 'Server error' });
  53. }
  54. });
  55. // 安排候选人面试
  56. router.post('/schedule', async (req, res) => {
  57. try {
  58. const {
  59. candidateId,
  60. interviewId,
  61. interviewTime,
  62. interviewerId,
  63. notes
  64. } = req.body;
  65. const id = require('crypto').randomUUID();
  66. await pool.query(
  67. `INSERT INTO candidate_interviews (
  68. id, candidate_id, interview_id, interview_time,
  69. interviewer_id, notes, result
  70. ) VALUES (?, ?, ?, ?, ?, ?, 'scheduled')`,
  71. [
  72. id, candidateId, interviewId,
  73. new Date(interviewTime),
  74. interviewerId, notes
  75. ]
  76. );
  77. // 更新候选人状态
  78. await pool.query(
  79. `UPDATE candidates
  80. SET status = 'interviewed', reviewed_at = ?
  81. WHERE id = ?`,
  82. [new Date(), candidateId]
  83. );
  84. // 记录状态变更历史
  85. await pool.query(
  86. `INSERT INTO candidate_status_history (
  87. id, candidate_id, old_status, new_status,
  88. changed_by, change_time
  89. ) VALUES (?, ?, ?, ?, ?, ?)`,
  90. [
  91. require('crypto').randomUUID(),
  92. candidateId,
  93. 'passed',
  94. 'interviewed',
  95. req.user?.id || 'system',
  96. new Date()
  97. ]
  98. );
  99. const [scheduledInterview] = await pool.query(
  100. `SELECT ci.*, i.title AS interview_title
  101. FROM candidate_interviews ci
  102. JOIN interviews i ON ci.interview_id = i.id
  103. WHERE ci.id = ?`,
  104. [id]
  105. );
  106. res.status(201).json(formatCandidateInterview(scheduledInterview[0]));
  107. } catch (error) {
  108. console.error('Schedule interview error:', error);
  109. res.status(500).json({ error: 'Server error' });
  110. }
  111. });
  112. // 更新面试结果
  113. router.put('/:id/result', async (req, res) => {
  114. try {
  115. const { id } = req.params;
  116. const { result, notes } = req.body;
  117. await pool.query(
  118. `UPDATE candidate_interviews
  119. SET result = ?, notes = ?
  120. WHERE id = ?`,
  121. [result, notes, id]
  122. );
  123. const [updatedInterview] = await pool.query(
  124. `SELECT ci.*, i.title AS interview_title
  125. FROM candidate_interviews ci
  126. JOIN interviews i ON ci.interview_id = i.id
  127. WHERE ci.id = ?`,
  128. [id]
  129. );
  130. res.json(formatCandidateInterview(updatedInterview[0]));
  131. } catch (error) {
  132. console.error('Update interview result error:', error);
  133. res.status(500).json({ error: 'Server error' });
  134. }
  135. });
  136. // 格式化面试数据
  137. function formatInterview(interview) {
  138. return {
  139. ...interview,
  140. questions: JSON.parse(interview.questions),
  141. createdAt: interview.created_at
  142. };
  143. }
  144. // 格式化候选人面试数据
  145. function formatCandidateInterview(candidateInterview) {
  146. return {
  147. ...candidateInterview,
  148. interviewTime: candidateInterview.interview_time,
  149. interviewerId: candidateInterview.interviewer_id,
  150. interviewTitle: candidateInterview.interview_title
  151. };
  152. }
  153. module.exports = router;