1. 课程学习进度追踪
- 新增 UserCourseProgress 和 UserMaterialProgress 模型
- 新增 /api/v1/progress/* 进度追踪 API
- 更新 admin.py 使用真实课程完成率数据
2. 路由权限检查完善
- 新增前端 permissionChecker.ts 权限检查工具
- 更新 router/guard.ts 实现团队和课程权限验证
- 新增后端 permission_service.py
3. AI 陪练音频转文本
- 新增 speech_recognition.py 语音识别服务
- 新增 /api/v1/speech/* API
- 更新 ai-practice-coze.vue 支持语音输入
4. 双人对练报告生成
- 更新 practice_room_service.py 添加报告生成功能
- 新增 /rooms/{room_code}/report API
- 更新 duo-practice-report.vue 调用真实 API
5. 学习提醒推送
- 新增 notification_service.py 通知服务
- 新增 scheduler_service.py 定时任务服务
- 支持钉钉、企微、站内消息推送
6. 智能学习推荐
- 新增 recommendation_service.py 推荐服务
- 新增 /api/v1/recommendations/* API
- 支持错题、能力、进度、热门多维度推荐
7. 安全问题修复
- DEBUG 默认值改为 False
- 添加 SECRET_KEY 安全警告
- 新增 check_security_settings() 检查函数
8. 证书 PDF 生成
- 更新 certificate_service.py 添加 PDF 生成
- 添加 weasyprint、Pillow、qrcode 依赖
- 更新下载 API 支持 PDF 和 PNG 格式
This commit is contained in:
157
backend/app/api/v1/endpoints/recommendation.py
Normal file
157
backend/app/api/v1/endpoints/recommendation.py
Normal file
@@ -0,0 +1,157 @@
|
||||
"""
|
||||
智能学习推荐 API
|
||||
"""
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.api.deps import get_current_user
|
||||
from app.models.user import User
|
||||
from app.services.recommendation_service import RecommendationService
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
# ============ Schemas ============
|
||||
|
||||
class CourseRecommendation(BaseModel):
|
||||
"""课程推荐响应"""
|
||||
course_id: int
|
||||
course_name: str
|
||||
category: Optional[str] = None
|
||||
cover_image: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
progress_percent: Optional[float] = None
|
||||
student_count: Optional[int] = None
|
||||
source: Optional[str] = None
|
||||
reason: Optional[str] = None
|
||||
|
||||
|
||||
class KnowledgePointRecommendation(BaseModel):
|
||||
"""知识点推荐响应"""
|
||||
knowledge_point_id: int
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
type: Optional[str] = None
|
||||
course_id: int
|
||||
mistake_count: Optional[int] = None
|
||||
reason: Optional[str] = None
|
||||
|
||||
|
||||
class RecommendationResponse(BaseModel):
|
||||
"""推荐响应"""
|
||||
code: int = 200
|
||||
message: str = "success"
|
||||
data: dict
|
||||
|
||||
|
||||
# ============ API Endpoints ============
|
||||
|
||||
@router.get("/courses", response_model=RecommendationResponse)
|
||||
async def get_course_recommendations(
|
||||
limit: int = Query(10, ge=1, le=50, description="推荐数量"),
|
||||
include_reasons: bool = Query(True, description="是否包含推荐理由"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""
|
||||
获取个性化课程推荐
|
||||
|
||||
推荐策略:
|
||||
- 基于错题分析推荐相关课程
|
||||
- 基于能力评估推荐弱项课程
|
||||
- 基于学习进度推荐未完成课程
|
||||
- 基于热门程度推荐高人气课程
|
||||
"""
|
||||
service = RecommendationService(db)
|
||||
recommendations = await service.get_recommendations(
|
||||
user_id=current_user.id,
|
||||
limit=limit,
|
||||
include_reasons=include_reasons,
|
||||
)
|
||||
|
||||
return RecommendationResponse(
|
||||
code=200,
|
||||
message="获取推荐成功",
|
||||
data={
|
||||
"recommendations": recommendations,
|
||||
"total": len(recommendations),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/knowledge-points", response_model=RecommendationResponse)
|
||||
async def get_knowledge_point_recommendations(
|
||||
limit: int = Query(5, ge=1, le=20, description="推荐数量"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""
|
||||
获取知识点复习推荐
|
||||
|
||||
基于错题记录推荐需要重点复习的知识点
|
||||
"""
|
||||
service = RecommendationService(db)
|
||||
recommendations = await service.get_knowledge_point_recommendations(
|
||||
user_id=current_user.id,
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
return RecommendationResponse(
|
||||
code=200,
|
||||
message="获取推荐成功",
|
||||
data={
|
||||
"recommendations": recommendations,
|
||||
"total": len(recommendations),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/summary")
|
||||
async def get_recommendation_summary(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""
|
||||
获取推荐摘要
|
||||
|
||||
返回各类推荐的概要信息
|
||||
"""
|
||||
service = RecommendationService(db)
|
||||
|
||||
# 获取各类推荐
|
||||
all_recs = await service.get_recommendations(
|
||||
user_id=current_user.id,
|
||||
limit=20,
|
||||
include_reasons=True,
|
||||
)
|
||||
|
||||
# 按来源分类统计
|
||||
source_counts = {}
|
||||
for rec in all_recs:
|
||||
source = rec.get("source", "other")
|
||||
source_counts[source] = source_counts.get(source, 0) + 1
|
||||
|
||||
# 获取知识点推荐
|
||||
kp_recs = await service.get_knowledge_point_recommendations(
|
||||
user_id=current_user.id,
|
||||
limit=5,
|
||||
)
|
||||
|
||||
return {
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"total_recommendations": len(all_recs),
|
||||
"source_breakdown": {
|
||||
"mistake_based": source_counts.get("mistake", 0),
|
||||
"ability_based": source_counts.get("ability", 0),
|
||||
"progress_based": source_counts.get("progress", 0),
|
||||
"popular": source_counts.get("popular", 0),
|
||||
},
|
||||
"weak_knowledge_points": len(kp_recs),
|
||||
"top_recommendation": all_recs[0] if all_recs else None,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user