feat: 循环训练模式 + 语音补全 / 屏幕常亮 / 卡片渲染修复
循环训练(circuit)
- 新增 utils/circuitTimer.js 状态机: 工作->休息->...->完成, stop() 返回有效撑总秒(不含休息)
- 首页新增「循环训练·分组练习」入口 + stepper 配置弹窗
- 配置本地持久化 circuit_config(每组时长/组数/休息/每周目标), 下次自动预填
- 记录以 planId:'circuit' + mode:'circuit' 落库, duration 语义不变 -> 排行榜/统计/每日计划进度零改动
- 记录页展示「循环 N组xMs·休Rs」
计时器顶部循环进度面板
- 组进度点阵按组数等分铺满(flex:1 1 0, 去掉 max-width 封顶), 当前组以增高而非加宽强调
- 大号「X/Y 组」+ 四态阶段徽章(撑住/休息中/准备开始/已暂停) + 累计秒数副行
- 状态灯用纯 CSS 圆点(SVG 图标颜色烤死在 data URI 里, CSS 改不动)
- 超过 15 组自动降级为线性进度条; 面板不设固定高度, 规避真机大字体档裁字
修复: 循环训练全程无语音
- 根因: circuit 的 onTick 走 _circuitCue(只有震动), 从未调用 _remind
- 接入整场进度播报, 基准为 sets x holdPerSet(而非每组), 避免 4 组播 4 次「已完成一半」
- 新增 restStart/nextSet/lastSet 三条不含数字的词条, 客户端与 tts 云函数词表同步
- 修复必然撞车的时序: 偶数组时 halfway 与休息切换同一 tick, 加 2.6s 优先窗口让位
- 防吵闸门: 每组 <10s 不播过场语音, 休息 <5s 不播; 预载按模式取词条
训练期间屏幕常亮
- wx.setKeepScreenOn: onStart 开 / onUnload 关 / onShow 在 isRunning 时重新武装
- 切后台再回来该标志会被系统清掉, 故必须重新武装, 否则后半程丢语音与震动
- 低基础库与 Android 省电模式静默降级, 不弹 toast
修复: 首页打卡卡片左侧两个竖条
- 根因: ui-card 宿主节点无 display 声明为 inline, 页面侧加的 border 被打断成两个零宽行盒碎片
- ui-card 加 :host{display:block}, margin-bottom 从内部 view 上提到宿主
- 高亮由 border 改为 box-shadow spread 描边(不占布局, 无跳动) + 补 border-radius
- 连带修复失效的交错入场: nth-child 跨组件边界恒匹配 1, 改为 index 属性驱动内联 animation-delay, 14 处调用点补序号
注意: tts 云函数需重新部署, 否则新增的 3 条词条返回 Unknown prompt key(静默降级不报错)
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# 2026-07-31 工作日志
|
||||
|
||||
## 排行榜新增「耐力榜」(endurance)
|
||||
- 需求:全局单次最久 top10,显示该次日期;本人未上榜则在底部 my-bar 显示最佳成绩+产生时间。
|
||||
- 云函数 `cloudfunctions/leaderboard/index.js`:
|
||||
- `_buildFromScan` 新增 `endurance` 分支:遍历每人全部 records 取 `max(duration)`,记下 `bestDate`(该条 r.date);`ranked`/`myEntry` 映射均透传 `bestDate`。
|
||||
- `exports.main` 放行 `endurance`;`_rebuildSnapshots` 循环加入 `endurance`(随定时器每 4 分钟重算,存 top500)。
|
||||
- `bestDate` 经 `publicEntry` 的 `...publicData` 展开自动进快照/响应,data.js 无需改。
|
||||
- 客户端 `pages/leaderboard/leaderboard.js`:
|
||||
- `periods` 加 `{key:'endurance',label:'耐力',maxRank:10}`(日/月/年保持 config.leaderboardMaxRank=50)。
|
||||
- `fetchRank` 按当前周期取 `maxRank`(不再写死)。
|
||||
- `_applyResult` 计算 `subText`(耐力=格式化 bestDate 去秒,其余=`N次`);新增 `_formatBestDate` 辅助。
|
||||
- `_applyLocal` 加耐力兜底分支(本地 records 取 max+日期);分享 map 加 `endurance:'耐力'`。
|
||||
- wxml 5 处 `{{x.sessions}}次` → `{{x.subText}}`(领奖台3/列表1/my-bar1)。
|
||||
- wxss `.podium-base__label` 加 `nowrap`+省略号,防窄屏日期串换行撑破领奖台底座。
|
||||
- 校验:`node --check` 云函数+客户端均通过;grep 确认无 `sessions}}次` 残留。
|
||||
- **待办**:改云函数后须重新部署(定时器随部署注册),否则 endurance 周期不生效。改动尚未提交推送,等用户确认。
|
||||
|
||||
## 领奖台底座日期时间拆两行(耐力榜)
|
||||
- 用户要求领奖台底座的「单次日期」拆成日期+时间两行。
|
||||
- `leaderboard.js`:`_applyResult`/`_applyLocal` 给每条耐力榜数据补 `subDate`(YYYY-MM-DD)、`subTime`(HH:MM) 两字段(新增 `_splitBestDate` 从 bestDate 截断);`subText` 仍保留供列表/my-bar 单行使用。
|
||||
- `leaderboard.wxml`:领奖台 3 处 `<text>` 改为 `<view>` 容器 + `wx:if activePeriod==='endurance'` 渲染两行 `podium-base__date`/`podium-base__time`,否则单行 `subText`。
|
||||
- `leaderboard.wxss`:`.podium-base__label` 由单行绝对定位 text 改为 flex column 居中 view(去掉 nowrap/ellipsis),新增 `.podium-base__date`(20rpx)/`.podium-base__time`(18rpx) 缩小字号以适配最矮的第3名底座(48rpx)。
|
||||
- 校验:`node --check` 通过,grep 确认 subDate/subTime/_splitBestDate 已接入。
|
||||
|
||||
## 领奖台第3名贴顶修复 + 顶部文案
|
||||
- 第3名底座仅 48rpx,两行日期时间文字溢出贴顶。统一抬高三阶底座高度:first 96 / second 64→80 / third 48→64(梯度 96/80/64)。
|
||||
- `.podium-base__label` bottom 8→6rpx;耐力榜两行字号缩小:date 20→18rpx、time 18→16rpx。两级余量足以抗微信字体缩放放大。
|
||||
- 领奖台顶部新增哲理文案(仅耐力榜显示,`wx:if activePeriod==='endurance'`):
|
||||
「平板支撑不是一场和时间的恋爱。撑得越久,不一定越好;真正重要的,是每一秒都没有辜负身体。」
|
||||
- 文案配置进 `config.js` 新增 `leaderboardPodiumSlogan`;`leaderboard.js` data 挂 `podiumSlogan: config.leaderboardPodiumSlogan`;wxml 在 `<block wx:else>` 内 podium 前插入 `.podium-slogan` 块;wxss 新增 `.podium-slogan` 样式(居中、淡色、引用感卡片)。
|
||||
- 校验:`node --check` 客户端 + config 均通过;grep 确认 podiumSlogan / leaderboardPodiumSlogan / podium-slogan 三处链路完整。
|
||||
|
||||
## 顶部文案配色与样式微调
|
||||
- 首版 `.podium-slogan` 为灰底灰字,用户认为不好看 → 改为「极淡橙渐变底 + 主色描边 + 主色微光阴影 + 顶部主色大引号(`::before` `\201C`)点睛」金句卡片质感(用 `--primary-rgb`/`--text` 变量,深色模式自适应)。
|
||||
- 用户再要求:去掉引号、文案改斜体。已删除 `.podium-slogan::before` 块;主块加 `font-style: italic`,并把 padding-top 从 26rpx 收到 22rpx 抵消去掉引号后的顶部留白。纯样式改动,无逻辑、无需重新部署云函数。
|
||||
|
||||
## 首页去掉 toolbar 上方小提示卡片
|
||||
- 删除首页底部随机姿势提示卡片(homeTip):wxml 移除 tip-card 整块、wxss 清理 .tip-card/.tip-icon/.tip-text、js 移除 data.homeTip + 随机取 postureTips 逻辑 + setData 引用。
|
||||
- `config.postureTips` 仍被训练页(timer)复用,保留不动。纯前端,编译即可生效,无需重新部署云函数。
|
||||
- 提交:`deaff72`(含 config.js v3.02→v3.1 升版 + 顶部文案标点修正,均无害)。
|
||||
|
||||
## 三个 P2 小修(体检发现)
|
||||
1. **离线兜底缺"N次"**:`pages/leaderboard/leaderboard.js` `_applyLocal` 非 endurance 分支 entry 漏 `subText`,补 `subText: \`${sessions}次\``,与云端 `_applyResult` 对齐。断网/未部署时底部成绩栏不再留白。
|
||||
2. **同天二次训练文案虚高 1 天**:`pages/timer/timer.js` `_detectCelebrationLevel` 未判断 streak.lastDate 是否已为今天。updateStreak 对同天再次训练不递增,故 `nextStreak` 加 `lastIsToday` 判断:是则取 `streak.count`,否则取 `count+1`。只错文案、存储连胜数本就对。用 `storage.getToday().substring(0,10)` 比 lastDate(timer.js 未引入 util,故未用 util.dateOnly)。
|
||||
3. **热力图日期解析脆弱**:`components/calendar-heatmap/calendar-heatmap.js` line 64 原 `parseInt(r.date.split('-')[2])` 靠 parseInt 侥幸解析 `DD HH:MM:SS`。改为 `parseInt(util.dateOnly(r.date).split('-')[2], 10)`,与全局日期规范统一(该组件已引入 util)。
|
||||
- 校验:`node --check` 三文件均通过;grep 确认三处改动已落实。纯前端,无需重新部署云函数。尚未提交推送,等用户确认。
|
||||
|
||||
## 配置澄清
|
||||
- `config.js` 的 `leaderboardMaxRank: 50` 是**客户端显示行数上限**(日/月/年榜 50、耐力榜 10)。
|
||||
- 云函数 `cloudfunctions/leaderboard/index.js:11` `SNAPSHOT_TOP = 500` 是**快照每周期存储人数上限**(写死在云函数,不读 config)。底部「我的成绩」栏靠 findMyEntry 在存下的完整 500 里找本人,故排 51~500 也能在底部显示;仅走缓存快照时受 500 限制(force 实时重算路径在完整全量榜找人,不受 500 限)。两数字各管一摊。
|
||||
Reference in New Issue
Block a user