fix(ui): 多项 UI 修复 — 弹窗遮挡/按钮可见性/暗黑闪烁/云函数版本

- 计划编辑弹窗移出 .container 避免 fixed 降级 + 修复滚动
- dock bottom 40rpx→8rpx 紧贴底部, sheet padding 同步调整
- 计划编辑器取消/恢复默认按钮可见性修复(bg 匹配容器)
- ui-btn--danger 按钮可见性修复
- 清除确认弹窗跟随暗黑模式切换
- icons.js build() 中 Fill 路径覆盖 outlined 路径修复
- plan.js getPlanDay 忽略 customPlans 修复
- darkMode.js 冗余三元简化
- util.js fileToDataURI fallback 可读性提升
- theme.js: BASE_VARS 与 getThemeStyle 统一来源, 去 50ms navbar 延迟
- app.wxss: 移除 page transition 和 background-color 减少闪白
- 云函数 wx-server-sdk 版本统一 ~2.6.3, tts cloud.init 一致化
- 闪白问题: wx.setBackgroundColor 三层防护(onLaunch/applyThemeToPage/switchTab)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-10 09:40:04 +08:00
parent d5121d349f
commit 1eff3d60c4
21 changed files with 104 additions and 76 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
const storage = require('../../utils/storage')
const themeMod = require('../../utils/theme')
const darkMod = require('../../utils/darkMode')
const planMod = require('../../utils/plan')
const iconsMod = require('../../utils/icons')
const cloud = require('../../utils/cloud')
const config = require('../../config')
const darkMod = require('../../utils/darkMode')
const util = require('../../utils/util')
/**
@@ -217,7 +217,7 @@ Page({
this.setData({ currentThemeId: id })
try {
const tb = this.getTabBar()
if (tb) tb.setData({ themeStyle: themeMod.getThemeStyle(theme) })
if (tb) tb.setData({ themeStyle: themeMod.getThemeStyle(theme, darkMod.getInitialDarkMode()) })
} catch (e) {}
themeMod.applyThemeToPage(this)
},
+28 -22
View File
@@ -197,12 +197,14 @@
<text class="about-copy">Made with ❤️ for better fitness</text>
</view>
</ui-card>
</view>
<!-- /container — 关闭在这里,让下面的弹窗 fixed 相对视口而非 .container -->
<!-- 训练计划编辑器:用普通 view 不用 ui-modal,
因为 WeChat 自定义组件根元素上 position: fixed 会被吃,导致 body 被推到容器末尾。
普通 view 的 position: fixed 在小程序里 100% 生效。 -->
<view wx:if="{{showPlanEditor}}" class="plan-editor-mask" catchtouchmove="onNoop">
<view class="plan-editor-mask__bg" bindtap="onCloseEditor"></view>
<view wx:if="{{showPlanEditor}}" class="plan-editor-mask" style="{{themeStyle}}">
<view class="plan-editor-mask__bg" bindtap="onCloseEditor" catchtouchmove="onNoop"></view>
<view class="plan-editor-sheet" catchtap="onNoop">
<view class="plan-editor-handle"></view>
<view class="editor-title">编辑训练计划</view>
@@ -284,33 +286,37 @@
<view class="editor-action-reset" wx:if="{{editingIsCustom}}" bindtap="onResetPlan">
<text>恢复默认</text>
</view>
<view class="editor-action-cancel" bindtap="onCloseEditor">
<text>取消</text>
</view>
<view class="editor-action-save" bindtap="onSavePlan">
<text>保存</text>
</view>
</view>
<text class="editor-cancel" bindtap="onCloseEditor">取消</text>
</view>
</view>
<!-- 清除数据确认弹窗:用自定义 ui-modal 替代 wx.showModal
避免开发者工具中 wx.showModal 首次点击不关闭的问题 -->
<ui-modal
visible="{{showClearConfirm}}"
position="center"
showHandle="{{false}}"
bind:close="onCancelClear"
>
<view class="confirm-dialog" catchtap="onNoop">
<text class="confirm-title">清除数据</text>
<text class="confirm-desc">将删除所有训练记录和连续打卡数据,此操作不可恢复。确定继续吗?</text>
<view class="confirm-actions">
<view class="confirm-btn confirm-btn--cancel" bindtap="onCancelClear">
<text>取消</text>
</view>
<view class="confirm-btn confirm-btn--danger" bindtap="onConfirmClear">
<text>确定清除</text>
避免开发者工具中 wx.showModal 首次点击不关闭的问题
外层 view 注入 themeStyle,确保弹窗跟随暗黑模式切换。 -->
<view style="{{themeStyle}}">
<ui-modal
visible="{{showClearConfirm}}"
position="center"
showHandle="{{false}}"
bind:close="onCancelClear"
>
<view class="confirm-dialog" catchtap="onNoop">
<text class="confirm-title">清除数据</text>
<text class="confirm-desc">将删除所有训练记录和连续打卡数据,此操作不可恢复。确定继续吗?</text>
<view class="confirm-actions">
<view class="confirm-btn confirm-btn--cancel" bindtap="onCancelClear">
<text>取消</text>
</view>
<view class="confirm-btn confirm-btn--danger" bindtap="onConfirmClear">
<text>确定清除</text>
</view>
</view>
</view>
</view>
</ui-modal>
</view>
</ui-modal>
</view>
+17 -15
View File
@@ -370,12 +370,11 @@
box-sizing: border-box;
background: var(--card-bg);
border-radius: 32rpx 32rpx 0 0;
padding: 12rpx 32rpx 40rpx;
/* Sheet is z-index 1000 above the tab bar (z-index 999), but the tab bar
still visually covers the bottom of the sheet. Add the tab bar's
height (110rpx + safe area) to padding-bottom so "保存/取消" sit
clearly above the tab bar. */
padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
padding: 12rpx 32rpx 0;
/* Dock 原生 cover-view 层永远在 webview 上方。
dock 占视口底部: 8rpx(bottom) + 118rpx(高度) + 32rpx(shadow) ≈ 158rpx。
168rpx 给「保存/取消」留出 10rpx 可见间距。 */
padding-bottom: calc(168rpx + env(safe-area-inset-bottom));
animation: planEditorSlideUp 0.3s cubic-bezier(0.32, 0.72, 0, 1);
}
@@ -506,6 +505,7 @@
}
.editor-action-reset,
.editor-action-cancel,
.editor-action-save {
flex: 1;
height: 80rpx;
@@ -519,7 +519,7 @@
}
.editor-action-reset {
background: var(--card-bg);
background: var(--bg-soft);
color: var(--text-secondary);
border: 2rpx solid var(--border);
}
@@ -528,6 +528,16 @@
background: var(--bg-soft);
}
.editor-action-cancel {
background: var(--bg-soft);
color: var(--text-secondary);
border: 2rpx solid var(--border);
}
.editor-action-cancel:active {
background: var(--border);
}
.editor-action-save {
background: linear-gradient(135deg, var(--primary), var(--primary-light));
color: #FFFFFF;
@@ -538,14 +548,6 @@
opacity: 0.9;
}
.editor-cancel {
display: block;
text-align: center;
font-size: 26rpx;
color: var(--text-secondary);
padding: 12rpx 0 0;
}
/* ---- 清除数据确认弹窗 ---- */
.confirm-dialog {