后端功能增强:全局异常处理、API控制器、JSP视图和单元测试
- 添加 GlobalExceptionHandler 全局异常处理 - 添加 ApiController REST API 控制器 - 更新 WebConfig 跨域配置和 ProductRepository 查询方法 - 新增 monitor/product-detail/profile JSP 视图页面 - 添加 FlashSaleServiceTest 秒杀服务单元测试 - 更新 application.yml 配置
This commit is contained in:
71
flash-sale-frontend/src/components/business/CountDown.vue
Normal file
71
flash-sale-frontend/src/components/business/CountDown.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="countdown-timer">
|
||||
<template v-if="timeLeft > 0">
|
||||
<el-icon class="text-red-500 mr-1"><Clock /></el-icon>
|
||||
<span class="time-block">{{ hours.toString().padStart(2, '0') }}</span>
|
||||
<span class="separator">:</span>
|
||||
<span class="time-block">{{ minutes.toString().padStart(2, '0') }}</span>
|
||||
<span class="separator">:</span>
|
||||
<span class="time-block">{{ seconds.toString().padStart(2, '0') }}</span>
|
||||
</template>
|
||||
<span v-else class="text-gray-400">已结束</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
endTime: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
finish: []
|
||||
}>()
|
||||
|
||||
const timeLeft = ref(0)
|
||||
let timer: number | null = null
|
||||
|
||||
const hours = computed(() => Math.floor(timeLeft.value / 3600))
|
||||
const minutes = computed(() => Math.floor((timeLeft.value % 3600) / 60))
|
||||
const seconds = computed(() => timeLeft.value % 60)
|
||||
|
||||
const updateTime = () => {
|
||||
const now = Date.now()
|
||||
const remaining = Math.max(0, Math.floor((props.endTime - now) / 1000))
|
||||
timeLeft.value = remaining
|
||||
|
||||
if (remaining === 0 && timer) {
|
||||
clearInterval(timer)
|
||||
timer = null
|
||||
emit('finish')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateTime()
|
||||
if (timeLeft.value > 0) {
|
||||
timer = setInterval(updateTime, 1000)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.countdown-timer {
|
||||
@apply flex items-center justify-center text-lg font-mono;
|
||||
|
||||
.time-block {
|
||||
@apply px-2 py-1 bg-red-50 text-red-600 rounded;
|
||||
}
|
||||
|
||||
.separator {
|
||||
@apply mx-1 text-red-500 font-bold;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user