Compare commits
5 Commits
a2be2f6378
...
c0d0e43e73
| Author | SHA1 | Date |
|---|---|---|
|
|
c0d0e43e73 | |
|
|
3e79a22956 | |
|
|
ca55d9d2fd | |
|
|
e655b72a5c | |
|
|
e75cce4dc9 |
|
|
@ -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_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 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); // 初始加载第一页
|
||||||
|
});
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
40
app/views.py
40
app/views.py
|
|
@ -1,19 +1,21 @@
|
||||||
import os
|
import os
|
||||||
import openpyxl as openpyxl
|
import logging
|
||||||
|
|
||||||
|
# 第三方库
|
||||||
|
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.time_utils import check_now_time
|
||||||
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
|
|
||||||
from datetime import datetime
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
app = Flask(__name__, static_folder='static')
|
app = Flask(__name__, static_folder='static')
|
||||||
app.secret_key = SECRET_KEY # 从配置文件设置
|
app.secret_key = SECRET_KEY # 从配置文件设置
|
||||||
|
|
@ -245,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
|
||||||
|
|
@ -315,7 +318,8 @@ def get_course_name():
|
||||||
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
|
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
|
||||||
|
|
||||||
# 获取今天是星期几
|
# 获取今天是星期几
|
||||||
day_of_week = datetime.date.today().weekday() + 1
|
now = datetime.now()
|
||||||
|
day_of_week = now.weekday() + 1
|
||||||
|
|
||||||
# 如果是周末
|
# 如果是周末
|
||||||
if not (1 <= day_of_week <= 5):
|
if not (1 <= day_of_week <= 5):
|
||||||
|
|
@ -358,7 +362,8 @@ def student_get_today_courses():
|
||||||
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
|
return jsonify({"msg": "用户未登录或编号不可用", "data": None})
|
||||||
|
|
||||||
# 获取今天是星期几
|
# 获取今天是星期几
|
||||||
day_of_week = datetime.date.today().weekday() + 1
|
now = datetime.now() # 获取当前时间
|
||||||
|
day_of_week = now.weekday() + 1
|
||||||
|
|
||||||
# 如果是周末
|
# 如果是周末
|
||||||
if not (1 <= day_of_week <= 5):
|
if not (1 <= day_of_week <= 5):
|
||||||
|
|
@ -374,5 +379,22 @@ def student_get_today_courses():
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/teacher-sign-in', methods=['POST'])
|
||||||
|
def teacher_sign_in():
|
||||||
|
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)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|
|
||||||
|
|
@ -31,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,))
|
||||||
|
|
@ -76,12 +92,14 @@ class DatabaseManager:
|
||||||
def get_current_teacher_courses(self, teacher_number):
|
def get_current_teacher_courses(self, teacher_number):
|
||||||
# 使用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
|
||||||
|
|
@ -128,6 +146,7 @@ WHERE
|
||||||
return self.execute(sql, data)
|
return self.execute(sql, data)
|
||||||
|
|
||||||
def get_course_name(self, student_number, day_of_week, period_id):
|
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
|
# 从student表获取class_name
|
||||||
sql_student = "SELECT class_name FROM student WHERE student_number = %s;"
|
sql_student = "SELECT class_name FROM student WHERE student_number = %s;"
|
||||||
class_name = self.fetch(sql_student, (student_number,))[0]['class_name']
|
class_name = self.fetch(sql_student, (student_number,))[0]['class_name']
|
||||||
|
|
@ -189,3 +208,26 @@ WHERE
|
||||||
time = get_time_by_ids(id)
|
time = get_time_by_ids(id)
|
||||||
data.append({"course_name": course_name, "time": time})
|
data.append({"course_name": course_name, "time": time})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def teacher_sign_in(self, course_id, course_name, class_name, major_id, date, status):
|
||||||
|
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))
|
||||||
|
|
||||||
|
# 检查是否有学生编号被返回
|
||||||
|
if student_sql_result:
|
||||||
|
values_list = []
|
||||||
|
for student in student_sql_result:
|
||||||
|
# 对于每个学生编号,创建一条记录的值元组
|
||||||
|
student_number = student['student_number']
|
||||||
|
values_list.append((student_number, course_id, course_name, date, status))
|
||||||
|
|
||||||
|
# 构建一次性插入多条记录的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(result)
|
||||||
|
return {"msg": "班级签到成功,签到人数:" + str(result)}
|
||||||
|
else:
|
||||||
|
# 如果没有学生编号,可能需要处理错误或记录日志
|
||||||
|
return {"msg": "当前班级专业没有学生"}
|
||||||
|
|
|
||||||
Reference in New Issue