161 lines
6.8 KiB
TypeScript
161 lines
6.8 KiB
TypeScript
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,
|
||
userGroupController as UserGroupController
|
||
} from './controllers';
|
||
import {
|
||
upload,
|
||
errorHandler,
|
||
adminAuth,
|
||
requestLogger,
|
||
responseFormatter
|
||
} from './middlewares';
|
||
|
||
const app = express();
|
||
const PORT = process.env.PORT || 3001;
|
||
|
||
// 中间件
|
||
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/user-groups', adminAuth, UserGroupController.getAll);
|
||
apiRouter.post('/admin/user-groups', adminAuth, UserGroupController.create);
|
||
apiRouter.put('/admin/user-groups/:id', adminAuth, UserGroupController.update);
|
||
apiRouter.delete('/admin/user-groups/:id', adminAuth, UserGroupController.delete);
|
||
apiRouter.get('/admin/user-groups/:id/members', adminAuth, UserGroupController.getMembers);
|
||
|
||
// 用户管理
|
||
apiRouter.get('/admin/users', adminAuth, AdminUserController.getUsers);
|
||
apiRouter.post('/admin/users', adminAuth, AdminUserController.createUser);
|
||
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/statistics/users', adminAuth, AdminController.getUserStats);
|
||
apiRouter.get('/admin/statistics/subjects', adminAuth, AdminController.getSubjectStats);
|
||
apiRouter.get('/admin/statistics/tasks', adminAuth, AdminController.getTaskStats);
|
||
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 {
|
||
// 初始化数据库
|
||
console.log('开始数据库初始化...');
|
||
await initDatabase();
|
||
} catch (error) {
|
||
console.error('数据库初始化失败,将继续启动服务器:', error);
|
||
}
|
||
|
||
// 无论数据库初始化是否成功,都启动服务器
|
||
try {
|
||
app.listen(PORT, () => {
|
||
console.log(`服务器运行在端口 ${PORT}`);
|
||
console.log(`API文档: http://localhost:${PORT}/api`);
|
||
});
|
||
} catch (error) {
|
||
console.error('启动服务器失败:', error);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// 启动服务器
|
||
// 重启触发
|
||
startServer();
|