42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
"""用户头像 URL 解析(sys_user.avatar 可能存 MinIO 相对路径或完整 URL)"""
|
||
from typing import Optional
|
||
|
||
from app.core.config import settings
|
||
from app.core.storage import storage
|
||
|
||
|
||
def resolve_avatar_display_url(raw: Optional[str]) -> Optional[str]:
|
||
"""服务端内部拼完整 URL(邮件等);Web API 应返回库中原始路径。"""
|
||
if raw is None:
|
||
return None
|
||
s = str(raw).strip()
|
||
if not s:
|
||
return None
|
||
lower = s.lower()
|
||
if lower.startswith("http://") or lower.startswith("https://") or s.startswith("/"):
|
||
return s
|
||
try:
|
||
return storage.get_url(s.lstrip("/"))
|
||
except Exception:
|
||
base = (settings.MINIO_BASE_URL or settings.LOCAL_STORAGE_URL or "").rstrip("/")
|
||
if base:
|
||
return f"{base}/{s.lstrip('/')}"
|
||
return s
|
||
|
||
|
||
def extract_avatar_storage_key(full_url: str) -> str:
|
||
"""从 upload 返回值或历史完整 URL 中提取 avatar/ 相对路径。"""
|
||
u = (full_url or "").strip()
|
||
if not u:
|
||
return ""
|
||
base_url = (settings.MINIO_BASE_URL or "").rstrip("/")
|
||
if base_url and u.startswith(base_url + "/"):
|
||
return u[len(base_url) + 1 :].lstrip("/")
|
||
marker = "/avatar/"
|
||
idx = u.lower().find(marker)
|
||
if idx >= 0:
|
||
return f"avatar/{u[idx + len(marker) :].lstrip('/')}"
|
||
if not u.lower().startswith("http") and not u.startswith("/"):
|
||
return u.lstrip("/")
|
||
return u
|