wx-starlock/pages/notificationList/notificationList.vue
2024-09-30 14:03:25 +08:00

312 lines
8.1 KiB
Vue

<template>
<view>
<scroll-view v-if="deviceInfo" scroll-y="true" :style="{ height: deviceInfo.windowHeight + 'px' }"
lower-threshold="100" @refresherrefresh="refresherList" :refresher-enabled="true" @scrolltolower="nextPage"
:refresher-triggered="refresherTriggered">
<view class="list" v-if="requestFinished">
<view v-if="notificationList.length === 0">
<image class="empty-list" src="/static/images/background_empty_list.png" mode="aspectFill"></image>
<view class="empty-list-text">暂无数据</view>
</view>
<up-swipe-action v-else>
<up-swipe-action-item class="item" ref="swipeItem" :options="options"
v-for="(notification,index) in notificationList" :key="notification.id"
:threshold="50" @click="deleteNotification(notification, index)">
<view class="notification" @click="toDetail(index,notification)">
<view v-if="notification.readAt === 0">
<image class="icon" src="/static/images/icon_notification_unread.png" mode="aspectFill"></image>
<view class="point"></view>
</view>
<image v-else class="icon" src="/static/images/icon_notification_read.png" mode="aspectFill"></image>
<view>
<view class="content" :style="{color:notification.readAt === 0?'#000000':'#6c6c6c'}">{{ notification.data
}}</view>
<view class="time" :style="{color:notification.readAt === 0?'#000000':'#6c6c6c'}">{{ timeFormat(notification.createdAt, 'yyyy-mm-dd h:M') }}</view>
</view>
</view>
</up-swipe-action-item>
</up-swipe-action>
</view>
</scroll-view>
<view class="delete" @click="deleteAllNotification">
<image class="delete-image" src="/static/images/icon_delete.png" mode="aspectFill"></image>
</view>
</view>
</template>
<script>
import { mapActions, mapState } from 'pinia'
import { useNotificationStore } from '../../stores/notification'
import { useBasicStore } from '../../stores/basic'
import { timeFormat } from 'uview-plus'
import { deleteAllNotification, deleteNotification, markAsReadNotification } from '../../api/notification'
export default {
data () {
return {
refresherTriggered: false,
requestFinished: false,
deviceInfo: null,
options: [{
text: '删除',
style: {
backgroundColor: '#f56c6c'
}
}],
}
},
computed: {
...mapState(useNotificationStore, ['notificationTotal', 'notificationList', 'notificationSearch']),
},
async onLoad () {
uni.showLoading({
title: '加载中',
mask: true
})
this.deviceInfo = await this.getDeviceInfo()
const { code, message } = await this.getNotificationList(this.notificationSearch)
uni.hideLoading()
this.requestFinished = true
if (code !== 0) {
uni.showToast({
title: message,
icon: 'none'
})
}
},
methods: {
timeFormat,
...mapActions(useNotificationStore, ['getNotificationList', 'updateNotificationSearch', 'updateNotificationItem','deleteNotificationItem']),
...mapActions(useBasicStore, ['routeJump', 'getDeviceInfo', 'getNetworkType']),
async deleteNotification (notification, index) {
const netWork = await this.getNetworkType()
if (!netWork) {
return
}
this.$refs.swipeItem[index].closeHandler()
uni.showModal({
title: '提示',
content: '确定要删除该通知吗?',
success: async (res) => {
if (res.confirm) {
const { code, message } = await deleteNotification({
id: notification.id
})
if (code === 0) {
this.deleteNotificationItem(index)
uni.showToast({
title: '删除成功',
icon: 'none'
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
}
}
})
},
deleteAllNotification() {
uni.showModal({
title: '提示',
content: '确定要删除所有通知吗?',
success: async (res) => {
if (res.confirm) {
const { code, message } = await deleteAllNotification()
if (code === 0) {
uni.showToast({
title: '删除成功',
icon: 'none'
})
this.updateNotificationSearch({
pageNo: 1
})
await this.getNotificationList(this.notificationSearch)
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
}
}
})
},
toDetail(index, notification) {
if(notification.readAt === 0) {
notification.readAt = 1
this.updateNotificationItem(index,notification)
markAsReadNotification({
id: notification.id
})
}
this.routeJump({
name: 'notificationDetail',
params: {
notification: JSON.stringify(notification)
}
})
},
async refresherList() {
this.refresherTriggered = true
this.updateNotificationSearch({
pageNo: 1
})
const { code, message } = await this.getNotificationList(this.notificationSearch)
if(code === 0) {
uni.showToast({
title: '刷新成功',
icon: 'none'
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
this.refresherTriggered = false
},
async nextPage() {
if(this.notificationTotal <= this.notificationSearch.pageNo * this.notificationSearch.pageSize) {
return
}
const pageNo = this.notificationSearch.pageNo + 1
const params = {
...this.notificationSearch,
pageNo
}
const { code, message } = await this.getNotificationList(params)
if(code === 0) {
this.updateNotificationSearch({
pageNo
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
},
},
}
</script>
<style lang="scss">
page {
background-color: $uni-bg-color-grey;
}
.u-swipe-action {
overflow: inherit !important;
width: 700rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding-bottom: 140rpx !important;
}
.u-swipe-action-item {
overflow: inherit !important;
border-radius: 32rpx !important;
background: transparent !important;
}
.u-swipe-action-item__right {
margin-top: 32rpx;
border-radius: 32rpx !important;
}
.u-swipe-action-item__content {
border-radius: 32rpx !important;
margin-left: 25rpx;
}
.u-swipe-action-item__right__button {
border-radius: 32rpx !important;
}
</style>
<style lang="scss" scoped>
.item {
border-radius: 32rpx;
}
.notification {
border-radius: 32rpx;
margin-top: 32rpx;
display: flex;
width: 636rpx;
padding: 32rpx;
justify-content: space-between;
align-items: center;
position: relative;
box-shadow: 2rpx 2rpx 10rpx rgba(0, 0, 0, 0.3);
.icon {
width: 50rpx;
height: 50rpx;
}
.point {
width: 16rpx;
height: 16rpx;
background-color: #ff0000;
border-radius: 50%;
position: absolute;
top: 41rpx;
left: 72rpx;
}
.content {
width: 550rpx;
font-size: 28rpx;
color: #6c6c6c;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: bold;
}
.time {
font-size: 24rpx;
color: #6c6c6c;
margin-top: 5rpx;
font-weight: bold;
}
}
.delete {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background-color: #5db5aa;
position: fixed;
bottom: 80rpx;
right: 30rpx;
display: flex;
justify-content: center;
align-items: center;
.delete-image {
width: 45rpx;
height: 45rpx;
}
}
.empty-list {
width: 150rpx;
height: 150rpx;
margin: 400rpx auto 20rpx 50%;
transform: translateX(-50%);
}
.empty-list-text {
text-align: center;
font-size: 32rpx;
color: #999999;
}
</style>