Files
device-voice-h5/components/NotificationPopup.vue
luo 6a794d88af
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 1m2s
feat: 新增文档
2026-07-27 16:21:34 +08:00

153 lines
3.2 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 v-if="show" class="notification-popup" @tap.stop>
<view class="notification-popup-card">
<view class="popup-header">
<view class="popup-heading">新通知</view>
<view class="popup-close" role="button" aria-label="关闭" @tap="$emit('close')">×</view>
</view>
<swiper class="notification-swiper" :current="current" @change="$emit('change', $event)">
<swiper-item v-for="item in items" :key="item.id">
<view class="notification-content">
<view class="notification-title">{{ item.title || '业务通知' }}</view>
<view class="notification-time">{{ formatDate(item.created_at) }}</view>
<scroll-view scroll-y class="notification-body">
<text>{{ item.body || '暂无通知内容' }}</text>
</scroll-view>
</view>
</swiper-item>
</swiper>
<view v-if="items.length > 1" class="popup-footer">
<view class="popup-dots">
<view v-for="(_, index) in items" :key="index" class="popup-dot" :class="{ active: index === current }"></view>
</view>
<view class="popup-counter">{{ current + 1 }}/{{ items.length }} 左右滑动查看</view>
</view>
</view>
</view>
</template>
<script setup>
defineProps({
show: Boolean,
items: {
type: Array,
default: () => []
},
current: {
type: Number,
default: 0
}
});
defineEmits(['close', 'change']);
const formatDate = (value) => {
if (!value) return '-';
return value.replace('T', ' ').slice(0, 16);
};
</script>
<style scoped lang="scss">
.notification-popup {
position: fixed;
z-index: 1000;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
background: rgba(0, 0, 0, 0.48);
}
.notification-popup-card {
width: 100%;
max-width: 640rpx;
overflow: hidden;
border-radius: 24rpx;
background: #fff;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.18);
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 32rpx 18rpx;
}
.popup-heading {
color: var(--text-primary);
font-size: 34rpx;
font-weight: 600;
}
.popup-close {
width: 52rpx;
height: 52rpx;
color: var(--text-tertiary);
font-size: 48rpx;
font-weight: 300;
line-height: 46rpx;
text-align: center;
}
.notification-swiper { height: 360rpx; }
.notification-content {
height: 100%;
box-sizing: border-box;
padding: 18rpx 32rpx 28rpx;
}
.notification-title {
color: var(--text-primary);
font-size: 32rpx;
font-weight: 600;
line-height: 1.45;
}
.notification-time {
margin-top: 12rpx;
color: var(--text-tertiary);
font-size: 22rpx;
}
.notification-body {
box-sizing: border-box;
height: 230rpx;
margin-top: 28rpx;
color: var(--text-secondary);
font-size: 28rpx;
line-height: 1.7;
white-space: pre-wrap;
}
.popup-footer {
padding: 0 32rpx 28rpx;
text-align: center;
}
.popup-dots {
display: flex;
justify-content: center;
gap: 10rpx;
}
.popup-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: #d8dce3;
}
.popup-dot.active { width: 28rpx; border-radius: 8rpx; background: var(--primary); }
.popup-counter {
margin-top: 16rpx;
color: var(--text-tertiary);
font-size: 22rpx;
}
</style>