From a915a08f4d62e1413d5b465ce6e869447c20f175 Mon Sep 17 00:00:00 2001 From: "jif2.zhang" Date: Sat, 24 Oct 2026 08:05:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20OTA=20=E5=90=8E=E9=A1=B6?= =?UTF-8?q?=E9=83=A8=E5=86=85=E5=AE=B9=E9=A1=B6=E5=88=B0=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=A0=8F=20(=E6=9C=AA=E8=AE=A9=E5=87=BA=E7=94=B5=E9=87=8F/?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=E6=A0=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现象: 直装 APK 时头部正常让开状态栏; 经 OTA 升级到 V0.2 前端后, 页面从屏幕最顶部开始, 与电量/信号栏重叠. 根因: 顶部让位一直只依赖 antd-mobile 的 , 它只是一个空 div, 高度完全来自 env(safe-area-inset-top). 而 Android WebView (Tauri) 下该变量常返回 0. 旧版每页顶部都有 45px 的 antd-mobile , 视觉上兜住了状态栏, 掩盖了 inset 失效; V0.2 把 NavBar 换成 23px 的 PageHeader (「我」页甚至无头部), 兜底消失后问题暴露. 与 OTA 机制本身无关. 修复: - MobileShell: 换成 .app-safe-top, 高度由 --safe-top 控制 - main.jsx: 新增 calibrateSafeTop(), 用临时元素测 env(safe-area-inset-top), 并与 screen.height - visualViewport.height 交叉校验, 取较大值写入 --safe-top; 两者都不可用时保底 24px; 监听旋转/视口变化重算 - globals.css: --safe-top 保留 env() 表达式, 新增 .app-safe-top 样式 这样无论 WebView 是否上报 inset, 顶部都能正确让位. --- src/layouts/MobileShell.jsx | 13 ++++++----- src/main.jsx | 45 +++++++++++++++++++++++++++++++++++++ src/styles/globals.css | 14 +++++++++++- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/layouts/MobileShell.jsx b/src/layouts/MobileShell.jsx index 9b07fa1..7e2eac6 100644 --- a/src/layouts/MobileShell.jsx +++ b/src/layouts/MobileShell.jsx @@ -1,13 +1,16 @@ import { useEffect, useState } from 'react' import { Outlet, useLocation } from 'react-router-dom' -import { SafeArea } from 'antd-mobile' import BottomNav from '../components/BottomNav.jsx' // 移动端应用外壳 -// - 顶部 SafeArea: 让出手机状态栏高度 +// - 顶部安全区: 用 --safe-top 撑开 (由 main.jsx 的 calibrateSafeTop 实测校准) // - 中间
: flex:1 可滚动主区 // - 底部 TabBar: antd-mobile TabBar 自带底部安全区 -// 解决: 状态栏遮挡/底部 TabBar 遮挡/左右贴边 +// +// 注意: 这里不再用 antd-mobile 的 . +// 它只是一个空 div, 高度完全依赖 env(safe-area-inset-top); 而 Android WebView +// (Tauri) 下该变量常为 0, 会导致内容顶到状态栏底下 —— V0.2 把 45px 的 NavBar +// 换成 23px 的 PageHeader 后这个问题就暴露了. 改用可控高度的 div + JS 校准. export default function MobileShell() { const location = useLocation() // pathname 变化时给页面容器加动画 class (仅播放入场动画, 不重挂载子树, @@ -21,7 +24,7 @@ export default function MobileShell() { return (
- +