merge main
This commit is contained in:
@@ -2,18 +2,57 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from fastapi import APIRouter, Body, Depends, Query
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.dependencies import get_admin_user, get_db
|
||||
from app.models.team import Team
|
||||
from app.models.user import User
|
||||
from app.schemas.team import TeamCreate, TeamListOut, TeamOptionOut, TeamOut, TeamUpdate
|
||||
from app.schemas.team import TeamCreate, TeamListOut, TeamOptionOut, TeamUpdate
|
||||
from app.schemas.team_manager import SetManagerRequest
|
||||
from app.services.operation_log import log_operation
|
||||
from app.services.team_manager_service import set_team_manager
|
||||
from app.services.team_service import create_team, list_team_options, list_teams, soft_delete_team, update_team
|
||||
|
||||
router = APIRouter(prefix="/admin/teams", tags=["admin-teams"])
|
||||
|
||||
|
||||
async def _team_detail_payload(db: AsyncSession, team: Team) -> dict:
|
||||
"""构造返回团队详情,包含 manager_name。"""
|
||||
payload = {
|
||||
"id": team.id,
|
||||
"name": team.name,
|
||||
"code": getattr(team, "code", None),
|
||||
"description": getattr(team, "description", None),
|
||||
"status": getattr(team, "status", "active"),
|
||||
"sort_order": getattr(team, "sort_order", 0) or 0,
|
||||
"member_count": 0,
|
||||
"created_at": team.created_at,
|
||||
"updated_at": team.updated_at,
|
||||
"manager_id": getattr(team, "manager_id", None),
|
||||
"manager_name": None,
|
||||
}
|
||||
# 查询成员数和管理人用户名
|
||||
from sqlalchemy import func
|
||||
from app.enums.user import UserType
|
||||
member_count = (await db.execute(
|
||||
select(func.count(User.id)).where(
|
||||
User.user_type == UserType.FRONTEND.value,
|
||||
User.team_id == team.id,
|
||||
)
|
||||
)).scalar() or 0
|
||||
payload["member_count"] = int(member_count)
|
||||
|
||||
if getattr(team, "manager_id", None):
|
||||
mgr = await db.execute(
|
||||
select(User.username).where(User.id == team.manager_id).limit(1)
|
||||
)
|
||||
payload["manager_name"] = mgr.scalar_one_or_none()
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
@router.get("", response_model=TeamListOut)
|
||||
async def list_admin_teams(
|
||||
page: int = Query(1, ge=1),
|
||||
@@ -35,7 +74,7 @@ async def list_admin_team_options(
|
||||
return await list_team_options(db, include_disabled=include_disabled)
|
||||
|
||||
|
||||
@router.post("", response_model=TeamOut)
|
||||
@router.post("", )
|
||||
async def create_admin_team(
|
||||
req: TeamCreate,
|
||||
admin: User = Depends(get_admin_user),
|
||||
@@ -51,20 +90,10 @@ async def create_admin_team(
|
||||
"/admin/teams",
|
||||
detail=json.dumps({"after": req.model_dump()}, ensure_ascii=False),
|
||||
)
|
||||
return {
|
||||
"id": team.id,
|
||||
"name": team.name,
|
||||
"code": team.code,
|
||||
"description": team.description,
|
||||
"status": team.status,
|
||||
"sort_order": team.sort_order,
|
||||
"member_count": 0,
|
||||
"created_at": team.created_at,
|
||||
"updated_at": team.updated_at,
|
||||
}
|
||||
return await _team_detail_payload(db, team)
|
||||
|
||||
|
||||
@router.put("/{team_id}", response_model=TeamOut)
|
||||
@router.put("/{team_id}", )
|
||||
async def update_admin_team(
|
||||
team_id: str,
|
||||
req: TeamUpdate,
|
||||
@@ -81,17 +110,35 @@ async def update_admin_team(
|
||||
f"/admin/teams/{team_id}",
|
||||
detail=json.dumps({"before": before, "after": after}, ensure_ascii=False),
|
||||
)
|
||||
return {
|
||||
"id": team.id,
|
||||
"name": team.name,
|
||||
"code": team.code,
|
||||
"description": team.description,
|
||||
"status": team.status,
|
||||
"sort_order": team.sort_order,
|
||||
"member_count": 0,
|
||||
"created_at": team.created_at,
|
||||
"updated_at": team.updated_at,
|
||||
}
|
||||
return await _team_detail_payload(db, team)
|
||||
|
||||
|
||||
@router.put("/{team_id}/manager", )
|
||||
async def set_team_manager_endpoint(
|
||||
team_id: str,
|
||||
req: SetManagerRequest = Body(...),
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
team = await set_team_manager(db, team_id, req.user_id)
|
||||
manager_name = None
|
||||
# 使用 req.user_id 避免访问 team.manager_id 触发懒加载
|
||||
if req.user_id:
|
||||
mgr = await db.execute(
|
||||
select(User.username).where(User.id == req.user_id).limit(1)
|
||||
)
|
||||
manager_name = mgr.scalar_one_or_none()
|
||||
team_name = team.name
|
||||
await log_operation(
|
||||
db,
|
||||
admin.id,
|
||||
admin.username,
|
||||
f"设置团队管理人 {team_name}: {manager_name or '取消'}",
|
||||
"PUT",
|
||||
f"/admin/teams/{team_id}/manager",
|
||||
detail=json.dumps({"manager_id": req.user_id}, ensure_ascii=False),
|
||||
)
|
||||
return await _team_detail_payload(db, team)
|
||||
|
||||
|
||||
@router.delete("/{team_id}")
|
||||
|
||||
Reference in New Issue
Block a user