|
|
|
@ -0,0 +1,204 @@
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="zh">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-scale, initial-scale=1.0">
|
|
|
|
|
<title>学生点名系统</title>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
font-family: Arial, sans-serif;
|
|
|
|
|
margin: 20px;
|
|
|
|
|
background: linear-gradient(to bottom right, #e0f7fa, #fce4ec); /* 柔和的渐变背景色 */
|
|
|
|
|
color: #333; /* 调整文本颜色以增加可读性 */
|
|
|
|
|
display: flex; /* 使用 flexbox */
|
|
|
|
|
flex-direction: column; /* 垂直排列 */
|
|
|
|
|
align-items: center; /* 水平居中 */
|
|
|
|
|
}
|
|
|
|
|
#students, #calledList { margin-top: 20px; }
|
|
|
|
|
#result { font-weight: bold; margin-top: 10px; }
|
|
|
|
|
.called-student { color: rgb(254, 2, 2); }
|
|
|
|
|
.btn {
|
|
|
|
|
padding: 10px 15px;
|
|
|
|
|
margin: 10px 0;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
background-color: #ffab40; /* 按钮背景颜色 */
|
|
|
|
|
color: white;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: background-color 0.3s ease;
|
|
|
|
|
font-family: "kaiti";
|
|
|
|
|
font-size: 35px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn:hover {
|
|
|
|
|
background-color: #ff9800; /* 悬停时的按钮背景颜色 */
|
|
|
|
|
}
|
|
|
|
|
@keyframes gradient-animation {
|
|
|
|
|
0% { background-position: 0% 50%; }
|
|
|
|
|
50% { background-position: 100% 50%; }
|
|
|
|
|
100% { background-position: 0% 50%; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-weight: bolder;
|
|
|
|
|
font-size: 80px;
|
|
|
|
|
background: linear-gradient(45deg, #ff6b6b, #f7c24a);
|
|
|
|
|
background-size: 400% 400%;
|
|
|
|
|
-webkit-background-clip: text;
|
|
|
|
|
-webkit-text-fill-color: transparent;
|
|
|
|
|
animation: gradient-animation 3s ease infinite;
|
|
|
|
|
background-clip: text; /* 标准属性 */
|
|
|
|
|
color: transparent; /* 标准属性 */
|
|
|
|
|
font-family: "kaiti";
|
|
|
|
|
}
|
|
|
|
|
.file-upload-container {
|
|
|
|
|
display: flex; /* 使用 flexbox */
|
|
|
|
|
justify-content: center; /* 水平居中 */
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
flex-direction: column; /* 垂直排列 */
|
|
|
|
|
margin: 20px 0; /* 添加间距 */
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
<h1>学生点名系统</h1>
|
|
|
|
|
|
|
|
|
|
<input type="file" id="fileInput" class="btn"/>
|
|
|
|
|
<button id="uploadBtn" class="btn">上传学生名单</button>
|
|
|
|
|
|
|
|
|
|
<div id="students"></div>
|
|
|
|
|
<button id="rollcallBtn" style="display: none;" class="btn">随机点名</button>
|
|
|
|
|
<button id="resetBtn" style="display: none;" class="btn">重置点名状态</button>
|
|
|
|
|
<button id="lotteryBtn" style="display: none;" class="btn">幸运抽奖</button>
|
|
|
|
|
<div id="result"></div>
|
|
|
|
|
<div id="calledList"></div>
|
|
|
|
|
|
|
|
|
|
<!-- 积分操作按钮 -->
|
|
|
|
|
<div id="scoreActions" style="display: none;">
|
|
|
|
|
<button id="arriveBtn" class="btn">抵达教室</button>
|
|
|
|
|
<button id="repeatCorrectBtn" class="btn">重复问题</button>
|
|
|
|
|
<button id="repeatWrongBtn" class="btn">重复错误</button>
|
|
|
|
|
<button id="accurateAnswerBtn" class="btn">准确回答</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
let allStudents = []; // 存储所有学生
|
|
|
|
|
let calledStudents = []; // 存储已点名的学生 ID
|
|
|
|
|
let currentStudentId = null; // 当前被点名学生的 ID
|
|
|
|
|
|
|
|
|
|
document.getElementById('uploadBtn').onclick = async () => {
|
|
|
|
|
const fileInput = document.getElementById('fileInput');
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('file', fileInput.files[0]);
|
|
|
|
|
|
|
|
|
|
const response = await fetch('http://localhost:3000/upload', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
body: formData,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
allStudents = result.students;
|
|
|
|
|
calledStudents = [];
|
|
|
|
|
document.getElementById('rollcallBtn').style.display = 'block';
|
|
|
|
|
document.getElementById('resetBtn').style.display = 'block';
|
|
|
|
|
document.getElementById('lotteryBtn').style.display = 'block';
|
|
|
|
|
document.getElementById('calledList').innerHTML = ''; // 清空已点名列表
|
|
|
|
|
document.getElementById('scoreActions').style.display = 'none'; // 隐藏积分操作
|
|
|
|
|
} else {
|
|
|
|
|
alert(result.message);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('rollcallBtn').onclick = async () => {
|
|
|
|
|
if (calledStudents.length === allStudents.length) {
|
|
|
|
|
alert("所有学生都已被点名,请重置点名状态!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await fetch('http://localhost:3000/rollcall');
|
|
|
|
|
const student = await response.json();
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
currentStudentId = student.id;
|
|
|
|
|
document.getElementById('result').innerText = `被点到的学生: ${student.id} - ${student.name}`;
|
|
|
|
|
calledStudents.push(student.id);
|
|
|
|
|
|
|
|
|
|
const calledList = document.getElementById('calledList');
|
|
|
|
|
calledList.innerHTML += `<div class="called-student">${student.id} - ${student.name}</div>`;
|
|
|
|
|
document.getElementById('scoreActions').style.display = 'block'; // 显示积分操作按钮
|
|
|
|
|
} else {
|
|
|
|
|
alert(student.message);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('resetBtn').onclick = () => {
|
|
|
|
|
calledStudents = []; // 重置已点名数组
|
|
|
|
|
currentStudentId = null; // 清空当前点名学生 ID
|
|
|
|
|
document.getElementById('result').innerText = '';
|
|
|
|
|
document.getElementById('calledList').innerHTML = ''; // 清空已点名列表
|
|
|
|
|
document.getElementById('scoreActions').style.display = 'none'; // 隐藏积分操作
|
|
|
|
|
alert("已重置点名状态!");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 积分操作
|
|
|
|
|
document.getElementById('arriveBtn').onclick = async () => {
|
|
|
|
|
await updateScore({ isInClass: true });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('repeatCorrectBtn').onclick = async () => {
|
|
|
|
|
await updateScore({ isQuestionCorrect: true });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('repeatWrongBtn').onclick = async () => {
|
|
|
|
|
await updateScore({ isQuestionCorrect: false });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('accurateAnswerBtn').onclick = async () => {
|
|
|
|
|
const score = prompt("请输入分数(0.5 - 3):");
|
|
|
|
|
if (score !== null && !isNaN(score)) {
|
|
|
|
|
await updateScore({ isAnswerCorrect: true, score: parseFloat(score) });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
document.getElementById('lotteryBtn').onclick = async () => {
|
|
|
|
|
const response = await fetch('http://localhost:3000/lottery', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ id: currentStudentId })
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
alert(`幸运抽奖结果: ${result.message}`);
|
|
|
|
|
} else {
|
|
|
|
|
alert(result.message);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
async function updateScore(scoreData) {
|
|
|
|
|
const response = await fetch('http://localhost:3000/update-score', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
id: currentStudentId,
|
|
|
|
|
...scoreData
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
alert(`积分已更新: ${result.score}`);
|
|
|
|
|
} else {
|
|
|
|
|
alert(result.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|