fix: 优化 TabBar 样式和调试信息展示,确保在 PWA 中正确贴底
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 1m16s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 1m16s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -405,7 +405,6 @@ Web/dist
|
|||||||
# ESLint
|
# ESLint
|
||||||
.eslintcache
|
.eslintcache
|
||||||
.aider*
|
.aider*
|
||||||
.screenshot/微信图片_20260211130722_17_37.png
|
.screenshot/*
|
||||||
.screenshot/微信图片_20260211131102_18_37.png
|
|
||||||
.screenshot/微信图片_20260211131103_19_37.png
|
|
||||||
.screenshot/微信图片_20260211131106_20_37.png
|
|
||||||
|
|||||||
102
Web/src/App.vue
102
Web/src/App.vue
@@ -19,6 +19,7 @@
|
|||||||
<van-tabbar
|
<van-tabbar
|
||||||
v-show="showTabbar"
|
v-show="showTabbar"
|
||||||
v-model="active"
|
v-model="active"
|
||||||
|
style="position: fixed !important; bottom: 0 !important; left: 0; right: 0;"
|
||||||
>
|
>
|
||||||
<van-tabbar-item
|
<van-tabbar-item
|
||||||
name="ccalendar"
|
name="ccalendar"
|
||||||
@@ -87,46 +88,56 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="debug-section">
|
<div class="debug-section">
|
||||||
<div class="debug-subtitle">
|
<div class="debug-subtitle">
|
||||||
容器高度
|
TabBar 存在性检查
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="debug-item"
|
||||||
|
:style="{ color: debugInfo.tabbarExists ? '#81c784' : '#ff4d4f', fontWeight: 'bold' }"
|
||||||
|
>
|
||||||
|
TabBar 元素存在: {{ debugInfo.tabbarExists ? '✓ 是' : '✗ 否' }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="debug-item"
|
||||||
|
:style="{ color: debugInfo.tabbarVisible ? '#81c784' : '#ff4d4f', fontWeight: 'bold' }"
|
||||||
|
>
|
||||||
|
TabBar 可见: {{ debugInfo.tabbarVisible ? '✓ 是' : '✗ 否' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
HTML 高度: {{ debugInfo.htmlHeight }}px
|
display: {{ debugInfo.tabbarDisplay }}
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
Body 高度: {{ debugInfo.bodyHeight }}px
|
opacity: {{ debugInfo.tabbarOpacity }}
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
App Root 高度: {{ debugInfo.appRootHeight }}px
|
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
App Root bottom: {{ debugInfo.appRootBottom }}px
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-section">
|
<div class="debug-section">
|
||||||
<div class="debug-subtitle">
|
<div class="debug-subtitle">
|
||||||
视口尺寸
|
TabBar 位置样式
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
窗口高度: {{ debugInfo.windowHeight }}px
|
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
视口高度: {{ debugInfo.viewportHeight }}px
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="debug-section">
|
|
||||||
<div class="debug-subtitle">
|
|
||||||
TabBar 位置
|
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
position: {{ debugInfo.tabbarPosition }}
|
position: {{ debugInfo.tabbarPosition }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="debug-item">
|
||||||
|
top (CSS): {{ debugInfo.tabbarTopStyle }}
|
||||||
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
bottom (CSS): {{ debugInfo.tabbarBottomStyle }}
|
bottom (CSS): {{ debugInfo.tabbarBottomStyle }}
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
top (实际): {{ debugInfo.tabbarTop }}px
|
left (实际): {{ debugInfo.tabbarLeft }}px
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
|
right (实际): {{ debugInfo.tabbarRight }}px
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="debug-item"
|
||||||
|
:style="{ fontWeight: 'bold', color: '#ff9800' }"
|
||||||
|
>
|
||||||
|
top (实际): {{ debugInfo.tabbarTop }}px
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="debug-item"
|
||||||
|
:style="{ fontWeight: 'bold', color: '#ff9800' }"
|
||||||
|
>
|
||||||
bottom (实际): {{ debugInfo.tabbarBottom }}px
|
bottom (实际): {{ debugInfo.tabbarBottom }}px
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -135,10 +146,10 @@
|
|||||||
TabBar 尺寸
|
TabBar 尺寸
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
height (实际): {{ debugInfo.tabbarHeight }}px
|
width: {{ debugInfo.tabbarWidth }}px
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
min-height: {{ debugInfo.tabbarMinHeight }}
|
height: {{ debugInfo.tabbarHeight }}px
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
padding-bottom: {{ debugInfo.tabbarPaddingBottom }}
|
padding-bottom: {{ debugInfo.tabbarPaddingBottom }}
|
||||||
@@ -146,23 +157,14 @@
|
|||||||
<div class="debug-item">
|
<div class="debug-item">
|
||||||
box-sizing: {{ debugInfo.tabbarBoxSizing }}
|
box-sizing: {{ debugInfo.tabbarBoxSizing }}
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-item">
|
|
||||||
安全区域底部: {{ debugInfo.safeAreaBottom }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="debug-section">
|
<div class="debug-section">
|
||||||
<div class="debug-subtitle">
|
<div class="debug-subtitle">
|
||||||
TabBar 定位检查
|
结果
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
z-index: {{ debugInfo.tabbarZIndex }}
|
|
||||||
</div>
|
|
||||||
<div class="debug-item">
|
|
||||||
transform: {{ debugInfo.tabbarTransform }}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="debug-item"
|
class="debug-item"
|
||||||
:style="{ color: debugInfo.distanceFromBottom === '0.00' ? '#81c784' : '#ff4d4f', fontWeight: 'bold' }"
|
:style="{ color: debugInfo.distanceFromBottom === '0.00' ? '#81c784' : '#ff4d4f', fontWeight: 'bold', fontSize: '12px' }"
|
||||||
>
|
>
|
||||||
距离底部: {{ debugInfo.distanceFromBottom }}px {{ debugInfo.distanceFromBottom === '0.00' ? '✓ 已贴底' : '✗ 未贴底' }}
|
距离底部: {{ debugInfo.distanceFromBottom }}px {{ debugInfo.distanceFromBottom === '0.00' ? '✓ 已贴底' : '✗ 未贴底' }}
|
||||||
</div>
|
</div>
|
||||||
@@ -361,14 +363,22 @@ const debugInfo = ref({
|
|||||||
windowHeight: 0,
|
windowHeight: 0,
|
||||||
viewportHeight: 0,
|
viewportHeight: 0,
|
||||||
safeAreaBottom: '0',
|
safeAreaBottom: '0',
|
||||||
|
tabbarExists: false,
|
||||||
|
tabbarVisible: false,
|
||||||
tabbarHeight: 0,
|
tabbarHeight: 0,
|
||||||
|
tabbarWidth: 0,
|
||||||
tabbarBottom: 0,
|
tabbarBottom: 0,
|
||||||
tabbarTop: 0,
|
tabbarTop: 0,
|
||||||
|
tabbarLeft: 0,
|
||||||
|
tabbarRight: 0,
|
||||||
tabbarPaddingBottom: '0',
|
tabbarPaddingBottom: '0',
|
||||||
tabbarPosition: '',
|
tabbarPosition: '',
|
||||||
tabbarBottomStyle: '',
|
tabbarBottomStyle: '',
|
||||||
|
tabbarTopStyle: '',
|
||||||
tabbarMinHeight: '',
|
tabbarMinHeight: '',
|
||||||
tabbarBoxSizing: '',
|
tabbarBoxSizing: '',
|
||||||
|
tabbarDisplay: '',
|
||||||
|
tabbarOpacity: '',
|
||||||
appRootHeight: 0,
|
appRootHeight: 0,
|
||||||
appRootBottom: 0,
|
appRootBottom: 0,
|
||||||
bodyHeight: 0,
|
bodyHeight: 0,
|
||||||
@@ -393,17 +403,30 @@ const updateDebugInfo = () => {
|
|||||||
|
|
||||||
// 获取 TabBar 的实际尺寸和位置
|
// 获取 TabBar 的实际尺寸和位置
|
||||||
const tabbar = document.querySelector('.van-tabbar')
|
const tabbar = document.querySelector('.van-tabbar')
|
||||||
|
debugInfo.value.tabbarExists = !!tabbar
|
||||||
|
debugInfo.value.tabbarVisible = tabbar ? window.getComputedStyle(tabbar).display !== 'none' : false
|
||||||
|
|
||||||
if (tabbar) {
|
if (tabbar) {
|
||||||
const rect = tabbar.getBoundingClientRect()
|
const rect = tabbar.getBoundingClientRect()
|
||||||
const styles = window.getComputedStyle(tabbar)
|
const styles = window.getComputedStyle(tabbar)
|
||||||
debugInfo.value.tabbarHeight = rect.height.toFixed(2)
|
debugInfo.value.tabbarHeight = rect.height.toFixed(2)
|
||||||
|
debugInfo.value.tabbarWidth = rect.width.toFixed(2)
|
||||||
debugInfo.value.tabbarBottom = rect.bottom.toFixed(2)
|
debugInfo.value.tabbarBottom = rect.bottom.toFixed(2)
|
||||||
debugInfo.value.tabbarPaddingBottom = styles.paddingBottom
|
debugInfo.value.tabbarPaddingBottom = styles.paddingBottom
|
||||||
debugInfo.value.tabbarTop = rect.top.toFixed(2)
|
debugInfo.value.tabbarTop = rect.top.toFixed(2)
|
||||||
|
debugInfo.value.tabbarLeft = rect.left.toFixed(2)
|
||||||
|
debugInfo.value.tabbarRight = rect.right.toFixed(2)
|
||||||
debugInfo.value.tabbarPosition = styles.position
|
debugInfo.value.tabbarPosition = styles.position
|
||||||
debugInfo.value.tabbarBottomStyle = styles.bottom
|
debugInfo.value.tabbarBottomStyle = styles.bottom
|
||||||
|
debugInfo.value.tabbarTopStyle = styles.top
|
||||||
debugInfo.value.tabbarMinHeight = styles.minHeight
|
debugInfo.value.tabbarMinHeight = styles.minHeight
|
||||||
debugInfo.value.tabbarBoxSizing = styles.boxSizing
|
debugInfo.value.tabbarBoxSizing = styles.boxSizing
|
||||||
|
debugInfo.value.tabbarDisplay = styles.display
|
||||||
|
debugInfo.value.tabbarOpacity = styles.opacity
|
||||||
|
|
||||||
|
// 检查是否有 transform 或其他可能影响定位的样式
|
||||||
|
debugInfo.value.tabbarTransform = styles.transform
|
||||||
|
debugInfo.value.tabbarZIndex = styles.zIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取 app-root 的高度
|
// 获取 app-root 的高度
|
||||||
@@ -418,15 +441,8 @@ const updateDebugInfo = () => {
|
|||||||
debugInfo.value.bodyHeight = document.body.getBoundingClientRect().height.toFixed(2)
|
debugInfo.value.bodyHeight = document.body.getBoundingClientRect().height.toFixed(2)
|
||||||
debugInfo.value.htmlHeight = document.documentElement.getBoundingClientRect().height.toFixed(2)
|
debugInfo.value.htmlHeight = document.documentElement.getBoundingClientRect().height.toFixed(2)
|
||||||
|
|
||||||
// 检查是否有 transform 或其他可能影响定位的样式
|
|
||||||
if (tabbar) {
|
|
||||||
const styles = window.getComputedStyle(tabbar)
|
|
||||||
debugInfo.value.tabbarTransform = styles.transform
|
|
||||||
debugInfo.value.tabbarZIndex = styles.zIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算 TabBar 距离屏幕底部的实际距离
|
// 计算 TabBar 距离屏幕底部的实际距离
|
||||||
debugInfo.value.distanceFromBottom = (window.innerHeight - debugInfo.value.tabbarBottom).toFixed(2)
|
debugInfo.value.distanceFromBottom = (window.innerHeight - parseFloat(debugInfo.value.tabbarBottom || 0)).toFixed(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -31,12 +31,16 @@
|
|||||||
--icon-star: #FF6B6B;
|
--icon-star: #FF6B6B;
|
||||||
--icon-coffee: #FCD34D;
|
--icon-coffee: #FCD34D;
|
||||||
|
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
--border-color: #E5E7EB;
|
||||||
|
|
||||||
/* ============ 布局变量 ============ */
|
/* ============ 布局变量 ============ */
|
||||||
|
|
||||||
/* 间距 */
|
/* 间距 */
|
||||||
--spacing-xs: 2px;
|
--spacing-xs: 2px;
|
||||||
--spacing-sm: 4px;
|
--spacing-sm: 4px;
|
||||||
--spacing-md: 8px
|
--spacing-md: 8px;
|
||||||
--spacing-lg: 12px;
|
--spacing-lg: 12px;
|
||||||
--spacing-xl: 16px;
|
--spacing-xl: 16px;
|
||||||
--spacing-2xl: 20px;
|
--spacing-2xl: 20px;
|
||||||
@@ -72,6 +76,9 @@
|
|||||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.05);
|
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.05);
|
||||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.05);
|
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
--border-color: #E5E7EB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============ 深色主题 ============ */
|
/* ============ 深色主题 ============ */
|
||||||
@@ -137,8 +144,7 @@
|
|||||||
background-color: var(--bg-tertiary);
|
background-color: var(--bg-tertiary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 边框颜色 */
|
|
||||||
--border-color: #E5E7EB;
|
|
||||||
|
|
||||||
/* 布局容器 */
|
/* 布局容器 */
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
|
|||||||
@@ -167,8 +167,9 @@ onMounted(() => {
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
// 基础高度 + 安全区域,确保在PWA中正确贴底
|
// 导航栏实际高度 62px + 上下 padding (12px + 21px) = 95px + 安全区域
|
||||||
height: calc(95px + env(safe-area-inset-bottom, 0px));
|
// 修改:直接贴底,只保留必要的 padding 和安全区域
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
@@ -176,9 +177,9 @@ onMounted(() => {
|
|||||||
/* 亮色模式渐变(默认) */
|
/* 亮色模式渐变(默认) */
|
||||||
.gradient-fade {
|
.gradient-fade {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(180deg, rgba(246, 247, 248, 0) 0%, rgba(246, 247, 248, 1) 50%);
|
background: linear-gradient(180deg, rgba(246, 247, 248, 0) 0%, rgba(246, 247, 248, 1) 50%);
|
||||||
padding: 12px 21px 21px 21px;
|
padding: 12px 21px;
|
||||||
|
padding-bottom: calc(21px + env(safe-area-inset-bottom, 0px));
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@@ -233,13 +234,6 @@ onMounted(() => {
|
|||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 适配安全区域 */
|
|
||||||
@supports (padding-bottom: env(safe-area-inset-bottom)) {
|
|
||||||
.gradient-fade {
|
|
||||||
padding-bottom: calc(21px + env(safe-area-inset-bottom));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式适配 */
|
/* 响应式适配 */
|
||||||
@media (max-width: 375px) {
|
@media (max-width: 375px) {
|
||||||
.gradient-fade {
|
.gradient-fade {
|
||||||
|
|||||||
Reference in New Issue
Block a user