|
|
|
@ -0,0 +1,138 @@
|
|
|
|
|
document.getElementById("fileInput").addEventListener("change", handleFile, false);
|
|
|
|
|
document.getElementById("randomSelectButton").addEventListener("click", randomSelect);
|
|
|
|
|
document.getElementById("clearScoresButton").addEventListener("click", clearScores);
|
|
|
|
|
|
|
|
|
|
let students = [];
|
|
|
|
|
|
|
|
|
|
// 处理文件上传
|
|
|
|
|
function handleFile(e) {
|
|
|
|
|
const file = e.target.files[0];
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
|
|
|
|
|
reader.onload = function (event) {
|
|
|
|
|
const data = new Uint8Array(event.target.result);
|
|
|
|
|
const workbook = XLSX.read(data, { type: "array" });
|
|
|
|
|
|
|
|
|
|
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
|
|
|
|
|
const rows = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
|
|
|
|
|
|
|
|
|
|
// 将学生数据转换为对象数组
|
|
|
|
|
students = rows.map(row => ({
|
|
|
|
|
id: row[0],
|
|
|
|
|
name: row[1],
|
|
|
|
|
score: 0, // 初始积分为0
|
|
|
|
|
}));
|
|
|
|
|
students.shift(); // 删除第一行的标题
|
|
|
|
|
|
|
|
|
|
// 加载已存储的学生积分
|
|
|
|
|
loadSavedScores();
|
|
|
|
|
|
|
|
|
|
// 移除按钮的 hidden 类以显示点名按钮
|
|
|
|
|
document.getElementById("randomSelectButton").classList.remove("hidden");
|
|
|
|
|
document.getElementById("clearScoresButton").classList.remove("hidden");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
reader.readAsArrayBuffer(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加载本地存储的积分数据
|
|
|
|
|
function loadSavedScores() {
|
|
|
|
|
const savedData = localStorage.getItem("studentsData");
|
|
|
|
|
if (savedData) {
|
|
|
|
|
const savedStudents = JSON.parse(savedData);
|
|
|
|
|
students.forEach(student => {
|
|
|
|
|
const savedStudent = savedStudents.find(s => s.id === student.id);
|
|
|
|
|
if (savedStudent) {
|
|
|
|
|
student.score = savedStudent.score;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
updateRanking();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存积分数据到本地存储
|
|
|
|
|
function saveScores() {
|
|
|
|
|
localStorage.setItem("studentsData", JSON.stringify(students));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 随机点名并计算积分
|
|
|
|
|
function randomSelect() {
|
|
|
|
|
if (students.length === 0) return;
|
|
|
|
|
|
|
|
|
|
// 计算总积分,按比例降低被点到的概率
|
|
|
|
|
const totalScore = students.reduce((acc, student) => acc + (1 / (student.score + 1)), 0);
|
|
|
|
|
let randomValue = Math.random() * totalScore;
|
|
|
|
|
let selectedStudent = null;
|
|
|
|
|
|
|
|
|
|
for (let student of students) {
|
|
|
|
|
randomValue -= 1 / (student.score + 1);
|
|
|
|
|
if (randomValue <= 0) {
|
|
|
|
|
selectedStudent = student;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 点到学生
|
|
|
|
|
document.getElementById("studentInfo").innerHTML = `
|
|
|
|
|
<p>点到学生:${selectedStudent.name} (学号: ${selectedStudent.id})</p>
|
|
|
|
|
`;
|
|
|
|
|
document.getElementById("studentInfo").classList.remove("hidden");
|
|
|
|
|
|
|
|
|
|
// 积分逻辑:每点到一次且到达课堂,积分 +1
|
|
|
|
|
selectedStudent.score += 1;
|
|
|
|
|
|
|
|
|
|
// 模拟回答是否正确
|
|
|
|
|
const isAnswerCorrect = Math.random() > 0.5; // 随机决定答案是否正确
|
|
|
|
|
let answerScore = 0;
|
|
|
|
|
|
|
|
|
|
// 答题逻辑
|
|
|
|
|
if (isAnswerCorrect) {
|
|
|
|
|
answerScore = Math.random() * 2 + 0.5; // 随机增加0.5到2.5分
|
|
|
|
|
selectedStudent.score += answerScore; // 增加答对的分数
|
|
|
|
|
} else {
|
|
|
|
|
answerScore = -1; // 答错则扣1分
|
|
|
|
|
selectedStudent.score += answerScore; // 扣分
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示反馈
|
|
|
|
|
const answerFeedback = isAnswerCorrect ? `+${answerScore.toFixed(1)} (答对)` : `${answerScore} (答错)`;
|
|
|
|
|
document.getElementById("feedback").innerHTML = `
|
|
|
|
|
<p>${selectedStudent.name} 的积分变动:+1 (点到) ${answerFeedback}</p>
|
|
|
|
|
`;
|
|
|
|
|
document.getElementById("feedback").classList.remove("hidden");
|
|
|
|
|
|
|
|
|
|
// 保存积分到本地存储
|
|
|
|
|
saveScores();
|
|
|
|
|
|
|
|
|
|
updateRanking();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新积分排行榜
|
|
|
|
|
function updateRanking() {
|
|
|
|
|
students.sort((a, b) => b.score - a.score);
|
|
|
|
|
|
|
|
|
|
let rankTableHTML = students.map(student => `
|
|
|
|
|
<tr>
|
|
|
|
|
<td>${student.id}</td>
|
|
|
|
|
<td>${student.name}</td>
|
|
|
|
|
<td>${student.score.toFixed(1)}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
`).join("");
|
|
|
|
|
|
|
|
|
|
document.getElementById("rankList").innerHTML = rankTableHTML;
|
|
|
|
|
document.getElementById("rankTable").classList.remove("hidden");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清除积分
|
|
|
|
|
function clearScores() {
|
|
|
|
|
students.forEach(student => {
|
|
|
|
|
student.score = 0; // 清除积分
|
|
|
|
|
});
|
|
|
|
|
saveScores(); // 保存清空后的数据
|
|
|
|
|
updateRanking(); // 更新排行榜
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 页面加载时,加载学生数据
|
|
|
|
|
window.onload = function() {
|
|
|
|
|
loadSavedScores();
|
|
|
|
|
};
|