116 lines
3.8 KiB
Python
116 lines
3.8 KiB
Python
"""User skill bindings and history endpoints."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import List
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ....core.database import get_db
|
|
from ....dependencies import get_current_user, get_tenant_id
|
|
from ....models import User
|
|
from ....schemas.skill import (
|
|
SkillTaskHistoryItem,
|
|
SkillTaskHistoryResponse,
|
|
UserSkillBindingBatchUpdate,
|
|
UserSkillBindingResponse,
|
|
)
|
|
from ....services import skill as skill_service
|
|
from .shared import ensure_self_or_admin
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/users/{user_id}/bindings", response_model=List[UserSkillBindingResponse])
|
|
async def get_user_skill_bindings(
|
|
user_id: int,
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
_ = current_user
|
|
bindings = await skill_service.get_user_skill_bindings(db, tenant_id, user_id)
|
|
return [
|
|
UserSkillBindingResponse(
|
|
id=str(binding.id),
|
|
user_id=str(binding.user_id),
|
|
skill_tag_id=str(binding.skill_tag_id),
|
|
skill_name=binding.skill_tag.name if binding.skill_tag else "",
|
|
proficiency=binding.proficiency or 50,
|
|
level=binding.level or binding.proficiency_level or "intermediate",
|
|
years_experience=binding.years_experience,
|
|
quality_score=getattr(binding, "quality_score", None),
|
|
efficiency_score=getattr(binding, "efficiency_score", None),
|
|
last_used_at=binding.last_used_at.isoformat() if binding.last_used_at else None,
|
|
created_at=binding.created_at.isoformat() if binding.created_at else None,
|
|
updated_at=binding.updated_at.isoformat() if binding.updated_at else None,
|
|
)
|
|
for binding in bindings
|
|
]
|
|
|
|
|
|
@router.put("/users/{user_id}/bindings/batch")
|
|
async def batch_update_user_skill_bindings(
|
|
user_id: int,
|
|
body: UserSkillBindingBatchUpdate,
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
_ = current_user
|
|
bindings = await skill_service.batch_update_user_skill_bindings(
|
|
db,
|
|
tenant_id,
|
|
user_id,
|
|
body.bindings,
|
|
)
|
|
return {"updated_count": len(bindings), "message": "已更新"}
|
|
|
|
|
|
@router.get("/tags/{tag_id}/users")
|
|
async def get_skill_tag_users(
|
|
tag_id: int,
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
_ = current_user
|
|
bindings = await skill_service.get_skill_tag_user_bindings(db, tenant_id, tag_id)
|
|
return [
|
|
{
|
|
"user_id": str(binding.user_id),
|
|
"user_name": binding.user.name if binding.user else "",
|
|
"proficiency": binding.proficiency,
|
|
"level": binding.level,
|
|
}
|
|
for binding in bindings
|
|
]
|
|
|
|
|
|
@router.get("/users/{user_id}/tasks", response_model=SkillTaskHistoryResponse)
|
|
async def get_user_skill_task_history(
|
|
user_id: int,
|
|
skill_id: int = Query(..., description="技能标签 ID"),
|
|
limit: int = Query(50, ge=1, le=200, description="返回条数上限"),
|
|
tenant_id: int = Depends(get_tenant_id),
|
|
current_user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
ensure_self_or_admin(
|
|
current_user=current_user,
|
|
target_user_id=user_id,
|
|
detail="仅可查询自己的技能历史任务",
|
|
)
|
|
items = await skill_service.get_user_skill_task_history(
|
|
db=db,
|
|
tenant_id=tenant_id,
|
|
user_id=user_id,
|
|
skill_tag_id=skill_id,
|
|
limit=limit,
|
|
)
|
|
return SkillTaskHistoryResponse(
|
|
items=[SkillTaskHistoryItem(**item) for item in items],
|
|
total=len(items),
|
|
)
|