Gate record features and storage entry points with invitation guidance; enforce record access in the backend. Add homepage greetings, right-swipe profile dismissal, and move the smoking switch to settings. Simplify API base configuration and remove the unused legacy tab bar component.
212 lines
7.1 KiB
JavaScript
212 lines
7.1 KiB
JavaScript
const { withRecordAccess } = require('../../utils/record-access');
|
|
const { tryLoginRenewal } = require('../../utils/subscribe');
|
|
const { withDataCache } = require('../../utils/page-cache');
|
|
const { getLayout } = require('../../utils/layout');
|
|
// pages/timeline-detail/timeline-detail.js
|
|
const { api, getImageUrl } = require('../../utils/request');
|
|
const { createSwipeBack } = require('../../utils/util');
|
|
|
|
// 重复周期映射
|
|
var repeatUnitMap = { 'day': '天', 'week': '周', 'month': '月', 'year': '年' };
|
|
var weekdayNames = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
|
|
|
// 计算距离今天最近的重复日期
|
|
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(withRecordAccess(withDataCache({
|
|
onLoginSubscribeTap: function() { return tryLoginRenewal(); },
|
|
onResize: function() { this.setData(getLayout()); },
|
|
data: { loading: true, loadError: false,
|
|
item: null,
|
|
detailId: 0,
|
|
bgImageUrl: '',
|
|
daysNumber: '',
|
|
daysSign: '',
|
|
weekdayText: '',
|
|
isAnniversary: true
|
|
},
|
|
|
|
onLoad: function(options) {
|
|
this.setData(getLayout());
|
|
var id = options.id;
|
|
if (id) {
|
|
this.setData({ detailId: String(id) });
|
|
this.loadDetail(String(id));
|
|
}
|
|
var self = this;
|
|
var swipe = createSwipeBack(function() { wx.navigateBack(); });
|
|
this.onTouchStart = swipe.onTouchStart;
|
|
this.onTouchEnd = swipe.onTouchEnd;
|
|
},
|
|
|
|
retryDetail: function() { this.loadDetail(this.data.detailId); },
|
|
onShow: function() {
|
|
this._syncNavigationColor();
|
|
if (this.data.detailId) {
|
|
this.loadDetail(this.data.detailId);
|
|
}
|
|
},
|
|
|
|
onHide: function() {
|
|
if (wx.setNavigationBarColor) wx.setNavigationBarColor({frontColor:'#000000',backgroundColor:'#FDE4EC'});
|
|
},
|
|
_syncNavigationColor: function() {
|
|
if (wx.setNavigationBarColor) wx.setNavigationBarColor({frontColor:this.data.bgImageUrl?'#ffffff':'#000000',backgroundColor:this.data.bgImageUrl?'#000000':'#FDE4EC'});
|
|
},
|
|
goBack: function() {
|
|
wx.navigateBack({fail:function(){wx.switchTab({url:'/pages/discover/discover'});}});
|
|
},
|
|
|
|
loadDetail: async function(id) {
|
|
if (this._pageLoading) return;
|
|
this._pageLoading = true;
|
|
this.setData({loading: !this._hasCachedData, loadError:false});
|
|
try {
|
|
var item = await api.timelineDetail(id);
|
|
var myUid = wx.getStorageSync('userId');
|
|
var cid = String(item.created_by) || 0;
|
|
|
|
// 获取情侣信息
|
|
try {
|
|
var info = await api.coupleInfo();
|
|
var p1 = info.partner1 || {};
|
|
var p2 = info.partner2 || {};
|
|
var nameMap = {};
|
|
var avatarMap = {};
|
|
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); }
|
|
item.creator_name = nameMap[cid] || (cid == myUid ? '我' : 'TA');
|
|
item.creator_avatar = avatarMap[cid] || '';
|
|
} catch(e) {
|
|
item.creator_name = cid == myUid ? '我' : 'TA';
|
|
item.creator_avatar = '';
|
|
}
|
|
item.creator_initial = (item.creator_name || '?')[0].toUpperCase();
|
|
|
|
// 计算天数
|
|
var today = new Date(); today.setHours(0,0,0,0);
|
|
var daysNumber = '';
|
|
var daysSign = '';
|
|
var isAnniversary = true;
|
|
|
|
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 || '';
|
|
|
|
var diff;
|
|
if (repeatInterval > 0 && repeatUnit) {
|
|
var baseDate = calcNearestRepeatDate(ed, today, repeatInterval, repeatUnit);
|
|
diff = Math.floor((today - baseDate) / 86400000);
|
|
isAnniversary = diff >= 0;
|
|
daysSign = isAnniversary ? '+' : '-';
|
|
daysNumber = Math.abs(diff);
|
|
item.repeat_label = repeatUnitMap[repeatUnit] + '重复';
|
|
} else {
|
|
diff = Math.floor((today - ed) / 86400000);
|
|
isAnniversary = diff >= 0;
|
|
daysSign = isAnniversary ? '+' : '-';
|
|
daysNumber = Math.abs(diff);
|
|
}
|
|
}
|
|
|
|
// 星期
|
|
var eventDateObj = new Date(item.event_date.replace(/-/g, '/'));
|
|
var weekdayText = weekdayNames[eventDateObj.getDay()] || '';
|
|
|
|
item.is_anniversary = isAnniversary;
|
|
this.setData({
|
|
item: item,
|
|
daysNumber: daysNumber,
|
|
daysSign: daysSign,
|
|
weekdayText: weekdayText,
|
|
isAnniversary: isAnniversary
|
|
});
|
|
|
|
// 从API数据加载背景图
|
|
this.loadBgImage();
|
|
|
|
} 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}); }
|
|
},
|
|
|
|
// ===== 背景图片 =====
|
|
loadBgImage: function() {
|
|
var item = this.data.item;
|
|
if (item && item.bg_image) {
|
|
var fullUrl = getImageUrl(item.bg_image);
|
|
this.setData({ bgImageUrl: fullUrl });
|
|
} else {
|
|
this.setData({ bgImageUrl: '' });
|
|
}
|
|
this._syncNavigationColor();
|
|
},
|
|
|
|
// ===== 编辑 =====
|
|
goEdit: function() {
|
|
var item = this.data.item;
|
|
if (item && item.id) {
|
|
wx.navigateTo({
|
|
url: '/pages/publish/publish?type=timeline&edit=' + item.id
|
|
});
|
|
}
|
|
},
|
|
|
|
// ===== 导航 =====
|
|
goBack: function() { wx.navigateBack(); },
|
|
goHome: function() { wx.switchTab({ url: '/pages/index/index' }); },
|
|
goProfile: function() { wx.switchTab({ url: '/pages/profile/profile' }); }
|
|
}, {"loadDetail": ["timelineDetail", "coupleInfo"]})));
|