const { getLayout } = require('../../utils/layout'); // pages/timeline/timeline.js const { api, getImageUrl } = require('../../utils/request'); // 重复周期映射 var repeatUnitMap = { 'day': '天', 'week': '周', 'month': '月', 'year': '年' }; // 计算距离今天最近的重复日期(返回 Date 对象,已归零) function calcNearestRepeatDate(eventDate, today, interval, unit) { var base = new Date(eventDate); base.setHours(0,0,0,0); if (unit === 'day') { var diff = Math.floor((today - base) / 86400000); var cycles = Math.floor(diff / interval); var nearest = new Date(base.getTime() + cycles * interval * 86400000); nearest.setHours(0,0,0,0); if (nearest > today) { nearest = new Date(nearest.getTime() - interval * 86400000); nearest.setHours(0,0,0,0); } return nearest; } else if (unit === 'week') { var diff = Math.floor((today - base) / 86400000); var cycles = Math.floor(diff / (7 * interval)); var nearest = new Date(base.getTime() + cycles * 7 * interval * 86400000); nearest.setHours(0,0,0,0); if (nearest > today) { nearest = new Date(nearest.getTime() - 7 * interval * 86400000); nearest.setHours(0,0,0,0); } return nearest; } else if (unit === 'month') { var nearest = new Date(base); nearest.setHours(0,0,0,0); while (true) { var next = new Date(nearest); next.setMonth(next.getMonth() + interval); next.setHours(0,0,0,0); if (next > today) break; nearest = next; } return nearest; } else if (unit === 'year') { var nearest = new Date(base); nearest.setHours(0,0,0,0); while (true) { var next = new Date(nearest); next.setFullYear(next.getFullYear() + interval); next.setHours(0,0,0,0); if (next > today) break; nearest = next; } return nearest; } return new Date(eventDate); } Page({ onResize: function() { this.setData(getLayout()); }, data: { loading: true, loadError: false, list: [] }, onLoad: function() { this.setData(getLayout()); this.loadData(); }, onShow: function() { this.loadData(); }, onPullDownRefresh: async function() { await this.loadData(); wx.stopPullDownRefresh(); }, onShareAppMessage: function() { return { title: '让所有的爱有迹可循', path: '/pages/timeline/timeline', imageUrl: '/images/share.png' }; }, onShareTimeline: function() { return { title: '让所有的爱有迹可循', imageUrl: '/images/share.png' }; }, loadData: async function() { if (this._pageLoading) return; this._pageLoading = true; this.setData({loading:true, loadError:false}); try { const list = await api.timelineList(); const myUid = wx.getStorageSync('userId'); var nameMap = {}; var avatarMap = {}; try { const info = await api.coupleInfo(); var p1 = info.partner1 || {}; var p2 = info.partner2 || {}; if (p1.id) { nameMap[p1.id] = p1.nickname || p1.username || 'TA'; avatarMap[p1.id] = getImageUrl(p1.avatar); } if (p2.id) { nameMap[p2.id] = p2.nickname || p2.username || 'TA'; avatarMap[p2.id] = getImageUrl(p2.avatar); } } catch (e) {} var today = new Date(); today.setHours(0,0,0,0); var items = (list || []).map(function(item, idx) { var cid = parseInt(item.created_by) || 0; item.creator_name = nameMap[cid] || (cid == myUid ? '我' : 'TA'); item.creator_avatar = avatarMap[cid] || ''; item.creator_initial = (item.creator_name || '?')[0].toUpperCase(); item.side = idx % 2 === 0 ? 'left' : 'right'; item.bg_image_url = item.bg_image ? getImageUrl(item.bg_image) : ''; // 计算纪念日/倒数日(支持重复事件) if (item.event_date) { var ed = new Date(item.event_date.replace(/-/g, '/')); ed.setHours(0,0,0,0); var repeatInterval = parseInt(item.repeat_interval) || 0; var repeatUnit = item.repeat_unit || ''; // 计算实际用来对比的基准日期 if (repeatInterval > 0 && repeatUnit) { // 重复事件:以今天的日期为基准,计算最近一次重复的日期 var baseDate = calcNearestRepeatDate(ed, today, repeatInterval, repeatUnit); var diff = Math.floor((today - baseDate) / 86400000); if (diff >= 0) { item.is_anniversary = true; item.days_text = '已过去 ' + diff + ' 天'; item.date_tag = '纪念日'; item.repeat_label = repeatUnitMap[repeatUnit] + '重复'; } else { item.is_anniversary = false; item.days_text = '还有 ' + Math.abs(diff) + ' 天'; item.date_tag = '倒数日'; item.repeat_label = repeatUnitMap[repeatUnit] + '重复'; } } else { // 非重复事件:直接用事件日期计算 var diff = Math.floor((today - ed) / 86400000); if (diff >= 0) { item.is_anniversary = true; item.days_text = '已过去 ' + diff + ' 天'; item.date_tag = '纪念日'; } else { item.is_anniversary = false; item.days_text = '还有 ' + Math.abs(diff) + ' 天'; item.date_tag = '倒数日'; } } } else { item.is_anniversary = true; item.days_text = ''; } return item; }); this.setData({ list: items }); } catch (e) { this.setData({loadError:true}); console.error(e); wx.showToast({ title: (e && (e.error || e.errMsg || e.message)) || '加载失败', icon: 'none' }); } finally { this._pageLoading = false; this.setData({loading:false}); } }, deleteTimeline: async function(e) { var id = e.currentTarget.dataset.id; wx.showModal({ title: '确认删除', content: '确定要删除这条记录吗?', success: async function(res) { if (res.confirm) { try { await api.timelineDelete({ id: id }); wx.showToast({ title: '已删除', icon: 'success' }); // need to re-get this context var pages = getCurrentPages(); var page = pages[pages.length - 1]; page.loadData(); } catch (err) { wx.showToast({ title: err.error || '删除失败', icon: 'none' }); } } } }); }, goToPublish: function() { wx.navigateTo({ url: '/pages/publish/publish?type=timeline' }); }, goToDetail: function(e) { var id = e.currentTarget.dataset.id; if (id) { wx.navigateTo({ url: '/pages/timeline-detail/timeline-detail?id=' + id }); } }, goHome: function() { wx.redirectTo({ url: '/pages/index/index' }); }, goBack: function() { wx.navigateBack(); }, goProfile: function() { wx.redirectTo({ url: '/pages/profile/profile' }); } });