This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<view class="card expiry-banner" :class="`expiry-${reminder.level}`" role="status">
|
||||
<view class="banner-heading">
|
||||
<view class="banner-title">{{ reminder.level_name || '套餐临期提醒' }}</view>
|
||||
<button class="banner-close" aria-label="关闭临期提醒" @tap="$emit('close')">关闭</button>
|
||||
</view>
|
||||
<view class="banner-body">当前资产套餐剩余 {{ reminder.remaining_days }} 天,请及时续费。</view>
|
||||
<view class="banner-expiry">预计到期:{{ formatShanghaiExpiry(reminder.expires_at) }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { formatShanghaiExpiry } from '@/utils/expiry-reminder.js';
|
||||
defineProps({ reminder: { type: Object, required: true } });
|
||||
defineEmits(['close']);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.expiry-banner {
|
||||
border-left: 8rpx solid var(--reminder-color);
|
||||
.banner-heading { display: flex; align-items: center; justify-content: space-between; gap: 16rpx; }
|
||||
.banner-title { color: var(--reminder-color); font-size: 30rpx; font-weight: 600; }
|
||||
.banner-close { margin: 0; padding: 8rpx 16rpx; font-size: 24rpx; line-height: 1.5; color: var(--text-secondary); background: var(--gray-100); }
|
||||
.banner-close::after { border: none; }
|
||||
.banner-body { margin-top: 12rpx; font-size: 28rpx; line-height: 1.6; color: var(--text-primary); }
|
||||
.banner-expiry { margin-top: 8rpx; font-size: 24rpx; color: var(--text-secondary); }
|
||||
}
|
||||
.expiry-red { --reminder-color: var(--danger); }
|
||||
.expiry-purple { --reminder-color: var(--purple); }
|
||||
.expiry-pink { --reminder-color: var(--pink); }
|
||||
</style>
|
||||
142
components/ExpiryReminderPopup.vue
Normal file
142
components/ExpiryReminderPopup.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<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">
|
||||
<view class="reminder-level">{{ reminder.level_name || '套餐临期提醒' }}</view>
|
||||
<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('close')">我知道了</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { formatShanghaiExpiry } from '@/utils/expiry-reminder.js';
|
||||
defineProps({ reminder: { type: Object, required: true } });
|
||||
defineEmits(['close']);
|
||||
</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-level {
|
||||
display: inline-block;
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
color: var(--reminder-color);
|
||||
background: var(--reminder-tint);
|
||||
}
|
||||
.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 { 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); }
|
||||
.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>
|
||||
Reference in New Issue
Block a user