提交所有文件

This commit is contained in:
MKStoler 2025-01-06 06:47:30 +08:00 committed by GitHub
parent 9b30ee9c6d
commit 537e10d252
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 363 additions and 0 deletions

47
exam_config.json Normal file
View File

@ -0,0 +1,47 @@
{
"examName": "周测",
"message": "诚信考试,作弊可耻",
"room": " ",
"examInfos": [
{
"name": "语文",
"start": "2025-01-04T07:20:00",
"end": "2025-01-04T09:50:00"
},
{
"name": "物理",
"start": "2025-01-04T10:20:00",
"end": "2025-01-04T12:15:00"
},
{
"name": "生物/政治",
"start": "2025-01-04T14:10:00",
"end": "2025-01-04T15:40:00"
},
{
"name": "地理",
"start": "2025-01-04T16:10:00",
"end": "2025-01-04T17:40:00"
},
{
"name": "数学",
"start": "2025-01-05T07:50:00",
"end": "2025-01-04T09:50:00"
},
{
"name": "历史",
"start": "2025-01-05T10:20:00",
"end": "2025-01-05T11:50:00"
},
{
"name": "英语",
"start": "2025-01-05T14:10:00",
"end": "2025-01-05T16:10:00"
},
{
"name": "化学",
"start": "2025-01-05T16:30:00",
"end": "2025-01-05T18:00:00"
}
]
}

41
index.html Normal file
View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exam Schedule</title>
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
</head>
<body>
<button id="fullscreen-btn">全屏</button>
<div class="container">
<h1 id="examName"></h1>
<p id="message"></p>
<div class="content">
<div class="left-column">
<div id="current-time"></div>
<div id="current-subject"></div>
<div id="exam-timing"></div>
<div id="remaining-time"></div>
<div id="status"></div>
</div>
<div class="right-column">
<table>
<thead>
<tr>
<th>科目</th>
<th>开始</th>
<th>结束</th>
</tr>
</thead>
<tbody id="exam-table-body">
<!-- Dynamically filled by JavaScript -->
</tbody>
</table>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

130
script.js Normal file
View File

@ -0,0 +1,130 @@
document.addEventListener("DOMContentLoaded", () => {
const examNameElem = document.getElementById("examName");
const messageElem = document.getElementById("message");
const currentTimeElem = document.getElementById("current-time");
const currentSubjectElem = document.getElementById("current-subject");
const examTimingElem = document.getElementById("exam-timing");
const remainingTimeElem = document.getElementById("remaining-time");
const statusElem = document.getElementById("status");
const examTableBodyElem = document.getElementById("exam-table-body");
const fullscreenBtn = document.getElementById("fullscreen-btn");
function fetchData() {
fetch('exam_config.json')
.then(response => response.json())
.then(data => {
displayExamInfo(data);
updateCurrentTime();
updateExamInfo(data);
setInterval(() => updateCurrentTime(), 1000); // Update current time every second
setInterval(() => updateExamInfo(data), 1000); // Update exam info every second
})
.catch(error => console.error('Error fetching exam data:', error));
}
function displayExamInfo(data) {
// Display exam name
examNameElem.textContent = data.examName;
// Display message
messageElem.textContent = data.message;
}
function updateCurrentTime() {
const now = new Date();
currentTimeElem.textContent = now.toLocaleTimeString('zh-CN', { hour12: false });
}
function formatTimeWithoutSeconds(time) {
// Convert time to string and remove seconds if present
return time.slice(0, -3);
}
function updateExamInfo(data) {
const now = new Date();
let currentExam = null;
let nextExam = null;
data.examInfos.forEach(exam => {
const start = new Date(exam.start);
const end = new Date(exam.end);
if (now >= start && now <= end) {
currentExam = exam;
}
if (!currentExam && !nextExam && now < start) {
nextExam = exam;
}
});
if (currentExam) {
currentSubjectElem.textContent = `当前科目: ${currentExam.name}`;
examTimingElem.textContent = `起止时间: ${formatTimeWithoutSeconds(new Date(currentExam.start).toLocaleTimeString('zh-CN', { hour12: false }))} - ${formatTimeWithoutSeconds(new Date(currentExam.end).toLocaleTimeString('zh-CN', { hour12: false }))}`;
const remainingTime = (new Date(currentExam.end) - now) / 1000;
const remainingHours = Math.floor(remainingTime / 3600);
const remainingMinutes = Math.floor((remainingTime % 3600) / 60);
const remainingSeconds = Math.floor(remainingTime % 60);
const remainingTimeText = `剩余时间: ${remainingHours}${remainingMinutes}${remainingSeconds}`;
if (remainingHours === 0 && remainingMinutes <= 15) {
remainingTimeElem.textContent = remainingTimeText;
remainingTimeElem.style.color = "red";
remainingTimeElem.style.fontWeight = "bold";
} else {
remainingTimeElem.textContent = remainingTimeText;
remainingTimeElem.style.color = "#93b4f7";
remainingTimeElem.style.fontWeight = "normal";
}
statusElem.textContent = "状态: 进行中";
statusElem.style.color = "green";
} else if (nextExam) {
currentSubjectElem.textContent = `下一场科目: ${nextExam.name}`;
examTimingElem.textContent = `起止时间: ${formatTimeWithoutSeconds(new Date(nextExam.start).toLocaleTimeString('zh-CN', { hour12: false }))} - ${formatTimeWithoutSeconds(new Date(nextExam.end).toLocaleTimeString('zh-CN', { hour12: false }))}`;
remainingTimeElem.textContent = "剩余时间: -";
statusElem.textContent = "状态: 即将开始";
statusElem.style.color = "orange";
} else {
currentSubjectElem.textContent = "当前无考试";
examTimingElem.textContent = "";
remainingTimeElem.textContent = "";
statusElem.textContent = "状态: 空闲";
statusElem.style.color = "blue";
}
// Update next exams table
examTableBodyElem.innerHTML = "";
data.examInfos.forEach(exam => {
const start = new Date(exam.start);
const end = new Date(exam.end);
let status = "";
if (now < start) {
status = "即将开始";
} else if (now > end) {
status = "已结束";
} else {
status = "进行中";
}
const row = document.createElement("tr");
row.className = `exam-status-${status}`;
row.innerHTML = `
<td>${exam.name}</td>
<td>${formatTimeWithoutSeconds(new Date(exam.start).toLocaleTimeString('zh-CN', { hour12: false }))}</td>
<td>${formatTimeWithoutSeconds(new Date(exam.end).toLocaleTimeString('zh-CN', { hour12: false }))}</td>
`;
examTableBodyElem.appendChild(row);
});
}
// Fullscreen functionality
fullscreenBtn.addEventListener("click", () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
});
fetchData();
});

145
styles.css Normal file
View File

@ -0,0 +1,145 @@
body {
font-family: 'HarmonyOS Sans SC Regular', Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #121212;
animation: fadeIn 1s;
color: #e0e0e0;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
#fullscreen-btn {
position: absolute;
top: 20px;
right: 20px;
padding: 10px 20px;
font-size: 1.5rem;
cursor: pointer;
background-color: #1f1f1f;
color: #e0e0e0;
border: 1px solid #333;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s ease, transform 0.3s ease;
}
#fullscreen-btn:hover {
background-color: #333;
transform: scale(1.05);
}
.container {
padding: 20px;
max-width: 1200px;
margin: auto;
background-color: #1f1f1f;
border-radius: 8px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}
h1 {
font-size: 4rem;
font-weight: bold;
text-align: left;
margin-bottom: 5px;
color: #e0e0e0;
}
#message {
font-size: 1.5rem;
color: #bb86fc;
margin-bottom: 20px;
}
.content {
display: flex;
justify-content: space-between;
}
.left-column, .right-column {
width: 48%;
background-color: #1f1f1f;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
border-radius: 8px;
}
#current-time {
font-size: 8rem;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
color: #bb86fc;
}
#current-subject, #exam-timing, #remaining-time, #status {
font-size: 3rem;
margin: 10px 0;
text-align: left;
color: #e0e0e0;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
border: 1px solid #333;
background-color: #1f1f1f;
}
th, td {
border: 1px solid #333;
padding: 8px; /* 缩短行高 */
font-size: 2rem;
text-align: center;
}
th {
background-color: #333;
color: #bb86fc;
font-weight: bold;
border-bottom: 2px solid #bb86fc;
}
.exam-status-进行中 td {
color: green !important; /* 绿色字体 */
}
.exam-status-即将开始 td {
color: orange !important; /* 橙色字体 */
}
.exam-status-已结束 td {
color: red !important; /* 红色字体 */
}
.exam-status-空闲 td {
color: blue !important; /* 蓝色字体 */
}
tr:hover {
background-color: #333;
}
table {
border-radius: 8px;
overflow: hidden;
}
td {
border-bottom: 1px solid #333;
}
td:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
td:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}