3532d0111b
循环训练(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(静默降级不报错)
6.2 KiB
6.2 KiB
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__labelbottom 8→6rpx;耐力榜两行字号缩小:date 20→18rpx、time 18→16rpx。两级余量足以抗微信字体缩放放大。- 领奖台顶部新增哲理文案(仅耐力榜显示,
wx:if activePeriod==='endurance'): 「平板支撑不是一场和时间的恋爱。撑得越久,不一定越好;真正重要的,是每一秒都没有辜负身体。」 - 文案配置进
config.js新增leaderboardPodiumSlogan;leaderboard.jsdata 挂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 小修(体检发现)
- 离线兜底缺"N次":
pages/leaderboard/leaderboard.js_applyLocal非 endurance 分支 entry 漏subText,补subText: \${sessions}次`,与云端_applyResult` 对齐。断网/未部署时底部成绩栏不再留白。 - 同天二次训练文案虚高 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)。 - 热力图日期解析脆弱:
components/calendar-heatmap/calendar-heatmap.jsline 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:11SNAPSHOT_TOP = 500是快照每周期存储人数上限(写死在云函数,不读 config)。底部「我的成绩」栏靠 findMyEntry 在存下的完整 500 里找本人,故排 51~500 也能在底部显示;仅走缓存快照时受 500 限制(force 实时重算路径在完整全量榜找人,不受 500 限)。两数字各管一摊。