""" app/api/v1/users.py — 管理员账号管理路由 全部挂 require_admin;路由层只做参数校验→调 service→格式化响应。 禁用=软删除可恢复(倩倩姐2026-06-30);不物理删除。 """ from typing import Annotated from fastapi import APIRouter, Depends from pydantic import BaseModel, field_validator from sqlalchemy.orm import Session from app.core.database import get_db from app.core.response import ok from app.middleware.workspace_guard import CurrentUser, require_admin from app.services import user_admin_service as svc router = APIRouter(prefix="/users", tags=["users"]) class CreateUserRequest(BaseModel): username: str email: str role: str init_password: str @field_validator("username", "email", "role", "init_password") @classmethod def not_empty(cls, v: str) -> str: if not v or not v.strip(): raise ValueError("不能为空") return v class SetActiveRequest(BaseModel): is_active: bool @router.get("") def list_users( current_user: Annotated[CurrentUser, Depends(require_admin)], db: Session = Depends(get_db), ): """列出本 workspace 成员(含已禁用)。""" return ok(svc.list_workspace_users(db, current_user.workspace_id)) @router.post("") def create_user( body: CreateUserRequest, current_user: Annotated[CurrentUser, Depends(require_admin)], db: Session = Depends(get_db), ): """建号,强制首登改密。""" return ok(svc.create_workspace_user( db, current_user.workspace_id, body.username, body.email, body.role, body.init_password, )) @router.post("/{user_id}/active") def set_active( user_id: int, body: SetActiveRequest, current_user: Annotated[CurrentUser, Depends(require_admin)], db: Session = Depends(get_db), ): """启用/禁用账号(软删除,可随时恢复)。""" return ok(svc.set_user_active( db, current_user.workspace_id, user_id, body.is_active, current_user.user_id, )) @router.delete("/{user_id}") def delete_user( user_id: int, current_user: Annotated[CurrentUser, Depends(require_admin)], db: Session = Depends(get_db), ): """物理删除账号(不可恢复,与禁用区分)。""" return ok(svc.delete_workspace_user( db, current_user.workspace_id, user_id, current_user.user_id, ))