Replace virtual payments with WeChat Pay API v3 and verify callbacks and order polling. Cache WeChat access tokens in Redis and write structured Zap logs. Support configurable capacity plans across the API, admin and mini program, with purchase snapshots and quota enforcement. Allow personal albums before binding and share them with the current partner. Update deployment configuration and domain routing.
1107 lines
41 KiB
JavaScript
1107 lines
41 KiB
JavaScript
const { uploadReference } = require('../../utils/file-media');
|
|
const { itemsOf, totalOf } = require('../../utils/list-pagination');
|
|
const { withDataCache } = require('../../utils/page-cache');
|
|
const { getLayout } = require('../../utils/layout');
|
|
// pages/profile/profile.js - 与原网站一致的个人中心
|
|
const { api, getImageUrl } = require('../../utils/request');
|
|
const { saveScrollPosition, resetScrollOnTabShow } = require('../../utils/scroll-pos');
|
|
const { requestSubscribe } = require('../../utils/subscribe');
|
|
const { guardStorageSpace } = require('../../utils/storage-guard');
|
|
|
|
function formatStorageBytes(bytes) {
|
|
bytes = bytes || 0;
|
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
if (bytes < 1024 * 1024 * 1024) return (bytes / 1024 / 1024).toFixed(1) + ' MB';
|
|
return (bytes / 1024 / 1024 / 1024).toFixed(2) + ' GB';
|
|
}
|
|
|
|
Page(withDataCache({
|
|
onResize: function() { this.setData(getLayout()); },
|
|
data: {
|
|
scrollTop: 0,
|
|
statsLoading:false, statsError:false,
|
|
storageText:'—', storagePercent:0, storageOverQuota:false, storageVip:false, storageExpireText:'',
|
|
statisticItems:[
|
|
{key:'timeline',label:'记忆日',icon:'stat-timeline',count:'—',color:'pink'},
|
|
{key:'album',label:'相册',icon:'stat-album',count:'—',color:'yellow'},
|
|
{key:'diary',label:'日记',icon:'stat-book',count:'—',color:'mint'},
|
|
{key:'songs',label:'歌曲',icon:'stat-music',count:'—',color:'blue'},
|
|
{key:'checkin',label:'打卡',icon:'stat-check',count:'—',color:'purple'},
|
|
{key:'pet',label:'宠物',icon:'stat-pet',count:'—',color:'pink'},
|
|
{key:'period',label:'姨姨',icon:'stat-j-flower',count:'',color:'pink'},
|
|
{key:'settings',label:'更多',icon:'stat-settings',count:'',color:'gray'}
|
|
],
|
|
|
|
// 我的信息
|
|
myNickname: '未登录',
|
|
myDisplayId: '',
|
|
myPhone: '-',
|
|
myGender: '-',
|
|
myAge: '-',
|
|
myBirthday: '-',
|
|
myRegion: '',
|
|
myLocation: '',
|
|
myStatus: '设置恋爱信息',
|
|
myAvatarUrl: '',
|
|
myInitial: '?',
|
|
|
|
// TA的信息
|
|
hasPartner: false,
|
|
bindingKnown: false, bindingError: false,
|
|
partnerName: 'TA',
|
|
partnerDisplayId: '',
|
|
partnerId: 0,
|
|
partnerDetail: '',
|
|
partnerAvatarUrl: '',
|
|
partnerInitial: '?',
|
|
partnerBirthday: '',
|
|
partnerGenderRaw: '',
|
|
|
|
// 恋爱信息
|
|
anniversaryDateText: '点击设置你们的纪念日',
|
|
loveStoryText: '记录你们的故事',
|
|
loveStartDate: '',
|
|
|
|
// 编辑资料弹窗
|
|
showEditProfileModal: false,
|
|
editNickname: '',
|
|
editGender: 'male',
|
|
editGenderText: '男',
|
|
editAge: '',
|
|
editBirthday: '',
|
|
editRegion: '',
|
|
editAvatarUrl: '',
|
|
editAvatarPath: '',
|
|
editNicknameInitial: '?',
|
|
|
|
// 设置恋爱日期弹窗
|
|
showSetDateModal: false,
|
|
tempLoveDate: '',
|
|
tempLoveStory: '',
|
|
|
|
// 编辑TA资料弹窗
|
|
showEditPartnerModal: false,
|
|
partnerSaving: false, partnerAvatarUploading: false,
|
|
editPartnerNickname: '',
|
|
editPartnerGender: 'male',
|
|
editPartnerGenderText: '男',
|
|
editPartnerAge: '',
|
|
editPartnerBirthday: '',
|
|
editPartnerAvatarUrl: '',
|
|
editPartnerAvatarPath: '',
|
|
editPartnerNameInitial: '?',
|
|
genderOptions: ['男', '女'],
|
|
|
|
// 解除绑定验证
|
|
showUnbindVerifyModal: false,
|
|
unbindQuestion: '',
|
|
unbindAnswer: 0,
|
|
unbindUserInput: '',
|
|
|
|
// 解绑状态
|
|
unbindStatus: '',
|
|
unbindIsRequester: false,
|
|
unbindRequesterName: '',
|
|
unbindRemaining: 0,
|
|
|
|
// TA详情弹窗
|
|
showPartnerDetailModal: false,
|
|
partnerDetailNickname: '-',
|
|
partnerDetailGender: '-',
|
|
partnerDetailAge: '-',
|
|
partnerDetailBirthday: '-',
|
|
partnerDetailAvatarUrl: '',
|
|
partnerNameInitial: '?',
|
|
|
|
// ===== 邀请绑定相关 =====
|
|
showInvitePanel: false,
|
|
inviteTab: 'received',
|
|
receivedInvites: [],
|
|
sentInvites: [],
|
|
inviteTargetId: '',
|
|
inviteMessage: '',
|
|
// 分享绑定
|
|
showShareBindModal: false,
|
|
shareInviterId: '',
|
|
shareInviterName: '',
|
|
shareDisagree: false
|
|
},
|
|
|
|
// 左滑返回机制
|
|
touchStartX: 0, touchStartY: 0,
|
|
onTouchStart: function(e) {
|
|
this.touchStartX = e.touches[0].clientX;
|
|
this.touchStartY = e.touches[0].clientY;
|
|
},
|
|
onTouchEnd: function(e) {
|
|
var dx = this.touchStartX - e.changedTouches[0].clientX;
|
|
var dy = Math.abs(this.touchStartY - e.changedTouches[0].clientY);
|
|
// 短距离/垂直滑动不处理(交给按钮tap事件)
|
|
if (dx < 20 && dy < 20) return;
|
|
// 只有水平且左滑超过80px才处理
|
|
if (Math.abs(dx) > dy && dx > 80) {
|
|
if (this.data.showEditProfileModal) {
|
|
this.hideEditProfileModal();
|
|
} else if (this.data.showEditPartnerModal) {
|
|
this.hideEditPartnerModal();
|
|
} else {
|
|
wx.navigateBack();
|
|
}
|
|
}
|
|
},
|
|
|
|
_needRefresh: true,
|
|
|
|
onScroll: function(e) {
|
|
this._scrollTop = e.detail.scrollTop;
|
|
saveScrollPosition('profile', e.detail.scrollTop);
|
|
},
|
|
|
|
onLoad: function(options) {
|
|
this.setData(getLayout());
|
|
this._needRefresh = true;
|
|
this._openBindOnLoad = !!(options && options.bind);
|
|
this.setData({
|
|
userId: wx.getStorageSync('userId'),
|
|
coupleId: wx.getStorageSync('coupleId'),
|
|
scrollTop: 0
|
|
});
|
|
this.loadData();
|
|
this.loadUnbindStatus();
|
|
this.fetchAndSaveLocation();
|
|
// 从首页点击头像跳转过来,自动打开编辑
|
|
if (options.edit === 'self') {
|
|
var self = this;
|
|
setTimeout(function() { self.showEditProfileModal(); }, 500);
|
|
} else if (options.edit === 'partner') {
|
|
var self = this;
|
|
setTimeout(function() { self.showEditPartnerModal(); }, 500);
|
|
}
|
|
// 从分享邀请链接进入
|
|
if (options && options.inviter) {
|
|
var self = this;
|
|
setTimeout(function() { self.handleShareInvite(options.inviter, options.invite_code); }, 800);
|
|
}
|
|
},
|
|
|
|
|
|
onShow: function() {
|
|
resetScrollOnTabShow(this, 'profile');
|
|
if (!wx.getStorageSync('coupleId') && !this.data.shareOutgoingCode) api.generateInviteLink().then(res => this.setData({shareOutgoingCode:res.code || ''})).catch(() => {});
|
|
const tabBar = this.getTabBar && this.getTabBar();
|
|
if (tabBar) tabBar.syncActive();
|
|
var uid = wx.getStorageSync('userId');
|
|
var cid = wx.getStorageSync('coupleId');
|
|
this.setData({ userId: uid, coupleId: cid });
|
|
const app = getApp();
|
|
if (app.globalData.openProfileBind) {
|
|
app.globalData.openProfileBind = false;
|
|
this._openBindOnLoad = true;
|
|
this._dataLoads = {};
|
|
}
|
|
this.loadData();
|
|
this.loadProfileStats();
|
|
this.loadStorageInfo();
|
|
if (!cid && this.data.showInvitePanel && !this._pollTimer) this.startPollCoupleStatus();
|
|
// 如果已绑定情侣,关闭邀请面板
|
|
if (cid && this.data.showInvitePanel) {
|
|
this.setData({ showInvitePanel: false });
|
|
if (this._pollTimer) {
|
|
clearInterval(this._pollTimer);
|
|
this._pollTimer = null;
|
|
}
|
|
}
|
|
},
|
|
|
|
onHide: function() {
|
|
if (this._pollTimer) { clearInterval(this._pollTimer); this._pollTimer = null; }
|
|
},
|
|
|
|
onUnload: function() {
|
|
if (this._pollTimer) {
|
|
clearInterval(this._pollTimer);
|
|
this._pollTimer = null;
|
|
}
|
|
},
|
|
|
|
onPullDownRefresh: async function() {
|
|
await Promise.all([this.loadData(),this.loadProfileStats(),this.loadStorageInfo()]);
|
|
wx.stopPullDownRefresh();
|
|
},
|
|
|
|
// 比较新旧值,只返回变化的字段(避免全量 setData 导致闪屏)
|
|
_diffUpdate: function(newData) {
|
|
var updates = {};
|
|
for (var key in newData) {
|
|
if (this.data[key] !== newData[key]) {
|
|
updates[key] = newData[key];
|
|
}
|
|
}
|
|
if (Object.keys(updates).length > 0) {
|
|
this.setData(updates);
|
|
}
|
|
},
|
|
|
|
loadData: async function() {
|
|
this.setData({bindingError:false});
|
|
var requestId = (this._coupleInfoRequestId || 0) + 1;
|
|
this._coupleInfoRequestId = requestId;
|
|
try {
|
|
// 获取情侣信息
|
|
const info = await api.coupleInfo();
|
|
this.setData({userId: wx.getStorageSync('userId')});
|
|
if (requestId !== this._coupleInfoRequestId) return;
|
|
// 未绑定情侣时从后端获取用户最新资料
|
|
if (info.not_bound) {
|
|
wx.removeStorageSync('coupleId');
|
|
var myInfo = info.partner1 || {};
|
|
var genderText = myInfo.gender === 'male' ? '男' : (myInfo.gender === 'female' ? '女' : '-');
|
|
var region = myInfo.region || '';
|
|
var location = myInfo.location || '';
|
|
if (/^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/.test(location)) location = '';
|
|
wx.setStorageSync('region', region);
|
|
this._diffUpdate({
|
|
bindingKnown: true,
|
|
coupleId: null,
|
|
hasPartner: false,
|
|
partnerName: 'TA',
|
|
partnerDisplayId: '',
|
|
partnerId: 0,
|
|
partnerDetail: '',
|
|
partnerAvatarUrl: '',
|
|
partnerInitial: '?',
|
|
partnerBirthday: '',
|
|
partnerGenderRaw: '',
|
|
myStatus: '设置恋爱信息',
|
|
anniversaryDateText: '点击设置你们的纪念日',
|
|
loveStoryText: '记录你们的故事',
|
|
loveStartDate: '',
|
|
tempLoveDate: '',
|
|
tempLoveStory: '',
|
|
myNickname: myInfo.nickname || myInfo.username || '未登录',
|
|
myDisplayId: myInfo.user_id || wx.getStorageSync('displayId') || '',
|
|
myPhone: myInfo.phone || myInfo.username || '-',
|
|
myGender: genderText,
|
|
myGenderRaw: myInfo.gender || '',
|
|
myAge: myInfo.age > 0 ? myInfo.age + '岁' : '-',
|
|
myAgeText: myInfo.age > 0 ? myInfo.age : '',
|
|
myBirthday: myInfo.birthday || '-',
|
|
myBirthdayText: myInfo.birthday || '',
|
|
myRegion: region,
|
|
myLocation: location,
|
|
myAvatarUrl: getImageUrl(myInfo.avatar),
|
|
myInitial: (myInfo.nickname || myInfo.username || '?')[0],
|
|
editNickname: myInfo.nickname || '',
|
|
editAge: myInfo.age > 0 ? myInfo.age : '',
|
|
editBirthday: myInfo.birthday || '',
|
|
editRegion: region,
|
|
editNicknameInitial: (myInfo.nickname || myInfo.username || '?')[0]
|
|
});
|
|
if (this._openBindOnLoad) {
|
|
this._openBindOnLoad = false;
|
|
this.showInvitePanel();
|
|
}
|
|
return;
|
|
}
|
|
// 同步情侣ID到本地存储
|
|
if (info.id) {
|
|
wx.setStorageSync('coupleId', info.id);
|
|
if (this.data.coupleId !== info.id) {
|
|
this.setData({ coupleId: info.id });
|
|
}
|
|
}
|
|
const myUid = this.data.userId;
|
|
const p1 = info.partner1 || {};
|
|
const p2 = info.partner2 || {};
|
|
|
|
const me = p1.id == myUid ? p1 : (p2.id == myUid ? p2 : null);
|
|
const partner = p1.id == myUid ? p2 : (p2.id == myUid ? p1 : null);
|
|
|
|
// 我的信息 — 只更新变化的字段
|
|
if (me) {
|
|
const genderText = me.gender === 'male' ? '男' : (me.gender === 'female' ? '女' : '-');
|
|
const storedDisplayId = wx.getStorageSync('displayId') || '';
|
|
var region = me.region || '';
|
|
var location = me.location || '';
|
|
if (/^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/.test(location)) location = '';
|
|
wx.setStorageSync('region', region);
|
|
this._diffUpdate({
|
|
myNickname: me.nickname || me.username || '未登录',
|
|
myDisplayId: me.user_id || storedDisplayId,
|
|
myPhone: me.phone || me.username || '-',
|
|
myGender: genderText,
|
|
myGenderRaw: me.gender || '',
|
|
myAge: me.age > 0 ? me.age + '岁' : '-',
|
|
myAgeText: me.age > 0 ? me.age : '',
|
|
myBirthday: me.birthday || '-',
|
|
myBirthdayText: me.birthday || '',
|
|
myRegion: region,
|
|
myLocation: location,
|
|
myAvatarUrl: getImageUrl(me.avatar),
|
|
myInitial: (me.nickname || me.username || '?')[0],
|
|
editNickname: me.nickname || '',
|
|
editAge: me.age > 0 ? me.age : '',
|
|
editBirthday: me.birthday || '',
|
|
editRegion: region,
|
|
editNicknameInitial: (me.nickname || me.username || '?')[0]
|
|
});
|
|
}
|
|
|
|
// TA的信息 — 只更新变化的字段
|
|
if (partner) {
|
|
const genderText = partner.gender === 'male' ? '男' : (partner.gender === 'female' ? '女' : '-');
|
|
let details = [];
|
|
if (genderText !== '-') details.push(genderText);
|
|
if (partner.age > 0) details.push(partner.age + '岁');
|
|
if (partner.birthday) details.push('🎂 ' + partner.birthday);
|
|
|
|
this._diffUpdate({
|
|
bindingKnown: true,
|
|
hasPartner: true,
|
|
partnerName: partner.nickname || partner.username || 'TA',
|
|
partnerDisplayId: partner.user_id || '',
|
|
partnerId: String(partner.id),
|
|
partnerDetail: details.join(' · ') || 'TA的信息',
|
|
partnerAvatarUrl: getImageUrl(partner.avatar),
|
|
partnerInitial: (partner.nickname || partner.username || '?')[0],
|
|
partnerBirthday: partner.birthday || '',
|
|
partnerGenderRaw: partner.gender || '',
|
|
partnerDetailNickname: partner.nickname || partner.username || '-',
|
|
partnerDetailGender: genderText,
|
|
partnerDetailAge: partner.age > 0 ? partner.age + '岁' : '-',
|
|
partnerDetailBirthday: partner.birthday || '-',
|
|
partnerDetailAvatarUrl: getImageUrl(partner.avatar),
|
|
partnerNameInitial: (partner.nickname || partner.username || '?')[0]
|
|
});
|
|
}
|
|
|
|
// 恋爱天数和状态 — 只更新变化的字段
|
|
let daysCount = 0;
|
|
if (info.love_start_date) {
|
|
const start = new Date(info.love_start_date);
|
|
daysCount = Math.floor((Date.now() - start) / 86400000);
|
|
const partnerName = partner ? (partner.nickname || partner.username || 'TA') : 'TA';
|
|
this._diffUpdate({
|
|
anniversaryDateText: info.love_start_date + ' (已设置)',
|
|
loveStoryText: info.love_story ? (info.love_story.length > 20 ? info.love_story.substring(0, 20) + '...' : info.love_story) : '记录你们的故事',
|
|
myStatus: '和' + partnerName + '在一起 ' + daysCount + ' 天 💕',
|
|
loveStartDate: info.love_start_date,
|
|
tempLoveDate: info.love_start_date || '',
|
|
tempLoveStory: info.love_story || ''
|
|
});
|
|
} else {
|
|
this._diffUpdate({
|
|
anniversaryDateText: '点击设置你们的纪念日',
|
|
loveStoryText: info.love_story ? (info.love_story.length > 20 ? info.love_story.substring(0, 20) + '...' : info.love_story) : '记录你们的故事',
|
|
myStatus: '设置恋爱信息',
|
|
loveStartDate: '',
|
|
tempLoveDate: '',
|
|
tempLoveStory: ''
|
|
});
|
|
}
|
|
} catch (e) {
|
|
if (requestId !== this._coupleInfoRequestId) return;
|
|
console.error(e);
|
|
this.setData({ bindingKnown: false, bindingError:true });
|
|
}
|
|
},
|
|
|
|
// 获取定位并保存到数据库(使用模糊定位,getLocation 与 getFuzzyLocation 互斥,统一用模糊定位)
|
|
fetchAndSaveLocation: function() {
|
|
var self = this;
|
|
self._fuzzyLocation();
|
|
},
|
|
|
|
// 模糊定位兜底
|
|
_fuzzyLocation: function() {
|
|
var self = this;
|
|
if (!wx.getFuzzyLocation) return;
|
|
wx.getFuzzyLocation({
|
|
type: 'gcj02',
|
|
success: function(res) {
|
|
self._reportLocation(res.latitude, res.longitude);
|
|
},
|
|
fail: function() {}
|
|
});
|
|
},
|
|
|
|
// 上报经纬度到后端并更新城市地址显示
|
|
_reportLocation: function(lat, lng) {
|
|
var self = this;
|
|
if (!lat || !lng) return;
|
|
// 保留更多小数位,减少坐标截断误差
|
|
var location = lat.toFixed(6) + ',' + lng.toFixed(6);
|
|
api.updateLocation(location).then(function(resp) {
|
|
// 后端返回的地址;若为空或经纬度(说明逆地理编码失败),一律不采用,绝不显示经纬度
|
|
var city = (resp && resp.location) ? resp.location : '';
|
|
if (city === '' || /^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/.test(city)) {
|
|
return;
|
|
}
|
|
// 转换成功后展示接口返回的城市地址
|
|
if (self.data.myLocation !== city) {
|
|
self.setData({ myLocation: city });
|
|
}
|
|
}).catch(function() {});
|
|
},
|
|
|
|
_syncProfileTabBar: function() {
|
|
const tabBar = this.getTabBar && this.getTabBar();
|
|
if (tabBar && tabBar.setHidden) tabBar.setHidden(this.data.showEditProfileModal || this.data.showEditPartnerModal);
|
|
},
|
|
|
|
// 编辑资料
|
|
showEditProfileModal: function() {
|
|
var d = this.data;
|
|
var rawGender = d.myGenderRaw || '';
|
|
var genderText = rawGender === 'female' ? '女' : '男';
|
|
this.setData({
|
|
showEditProfileModal: true,
|
|
editNickname: d.myNickname === '未设置' ? '' : d.myNickname,
|
|
editGender: rawGender || 'male',
|
|
editGenderText: genderText,
|
|
editAge: d.myAgeText ? String(parseInt(d.myAgeText) || '') : '',
|
|
editBirthday: d.myBirthdayText || '',
|
|
editRegion: d.myRegion || '',
|
|
editAvatarUrl: d.myAvatarUrl || '',
|
|
editNicknameInitial: d.myInitial || '?'
|
|
});
|
|
this._syncProfileTabBar();
|
|
},
|
|
onEditGenderChange: function(e) {
|
|
var idx = e.detail.value;
|
|
var texts = ['男', '女'];
|
|
var vals = ['male', 'female'];
|
|
this.setData({ editGender: vals[idx], editGenderText: texts[idx] });
|
|
},
|
|
hideEditProfileModal: function() {
|
|
this.setData({ showEditProfileModal: false });
|
|
this._syncProfileTabBar();
|
|
},
|
|
onEditNicknameInput: function(e) {
|
|
this.setData({ editNickname: e.detail.value });
|
|
},
|
|
onEditBirthdayInput: function(e) {
|
|
var birthday = e.detail.value;
|
|
var age = '';
|
|
if (birthday) {
|
|
var birthDate = new Date(birthday);
|
|
var today = new Date();
|
|
var calcAge = today.getFullYear() - birthDate.getFullYear();
|
|
var m = today.getMonth() - birthDate.getMonth();
|
|
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
|
|
calcAge--;
|
|
}
|
|
age = calcAge > 0 ? calcAge : 1;
|
|
}
|
|
this.setData({ editBirthday: birthday, editAge: String(age) });
|
|
},
|
|
|
|
chooseAvatar: function() {
|
|
const self = this;
|
|
guardStorageSpace(0).then(function(ok) {
|
|
if (!ok) return;
|
|
wx.chooseImage({
|
|
count: 1,
|
|
sizeType: ['compressed'],
|
|
sourceType: ['album', 'camera'],
|
|
success: async (res) => {
|
|
const filePath = res.tempFiles[0].path;
|
|
self.setData({ editAvatarUrl: filePath });
|
|
// 上传头像
|
|
try {
|
|
const data = await api.uploadAvatar(filePath);
|
|
self.setData({
|
|
editAvatarUrl: getImageUrl(data.path),
|
|
editAvatarPath: uploadReference(data)
|
|
});
|
|
wx.showToast({ title: '头像上传成功 ✨', icon: 'success' });
|
|
} catch (e) {
|
|
wx.showToast({ title: e.error || '上传失败', icon: 'none' });
|
|
}
|
|
}
|
|
});
|
|
});
|
|
},
|
|
|
|
saveProfile: async function() {
|
|
const { editNickname, editGender, editAge, editBirthday, editRegion, editAvatarPath, tempLoveDate, tempLoveStory, coupleId } = this.data;
|
|
if (!editNickname) {
|
|
wx.showToast({ title: '请输入昵称', icon: 'none' }); return;
|
|
}
|
|
try {
|
|
await api.updateProfile({
|
|
nickname: editNickname,
|
|
gender: editGender,
|
|
age: parseInt(editAge) || 0,
|
|
birthday: editBirthday,
|
|
region: editRegion,
|
|
avatar: editAvatarPath
|
|
});
|
|
// 更新本地存储的昵称,确保未绑定情侣时也能正确显示
|
|
wx.setStorageSync('nickname', editNickname);
|
|
if (editAvatarPath) {
|
|
wx.setStorageSync('avatar', editAvatarPath);
|
|
}
|
|
// 如果有恋爱日期且已绑定情侣,也保存
|
|
if (tempLoveDate && coupleId) {
|
|
await api.updateCoupleInfo({ love_start_date: tempLoveDate, love_story: tempLoveStory || '' });
|
|
}
|
|
wx.showToast({ title: '资料更新成功 💕', icon: 'success' });
|
|
this.hideEditProfileModal();
|
|
this.loadData();
|
|
} catch (e) {
|
|
wx.showToast({ title: e.error || '保存失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
// 设置恋爱日期
|
|
showSetDateModal: function() {
|
|
this.setData({ showSetDateModal: true });
|
|
},
|
|
hideSetDateModal: function() {
|
|
this.setData({ showSetDateModal: false });
|
|
},
|
|
onLoveDateInput: function(e) {
|
|
this.setData({ tempLoveDate: e.detail.value });
|
|
},
|
|
onLoveStoryInput: function(e) {
|
|
this.setData({ tempLoveStory: e.detail.value });
|
|
},
|
|
|
|
// 显示恋爱故事
|
|
showCoupleStory: function() {
|
|
const { tempLoveStory } = this.data;
|
|
if (!tempLoveStory) {
|
|
wx.showToast({ title: '还没有恋爱故事,先设置纪念日吧 ✨', icon: 'none' });
|
|
this.showSetDateModal();
|
|
} else {
|
|
wx.showModal({
|
|
title: '💕 恋爱故事',
|
|
content: tempLoveStory,
|
|
showCancel: false
|
|
});
|
|
}
|
|
},
|
|
|
|
saveLoveDate: async function() {
|
|
const { tempLoveDate, tempLoveStory } = this.data;
|
|
if (!tempLoveDate) {
|
|
wx.showToast({ title: '请选择日期', icon: 'none' }); return;
|
|
}
|
|
try {
|
|
await api.updateCoupleInfo({
|
|
love_start_date: tempLoveDate,
|
|
love_story: tempLoveStory
|
|
});
|
|
wx.showToast({ title: '纪念日设置成功 💕', icon: 'success' });
|
|
this.hideSetDateModal();
|
|
this.loadData();
|
|
} catch (e) {
|
|
wx.showToast({ title: e.error || '保存失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
// TA详情
|
|
showPartnerDetail: function() {
|
|
this.setData({ showPartnerDetailModal: true });
|
|
},
|
|
hidePartnerDetailModal: function() {
|
|
this.setData({ showPartnerDetailModal: false });
|
|
},
|
|
|
|
// 编辑TA资料
|
|
showEditPartnerModal: function() {
|
|
const d = this.data;
|
|
this._editPartnerId = d.partnerId;
|
|
this._partnerOriginalStory = d.tempLoveStory;
|
|
var rawGender = d.partnerGenderRaw || '';
|
|
var genderText = rawGender === 'male' ? '男' : (rawGender === 'female' ? '女' : '未设置');
|
|
// 从 partnerDetail 中解析年龄(格式:XX岁)
|
|
var ageMatch = d.partnerDetail.match(/(\d+)岁/);
|
|
var partnerAge = ageMatch ? ageMatch[1] : '';
|
|
this.setData({
|
|
showEditPartnerModal: true,
|
|
editPartnerNickname: d.partnerName === 'TA' ? '' : d.partnerName,
|
|
editPartnerGender: rawGender || '',
|
|
editPartnerGenderText: genderText,
|
|
editPartnerAge: partnerAge,
|
|
editPartnerBirthday: d.partnerBirthday || '',
|
|
editPartnerAvatarUrl: d.partnerAvatarUrl || '',
|
|
editPartnerAvatarPath: '',
|
|
editPartnerNameInitial: d.partnerInitial || '?'
|
|
});
|
|
this._syncProfileTabBar();
|
|
},
|
|
hideEditPartnerModal: function() {
|
|
if (this.data.partnerSaving || this.data.partnerAvatarUploading) return;
|
|
this.setData({ showEditPartnerModal: false });
|
|
this._syncProfileTabBar();
|
|
},
|
|
onEditPartnerNicknameInput: function(e) {
|
|
if (!this.data.partnerSaving) this.setData({editPartnerNickname:e.detail.value});
|
|
},
|
|
onEditPartnerGenderChange: function(e) {
|
|
if (this.data.partnerSaving) return;
|
|
const index = Number(e.detail.value);
|
|
this.setData({editPartnerGender:['male','female'][index],editPartnerGenderText:['男','女'][index]});
|
|
},
|
|
onEditPartnerBirthdayInput: function(e) {
|
|
if (this.data.partnerSaving) return;
|
|
const birthday = e.detail.value;
|
|
const birth = new Date(birthday), today = new Date();
|
|
let age = today.getFullYear() - birth.getFullYear();
|
|
if (today.getMonth() < birth.getMonth() || (today.getMonth() === birth.getMonth() && today.getDate() < birth.getDate())) age--;
|
|
this.setData({editPartnerBirthday:birthday,editPartnerAge:String(Math.max(0,age))});
|
|
},
|
|
choosePartnerAvatar: function() {
|
|
if (this.data.partnerSaving || this.data.partnerAvatarUploading || !this._editPartnerId) return;
|
|
const self = this;
|
|
const partnerId = this._editPartnerId;
|
|
guardStorageSpace(0).then(function(ok) {
|
|
if (!ok) return;
|
|
wx.chooseImage({count:1,sizeType:['compressed'],sourceType:['album','camera'],success:async res=>{
|
|
if (!self.data.showEditPartnerModal || partnerId !== self._editPartnerId) return;
|
|
self.setData({partnerAvatarUploading:true});
|
|
try {
|
|
const uploaded = await api.uploadPartnerAvatar(res.tempFilePaths[0],partnerId);
|
|
self.setData({editPartnerAvatarUrl:getImageUrl(uploaded.path),editPartnerAvatarPath:uploadReference(uploaded)});
|
|
} catch(error) { wx.showToast({title:error.error || '头像上传失败',icon:'none'}); }
|
|
finally { self.setData({partnerAvatarUploading:false}); }
|
|
}});
|
|
});
|
|
},
|
|
savePartnerProfile: async function() {
|
|
const d = this.data;
|
|
if (d.partnerSaving || d.partnerAvatarUploading) return;
|
|
if (!d.hasPartner || !this._editPartnerId || this._editPartnerId !== d.partnerId) {
|
|
wx.showToast({title:'绑定信息已变化,请重新打开资料',icon:'none'});return;
|
|
}
|
|
const nickname = d.editPartnerNickname.trim();
|
|
if (!nickname) { wx.showToast({title:'请输入TA的昵称',icon:'none'});return; }
|
|
this.setData({partnerSaving:true});
|
|
try {
|
|
const result = await api.updatePartnerProfile({partner_id:this._editPartnerId,nickname,gender:d.editPartnerGender,age:parseInt(d.editPartnerAge) || 0,birthday:d.editPartnerBirthday,avatar:d.editPartnerAvatarPath || undefined});
|
|
if (!result || !result.success) throw result || {};
|
|
if (d.coupleId && (d.tempLoveDate !== d.loveStartDate || d.tempLoveStory !== this._partnerOriginalStory)) {
|
|
await api.updateCoupleInfo({love_start_date:d.tempLoveDate,love_story:d.tempLoveStory || ''});
|
|
}
|
|
this.setData({partnerSaving:false});
|
|
this.hideEditPartnerModal();
|
|
await this.loadData();
|
|
wx.showToast({title:'TA的资料已保存',icon:'success'});
|
|
} catch(error) { wx.showToast({title:error.error || '保存失败,请重试',icon:'none'}); }
|
|
finally { this.setData({partnerSaving:false}); }
|
|
},
|
|
|
|
// 加载解绑状态
|
|
loadUnbindStatus: function() {
|
|
var self = this;
|
|
api.unbindStatus().then(function(res) {
|
|
if (res && res.status && res.status !== 'none') {
|
|
self.setData({
|
|
unbindStatus: res.status,
|
|
unbindIsRequester: !!res.is_requester,
|
|
unbindRequesterName: res.requester_name || '对方',
|
|
unbindRemaining: res.remaining_seconds || 0
|
|
});
|
|
} else {
|
|
self.setData({ unbindStatus: '', unbindIsRequester: false, unbindRequesterName: '' });
|
|
}
|
|
}).catch(function() {});
|
|
},
|
|
|
|
// 解除绑定 — 根据状态显示不同操作
|
|
showUnbindVerify: function() {
|
|
var status = this.data.unbindStatus;
|
|
var isRequester = this.data.unbindIsRequester;
|
|
|
|
if (status === 'pending') {
|
|
if (isRequester) {
|
|
this.doCancelUnbind();
|
|
} else {
|
|
this.doRespondUnbind();
|
|
}
|
|
} else if (status === 'cooling') {
|
|
wx.showToast({ title: '正在72小时冷静期', icon: 'none' });
|
|
wx.navigateTo({ url: '/pages/unbind/unbind' });
|
|
} else {
|
|
this.doRequestUnbind();
|
|
}
|
|
},
|
|
|
|
doRequestUnbind: function() {
|
|
var self = this;
|
|
wx.showModal({
|
|
title: '💔 解除绑定',
|
|
content: '对方同意后进入72小时冷静期,期间任一方可取消。到期自动解绑并永久删除共同数据;个人抽烟记录保留。',
|
|
cancelText: '取消',
|
|
confirmText: '发起解绑',
|
|
confirmColor: '#FF4757',
|
|
success: function(res) {
|
|
if (res.confirm) {
|
|
wx.showLoading({ title: '发送请求...' });
|
|
api.unbindRequest().then(function() {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '解绑请求已发送', icon: 'success' });
|
|
self.loadUnbindStatus();
|
|
wx.navigateTo({ url: '/pages/unbind/unbind' });
|
|
}).catch(function(err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
doCancelUnbind: function() {
|
|
var self = this;
|
|
wx.showModal({
|
|
title: '↩️ 撤销解绑',
|
|
content: '取消后关系继续保留。确定取消解绑吗?',
|
|
cancelText: '取消',
|
|
confirmText: '撤销请求',
|
|
confirmColor: '#FF6B9D',
|
|
success: function(res) {
|
|
if (res.confirm) {
|
|
wx.showLoading({ title: '撤销中...' });
|
|
api.unbindCancel().then(function() {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '已撤销解绑请求', icon: 'success' });
|
|
self.loadUnbindStatus();
|
|
}).catch(function(err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
doRespondUnbind: function() {
|
|
var self = this;
|
|
var name = this.data.unbindRequesterName;
|
|
wx.showActionSheet({
|
|
itemList: ['✅ 同意解绑', '❌ 拒绝解绑'],
|
|
success: function(res) {
|
|
if (res.tapIndex === 0) {
|
|
wx.showModal({
|
|
title: '⚠️ 确认同意',
|
|
content: name + ' 发起了解绑请求。同意后进入72小时冷静期,期间可取消;到期自动解绑并永久删除共同数据,个人抽烟记录保留。',
|
|
cancelText: '取消',
|
|
confirmText: '同意解绑',
|
|
confirmColor: '#FF4757',
|
|
success: function(r) {
|
|
if (r.confirm) {
|
|
wx.showLoading({ title: '处理中...' });
|
|
api.unbindRespond({ agree: true }).then(function() {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '已进入72小时冷静期', icon: 'none' });
|
|
self.loadUnbindStatus();
|
|
}).catch(function(err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
});
|
|
}
|
|
}
|
|
});
|
|
} else if (res.tapIndex === 1) {
|
|
wx.showModal({
|
|
title: '拒绝解绑',
|
|
content: '确定要拒绝 ' + name + ' 的解绑请求吗?',
|
|
cancelText: '取消',
|
|
confirmText: '拒绝',
|
|
confirmColor: '#FF6B9D',
|
|
success: function(r) {
|
|
if (r.confirm) {
|
|
wx.showLoading({ title: '处理中...' });
|
|
api.unbindRespond({ agree: false }).then(function() {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '已拒绝解绑请求', icon: 'success' });
|
|
self.loadUnbindStatus();
|
|
}).catch(function(err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
// 空操作(用于 catchtap 阻止冒泡)
|
|
noop: function() {},
|
|
|
|
// 退出登录
|
|
logout: function() {
|
|
wx.showModal({
|
|
title: '确认退出',
|
|
content: '确定要退出登录吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
api.logout().catch(() => {});
|
|
wx.clearStorageSync();
|
|
wx.reLaunch({ url: '/pages/index/index' });
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
// 跳转前保存当前滚动位置
|
|
_savePosBeforeLeave: function() {
|
|
saveScrollPosition('profile', this._scrollTop == null ? this.data.scrollTop : this._scrollTop);
|
|
},
|
|
|
|
// ===== 邀请绑定 =====
|
|
showInvitePanel: function() {
|
|
var displayId = wx.getStorageSync('displayId') || '';
|
|
this.setData({
|
|
showInvitePanel: true,
|
|
inviteTab: 'received',
|
|
inviteTargetId: '',
|
|
inviteMessage: '',
|
|
myDisplayId: displayId
|
|
});
|
|
this.loadInvites();
|
|
this.startPollCoupleStatus();
|
|
},
|
|
|
|
hideInvitePanel: function() {
|
|
this.setData({ showInvitePanel: false });
|
|
if (this._pollTimer) {
|
|
clearInterval(this._pollTimer);
|
|
this._pollTimer = null;
|
|
}
|
|
},
|
|
|
|
onInviteTargetIdInput: function(e) { this.setData({ inviteTargetId: e.detail.value }); },
|
|
onInviteMessageInput: function(e) { this.setData({ inviteMessage: e.detail.value }); },
|
|
|
|
// 轮询检查情侣关系是否已恢复
|
|
startPollCoupleStatus: function() {
|
|
var self = this;
|
|
if (self._pollTimer) clearInterval(self._pollTimer);
|
|
self._pollTimer = setInterval(function() {
|
|
api.myInvitations().then(function(data) {
|
|
if (data && data.couple_id) {
|
|
clearInterval(self._pollTimer);
|
|
self._pollTimer = null;
|
|
wx.setStorageSync('coupleId', data.couple_id);
|
|
wx.showToast({ title: '情侣关系已恢复 💕', icon: 'success' });
|
|
setTimeout(function() {
|
|
self.setData({ showInvitePanel: false });
|
|
self.loadData();
|
|
}, 1500);
|
|
}
|
|
}).catch(function() {});
|
|
}, 10000);
|
|
},
|
|
|
|
sendInvite: async function() {
|
|
const inviteTargetId = String(this.data.inviteTargetId || '').trim();
|
|
const { inviteMessage } = this.data;
|
|
if (!inviteTargetId) { wx.showToast({ title: '请输入对方ID', icon: 'none' }); return; }
|
|
if (!/^[0-9]{6}$/.test(inviteTargetId)) { wx.showToast({ title: 'ID为6位数字', icon: 'none' }); return; }
|
|
// 邀请成功且对方接受时,需要通知邀请人,提前申请一次性订阅授权
|
|
requestSubscribe('notify').catch(function() {});
|
|
try {
|
|
wx.showLoading({ title: '发送中...' });
|
|
const res = await api.invitePartner({ target_user_id: inviteTargetId, message: inviteMessage });
|
|
wx.hideLoading();
|
|
wx.showToast({ title: res.msg || '邀请已发送,等待对方同意 💕', icon: 'success' });
|
|
this.setData({ inviteTargetId: '', inviteTab: 'sent' });
|
|
this.loadInvites();
|
|
} catch (err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '发送失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
loadInvites: async function() {
|
|
try {
|
|
const data = await api.myInvitations();
|
|
const received = (data.received || []).map(function(item) {
|
|
item.from_initial = (item.from_nickname || item.from_username || '?')[0];
|
|
item.short_date = item.created_at ? item.created_at.substring(0, 16).replace('T', ' ') : '';
|
|
return item;
|
|
});
|
|
const sent = (data.sent || []).map(function(item) {
|
|
item.to_initial = (item.to_nickname || item.to_username || '?')[0];
|
|
item.short_date = item.created_at ? item.created_at.substring(0, 16).replace('T', ' ') : '';
|
|
return item;
|
|
});
|
|
this.setData({ receivedInvites: received, sentInvites: sent });
|
|
if (data.couple_id) {
|
|
wx.setStorageSync('coupleId', data.couple_id);
|
|
wx.showToast({ title: '情侣关系已恢复 💕', icon: 'success' });
|
|
setTimeout(() => {
|
|
this.setData({ showInvitePanel: false });
|
|
this.loadData();
|
|
}, 1500);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
},
|
|
|
|
switchInviteTab: function(e) {
|
|
const tab = e.currentTarget.dataset.tab;
|
|
this.setData({ inviteTab: tab });
|
|
},
|
|
|
|
acceptInvite: async function(e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
try {
|
|
wx.showLoading({ title: '处理中...' });
|
|
const res = await api.respondInvitation({ invitation_id: id, accept: 1 });
|
|
wx.hideLoading();
|
|
if (res.couple_id) {
|
|
wx.setStorageSync('coupleId', res.couple_id);
|
|
wx.showToast({ title: '绑定成功 💕', icon: 'success' });
|
|
setTimeout(() => {
|
|
this.setData({ showInvitePanel: false });
|
|
this.loadData();
|
|
}, 1000);
|
|
}
|
|
} catch (err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
rejectInvite: async function(e) {
|
|
const id = e.currentTarget.dataset.id;
|
|
try {
|
|
wx.showLoading({ title: '处理中...' });
|
|
await api.respondInvitation({ invitation_id: id, accept: 0 });
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '已拒绝', icon: 'success' });
|
|
this.loadInvites();
|
|
} catch (err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
// ===== 分享绑定 =====
|
|
onShareAppMessage: function() {
|
|
if (!this.data.shareOutgoingCode) return {title:'邀请你绑定情侣', path:'/pages/profile/profile'};
|
|
var displayId = wx.getStorageSync('displayId') || this.data.myDisplayId;
|
|
var nick = wx.getStorageSync('nickname') || '我';
|
|
if (!displayId) {
|
|
wx.showToast({ title: '请先完善资料', icon: 'none' });
|
|
return {};
|
|
}
|
|
return {
|
|
title: nick + ' 邀请你绑定情侣 💕',
|
|
path: '/pages/profile/profile?inviter=' + displayId + '&invite_code=' + encodeURIComponent(this.data.shareOutgoingCode || ''),
|
|
imageUrl: '/images/share.png'
|
|
};
|
|
},
|
|
|
|
// 从分享链接进入时处理邀请绑定
|
|
handleShareInvite: function(inviterId, code) {
|
|
if (!inviterId) return;
|
|
this.setData({ shareInviterId: inviterId, shareInviteCode: code || '', showShareBindModal: true, shareDisagree: false });
|
|
},
|
|
|
|
acceptShareBind: async function() {
|
|
var self = this;
|
|
try {
|
|
wx.showLoading({ title: '处理中...' });
|
|
const res = await api.acceptShareInvite({ inviter_id: this.data.shareInviterId, invite_code: this.data.shareInviteCode });
|
|
wx.hideLoading();
|
|
if (res.couple_id) {
|
|
wx.setStorageSync('coupleId', res.couple_id);
|
|
wx.showToast({ title: '绑定成功 💕', icon: 'success' });
|
|
this.setData({ showShareBindModal: false });
|
|
setTimeout(() => { this.loadData(); }, 1000);
|
|
}
|
|
} catch (err) {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: err.error || '操作失败', icon: 'none' });
|
|
}
|
|
},
|
|
|
|
rejectShareBind: function() {
|
|
this.setData({ shareDisagree: true, shareInviterName: 'TA' });
|
|
},
|
|
|
|
hideShareBindModal: function() {
|
|
this.setData({ showShareBindModal: false });
|
|
},
|
|
|
|
loadStorageInfo: async function() {
|
|
try {
|
|
const d = await api.storageInfo();
|
|
const freeBytes = d.quota_bytes != null ? d.quota_bytes : (d.quotaBytes != null ? d.quotaBytes : (d.free_bytes || d.freeBytes || 0));
|
|
const usedBytes = d.used_bytes || d.usedBytes || 0;
|
|
const isVip = !!(d.is_vip || d.isVip);
|
|
const usedText = formatStorageBytes(usedBytes);
|
|
if (isVip) {
|
|
// 会员:展示「无限空间」+ 已用容量 + 到期时间,不再提示空间已满。
|
|
const expire = d.vip_expire_at || d.vipExpireAt;
|
|
this.setData({
|
|
storageVip: true,
|
|
storageText: (d.is_unlimited || d.isUnlimited) ? '无限空间' : formatStorageBytes(freeBytes),
|
|
storagePercent: 0,
|
|
storageOverQuota: !(d.is_unlimited || d.isUnlimited) && usedBytes>freeBytes,
|
|
storageUsedText: usedText,
|
|
storageExpireText: expire ? ('有效期至 ' + String(expire).slice(0, 10)) : '已开通容量套餐'
|
|
});
|
|
} else {
|
|
const percent = freeBytes > 0 ? Math.min(100, Math.round(usedBytes / freeBytes * 100)) : 0;
|
|
this.setData({
|
|
storageVip: false,
|
|
storageText: usedText,
|
|
storagePercent: percent,
|
|
storageOverQuota: usedBytes > freeBytes,
|
|
storageUsedText: usedText,
|
|
storageExpireText: ''
|
|
});
|
|
}
|
|
} catch (e) {
|
|
console.error('加载存储信息失败', e);
|
|
}
|
|
},
|
|
goStorage: function() {
|
|
this._savePosBeforeLeave();
|
|
wx.navigateTo({ url: '/pages/storage/storage' });
|
|
},
|
|
|
|
loadProfileStats: async function() {
|
|
this.setData({statsLoading:true,statsError:false});
|
|
const keys=['timeline','album','diary','songs','checkin','pet'];
|
|
const results=await Promise.allSettled([
|
|
api.timelineList(),api.albumList(),api.diaryList(),api.songsList(),api.checkinList(),
|
|
(this.data.coupleId || wx.getStorageSync('coupleId')) ? api.petInfo() : Promise.resolve({has_pet:false})
|
|
]);
|
|
const counts={};let failed=false;
|
|
results.forEach((result,index)=>{
|
|
const key=keys[index];
|
|
if(result.status !== 'fulfilled') { counts[key]='—';failed=true;return; }
|
|
const value=result.value;
|
|
if(key==='album') counts[key]=value && value.photo_total != null ? Number(value.photo_total) : itemsOf(value).reduce((sum,album)=>sum+(Number(album.photo_count)||0),0);
|
|
else if(key==='diary') counts[key]=Number(value && value.total)||0;
|
|
else if(key==='checkin') counts[key]=value && value.checkin_log_total !== undefined ? Number(value.checkin_log_total)||0 : (Array.isArray(value)?value.length:(value && value.items || []).length);
|
|
else if(key==='pet') counts[key]=value && value.has_pet && value.pet ? 'Lv.'+(Number(value.pet.level)||0) : '未领养';
|
|
else counts[key]=totalOf(value);
|
|
});
|
|
this.setData({statisticItems:this.data.statisticItems.map(item=>({...item,count:counts[item.key]===undefined?item.count:counts[item.key]})),statsLoading:false,statsError:failed});
|
|
},
|
|
openStatistic: function(e) {
|
|
const routes={timeline:'timeline',album:'albums',diary:'diary',songs:'lovewords',checkin:'punch',pet:'pet',period:'period',settings:'settings'};
|
|
const route=routes[e.currentTarget.dataset.key];
|
|
if(!route)return;
|
|
this._savePosBeforeLeave();
|
|
wx.navigateTo({url:'/pages/'+route+'/'+route});
|
|
},
|
|
|
|
// 页面跳转
|
|
manageRelationship: function() { wx.navigateTo({ url: '/pages/unbind/unbind' }); },
|
|
goToSettings: function() { this._savePosBeforeLeave(); wx.navigateTo({ url: '/pages/settings/settings' }); },
|
|
goHome: function() { this._savePosBeforeLeave(); wx.switchTab({ url: '/pages/index/index' }); }
|
|
}, {"loadData": ["coupleInfo"], "loadProfileStats": ["timelineList","albumList","diaryList","songsList","checkinList","petInfo"], "loadStorageInfo": ["storageInfo"]}));
|