mirror of
https://github.com/ZeroCatDev/Classworks.git
synced 2026-03-21 09:13:10 +00:00
添加倒计时结束弹框功能,优化用户体验,支持超时提示和倒计时格式化显示
This commit is contained in:
parent
f1838a891b
commit
4cd948ff63
@ -38,6 +38,7 @@
|
|||||||
v-model="showFullscreen"
|
v-model="showFullscreen"
|
||||||
fullscreen
|
fullscreen
|
||||||
:scrim="false"
|
:scrim="false"
|
||||||
|
persistent
|
||||||
transition="dialog-bottom-transition"
|
transition="dialog-bottom-transition"
|
||||||
>
|
>
|
||||||
<v-card
|
<v-card
|
||||||
@ -111,7 +112,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="fullscreen-extra mt-8 text-medium-emphasis d-flex ga-8">
|
<div class="fullscreen-extra mt-8 text-medium-emphasis d-flex ga-8">
|
||||||
<div class="text-center">
|
<!--<div class="text-center">
|
||||||
<div class="text-h6 font-weight-bold">
|
<div class="text-h6 font-weight-bold">
|
||||||
{{ dayOfYear }}
|
{{ dayOfYear }}
|
||||||
</div>
|
</div>
|
||||||
@ -134,7 +135,7 @@
|
|||||||
<div class="text-caption">
|
<div class="text-caption">
|
||||||
距离新年
|
距离新年
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-tabs-window-item>
|
</v-tabs-window-item>
|
||||||
@ -379,6 +380,61 @@
|
|||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
|
<!-- 倒计时结束弹框 -->
|
||||||
|
<v-dialog
|
||||||
|
v-model="countdownEndedDialog"
|
||||||
|
max-width="480"
|
||||||
|
persistent
|
||||||
|
>
|
||||||
|
<v-card rounded="xl">
|
||||||
|
<v-card-title class="d-flex align-center justify-center pt-6">
|
||||||
|
<v-icon
|
||||||
|
color="error"
|
||||||
|
size="32"
|
||||||
|
class="mr-2"
|
||||||
|
icon="mdi-alarm"
|
||||||
|
/>
|
||||||
|
时间到!
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text class="text-center pb-2">
|
||||||
|
<div
|
||||||
|
class="text-h4 font-weight-bold my-4"
|
||||||
|
style="font-variant-numeric: tabular-nums;"
|
||||||
|
>
|
||||||
|
{{ formatCountdownTotal(countdownTotal) }}
|
||||||
|
</div>
|
||||||
|
<div class="text-body-1 text-medium-emphasis">
|
||||||
|
设定的倒计时已结束
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="overtimeElapsed > 0"
|
||||||
|
class="mt-4"
|
||||||
|
>
|
||||||
|
<v-chip
|
||||||
|
color="error"
|
||||||
|
variant="tonal"
|
||||||
|
size="large"
|
||||||
|
prepend-icon="mdi-clock-alert-outline"
|
||||||
|
>
|
||||||
|
已超时 {{ overtimeDisplay }}
|
||||||
|
</v-chip>
|
||||||
|
</div>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions class="justify-center pb-6">
|
||||||
|
<v-btn
|
||||||
|
color="primary"
|
||||||
|
variant="tonal"
|
||||||
|
size="large"
|
||||||
|
rounded="xl"
|
||||||
|
prepend-icon="mdi-check"
|
||||||
|
@click="dismissCountdownDialog"
|
||||||
|
>
|
||||||
|
知道了
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
<!-- 设置弹框 -->
|
<!-- 设置弹框 -->
|
||||||
<v-dialog
|
<v-dialog
|
||||||
v-model="showSettings"
|
v-model="showSettings"
|
||||||
@ -471,6 +527,11 @@ export default {
|
|||||||
{ label: '30 分钟', h: 0, m: 30, s: 0 },
|
{ label: '30 分钟', h: 0, m: 30, s: 0 },
|
||||||
{ label: '1 小时', h: 1, m: 0, s: 0 },
|
{ label: '1 小时', h: 1, m: 0, s: 0 },
|
||||||
],
|
],
|
||||||
|
// 倒计时结束弹框
|
||||||
|
countdownEndedDialog: false,
|
||||||
|
overtimeElapsed: 0,
|
||||||
|
overtimeTimer: null,
|
||||||
|
overtimeLastTick: null,
|
||||||
// 秒表
|
// 秒表
|
||||||
stopwatchRunning: false,
|
stopwatchRunning: false,
|
||||||
stopwatchElapsed: 0, // 已走毫秒
|
stopwatchElapsed: 0, // 已走毫秒
|
||||||
@ -517,24 +578,7 @@ export default {
|
|||||||
const totalSeconds = h * 3600 + m * 60 + s
|
const totalSeconds = h * 3600 + m * 60 + s
|
||||||
return ((totalSeconds / 86400) * 100).toFixed(1)
|
return ((totalSeconds / 86400) * 100).toFixed(1)
|
||||||
},
|
},
|
||||||
dayOfYear() {
|
|
||||||
const start = new Date(this.now.getFullYear(), 0, 0)
|
|
||||||
const diff = this.now - start
|
|
||||||
const oneDay = 1000 * 60 * 60 * 24
|
|
||||||
return Math.floor(diff / oneDay)
|
|
||||||
},
|
|
||||||
weekOfYear() {
|
|
||||||
const d = new Date(Date.UTC(this.now.getFullYear(), this.now.getMonth(), this.now.getDate()))
|
|
||||||
const dayNum = d.getUTCDay() || 7
|
|
||||||
d.setUTCDate(d.getUTCDate() + 4 - dayNum)
|
|
||||||
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))
|
|
||||||
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7)
|
|
||||||
},
|
|
||||||
daysLeftInYear() {
|
|
||||||
const endOfYear = new Date(this.now.getFullYear(), 11, 31)
|
|
||||||
const diff = endOfYear - this.now
|
|
||||||
return Math.ceil(diff / (1000 * 60 * 60 * 24))
|
|
||||||
},
|
|
||||||
timeStyle() {
|
timeStyle() {
|
||||||
return {
|
return {
|
||||||
'font-size': `${this.fontSize * TIME_FONT_RATIO}px`,
|
'font-size': `${this.fontSize * TIME_FONT_RATIO}px`,
|
||||||
@ -577,6 +621,19 @@ export default {
|
|||||||
if (this.countdownTotal <= 0) return 0
|
if (this.countdownTotal <= 0) return 0
|
||||||
return ((this.countdownTotal - this.countdownRemaining) / this.countdownTotal) * 100
|
return ((this.countdownTotal - this.countdownRemaining) / this.countdownTotal) * 100
|
||||||
},
|
},
|
||||||
|
overtimeDisplay() {
|
||||||
|
const totalSec = Math.floor(this.overtimeElapsed / 1000)
|
||||||
|
const h = Math.floor(totalSec / 3600)
|
||||||
|
const m = Math.floor((totalSec % 3600) / 60)
|
||||||
|
const s = totalSec % 60
|
||||||
|
if (h > 0) {
|
||||||
|
return `${h}小时${m}分${s}秒`
|
||||||
|
}
|
||||||
|
if (m > 0) {
|
||||||
|
return `${m}分${s}秒`
|
||||||
|
}
|
||||||
|
return `${s}秒`
|
||||||
|
},
|
||||||
// 秒表 computed
|
// 秒表 computed
|
||||||
stopwatchDisplay() {
|
stopwatchDisplay() {
|
||||||
const ms = this.stopwatchElapsed
|
const ms = this.stopwatchElapsed
|
||||||
@ -598,9 +655,10 @@ export default {
|
|||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
if (this.showSettings) {
|
if (this.showSettings) {
|
||||||
this.showSettings = false
|
this.showSettings = false
|
||||||
} else {
|
} else if (this.countdownEndedDialog) {
|
||||||
this.showFullscreen = false
|
this.dismissCountdownDialog()
|
||||||
}
|
}
|
||||||
|
// 不关闭全屏弹框,阻止默认行为
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
}
|
}
|
||||||
@ -628,6 +686,7 @@ export default {
|
|||||||
this.clearCountdownTimer()
|
this.clearCountdownTimer()
|
||||||
this.clearStopwatchTimer()
|
this.clearStopwatchTimer()
|
||||||
this.clearToolbarTimer()
|
this.clearToolbarTimer()
|
||||||
|
this.dismissCountdownDialog()
|
||||||
if (this.unwatch) {
|
if (this.unwatch) {
|
||||||
this.unwatch()
|
this.unwatch()
|
||||||
}
|
}
|
||||||
@ -697,6 +756,7 @@ export default {
|
|||||||
this.countdownRunning = false
|
this.countdownRunning = false
|
||||||
this.clearCountdownTimer()
|
this.clearCountdownTimer()
|
||||||
playSound(defaultSingleSound)
|
playSound(defaultSingleSound)
|
||||||
|
this.showCountdownEndedDialog()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleCountdown() {
|
toggleCountdown() {
|
||||||
@ -716,6 +776,36 @@ export default {
|
|||||||
this.countdownRemaining = 0
|
this.countdownRemaining = 0
|
||||||
this.countdownTotal = 0
|
this.countdownTotal = 0
|
||||||
this.clearCountdownTimer()
|
this.clearCountdownTimer()
|
||||||
|
this.dismissCountdownDialog()
|
||||||
|
},
|
||||||
|
showCountdownEndedDialog() {
|
||||||
|
this.countdownEndedDialog = true
|
||||||
|
this.overtimeElapsed = 0
|
||||||
|
this.overtimeLastTick = Date.now()
|
||||||
|
this.overtimeTimer = setInterval(() => {
|
||||||
|
const now = Date.now()
|
||||||
|
this.overtimeElapsed += now - this.overtimeLastTick
|
||||||
|
this.overtimeLastTick = now
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
dismissCountdownDialog() {
|
||||||
|
this.countdownEndedDialog = false
|
||||||
|
this.overtimeElapsed = 0
|
||||||
|
if (this.overtimeTimer) {
|
||||||
|
clearInterval(this.overtimeTimer)
|
||||||
|
this.overtimeTimer = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatCountdownTotal(ms) {
|
||||||
|
const totalSec = Math.round(ms / 1000)
|
||||||
|
const h = Math.floor(totalSec / 3600)
|
||||||
|
const m = Math.floor((totalSec % 3600) / 60)
|
||||||
|
const s = totalSec % 60
|
||||||
|
const parts = []
|
||||||
|
if (h > 0) parts.push(`${h}小时`)
|
||||||
|
if (m > 0) parts.push(`${m}分钟`)
|
||||||
|
if (s > 0) parts.push(`${s}秒`)
|
||||||
|
return parts.join('') || '0秒'
|
||||||
},
|
},
|
||||||
clearCountdownTimer() {
|
clearCountdownTimer() {
|
||||||
if (this.countdownTimer) {
|
if (this.countdownTimer) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user