- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
140 lines
5.3 KiB
Python
140 lines
5.3 KiB
Python
"""
|
||
系统API - 供外部服务回调使用
|
||
"""
|
||
import logging
|
||
from typing import List, Dict, Any, Optional
|
||
|
||
from fastapi import APIRouter, Depends, HTTPException, status, Header
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from pydantic import BaseModel, Field
|
||
|
||
from app.core.deps import get_db
|
||
from app.schemas.base import ResponseModel
|
||
from app.schemas.course import KnowledgePointCreate
|
||
from app.services.course_service import knowledge_point_service, course_service
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
router = APIRouter(prefix="/system")
|
||
|
||
|
||
class KnowledgePointData(BaseModel):
|
||
"""知识点数据模型"""
|
||
name: str = Field(..., description="知识点名称")
|
||
description: str = Field(default="", description="知识点描述")
|
||
type: str = Field(default="理论知识", description="知识点类型")
|
||
source: int = Field(default=1, description="来源:0=手动,1=AI分析")
|
||
topic_relation: Optional[str] = Field(None, description="与主题的关系描述")
|
||
|
||
|
||
class KnowledgeCallbackRequest(BaseModel):
|
||
"""知识点回调请求模型(已弃用,保留向后兼容)"""
|
||
course_id: int = Field(..., description="课程ID")
|
||
material_id: int = Field(..., description="资料ID")
|
||
knowledge_points: List[KnowledgePointData] = Field(..., description="知识点列表")
|
||
|
||
|
||
@router.post("/knowledge", response_model=ResponseModel[Dict[str, Any]])
|
||
async def create_knowledge_points_callback(
|
||
request: KnowledgeCallbackRequest,
|
||
authorization: str = Header(None),
|
||
db: AsyncSession = Depends(get_db),
|
||
):
|
||
"""
|
||
创建知识点回调接口(已弃用)
|
||
|
||
注意:此接口已弃用,知识点分析现使用 Python 原生实现。
|
||
保留此接口仅为向后兼容。
|
||
"""
|
||
try:
|
||
# API密钥验证(已弃用的接口,保留向后兼容)
|
||
expected_token = "Bearer callback-token-2025"
|
||
if authorization != expected_token:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||
detail="无效的授权令牌"
|
||
)
|
||
|
||
# 验证课程是否存在
|
||
course = await course_service.get_by_id(db, request.course_id)
|
||
if not course:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"课程 {request.course_id} 不存在"
|
||
)
|
||
|
||
# 验证资料是否存在
|
||
materials = await course_service.get_course_materials(db, course_id=request.course_id)
|
||
material = next((m for m in materials if m.id == request.material_id), None)
|
||
if not material:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_404_NOT_FOUND,
|
||
detail=f"资料 {request.material_id} 不存在"
|
||
)
|
||
|
||
# 创建知识点
|
||
created_points = []
|
||
for kp_data in request.knowledge_points:
|
||
try:
|
||
knowledge_point_create = KnowledgePointCreate(
|
||
name=kp_data.name,
|
||
description=kp_data.description,
|
||
type=kp_data.type,
|
||
source=kp_data.source, # AI分析来源=1
|
||
topic_relation=kp_data.topic_relation,
|
||
material_id=request.material_id # 关联资料ID
|
||
)
|
||
|
||
# 使用系统用户ID (假设为1,或者可以配置)
|
||
system_user_id = 1
|
||
knowledge_point = await knowledge_point_service.create_knowledge_point(
|
||
db=db,
|
||
course_id=request.course_id,
|
||
point_in=knowledge_point_create,
|
||
created_by=system_user_id
|
||
)
|
||
|
||
created_points.append({
|
||
"id": knowledge_point.id,
|
||
"name": knowledge_point.name,
|
||
"description": knowledge_point.description,
|
||
"type": knowledge_point.type,
|
||
"source": knowledge_point.source,
|
||
"material_id": knowledge_point.material_id
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(
|
||
f"创建知识点失败 - name: {kp_data.name}, error: {str(e)}"
|
||
)
|
||
# 继续处理其他知识点,不因为单个失败而中断
|
||
continue
|
||
|
||
logger.info(
|
||
f"知识点回调成功 - course_id: {request.course_id}, material_id: {request.material_id}, created_points: {len(created_points)}"
|
||
)
|
||
|
||
return ResponseModel(
|
||
data={
|
||
"course_id": request.course_id,
|
||
"material_id": request.material_id,
|
||
"knowledge_points_count": len(created_points),
|
||
"knowledge_points": created_points
|
||
},
|
||
message=f"成功创建 {len(created_points)} 个知识点"
|
||
)
|
||
|
||
except HTTPException:
|
||
raise
|
||
except Exception as e:
|
||
logger.error(
|
||
f"知识点回调处理失败 - course_id: {request.course_id}, material_id: {request.material_id}, error: {str(e)}",
|
||
exc_info=True
|
||
)
|
||
raise HTTPException(
|
||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||
detail="知识点创建失败"
|
||
)
|
||
|
||
|