96 lines
3.1 KiB
Python
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,
|
|
}
|