wx-starlock/pages/notificationList/notificationList.vue

372 lines
9.7 KiB
Vue
Raw Normal View History

2024-09-30 14:03:25 +08:00
<template>
<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" @scroll="scroll">
<view v-if="isLogin">
2024-09-30 14:03:25 +08:00
<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"
2024-10-07 10:35:37 +08:00
:threshold="50" @click="deleteNotification(notification, index)" :index="index"
:name="index">
2024-09-30 14:03:25 +08:00
<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>
</view>
<view v-else>
<view class="tips">因智能门锁与账号绑定登录为手机号登录</view>
<label for="phone">
<view class="button-login">登录</view>
</label>
</view>
</scroll-view>
<view class="delete" @click="deleteAllNotification" v-if="isLogin && requestFinished && notificationList.length !==
0">
<image class="delete-image" src="/static/images/icon_delete.png" mode="aspectFill"></image>
2024-09-30 14:03:25 +08:00
</view>
<button open-type="getPhoneNumber" style="display:none" id="phone" @getphonenumber="getphonenumber"></button>
2024-09-30 14:03:25 +08:00
</template>
<script>
import { mapActions, mapState } from 'pinia'
import { useNotificationStore } from '@/stores/notification'
import { useBasicStore } from '@/stores/basic'
2024-09-30 14:03:25 +08:00
import { timeFormat } from 'uview-plus'
import { deleteAllNotification, deleteNotification, markAsReadNotification } from '@/api/notification'
import { useUserStore } from '@/stores/user'
2024-09-30 14:03:25 +08:00
export default {
data () {
return {
refresherTriggered: false,
requestFinished: false,
deviceInfo: null,
options: [{
text: '删除',
style: {
backgroundColor: '#f56c6c'
}
}],
}
},
computed: {
...mapState(useNotificationStore, ['notificationTotal', 'notificationList', 'notificationSearch']),
...mapState(useUserStore, ['isLogin']),
2024-09-30 14:03:25 +08:00
},
async onLoad () {
this.deviceInfo = await this.getDeviceInfo()
if(this.isLogin) {
await this.getList()
2024-09-30 14:03:25 +08:00
}
this.requestFinished = true
2024-09-30 14:03:25 +08:00
},
methods: {
timeFormat,
...mapActions(useNotificationStore, ['getNotificationList', 'updateNotificationSearch', 'updateNotificationItem','deleteNotificationItem']),
...mapActions(useBasicStore, ['routeJump', 'getDeviceInfo', 'getNetworkType']),
...mapActions(useUserStore, ['phoneLogin']),
async getList() {
uni.showLoading({
title: '加载中',
mask: true
})
const { code, message } = await this.getNotificationList(this.notificationSearch)
uni.hideLoading()
if (code !== 0) {
uni.showToast({
title: message,
icon: 'none'
})
}
},
async getphonenumber(data) {
if(data.detail.errMsg === 'getPhoneNumber:fail user deny') {
return
}
const result = await this.phoneLogin({
encryptedData: data.detail.encryptedData,
iv: data.detail.iv
})
if(!result) {
uni.showToast({
title: '登录失败,请重试',
icon: 'none'
})
}
},
scroll() {
2024-10-07 10:35:37 +08:00
this.$refs.swipeItem.forEach(item => {
if(item.show) {
item.closeHandler()
}
})
},
2024-09-30 14:03:25 +08:00
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;
}
.tips {
margin-top: 40vh;
padding: 32rpx 0;
text-align: center;
font-size: 28rpx;
color: #999999;
}
.button-login {
border-radius: 46rpx;
width: 650rpx;
height: 120rpx;
line-height: 120rpx;
text-align: center;
margin-left: 50rpx;
background: #63b8af;
color: #ffffff;
font-size: 48rpx;
font-weight: bold;
}
2024-09-30 14:03:25 +08:00
</style>