mirror of
https://github.com/ExamAware/ExamSchedule.git
synced 2025-04-29 19:16:33 +00:00
提交所有文件
This commit is contained in:
parent
9b30ee9c6d
commit
537e10d252
47
exam_config.json
Normal file
47
exam_config.json
Normal 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
41
index.html
Normal 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
130
script.js
Normal 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
145
styles.css
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user