Files
danyang-match/miniapp/pages/notifications/notifications.js
T

116 lines
3.8 KiB
JavaScript

/**
* 通知中心页 U25
*/
const api = require('../../utils/api');
Page({
data: {
notifications: [],
unreadCount: 0,
loading: true,
page: 1,
hasMore: true
},
onLoad() {
this.loadNotifications();
},
getTypeText(type) {
return { matchmaker: '红娘服务', appointment: '预约提醒', counseling: '咨询服务', premarital: '婚前辅导', service_location: '服务站服务', match: '匹配提醒', activity: '活动提醒', account: '账号状态', review: '审核通知', local_eligibility: '资格认证', risk: '安全提醒', system: '系统通知' }[type] || '系统通知';
},
openNotification(item) {
const type = item && item.type;
const url = ['matchmaker', 'appointment', 'counseling', 'premarital', 'service_location'].includes(type)
? '/pages/service-history/service-history'
: ['match', 'activity'].includes(type) ? '/pages/fate-center/fate-center' : '/pages/settings/settings';
wx.navigateTo({ url });
},
onShow() {
this.loadUnreadCount();
},
async loadNotifications() {
this.setData({ loading: true });
try {
const token = wx.getStorageSync('accessToken');
const res = await api.get(
`/notifications?page=${this.data.page}&pageSize=20`,
{},
{ Authorization: `Bearer ${token}` }
);
if (res) {
const raw = Array.isArray(res) ? res : (res.notifications || res.items || res.records || []);
const isNewPage = this.data.page === 1;
this.setData({
notifications: isNewPage ? raw.map(this.normalizeNotification) : [...this.data.notifications, ...raw.map(this.normalizeNotification)],
unreadCount: res.unreadCount || res.count || 0,
hasMore: raw.length >= 20,
loading: false
});
}
} catch (err) {
this.setData({ loading: false });
}
},
normalizeNotification(item) {
return { ...item, notificationId: item.notificationId || item.id, read: item.read === true || item.readStatus === 'read' };
},
async loadUnreadCount() {
try {
const token = wx.getStorageSync('accessToken');
const res = await api.get('/notifications/unread', {}, { Authorization: `Bearer ${token}` });
this.setData({ unreadCount: res?.unreadCount ?? res?.count ?? 0 });
} catch (e) { /* ignore */ }
},
async onMarkRead(e) {
const notificationId = e.currentTarget.dataset.id;
try {
const token = wx.getStorageSync('accessToken');
await api.put(`/notifications/${notificationId}/read`, {}, { Authorization: `Bearer ${token}` });
this.setData({
notifications: this.data.notifications.map(n =>
n.notificationId === notificationId ? { ...n, read: true } : n
),
unreadCount: Math.max(0, this.data.unreadCount - 1)
});
} catch (err) { /* ignore */ }
this.openNotification(this.data.notifications.find((n) => n.notificationId === notificationId));
},
async onMarkAllRead() {
try {
const token = wx.getStorageSync('accessToken');
await api.put('/notifications/read-all', {}, { Authorization: `Bearer ${token}` });
this.setData({ unreadCount: 0 });
} catch (err) { /* ignore */ }
},
async onReachBottom() {
if (this.data.hasMore && !this.data.loading) {
this.setData({ page: this.data.page + 1 });
this.loadNotifications();
}
},
onPullDownRefresh() {
this.setData({ page: 1 });
this.loadNotifications().then(() => wx.stopPullDownRefresh());
},
formatTime(ts) {
if (!ts) return '';
const d = new Date(ts);
const now = new Date();
if (d.toDateString() === now.toDateString()) {
return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
}
return `${d.getMonth() + 1}/${d.getDate()} ${d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}`;
}
});