55 lines
2.4 KiB
Vue
55 lines
2.4 KiB
Vue
<template>
|
|
<view class="page-shell notification-page">
|
|
<PageHeader title="消息通知" action="全部已读" @action="readAll" />
|
|
<view class="notice-intro"><text>{{ loadError || '与家谱相关的提醒都会留在这里。' }}</text></view>
|
|
<view class="notice-list"><view v-for="item in list" :key="item.id" class="notice-row" :class="{ unread: item.unread }" @click="read(item)"><view class="notice-dot"></view><view class="notice-copy"><text class="notice-title">{{ item.title }}</text><text class="notice-content">{{ item.content }}</text></view><text class="notice-time">{{ item.time }}</text></view></view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, ref } from 'vue'
|
|
import PageHeader from '@/components/PageHeader.vue'
|
|
import { appApi } from '@/utils/api.js'
|
|
|
|
const list = ref([])
|
|
const loadError = ref('')
|
|
onMounted(async () => {
|
|
try {
|
|
list.value = await appApi.getNotifications()
|
|
} catch (error) {
|
|
loadError.value = error.message || '通知加载失败。'
|
|
}
|
|
})
|
|
const read = async (item) => {
|
|
if (!item.unread) return
|
|
try {
|
|
await appApi.markNotificationRead(item.id)
|
|
item.unread = false
|
|
} catch (error) {
|
|
uni.showToast({ title: error.message || '标记已读失败', icon: 'none' })
|
|
}
|
|
}
|
|
const readAll = async () => {
|
|
try {
|
|
await appApi.markAllNotificationsRead()
|
|
list.value.forEach((item) => { item.unread = false })
|
|
uni.showToast({ title: '已全部标记为已读', icon: 'none' })
|
|
} catch (error) {
|
|
uni.showToast({ title: error.message || '操作失败,请稍后重试', icon: 'none' })
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.notification-page { padding-bottom: 36rpx; }
|
|
.notice-intro { padding: 28rpx 30rpx; background: #efe3cd; color: $ink-muted; font-size: 24rpx; }
|
|
.notice-list { margin: 0 28rpx; }
|
|
.notice-row { display: flex; align-items: flex-start; gap: 16rpx; padding: 28rpx 0; border-bottom: 1rpx solid #e4d8c0; }
|
|
.notice-dot { width: 14rpx; height: 14rpx; flex: 0 0 auto; margin-top: 13rpx; border-radius: 50%; background: transparent; }
|
|
.notice-row.unread .notice-dot { background: $brand-red; }
|
|
.notice-copy { min-width: 0; flex: 1; }
|
|
.notice-title { display: block; color: $ink; font-size: 30rpx; font-weight: 700; }
|
|
.notice-content { display: block; margin-top: 10rpx; color: $ink-muted; font-size: 24rpx; line-height: 1.55; }
|
|
.notice-time { flex: 0 0 auto; color: #a19482; font-size: 20rpx; }
|
|
</style>
|