v2.2更新

This commit is contained in:
2026-05-28 15:38:32 +08:00
parent f84c9d3efb
commit ca53fdc349
38 changed files with 688 additions and 686 deletions

View File

@@ -27,14 +27,15 @@ class AdminService:
async def get_students(
page: int = 1,
page_size: int = 20,
search: str = None
search: str = None,
dormitory_number: str = None
) -> Dict[str, Any]:
"""获取所有学生列表"""
offset = (page - 1) * page_size
sql = """
SELECT student_id, student_no, name, total_points, parent_phone, status
FROM students
SELECT student_id, student_no, name, total_points, parent_phone, dormitory_number, status
FROM students
WHERE status = 1
"""
params = []
@@ -43,6 +44,10 @@ class AdminService:
sql += " AND (student_no LIKE %s OR name LIKE %s)"
params.extend([f"%{search}%", f"%{search}%"])
if dormitory_number:
sql += " AND dormitory_number = %s"
params.append(dormitory_number)
sql += " ORDER BY student_no LIMIT %s OFFSET %s"
params.extend([page_size, offset])
@@ -50,12 +55,17 @@ class AdminService:
# 获取总数
count_sql = "SELECT COUNT(*) as total FROM students WHERE status = 1"
count_params = []
if search:
count_sql += " AND (student_no LIKE %s OR name LIKE %s)"
total_result = await execute_one(count_sql, (f"%{search}%", f"%{search}%"))
count_params.extend([f"%{search}%", f"%{search}%"])
if dormitory_number:
count_sql += " AND dormitory_number = %s"
count_params.append(dormitory_number)
if count_params:
total_result = await execute_one(count_sql, tuple(count_params))
else:
total_result = await execute_one(count_sql)
total = total_result["total"] if total_result else 0
return {

View File

@@ -235,6 +235,7 @@ class ConductService:
student_id=student_id,
start_date=start_date,
end_date=end_date,
related_type=related_type,
page=page,
page_size=page_size
)

View File

@@ -1,135 +0,0 @@
# ===========================================
# 班级操行分管理系统 - 后端服务
#
# 开发者: Canglan
# 联系方式: admin@sea-studio.top
# 版权归属: Sea Network Technology Studio
# 许可证: MIT License
#
# 版权所有 © Sea Network Technology Studio
# ===========================================
from typing import Dict, Any, List, Optional
from datetime import datetime
from models.homework import HomeworkModel
from models.student import StudentModel
from models.conduct import ConductModel
from middleware.permission import PermissionChecker
from config import settings
from utils.logger import get_logger
logger = get_logger(__name__)
class HomeworkService:
"""作业服务"""
@staticmethod
async def get_assignments(user_id: int) -> Dict[str, Any]:
"""获取作业列表"""
role = await PermissionChecker.get_user_role(user_id)
if role == "班主任":
assignments = await HomeworkModel.get_all_assignments()
elif role == "学习委员":
subject_ids = await PermissionChecker.get_user_subject_ids(user_id)
assignments = await HomeworkModel.get_assignments_by_subjects(subject_ids)
else:
assignments = []
return {"assignments": assignments}
@staticmethod
async def create_assignment(
subject_id: int,
title: str,
description: Optional[str],
deadline: str,
created_by: int
) -> Dict[str, Any]:
"""创建作业"""
assignment_id = await HomeworkModel.create_assignment(
subject_id=subject_id,
title=title,
description=description,
deadline=deadline,
created_by=created_by
)
if assignment_id:
logger.info(f"用户[{created_by}] 创建作业[{assignment_id}]: {title}")
return {"success": True, "assignment_id": assignment_id}
else:
return {"success": False, "message": "创建作业失败"}
@staticmethod
async def update_submission_status(
submission_id: int,
status: str,
comments: Optional[str],
apply_deduction: bool,
operator_id: int
) -> Dict[str, Any]:
"""更新作业提交状态"""
# 获取提交记录信息
submission = await HomeworkModel.get_submission(submission_id)
if not submission:
return {"success": False, "message": "提交记录不存在"}
# 检查权限
role = await PermissionChecker.get_user_role(operator_id)
if role == "学习委员":
# 检查是否管理该科目
subject_ids = await PermissionChecker.get_user_subject_ids(operator_id)
if submission["subject_id"] not in subject_ids:
return {"success": False, "message": "无权操作此作业"}
elif role != "班主任":
return {"success": False, "message": "无权进行此操作"}
# 更新状态
result = await HomeworkModel.update_submission(
submission_id=submission_id,
status=status,
comments=comments,
updated_by=operator_id
)
if not result:
return {"success": False, "message": "更新失败"}
# 应用扣分
if apply_deduction and status in ["not_submitted", "late"]:
# 确定扣分数值
if status == "not_submitted":
points_change = -settings.DEDUCTION_HOMEWORK_NOT_SUBMIT
else:
points_change = -settings.DEDUCTION_HOMEWORK_LATE
# 创建扣分记录
student = await StudentModel.get_by_id(submission["student_id"])
if student:
# 获取操作人姓名
from models.user import UserModel
user = await UserModel.get_by_user_id(operator_id)
recorder_name = user.get("real_name", "班主任") if user else "班主任"
await ConductModel.create_record(
student_id=submission["student_id"],
points_change=points_change,
reason=f"作业未提交/迟交: {submission['title']}",
recorder_id=operator_id,
recorder_name=recorder_name,
related_type="homework",
related_id=submission["assignment_id"]
)
# 更新学生总分
await StudentModel.update_total_points(submission["student_id"], points_change)
# 标记已应用扣分
await HomeworkModel.mark_deduction_applied(submission_id)
logger.info(f"用户[{operator_id}] 更新作业提交状态[{submission_id}] -> {status}")
return {"success": True, "message": "状态更新成功"}

View File

@@ -15,7 +15,6 @@ from typing import Dict, Any, Optional, List
from models.user import UserModel
from models.student import StudentModel
from models.conduct import ConductModel
from models.homework import HomeworkModel
from models.attendance import AttendanceModel
from utils.logger import get_logger
@@ -46,24 +45,6 @@ class ParentService:
}
@staticmethod
async def get_child_homework(parent_id: int) -> Dict[str, Any]:
"""获取子女作业情况"""
user = await UserModel.get_by_user_id(parent_id)
if not user or not user["student_id"]:
return {"error": "未关联学生"}
student = await StudentModel.get_by_id(user["student_id"])
if not student:
return {"error": "学生不存在"}
homework = await HomeworkModel.get_student_homework(user["student_id"])
return {
"student_id": student["student_id"],
"student_name": student["name"],
"homework": homework
}
@staticmethod
async def get_child_attendance(parent_id: int) -> Dict[str, Any]:
"""获取子女考勤记录"""
user = await UserModel.get_by_user_id(parent_id)

View File

@@ -14,9 +14,9 @@ from datetime import datetime, timedelta
from models.student import StudentModel
from models.conduct import ConductModel
from models.homework import HomeworkModel
from models.attendance import AttendanceModel
from middleware.permission import PermissionChecker
from utils.database import execute_query
from utils.logger import get_logger
logger = get_logger(__name__)
@@ -57,29 +57,33 @@ class StudentService:
@staticmethod
async def get_homework_status(student_id: int) -> Dict[str, Any]:
"""获取学生作业情况"""
"""获取学生作业扣分记录"""
student = await StudentModel.get_by_id(student_id)
if not student:
return {"error": "学生不存在"}
homework = await HomeworkModel.get_student_homework(student_id)
# 查询作业相关的操行分记录
sql = """
SELECT cr.record_id, cr.points_change, cr.reason, cr.created_at,
cr.related_type, cr.recorder_name
FROM conduct_records cr
WHERE cr.student_id = %s AND cr.related_type = 'homework' AND cr.is_revoked = 0
ORDER BY cr.created_at DESC
"""
records = await execute_query(sql, (student_id,))
# 统计
total = len(homework)
submitted = sum(1 for h in homework if h["status"] == "submitted")
not_submitted = sum(1 for h in homework if h["status"] == "not_submitted")
late = sum(1 for h in homework if h["status"] == "late")
total = len(records)
deductions = sum(1 for r in records if r["points_change"] < 0)
return {
"student_id": student_id,
"student_name": student["name"],
"statistics": {
"total": total,
"submitted": submitted,
"not_submitted": not_submitted,
"late": late
"deductions": deductions
},
"homework": homework
"homework": records
}
@staticmethod