wx-starlock/pages/main/notificationList.vue

455 lines
11 KiB
Vue
Raw Normal View History

2024-09-30 14:03:25 +08:00
<template>
2025-02-06 11:37:41 +08:00
<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">
2025-02-06 11:37:41 +08:00
<image
class="empty-list"
src="https://oss-lock.xhjcn.ltd/mp/background_empty_list.png"
2025-02-06 11:37:41 +08:00
mode="aspectFill"
></image>
2024-09-30 14:03:25 +08:00
<view class="empty-list-text">暂无数据</view>
</view>
<up-swipe-action v-else>
2025-02-06 11:37:41 +08:00
<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)"
:index="index"
:name="index"
>
<view class="notification" @click="toDetail(index, notification)">
<view v-if="notification.readAt === 0">
<image
class="icon"
src="https://oss-lock.xhjcn.ltd/mp/icon_notification_unread.png"
2025-02-06 11:37:41 +08:00
mode="aspectFill"
></image>
<view class="point"></view>
</view>
<image
v-else
class="icon"
src="https://oss-lock.xhjcn.ltd/mp/icon_notification_read.png"
2025-02-06 11:37:41 +08:00
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>
2024-09-30 14:03:25 +08:00
</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>
2025-02-06 11:37:41 +08:00
<view
class="delete"
@click="deleteAllNotification"
v-if="isLogin && requestFinished && notificationList.length !== 0"
>
<image
class="delete-image"
src="https://oss-lock.xhjcn.ltd/mp/icon_delete.png"
mode="aspectFill"
/>
2024-09-30 14:03:25 +08:00
</view>
2025-02-06 11:37:41 +08:00
<button
open-type="getPhoneNumber"
style="display: none"
id="phone"
@getphonenumber="getphonenumber"
></button>
2024-09-30 14:03:25 +08:00
</template>
<script>
2025-02-06 11:37:41 +08:00
import { mapActions, mapState } from 'pinia'
import { timeFormat } from 'uview-plus'
import { useNotificationStore } from '@/stores/notification'
import { useBasicStore } from '@/stores/basic'
import {
deleteAllNotification,
deleteNotification,
markAsReadNotification
} from '@/api/notification'
import { useUserStore } from '@/stores/user'
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
export default {
data() {
return {
refresherTriggered: false,
requestFinished: false,
deviceInfo: null,
options: [
{
text: '删除',
style: {
backgroundColor: '#f56c6c'
}
}
]
}
},
2025-02-06 11:37:41 +08:00
computed: {
...mapState(useNotificationStore, [
'notificationTotal',
'notificationList',
'notificationSearch'
]),
...mapState(useUserStore, ['isLogin'])
},
async onLoad() {
this.deviceInfo = await this.getDeviceInfo()
if (this.isLogin) {
await this.getList()
}
2025-02-06 11:37:41 +08:00
this.requestFinished = true
},
2025-02-06 11:37:41 +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
}
2025-03-25 15:08:00 +08:00
const that = this
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'weixin',
async success(loginRes) {
const result = await that.phoneLogin({
encryptedData: data.detail.encryptedData,
iv: data.detail.iv,
code: loginRes.code
})
uni.hideLoading()
if (!result) {
uni.showToast({
title: result.message,
icon: 'none'
})
}
},
fail() {
uni.hideLoading()
uni.showToast({
title: '登录失败,请重试'
})
}
2025-02-06 11:37:41 +08:00
})
},
scroll() {
this.$refs.swipeItem.forEach(item => {
if (item.show) {
item.closeHandler()
}
})
},
async deleteNotification(notification, index) {
const netWork = await this.getNetworkType()
if (!netWork) {
return
2024-10-07 10:35:37 +08:00
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
this.$refs.swipeItem[index].closeHandler()
uni.showModal({
title: '提示',
content: '确定要删除该通知吗?',
success: async res => {
if (res.confirm) {
const { code, message } = await deleteNotification({
id: notification.id
2024-09-30 14:03:25 +08:00
})
2025-02-06 11:37:41 +08:00
if (code === 0) {
this.deleteNotificationItem(index)
uni.showToast({
title: '删除成功',
icon: 'none'
})
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
2024-09-30 14:03:25 +08:00
}
}
2025-02-06 11:37:41 +08:00
})
},
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'
})
}
2024-09-30 14:03:25 +08:00
}
}
})
2025-02-06 11:37:41 +08:00
},
toDetail(index, notification) {
if (notification.readAt === 0) {
notification.readAt = 1
this.updateNotificationItem(index, notification)
markAsReadNotification({
id: notification.id
})
2024-09-30 14:03:25 +08:00
}
2025-02-06 11:37:41 +08:00
this.routeJump({
name: 'notificationDetail',
params: {
notification: JSON.stringify(notification)
}
2024-09-30 14:03:25 +08:00
})
2025-02-06 11:37:41 +08:00
},
async refresherList() {
this.refresherTriggered = true
2024-09-30 14:03:25 +08:00
this.updateNotificationSearch({
2025-02-06 11:37:41 +08:00
pageNo: 1
2024-09-30 14:03:25 +08:00
})
2025-02-06 11:37:41 +08:00
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'
})
}
2024-09-30 14:03:25 +08:00
}
2025-02-06 11:37:41 +08:00
}
}
2024-09-30 14:03:25 +08:00
</script>
<style lang="scss">
2025-02-06 11:37:41 +08:00
page {
background-color: $uni-bg-color-grey;
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.u-swipe-action {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
2025-06-06 15:20:34 +08:00
width: 700rpx;
2025-02-06 11:37:41 +08:00
padding-bottom: 140rpx !important;
2025-06-06 15:20:34 +08:00
overflow: inherit !important;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.u-swipe-action-item {
overflow: inherit !important;
background: transparent !important;
2025-06-06 15:20:34 +08:00
border-radius: 32rpx !important;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.u-swipe-action-item__right {
margin-top: 32rpx;
border-radius: 32rpx !important;
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.u-swipe-action-item__content {
margin-left: 25rpx;
2025-06-06 15:20:34 +08:00
border-radius: 32rpx !important;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.u-swipe-action-item__right__button {
border-radius: 32rpx !important;
}
2024-09-30 14:03:25 +08:00
</style>
<style lang="scss" scoped>
2025-02-06 11:37:41 +08:00
.item {
border-radius: 32rpx;
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.notification {
2025-06-06 15:20:34 +08:00
position: relative;
2025-02-06 11:37:41 +08:00
display: flex;
2025-06-06 15:20:34 +08:00
align-items: center;
justify-content: space-between;
2025-02-06 11:37:41 +08:00
width: 636rpx;
padding: 32rpx;
2025-06-06 15:20:34 +08:00
margin-top: 32rpx;
border-radius: 32rpx;
2025-02-06 11:37:41 +08:00
box-shadow: 2rpx 2rpx 10rpx rgba(0, 0, 0, 0.3);
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.icon {
width: 50rpx;
height: 50rpx;
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.point {
2025-06-06 15:20:34 +08:00
position: absolute;
top: 41rpx;
left: 72rpx;
2025-02-06 11:37:41 +08:00
width: 16rpx;
height: 16rpx;
background-color: #ff0000;
border-radius: 50%;
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.content {
width: 550rpx;
overflow: hidden;
text-overflow: ellipsis;
2025-06-06 15:20:34 +08:00
font-size: 28rpx;
2025-02-06 11:37:41 +08:00
font-weight: bold;
2025-06-06 15:20:34 +08:00
color: #6c6c6c;
white-space: nowrap;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.time {
margin-top: 5rpx;
2025-06-06 15:20:34 +08:00
font-size: 24rpx;
2025-02-06 11:37:41 +08:00
font-weight: bold;
2025-06-06 15:20:34 +08:00
color: #6c6c6c;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
}
2025-02-06 11:37:41 +08:00
.delete {
position: fixed;
right: 30rpx;
2025-06-06 15:20:34 +08:00
bottom: 80rpx;
2025-02-06 11:37:41 +08:00
display: flex;
align-items: center;
2025-06-06 15:20:34 +08:00
justify-content: center;
width: 100rpx;
height: 100rpx;
background-color: #5db5aa;
border-radius: 50%;
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.delete-image {
width: 45rpx;
height: 45rpx;
}
2024-09-30 14:03:25 +08:00
}
2025-02-06 11:37:41 +08:00
.empty-list {
width: 150rpx;
height: 150rpx;
margin: 400rpx auto 20rpx 50%;
transform: translateX(-50%);
}
2024-09-30 14:03:25 +08:00
2025-02-06 11:37:41 +08:00
.empty-list-text {
font-size: 32rpx;
color: #999999;
2025-06-06 15:20:34 +08:00
text-align: center;
2025-02-06 11:37:41 +08:00
}
2025-02-06 11:37:41 +08:00
.tips {
padding: 32rpx 0;
2025-06-06 15:20:34 +08:00
margin-top: 40vh;
2025-02-06 11:37:41 +08:00
font-size: 28rpx;
color: #999999;
2025-06-06 15:20:34 +08:00
text-align: center;
2025-02-06 11:37:41 +08:00
}
2025-02-06 11:37:41 +08:00
.button-login {
width: 650rpx;
height: 120rpx;
margin-left: 50rpx;
font-size: 48rpx;
font-weight: bold;
2025-06-06 15:20:34 +08:00
line-height: 120rpx;
color: #ffffff;
text-align: center;
background: #63b8af;
border-radius: 46rpx;
2025-02-06 11:37:41 +08:00
}
2024-09-30 14:03:25 +08:00
</style>