avatar_url.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. """用户头像 URL 解析(sys_user.avatar 可能存 MinIO 相对路径或完整 URL)"""
  2. from typing import Optional
  3. from app.core.config import settings
  4. from app.core.storage import storage
  5. def resolve_avatar_display_url(raw: Optional[str]) -> Optional[str]:
  6. """服务端内部拼完整 URL(邮件等);Web API 应返回库中原始路径。"""
  7. if raw is None:
  8. return None
  9. s = str(raw).strip()
  10. if not s:
  11. return None
  12. lower = s.lower()
  13. if lower.startswith("http://") or lower.startswith("https://") or s.startswith("/"):
  14. return s
  15. try:
  16. return storage.get_url(s.lstrip("/"))
  17. except Exception:
  18. base = (settings.MINIO_BASE_URL or settings.LOCAL_STORAGE_URL or "").rstrip("/")
  19. if base:
  20. return f"{base}/{s.lstrip('/')}"
  21. return s
  22. def extract_avatar_storage_key(full_url: str) -> str:
  23. """从 upload 返回值或历史完整 URL 中提取 avatar/ 相对路径。"""
  24. u = (full_url or "").strip()
  25. if not u:
  26. return ""
  27. base_url = (settings.MINIO_BASE_URL or "").rstrip("/")
  28. if base_url and u.startswith(base_url + "/"):
  29. return u[len(base_url) + 1 :].lstrip("/")
  30. marker = "/avatar/"
  31. idx = u.lower().find(marker)
  32. if idx >= 0:
  33. return f"avatar/{u[idx + len(marker) :].lstrip('/')}"
  34. if not u.lower().startswith("http") and not u.startswith("/"):
  35. return u.lstrip("/")
  36. return u