""" 成长路径 API 端点 """ import logging from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_db, get_current_user from app.models.user import User from app.services.growth_path_service import growth_path_service from app.schemas.growth_path import ( GrowthPathCreate, GrowthPathUpdate, GrowthPathResponse, GrowthPathListResponse, TraineeGrowthPathResponse, UserGrowthPathProgressResponse, StartGrowthPathRequest, CompleteNodeRequest, ) logger = logging.getLogger(__name__) router = APIRouter() # ===================================================== # 学员端 API # ===================================================== @router.get("/trainee/growth-path", response_model=Optional[TraineeGrowthPathResponse]) async def get_trainee_growth_path( position_id: Optional[int] = Query(None, description="岗位ID,不传则自动匹配"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 获取学员的成长路径(含进度) 返回数据包含: - 成长路径基本信息 - 各阶段及节点信息 - 每个节点的学习状态(locked/unlocked/in_progress/completed) - 每个节点的课程学习进度 """ try: result = await growth_path_service.get_trainee_growth_path( db=db, user_id=current_user.id, position_id=position_id ) return result except Exception as e: logger.error(f"获取成长路径失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/trainee/growth-path/start") async def start_growth_path( request: StartGrowthPathRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 开始学习成长路径 """ try: progress = await growth_path_service.start_growth_path( db=db, user_id=current_user.id, growth_path_id=request.growth_path_id ) return { "success": True, "message": "已开始学习成长路径", "progress_id": progress.id, } except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"开始成长路径失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/trainee/growth-path/node/complete") async def complete_growth_path_node( request: CompleteNodeRequest, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 完成成长路径节点 """ try: result = await growth_path_service.complete_node( db=db, user_id=current_user.id, node_id=request.node_id ) return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"完成节点失败: {e}") raise HTTPException(status_code=500, detail=str(e)) # ===================================================== # 管理端 API # ===================================================== @router.get("/manager/growth-paths") async def list_growth_paths( position_id: Optional[int] = Query(None, description="岗位ID筛选"), is_active: Optional[bool] = Query(None, description="是否启用"), page: int = Query(1, ge=1, description="页码"), page_size: int = Query(20, ge=1, le=100, description="每页数量"), db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 获取成长路径列表(管理端) """ try: result = await growth_path_service.list_growth_paths( db=db, position_id=position_id, is_active=is_active, page=page, page_size=page_size ) return result except Exception as e: logger.error(f"获取成长路径列表失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/manager/growth-paths") async def create_growth_path( data: GrowthPathCreate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 创建成长路径(管理端) """ try: growth_path = await growth_path_service.create_growth_path( db=db, data=data, created_by=current_user.id ) return { "success": True, "message": "创建成功", "id": growth_path.id, } except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"创建成长路径失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/manager/growth-paths/{path_id}") async def get_growth_path( path_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 获取成长路径详情(管理端) """ try: result = await growth_path_service.get_growth_path(db=db, path_id=path_id) if not result: raise HTTPException(status_code=404, detail="成长路径不存在") return result except HTTPException: raise except Exception as e: logger.error(f"获取成长路径详情失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.put("/manager/growth-paths/{path_id}") async def update_growth_path( path_id: int, data: GrowthPathUpdate, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 更新成长路径(管理端) """ try: await growth_path_service.update_growth_path( db=db, path_id=path_id, data=data ) return { "success": True, "message": "更新成功", } except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"更新成长路径失败: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.delete("/manager/growth-paths/{path_id}") async def delete_growth_path( path_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """ 删除成长路径(管理端) """ try: await growth_path_service.delete_growth_path(db=db, path_id=path_id) return { "success": True, "message": "删除成功", } except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"删除成长路径失败: {e}") raise HTTPException(status_code=500, detail=str(e))