diff --git a/backend/app/api/v1/endpoints/app_version.py b/backend/app/api/v1/endpoints/app_version.py index 69a2176..0e1d876 100644 --- a/backend/app/api/v1/endpoints/app_version.py +++ b/backend/app/api/v1/endpoints/app_version.py @@ -10,13 +10,47 @@ from app.schemas.app_version import AppVersionResponse router = APIRouter(prefix="/app", tags=["App版本"]) -@router.get("/version", response_model=AppVersionResponse) -async def check_version( - current: str = Query(..., description="当前 App 版本号,如 T1.0.0"), +@router.get("/check-update", response_model=AppVersionResponse) +async def check_update( db: AsyncSession = Depends(get_db), ): - """检测是否有新版本可用""" - # 查询最新的激活版本 + """ + 热更新检测接口(无需传参)。 + 查询 app_versions 表中 is_active=true 的最新记录, + 返回最新版本号、版本代码、WGT下载地址、更新说明。 + App 端自行对比本地版本号决定是否升级。 + """ + result = await db.execute( + select(AppVersion) + .where(AppVersion.is_active.is_(True)) + .order_by(desc(AppVersion.version_code)) + .limit(1) + ) + latest = result.scalar_one_or_none() + + if not latest: + return AppVersionResponse( + version="0", + version_code=0, + has_update=False, + ) + + return AppVersionResponse( + version=latest.version, + version_code=latest.version_code, + has_update=bool(latest.wgt_url), # 只有配置了 WGT 下载地址才算有效更新 + wgt_url=latest.wgt_url, + description=latest.description, + force_update=False, + ) + + +@router.get("/version", response_model=AppVersionResponse) +async def check_version( + current: str = Query(..., description="当前 App 版本号,如 T1.0.0"), + db: AsyncSession = Depends(get_db), +): + """检测是否有新版本可用(服务端对比)""" result = await db.execute( select(AppVersion) .where(AppVersion.is_active.is_(True)) @@ -26,14 +60,12 @@ async def check_version( latest = result.scalar_one_or_none() if not latest: - # 无版本记录 → 无更新 return AppVersionResponse( version=current, version_code=0, has_update=False, ) - # 比较版本号 has_update = latest.version_code > _parse_version_code(current) return AppVersionResponse( @@ -47,7 +79,7 @@ async def check_version( def _parse_version_code(version_str: str) -> int: - """从版本字符串提取数字版本号(兜底用最后3位)""" + """从版本字符串提取数字版本号""" import re nums = re.findall(r"\d+", version_str) if nums: diff --git a/track-uniapp/src/App.vue b/track-uniapp/src/App.vue index 1a57a3a..537d117 100644 --- a/track-uniapp/src/App.vue +++ b/track-uniapp/src/App.vue @@ -26,24 +26,35 @@ export default { }, methods: { // ========================================================== - // OTA 热更新 — 版本检测 + WGT 下载 + 静默安装 + // OTA 热更新雷达 — 版本检测 + WGT 下载 + 静默安装 // ========================================================== checkUpdate() { - // 获取当前 App 版本号 - const currentVersion = plus.runtime.version; + // 获取当前 App 的 WGT 资源版本号(uni-app 编译后的版本标识) + const sysInfo = uni.getSystemInfoSync(); + const currentWgtVersion = sysInfo.appWgtVersion || sysInfo.appVersion || "0"; + const currentVersionCode = this.parseVersionCode(currentWgtVersion); const baseUrl = uni.getStorageSync("env_base_url") || "http://172.16.0.198:8011/api/v1"; - console.log("[OTA] 当前版本:", currentVersion, "检测服务器:", baseUrl); + console.log("[OTA] 本地WGT版本:", currentWgtVersion, "| 数字版本:", currentVersionCode); uni.request({ - url: `${baseUrl}/app/version?current=${encodeURIComponent(currentVersion)}`, + url: `${baseUrl}/app/check-update`, method: "GET", timeout: 8000, success: (res) => { if (res.statusCode !== 200) return; const data = res.data; - if (!data || !data.has_update) { - console.log("[OTA] 已是最新版本"); + if (!data || !data.wgt_url) { + console.log("[OTA] 服务端无可用更新包"); + return; + } + + const serverVersionCode = data.version_code || 0; + console.log("[OTA] 服务端版本:", data.version, "| 数字版本:", serverVersionCode); + + // 客户端自行对比:服务端 > 本地 = 需要更新 + if (serverVersionCode <= currentVersionCode) { + console.log("[OTA] 已是最新版本,无需更新"); return; } @@ -56,6 +67,15 @@ export default { }); }, + /** 从版本字符串提取数字版本号用于对比 */ + parseVersionCode(versionStr) { + if (!versionStr) return 0; + const nums = versionStr.match(/\d+/g); + if (!nums) return 0; + // 取后三位拼成整数: "T1.0.1" → [1,0,1] → 101 + return parseInt(nums.slice(-3).join("").padEnd(3, "0").slice(0, 3), 10); + }, + downloadAndInstall(wgtUrl, newVersion, description) { if (!wgtUrl) { console.log("[OTA] 无 WGT 下载地址");