All checks were successful
continuous-integration/drone/push Build is passing
- 新增数据库表: growth_path_nodes, user_growth_path_progress, user_node_completions - 新增 Model: GrowthPathNode, UserGrowthPathProgress, UserNodeCompletion - 新增 Service: GrowthPathService(管理端CRUD、学员端进度追踪) - 新增 API: 学员端获取成长路径、管理端CRUD - 前端学员端从API动态加载成长路径数据 - 更新管理端API接口定义
225 lines
7.1 KiB
Python
225 lines
7.1 KiB
Python
"""
|
|
成长路径相关 Schema
|
|
"""
|
|
from typing import List, Optional
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# =====================================================
|
|
# 基础数据结构
|
|
# =====================================================
|
|
|
|
class StageConfig(BaseModel):
|
|
"""阶段配置"""
|
|
name: str = Field(..., description="阶段名称")
|
|
description: Optional[str] = Field(None, description="阶段描述")
|
|
order: int = Field(0, description="排序")
|
|
|
|
|
|
class NodeBase(BaseModel):
|
|
"""节点基础信息"""
|
|
course_id: int = Field(..., description="课程ID")
|
|
stage_name: Optional[str] = Field(None, description="所属阶段名称")
|
|
title: str = Field(..., description="节点标题")
|
|
description: Optional[str] = Field(None, description="节点描述")
|
|
order_num: int = Field(0, description="排序顺序")
|
|
is_required: bool = Field(True, description="是否必修")
|
|
prerequisites: Optional[List[int]] = Field(None, description="前置节点IDs")
|
|
estimated_days: int = Field(7, description="预计学习天数")
|
|
|
|
|
|
# =====================================================
|
|
# 管理端 - 创建/更新
|
|
# =====================================================
|
|
|
|
class GrowthPathNodeCreate(NodeBase):
|
|
"""创建节点"""
|
|
pass
|
|
|
|
|
|
class GrowthPathNodeUpdate(BaseModel):
|
|
"""更新节点"""
|
|
course_id: Optional[int] = None
|
|
stage_name: Optional[str] = None
|
|
title: Optional[str] = None
|
|
description: Optional[str] = None
|
|
order_num: Optional[int] = None
|
|
is_required: Optional[bool] = None
|
|
prerequisites: Optional[List[int]] = None
|
|
estimated_days: Optional[int] = None
|
|
|
|
|
|
class GrowthPathCreate(BaseModel):
|
|
"""创建成长路径"""
|
|
name: str = Field(..., description="路径名称")
|
|
description: Optional[str] = Field(None, description="路径描述")
|
|
target_role: Optional[str] = Field(None, description="目标角色")
|
|
position_id: Optional[int] = Field(None, description="关联岗位ID")
|
|
stages: Optional[List[StageConfig]] = Field(None, description="阶段配置")
|
|
estimated_duration_days: Optional[int] = Field(None, description="预计完成天数")
|
|
is_active: bool = Field(True, description="是否启用")
|
|
sort_order: int = Field(0, description="排序")
|
|
nodes: Optional[List[GrowthPathNodeCreate]] = Field(None, description="节点列表")
|
|
|
|
|
|
class GrowthPathUpdate(BaseModel):
|
|
"""更新成长路径"""
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
target_role: Optional[str] = None
|
|
position_id: Optional[int] = None
|
|
stages: Optional[List[StageConfig]] = None
|
|
estimated_duration_days: Optional[int] = None
|
|
is_active: Optional[bool] = None
|
|
sort_order: Optional[int] = None
|
|
nodes: Optional[List[GrowthPathNodeCreate]] = None # 整体替换节点
|
|
|
|
|
|
# =====================================================
|
|
# 管理端 - 响应
|
|
# =====================================================
|
|
|
|
class GrowthPathNodeResponse(NodeBase):
|
|
"""节点响应"""
|
|
id: int
|
|
growth_path_id: int
|
|
course_name: Optional[str] = None # 课程名称(关联查询)
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class GrowthPathResponse(BaseModel):
|
|
"""成长路径响应(管理端)"""
|
|
id: int
|
|
name: str
|
|
description: Optional[str] = None
|
|
target_role: Optional[str] = None
|
|
position_id: Optional[int] = None
|
|
position_name: Optional[str] = None # 岗位名称(关联查询)
|
|
stages: Optional[List[StageConfig]] = None
|
|
estimated_duration_days: Optional[int] = None
|
|
is_active: bool
|
|
sort_order: int
|
|
nodes: List[GrowthPathNodeResponse] = []
|
|
node_count: int = 0 # 节点数量
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class GrowthPathListResponse(BaseModel):
|
|
"""成长路径列表响应"""
|
|
id: int
|
|
name: str
|
|
description: Optional[str] = None
|
|
position_id: Optional[int] = None
|
|
position_name: Optional[str] = None
|
|
is_active: bool
|
|
node_count: int = 0
|
|
estimated_duration_days: Optional[int] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# =====================================================
|
|
# 学员端 - 响应
|
|
# =====================================================
|
|
|
|
class TraineeNodeResponse(BaseModel):
|
|
"""学员端节点响应(含进度状态)"""
|
|
id: int
|
|
course_id: int
|
|
title: str
|
|
description: Optional[str] = None
|
|
stage_name: Optional[str] = None
|
|
is_required: bool
|
|
estimated_days: int
|
|
order_num: int
|
|
|
|
# 学员特有
|
|
status: str = Field(..., description="状态: locked/unlocked/in_progress/completed")
|
|
progress: float = Field(0, description="课程学习进度 0-100")
|
|
|
|
# 课程信息
|
|
course_name: Optional[str] = None
|
|
course_cover: Optional[str] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class TraineeStageResponse(BaseModel):
|
|
"""学员端阶段响应"""
|
|
name: str
|
|
description: Optional[str] = None
|
|
completed: int = Field(0, description="已完成节点数")
|
|
total: int = Field(0, description="总节点数")
|
|
nodes: List[TraineeNodeResponse] = []
|
|
|
|
|
|
class TraineeGrowthPathResponse(BaseModel):
|
|
"""学员端成长路径响应"""
|
|
id: int
|
|
name: str
|
|
description: Optional[str] = None
|
|
position_id: Optional[int] = None
|
|
position_name: Optional[str] = None
|
|
|
|
# 进度信息
|
|
total_progress: float = Field(0, description="总进度百分比")
|
|
completed_nodes: int = Field(0, description="已完成节点数")
|
|
total_nodes: int = Field(0, description="总节点数")
|
|
status: str = Field("not_started", description="状态: not_started/in_progress/completed")
|
|
|
|
# 时间信息
|
|
started_at: Optional[datetime] = None
|
|
estimated_completion_days: Optional[int] = None
|
|
|
|
# 阶段和节点
|
|
stages: List[TraineeStageResponse] = []
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# =====================================================
|
|
# 用户进度
|
|
# =====================================================
|
|
|
|
class UserGrowthPathProgressResponse(BaseModel):
|
|
"""用户成长路径进度响应"""
|
|
id: int
|
|
user_id: int
|
|
growth_path_id: int
|
|
growth_path_name: str
|
|
current_node_id: Optional[int] = None
|
|
current_node_title: Optional[str] = None
|
|
completed_node_ids: List[int] = []
|
|
total_progress: float
|
|
status: str
|
|
started_at: Optional[datetime] = None
|
|
completed_at: Optional[datetime] = None
|
|
last_activity_at: Optional[datetime] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class StartGrowthPathRequest(BaseModel):
|
|
"""开始学习成长路径请求"""
|
|
growth_path_id: int = Field(..., description="成长路径ID")
|
|
|
|
|
|
class CompleteNodeRequest(BaseModel):
|
|
"""完成节点请求"""
|
|
node_id: int = Field(..., description="节点ID")
|