This commit is contained in:
2026-07-07 19:52:19 +08:00
16 changed files with 745 additions and 600 deletions
+20
View File
@@ -279,6 +279,26 @@ async def update_user_status(
return {"message": "ok"}
@router.put("/users/{user_id}/admin-status")
async def update_user_admin_status(
user_id: str,
body: dict,
admin: User = Depends(get_admin_user),
db: AsyncSession = Depends(get_db),
):
is_admin = body.get("is_admin", False)
result = await db.execute(select(User).where(User.id == user_id).limit(1))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="用户不存在")
if user.user_type != "admin":
raise HTTPException(status_code=400, detail="仅后台用户支持设置超级管理员状态")
user.is_admin = is_admin
await db.flush()
await log_operation(db, admin.id, admin.username, f"{is_admin and '设为' or '取消'}超级管理员", "PUT", f"/admin/users/{user_id}/admin-status")
return {"message": "ok"}
@router.put("/users/{user_id}/frontend-kind", response_model=AdminUserOut)
async def update_user_frontend_kind(
user_id: str,
+4 -2
View File
@@ -245,13 +245,14 @@ async def get_join_info_public(
@router.get("/join-requests", )
async def list_join_requests(
status: str | None = Query(None),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
team = await get_managed_team(db, current_user.id)
if not team:
raise HTTPException(status_code=403, detail="只有团队管理人可查看")
requests = await team_invitation_service.get_pending_requests(db, team.id)
requests = await team_invitation_service.get_all_requests(db, team.id, status)
# 获取团队名
team_name_result = await db.execute(
@@ -269,7 +270,8 @@ async def list_join_requests(
phone=r.get("phone"),
status=r["status"],
note=r.get("note"),
created_at=r.get("created_at"),
created_at=r["created_at"],
handled_at=r.get("handled_at"),
)
for r in requests
]
+14
View File
@@ -11,5 +11,19 @@ TEAM_STATUS_LABELS = {
TeamStatus.DISABLED.value: "禁用",
}
class TeamJoinRequestStatus(str, Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
TEAM_JOIN_REQUEST_STATUS_LABELS = {
TeamJoinRequestStatus.PENDING.value: "待处理",
TeamJoinRequestStatus.APPROVED.value: "已通过",
TeamJoinRequestStatus.REJECTED.value: "已拒绝",
}
# 前端筛选“未分配团队”时使用的稳定哨兵值,不与真实团队ID混用。
TEAM_UNASSIGNED_VALUE = "__none__"
@@ -22,6 +22,7 @@ class JoinRequestOut(BaseModel):
status: str
note: str | None = None
created_at: NaiveDatetimeOptional = None
handled_at: NaiveDatetimeOptional = None
model_config = {"from_attributes": True}
@@ -222,6 +222,40 @@ async def get_pending_requests(db: AsyncSession, team_id: str) -> list[dict[str,
"status": req.status,
"note": req.note,
"created_at": req.created_at,
"handled_at": req.updated_at if req.status != "pending" else None,
}
for req, username, phone in rows
]
async def get_all_requests(
db: AsyncSession,
team_id: str,
status: str | None = None,
) -> list[dict[str, Any]]:
"""获取团队所有加入申请列表,支持按状态筛选。"""
where = [TeamJoinRequest.team_id == team_id]
if status:
where.append(TeamJoinRequest.status == status)
result = await db.execute(
select(TeamJoinRequest, User.username, User.phone)
.join(User, User.id == TeamJoinRequest.user_id)
.where(*where)
.order_by(TeamJoinRequest.created_at.desc())
)
rows = result.all()
return [
{
"id": req.id,
"team_id": req.team_id,
"user_id": req.user_id,
"username": username,
"phone": phone,
"status": req.status,
"note": req.note,
"created_at": req.created_at,
"handled_at": req.updated_at if req.status != "pending" else None,
}
for req, username, phone in rows
]