183 lines
6.5 KiB
Python
183 lines
6.5 KiB
Python
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
|
||
)
|