You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
7.6 KiB

<!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>