816 lines
18 KiB
Vue
816 lines
18 KiB
Vue
<template>
|
||
<view class="notifications-container page-container-with-bg">
|
||
<!-- 通知设置卡片 -->
|
||
<view class="settings-card">
|
||
<view class="card-header">
|
||
<text class="card-title">通知设置</text>
|
||
</view>
|
||
<view class="settings-list">
|
||
<view class="setting-item">
|
||
<view class="setting-info">
|
||
<text class="setting-title">系统通知</text>
|
||
<text class="setting-desc">接收系统重要消息和更新通知</text>
|
||
</view>
|
||
<view class="setting-switch">
|
||
<u-switch
|
||
v-model="notificationSettings.system"
|
||
@change="onSettingChange('system', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="setting-item">
|
||
<view class="setting-info">
|
||
<text class="setting-title">宠物提醒</text>
|
||
<text class="setting-desc">宠物喂食、医疗等重要提醒</text>
|
||
</view>
|
||
<view class="setting-switch">
|
||
<u-switch
|
||
v-model="notificationSettings.petReminder"
|
||
@change="onSettingChange('petReminder', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="setting-item">
|
||
<view class="setting-info">
|
||
<text class="setting-title">领养消息</text>
|
||
<text class="setting-desc">领养申请、回复等相关消息</text>
|
||
</view>
|
||
<view class="setting-switch">
|
||
<u-switch
|
||
v-model="notificationSettings.adoption"
|
||
@change="onSettingChange('adoption', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="setting-item">
|
||
<view class="setting-info">
|
||
<text class="setting-title">家庭动态</text>
|
||
<text class="setting-desc">家庭成员活动和共享内容通知</text>
|
||
</view>
|
||
<view class="setting-switch">
|
||
<u-switch
|
||
v-model="notificationSettings.family"
|
||
@change="onSettingChange('family', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="setting-item">
|
||
<view class="setting-info">
|
||
<text class="setting-title">营销推广</text>
|
||
<text class="setting-desc">产品推荐、活动优惠等信息</text>
|
||
</view>
|
||
<view class="setting-switch">
|
||
<u-switch
|
||
v-model="notificationSettings.marketing"
|
||
@change="onSettingChange('marketing', $event)"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 免打扰设置卡片 -->
|
||
<view class="dnd-card">
|
||
<view class="card-header">
|
||
<text class="card-title">免打扰设置</text>
|
||
</view>
|
||
<view class="dnd-content">
|
||
<view class="dnd-toggle">
|
||
<view class="toggle-info">
|
||
<text class="toggle-title">开启免打扰</text>
|
||
<text class="toggle-desc">在指定时间段内不接收通知</text>
|
||
</view>
|
||
<view class="toggle-switch">
|
||
<u-switch
|
||
v-model="dndSettings.enabled"
|
||
@change="onDndToggle"
|
||
active-color="#FF8A80"
|
||
></u-switch>
|
||
</view>
|
||
</view>
|
||
<view class="dnd-time" v-if="dndSettings.enabled">
|
||
<view class="time-item" @click="showStartTimePicker">
|
||
<text class="time-label">开始时间</text>
|
||
<text class="time-value">{{ dndSettings.startTime }}</text>
|
||
</view>
|
||
<view class="time-item" @click="showEndTimePicker">
|
||
<text class="time-label">结束时间</text>
|
||
<text class="time-value">{{ dndSettings.endTime }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息列表卡片 -->
|
||
<view class="messages-card">
|
||
<view class="card-header">
|
||
<text class="card-title">最近消息</text>
|
||
<view class="header-action" @click="markAllRead" v-if="unreadCount > 0">
|
||
<text class="action-text">全部已读</text>
|
||
</view>
|
||
</view>
|
||
<view class="messages-list" v-if="messagesList.length > 0">
|
||
<view
|
||
class="message-item"
|
||
v-for="message in messagesList"
|
||
:key="message.id"
|
||
:class="{ unread: !message.read }"
|
||
@click="readMessage(message)"
|
||
>
|
||
<view class="message-icon" :class="message.type">
|
||
<text class="icon-text">{{ getMessageIcon(message.type) }}</text>
|
||
</view>
|
||
<view class="message-content">
|
||
<view class="message-title">{{ message.title }}</view>
|
||
<view class="message-desc">{{ message.content }}</view>
|
||
<view class="message-time">{{ formatTime(message.time) }}</view>
|
||
</view>
|
||
<view class="message-status" v-if="!message.read">
|
||
<view class="unread-dot"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="empty-messages" v-else>
|
||
<view class="empty-icon">📬</view>
|
||
<view class="empty-text">暂无消息</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 清理设置卡片 -->
|
||
<view class="cleanup-card">
|
||
<view class="card-header">
|
||
<text class="card-title">消息管理</text>
|
||
</view>
|
||
<view class="cleanup-list">
|
||
<view class="cleanup-item" @click="clearReadMessages">
|
||
<view class="cleanup-info">
|
||
<text class="cleanup-title">清理已读消息</text>
|
||
<text class="cleanup-desc">删除所有已读的消息记录</text>
|
||
</view>
|
||
<view class="cleanup-action">
|
||
<text class="action-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
<view class="cleanup-item" @click="clearAllMessages">
|
||
<view class="cleanup-info">
|
||
<text class="cleanup-title">清空所有消息</text>
|
||
<text class="cleanup-desc">删除所有消息记录(不可恢复)</text>
|
||
</view>
|
||
<view class="cleanup-action">
|
||
<text class="action-arrow">→</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 时间选择器 -->
|
||
<u-datetime-picker
|
||
:show="showStartTime"
|
||
v-model="selectedStartTime"
|
||
mode="time"
|
||
@confirm="onStartTimeConfirm"
|
||
@cancel="showStartTime = false"
|
||
></u-datetime-picker>
|
||
|
||
<u-datetime-picker
|
||
:show="showEndTime"
|
||
v-model="selectedEndTime"
|
||
mode="time"
|
||
@confirm="onEndTimeConfirm"
|
||
@cancel="showEndTime = false"
|
||
></u-datetime-picker>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { reactive, ref, onMounted, computed } from 'vue'
|
||
|
||
export default {
|
||
name: 'NotificationsPage',
|
||
setup() {
|
||
// 响应式数据
|
||
const notificationSettings = reactive({
|
||
system: true,
|
||
petReminder: true,
|
||
adoption: true,
|
||
family: true,
|
||
marketing: false
|
||
})
|
||
|
||
const dndSettings = reactive({
|
||
enabled: false,
|
||
startTime: '22:00',
|
||
endTime: '08:00'
|
||
})
|
||
|
||
const messagesList = ref([])
|
||
const showStartTime = ref(false)
|
||
const showEndTime = ref(false)
|
||
const selectedStartTime = ref(Date.now())
|
||
const selectedEndTime = ref(Date.now())
|
||
|
||
// 计算属性
|
||
const unreadCount = computed(() => {
|
||
return messagesList.value.filter(msg => !msg.read).length
|
||
})
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
loadSettings()
|
||
loadMessages()
|
||
})
|
||
|
||
// 方法定义
|
||
const loadSettings = () => {
|
||
try {
|
||
const savedSettings = uni.getStorageSync('notificationSettings')
|
||
if (savedSettings) {
|
||
Object.assign(notificationSettings, savedSettings)
|
||
}
|
||
|
||
const savedDndSettings = uni.getStorageSync('dndSettings')
|
||
if (savedDndSettings) {
|
||
Object.assign(dndSettings, savedDndSettings)
|
||
}
|
||
} catch (error) {
|
||
console.error('加载设置失败:', error)
|
||
}
|
||
}
|
||
|
||
const loadMessages = () => {
|
||
try {
|
||
const savedMessages = uni.getStorageSync('notifications') || []
|
||
|
||
// 如果没有消息,创建一些模拟消息
|
||
if (savedMessages.length === 0) {
|
||
const mockMessages = [
|
||
{
|
||
id: 'msg_1',
|
||
type: 'system',
|
||
title: '系统更新',
|
||
content: '宠物AI助手已更新到最新版本,新增了家庭共享功能。',
|
||
time: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
|
||
read: false
|
||
},
|
||
{
|
||
id: 'msg_2',
|
||
type: 'pet',
|
||
title: '喂食提醒',
|
||
content: '小橘的晚餐时间到了,记得给它准备食物哦!',
|
||
time: new Date(Date.now() - 4 * 60 * 60 * 1000).toISOString(),
|
||
read: true
|
||
},
|
||
{
|
||
id: 'msg_3',
|
||
type: 'adoption',
|
||
title: '领养申请',
|
||
content: '有用户申请领养您发布的小白,请及时查看处理。',
|
||
time: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
|
||
read: false
|
||
},
|
||
{
|
||
id: 'msg_4',
|
||
type: 'family',
|
||
title: '家庭动态',
|
||
content: '家庭成员小明为小花添加了一条健康记录。',
|
||
time: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
||
read: true
|
||
}
|
||
]
|
||
|
||
uni.setStorageSync('notifications', mockMessages)
|
||
messagesList.value = mockMessages
|
||
} else {
|
||
messagesList.value = savedMessages
|
||
}
|
||
} catch (error) {
|
||
console.error('加载消息失败:', error)
|
||
}
|
||
}
|
||
|
||
const saveSettings = () => {
|
||
uni.setStorageSync('notificationSettings', notificationSettings)
|
||
uni.setStorageSync('dndSettings', dndSettings)
|
||
}
|
||
|
||
const saveMessages = () => {
|
||
uni.setStorageSync('notifications', messagesList.value)
|
||
}
|
||
|
||
const onSettingChange = (key, value) => {
|
||
notificationSettings[key] = value
|
||
saveSettings()
|
||
|
||
uni.showToast({
|
||
title: value ? '已开启' : '已关闭',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
const onDndToggle = (value) => {
|
||
dndSettings.enabled = value
|
||
saveSettings()
|
||
|
||
if (value) {
|
||
uni.showToast({
|
||
title: '免打扰已开启',
|
||
icon: 'success'
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: '免打扰已关闭',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
|
||
const showStartTimePicker = () => {
|
||
const [hours, minutes] = dndSettings.startTime.split(':')
|
||
const date = new Date()
|
||
date.setHours(parseInt(hours), parseInt(minutes), 0, 0)
|
||
selectedStartTime.value = date.getTime()
|
||
showStartTime.value = true
|
||
}
|
||
|
||
const showEndTimePicker = () => {
|
||
const [hours, minutes] = dndSettings.endTime.split(':')
|
||
const date = new Date()
|
||
date.setHours(parseInt(hours), parseInt(minutes), 0, 0)
|
||
selectedEndTime.value = date.getTime()
|
||
showEndTime.value = true
|
||
}
|
||
|
||
const onStartTimeConfirm = (e) => {
|
||
const date = new Date(e.value)
|
||
dndSettings.startTime = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||
saveSettings()
|
||
showStartTime.value = false
|
||
}
|
||
|
||
const onEndTimeConfirm = (e) => {
|
||
const date = new Date(e.value)
|
||
dndSettings.endTime = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||
saveSettings()
|
||
showEndTime.value = false
|
||
}
|
||
|
||
const getMessageIcon = (type) => {
|
||
const iconMap = {
|
||
'system': '🔔',
|
||
'pet': '🐱',
|
||
'adoption': '🏠',
|
||
'family': '👨👩👧👦',
|
||
'marketing': '📢'
|
||
}
|
||
return iconMap[type] || '📬'
|
||
}
|
||
|
||
const formatTime = (timeString) => {
|
||
if (!timeString) return ''
|
||
const date = new Date(timeString)
|
||
const now = new Date()
|
||
const diffTime = now - date
|
||
const diffHours = Math.floor(diffTime / (1000 * 60 * 60))
|
||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24))
|
||
|
||
if (diffHours < 1) {
|
||
return '刚刚'
|
||
} else if (diffHours < 24) {
|
||
return `${diffHours}小时前`
|
||
} else if (diffDays < 7) {
|
||
return `${diffDays}天前`
|
||
} else {
|
||
return date.toLocaleDateString('zh-CN')
|
||
}
|
||
}
|
||
|
||
const readMessage = (message) => {
|
||
if (!message.read) {
|
||
message.read = true
|
||
saveMessages()
|
||
}
|
||
|
||
// 显示消息详情
|
||
uni.showModal({
|
||
title: message.title,
|
||
content: message.content,
|
||
showCancel: false
|
||
})
|
||
}
|
||
|
||
const markAllRead = () => {
|
||
messagesList.value.forEach(msg => {
|
||
msg.read = true
|
||
})
|
||
saveMessages()
|
||
|
||
uni.showToast({
|
||
title: '已全部标记为已读',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
const clearReadMessages = () => {
|
||
uni.showModal({
|
||
title: '清理已读消息',
|
||
content: '确定要删除所有已读消息吗?此操作不可恢复。',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
messagesList.value = messagesList.value.filter(msg => !msg.read)
|
||
saveMessages()
|
||
|
||
uni.showToast({
|
||
title: '已清理已读消息',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const clearAllMessages = () => {
|
||
uni.showModal({
|
||
title: '清空所有消息',
|
||
content: '确定要删除所有消息吗?此操作不可恢复。',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
messagesList.value = []
|
||
saveMessages()
|
||
|
||
uni.showToast({
|
||
title: '已清空所有消息',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
return {
|
||
notificationSettings,
|
||
dndSettings,
|
||
messagesList,
|
||
showStartTime,
|
||
showEndTime,
|
||
selectedStartTime,
|
||
selectedEndTime,
|
||
unreadCount,
|
||
onSettingChange,
|
||
onDndToggle,
|
||
showStartTimePicker,
|
||
showEndTimePicker,
|
||
onStartTimeConfirm,
|
||
onEndTimeConfirm,
|
||
getMessageIcon,
|
||
formatTime,
|
||
readMessage,
|
||
markAllRead,
|
||
clearReadMessages,
|
||
clearAllMessages
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.notifications-container {
|
||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||
min-height: 100vh;
|
||
padding-bottom: 40rpx;
|
||
}
|
||
|
||
/* 通用卡片样式 */
|
||
.settings-card,
|
||
.dnd-card,
|
||
.messages-card,
|
||
.cleanup-card {
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20rpx);
|
||
margin: 0 30rpx 24rpx 30rpx;
|
||
border-radius: 24rpx;
|
||
padding: 32rpx;
|
||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
|
||
.card-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
}
|
||
|
||
.header-action {
|
||
.action-text {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 设置列表 */
|
||
.settings-list {
|
||
.setting-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 24rpx 0;
|
||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.setting-info {
|
||
flex: 1;
|
||
|
||
.setting-title {
|
||
display: block;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.setting-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
line-height: 1.4;
|
||
}
|
||
}
|
||
|
||
.setting-switch {
|
||
margin-left: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 免打扰设置 */
|
||
.dnd-content {
|
||
.dnd-toggle {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 24rpx;
|
||
|
||
.toggle-info {
|
||
flex: 1;
|
||
|
||
.toggle-title {
|
||
display: block;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.toggle-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.toggle-switch {
|
||
margin-left: 24rpx;
|
||
}
|
||
}
|
||
|
||
.dnd-time {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 20rpx;
|
||
|
||
.time-item {
|
||
padding: 20rpx;
|
||
background: rgba(255, 138, 128, 0.05);
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.time-label {
|
||
display: block;
|
||
font-size: 22rpx;
|
||
color: #666666;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.time-value {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 消息列表 */
|
||
.messages-list {
|
||
.message-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
transition: all 0.3s ease;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
&.unread {
|
||
background: rgba(255, 138, 128, 0.05);
|
||
border-radius: 16rpx;
|
||
padding: 20rpx;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.message-icon {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 20rpx;
|
||
|
||
&.system {
|
||
background: rgba(33, 150, 243, 0.1);
|
||
}
|
||
|
||
&.pet {
|
||
background: rgba(255, 138, 128, 0.1);
|
||
}
|
||
|
||
&.adoption {
|
||
background: rgba(76, 175, 80, 0.1);
|
||
}
|
||
|
||
&.family {
|
||
background: rgba(255, 152, 0, 0.1);
|
||
}
|
||
|
||
&.marketing {
|
||
background: rgba(156, 39, 176, 0.1);
|
||
}
|
||
|
||
.icon-text {
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
|
||
.message-content {
|
||
flex: 1;
|
||
|
||
.message-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.message-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
line-height: 1.5;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.message-time {
|
||
font-size: 20rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
.message-status {
|
||
margin-left: 16rpx;
|
||
|
||
.unread-dot {
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
background: #FF8A80;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 空消息状态 */
|
||
.empty-messages {
|
||
text-align: center;
|
||
padding: 60rpx 0;
|
||
|
||
.empty-icon {
|
||
font-size: 60rpx;
|
||
margin-bottom: 16rpx;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.empty-text {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
|
||
/* 清理设置 */
|
||
.cleanup-list {
|
||
.cleanup-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 24rpx 0;
|
||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
|
||
transition: all 0.3s ease;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
&:active {
|
||
background: rgba(255, 138, 128, 0.05);
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.cleanup-info {
|
||
flex: 1;
|
||
|
||
.cleanup-title {
|
||
display: block;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
color: #333333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.cleanup-desc {
|
||
font-size: 24rpx;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.cleanup-action {
|
||
.action-arrow {
|
||
font-size: 24rpx;
|
||
color: #FF8A80;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 375px) {
|
||
.notifications-container {
|
||
.settings-card,
|
||
.dnd-card,
|
||
.messages-card,
|
||
.cleanup-card {
|
||
margin: 0 20rpx 20rpx 20rpx;
|
||
padding: 24rpx;
|
||
}
|
||
|
||
.dnd-time {
|
||
gap: 16rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 动画效果 */
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.notifications-container > view {
|
||
animation: fadeIn 0.5s ease-out;
|
||
}
|
||
|
||
.notifications-container > view:nth-child(1) { animation-delay: 0.1s; }
|
||
.notifications-container > view:nth-child(2) { animation-delay: 0.2s; }
|
||
.notifications-container > view:nth-child(3) { animation-delay: 0.3s; }
|
||
.notifications-container > view:nth-child(4) { animation-delay: 0.4s; }
|
||
</style>
|