优化个人中心与界面交互

This commit is contained in:
Cheng Zhou
2026-06-11 09:09:17 +08:00
parent 84e55af8fe
commit b7484c8e01
15 changed files with 572 additions and 141 deletions
+12 -1
View File
@@ -42,6 +42,12 @@ class ExtendResponse(BaseModel):
router = APIRouter()
AVATAR_ROOT = Path(__file__).resolve().parent.parent.parent / "uploads" / "avatars"
AVATAR_ROOT.mkdir(parents=True, exist_ok=True)
AVATAR_ALLOWED_CONTENT_TYPES = {
"image/png": ".png",
"image/jpeg": ".jpg",
"image/gif": ".gif",
"image/webp": ".webp",
}
def issue_user_token(db_user) -> Token:
@@ -215,10 +221,15 @@ async def upload_avatar(
current_user=Depends(get_current_user),
db: AsyncSession = Depends(get_db_session),
) -> UserRead:
ext = AVATAR_ALLOWED_CONTENT_TYPES.get(file.content_type or "")
if not ext:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="头像仅支持图片格式",
)
AVATAR_ROOT.mkdir(parents=True, exist_ok=True)
user_dir = AVATAR_ROOT / str(current_user.id)
user_dir.mkdir(parents=True, exist_ok=True)
ext = Path(file.filename).suffix or ".png"
filename = f"{uuid.uuid4()}{ext}"
dest = user_dir / filename
content = await file.read()
+21 -1
View File
@@ -274,6 +274,27 @@ async def test_dev_login_allows_plaintext_only_in_development(client_and_db):
assert resp.json()["access_token"]
@pytest.mark.asyncio
async def test_avatar_upload_rejects_non_image_files(client_and_db):
client, _ = client_and_db
original_env = settings.ENV
settings.ENV = "development"
try:
login_resp = await client.post("/api/v1/auth/dev-login", json={"email": "admin@test.com", "password": "admin123"})
finally:
settings.ENV = original_env
token = login_resp.json()["access_token"]
resp = await client.post(
"/api/v1/auth/me/avatar",
files={"file": ("avatar.txt", b"not an image", "text/plain")},
headers={"Authorization": f"Bearer {token}"},
)
assert resp.status_code == 400
assert resp.json()["detail"] == "头像仅支持图片格式"
@pytest.mark.asyncio
async def test_dev_login_is_disabled_outside_development(client_and_db):
client, _ = client_and_db
@@ -357,4 +378,3 @@ async def test_login_challenge_cannot_be_reused(client_and_db):
assert first.status_code == 200
assert second.status_code == 401