Compare commits

..

68 Commits

Author SHA1 Message Date
32e1af6bf2 更新 requirements.txt 2023-12-31 00:23:03 +08:00
b5dd4b6d7d 1 2023-12-30 22:44:36 +08:00
cf2ff28e58 更新 login.html 2023-12-30 21:31:47 +08:00
58c4b85e6a 删除 requirements.txt 2023-12-29 17:31:25 +08:00
b6fc41994e 创建 ReceiveExcelTest.py 2023-12-29 17:31:23 +08:00
1a08ba460c 创建 StudentSignInTest.py 2023-12-29 17:25:11 +08:00
692631e395 创建 TeacherSignInTest.py 2023-12-29 17:25:09 +08:00
1174b225a7 创建 TestGetHtml.py 2023-12-29 17:25:05 +08:00
ded28f6a1e 创建 TestLogout.py 2023-12-29 16:31:56 +08:00
4e64fb2422 创建 TestGetMenu.py 2023-12-29 16:31:55 +08:00
eb074e5dd5 更新 database_manager.py 2023-12-29 16:07:22 +08:00
6ef3faf149 创建 TestLogin.py 2023-12-29 16:07:20 +08:00
9b519f4650 更新 login.html 2023-12-29 16:04:57 +08:00
d6bef5812b 删除 init.py 2023-12-29 16:04:54 +08:00
8e8fccbb1a 创建 app.py 2023-12-29 16:04:52 +08:00
237f0acf8d 删除 app.py 2023-12-29 16:04:50 +08:00
44ce96c7d9 更新 views.py 2023-12-29 16:04:42 +08:00
dae0ce21be 更新 announcement.html 2023-12-29 15:19:49 +08:00
a94dc7b415 更新 app.py 2023-12-29 15:06:04 +08:00
ca44cf0eaa 创建 requirements.txt 2023-12-29 15:05:23 +08:00
18c3968e59 更新 database_manager.py 2023-12-29 15:02:57 +08:00
5ce9ee1b1e 更新 mysql.sql 2023-12-29 14:47:07 +08:00
2596680c3a 更新 views.py 2023-12-29 14:47:05 +08:00
ff030444e4 更新 mysql.sql 2023-12-29 14:39:51 +08:00
e14688471a 更新 mysql.sql 2023-12-29 14:31:29 +08:00
c554d2d7af 创建 parse_table.py 2023-12-29 14:27:59 +08:00
9296b70ac3 更新 mysql.sql 2023-12-29 14:27:57 +08:00
cff2b66bc0 更新 template.xlsx 2023-12-29 14:27:54 +08:00
9d68073dd5 更新 database_manager.py 2023-12-29 14:27:52 +08:00
894d075d55 更新 views.py 2023-12-29 14:27:49 +08:00
8021f15e58 更新 import-class.html 2023-12-29 14:27:46 +08:00
b5461dbff4 更新 attendance-teacher.html 2023-12-29 14:27:44 +08:00
aab814a23a 更新 get_teacher_attendance_table.js 2023-12-29 14:27:38 +08:00
c0d0e43e73 创建 get_teacher_attendance_table.js 2023-12-29 11:34:34 +08:00
3e79a22956 更新 attendance-teacher.html 2023-12-29 11:34:31 +08:00
ca55d9d2fd 更新 views.py 2023-12-29 11:34:26 +08:00
e655b72a5c 更新 database_manager.py 2023-12-29 11:34:24 +08:00
e75cce4dc9 更新 mysql.sql 2023-12-29 11:34:18 +08:00
a2be2f6378 更新 announcement.html 2023-12-29 10:12:56 +08:00
b07880eb7d 创建 time_utils.py 2023-12-29 01:58:24 +08:00
9048134f55 创建 allowed_files.py 2023-12-29 01:58:22 +08:00
dc2aedb06b 创建 __init__.py 2023-12-29 01:58:19 +08:00
74d63734bc 更新 database_manager.py 2023-12-29 01:58:17 +08:00
70c0c7925d 更新 views.py 2023-12-29 01:58:15 +08:00
1dddf07b54 删除 time_utils.py 2023-12-29 01:58:12 +08:00
88f5713f16 删除 allowed_files.py 2023-12-29 01:58:10 +08:00
7075531fc6 更新 announcement.html 2023-12-29 01:58:02 +08:00
908fa9344b 更新 mysql.sql 2023-12-29 01:15:55 +08:00
519d77d5b2 更新 database_manager.py 2023-12-29 01:15:53 +08:00
d404ccfa78 更新 views.py 2023-12-29 01:15:51 +08:00
1deec07d33 更新 announcement.html 2023-12-29 01:15:49 +08:00
a00a85efdb 更新 database_manager.py 2023-12-29 00:47:59 +08:00
feb6d1e2ce 更新 views.py 2023-12-29 00:47:57 +08:00
548120f9db 更新 views.py 2023-12-29 00:21:54 +08:00
964332cf44 更新 mysql.sql 2023-12-29 00:21:30 +08:00
b5b5e92b73 更新 database_manager.py 2023-12-29 00:21:28 +08:00
f59b43c99e 更新 views.py 2023-12-29 00:21:26 +08:00
68a126cb8b 更新 attendance.html 2023-12-29 00:21:24 +08:00
dc66080c22 更新 mysql.sql 2023-12-28 23:32:11 +08:00
f69c0a112f 更新 database_manager.py 2023-12-28 23:32:08 +08:00
d41e846ee4 更新 views.py 2023-12-28 23:32:06 +08:00
c7024d5851 创建 time_utils.py 2023-12-28 23:32:03 +08:00
ada0a97a42 更新 attendance.html 2023-12-28 23:32:00 +08:00
fdd09d5e4d 更新 upload_excel.js 2023-12-28 23:31:52 +08:00
6ce370db9c 更新 mysql.sql 2023-12-28 20:14:39 +08:00
1edb119983 更新 course-category.html 2023-12-28 20:10:22 +08:00
ad9fcf4781 更新 attendance.html 2023-12-28 20:10:19 +08:00
7c13aa0e6c 更新 mysql.sql 2023-12-28 20:10:13 +08:00
31 changed files with 1226 additions and 326 deletions

View File

@@ -0,0 +1,2 @@
import views

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,60 @@
layui.use(['laypage', 'element', 'jquery', 'dropdown'], function () {
var laypage = layui.laypage;
var $ = layui.jquery;
function renderTable(page) {
$.get('/api/get-teacher-attendance-table?page=' + page, function (response) {
var $tbody = $('#attendanceTable tbody');
$tbody.empty(); // 清空表格内容
response.data.forEach(function (item) {
var $row = $('<tr></tr>');
$row.append(`<td>${item.course_id}</td>`);
$row.append(`<td>${item.course_name}</td>`);
$row.append(`<td>${item.class_name}</td>`);
$row.append(`<td>${item.major}</td>`);
$row.append(`<td><div class="layui-btn-container">
<button type="button" class="layui-btn btn-sign-in"
data-course-id="${item.course_id}"
data-course-name="${item.course_name}"
data-class-name = "${item.class_name}"
data-major-id = "${item.major_id}"
>签到</button>
</div>
</td>`)
$tbody.append($row);
});
laypage.render({
elem: 'pagination',
count: response.count,
limit: 10,
curr: page,
jump: function (obj, first) {
if (!first) {
renderTable(obj.curr);
}
}
});
});
}
// 为动态生成的按钮添加点击事件
$(document).on('click', '.btn-sign-in', function () {
var courseId = $(this).data('course-id'); // 获取课程ID
var courseName = $(this).data('course-name'); // 获取课程名
var className = $(this).data('class-name'); // 获取课程名
var majorId = $(this).data('major-id'); // 获取课程名
// console.log(courseId,courseName,className,majorId)
// 向后端发送POST请求
$.post('/api/teacher-sign-in', {
course_id: courseId,
course_name: courseName,
class_name: className,
major_id:majorId
}, function (response) {
layer.msg(response.msg);
});
});
renderTable(1); // 初始加载第一页
});

View File

@@ -36,7 +36,7 @@ fileInput.addEventListener('change', function () {
}) })
.catch(error => { .catch(error => {
console.error('Upload failed:', error); console.error('Upload failed:', error);
alert("文件上传失败!"); // 弹出失败消息 layer.msg("文件上传失败!"); // 弹出失败消息
}); });
} else { } else {
alert("请上传Excel文件!"); alert("请上传Excel文件!");

View File

@@ -7,6 +7,47 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="static/css/layui.css" rel="stylesheet"/> <link href="static/css/layui.css" rel="stylesheet"/>
<style>
/* 容器样式 */
.layui-container {
padding: 20px;
background-color: #f7f7f7;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
/* 标题样式 */
.layui-header {
margin-bottom: 20px;
font-size: 2em; /* 更大的标题字体 */
color: #333;
border-bottom: 2px solid #e2e2e2;
padding-bottom: 10px;
}
/* 课程信息样式 */
.layui-field-box p {
font-size: 1.2em; /* 更大的文字 */
margin: 10px 0; /* 调整段落间距 */
padding: 10px; /* 内边距 */
background-color: #fff; /* 背景色 */
border-radius: 4px; /* 轻微的圆角 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* 细微的阴影 */
}
/* 字段集合样式调整 */
fieldset.layui-elem-field {
border-color: #ddd; /* 更淡的边框颜色 */
}
legend {
font-size: 1.4em; /* Legend文字大小 */
color: #333; /* 文字颜色 */
}
</style>
</head> </head>
<body> <body>
@@ -21,7 +62,7 @@
src="//unpkg.com/outeres@0.0.10/img/layui/icon-v2.png" src="//unpkg.com/outeres@0.0.10/img/layui/icon-v2.png"
class="layui-nav-img" class="layui-nav-img"
/> />
{{ session.nickname }} {{ session.name }}
</a> </a>
<dl class="layui-nav-child"> <dl class="layui-nav-child">
<dd><a href="/home/profile">资料</a></dd> <!-- 修改这里的href指向/profile --> <dd><a href="/home/profile">资料</a></dd> <!-- 修改这里的href指向/profile -->
@@ -54,11 +95,8 @@
<div class="layui-col-md6"> <div class="layui-col-md6">
<fieldset class="layui-elem-field"> <fieldset class="layui-elem-field">
<legend>今日课程</legend> <legend>今日课程</legend>
<div class="layui-field-box"> <div class="layui-field-box" id="courses-container">
<!-- 这里可以动态列出今日课程 --> <!-- 课程信息将通过JavaScript动态添加 -->
<p>1. 数学 - 上午9:00</p>
<p>2. 物理 - 下午1:00</p>
<p>3. 文学 - 下午3:00</p>
</div> </div>
</fieldset> </fieldset>
</div> </div>
@@ -72,6 +110,20 @@
<script src="/static/js/menu.js"></script> <script src="/static/js/menu.js"></script>
<script src="/static/js/logout.js"></script> <script src="/static/js/logout.js"></script>
<script> <script>
$(document).ready(function () {
// 请求后端获取课程信息
$.get('/api/get-today-courses', function (data) {
if (data.msg == "ok") {
data.data.forEach(function (course) {
// 为每个课程创建一个段落<p>并添加到容器中,并设置样式使字体更大且更加好看
$('#courses-container').append('<p style="font-size: 1.2em; margin: 5px 0;">课程: ' + course.course_name + ' <br> 时间: ' + course.time + '</p>');
});
} else {
$('#courses-container').append(data.msg)
}
});
});
</script> </script>
</body> </body>
</html> </html>

View File

@@ -91,32 +91,11 @@
</div> </div>
</div> </div>
<div class="layui-body"> <div class="layui-body">
<div> <div class="layui-container">
<!-- 动态显示当前时间的标题 --> <div class="layui-row">
<h2 id="attendance-reminder">签到提醒 </h2> </div>
<h2 id="current-time">当前时间</h2> <div id="course-list" class="layui-row">
<table class="layui-table calendar-table" id="calendar"> <!-- 课程列表将在这里生成 -->
<!-- 日历的头部 -->
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<!-- 日历的主体部分 -->
<tbody id="calendar-body">
<!-- 动态生成日历的日期部分 -->
</tbody>
</table>
<!-- 提醒内容 -->
<div class="reminder">
<span><span class="color-box" style="background-color: green;"></span>绿色代表当月已签到</span><br>
<span><span class="color-box" style="background-color: #FFA07A;"></span>颜色代表本月需要签到</span>
</div> </div>
</div> </div>
</div> </div>
@@ -127,59 +106,34 @@
<script src="/static/js/menu.js"></script> <script src="/static/js/menu.js"></script>
<script src="/static/js/logout.js"></script> <script src="/static/js/logout.js"></script>
<script> <script>
layui.use(['layer'], function () { document.addEventListener("DOMContentLoaded", function () {
var layer = layui.layer; // 模拟从后端获取的课程数据
let courses = [
{name: "线性代数", time: "14:00", description: "线性代数是数学的一个基础分支,关注线性方程组、向量空间、矩阵理论及线性变换等概念。本课程将带领学生探索向量和矩阵的运算,理解行列式、特征值和特征向量的计算,以及线性空间和子空间的概念。透过一系列的应用实例,如图像处理和机器学习,学生将学会如何将理论应用于实际问题中,为进一步学习高等数学和工程应用打下坚实的基础。", room: "101教室"},
{name: "数据结构", time: "15:00", description: "数据结构是计算机科学中的一个重要领域,涉及组织、管理和存储数据的方式,以便高效地访问和修改。本课程覆盖了从基本的数据结构如数组、链表、栈和队列,到更高级的结构如树、图、散列表和堆。通过理论学习与实际编程相结合的方式,学生将掌握如何选择合适的数据结构解决特定问题,以及对各种数据结构进行效率分析和比较。", room: "102教室"},
{name: "计算机网络", time: "16:00", description: "计算机网络是研究计算机之间的连接方式及其通信协议的科学。本课程提供计算机网络的综合介绍包括网络架构、协议、网络通信理论、实际应用等内容。学生将了解网络层次结构包括物理层、数据链路层、网络层、传输层和应用层。课程重点讲解TCP/IP模型以及它在网络通信中的关键作用。通过本课程的学习学生将获得设计、实施、管理和维护网络的基本知识和技能。", room: "103教室"}
];
// 假设的已签到日期数据 // 获取课程列表容器
var signedDays = [1, 5, 9]; // 这里仅为示例,实际应从服务器获取 let courseListDiv = document.getElementById('course-list');
var requiredSignDays = [2, 6, 15, 23];
// 动态生成日历 // 遍历课程数组,为每门课创建一个卡片
function generateCalendar() { courses.forEach(course => {
var today = new Date(); let courseDiv = document.createElement('div');
var currentMonth = today.getMonth(); courseDiv.className = 'layui-col-md4';
var currentYear = today.getFullYear(); courseDiv.innerHTML = `<div class="course-card layui-elem-field">
<legend>${course.name}</legend>
var firstDay = new Date(currentYear, currentMonth, 1).getDay(); <div class="layui-field-box">
var daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate(); <p><strong>时间:</strong> ${course.time}</p>
<p><strong>教室:</strong> ${course.room}</p>
var calendarHtml = ''; <p><strong>描述:</strong> ${course.description}</p>
var day = 1; <p><strong>剩余时间:</strong> <span class="countdown">计算中...</span></p>
</div>
for (var i = 0; i < 6; i++) { </div>`;
calendarHtml += '<tr>'; courseListDiv.appendChild(courseDiv);
for (var j = 0; j < 7; j++) {
if (i === 0 && j < firstDay) {
calendarHtml += '<td></td>';
} else if (day > daysInMonth) {
break;
} else {
var classes = '';
if (signedDays.includes(day)) classes += 'signed '; // 已签到
if (requiredSignDays.includes(day)) classes += 'required-sign'; // 需要签到
calendarHtml += `<td class="${classes}">${day}</td>`;
day++;
}
}
calendarHtml += '</tr>';
if (day > daysInMonth) {
break;
}
}
document.getElementById('calendar-body').innerHTML = calendarHtml;
}
function updateTime() {
var now = new Date();
var timeStr = now.getFullYear() + '年' + (now.getMonth() + 1) + '月' + now.getDate() + '日';
document.getElementById('current-time').innerText = '当前时间: ' + timeStr;
}
// 页面加载时生成日历
generateCalendar();
updateTime();
}); });
});
</script> </script>
</body> </body>
</html> </html>

View File

@@ -55,10 +55,10 @@
<!-- 表头 --> <!-- 表头 -->
<thead> <thead>
<tr> <tr>
<th>课程名称</th>
<th>课程代码</th> <th>课程代码</th>
<th>学分</th> <th>课程名称</th>
<th>班级专业</th> <th>班级</th>
<th>专业</th>
<th>签到</th> <th>签到</th>
</tr> </tr>
</thead> </thead>
@@ -74,50 +74,8 @@
<script src="/static/layui.js"></script> <script src="/static/layui.js"></script>
<script src="/static/js/menu.js"></script> <script src="/static/js/menu.js"></script>
<script src="/static/js/logout.js"></script> <script src="/static/js/logout.js"></script>
<script src="/static/js/get_teacher_attendance_table.js"></script>
<script> <script>
layui.use(['laypage', 'element', 'jquery', 'dropdown'], function () {
var laypage = layui.laypage;
var $ = layui.jquery;
function renderTable(page) {
// 发送GET请求到服务器端点
$.get('/api/get-teacher-attendance-table?page=' + page, function (response) {
var $tbody = $('#attendanceTable tbody');
$tbody.empty(); // 清空表格内容
// 遍历返回的数据数组
response.data.forEach(function (item) {
// 创建新的行并填充数据
var $row = $('<tr></tr>');
$row.append(`<td>${item.course_name}</td>`);
$row.append(`<td>${item.course_code}</td>`);
$row.append(`<td>${item.credits}</td>`);
$row.append(`<td>${item.class_name + item.major}</td>`);
$row.append(`<td><div class="layui-btn-container">
<button type="button" class="layui-btn">签到</button>
</div>
</td>`)
$tbody.append($row);
});
// 渲染分页控件
laypage.render({
elem: 'pagination', // 分页容器的id
count: response.count, // 总条数
limit: 10, // 每页显示条数
curr: page, // 当前页
jump: function (obj, first) {
if (!first) { // 首次不执行
renderTable(obj.curr); // 根据页码加载数据
}
}
});
});
}
// 初始加载第一页
renderTable(1);
});
</script> </script>
</body> </body>
</html> </html>

View File

@@ -7,6 +7,40 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="static/css/layui.css" rel="stylesheet"> <link href="static/css/layui.css" rel="stylesheet">
<style>
#sign-in-reminder {
max-width: 600px; /* 限制最大宽度 */
margin: 50px auto; /* 上下保留空间,左右自动以居中显示 */
padding: 20px; /* 内边距 */
border-radius: 8px; /* 轻微的圆角 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 给予阴影以突出层次 */
background-color: #f7f7f7; /* 浅灰色背景 */
}
#title {
text-align: center; /* 标题居中 */
color: #333; /* 标题颜色 */
font-size: 24px; /* 字号大小 */
}
#course-info {
text-align: center; /* 课程信息文本居中 */
margin-bottom: 20px; /* 与下方元素保持距离 */
}
.layui-btn {
width: 100%; /* 使按钮宽度填满容器 */
background-color: #009688; /* 设定一个现代感的按钮颜色 */
color: white; /* 文字颜色为白色 */
border-radius: 4px; /* 轻微的圆角 */
padding: 10px 0; /* 上下填充,增加按钮触摸面积 */
text-align: center; /* 文字水平居中 */
display: block; /* 转换为块级元素以应用宽度 */
line-height: 1.5; /* 调整行高以垂直居中文字 */
font-size: 16px; /* 设定文字大小 */
}
</style>
</head> </head>
<body> <body>
@@ -44,17 +78,10 @@
</div> </div>
<div class="layui-body"> <div class="layui-body">
<div id="sign-in-reminder" class="layui-container"> <div id="sign-in-reminder" class="layui-container">
<h1>每日签到</h1> <blockquote class="layui-card-header" id="title">
<p>每天签到,享受连续签到奖励!</p> 课程签到
</blockquote>
<!-- 签到状态 --> <div class="layui-text" id="course-info"></div>
<div class="layui-row">
<div class="layui-col-xs12">
<div id="sign-in-status">你已连续签到 <span id="days-count">0</span></div>
</div>
</div>
<!-- 操作按钮 -->
<div class="layui-row" style="margin-top: 20px;"> <div class="layui-row" style="margin-top: 20px;">
<div class="layui-col-xs12"> <div class="layui-col-xs12">
<button class="layui-btn" id="sign-in-btn">立即签到</button> <button class="layui-btn" id="sign-in-btn">立即签到</button>
@@ -70,7 +97,43 @@
<script src="/static/js/menu.js"></script> <script src="/static/js/menu.js"></script>
<script src="/static/js/logout.js"></script> <script src="/static/js/logout.js"></script>
<script> <script>
// 请求后端获取菜单数 $(document).ready(function () {
let courseData = {};
// 获取课程名称或状态
$.get("/api/get-course-name", function (response) {
if (response.msg === "ok") {
// 如果后端返回课程名
$("#course-info").text("课程:" + response.data.course_name + "。在上课时间内,请及时签到!");
// 启用签到按钮
$("#sign-in-btn").prop('disabled', false);
courseData = response.data;
} else {
// 根据不同的消息更新状态
$("#course-info").text(response.msg); // 显示没有课程的消息
// 禁用签到按钮
$("#sign-in-btn").prop('disabled', true);
}
});
// 绑定签到按钮事件
$("#sign-in-btn").click(function () {
if (!$(this).prop('disabled')) {
// 发送签到请求到后端
$.post("/api/student-sign-in", courseData, function (response) {
// 处理签到后的响应
if (response.msg === 'ok') {
layer.msg('签到成功!');
} else {
layer.msg(response.data);
}
});
} else {
layer.msg("当前不可签到"); // Or handle disabled button click as needed
}
});
});
</script> </script>
</body> </body>
</html> </html>

View File

@@ -9,9 +9,10 @@
<link href="static/css/layui.css" rel="stylesheet"/> <link href="static/css/layui.css" rel="stylesheet"/>
</head> </head>
<body> <body>
<div class="layui-layout layui-layout-admin"> <div class="layui-layout layui-layout-admin">
<div class="layui-header"> <div class="layui-header layui-bg-black">
<div class="layui-logo layui-hide-xs layui-bg-black">网上上课点名系统</div> <div class="layui-logo layui-hide-xs layui-bg-black">网上上课点名系统</div>
<!-- 头部区域可配合layui 已有的水平导航) --> <!-- 头部区域可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-right"> <ul class="layui-nav layui-layout-right">
@@ -62,7 +63,6 @@
// 发起GET请求获取数据 // 发起GET请求获取数据
$.get('/api/get-course-type', function (res) { $.get('/api/get-course-type', function (res) {
// 假设返回的res是一个对象包含必修和选修的课程名数组 // 假设返回的res是一个对象包含必修和选修的课程名数组
console.log(res);
// 处理返回的数据,转换为表格能接受的格式 // 处理返回的数据,转换为表格能接受的格式
var tableData = []; var tableData = [];

View File

@@ -7,6 +7,34 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="static/css/layui.css" rel="stylesheet"/> <link href="static/css/layui.css" rel="stylesheet"/>
<style>
.custom-table {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd; /* 轻灰色边框 */
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); /* 轻微的阴影 */
}
.custom-table th, .custom-table td {
text-align: left;
padding: 12px 15px;
border-bottom: 1px solid #ddd; /* 每行之间的分割线 */
}
.custom-table th {
background-color: #f2f2f2; /* 轻灰色背景 */
color: #333; /* 深色文字 */
}
.custom-table tr:hover {
background-color: #f5f5f5; /* 鼠标悬浮时的背景色 */
}
.custom-table td {
color: #555; /* 内容的文字颜色 */
}
</style>
</head> </head>
<body> <body>
@@ -45,27 +73,21 @@
<div class="layui-body"> <div class="layui-body">
<!-- 内容主体区域 --> <!-- 内容主体区域 -->
<div style="padding: 15px;"> <div style="padding: 15px;">
<blockquote class="layui-elem-quote layui-text"> <table class="layui-table custom-table">
课程信息 <!-- 略去colgroup中课程代码的列 -->
</blockquote>
<table class="layui-table">
<colgroup> <colgroup>
<col width="200">
<col width="150"> <col width="150">
<col width="150"> <col width="200">
<col width="150">
<col width="100">
<col>
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th>课程名称</th> <th>课程名称</th>
<th>课程代码</th>
<th>学分</th> <th>学分</th>
<th>课程描述</th> <th>课程描述</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<!-- 动态生成的课程信息将填充在这里 -->
</tbody> </tbody>
</table> </table>
</div> </div>
@@ -77,6 +99,7 @@
<script src="static/layui.js"></script> <script src="static/layui.js"></script>
<script src="/static/js/menu.js"></script> <script src="/static/js/menu.js"></script>
<script src="/static/js/logout.js"></script> <script src="/static/js/logout.js"></script>
<script> <script>
$.get('/api/get-course-info', function (courses) { $.get('/api/get-course-info', function (courses) {
var tbody = $('.layui-table tbody'); var tbody = $('.layui-table tbody');
@@ -84,13 +107,14 @@
courses.forEach(function (course) { courses.forEach(function (course) {
var row = '<tr>' + var row = '<tr>' +
'<td>' + course.course_name + '</td>' + '<td>' + course.course_name + '</td>' +
'<td>' + course.course_code + '</td>' + // 移除课程代码的数据
'<td>' + course.credits + '</td>' + '<td>' + course.credits + '</td>' +
'<td>' + course.description + '</td>' + '<td>' + course.description + '</td>' +
'</tr>'; '</tr>';
tbody.append(row); // 将新行添加到表格中 tbody.append(row); // 将新行添加到表格中
}); });
}); }
);
</script> </script>
</body> </body>
</html> </html>

View File

@@ -29,7 +29,7 @@
src="//unpkg.com/outeres@0.0.10/img/layui/icon-v2.png" src="//unpkg.com/outeres@0.0.10/img/layui/icon-v2.png"
class="layui-nav-img" class="layui-nav-img"
/> />
{{ session.nickname }} {{ session.name }}
</a> </a>
<dl class="layui-nav-child"> <dl class="layui-nav-child">
<dd><a href="/home/profile">资料</a></dd> <!-- 修改这里的href指向/profile --> <dd><a href="/home/profile">资料</a></dd> <!-- 修改这里的href指向/profile -->

View File

@@ -9,11 +9,22 @@
<body class="layui-padding-3"> <body class="layui-padding-3">
<style> <style>
.demo-login-container{width: 320px; margin: 21px auto 0;} .demo-login-container {
.demo-login-other .layui-icon{position: relative; display: inline-block; margin: 0 2px; top: 2px; font-size: 26px;} width: 320px;
margin: 21px auto 0;
}
.demo-login-other .layui-icon {
position: relative;
display: inline-block;
margin: 0 2px;
top: 2px;
font-size: 26px;
}
</style> </style>
<form class="layui-form" id="loginForm"> <form class="layui-form" id="loginForm">
<h1 style="text-align:center; color: #16baaa;">网上上课点名系统</h1> <h1 style="text-align:center; color: #1E90FF; font-family: 'Arial', sans-serif; text-shadow: 2px 2px 4px;">
网上上课点名系统</h1>
<div class="demo-login-container"> <div class="demo-login-container">
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-wrap"> <div class="layui-input-wrap">
@@ -39,13 +50,17 @@
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<!-- 登录按钮 --> <!-- 登录按钮 -->
<button class="layui-btn layui-btn-fluid" type="submit" lay-submit lay-filter="login" id="btnLogin">登录</button> <button class="layui-btn layui-btn-fluid" type="submit" lay-submit lay-filter="login" id="btnLogin"
style="background-color: #4CAF50; color: white;">登录
</button>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<!-- 注册按钮 --> <!-- 注册按钮 -->
<button type="button" class="layui-btn layui-btn-fluid" id="btnRegister">注册</button> <button type="button" class="layui-btn layui-btn-fluid" id="btnRegister"
style="background-color: #1E90FF; color: white;">注册
</button>
</div> </div>
</div> </div>
</form> </form>
@@ -64,6 +79,7 @@
data: data.field, // 表单数据 data: data.field, // 表单数据
dataType: 'json', dataType: 'json',
success: function (response) { success: function (response) {
console.log(response)
if (response.success) { if (response.success) {
window.location.href = '/attendance-reminder'; // 或者你的成功页面 window.location.href = '/attendance-reminder'; // 或者你的成功页面
} else { } else {

View File

@@ -18,7 +18,7 @@
} }
</style> </style>
<h1 style="text-align:center; color: #16baaa;">注册</h1> <h1 style="text-align:center; color: #1E90FF;">注册</h1>
<form class="layui-form"> <form class="layui-form">
<div class="demo-reg-container"> <div class="demo-reg-container">
@@ -60,7 +60,8 @@
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" type="submit" lay-submit lay-filter="btnRegister">注册</button> <button class="layui-btn layui-btn-fluid" type="submit" lay-submit lay-filter="btnRegister" style="background-color: #1E90FF; color: white;">注册</button>
</div> </div>
</div> </div>
</form> </form>

76
app/templates/test.html Normal file
View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>签到提醒仪表板</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/layui-src/dist/css/layui.css" media="all">
<style>
.course-card {
padding: 10px;
border: 1px solid #DDD;
border-radius: 5px;
margin: 10px 0;
background-color: #FFF;
}
.course-card .layui-field-box {
padding: 10px;
}
.course-card button {
width: 100%;
text-align: center;
}
</style>
</head>
<body>
<div class="layui-container">
<div class="layui-row">
<div class="layui-col-xs12">
<h1>签到提醒仪表板</h1>
</div>
</div>
<div id="course-list" class="layui-row">
<!-- 课程列表将在这里生成 -->
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/layui-src/dist/layui.all.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
// 模拟从后端获取的课程数据
let courses = [
{name: "数学", time: "14:00", description: "关于几何和代数的深入学习", teacher: "张老师", room: "101教室"},
{name: "物理", time: "15:00", description: "探索物质世界的基本规律", teacher: "李老师", room: "102教室"},
{name: "化学", time: "16:00", description: "化合物与元素的神秘世界", teacher: "王老师", room: "103教室"}
];
// 获取课程列表容器
let courseListDiv = document.getElementById('course-list');
// 遍历课程数组,为每门课创建一个卡片
courses.forEach(course => {
let courseDiv = document.createElement('div');
courseDiv.className = 'layui-col-md4';
courseDiv.innerHTML = `<div class="course-card layui-elem-field">
<legend>${course.name} - ${course.teacher}</legend>
<div class="layui-field-box">
<p><strong>时间:</strong> ${course.time}</p>
<p><strong>教室:</strong> ${course.room}</p>
<p><strong>描述:</strong> ${course.description}</p>
<p><strong>剩余时间:</strong> <span class="countdown">计算中...</span></p>
<button class="layui-btn layui-btn-normal">签到</button>
</div>
</div>`;
courseListDiv.appendChild(courseDiv);
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,43 @@
import unittest
import os
from app.views import *
from werkzeug.datastructures import FileStorage # 用于创建测试文件
class ReceiveExcelTestCase(unittest.TestCase):
def setUp(self):
app.testing = True # 设置 Flask 应用为测试模式
self.client = app.test_client()
# 创建一个测试用的Excel文件或使用一个真实的Excel文件路径
self.test_file_path = 'template.xlsx'
def test_receive_excel_no_file(self):
# 测试没有文件时的情况
response = self.client.post('/api/receive-excel')
self.assertEqual(response.status_code, 400)
self.assertEqual(response.get_json(), {"error": "No file part"})
def test_receive_excel_with_file(self):
# 模拟已登录用户
with self.client.session_transaction() as sess:
sess['number'] = 'X202301000001'
# 使用 FileStorage 创建测试文件对象
data = {
'file': (open(self.test_file_path, 'rb'), self.test_file_path)
}
# 发送 POST 请求到 /api/receive-excel
response = self.client.post('/api/receive-excel', data=data, content_type='multipart/form-data')
# 验证返回的状态码和响应
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json(), {"message": "File successfully processed"})
def tearDown(self):
# 清理测试用的文件或数据
if os.path.exists(self.test_file_path):
os.remove(self.test_file_path)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,39 @@
import unittest
from app.views import *
from unittest.mock import patch
from flask import session
class StudentSignInTestCase(unittest.TestCase):
def setUp(self):
# 设置 Flask 测试模式
app.testing = True
self.client = app.test_client()
@patch('db.database_manager.DatabaseManager.update_sign_in_info')
def test_student_sign_in(self, mock_update_sign_in_info):
# 模拟已登录用户
with self.client.session_transaction() as sess:
sess['number'] = 'X202301000001'
# 模拟数据库操作
mock_update_sign_in_info.return_value = 1 # 假设成功更新签到信息
# 发送 POST 请求到/api/student-sign-in
response = self.client.post('/api/student-sign-in', data={
'course_name': '计算机导论',
'course_id': '2',
'student_number': 'X202301000001',
})
# 验证返回的状态码和JSON数据
self.assertEqual(response.status_code, 200)
json_data = response.get_json()
self.assertEqual(json_data, {"msg": "ok", "data": "签到成功!"})
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,37 @@
import unittest
from app.views import *
from unittest.mock import patch
from flask import session
class TeacherSignInTestCase(unittest.TestCase):
def setUp(self):
# 设置 Flask 测试模式
app.testing = True
self.client = app.test_client()
@patch('db.database_manager.DatabaseManager.update_sign_in_info')
def test_teacher_sign_in(self, mock_teacher_sign_in):
# 模拟已登录用户
with self.client.session_transaction() as sess:
sess['number'] = 'X202301000001'
# 模拟数据库操作的返回值
mock_teacher_sign_in.return_value = {"msg": "当前班级专业没有学生'"}
# 发送 POST 请求到/api/teacher-sign-in
response = self.client.post('/api/teacher-sign-in', data={
'course_id': '123',
'course_name': 'Test Course',
'class_name': 'TestClass',
'major_id': '456'
})
# 验证返回的状态码和数据
self.assertEqual(response.status_code, 200)
json_data = response.get_json()
self.assertEqual(json_data, {"msg": "当前班级专业没有学生"})
if __name__ == '__main__':
unittest.main()

73
app/tests/TestGetHtml.py Normal file
View File

@@ -0,0 +1,73 @@
import unittest
from app.views import *
class HtmlTestCase(unittest.TestCase):
def setUp(self):
app.testing = True # 设置 Flask 应用为测试模式
self.client = app.test_client() # 创建一个测试客户端
def test_get_course_info(self):
# 测试 GET 请求
response = self.client.get('/course-info')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
def test_get_attendance(self):
# 测试 GET 请求
response = self.client.get('/attendance')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
def test_get_announcement(self):
# 测试 GET 请求
response = self.client.get('/announcement')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
def test_get_attendance_reminder(self):
# 测试 GET 请求
response = self.client.get('/attendance-reminder')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
def test_get_course_category(self):
# 测试 GET 请求
response = self.client.get('/course-category')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
def test_get_attendance_teacher(self):
# 测试 GET 请求
response = self.client.get('/attendance-teacher')
# 验证响应状态码
self.assertEqual(response.status_code, 200)
# 验证响应的Content-Type头部值
self.assertIn('text/html', response.content_type)
if __name__ == '__main__':
unittest.main()

44
app/tests/TestGetMenu.py Normal file
View File

@@ -0,0 +1,44 @@
import unittest
from app.views import *
from flask import session
from unittest.mock import patch # 如果需要模拟数据库方法
class MenuAPITestCase(unittest.TestCase):
def setUp(self):
app.testing = True # 设置 Flask 应用为测试模式
self.client = app.test_client() # 创建一个测试客户端
self.expected_menu = [
{"name": "课程类别", "path": "/course-category"},
{"name": "课程信息", "path": "/course-info"},
{"name": "课程签到", "path": "/attendance-teacher"},
{"name": "签到提醒", "path": "/attendance-reminder"}
]
def test_menu_no_login(self):
# 测试未登录情况下请求API
response = self.client.get('/api/menu')
self.assertEqual(response.status_code, 401)
self.assertEqual(response.get_json(), [])
def test_login(self):
with self.client:
self.client.post('/login', data=dict(
number='G0001',
password='1'
))
# 确认登录后session中有数据
self.assertIn('role', session)
# 执行logout
response = self.client.get('/api/menu')
print(response.get_json())
# 确认响应是重定向到登录页面
self.assertEqual(response.status_code, 200)
self.assertEqual(self.expected_menu,response.get_json())
if __name__ == '__main__':
unittest.main()

45
app/tests/TestLogin.py Normal file
View File

@@ -0,0 +1,45 @@
import unittest
from app.views import *
from db.database_manager import DatabaseManager # 确保你可以导入DatabaseManager
class LoginTestCase(unittest.TestCase):
def setUp(self):
# 设置 Flask 测试模式
app.testing = True
self.client = app.test_client()
def test_login_get(self):
# 测试 GET 请求返回登录页面
response = self.client.get('/login')
self.assertEqual(response.status_code, 200)
self.assertIn('text/html', response.content_type)
def test_successful_login_post(self):
# 测试有效的登录 POST 请求
with self.client:
response = self.client.post('/login', data={
'number': 'G0001',
'password': '1'
})
# 根据你的应用逻辑调整断言
self.assertEqual(response.status_code, 200)
def test_invalid_login_post(self):
# 测试无效的登录 POST 请求
response = self.client.post('/login', data={
'number': 'admin',
'password': 'admin'
})
# 将返回的数据解析为JSON
json_data = response.get_json()
# 确认JSON响应中的值
self.assertEqual(response.status_code, 200)
self.assertFalse(json_data['success'])
self.assertEqual(json_data['message'], "无效的用户名或密码")
# 运行测试
if __name__ == '__main__':
unittest.main()

34
app/tests/TestLogout.py Normal file
View File

@@ -0,0 +1,34 @@
import unittest
from app.views import *
class LogoutTestCase(unittest.TestCase):
def setUp(self):
# 设置 Flask 测试模式
app.testing = True
self.client = app.test_client()
def test_logout(self):
# 先登录,确保 session 是设置的
with self.client:
self.client.post('/login', data=dict(
number='G0001',
password='1'
))
# 确认登录后session中有数据
self.assertIn('number', session)
# 执行logout
response = self.client.get('/logout')
# 确认 session 被清空
self.assertNotIn('number', session)
# 确认响应是重定向到登录页面
self.assertEqual(response.status_code, 302)
self.assertTrue(response.location.endswith('/login'))
if __name__ == '__main__':
unittest.main()

View File

@@ -1,18 +1,21 @@
import os import os
import logging
import openpyxl as openpyxl # 第三方库
import openpyxl
from flask import Flask, redirect, url_for, render_template, session, jsonify, request, send_file from flask import Flask, redirect, url_for, render_template, session, jsonify, request, send_file
from datetime import datetime
# 应用内部模块
from utils.time_utils import check_now_time
from utils.parse_table import parse_table
from utils.allowed_files import allowed_excel from utils.allowed_files import allowed_excel
from db.connection import MySQLPool from db.connection import MySQLPool
from config import SECRET_KEY
from db.database_manager import DatabaseManager from db.database_manager import DatabaseManager
from models.Student import Student from models.Student import Student
from models.Teacher import Teacher from models.Teacher import Teacher
from models.User import User from models.User import User
import logging from config import SECRET_KEY, LOGGING_CONFIG, FILE_PATH
from config import LOGGING_CONFIG
from config import FILE_PATH
app = Flask(__name__, static_folder='static') app = Flask(__name__, static_folder='static')
app.secret_key = SECRET_KEY # 从配置文件设置 app.secret_key = SECRET_KEY # 从配置文件设置
@@ -86,7 +89,7 @@ def login():
db_manager = DatabaseManager() db_manager = DatabaseManager()
result = db_manager.valid_login(number, password) # 获取验证结果 result = db_manager.valid_login(number, password) # 获取验证结果
print(result)
# 确保用户已验证且活跃(未被禁用) # 确保用户已验证且活跃(未被禁用)
if result['valid'] and result['status'] == 1: if result['valid'] and result['status'] == 1:
# 登录成功 # 登录成功
@@ -94,7 +97,7 @@ def login():
session['role'] = check_identity(number) session['role'] = check_identity(number)
session['name'] = result['name'] session['name'] = result['name']
return jsonify(success=True, message="登录成功") return jsonify(success=True, message="登录成功")
elif not result['status']: elif not result.get('status'):
# 用户被禁用的情况 # 用户被禁用的情况
return jsonify(success=False, message="账户已被禁用") return jsonify(success=False, message="账户已被禁用")
else: else:
@@ -166,7 +169,12 @@ def course_info():
@app.route('/api/get-course-info', methods=['GET']) @app.route('/api/get-course-info', methods=['GET'])
def get_course_info(): def get_course_info():
student_number = session.get('number')
db_manager = DatabaseManager() db_manager = DatabaseManager()
if check_identity(student_number) == "student":
course_data = db_manager.get_class_courses(student_number)
return jsonify(course_data)
else:
course_data = db_manager.get_all_courses() course_data = db_manager.get_all_courses()
return jsonify(course_data) return jsonify(course_data)
@@ -239,6 +247,7 @@ def get_current_teacher_courses():
# 获取所有课程数据 # 获取所有课程数据
db_manager = DatabaseManager() db_manager = DatabaseManager()
all_course_data = db_manager.get_current_teacher_courses(number) all_course_data = db_manager.get_current_teacher_courses(number)
print(all_course_data)
logging.info(f"all_course_data: {all_course_data}") logging.info(f"all_course_data: {all_course_data}")
# 计算分页的起始和结束索引 # 计算分页的起始和结束索引
start = (page - 1) * limit start = (page - 1) * limit
@@ -267,6 +276,7 @@ def download_template():
@app.route('/api/receive-excel', methods=['POST']) @app.route('/api/receive-excel', methods=['POST'])
def receive_excel(): def receive_excel():
number = session.get('number')
# 检查是否有文件在请求中 # 检查是否有文件在请求中
if 'file' not in request.files: if 'file' not in request.files:
return jsonify({"error": "No file part"}), 400 return jsonify({"error": "No file part"}), 400
@@ -281,9 +291,10 @@ def receive_excel():
if file and allowed_excel(file.filename): if file and allowed_excel(file.filename):
try: try:
# 使用 openpyxl 读取文件内容 # 使用 openpyxl 读取文件内容
workbook = openpyxl.load_workbook(file) data = parse_table(file, number)
# TODO: 在这里处理你的Excel文件例如读取数据 db_manager = DatabaseManager()
print(workbook) result = db_manager.insert_into_class_student(data)
print(result)
return jsonify({"message": "File successfully processed"}), 200 return jsonify({"message": "File successfully processed"}), 200
except Exception as e: except Exception as e:
return jsonify({"error": str(e)}), 500 return jsonify({"error": str(e)}), 500
@@ -291,5 +302,102 @@ def receive_excel():
return jsonify({"error": "Invalid file type"}), 400 return jsonify({"error": "Invalid file type"}), 400
@app.route('/api/get-course-name', methods=['GET'])
def get_course_name():
period_id, period_name = check_now_time() # 获取当前时间段信息
print(f"period_id: {period_id}, period_name: {period_name}")
# 如果当前不在任何时间段内
if period_id is None:
return jsonify({
'msg': period_name, # 返回不在课程时间段内的消息
'data': None
})
# 获取当前用户编号
number = session.get('number')
if not number:
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
# 获取今天是星期几
now = datetime.now()
day_of_week = now.weekday() + 1
# 如果是周末
if not (1 <= day_of_week <= 5):
return jsonify({"msg": "周末没有课程", "data": None})
# 如果是工作日,获取课程信息
print(f"day of week: {day_of_week}")
db_manager = DatabaseManager()
data = db_manager.get_course_name(number, day_of_week, period_id)
print(data)
# 返回课程信息
return jsonify({
'msg': 'ok',
'data': data
})
@app.route('/api/student-sign-in', methods=['POST'])
def student_sign_in():
number = session.get("number")
course_name = request.form.get('course_name')
course_id = request.form.get('course_id')
now = datetime.now()
date = now.strftime("%Y年%m月%d%H:%M")
status = "出勤"
print(f"number: {number},course_name: {course_name},course_id: {course_id}")
db_manager = DatabaseManager()
result = db_manager.update_sign_in_info(number, course_id, course_name, date, status)
if result == 1:
return jsonify({"msg": "ok", "data": "签到成功!"})
else:
return jsonify({"msg": "fail", "data": "签到失败!"})
@app.route('/api/get-today-courses')
def student_get_today_courses():
number = session.get('number')
if not number:
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
# 获取今天是星期几
now = datetime.now() # 获取当前时间
day_of_week = now.weekday() + 1
# 如果是周末
if not (1 <= day_of_week <= 5):
return jsonify({"msg": "周末没有课程", "data": None})
db_manager = DatabaseManager()
data = db_manager.student_get_today_courses(number, day_of_week)
# 返回课程信息
return jsonify({
'msg': 'ok',
'data': data
})
@app.route('/api/teacher-sign-in', methods=['POST'])
def teacher_sign_in():
teacher_number = session.get('number')
course_id = request.form['course_id']
course_name = request.form['course_name']
class_name = request.form['class_name']
major_id = request.form['major_id']
now = datetime.now()
date = now.strftime("%Y年%m月%d%H:%M")
status = "出勤"
print(f"course_id: {course_id},course_name: {course_name},class_name: {class_name},major_id: {major_id}")
db_manager = DatabaseManager()
data = db_manager.teacher_sign_in(course_id, course_name, class_name, major_id, date, status, teacher_number)
return data
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)

View File

@@ -1,3 +1,5 @@
from utils.time_utils import check_now_time
from utils.time_utils import get_time_by_ids
from db.connection import MySQLPool from db.connection import MySQLPool
import bcrypt import bcrypt
@@ -29,6 +31,22 @@ class DatabaseManager:
cursor.close() cursor.close()
conn.close() conn.close()
def executemany(self, query, params_list):
conn = self.pool.get_connection()
try:
cursor = conn.cursor()
cursor.executemany(query, params_list) # 使用executemany代替execute
conn.commit() # 提交事务
return cursor.rowcount # 返回受影响的行数
except Exception as e:
# 可以在这里添加错误处理逻辑,例如打印错误日志、回滚事务等
print("An error occurred: ", e)
conn.rollback()
return None
finally:
cursor.close()
conn.close()
def user_exists(self, phone_number): def user_exists(self, phone_number):
sql = "SELECT 1 FROM user WHERE number=%s LIMIT 1" sql = "SELECT 1 FROM user WHERE number=%s LIMIT 1"
result = self.fetch(sql, (phone_number,)) result = self.fetch(sql, (phone_number,))
@@ -59,7 +77,7 @@ class DatabaseManager:
return {'valid': True, 'status': status, 'name': name} return {'valid': True, 'status': status, 'name': name}
# 密码不匹配或用户不存在,返回登录失败 # 密码不匹配或用户不存在,返回登录失败
return {'valid': False} return {'valid': False, 'status': True}
def get_menu(self, role): def get_menu(self, role):
sql = "SELECT menu_name,path FROM menu_items WHERE role=%s ORDER BY `order`" sql = "SELECT menu_name,path FROM menu_items WHERE role=%s ORDER BY `order`"
@@ -75,11 +93,13 @@ class DatabaseManager:
# 使用INNER JOIN连接teacher_class_course表和course表 # 使用INNER JOIN连接teacher_class_course表和course表
sql = """ sql = """
SELECT SELECT
c.course_id,
c.course_name, c.course_name,
c.course_code, c.course_code,
c.credits, c.credits,
tcc.class_name, tcc.class_name,
m.major m.major,
m.major_id
FROM FROM
teacher_class_course tcc teacher_class_course tcc
JOIN JOIN
@@ -91,8 +111,34 @@ WHERE
""" """
# 执行查询并返回结果 # 执行查询并返回结果
result = self.fetch(sql, (teacher_number,)) class_student_sql = """SELECT course_id, course_name,class_name,major,major_id,major FROM class_student where teacher_number = %s;"""
return result result1 = self.fetch(sql, (teacher_number,))
result2 = self.fetch(class_student_sql, (teacher_number))
data = []
# 遍历第一个结果集
if result1:
for row in result1:
data.append({
"course_id": row['course_id'],
"course_name": row['course_name'],
"class_name": row['class_name'],
"major_id": row['major_id'],
"major": row['major']
})
# 遍历第二个结果集
if result2:
for row in result2:
data.append({
"course_id": row['course_id'],
"course_name": row['course_name'],
"class_name": row['class_name'],
"major_id": row['major_id'],
"major": row['major']
})
# 返回包含两个结果集信息的data列表
return data
def get_course_type(self): def get_course_type(self):
sql = "SELECT course_name, course_type FROM course" sql = "SELECT course_name, course_type FROM course"
@@ -124,3 +170,130 @@ WHERE
""" """
data = (student.student_name, student.student_number, student.user_id, student.major_id, student.class_name) data = (student.student_name, student.student_number, student.user_id, student.major_id, student.class_name)
return self.execute(sql, data) return self.execute(sql, data)
def get_course_name(self, student_number, day_of_week, period_id):
print(f"student_number: {student_number}, day_of_week: {day_of_week}, period_id: {period_id}")
# 从student表获取class_name
sql_student = "SELECT class_name FROM student WHERE student_number = %s;"
class_name = self.fetch(sql_student, (student_number,))[0]['class_name']
# 使用class_name和day_of_week从schedule表获取course_id
sql_schedule = "SELECT course_id FROM schedule WHERE day_of_week = %s AND class_name = %s AND period_id = %s;"
course_id = self.fetch(sql_schedule, (day_of_week, class_name, period_id))
print(f"course_id: {course_id}")
id = course_id[0]['course_id']
print(f"id: {id}")
# 对于每一个course_id从course表中查询course_name
sql_course = "SELECT course_name FROM course WHERE course_id = %s;"
course_name = self.fetch(sql_course, (id,))[0]['course_name']
print(f"course_name: {course_name}")
data = {"course_name": course_name, "course_id": id}
return data
def update_sign_in_info(self, student_number, course_id, course_name, date, status):
sql = """
INSERT INTO attendance_record (student_number, course_id, course_name, date, status)
VALUES (%s, %s, %s, %s, %s)
"""
val = (student_number, course_id, course_name, date, status)
result = self.execute(sql, val)
return result
def get_class_courses(self, student_number):
# 1. 查询学生的主修专业
major_sql = "SELECT major_id FROM student WHERE student_number = %s;"
major_result = self.fetch(major_sql, student_number)
print(major_result)
major_id = major_result[0]['major_id']
# 2. 查询专业的所有课程ID
course_ids_sql = "SELECT course_id FROM major_course WHERE major_id = %s;"
courses_result = self.fetch(course_ids_sql, major_id)
course_ids = [course['course_id'] for course in courses_result]
# 3. 对每个课程ID查询课程详细信息
courses_data = []
for course_id in course_ids:
course_sql = "SELECT course_name, course_code, credits, description FROM course WHERE course_id = %s;"
result = self.fetch(course_sql, course_id)
courses_data.append(result[0])
return courses_data # 返回课程详细信息列表
def student_get_today_courses(self, student_number, day_of_week):
# 从student表获取class_name
sql_student = "SELECT class_name FROM student WHERE student_number = %s;"
class_name = self.fetch(sql_student, (student_number,))[0]['class_name']
# 使用class_name和day_of_week从schedule表获取course_id
sql_schedule = "SELECT course_id,period_id FROM schedule WHERE day_of_week = %s AND class_name = %s;"
schedule_results = self.fetch(sql_schedule, (day_of_week, class_name))
print(schedule_results)
data = []
for i in schedule_results:
course_id = i['course_id']
sql_course = "SELECT course_name FROM course WHERE course_id = %s;"
course_name = self.fetch(sql_course, (course_id))[0]['course_name']
id = i['period_id']
time = get_time_by_ids(id)
data.append({"course_name": course_name, "time": time})
return data
def teacher_sign_in(self, course_id, course_name, class_name, major_id, date, status, teacher_number):
class_student_sql = "SELECT student_number FROM class_student WHERE teacher_number = %s AND major_id = %s AND class_name = %s"
class_student_result = self.fetch(class_student_sql, (teacher_number, major_id, class_name))
student_sql = "SELECT student_number FROM student WHERE class_name = %s AND major_id = %s;"
student_sql_result = self.fetch(student_sql, (class_name, major_id))
values_list = []
# 检查是否有学生编号被返回
if student_sql_result:
for student in student_sql_result:
# 对于每个学生编号,创建一条记录的值元组
student_number = student['student_number']
values_list.append((student_number, course_id, course_name, date, status))
if class_student_result:
for class_student in class_student_result:
# 注意这里变量名已经修改为class_student
student_number = class_student['student_number']
values_list.append((student_number, course_id, course_name, date, status))
# 如果没有任何学生编号,返回相应的消息
if not values_list:
return {"msg": "当前班级专业没有学生"}
# 构建一次性插入多条记录的SQL语句
attendance_sql = "INSERT INTO attendance_record (student_number, course_id, course_name, date, status) VALUES (%s, %s, %s, %s, %s)"
# 使用executemany一次性插入多条记录
result = self.executemany(attendance_sql, values_list)
print(f"Inserted rows: {result}")
return {"msg": "班级签到成功,签到人数:" + str(result)}
def insert_into_class_student(self, class_students):
try:
values_list = [
(
cs['teacher_number'],
cs['class_name'],
cs['student_name'],
cs['student_number'],
cs['course_id'],
cs['course_name'],
cs['major_id'],
cs['major']
)
for cs in class_students
]
sql = """INSERT INTO class_student
(teacher_number, class_name, student_name, student_number, course_id, course_name, major_id, major)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""
result = self.executemany(sql, values_list)
return {"inserted_rows": result}
except Exception as e:
# 这里应根据实际情况记录日志或返回错误信息
print(f"An error occurred: {e}")
return {"error": str(e)}

Binary file not shown.

241
mysql.sql
View File

@@ -1,18 +1,3 @@
CREATE TABLE user
(
user_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
number VARCHAR(15) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
status BOOLEAN NOT NULL
);
INSERT INTO user (name, number, password, identity, status)
VALUES ('学生', '1', '$2b$12$okY88GrzlUHb/Ox1ENwtqeBUnE0bgMOCPy.UKmFaTnu3El7EYX8Em', 'student', TRUE),
('老师', '2', '$2b$12$okY88GrzlUHb/Ox1ENwtqeBUnE0bgMOCPy.UKmFaTnu3El7EYX8Em', 'teacher', TRUE);
CREATE TABLE menu_items CREATE TABLE menu_items
( (
id INT AUTO_INCREMENT PRIMARY KEY, id INT AUTO_INCREMENT PRIMARY KEY,
@@ -27,11 +12,8 @@ INSERT INTO menu_items (menu_name, role, path, `order`)
VALUES ('课程信息', 'student', '/course-info', 1), VALUES ('课程信息', 'student', '/course-info', 1),
('课程签到', 'student', '/attendance', 2), ('课程签到', 'student', '/attendance', 2),
('公告信息', 'student', '/announcement', 3), ('公告信息', 'student', '/announcement', 3),
('签到提醒', 'student', '/attendance-reminder', 4); ('签到提醒', 'student', '/attendance-reminder', 4),
('课程类别', 'teacher', '/course-category', 1),
INSERT INTO menu_items (menu_name, role, path, `order`)
VALUES ('课程类别', 'teacher', '/course-category', 1),
('课程信息', 'teacher', '/course-info', 2), ('课程信息', 'teacher', '/course-info', 2),
('课程签到', 'teacher', '/attendance-teacher', 3), ('课程签到', 'teacher', '/attendance-teacher', 3),
('签到提醒', 'teacher', '/attendance-reminder', 4); ('签到提醒', 'teacher', '/attendance-reminder', 4);
@@ -79,18 +61,71 @@ VALUES ('大学计算机基础', 'CF001', '必修', 3, '介绍计算机基础知
('离散数学导论', 'IDTM01', '必修', 3, '介绍离散数学的基础知识和应用'), ('离散数学导论', 'IDTM01', '必修', 3, '介绍离散数学的基础知识和应用'),
('计算机网络', 'CN002', '必修', 4, '学习计算机网络的基础理论和协议'); ('计算机网络', 'CN002', '必修', 4, '学习计算机网络的基础理论和协议');
CREATE TABLE attendance_record
CREATE TABLE attendance_records
( (
record_id INT AUTO_INCREMENT PRIMARY KEY, record_id INT AUTO_INCREMENT PRIMARY KEY,
student_number VARCHAR(20) NOT NULL,
course_id INT NOT NULL, course_id INT NOT NULL,
student_id INT NOT NULL, course_name VARCHAR(255) NOT NULL,
date DATE NOT NULL, date VARCHAR(255) NOT NULL,
status ENUM('present', 'absent', 'late', 'excused'), status VARCHAR(20)
FOREIGN KEY (course_id) REFERENCES course (course_id),
FOREIGN KEY (student_id) REFERENCES student (student_id)
); );
CREATE TABLE time_period
(
period_id INT AUTO_INCREMENT UNIQUE,
period_name VARCHAR(10),
start_time TIME,
end_time TIME,
PRIMARY KEY (period_id)
);
INSERT INTO time_period (period_name, start_time, end_time)
VALUES ('一、二节', '08:00:00', '09:30:00'),
('三、四节', '10:00:00', '11:30:00'),
('五、六节', '14:30:00', '16:00:00'),
('七、八节', '16:30:00', '18:00:00');
CREATE TABLE class_student (
id INT AUTO_INCREMENT PRIMARY KEY,
teacher_number VARCHAR(20) NOT NULL,
class_name VARCHAR(20) NOT NULL , -- 班级
student_name VARCHAR(50) NOT NULL , -- 姓名
student_number VARCHAR(20) NOT NULL UNIQUE, -- 学号
course_id INT NOT NULL , -- 课程ID
course_name VARCHAR(100) NOT NULL , -- 课程名称
major_id VARCHAR(20) NOT NULL,
major VARCHAR(255) NOT NULL
);
CREATE TABLE user
(
user_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
number VARCHAR(15) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
status BOOLEAN NOT NULL
);
INSERT INTO user (name, number, password, status) VALUES
('教师1','G0001','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('教师2','G0002','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('教师3','G0003','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('教师4','G0004','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生1','X202301000001','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生2','X202301000002','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生3','X202301000003','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生4','X202301000004','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生5','X202301000005','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生6','X202301000006','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生7','X202301000007','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生8','X202301000008','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生9','X202301000009','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生10','X2023010000010','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生11','X2023010000011','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE),
('学生12','X2023010000012','$2b$12$COT85R.ice41B/ofAra2ZewTe1En3ZhF6CBKOv2WScTcy.jQAhEVO',TRUE);
CREATE TABLE major CREATE TABLE major
( (
@@ -118,27 +153,20 @@ CREATE TABLE student
FOREIGN KEY (major_id) REFERENCES major (major_id) FOREIGN KEY (major_id) REFERENCES major (major_id)
); );
INSERT INTO student (user_id, student_number, student_name, class_id) INSERT INTO student (user_id, student_number, student_name, class_name,major_id)
VALUES (5,'王伟', 202300001000, 1), VALUES
(6,'李娜', 202300001001, 1), (5,'X202301000001','学生1','2023级01班','000'),
(7,'张伟', 202300001002, 1), (6,'X202301000002','学生2','2023级01班','000'),
(8,'刘洋', 202300001003, 1), (7,'X202301000003','学生3','2023级01班','000'),
(9,'陈敏', 202300001004, 1), (8,'X202301000004','学生4','2023级01班','000'),
(10,'杨静', 202300001005, 2), (9,'X202302000005','学生5','2023级02班','000'),
(11,'赵媛媛', 202300001006, 2), (10,'X202302000006','学生6','2023级02班','000'),
(12,'黄进', 202300001007, 2), (11,'X202302000007','学生7','2023级02班','000'),
(13,'周杰', 202300001008, 2), (12,'X202302000008','学生8','2023级02班','000'),
(14,'吴琳', 202300001009, 2), (13,'X202303000009','学生9','2023级03班','001'),
(15,'徐涛', 202300001010, 3), (14,'X202303000010','学生10','2023级03班','001'),
(16,'孙怡', 202300001011, 3), (15,'X202303000011','学生11','2023级03班','001'),
(17,'朱元璋', 202300001012, 3), (16,'X202303000012','学生12','2023级03班','001');
(18,'马云', 202300001013, 3),
(19,'胡雪', 202300001014, 3),
(20,'郭敬明', 202300001015, 4),
(21,'林芳', 202300001016, 4),
(22,'段誉', 202300001017, 4),
(23,'曹操', 202300001018, 4),
(24,'刘备', 202300001019, 4);
CREATE TABLE teacher CREATE TABLE teacher
( (
@@ -150,11 +178,11 @@ CREATE TABLE teacher
FOREIGN KEY (user_id) REFERENCES user (user_id) FOREIGN KEY (user_id) REFERENCES user (user_id)
); );
INSERT INTO teacher (name, user_id) INSERT INTO teacher (name, user_id,teacher_number)
VALUES ('教师1', 1), VALUES ('教师1', 1,'G0001'),
('教师2', 2), ('教师2', 2,'G0002'),
('教师3', 3), ('教师3', 3,'G0003'),
('教师4', 4); ('教师4', 4,'G0004');
CREATE TABLE major_course CREATE TABLE major_course
( (
@@ -189,65 +217,70 @@ CREATE TABLE teacher_class_course
); );
INSERT INTO teacher_class_course(teacher_number, course_id, class_name,major_id) VALUES INSERT INTO teacher_class_course(teacher_number, course_id, class_name,major_id) VALUES
('G0000',1,'2023级01班','000'); ('G0001',1,'2023级01班','000'),
('G0001',3,'2023级01班','000'),
INSERT INTO teacher_class_course(teacher_id, course_id, class_id) ('G0002',2,'2023级02班','000'),
VALUES (1, 1, 1), ('G0002',4,'2023级02班','000'),
(1, 2, 1), ('G0001',1,'2023级02班','000'),
(1, 1, 3), ('G0001',3,'2023级02班','000'),
(1, 1, 4), ('G0002',2,'2023级03班','001'),
(2, 2, 1), ('G0002',4,'2023级03班','001');
(2, 2, 2),
(2, 2, 3),
(2, 2, 4),
(3, 2, 1),
(3, 2, 2),
(3, 2, 3),
(3, 2, 4);
CREATE TABLE schedule CREATE TABLE schedule
( (
schedule_id INT AUTO_INCREMENT, schedule_id INT AUTO_INCREMENT UNIQUE,
day_of_week INT, day_of_week INT NOT NULL,
period_id INT, period_id INT NOT NULL,
teacher_id INT, teacher_number VARCHAR(20) NOT NULL,
class_id INT, class_name VARCHAR(20) NOT NULL,
course_id INT, course_id INT NOT NULL,
PRIMARY KEY (schedule_id), PRIMARY KEY (schedule_id),
FOREIGN KEY (period_id) REFERENCES time_period (period_id), FOREIGN KEY (period_id) REFERENCES time_period (period_id),
FOREIGN KEY (teacher_id) REFERENCES teacher (teacher_id), FOREIGN KEY (teacher_number) REFERENCES teacher (teacher_number),
FOREIGN KEY (class_id) REFERENCES class (class_id),
FOREIGN KEY (course_id) REFERENCES course (course_id) FOREIGN KEY (course_id) REFERENCES course (course_id)
); );
INSERT INTO schedule (day_of_week, period_id, teacher_id, class_id, course_id) VALUES INSERT INTO schedule (day_of_week, period_id, teacher_number, class_name, course_id) VALUES
(1,1,1,1,1), (1,1,'G0001','2023级01班',1),
(1,2,1,2,1), (1,2,'G0001','2023级01班',3),
(2,3,1,1,3), (1,3,'G0002','2023级01班',2),
(2,4,1,1,4), (1,4,'G0002','2023级01班',4),
(3,1,1,1,2), (2,1,'G0001','2023级01班',1),
(3,4,1,1,1), (2,2,'G0001','2023级01班',3),
(4,2,1,2,1), (2,3,'G0002','2023级01班',2),
(4,3,1,1,1), (2,4,'G0002','2023级01班',4),
(5,1,1,1,3), (3,1,'G0001','2023级01班',1),
(5,3,1,1,1); (3,2,'G0001','2023级01班',3),
(3,3,'G0002','2023级01班',2),
(3,4,'G0002','2023级01班',4),
(4,1,'G0001','2023级01班',1),
(4,2,'G0001','2023级01班',3),
(4,3,'G0002','2023级01班',2),
(4,4,'G0002','2023级01班',4),
(5,1,'G0001','2023级01班',1),
(5,2,'G0001','2023级01班',3),
(5,3,'G0002','2023级01班',2),
(5,4,'G0002','2023级01班',4),
(1,1,'G0002','2023级03班',2),
(1,2,'G0002','2023级03班',4),
(1,3,'G0001','2023级02班',1),
(1,4,'G0001','2023级02班',3),
(2,1,'G0002','2023级02班',2),
(2,2,'G0002','2023级02班',4),
(2,3,'G0001','2023级02班',1),
(2,4,'G0001','2023级02班',3),
(3,1,'G0002','2023级03班',2),
(3,2,'G0002','2023级03班',4),
(3,3,'G0001','2023级02班',1),
(3,4,'G0001','2023级02班',3),
(4,1,'G0002','2023级02班',2),
(4,2,'G0002','2023级02班',4),
(4,3,'G0001','2023级02班',1),
(4,4,'G0001','2023级02班',3),
(5,1,'G0002','2023级03班',2),
(5,2,'G0002','2023级03班',4),
(5,3,'G0001','2023级02班',1),
(5,4,'G0001','2023级02班',3);
CREATE TABLE time_period
(
period_id INT AUTO_INCREMENT,
period_name VARCHAR(10),
start_time TIME,
end_time TIME,
PRIMARY KEY (period_id)
);
INSERT INTO time_period (period_name, start_time, end_time)
VALUES ('一、二节', '08:00:00', '09:30:00'),
('三、四节', '10:00:00', '11:30:00'),
('五、六节', '14:30:00', '16:00:00'),
('七、八节', '16:30:00', '18:00:00');

Binary file not shown.

30
utils/parse_table.py Normal file
View File

@@ -0,0 +1,30 @@
from openpyxl import load_workbook
def parse_table(file_path, number):
# 加载Excel工作簿
work_book = load_workbook(file_path)
# 选择工作簿中的第一个工作表
sheet = work_book.active
# 创建一个列表来存储所有行的数据
data = []
# 从第二行开始遍历(假设第一行是标题行)
for row in sheet.iter_rows(min_row=2, values_only=True):
# 创建一个字典来存储每行的数据
row_data = {
"teacher_number": number,
"class_name": row[0], # 班级
"student_name": row[1], # 姓名
"student_number": row[2], # 学号
"course_id": row[3], # 课程id
"course_name": row[4], # 课程
"major_id": row[5], # 专业代码
"major": row[6]
}
data.append(row_data)
# 返回解析后的数据
return data

35
utils/time_utils.py Normal file
View File

@@ -0,0 +1,35 @@
import datetime
time_periods = {
1: {"period_name": "一、二节", "start_time": "08:00:00", "end_time": "09:30:00"},
2: {"period_name": "三、四节", "start_time": "10:00:00", "end_time": "11:30:00"},
3: {"period_name": "五、六节", "start_time": "14:30:00", "end_time": "16:00:00"},
4: {"period_name": "七、八节", "start_time": "16:30:00", "end_time": "18:00:00"}
}
def check_now_time():
# 获取当前时间
current_time = datetime.datetime.now().time()
# 遍历time_periods的每个时间段
for period_id, period_info in time_periods.items():
start_time = datetime.datetime.strptime(period_info["start_time"], "%H:%M:%S").time()
end_time = datetime.datetime.strptime(period_info["end_time"], "%H:%M:%S").time()
# 检查当前时间是否在时间段内
if start_time <= current_time <= end_time:
return period_id, period_info["period_name"]
# 如果当前时间不在任何一个时间段内
return None, "当前不在任何课程时间段内"
def get_time_by_ids(id):
# 获取对应的时间信息并添加到结果列表
period = time_periods.get(id)
if period: # 确保id是有效的
return period["start_time"][0:5] + "-" + period["end_time"][0:5]
else:
return None