Commit 7133e3a8 authored by uuo00_n's avatar uuo00_n

feat(仪表盘): 添加教师周课表查询功能

实现教师端周课表查询接口,包含相关数据模型和服务逻辑
- 新增 TeacherWeekScheduleItem 和 TeacherWeekSummary 数据模型
- 添加 teacher_week_schedule 服务函数处理教师课表查询
- 实现 /teacher/week API 端点,支持周次参数和权限验证
parent befb2764
...@@ -5,6 +5,7 @@ from app.api.deps import require_edition_for_mode, require_role, require_binding ...@@ -5,6 +5,7 @@ from app.api.deps import require_edition_for_mode, require_role, require_binding
from app.services.dashboard import ( from app.services.dashboard import (
student_today_summary, student_today_summary,
student_week_schedule, student_week_schedule,
teacher_week_schedule,
homeroom_current_summary, homeroom_current_summary,
department_overview, department_overview,
campus_overview, campus_overview,
...@@ -50,6 +51,20 @@ class StudentWeekSummary(BaseModel): ...@@ -50,6 +51,20 @@ class StudentWeekSummary(BaseModel):
week_dates: Dict[int, str] week_dates: Dict[int, str]
schedule: Dict[str, List[StudentWeekScheduleItem]] schedule: Dict[str, List[StudentWeekScheduleItem]]
class TeacherWeekScheduleItem(BaseModel):
lesson_id: Optional[str] = None
period: Optional[int] = None
course_name: Optional[str] = None
classes: List[Dict[str, Optional[str]]] = []
start_time: Optional[str] = None
end_time: Optional[str] = None
class TeacherWeekSummary(BaseModel):
teacher: Dict[str, Optional[str]]
current_week: int
week_dates: Dict[int, str]
schedule: Dict[str, List[TeacherWeekScheduleItem]]
class HomeroomLesson(BaseModel): class HomeroomLesson(BaseModel):
class_id: Optional[str] class_id: Optional[str]
course_name: Optional[str] course_name: Optional[str]
...@@ -131,6 +146,23 @@ async def student_week( ...@@ -131,6 +146,23 @@ async def student_week(
) -> StudentWeekSummary: ) -> StudentWeekSummary:
return await student_week_schedule(current_user, week) return await student_week_schedule(current_user, week)
@router.get(
"/teacher/week",
summary="教师端:周课表查询",
description="需角色等级≥2且主绑定为教师;返回指定周次(默认当前周)的任课课表(包含上课班级与地点)。",
response_model=TeacherWeekSummary,
responses={
401: {"description": "未认证", "content": {"application/json": {"example": {"detail": "无效的认证凭据"}}}},
403: {"description": "权限不足或未绑定教师", "content": {"application/json": {"example": {"detail": "实体绑定不存在或类型不匹配"}}}},
}
)
async def teacher_week(
week: Optional[int] = Query(None, description="周次(如 1, 2, ...),不传则默认为当前周"),
current_user: dict = Depends(require_role(2)),
_b: dict = Depends(require_binding("teacher"))
) -> TeacherWeekSummary:
return await teacher_week_schedule(current_user, week)
@router.get( @router.get(
"/homeroom/current", "/homeroom/current",
summary="班主任端:当前节次课程与地点、出勤率、请假、指示", summary="班主任端:当前节次课程与地点、出勤率、请假、指示",
......
...@@ -191,6 +191,82 @@ async def student_week_schedule(current_user: Dict[str, Any], week: int = None) ...@@ -191,6 +191,82 @@ async def student_week_schedule(current_user: Dict[str, Any], week: int = None)
"schedule": schedules_by_day "schedule": schedules_by_day
} }
async def teacher_week_schedule(current_user: Dict[str, Any], week: int = None) -> Dict[str, Any]:
if week is None:
week = await _get_current_week()
binding = await _get_primary_binding(current_user["_id"])
if binding.get("type") != "teacher":
raise HTTPException(status_code=403, detail="当前绑定非教师")
teacher = await _get_teacher_entity(current_user["_id"], binding)
teacher_person_id = teacher.get("person_id")
# 确保类型匹配
if isinstance(teacher_person_id, str) and ObjectId.is_valid(teacher_person_id):
teacher_person_id = ObjectId(teacher_person_id)
try:
start_date = datetime.strptime(settings.TERM_START_DATE, "%Y-%m-%d").date()
monday_of_week = start_date + timedelta(weeks=week-1)
except:
monday_of_week = datetime.now().date()
week_dates = {}
for i in range(1, 8):
d = monday_of_week + timedelta(days=i-1)
week_dates[i] = d.isoformat()
schedules_by_day = {str(i): [] for i in range(1, 8)}
# 查询该教师的所有课程
# 注意:teacher_person_id 在 schedules 中可能是 ObjectId 也可能是字符串,视具体数据而定
# 为稳妥起见,如果 teacher_person_id 是 ObjectId,也可以尝试转字符串匹配,或者由数据库层面保证一致性
# 这里我们使用 $in 查询来兼容
query_ids = [teacher_person_id]
if isinstance(teacher_person_id, ObjectId):
query_ids.append(str(teacher_person_id))
cursor = db.db.schedules.find({"teacher_person_id": {"$in": query_ids}}).sort("period", 1)
async for doc in cursor:
w_range = doc.get("week_range", "")
if not _is_week_valid(week, w_range):
continue
wd = doc.get("weekday")
# 提取班级和地点信息
classes_info = []
for c in doc.get("classes", []):
classes_info.append({
"class_id": c.get("class_id"),
"location": c.get("location")
})
item = {
"lesson_id": doc.get("lesson_id"),
"period": doc.get("period"),
"course_name": doc.get("course_name"),
"classes": classes_info,
"start_time": doc.get("start_time"),
"end_time": doc.get("end_time")
}
if str(wd) in schedules_by_day:
schedules_by_day[str(wd)].append(item)
return {
"teacher": {
"teacher_id": teacher.get("teacher_id"),
"name": teacher.get("name"), # 注意:teacher表可能没有name,通常在person表
"person_id": str(teacher.get("person_id"))
},
"current_week": week,
"week_dates": week_dates,
"schedule": schedules_by_day
}
async def homeroom_current_summary(current_user: Dict[str, Any]) -> Dict[str, Any]: async def homeroom_current_summary(current_user: Dict[str, Any]) -> Dict[str, Any]:
today = await _today_iso() today = await _today_iso()
weekday = await _weekday() weekday = await _weekday()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment