200 lines
5.7 KiB
Python
200 lines
5.7 KiB
Python
"""
|
|
PMFlow 人员能力图谱 - Pydantic 请求/响应模型
|
|
|
|
包含 SkillTag、UserSkillBinding、UserWorkload 及人员推荐相关模型。
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ============================================================================
|
|
# SkillTag 模型
|
|
# ============================================================================
|
|
|
|
|
|
class SkillTagCreate(BaseModel):
|
|
"""创建技能标签请求"""
|
|
|
|
name: str = Field(..., min_length=1, max_length=100, description="技能名称")
|
|
slug: str = Field(..., min_length=1, max_length=80, description="URL 安全标识")
|
|
category: Optional[str] = Field(None, max_length=50, description="分类")
|
|
description: Optional[str] = Field(None, description="描述")
|
|
sort_order: int = Field(default=0, ge=0, description="排序序号")
|
|
|
|
|
|
class SkillTagUpdate(BaseModel):
|
|
"""更新技能标签请求(系统标签不可更新)"""
|
|
|
|
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
|
category: Optional[str] = Field(None, max_length=50)
|
|
description: Optional[str] = None
|
|
sort_order: Optional[int] = Field(None, ge=0)
|
|
|
|
|
|
class SkillTagResponse(BaseModel):
|
|
"""技能标签响应"""
|
|
|
|
id: str
|
|
tenant_id: int | str
|
|
name: str
|
|
slug: str
|
|
category: Optional[str] = None
|
|
description: Optional[str] = None
|
|
is_system: bool
|
|
sort_order: int
|
|
created_at: str
|
|
updated_at: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================================================
|
|
# UserSkillBinding 模型
|
|
# ============================================================================
|
|
|
|
|
|
class UserSkillBindingCreate(BaseModel):
|
|
"""创建用户技能绑定请求"""
|
|
|
|
user_id: UUID
|
|
skill_tag_id: UUID
|
|
proficiency: int = Field(default=50, ge=0, le=100, description="掌握程度 0-100")
|
|
level: str = Field(
|
|
default="intermediate",
|
|
description="熟练等级: beginner, intermediate, advanced, expert",
|
|
)
|
|
years_experience: Optional[float] = Field(None, ge=0, description="从业年限")
|
|
|
|
|
|
class UserSkillBindingUpdate(BaseModel):
|
|
"""更新用户技能绑定请求"""
|
|
|
|
proficiency: Optional[int] = Field(None, ge=0, le=100)
|
|
level: Optional[str] = None
|
|
years_experience: Optional[float] = Field(None, ge=0)
|
|
|
|
|
|
class UserSkillBindingBatchUpdate(BaseModel):
|
|
"""批量更新用户技能绑定请求"""
|
|
|
|
user_id: Optional[UUID] = None # 可选,由路径提供时省略
|
|
bindings: List[dict] = Field(
|
|
...,
|
|
description="绑定列表,每项含 skill_tag_id, proficiency, level, years_experience",
|
|
)
|
|
|
|
|
|
class UserSkillBindingResponse(BaseModel):
|
|
"""用户技能绑定响应"""
|
|
|
|
id: str
|
|
user_id: str
|
|
skill_tag_id: str
|
|
skill_name: str
|
|
proficiency: int
|
|
level: str
|
|
years_experience: Optional[float] = None
|
|
quality_score: Optional[float] = None # 0-100 质量分
|
|
efficiency_score: Optional[float] = None # 0-100 效率分
|
|
last_used_at: Optional[str] = None
|
|
created_at: str
|
|
updated_at: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================================================
|
|
# UserWorkload 模型
|
|
# ============================================================================
|
|
|
|
|
|
class UserWorkloadUpdate(BaseModel):
|
|
"""更新用户工作量请求(通常由系统自动调用)"""
|
|
|
|
user_id: UUID
|
|
total_tasks: Optional[int] = Field(None, ge=0)
|
|
completed_tasks: Optional[int] = Field(None, ge=0)
|
|
in_progress_tasks: Optional[int] = Field(None, ge=0)
|
|
estimated_hours: Optional[float] = Field(None, ge=0)
|
|
completed_hours: Optional[float] = Field(None, ge=0)
|
|
|
|
|
|
class UserWorkloadResponse(BaseModel):
|
|
"""用户工作量响应"""
|
|
|
|
id: str
|
|
user_id: str
|
|
user_name: str
|
|
total_tasks: int
|
|
completed_tasks: int
|
|
in_progress_tasks: int
|
|
estimated_hours: float
|
|
completed_hours: float
|
|
workload_rate: float
|
|
period_start: str
|
|
period_end: str
|
|
updated_at: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============================================================================
|
|
# 人员推荐模型
|
|
# ============================================================================
|
|
|
|
|
|
class PersonnelRecommendationItem(BaseModel):
|
|
"""人员推荐单项"""
|
|
|
|
user_id: str
|
|
user_name: str
|
|
match_score: float = Field(..., ge=0, le=100, description="匹配度评分")
|
|
reason: str = Field(..., description="推荐理由")
|
|
skill_match_count: int = Field(..., ge=0)
|
|
avg_proficiency: float = Field(..., ge=0, le=100)
|
|
workload_rate: float = Field(..., ge=0, le=100)
|
|
recommended_role: Optional[str] = None
|
|
|
|
|
|
class PersonnelRecommendationResponse(BaseModel):
|
|
"""人员推荐响应"""
|
|
|
|
task_id: Optional[str] = None
|
|
task_description: Optional[str] = None
|
|
required_skills: List[str] = []
|
|
recommendations: List[PersonnelRecommendationItem] = []
|
|
total_count: int = 0
|
|
|
|
|
|
# ============================================================================
|
|
# 技能历史任务
|
|
# ============================================================================
|
|
|
|
|
|
class SkillTaskHistoryItem(BaseModel):
|
|
"""用户某技能下的历史任务项"""
|
|
|
|
id: str
|
|
title: str
|
|
description: Optional[str] = None
|
|
status: Optional[str] = None
|
|
priority: Optional[str] = None
|
|
estimated_hours: Optional[float] = None
|
|
project_id: Optional[str] = None
|
|
truth_node_id: Optional[str] = None
|
|
updated_at: Optional[str] = None
|
|
|
|
|
|
class SkillTaskHistoryResponse(BaseModel):
|
|
"""技能历史任务列表响应"""
|
|
|
|
items: List[SkillTaskHistoryItem] = []
|
|
total: int = 0
|