hookehuyr

feat(订单页面): 添加待支付订单的倒计时功能

实现待支付订单的支付倒计时显示,超时自动取消订单
...@@ -88,6 +88,9 @@ ...@@ -88,6 +88,9 @@
88 </button> 88 </button>
89 </div> 89 </div>
90 </div> 90 </div>
91 + <div v-if="order.status === 'NOT_PAY' && order.countdown" class="text-right mt-4">
92 + <span class="text-red-500 text-sm font-medium">支付倒计时:{{ order.countdown }}</span>
93 + </div>
91 </FrostedGlass> 94 </FrostedGlass>
92 </van-list> 95 </van-list>
93 96
...@@ -187,7 +190,7 @@ ...@@ -187,7 +190,7 @@
187 </template> 190 </template>
188 191
189 <script setup> 192 <script setup>
190 -import { ref } from 'vue' 193 +import { ref, computed, onMounted, onUnmounted } from 'vue'
191 import { useRoute, useRouter } from 'vue-router'; 194 import { useRoute, useRouter } from 'vue-router';
192 import AppLayout from '@/components/layout/AppLayout.vue' 195 import AppLayout from '@/components/layout/AppLayout.vue'
193 import FrostedGlass from '@/components/ui/FrostedGlass.vue' 196 import FrostedGlass from '@/components/ui/FrostedGlass.vue'
...@@ -292,6 +295,12 @@ const onLoad = async () => { ...@@ -292,6 +295,12 @@ const onLoad = async () => {
292 status: selectedStatus.value 295 status: selectedStatus.value
293 }); 296 });
294 if (res.code) { 297 if (res.code) {
298 + // 待支付订单倒计时
299 + res.data.forEach(order => {
300 + if (order.status === 'NOT_PAY') {
301 + startCountdown(order);
302 + }
303 + })
295 orders.value = [...orders.value, ...res.data]; 304 orders.value = [...orders.value, ...res.data];
296 finished.value = res.data.length < limit.value; 305 finished.value = res.data.length < limit.value;
297 page.value = nextPage + 1; 306 page.value = nextPage + 1;
...@@ -372,4 +381,78 @@ const handleCancel = async (order) => { ...@@ -372,4 +381,78 @@ const handleCancel = async (order) => {
372 // on cancel 381 // on cancel
373 }); 382 });
374 }; 383 };
384 +
385 +/**
386 + * 待支付订单的支付倒计时功能
387 + * @param {Object} order - 订单对象
388 + */
389 +const startCountdown = (order) => {
390 + // 清除可能存在的旧定时器
391 + if (order._countdownTimer) {
392 + clearInterval(order._countdownTimer);
393 + order._countdownTimer = null;
394 + }
395 +
396 + // 计算剩余时间(毫秒)
397 + const current_date = new Date(order.server_time);
398 + const end_date = new Date(order.pay_deadline_time);
399 + let time_left = end_date - current_date;
400 +
401 + // 检查是否已过期
402 + if (time_left <= 0) {
403 + // 使用Vue的响应式API更新对象属性
404 + order.status = 'CANCEL';
405 + order.statusText = '已取消';
406 + order.statusColor = 'text-gray-500';
407 + order.countdown = '';
408 + // 强制触发视图更新
409 + orders.value = [...orders.value];
410 + return;
411 + }
412 +
413 + // 更新倒计时显示
414 + const updateCountdown = () => {
415 + // 计算时、分、秒
416 + const hours = Math.floor(time_left / 3600000);
417 + const minutes = Math.floor((time_left % 3600000) / 60000);
418 + const seconds = Math.floor((time_left % 60000) / 1000);
419 +
420 + // 格式化显示
421 + order.countdown = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
422 +
423 + // 强制触发视图更新
424 + orders.value = [...orders.value];
425 +
426 + // 减少剩余时间
427 + time_left -= 1000;
428 +
429 + // 检查是否已到期
430 + if (time_left < 0) {
431 + clearInterval(order._countdownTimer);
432 + order._countdownTimer = null;
433 +
434 + order.status = 'CANCEL';
435 + order.statusText = '已取消';
436 + order.statusColor = 'text-gray-500';
437 + order.countdown = '';
438 +
439 + // 强制触发视图更新
440 + orders.value = [...orders.value];
441 + }
442 + };
443 +
444 + // 立即执行一次更新
445 + updateCountdown();
446 +
447 + // 设置定时器,每秒更新一次
448 + order._countdownTimer = setInterval(updateCountdown, 1000);
449 +
450 + // 组件卸载时清除定时器
451 + onUnmounted(() => {
452 + if (order._countdownTimer) {
453 + clearInterval(order._countdownTimer);
454 + order._countdownTimer = null;
455 + }
456 + });
457 +};
375 </script> 458 </script>
......