PMFlow/backend/app/api/users_api/routes_import.py

96 lines
3.1 KiB
Python

from __future__ import annotations
from .shared import *
from .helpers_user import _iter_import_rows, _create_user_with_defaults
@router.put("/{user_id}/workload")
async def update_user_workload(
user_id: int,
workload: int = Query(..., ge=0, le=200, description="Workload value (0-200)"),
tenant_id: int = Depends(get_tenant_id),
current_user: User = Depends(require_self_or_manager),
db: AsyncSession = Depends(get_db),
):
"""手动更新用户 workload 百分比。"""
_ = current_user
result = await db.execute(
select(User).where(and_(User.tenant_id == tenant_id, User.id == user_id))
)
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="User not found")
user.workload = max(0, min(200, int(workload)))
user.updated_at = now_cn_naive()
await db.commit()
await db.refresh(user)
return _serialize_user(user)
@router.post("/import")
async def import_users(
file: UploadFile = File(...),
tenant_id: int = Depends(get_tenant_id),
current_user: User = Depends(require_roles("OWNER", "REVIEWER")),
db: AsyncSession = Depends(get_db),
):
"""批量导入用户(最多 50 行)。"""
rows = await _iter_import_rows(file)
if not rows:
raise HTTPException(status_code=400, detail="Import file is empty")
if len(rows) > 50:
raise HTTPException(status_code=400, detail="Import rows exceed max limit: 50")
results: list[dict[str, Any]] = []
success_count = 0
for idx, raw in enumerate(rows, start=1):
row = _normalize_import_row(raw)
try:
if row["role"] not in {r.value for r in UserRole}:
raise ValueError(f"Invalid role: {row['role']}")
if not row["username"] or not row["password"]:
raise ValueError("username/password required")
data = UserCreate(
username=row["username"],
password=row["password"],
name=row["name"] or row["username"],
email=row["email"],
role=UserRole(row["role"]),
assigned_domains=[],
project_ids=row["project_ids"],
)
user = await _create_user_with_defaults(
db,
tenant_id=tenant_id,
user_data=data,
actor_id=int(current_user.id),
commit=True,
)
success_count += 1
results.append(
{
"row": idx,
"status": "success",
"user_id": str(user.id),
"message": "created",
}
)
except Exception as exc:
await db.rollback()
results.append(
{
"row": idx,
"status": "failed",
"message": str(exc),
}
)
return {
"total": len(rows),
"success": success_count,
"failed": len(rows) - success_count,
"results": results,
}