修改消息通知页面

This commit is contained in:
JACKYMYPERSON
2025-09-28 17:45:40 +08:00
parent f78448e8da
commit ea1ee70781
3 changed files with 291 additions and 429 deletions

View File

@@ -1,201 +1,136 @@
// 定义通知数据类型
interface Notification {
id: string;
type: 'system' | 'activity' | 'message';
title: string;
message: string;
time: string;
read: boolean;
}
// message.ts (适配最新数据库结构)
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'
});
// 接口定义从API获取的原始消息数据结构 (与数据库完全一致)
interface IApiMessage {
id: number;
sender_id: string;
receiver_id: string;
status: number; // 假设 status 字段仍有其他用途
sequence: string;
created_at: string; // e.g., "2025-09-28 18:10:00"
content: string;
is_read: 0 | 1; // 0: 未读, 1: 已读
msg_type: 'comment' | 'like' | 'follow' | 'system';
target: string | null; // e.g., "post:123", "user:456", "/pages/...", or null
}
});
// 接口:定义页面渲染所需的数据结构
interface IViewMessage {
id: number;
type: 'system' | 'user'; // 用于区分图标
title: string;
content: string;
timestamp: string;
is_read: 0 | 1; // 用于显示未读红点
target: string | null; // 用于点击跳转
}
Page({
data: {
systemIcon: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iIzQ3OTZGMyI+PHBhdGggZD0iTTIgMTVoMnYyaC0yem0wLTRoMnYyaC0yem0wLThoMnY2aC0yem00IDEyaDJ2MmgtMnptMC00aDJ2MmgtMnptMC00aDJ2MmgtMnptMTYtNGgtOHYtMmgtNHYyaC0yYTEgMSAwIDAgMC0xIDF2MTBhMSAxIDAgMCAwIDEgMWgxNGExIDEgMCAwIDAgMS0xdi0xMGExIDEgMCAwIDAtMS0xem0tMyAxMGgtMTB2LThoMTB6bS0xMS00aDJ2MmgtMnptMC00aDJ2MmgtMnptNCA0aDJ2MmgtMnptMC00aDJ2MmgtMnptNCA0aDJ2MmgtMnptMC00aDJ2MmgtMnoiLz48L3N2Zz4=',
userIcon: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZDQjMwMCI+PHBhdGggZD0iTTEyIDEyYzIuMjEgMCA0LTEuNzkgNC00cy0xLjc5LTQtNC00LTQgMSu3OS00IDQgMS.3OSA0IDQgNHptMCAyYy0yLjY3IDAtOCAyLjY5LTggNnYxaDE2di0xYzAtMi4zMS01LjMzLTUtOC01eiIvPjwvc3ZnPg==',
messageList: [] as IViewMessage[],
},
onLoad() {
this.fetchAndProcessMessages();
},
fetchAndProcessMessages() {
// 1. 模拟从您的后端API获取的、符合最新数据库结构的原始数据
const apiResponse: IApiMessage[] = [
{ id: 101, sender_id: "user_1001", receiver_id: "me", msg_type: "comment", status: 1, sequence: "seq_001", created_at: "2025-09-28 15:30:00", content: "这张照片的构图太棒了!", is_read: 0, target: "post:abc-123" },
{ id: 102, sender_id: "user_2035", receiver_id: "me", msg_type: "like", status: 1, sequence: "seq_002", created_at: "2025-09-28 09:15:00", content: "你的帖子「周末徒步之旅」", is_read: 0, target: "post:def-456" },
{ id: 103, sender_id: "user_3110", receiver_id: "me", msg_type: "follow", status: 1, sequence: "seq_003", created_at: "2025-09-27 20:05:00", content: "", is_read: 1, target: "user:user-3110" },
{ id: 104, sender_id: "system", receiver_id: "me", msg_type: "system", status: 1, sequence: "seq_004", created_at: "2025-09-26 10:00:00", content: "恭喜你获得了「创作新星」徽章,再接再厉!", is_read: 1, target: "/pages/my-badges/index" },
{ id: 105, sender_id: "user_1001", receiver_id: "me", msg_type: "like", status: 1, sequence: "seq_005", created_at: "2025-09-25 11:45:00", content: "你的帖子「美食探店分享」", is_read: 1, target: "post:ghi-789" },
];
const viewList = apiResponse.map(msg => this.transformMessage(msg));
this.setData({
messageList: viewList
});
},
transformMessage(msg: IApiMessage): IViewMessage {
let title = '';
let content = '';
const senderName = msg.sender_id;
// ⭐️ 现在根据 msg_type 判断
switch (msg.msg_type) {
case 'comment': title = '新的评论'; content = `${senderName}」评论了你:「${msg.content}`; break;
case 'like': title = '新的点赞'; content = `${senderName}」赞了${msg.content}`; break;
case 'follow': title = '新的关注'; content = `${senderName}」关注了你`; break;
case 'system': title = '系统通知'; content = msg.content; break;
}
return {
// ⭐️ 使用数据库的自增 id
id: msg.id,
// ⭐️ type 用于判断图标
type: msg.msg_type === 'system' ? 'system' : 'user',
title: title,
content: content,
timestamp: this.formatDisplayTime(msg.created_at),
// ⭐️ is_read 用于判断未读红点
is_read: msg.is_read,
// ⭐️ target 用于点击跳转
target: msg.target,
};
},
// ⭐️ 新增/恢复:卡片点击跳转的处理函数
handleNavigate(event: WechatMiniprogram.TouchEvent) {
const { target } = event.currentTarget.dataset;
if (!target) {
console.log("此消息没有可跳转的目标");
return;
}
let url = '';
// 解析 target, e.g., "post:abc-123"
const parts = target.split(':');
const type = parts[0];
const id = parts[1];
switch (type) {
case 'post':
url = `/pages/post-detail/index?id=${id}`;
break;
case 'user':
url = `/pages/user-profile/index?userId=${id}`;
break;
default:
// 如果 target 不包含 ':', 说明它可能是一个完整的内部页面路径
if (target.startsWith('/')) {
url = target;
} else {
console.warn("未知的 target 类型:", target);
return;
}
}
wx.navigateTo({
url: url,
fail: (err) => {
console.error("页面跳转失败", err);
wx.showToast({ title: '页面不存在', icon: 'none' });
}
});
},
formatDisplayTime(dateString: string): string {
const date = new Date(dateString.replace(/-/g, '/'));
const now = new Date();
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterdayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
const time = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
if (date.getTime() >= todayStart.getTime()) return `今天 ${time}`;
if (date.getTime() >= yesterdayStart.getTime()) return `昨天 ${time}`;
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
}
});