feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
201
backend/app/api/v1/knowledge_analysis.py
Normal file
201
backend/app/api/v1/knowledge_analysis.py
Normal file
@@ -0,0 +1,201 @@
|
||||
"""
|
||||
知识点分析 API
|
||||
|
||||
使用 Python 原生 AI 服务实现
|
||||
"""
|
||||
import logging
|
||||
from typing import Dict, Any
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.deps import get_db, get_current_user
|
||||
from app.schemas.base import ResponseModel
|
||||
from app.models.user import User
|
||||
from app.services.course_service import course_service
|
||||
from app.services.ai.knowledge_analysis_v2 import knowledge_analysis_service_v2
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/courses/{course_id}/materials/{material_id}/analyze", response_model=ResponseModel[Dict[str, Any]])
|
||||
async def analyze_material_knowledge_points(
|
||||
course_id: int,
|
||||
material_id: int,
|
||||
background_tasks: BackgroundTasks,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
分析单个资料的知识点
|
||||
|
||||
- **course_id**: 课程ID
|
||||
- **material_id**: 资料ID
|
||||
|
||||
使用 Python 原生 AI 服务:
|
||||
- 本地 AI 服务调用(4sapi.com 首选,OpenRouter 备选)
|
||||
- 多层 JSON 解析兜底
|
||||
- 无外部平台依赖,更稳定
|
||||
"""
|
||||
try:
|
||||
# 验证课程是否存在
|
||||
course = await course_service.get_by_id(db, course_id)
|
||||
if not course:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"课程 {course_id} 不存在"
|
||||
)
|
||||
|
||||
# 获取资料信息
|
||||
materials = await course_service.get_course_materials(db, course_id=course_id)
|
||||
material = next((m for m in materials if m.id == material_id), None)
|
||||
if not material:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"资料 {material_id} 不存在"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"准备启动知识点分析 - course_id: {course_id}, material_id: {material_id}, "
|
||||
f"file_url: {material.file_url}, user_id: {current_user.id}"
|
||||
)
|
||||
|
||||
# 调用 Python 原生知识点分析服务
|
||||
result = await knowledge_analysis_service_v2.analyze_course_material(
|
||||
db=db,
|
||||
course_id=course_id,
|
||||
material_id=material_id,
|
||||
file_url=material.file_url,
|
||||
course_title=course.name,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"知识点分析完成 - course_id: {course_id}, material_id: {material_id}, "
|
||||
f"knowledge_points: {result.get('knowledge_points_count', 0)}, "
|
||||
f"provider: {result.get('ai_provider')}"
|
||||
)
|
||||
|
||||
# 构建响应
|
||||
response_data = {
|
||||
"message": "知识点分析完成",
|
||||
"course_id": course_id,
|
||||
"material_id": material_id,
|
||||
"status": result.get("status", "completed"),
|
||||
"knowledge_points_count": result.get("knowledge_points_count", 0),
|
||||
"ai_provider": result.get("ai_provider"),
|
||||
"ai_model": result.get("ai_model"),
|
||||
"ai_tokens": result.get("ai_tokens"),
|
||||
"ai_latency_ms": result.get("ai_latency_ms"),
|
||||
}
|
||||
|
||||
return ResponseModel(
|
||||
data=response_data,
|
||||
message="知识点分析完成"
|
||||
)
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"知识点分析失败 - course_id: {course_id}, material_id: {material_id}, error: {e}",
|
||||
exc_info=True
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"知识点分析失败: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.post("/courses/{course_id}/reanalyze", response_model=ResponseModel[Dict[str, Any]])
|
||||
async def reanalyze_course_materials(
|
||||
course_id: int,
|
||||
background_tasks: BackgroundTasks,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
重新分析课程的所有资料
|
||||
|
||||
- **course_id**: 课程ID
|
||||
|
||||
该接口会重新分析课程下的所有资料,提取知识点
|
||||
"""
|
||||
try:
|
||||
# 验证课程是否存在
|
||||
course = await course_service.get_by_id(db, course_id)
|
||||
if not course:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"课程 {course_id} 不存在"
|
||||
)
|
||||
|
||||
# 获取课程资料信息
|
||||
materials = await course_service.get_course_materials(db, course_id=course_id)
|
||||
|
||||
if not materials:
|
||||
return ResponseModel(
|
||||
data={
|
||||
"message": "该课程暂无资料需要分析",
|
||||
"course_id": course_id,
|
||||
"status": "stopped",
|
||||
"materials_count": 0
|
||||
},
|
||||
message="无资料需要分析"
|
||||
)
|
||||
|
||||
# 调用 Python 原生知识点分析服务
|
||||
result = await knowledge_analysis_service_v2.reanalyze_course_materials(
|
||||
db=db,
|
||||
course_id=course_id,
|
||||
course_title=course.name,
|
||||
user_id=current_user.id
|
||||
)
|
||||
|
||||
return ResponseModel(
|
||||
data={
|
||||
"message": "课程资料重新分析完成",
|
||||
"course_id": course_id,
|
||||
"status": "completed",
|
||||
"materials_count": result.get("materials_count", 0),
|
||||
"success_count": result.get("success_count", 0),
|
||||
"knowledge_points_count": result.get("knowledge_points_count", 0),
|
||||
"analysis_results": result.get("analysis_results", [])
|
||||
},
|
||||
message="重新分析完成"
|
||||
)
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"启动课程资料重新分析失败 - course_id: {course_id}, error: {e}",
|
||||
exc_info=True
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="启动重新分析失败"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/engines", response_model=ResponseModel[Dict[str, Any]])
|
||||
async def list_analysis_engines():
|
||||
"""
|
||||
获取可用的分析引擎列表
|
||||
"""
|
||||
return ResponseModel(
|
||||
data={
|
||||
"engines": [
|
||||
{
|
||||
"id": "native",
|
||||
"name": "Python 原生实现",
|
||||
"description": "使用本地 AI 服务(4sapi.com + OpenRouter),稳定可靠",
|
||||
"default": True
|
||||
}
|
||||
],
|
||||
"default_engine": "native"
|
||||
},
|
||||
message="获取分析引擎列表成功"
|
||||
)
|
||||
Reference in New Issue
Block a user