flat: 暂存
This commit is contained in:
161
packageA/pages/reservation/component/countdown.vue
Normal file
161
packageA/pages/reservation/component/countdown.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div class="countdown-wrapper" style="width: 100%">
|
||||
<template v-if="isNotStarted">
|
||||
<view class="fl_box fl_nowarp fl_justbet" style="width: 100%">
|
||||
<view class="fl_box">
|
||||
<span class="colon">距离开始还剩</span>
|
||||
<div class="time-block">{{ days }}</div>
|
||||
<span class="colon">天</span>
|
||||
</view>
|
||||
<view style="color: #ff881a">待开始</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-else-if="isEnd">
|
||||
<view class="fl_box fl_nowarp fl_justbet" style="width: 100%">
|
||||
<view class="fl_box">
|
||||
<span class="colon hui">距离结束还剩</span>
|
||||
<div class="time-block huibg">00</div>
|
||||
<span class="colon hui">:</span>
|
||||
<div class="time-block huibg">00</div>
|
||||
<span class="colon hui">:</span>
|
||||
<div class="time-block huibg">00</div>
|
||||
</view>
|
||||
<view class="hui">已结束</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<template v-if="showDays">
|
||||
<view class="fl_box fl_nowarp fl_justbet" style="width: 100%">
|
||||
<view class="fl_box">
|
||||
<span class="colon">距离结束还剩</span>
|
||||
<div class="time-block">{{ days }}</div>
|
||||
<span class="colon">天</span>
|
||||
</view>
|
||||
<view style="color: #18a14f">进行中</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="fl_box fl_nowarp fl_justbet" style="width: 100%">
|
||||
<view class="fl_box">
|
||||
<span class="colon">距离结束还剩</span>
|
||||
<div class="time-block">{{ hours }}</div>
|
||||
<span class="colon">:</span>
|
||||
<div class="time-block">{{ minutes }}</div>
|
||||
<span class="colon">:</span>
|
||||
<div class="time-block">{{ seconds }}</div>
|
||||
</view>
|
||||
<view style="color: #18a14f">进行中</view>
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
startTime: { type: [String, Number, Date], required: true },
|
||||
endTime: { type: [String, Number, Date], required: true },
|
||||
interval: { type: Number, default: 1000 },
|
||||
});
|
||||
|
||||
const now = ref(Date.now());
|
||||
let timer = null;
|
||||
|
||||
const startTimestamp = computed(() => new Date(props.startTime).getTime());
|
||||
const endTimestamp = computed(() => new Date(props.endTime).getTime());
|
||||
|
||||
const isEnd = computed(() => now.value >= endTimestamp.value);
|
||||
const isNotStarted = computed(() => now.value < startTimestamp.value);
|
||||
|
||||
const targetTimestamp = computed(() => {
|
||||
if (isNotStarted.value) return startTimestamp.value;
|
||||
if (!isEnd.value) return endTimestamp.value;
|
||||
return now.value;
|
||||
});
|
||||
|
||||
const remainingMs = computed(() => Math.max(0, targetTimestamp.value - now.value));
|
||||
const secondsTotal = computed(() => Math.floor(remainingMs.value / 1000));
|
||||
|
||||
const showDays = computed(() => secondsTotal.value >= 86400);
|
||||
const days = computed(() => Math.ceil(secondsTotal.value / 86400));
|
||||
|
||||
const hours = computed(() => {
|
||||
const h = Math.floor(secondsTotal.value / 3600) % 24;
|
||||
return h.toString().padStart(2, '0');
|
||||
});
|
||||
const minutes = computed(() => {
|
||||
const m = Math.floor((secondsTotal.value % 3600) / 60);
|
||||
return m.toString().padStart(2, '0');
|
||||
});
|
||||
const seconds = computed(() => {
|
||||
const s = secondsTotal.value % 60;
|
||||
return s.toString().padStart(2, '0');
|
||||
});
|
||||
|
||||
const startTimer = () => {
|
||||
timer = setInterval(() => {
|
||||
now.value = Date.now();
|
||||
}, props.interval);
|
||||
};
|
||||
|
||||
const stopTimer = () => {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
startTimer();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopTimer();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.countdown-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.time-block {
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
font-size: 28rpx;
|
||||
color: #ffffff;
|
||||
height: 44rpx;
|
||||
line-height: 44rpx;
|
||||
padding: 0 14rpx;
|
||||
background: #256bfa;
|
||||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||||
margin: 0 10rpx;
|
||||
}
|
||||
|
||||
.colon {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #256bfa;
|
||||
}
|
||||
|
||||
.day-text {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.hui {
|
||||
color: #b6b6b6;
|
||||
}
|
||||
.huibg {
|
||||
background-color: #b6b6b6;
|
||||
}
|
||||
.lan {
|
||||
color: #256bfa;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user