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": []
},