import express from 'express'; import cors from 'cors'; import path from 'path'; import { initDatabase } from './database'; import { UserController, QuestionController, QuizController, AdminController, BackupController, QuestionCategoryController, ExamSubjectController, ExamTaskController, AdminUserController } from './controllers'; import { upload, errorHandler, adminAuth, requestLogger, responseFormatter } from './middlewares'; const app = express(); const PORT = process.env.PORT || 3000; // 中间件 app.use(cors()); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ extended: true, limit: '10mb' })); app.use(requestLogger); app.use(responseFormatter); // API路由 const apiRouter = express.Router(); // 用户相关 apiRouter.post('/users', UserController.createUser); apiRouter.get('/users/:id', UserController.getUser); apiRouter.post('/users/validate', UserController.validateUserInfo); apiRouter.get('/users/name/:name', UserController.getUsersByName); // 题库管理 apiRouter.get('/questions', QuestionController.getQuestions); apiRouter.get('/questions/:id', QuestionController.getQuestion); apiRouter.post('/questions', adminAuth, QuestionController.createQuestion); apiRouter.put('/questions/:id', adminAuth, QuestionController.updateQuestion); apiRouter.delete('/questions/:id', adminAuth, QuestionController.deleteQuestion); apiRouter.post('/questions/import', adminAuth, upload.single('file'), QuestionController.importQuestions); apiRouter.get('/questions/export', adminAuth, QuestionController.exportQuestions); // 为了兼容前端可能的错误请求,添加一个不包含 /api 前缀的路由 app.get('/questions/export', adminAuth, QuestionController.exportQuestions); // 题目类别 apiRouter.get('/question-categories', QuestionCategoryController.getCategories); apiRouter.post('/admin/question-categories', adminAuth, QuestionCategoryController.createCategory); apiRouter.put('/admin/question-categories/:id', adminAuth, QuestionCategoryController.updateCategory); apiRouter.delete('/admin/question-categories/:id', adminAuth, QuestionCategoryController.deleteCategory); // 考试科目 apiRouter.get('/exam-subjects', ExamSubjectController.getSubjects); apiRouter.get('/admin/subjects', adminAuth, ExamSubjectController.getSubjects); apiRouter.post('/admin/subjects', adminAuth, ExamSubjectController.createSubject); apiRouter.put('/admin/subjects/:id', adminAuth, ExamSubjectController.updateSubject); apiRouter.delete('/admin/subjects/:id', adminAuth, ExamSubjectController.deleteSubject); // 考试任务 apiRouter.get('/exam-tasks', ExamTaskController.getTasks); apiRouter.get('/admin/tasks', adminAuth, ExamTaskController.getTasks); apiRouter.get('/admin/tasks/:id/users', adminAuth, ExamTaskController.getTaskUsers); apiRouter.get('/exam-tasks/user/:userId', ExamTaskController.getUserTasks); apiRouter.post('/admin/tasks', adminAuth, ExamTaskController.createTask); apiRouter.put('/admin/tasks/:id', adminAuth, ExamTaskController.updateTask); apiRouter.delete('/admin/tasks/:id', adminAuth, ExamTaskController.deleteTask); apiRouter.get('/admin/tasks/:id/report', adminAuth, ExamTaskController.getTaskReport); // 用户管理 apiRouter.get('/admin/users', adminAuth, AdminUserController.getUsers); apiRouter.put('/admin/users/:id', adminAuth, AdminUserController.updateUser); apiRouter.delete('/admin/users', adminAuth, AdminUserController.deleteUser); apiRouter.get('/admin/users/export', adminAuth, AdminUserController.exportUsers); apiRouter.post('/admin/users/import', adminAuth, upload.single('file'), AdminUserController.importUsers); apiRouter.get('/admin/users/:userId/records', adminAuth, AdminUserController.getUserRecords); apiRouter.get('/admin/quiz/records/detail/:recordId', adminAuth, AdminUserController.getRecordDetail); // 答题相关 apiRouter.post('/quiz/generate', QuizController.generateQuiz); apiRouter.post('/quiz/submit', QuizController.submitQuiz); apiRouter.get('/quiz/records/:userId', QuizController.getUserRecords); apiRouter.get('/quiz/records/detail/:recordId', QuizController.getRecordDetail); apiRouter.get('/quiz/records', adminAuth, QuizController.getAllRecords); // 管理员相关 apiRouter.post('/admin/login', AdminController.login); apiRouter.get('/admin/statistics', adminAuth, AdminController.getStatistics); apiRouter.get('/admin/active-tasks', adminAuth, AdminController.getActiveTasksStats); apiRouter.put('/admin/config', adminAuth, AdminController.updateQuizConfig); apiRouter.get('/admin/config', adminAuth, AdminController.getQuizConfig); apiRouter.put('/admin/password', adminAuth, AdminController.updatePassword); apiRouter.get('/admin/configs', adminAuth, AdminController.getAllConfigs); // 数据备份和恢复 apiRouter.get('/admin/export/users', adminAuth, BackupController.exportUsers); apiRouter.get('/admin/export/questions', adminAuth, BackupController.exportQuestions); apiRouter.get('/admin/export/records', adminAuth, BackupController.exportRecords); apiRouter.get('/admin/export/answers', adminAuth, BackupController.exportAnswers); apiRouter.post('/admin/restore', adminAuth, BackupController.restoreData); // 应用API路由 app.use('/api', apiRouter); // 静态文件服务 app.use(express.static(path.join(process.cwd(), 'dist'))); // 前端路由(SPA支持) app.get('*', (req, res) => { res.sendFile(path.join(process.cwd(), 'dist', 'index.html')); }); // 错误处理 app.use(errorHandler); // 启动服务器 async function startServer() { try { await initDatabase(); console.log('数据库初始化完成'); app.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); console.log(`API文档: http://localhost:${PORT}/api`); }); } catch (error) { console.error('启动服务器失败:', error); process.exit(1); } } startServer();