Files

175 lines
4.8 KiB
TypeScript
Raw Permalink Normal View History

import { Request, Response } from 'express';
import * as XLSX from 'xlsx';
import { UserModel, QuestionModel, QuizModel } from '../models';
export class BackupController {
// 导出用户数据
static async exportUsers(req: Request, res: Response) {
try {
const result = await UserModel.findAll(10000, 0);
const usersData = result.users.map(user => ({
ID: user.id,
姓名: user.name,
手机号: user.phone,
创建时间: user.createdAt
}));
res.json({
success: true,
data: usersData
});
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || '导出用户数据失败'
});
}
}
// 导出问题数据
static async exportQuestions(req: Request, res: Response) {
try {
const { type } = req.query;
const result = await QuestionModel.findAll({
type: type as string,
limit: 10000,
offset: 0
});
const questionsData = result.questions.map(question => ({
ID: question.id,
题目内容: question.content,
题型: question.type,
题目类别: question.category,
选项: question.options ? question.options.join('|') : '',
标准答案: Array.isArray(question.answer) ? question.answer.join(',') : question.answer,
分值: question.score,
创建时间: question.createdAt
}));
res.json({
success: true,
data: questionsData
});
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || '导出问题数据失败'
});
}
}
// 导出答题记录
static async exportRecords(req: Request, res: Response) {
try {
const result = await QuizModel.findAllRecords(10000, 0);
const recordsData = result.records.map((record: any) => ({
ID: record.id,
用户ID: record.userId,
用户名: record.userName,
手机号: record.userPhone,
总得分: record.totalScore,
正确题数: record.correctCount,
总题数: record.totalCount,
答题时间: record.createdAt
}));
res.json({
success: true,
data: recordsData
});
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || '导出答题记录失败'
});
}
}
// 导出答题答案
static async exportAnswers(req: Request, res: Response) {
try {
// 这里简化处理,实际应该分页获取所有答案
const answersData: any[] = [];
res.json({
success: true,
data: answersData
});
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || '导出答题答案失败'
});
}
}
// 数据恢复
static async restoreData(req: Request, res: Response) {
try {
const { users, questions, records, answers } = req.body;
// 数据验证
if (!users && !questions && !records && !answers) {
return res.status(400).json({
success: false,
message: '没有可恢复的数据'
});
}
let restoredCount = {
users: 0,
questions: 0,
records: 0,
answers: 0
};
// 恢复用户数据
if (users && users.length > 0) {
for (const user of users) {
try {
await UserModel.create({
name: user.姓名 || user.name,
phone: user.手机号 || user.phone
});
restoredCount.users++;
} catch (error) {
console.log('用户已存在,跳过:', user. || user.phone);
}
}
}
// 恢复题目数据
if (questions && questions.length > 0) {
for (const question of questions) {
try {
await QuestionModel.create({
content: question.题目内容 || question.content,
type: question. || question.type,
category: question.题目类别 || question.category || '通用',
options: question.选项 ? (question. as string).split('|') : question.options,
answer: question.标准答案 || question.answer,
score: question.分值 || question.score
});
restoredCount.questions++;
} catch (error) {
console.log('题目创建失败,跳过:', error);
}
}
}
res.json({
success: true,
message: '数据恢复成功',
data: restoredCount
});
} catch (error: any) {
res.status(500).json({
success: false,
message: error.message || '数据恢复失败'
});
}
}
}