Some checks failed
continuous-integration/drone/push Build is failing
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 格式
158 lines
4.3 KiB
Python
158 lines
4.3 KiB
Python
"""
|
|
智能学习推荐 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,
|
|
}
|
|
}
|