132 lines
3.9 KiB
Vue
132 lines
3.9 KiB
Vue
<template>
|
||
<view class="silence-overlay" :class="{ 'silence-overlay-blocking': blocking }" @tap.stop @touchmove.stop.prevent>
|
||
<view class="silence-dialog" :class="`silence-${reminder.kind}`" role="dialog" aria-modal="true" aria-label="套餐沉默期提醒">
|
||
<button v-if="!blocking" class="silence-close" aria-label="关闭沉默期提醒" @tap="$emit('close')">×</button>
|
||
<view class="silence-title">{{ title }}</view>
|
||
<view v-if="reminder.packageName" class="silence-package">{{ reminder.packageName }}</view>
|
||
<view class="silence-body">
|
||
<template v-if="reminder.pendingOrderNo">
|
||
套餐沉默期已于 <text class="silence-strong">{{ deadline }}</text> 过期,您有一笔未支付的延期订单({{ reminder.pendingOrderNo }}),请继续支付;不需要了可以作废后重新办理。
|
||
</template>
|
||
<template v-else-if="reminder.kind === 'expired'">
|
||
套餐需在 <text class="silence-strong">{{ deadline }}</text> 前完成实名,现已过期。请先办理延期,延期后才能继续使用其他功能。
|
||
</template>
|
||
<template v-else>
|
||
套餐需在 <text class="silence-strong">{{ deadline }}</text> 前完成实名激活,还剩
|
||
<text class="silence-strong">{{ reminder.remainingDays }}</text> 天,过期后需办理延期。
|
||
</template>
|
||
</view>
|
||
<button class="silence-confirm" @tap="$emit('action')">{{ actionText }}</button>
|
||
<button v-if="!blocking" class="silence-later" @tap="$emit('close')">我知道了</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed } from 'vue';
|
||
import { formatSilenceDate, isSilenceReminderBlocking } from '@/utils/silence.js';
|
||
|
||
const props = defineProps({ reminder: { type: Object, required: true } });
|
||
defineEmits(['close', 'action']);
|
||
const blocking = computed(() => isSilenceReminderBlocking(props.reminder));
|
||
const deadline = computed(() => formatSilenceDate(props.reminder.silence?.silence_deadline_at));
|
||
const title = computed(() => {
|
||
if (props.reminder.pendingOrderNo) return '延期订单未支付';
|
||
return props.reminder.kind === 'expired' ? '套餐沉默期已过期' : '请尽快完成实名';
|
||
});
|
||
const actionText = computed(() => {
|
||
if (props.reminder.pendingOrderNo) return '去支付或作废';
|
||
return props.reminder.kind === 'expired' ? '去延期' : '查看套餐';
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.silence-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);
|
||
}
|
||
|
||
/* 强制延期弹窗盖在首页所有弹层(含 up-popup)之上 */
|
||
.silence-overlay-blocking {
|
||
z-index: 10200;
|
||
background: rgba(20, 26, 36, 0.64);
|
||
}
|
||
|
||
.silence-dialog {
|
||
position: relative;
|
||
width: 100%;
|
||
max-width: 640rpx;
|
||
padding: 48rpx 36rpx 32rpx;
|
||
box-sizing: border-box;
|
||
border-radius: 32rpx;
|
||
text-align: center;
|
||
background: var(--bg-primary);
|
||
box-shadow: 0 24rpx 80rpx rgba(0, 0, 0, 0.18);
|
||
}
|
||
|
||
.silence-close {
|
||
position: absolute;
|
||
top: 16rpx;
|
||
right: 20rpx;
|
||
padding: 0;
|
||
font-size: 44rpx;
|
||
line-height: 1;
|
||
color: var(--text-tertiary);
|
||
background: transparent;
|
||
&::after { border: none; }
|
||
}
|
||
|
||
.silence-title {
|
||
font-size: 36rpx;
|
||
font-weight: 700;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.silence-expired .silence-title {
|
||
color: var(--danger);
|
||
}
|
||
|
||
.silence-package {
|
||
margin-top: 12rpx;
|
||
font-size: 26rpx;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.silence-body {
|
||
margin: 28rpx 0 36rpx;
|
||
font-size: 28rpx;
|
||
line-height: 1.7;
|
||
color: var(--text-secondary);
|
||
text-align: left;
|
||
}
|
||
|
||
.silence-strong {
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.silence-confirm {
|
||
width: 100%;
|
||
border-radius: 999rpx;
|
||
font-size: 30rpx;
|
||
color: #fff;
|
||
background: var(--primary);
|
||
}
|
||
|
||
.silence-later {
|
||
width: 100%;
|
||
margin-top: 16rpx;
|
||
font-size: 28rpx;
|
||
color: var(--text-tertiary);
|
||
background: transparent;
|
||
&::after { border: none; }
|
||
}
|
||
</style>
|