添加消息通知界面

This commit is contained in:
2025-09-28 00:14:39 +08:00
parent e8186e723f
commit 38c00049ef
6 changed files with 450 additions and 1 deletions

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
}
}

View File

@@ -0,0 +1,201 @@
// 定义通知数据类型
interface Notification {
id: string;
type: 'system' | 'activity' | 'message';
title: string;
message: string;
time: string;
read: boolean;
}
Page({
data: {
// 标签状态
currentTab: 0,
// 所有通知数据
notifications: [] as Notification[],
// 过滤后的通知(根据当前标签)
filteredNotifications: [] as Notification[],
// 未读数量统计
totalUnread: 0,
systemUnread: 0,
activityUnread: 0,
messageUnread: 0
},
onLoad() {
// 初始化通知数据
this.initNotifications();
},
// 初始化通知数据
initNotifications() {
// 模拟通知数据
const notifications: Notification[] = [
{
id: '1',
type: 'system',
title: '系统更新通知',
message: '您的应用已更新至最新版本,新增多项功能,提升了使用体验。',
time: '今天 08:30',
read: false
},
{
id: '2',
type: 'activity',
title: '新活动上线',
message: '限时优惠活动已开始,点击查看详情,参与活动赢取大奖!',
time: '昨天 15:45',
read: false
},
{
id: '3',
type: 'message',
title: '张三给你发了消息',
message: '在吗?上次说的事情有进展了,我们约个时间讨论一下吧。',
time: '昨天 10:20',
read: true
},
{
id: '4',
type: 'system',
title: '账号安全提醒',
message: '您的账号在新设备登录,如非本人操作,请及时修改密码。',
time: '2023-05-15',
read: false
},
{
id: '5',
type: 'activity',
title: '活动即将结束',
message: '您参与的积分兑换活动还有3天结束抓紧时间兑换哦',
time: '2023-05-14',
read: true
},
{
id: '6',
type: 'message',
title: '李四回复了你的评论',
message: '你说得很有道理,我也这么认为。',
time: '2023-05-12',
read: false
}
];
// 更新数据
this.setData({
notifications
});
// 过滤通知并计算未读数量
this.filterNotifications();
this.calculateUnreadCounts();
},
// 切换标签
switchTab(e: { currentTarget: { dataset: { tab: number } } }) {
const tab = e.currentTarget.dataset.tab;
this.setData({
currentTab: tab
});
this.filterNotifications();
},
// 根据当前标签过滤通知
filterNotifications() {
const { currentTab, notifications } = this.data;
let filtered: Notification[] = [];
switch(currentTab) {
case 0: // 全部
filtered = notifications;
break;
case 1: // 系统
filtered = notifications.filter(item => item.type === 'system');
break;
case 2: // 活动
filtered = notifications.filter(item => item.type === 'activity');
break;
case 3: // 私信
filtered = notifications.filter(item => item.type === 'message');
break;
}
this.setData({
filteredNotifications: filtered
});
},
// 计算未读数量
calculateUnreadCounts() {
const { notifications } = this.data;
// 计算各类未读数量
const systemUnread = notifications.filter(item => item.type === 'system' && !item.read).length;
const activityUnread = notifications.filter(item => item.type === 'activity' && !item.read).length;
const messageUnread = notifications.filter(item => item.type === 'message' && !item.read).length;
const totalUnread = systemUnread + activityUnread + messageUnread;
this.setData({
totalUnread,
systemUnread,
activityUnread,
messageUnread
});
},
// 打开通知详情
openNotification(e: { currentTarget: { dataset: { id: string } } }) {
const id = e.currentTarget.dataset.id;
const { notifications } = this.data;
// 将通知标记为已读
const updatedNotifications = notifications.map(item => {
if (item.id === id && !item.read) {
return { ...item, read: true };
}
return item;
});
this.setData({
notifications: updatedNotifications
});
// 更新过滤列表和未读数量
this.filterNotifications();
this.calculateUnreadCounts();
// 跳转到通知详情页(实际项目中实现)
wx.showToast({
title: '查看通知详情',
icon: 'none'
});
},
// 标记全部已读
markAllAsRead() {
const { notifications } = this.data;
// 将所有通知标记为已读
const updatedNotifications = notifications.map(item => ({
...item,
read: true
}));
this.setData({
notifications: updatedNotifications
});
// 更新过滤列表和未读数量
this.filterNotifications();
this.calculateUnreadCounts();
wx.showToast({
title: '全部已读',
icon: 'none'
});
}
});

View File

@@ -0,0 +1,54 @@
<view class="notification-page">
<!-- 顶部导航栏 -->
<view class="navbar">
<view class="navbar-title">消息通知</view>
<view class="navbar-right" bindtap="markAllAsRead">
<text class="mark-read">全部已读</text>
</view>
</view>
<!-- 通知分类标签 -->
<view class="tabs">
<view class="tab-item {{currentTab === 0 ? 'active' : ''}}" bindtap="switchTab" data-tab="0">
<text>全部</text>
<view class="badge" wx:if="{{totalUnread > 0}}">{{totalUnread}}</view>
</view>
<view class="tab-item {{currentTab === 1 ? 'active' : ''}}" bindtap="switchTab" data-tab="1">
<text>系统</text>
<view class="badge" wx:if="{{systemUnread > 0}}">{{systemUnread}}</view>
</view>
<view class="tab-item {{currentTab === 2 ? 'active' : ''}}" bindtap="switchTab" data-tab="2">
<text>活动</text>
<view class="badge" wx:if="{{activityUnread > 0}}">{{activityUnread}}</view>
</view>
<view class="tab-item {{currentTab === 3 ? 'active' : ''}}" bindtap="switchTab" data-tab="3">
<text>私信</text>
<view class="badge" wx:if="{{messageUnread > 0}}">{{messageUnread}}</view>
</view>
</view>
<!-- 通知列表 -->
<view class="notification-list">
<view wx:for="{{filteredNotifications}}" wx:key="id" class="notification-item" bindtap="openNotification" data-id="{{item.id}}">
<view class="avatar-container">
<view class="avatar {{item.type === 'system' ? 'system-avatar' : item.type === 'activity' ? 'activity-avatar' : 'message-avatar'}}">
<text class="avatar-icon">{{item.type === 'system' ? '系' : item.type === 'activity' ? '活' : '私'}}</text>
</view>
<view class="unread-dot" wx:if="{{!item.read}}"></view>
</view>
<view class="notification-content">
<view class="notification-header">
<text class="title">{{item.title}}</text>
<text class="time">{{item.time}}</text>
</view>
<text class="message">{{item.message}}</text>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" wx:if="{{filteredNotifications.length === 0}}">
<view class="empty-icon">📭</view>
<text class="empty-text">暂无通知</text>
</view>
</view>
</view>

View File

@@ -0,0 +1,181 @@
.notification-page {
background-color: #f5f5f5;
min-height: 100vh;
}
/* 导航栏样式 */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background-color: white;
border-bottom: 1px solid #eee;
}
.navbar-title {
font-size: 18px;
font-weight: 600;
color: #333;
}
.mark-read {
font-size: 14px;
color: #07c160;
}
/* 标签样式 */
.tabs {
display: flex;
background-color: white;
border-bottom: 1px solid #eee;
overflow-x: auto;
white-space: nowrap;
}
.tab-item {
display: inline-flex;
align-items: center;
padding: 14px 20px;
font-size: 15px;
color: #666;
position: relative;
}
.tab-item.active {
color: #07c160;
}
.tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background-color: #07c160;
}
.badge {
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: 50%;
background-color: #ff3b30;
color: white;
font-size: 12px;
margin-left: 6px;
}
/* 通知列表样式 */
.notification-list {
padding-bottom: 20px;
}
.notification-item {
display: flex;
padding: 16px;
background-color: white;
border-bottom: 1px solid #eee;
transition: background-color 0.2s;
}
.notification-item:active {
background-color: #f9f9f9;
}
.avatar-container {
position: relative;
margin-right: 14px;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 16px;
font-weight: 500;
}
.system-avatar {
background-color: #07c160;
}
.activity-avatar {
background-color: #ff9500;
}
.message-avatar {
background-color: #007aff;
}
.unread-dot {
position: absolute;
top: -2px;
right: -2px;
width: 12px;
height: 12px;
border-radius: 50%;
background-color: #ff3b30;
}
.notification-content {
flex: 1;
overflow: hidden;
}
.notification-header {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
}
.title {
font-size: 16px;
color: #333;
font-weight: 500;
max-width: 80%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
font-size: 12px;
color: #999;
}
.message {
font-size: 14px;
color: #666;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
line-height: 1.4;
}
/* 空状态样式 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 0;
color: #999;
}
.empty-icon {
font-size: 60px;
margin-bottom: 20px;
}
.empty-text {
font-size: 16px;
}

View File

@@ -156,6 +156,12 @@ Component({
}
});
},
gotoMessage(){
console.log("跳转到notifitions界面")
wx.navigateTo({
url: `/pages/notifications/notifications?id=${this.data.userinfo.uid}`,
});
}