Files
012-kaopeilian/backend/app/api/v1/system.py
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

140 lines
5.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
系统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="知识点创建失败"
)