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.

366 lines
14 KiB

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>课堂随机点名系统</title>
<link rel="icon" href="static/logo.ico" type="image/x-icon">
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 50px;
background-image: url('/static/background.png'); /* 背景图片路径 */
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.card {
background-color: rgba(255, 255, 255, 0.8); /* 卡片背景色 */
border-radius: 10px; /* 圆角 */
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 阴影 */
margin: 20px auto; /* 上下间距和自动水平居中 */
padding: 20px; /* 内边距 */
width: 300px; /* 卡片宽度 */
}
h1 {
color: whitesmoke;
font-size: 36px;
margin-bottom: 20px;
}
/* 按钮样式 */
.button {
display: block; /* 改为块级元素以实现纵向排列 */
width: 100%; /* 设置按钮宽度为 100% */
margin: 15px 0; /* 上下间距 */
padding: 15px; /* 增加上边距和下边距 */
font-size: 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.button:hover {
background-color: #45a049;
}
.button:active {
transform: scale(0.95);
}
.modal {
display: none;
position: fixed;
z-index: 2;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.8);
opacity: 0;
transition: opacity 0.3s ease;
}
.modal.show {
opacity: 1;
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
transition: transform 0.3s ease;
}
.modal-content.show {
transform: scale(1);
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
}
.disabled {
opacity: 0.5; /* 设置透明度为 0.5 以表示禁用状态 */
pointer-events: none; /* 禁用事件 */
}
</style>
</head>
<body>
<h1>课堂随机点名系统</h1>
<img src="/static/kfc_cat.jpg" alt="Logo" style="width: 88px; height: auto;">
<div class="card">
<div class="card-body">
<button class="button" data-action="upload">上传学生名单</button>
<button class="button" data-action="roll-call">随机点名</button>
<button class="button" data-action="view-rank">查看积分排行</button>
</div>
</div>
<div id="myModal" class="modal">
<div class="modal-content">
<span id="closeModal" class="close">&times;</span>
<p id="rollResult"></p>
<form id="rollCallForm">
<p>是否来上课了?
<label><input type="radio" name="isCome" value="yes" onclick="toggleQuestionOptions()"> 来了</label>
<label><input type="radio" name="isCome" value="no" onclick="toggleQuestionOptions()"> 没来</label>
</p>
<div id="questionOptions">
<p>是否能够重复问题?
<label><input type="radio" name="canRepeat" value="yes"></label>
<label><input type="radio" name="canRepeat" value="no"> 不能</label>
</p>
<p>是否能够正确回答问题?
<label><input type="radio" name="answerCorrect" value="correct"> 完全正确</label>
<label><input type="radio" name="answerCorrect" value="partial"> 部分正确</label>
<label><input type="radio" name="answerCorrect" value="incorrect"> 错误</label>
</p>
</div>
<button type="button" id="submitRollCall">提交</button>
</form>
</div>
</div>
<script>
const apiBaseUrl = "http://127.0.0.1:8000"; /* 部署到服务器需要修改为http://8.130.115.98:8080 */
var modal = document.getElementById("myModal");
var rollResultElement = document.getElementById("rollResult");
var span = document.getElementById("closeModal");
// 关闭模态框的函数
function closeModal() {
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = "none";
}, 300);
}
span.onclick = closeModal;
window.onclick = function (event) {
if (event.target == modal) {
closeModal();
}
};
let studentData = [];
// 处理上传学生名单的函数
function uploadList() {
let fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.xlsx';
fileInput.onchange = function () {
let formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch(apiBaseUrl + '/upload', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
alert(data.message);
if (data.message === "名单上传成功!") {
studentData = data.students;
}
})
.catch(error => {
console.error('Error:', error);
alert('上传失败,请检查网络连接或文件格式。');
});
};
fileInput.click();
}
// 处理随机点名的函数
function rollCall() {
fetch(apiBaseUrl + '/roll?enable_random_events=true')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(responseData => {
if (responseData.message) {
alert(responseData.message);
} else {
sessionStorage.setItem('lastCalledStudentId', responseData.学号);
rollResultElement.innerText = `被点名的学生是:${responseData.学号}--${responseData.姓名}`;
modal.classList.add('show');
modal.style.display = "block";
if (responseData.转移权) {
showTransferOptions(responseData.学号);
}
if (responseData.随机事件) {
alert(`随机事件触发:${responseData.随机事件}`);
}
}
})
.catch(error => {
console.error('Error:', error);
alert(`无法完成点名,请检查网络连接或服务器状态。详细信息:${error.message}`);
});
}
// 切换问题选项的可用性
function toggleQuestionOptions() {
const form = document.getElementById("rollCallForm");
const isCome = form.elements["isCome"].value;
const questionOptions = document.getElementById("questionOptions");
if (isCome === "no") {
questionOptions.classList.add("disabled");
Array.from(questionOptions.querySelectorAll('input[type="radio"]')).forEach(input => {
input.checked = false;
input.disabled = true;
});
} else {
questionOptions.classList.remove("disabled");
Array.from(questionOptions.querySelectorAll('input[type="radio"]')).forEach(input => {
input.disabled = false;
});
}
}
// 显示转移选项的函数
function showTransferOptions(currentStudentId) {
const transferModal = document.createElement('div');
transferModal.className = 'modal transfer-modal';
const transferContent = document.createElement('div');
transferContent.className = 'modal-content';
transferContent.innerHTML = `<p>请选择转移的学生:</p>`;
studentData.forEach(student => {
if (student.学号 !== currentStudentId) {
const button = document.createElement('button');
button.innerText = `${student.姓名} (${student.学号})`;
button.onclick = function () {
alert(`转移到学生:${student.姓名} (${student.学号})`);
transferModal.style.display = "none";
modal.style.display = "none";
sessionStorage.setItem('lastCalledStudentId', student.学号);
rollCall();
};
transferContent.appendChild(button);
}
});
transferModal.appendChild(transferContent);
document.body.appendChild(transferModal);
transferModal.classList.add('show');
transferModal.style.display = "block";
const closeButton = document.createElement('span');
closeButton.className = 'close';
closeButton.innerHTML = '&times;';
closeButton.onclick = function () {
transferModal.style.display = "none";
};
transferContent.appendChild(closeButton);
}
// 提交点名评估的函数
document.getElementById("submitRollCall").onclick = function () {
const form = document.getElementById("rollCallForm");
const isCome = form.elements["isCome"].value === "yes";
const canRepeat = form.elements["canRepeat"].value === "yes";
const answerCorrect = form.elements["answerCorrect"].value === "correct" ? "完全正确" :
(form.elements["answerCorrect"].value === "partial" ? "部分正确" : "错误");
const studentId = sessionStorage.getItem('lastCalledStudentId');
if (!studentId) {
alert('没有找到被点名的学生 ID请重新点名。');
return;
}
const dataToSend = {
student_id: studentId,
is_come: isCome,
can_repeat: canRepeat,
answer_correct: answerCorrect
};
fetch(apiBaseUrl + '/evaluate-answer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(dataToSend),
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(updatedData => {
if (updatedData.success) {
alert('回答已评估!');
} else {
alert('回答评估失败!');
}
})
.catch(error => {
console.error('Error:', error);
alert('无法完成评估,请检查网络连接或服务器状态。');
});
closeModal();
};
// 处理查看积分排行的函数
function viewRank() {
fetch(apiBaseUrl + '/rank')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
if (data.message) {
alert(data.message);
} else {
let rankList = "积分排行:\n";
data.forEach((student, index) => {
rankList += `${index + 1}. 学号:${student.学号} 姓名:${student.姓名} 积分:${student.积分}\n`;
});
alert(rankList);
}
})
.catch(error => {
console.error('Error:', error);
alert('无法完成操作,请检查网络连接或服务器状态。');
});
}
// 为按钮添加点击事件处理
document.querySelectorAll('.button').forEach(button => {
button.addEventListener('click', function () {
const action = this.dataset.action;
if (action === 'upload') {
uploadList();
} else if (action === 'roll-call') {
rollCall();
} else if (action === 'view-rank') {
viewRank();
}
});
});
</script>
</body>
</html>