feat: 添加客户端更新检测功能,支持版本检查和更新提示;更新相关组件和样式
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
from contextlib import asynccontextmanager
|
||||
@@ -15,6 +16,7 @@ from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .admin import admin_login, admin_logout, admin_page
|
||||
from .config import settings
|
||||
@@ -120,6 +122,52 @@ async def download_installer():
|
||||
return JSONResponse({"detail": "安装包不存在"}, status_code=404)
|
||||
|
||||
|
||||
# ---------- 客户端更新检测(仅 Windows:比对版本 → 下发安装包下载地址) ----------
|
||||
|
||||
def _latest_installer():
|
||||
"""返回 backend/ 下最新(按文件名排序取最大)的 *.setup.exe。"""
|
||||
for f in sorted(_DOWNLOAD_ROOT.glob("*setup.exe"), reverse=True):
|
||||
if f.is_file():
|
||||
return f
|
||||
return None
|
||||
|
||||
|
||||
def _version_from_name(name: str) -> str:
|
||||
"""从安装包文件名解析版本,如 `..._0.1.0_x64-setup.exe` → `0.1.0`。"""
|
||||
m = re.search(r"_(\d+\.\d+(?:\.\d+)?)", name or "")
|
||||
return m.group(1) if m else ""
|
||||
|
||||
|
||||
def _version_key(v: str):
|
||||
return tuple(int(x) for x in v.split(".") if x.isdigit())
|
||||
|
||||
|
||||
class UpdateCheckBody(BaseModel):
|
||||
current: str = "" # 前端上报的当前版本,如 0.1.0
|
||||
|
||||
|
||||
@app.post("/api/update/check", include_in_schema=False)
|
||||
async def update_check(body: UpdateCheckBody):
|
||||
"""检测更新:返回最新版本号、安装包下载地址、是否需要更新(仅 Windows)。"""
|
||||
inst = _latest_installer()
|
||||
if not inst:
|
||||
return {"ok": False, "error": "installer not found"}
|
||||
latest = _version_from_name(inst.name)
|
||||
current = (body.current or "").strip()
|
||||
update_available = False
|
||||
if latest and current and current != latest:
|
||||
update_available = _version_key(latest) > _version_key(current)
|
||||
elif latest and not current:
|
||||
update_available = True
|
||||
return {
|
||||
"ok": True,
|
||||
"latest_version": latest,
|
||||
"installer_name": inst.name,
|
||||
"download_url": "/download",
|
||||
"update_available": update_available,
|
||||
}
|
||||
|
||||
|
||||
# ---------- 前端静态托管 + SPA 回退(浏览器直接访问 :8000 即可) ----------
|
||||
|
||||
@app.get("/{path:path}", include_in_schema=False)
|
||||
|
||||
Reference in New Issue
Block a user