Files
device-voice-h5/components/ExpiryReminderPopup.vue
2026-10-14 09:56:09 +08:00

135 lines
4.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="expiry-overlay" @tap.stop>
<view class="expiry-dialog" :class="`expiry-${reminder.level}`" role="dialog"
aria-modal="true" aria-label="套餐临期提醒" @keydown.esc="$emit('close')">
<view class="reminder-header">
<button class="reminder-close" aria-label="关闭临期提醒" @tap="$emit('close')">×</button>
<view class="clock-halo" aria-hidden="true"><view class="clock-face"></view></view>
<view class="reminder-title">套餐即将到期</view>
<view class="remaining-label">当前资产套餐剩余</view>
<view class="remaining-days"><text class="day-number">{{ reminder.remaining_days }}</text><text class="day-unit">天</text></view>
</view>
<view class="reminder-content">
<view class="expiry-details">
<text class="expiry-label">预计到期时间</text>
<text class="expiry-value">{{ formatShanghaiExpiry(reminder.expires_at) }}</text>
</view>
<view class="reminder-description">为避免套餐到期影响使用,请及时续费。</view>
<button class="reminder-confirm" @tap="$emit('renew')">立即续费</button>
<button class="reminder-later" @tap="$emit('close')">我知道了</button>
</view>
</view>
</view>
</template>
<script setup>
import { formatShanghaiExpiry } from '@/utils/expiry-reminder.js';
defineProps({ reminder: { type: Object, required: true } });
defineEmits(['close', 'renew']);
</script>
<style scoped lang="scss">
.expiry-overlay {
position: fixed;
inset: 0;
z-index: 1200;
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
box-sizing: border-box;
background: rgba(20, 26, 36, 0.48);
backdrop-filter: blur(4px);
}
.expiry-dialog {
width: 100%;
max-width: 640rpx;
max-height: calc(100vh - 80rpx);
overflow-y: auto;
border-radius: 32rpx;
background: var(--bg-primary);
box-shadow: 0 24rpx 80rpx rgba(0, 0, 0, 0.18);
}
.reminder-header {
position: relative;
padding: 40rpx 36rpx 28rpx;
text-align: center;
background: linear-gradient(180deg, var(--reminder-tint), var(--bg-primary));
}
.reminder-close {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 56rpx;
height: 56rpx;
margin: 0;
padding: 0;
border-radius: 50%;
font-size: 40rpx;
line-height: 52rpx;
color: var(--text-tertiary);
background: transparent;
}
.reminder-close::after, .reminder-confirm::after, .reminder-later::after { border: none; }
.clock-halo {
display: flex;
align-items: center;
justify-content: center;
width: 108rpx;
height: 108rpx;
margin: 28rpx auto 22rpx;
border-radius: 50%;
background: var(--reminder-tint);
}
.clock-face {
position: relative;
width: 50rpx;
height: 50rpx;
border: 4rpx solid var(--reminder-color);
border-radius: 50%;
}
.clock-face::before, .clock-face::after {
content: '';
position: absolute;
left: 23rpx;
top: 10rpx;
width: 4rpx;
height: 17rpx;
border-radius: 4rpx;
background: var(--reminder-color);
}
.clock-face::after { top: 23rpx; height: 14rpx; transform: rotate(-55deg); transform-origin: top center; }
.reminder-title { color: var(--text-primary); font-size: 38rpx; font-weight: 700; }
.remaining-label { margin-top: 20rpx; color: var(--text-secondary); font-size: 26rpx; }
.remaining-days { margin-top: 8rpx; color: var(--reminder-color); line-height: 1.2; }
.day-number { font-size: 88rpx; font-weight: 700; letter-spacing: -3rpx; font-variant-numeric: tabular-nums; }
.day-unit { margin-left: 12rpx; font-size: 28rpx; }
.reminder-content { padding: 0 36rpx 36rpx; }
.expiry-details {
display: flex;
flex-direction: column;
gap: 10rpx;
padding: 22rpx;
border-radius: 16rpx;
text-align: center;
background: var(--bg-secondary);
}
.expiry-label { font-size: 22rpx; color: var(--text-tertiary); }
.expiry-value { font-size: 26rpx; color: var(--text-primary); font-weight: 500; }
.reminder-description { margin: 22rpx 0 28rpx; color: var(--text-secondary); font-size: 24rpx; line-height: 1.6; text-align: center; }
.reminder-confirm {
margin: 0;
padding: 24rpx;
border-radius: 16rpx;
font-size: 28rpx;
font-weight: 600;
line-height: 1;
color: #fff;
background: var(--reminder-color);
}
.expiry-red { --reminder-color: #d94040; --reminder-tint: rgba(217, 64, 64, 0.08); }
.reminder-later { margin: 12rpx 0 0; padding: 14rpx; font-size: 24rpx; line-height: 1.5; color: var(--text-tertiary); background: transparent; }
.expiry-purple { --reminder-color: #8850c4; --reminder-tint: rgba(136, 80, 196, 0.08); }
.expiry-pink { --reminder-color: #ce4878; --reminder-tint: rgba(206, 72, 120, 0.08); }
</style>