Files
LoveACE-EndF/router/jwc/plan_completion.py

183 lines
6.5 KiB
Python
Raw Normal View History

2025-09-07 16:46:31 +08:00
from fastapi import APIRouter, Depends
from typing import Optional
from loguru import logger
from provider.aufe.jwc import JWCClient
from provider.aufe.jwc.depends import get_jwc_client
from provider.loveac.authme import AuthmeResponse
from provider.aufe.jwc.plan_completion_model import (
PlanCompletionInfo,
ErrorPlanCompletionInfo,
)
from provider.aufe.jwc.semester_week_model import (
SemesterWeekInfo,
ErrorSemesterWeekInfo,
)
from router.common_model import BaseResponse, ErrorResponse
router = APIRouter(prefix="/plan-completion", tags=["培养方案完成情况"])
class PlanCompletionInfoResponse(BaseResponse):
"""培养方案完成情况响应模型"""
data: Optional[PlanCompletionInfo] = None
@classmethod
def from_data(
cls,
data: PlanCompletionInfo,
success_message: str = "success",
error_message: str = "请求失败",
) -> "PlanCompletionInfoResponse":
"""根据数据创建响应"""
if isinstance(data, ErrorPlanCompletionInfo) or data.total_courses == -1:
return cls(code=-1, message=error_message, data=None)
return cls(code=0, message=success_message, data=data)
@router.post(
"/fetch_plan_completion_info",
summary="获取培养方案完成情况",
response_model=PlanCompletionInfoResponse | AuthmeResponse | ErrorResponse,
)
async def fetch_plan_completion_info(client: JWCClient = Depends(get_jwc_client)):
"""
获取培养方案完成情况信息
返回数据包括
- 培养方案基本信息名称专业年级
- 各分类的完成情况通识通修专业课等
- 每门课程的详细状态已通过未通过未修读
- 统计信息总课程数通过数等
"""
try:
result = await client.fetch_plan_completion_info()
# 检查是否是AuthmeResponse认证错误
if isinstance(result, AuthmeResponse):
return result
# 使用新的错误检测机制
response = PlanCompletionInfoResponse.from_data(
data=result,
success_message="培养方案完成情况获取成功",
error_message="获取培养方案完成情况失败,网络请求多次重试后仍无法连接教务系统,请稍后重试或联系管理员",
)
return response
except Exception as e:
logger.error(f"获取培养方案完成情况异常: {str(e)}")
return ErrorResponse(message=f"获取培养方案完成情况时发生系统错误:{str(e)}", code=500)
@router.post(
"/fetch_plan_completion_statistics",
summary="获取培养方案完成统计",
response_model=BaseResponse | AuthmeResponse | ErrorResponse,
)
async def fetch_plan_completion_statistics(client: JWCClient = Depends(get_jwc_client)):
"""
获取培养方案完成情况统计信息
返回简化的统计数据包括
- 总分类数
- 总课程数
- 已通过课程数
- 未通过课程数
- 未修读课程数
- 完成率
"""
try:
result = await client.fetch_plan_completion_info()
# 检查是否是AuthmeResponse认证错误
if isinstance(result, AuthmeResponse):
return result
# 检查是否是错误结果
if isinstance(result, ErrorPlanCompletionInfo) or result.total_courses == -1:
return BaseResponse(
code=-1,
message="获取培养方案统计信息失败,网络请求多次重试后仍无法连接教务系统,请稍后重试或联系管理员",
data=None
)
# 构建统计数据
statistics = {
"plan_name": result.plan_name,
"major": result.major,
"grade": result.grade,
"total_categories": result.total_categories,
"total_courses": result.total_courses,
"passed_courses": result.passed_courses,
"failed_courses": result.failed_courses,
"unread_courses": result.unread_courses,
"completion_rate": round(
result.passed_courses / result.total_courses * 100, 2
) if result.total_courses > 0 else 0.0
}
return BaseResponse(
code=0,
message="培养方案统计信息获取成功",
data=statistics
)
except Exception as e:
logger.error(f"获取培养方案统计信息异常: {str(e)}")
return ErrorResponse(message=f"获取培养方案统计信息时发生系统错误:{str(e)}", code=500)
class SemesterWeekInfoResponse(BaseResponse):
"""学期周数信息响应模型"""
data: Optional[SemesterWeekInfo] = None
@classmethod
def from_data(
cls,
data: SemesterWeekInfo,
success_message: str = "success",
error_message: str = "请求失败",
) -> "SemesterWeekInfoResponse":
"""根据数据创建响应"""
if isinstance(data, ErrorSemesterWeekInfo) or data.week_number == -1:
return cls(code=-1, message=error_message, data=None)
return cls(code=0, message=success_message, data=data)
@router.post("/fetch_semester_week_info", response_model=SemesterWeekInfoResponse, summary="获取学期周数信息")
async def fetch_semester_week_info(
jwc_client: JWCClient = Depends(get_jwc_client)
) -> SemesterWeekInfoResponse:
"""
获取当前学期周数信息
需要认证返回当前学期周数是否结束等信息
"""
try:
logger.info("开始获取学期周数信息")
result = await jwc_client.fetch_semester_week_info()
if isinstance(result, ErrorSemesterWeekInfo) or result.week_number == -1:
logger.warning("获取学期周数信息失败")
return SemesterWeekInfoResponse.from_data(
result,
error_message="获取学期周数信息失败,请稍后重试"
)
logger.info(f"学期周数信息获取成功: {result.academic_year} {result.semester}{result.week_number}")
return SemesterWeekInfoResponse.from_data(
result,
success_message="学期周数信息获取成功"
)
except Exception as e:
logger.error(f"获取学期周数信息异常: {str(e)}")
return SemesterWeekInfoResponse(
code=500,
message=f"获取学期周数信息时发生系统错误:{str(e)}",
data=None
)