- P0-2: Refresh token with Redis storage (UUID tokens, 30-day TTL, rotation on refresh) - P0-2: Backend POST /auth/refresh and /auth/revoke endpoints - P0-2: Android AuthInterceptor refresh-before-re-login flow - P0-2: AuthRepository saves refresh_token on login, revokes on logout - P0-4: Enable R8 minification (isMinifyEnabled=true) with comprehensive keep rules - P0-5: Backend GET /api/v1/app/check-update with force_update support - P0-5: Android AppUpdateManager with force/optional update dialogs on startup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
"""
|
|
应用升级检查 API
|
|
"""
|
|
from fastapi import APIRouter, Query
|
|
|
|
from app.core.config import settings
|
|
|
|
router = APIRouter(
|
|
prefix="/api/v1/app",
|
|
tags=["app"],
|
|
)
|
|
|
|
# 升级配置(可从 .env 或数据库读取,默认从配置文件)
|
|
_LATEST_ANDROID_VERSION = getattr(settings, 'LATEST_ANDROID_VERSION', settings.APP_VERSION)
|
|
_LATEST_ANDROID_URL = getattr(settings, 'LATEST_ANDROID_URL', "")
|
|
_ANDROID_FORCE_UPDATE_MIN = getattr(settings, 'ANDROID_FORCE_UPDATE_MIN', "1.0.0")
|
|
_ANDROID_RELEASE_NOTES = getattr(settings, 'ANDROID_RELEASE_NOTES', "")
|
|
|
|
|
|
def _version_tuple(v: str) -> tuple:
|
|
"""将版本号字符串转为可比较的元组。"""
|
|
try:
|
|
return tuple(int(x) for x in v.strip().split("."))
|
|
except (ValueError, AttributeError):
|
|
return (0,)
|
|
|
|
|
|
@router.get("/check-update")
|
|
async def check_update(
|
|
platform: str = Query("android", description="平台: android / ios"),
|
|
version: str = Query("1.0.0", description="当前客户端版本号"),
|
|
):
|
|
"""检查应用是否有新版本可用。"""
|
|
if platform == "android":
|
|
latest = _LATEST_ANDROID_VERSION
|
|
url = _LATEST_ANDROID_URL
|
|
force_min = _ANDROID_FORCE_UPDATE_MIN
|
|
notes = _ANDROID_RELEASE_NOTES
|
|
else:
|
|
latest = settings.APP_VERSION
|
|
url = ""
|
|
force_min = "1.0.0"
|
|
notes = ""
|
|
|
|
current_tuple = _version_tuple(version)
|
|
latest_tuple = _version_tuple(latest)
|
|
force_tuple = _version_tuple(force_min)
|
|
|
|
has_update = current_tuple < latest_tuple
|
|
force_update = current_tuple < force_tuple
|
|
|
|
return {
|
|
"latest_version": latest,
|
|
"current_version": version,
|
|
"has_update": has_update,
|
|
"force_update": force_update,
|
|
"update_url": url or "",
|
|
"release_notes": notes,
|
|
}
|