Files
SharedClassManager/backend/routes/admin.py
2026-04-09 15:17:47 +08:00

374 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ===========================================
# 班级操行分管理系统 - 管理端路由
#
# 开发者: Canglan
# 联系方式: admin@sea-studio.top
# 版权归属: Sea Network Technology Studio
# 许可证: MIT License
#
# 版权所有 © Sea Network Technology Studio
# ===========================================
from fastapi import APIRouter, Request, Query, UploadFile, File
from typing import Optional, List
import json
from middleware.permission import (
get_current_user,
require_teacher,
require_monitor,
PermissionChecker
)
from services.admin_service import AdminService
from services.conduct_service import ConductService
from services.homework_service import HomeworkService
from services.attendance_service import AttendanceService
from schemas.admin import (
AddPointsRequest, RevokeRequest, AddAdminRequest,
UpdateHomeworkStatusRequest, AddAttendanceRequest
)
from utils.response import success_response, error_response, paginated_response
from utils.logger import get_logger
from config import settings
router = APIRouter()
logger = get_logger(__name__)
# ========== 学生管理 ==========
@router.get("/students")
async def get_students(
request: Request,
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100),
search: Optional[str] = None
):
"""
获取所有学生列表(单班级)
"""
user = await get_current_user(request)
result = await AdminService.get_students(
page=page,
page_size=page_size,
search=search
)
return success_response(data=result)
@router.post("/students/import")
async def import_students(
request: Request,
file: UploadFile = File(...)
):
"""
批量导入学生JSON格式
初始操行分默认为60分
"""
user = await get_current_user(request)
# 检查权限(仅班主任)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher:
return error_response(message="仅班主任可导入学生", code=403)
# 检查文件大小
content = await file.read()
file_size = len(content)
if file_size > settings.MAX_UPLOAD_SIZE:
return error_response(message=f"文件大小不能超过{settings.MAX_UPLOAD_SIZE // 1024 // 1024}MB")
# 检查文件扩展名
filename = file.filename or ""
extension = filename.split('.')[-1].lower() if '.' in filename else ''
if extension not in settings.ALLOWED_EXTENSIONS:
return error_response(message=f"不支持的文件类型,仅支持 {', '.join(settings.ALLOWED_EXTENSIONS)}")
# 解析JSON
try:
data = json.loads(content.decode('utf-8'))
students = data.get("students", [])
except json.JSONDecodeError as e:
return error_response(message=f"JSON格式错误: {str(e)}")
except UnicodeDecodeError:
return error_response(message="文件编码错误请使用UTF-8编码")
if not students:
return error_response(message="文件中没有学生数据")
# 导入学生初始操行分60分
result = await AdminService.import_students(
students=students,
operator_id=user["user_id"],
initial_points=60
)
return success_response(data=result, message=f"导入完成: 成功{result['success_count']}人,失败{result['failed_count']}")
@router.post("/students")
async def add_student(
request: Request,
student_no: str,
name: str,
parent_phone: Optional[str] = None
):
"""
新增学生
"""
user = await get_current_user(request)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher:
return error_response(message="仅班主任可新增学生", code=403)
result = await AdminService.add_student(
student_no=student_no,
name=name,
parent_phone=parent_phone,
operator_id=user["user_id"],
initial_points=60
)
if result["success"]:
return success_response(data=result, message="学生添加成功")
else:
return error_response(message=result["message"])
# ========== 操行分管理 ==========
@router.post("/conduct/add")
async def add_conduct_points(request: Request, req: AddPointsRequest):
"""
批量加减分
"""
user = await get_current_user(request)
result = await ConductService.add_points(
student_ids=req.student_ids,
points_change=req.points_change,
reason=req.reason,
recorder_id=user["user_id"],
recorder_name=user["username"]
)
if result["success"]:
return success_response(data=result, message="操作成功")
else:
return error_response(message=result["message"])
@router.post("/conduct/revoke")
async def revoke_conduct_record(request: Request, req: RevokeRequest):
"""
撤销扣分记录
"""
user = await get_current_user(request)
result = await ConductService.revoke_record(
record_id=req.record_id,
revoker_id=user["user_id"]
)
if result["success"]:
return success_response(message="撤销成功")
else:
return error_response(message=result["message"])
@router.get("/conduct/history")
async def get_conduct_history(
request: Request,
student_id: Optional[int] = None,
page: int = Query(1, ge=1),
page_size: int = Query(20, ge=1, le=100),
start_date: Optional[str] = None,
end_date: Optional[str] = None
):
"""
获取操行分历史记录
"""
user = await get_current_user(request)
result = await ConductService.get_history(
user_id=user["user_id"],
student_id=student_id,
page=page,
page_size=page_size,
start_date=start_date,
end_date=end_date
)
return success_response(data=result)
# ========== 作业管理 ==========
@router.get("/homework/assignments")
async def get_assignments(request: Request):
"""
获取作业列表
"""
user = await get_current_user(request)
result = await HomeworkService.get_assignments(user["user_id"])
return success_response(data=result)
@router.get("/homework/submissions/{assignment_id}")
async def get_submissions(request: Request, assignment_id: int):
"""
获取作业提交记录
"""
user = await get_current_user(request)
result = await HomeworkService.get_submissions(
assignment_id=assignment_id,
user_id=user["user_id"]
)
return success_response(data=result)
@router.post("/homework/assignment")
async def create_assignment(
request: Request,
subject_id: int,
title: str,
description: Optional[str] = None,
deadline: str = None
):
"""
发布作业(班主任)
"""
user = await get_current_user(request)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher:
return error_response(message="仅班主任可发布作业", code=403)
result = await HomeworkService.create_assignment(
subject_id=subject_id,
title=title,
description=description,
deadline=deadline,
created_by=user["user_id"]
)
if result["success"]:
return success_response(data=result, message="作业发布成功")
else:
return error_response(message=result["message"])
@router.put("/homework/submission")
async def update_submission_status(request: Request, req: UpdateHomeworkStatusRequest):
"""
更新作业提交状态(科代表)
"""
user = await get_current_user(request)
result = await HomeworkService.update_submission_status(
submission_id=req.submission_id,
status=req.status,
comments=req.comments,
apply_deduction=req.apply_deduction,
operator_id=user["user_id"]
)
if result["success"]:
return success_response(message="状态更新成功")
else:
return error_response(message=result["message"])
# ========== 考勤管理 ==========
@router.post("/attendance")
async def add_attendance(request: Request, req: AddAttendanceRequest):
"""
添加考勤记录(考勤委员)
"""
user = await get_current_user(request)
result = await AttendanceService.add_attendance(
student_id=req.student_id,
date=str(req.date),
status=req.status,
reason=req.reason,
apply_deduction=req.apply_deduction,
recorder_id=user["user_id"]
)
if result["success"]:
return success_response(message="考勤记录添加成功")
else:
return error_response(message=result["message"])
@router.get("/attendance/records")
async def get_attendance_records(
request: Request,
date: Optional[str] = None,
student_id: Optional[int] = None
):
"""
获取考勤记录
"""
user = await get_current_user(request)
result = await AttendanceService.get_records(
user_id=user["user_id"],
date=date,
student_id=student_id
)
return success_response(data=result)
# ========== 管理员管理 ==========
@router.post("/admin/add")
async def add_admin(request: Request, req: AddAdminRequest):
"""
添加管理员(班主任)
"""
user = await get_current_user(request)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher:
return error_response(message="仅班主任可添加管理员", code=403)
result = await AdminService.add_admin(
username=req.username,
real_name=req.real_name,
password=req.password,
role_type=req.role_type,
operator_id=user["user_id"]
)
if result["success"]:
return success_response(data=result, message="管理员添加成功")
else:
return error_response(message=result["message"])
@router.get("/admin/list")
async def get_admins(request: Request):
"""
获取管理员列表(班主任)
"""
user = await get_current_user(request)
is_teacher = await PermissionChecker.check_is_teacher(user["user_id"])
if not is_teacher:
return error_response(message="仅班主任可查看管理员列表", code=403)
result = await AdminService.get_admins()
return success_response(data=result)