diff --git a/components/progress-ring/progress-ring.js b/components/progress-ring/progress-ring.js index 396281f..87c0906 100644 --- a/components/progress-ring/progress-ring.js +++ b/components/progress-ring/progress-ring.js @@ -11,7 +11,10 @@ Component({ primaryLightColor: { type: String, value: '#FF8C5A' }, // Track (background ring) color. Caller passes a darker shade in dark mode // so the ring isn't an eye-searing light circle on a dark background. - trackColor: { type: String, value: '#EEEEEE' } + trackColor: { type: String, value: '#EEEEEE' }, + // Total elapsed seconds (since start). Shown in the ring center once the + // countdown hits 0 (overtime mode) - replaces the old +Xs badge. + elapsed: { type: Number, value: 0 } }, data: { @@ -20,10 +23,12 @@ Component({ }, observers: { - 'remaining, status, duration'() { + 'remaining, status, duration, elapsed'() { const texts = { idle: '准备开始', running: '坚持住', paused: '已暂停', completed: '完成!' } + // 倒计时阶段显示剩余;达标后 remaining 归零,改显总训练时长(overtime 模式) + const shown = this.data.remaining > 0 ? this.data.remaining : (this.data.elapsed || 0) this.setData({ - displayTime: util.formatTime(this.data.remaining), + displayTime: util.formatTime(shown), statusText: texts[this.data.status] || '' }) }, diff --git a/config.js b/config.js index c247a5e..23ab168 100644 --- a/config.js +++ b/config.js @@ -4,10 +4,10 @@ */ module.exports = { /** 应用版本号,外显在设置页「关于」 */ - version: 'v2.9', + version: 'v3.0', /** 最后更新日期,外显在设置页「关于」 */ - updatedAt: '2026-07-22', + updatedAt: '2026-07-25', /** 开发者名称 / 微信号,设置页点击可复制 */ developer: '刘承', diff --git a/pages/timer/timer.js b/pages/timer/timer.js index e6dbc14..964c7d2 100644 --- a/pages/timer/timer.js +++ b/pages/timer/timer.js @@ -16,7 +16,7 @@ Page({ isRunning: false, isPaused: false, isCompleted: false, - overtime: 0, + elapsed: 0, goalReached: false, hintTip: (config.postureTips && config.postureTips[0]) || '', todayTarget: 0, @@ -82,7 +82,8 @@ Page({ todayTarget: target, planDay: isFreeMode ? 0 : planDay, isFreeMode, - goalReached: false + goalReached: false, + elapsed: 0 }) if (this._timer) { @@ -104,7 +105,7 @@ Page({ onTick: (tick) => { this.setData({ remaining: tick.remaining > 0 ? tick.remaining : 0, - overtime: tick.remaining <= 0 ? tick.elapsed - this.data.duration : 0 + elapsed: tick.elapsed }) this._updateHintTip(tick) this._remind(tick) @@ -321,11 +322,24 @@ Page({ // 用自定义确认弹窗替代 wx.showModal: // 系统原生 modal 在 WebView stacking context 下 hit-test 偶发不稳, // 自定义 modal + catchtouchmove 与现有 completion-mask 同模式,行为更可靠。 - this.setData({ showStopConfirm: true }) + // 弹窗停留期间暂停计时,避免犹豫时间被计入训练时长 + this._stopWasPaused = this.data.isPaused + const patch = { showStopConfirm: true } + if (this.data.isRunning && !this.data.isPaused) { + this._timer.pause() + patch.isPaused = true + patch.status = 'paused' + } + this.setData(patch) }, onStopCancel() { this.setData({ showStopConfirm: false }) + // 弹窗前若正在计时(被 onStop 暂停),取消后恢复 + if (!this._stopWasPaused && this.data.isRunning) { + this._timer.resume() + this.setData({ isRunning: true, isPaused: false, status: 'running' }) + } }, onStopConfirm() { @@ -462,7 +476,7 @@ Page({ isRunning: false, isPaused: false, remaining: this.data.duration, - overtime: 0, + elapsed: 0, goalReached: false }) }, diff --git a/pages/timer/timer.wxml b/pages/timer/timer.wxml index fb5ce8b..91a0621 100644 --- a/pages/timer/timer.wxml +++ b/pages/timer/timer.wxml @@ -28,12 +28,13 @@ wx:if="{{status !== 'completed'}}" duration="{{duration}}" remaining="{{isCompleted ? 0 : remaining}}" + elapsed="{{elapsed}}" size="{{360}}" ringWidth="{{22}}" status="{{status}}" primaryColor="{{theme.primary}}" primaryLightColor="{{theme.primaryLight}}" - trackColor="{{isDark ? '#3A3A40' : '#EEEEEE'}}" + trackColor="{{elapsed >= duration ? '#00B578' : (isDark ? '#3A3A40' : '#EEEEEE')}}" > @@ -45,11 +46,6 @@ - - - - +{{overtime}}s - @@ -134,6 +130,24 @@ + + // 秒数 -> 分秒展示: 45->"45"/"秒", 83->"1分23"/"秒", 120->"2"/"分钟" + // 与 utils/util.js 的 formatDuration 口径一致(整分钟走分钟单位) + module.exports = { + numPart: function (s) { + s = Math.floor(s || 0) + if (s < 60) return '' + s + var m = Math.floor(s / 60) + var sec = s % 60 + return sec === 0 ? '' + m : m + '分' + sec + }, + unitPart: function (s) { + s = Math.floor(s || 0) + if (s < 60) return '秒' + return s % 60 === 0 ? '分钟' : '秒' + } + } + @@ -142,8 +156,8 @@ {{completionMessage}} - {{completionElapsed}} - + {{fmt.numPart(completionElapsed)}} + {{fmt.unitPart(completionElapsed)}} 本次训练 diff --git a/pages/timer/timer.wxss b/pages/timer/timer.wxss index d6ce55d..1971dad 100644 --- a/pages/timer/timer.wxss +++ b/pages/timer/timer.wxss @@ -66,30 +66,6 @@ 100% { opacity: 0; transform: translate(0, -80rpx) scale(0.4); } } -/* overtime badge */ -.overtime-badge { - position: absolute; - bottom: 10rpx; - left: 50%; - transform: translateX(-50%); - background: rgba(var(--success-rgb), 0.12); - border: 2rpx solid rgba(var(--success-rgb), 0.3); - color: var(--success); - padding: 8rpx 24rpx; - border-radius: 24rpx; - font-size: 28rpx; - font-weight: 600; - display: flex; - align-items: center; - gap: 6rpx; - animation: popIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); -} - -.overtime-icon { - width: 28rpx; - height: 28rpx; -} - /* ---- hint section ---- */ .hint-section { margin-top: 36rpx; @@ -296,6 +272,11 @@ text-shadow: 0 4rpx 12rpx rgba(var(--primary-rgb), 0.2); } +/* >= 60 秒时数字部分变成「X分Y」,字符变多,缩小字号避免撑破卡片 */ +.completion-number--long { + font-size: 140rpx; +} + .completion-unit { font-size: 36rpx; font-weight: 600; diff --git a/project.config.json b/project.config.json index 9d57d29..a42b5bc 100644 --- a/project.config.json +++ b/project.config.json @@ -2,7 +2,10 @@ "description": "平板支撑训练小程序", "packOptions": { "ignore": [ - { "type": "glob", "value": ".!*" } + { + "value": ".!*", + "type": "glob" + } ], "include": [] },