"""用户头像 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