init: initial commit

This commit is contained in:
2026-10-07 09:28:43 +08:00
commit a68a4ef411
251 changed files with 38279 additions and 0 deletions
+932
View File
@@ -0,0 +1,932 @@
const { getLayout } = require('../../utils/layout');
// pages/profile/profile.js - 与原网站一致的个人中心
const { api, getImageUrl } = require('../../utils/request');
const { saveScrollPosition, getScrollPosition } = require('../../utils/scroll-pos');
Page({
onResize: function() { this.setData(getLayout()); },
data: {
scrollTop: 0,
// 我的信息
myNickname: '未登录',
myDisplayId: '',
myPhone: '-',
myGender: '-',
myAge: '-',
myBirthday: '-',
myRegion: '',
myLocation: '',
myStatus: '设置恋爱信息',
myAvatarUrl: '',
myInitial: '?',
// TA的信息
hasPartner: false,
bindingKnown: false, bindingError: false,
partnerName: 'TA',
partnerDisplayId: '',
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,
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) {
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: getScrollPosition('profile')
});
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); }, 800);
}
},
onShow: function() {
var uid = wx.getStorageSync('userId');
var cid = wx.getStorageSync('coupleId');
var self = this;
var savedTop = getScrollPosition('profile');
this.setData({ scrollTop: savedTop, bindingKnown: false, myLocation: '' });
// 延迟重新设置 scrollTop,解决从子页面 navigateBack 返回后滚动位置丢失的问题
setTimeout(function() {
self.setData({ scrollTop: savedTop });
}, 100);
this.setData({ userId: uid, coupleId: cid });
this.loadData();
// 如果已绑定情侣,关闭邀请面板
if (cid && this.data.showInvitePanel) {
this.setData({ showInvitePanel: false });
if (this._pollTimer) {
clearInterval(this._pollTimer);
this._pollTimer = null;
}
}
},
onUnload: function() {
if (this._pollTimer) {
clearInterval(this._pollTimer);
this._pollTimer = null;
}
},
onPullDownRefresh: async function() {
await this.loadData();
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: '',
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 || '',
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() {});
},
// 编辑资料
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 || '?'
});
},
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 });
},
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() {
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
const filePath = res.tempFiles[0].path;
this.setData({ editAvatarUrl: filePath });
// 上传头像
try {
const data = await api.uploadAvatar(filePath);
this.setData({
editAvatarUrl: getImageUrl(data.path),
editAvatarPath: data.path
});
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;
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 || 'male',
editPartnerGenderText: genderText,
editPartnerAge: partnerAge,
editPartnerBirthday: d.partnerBirthday || '',
editPartnerAvatarUrl: d.partnerAvatarUrl || '',
editPartnerAvatarPath: '',
editPartnerNameInitial: d.partnerInitial || '?'
});
},
hideEditPartnerModal: function() {
this.setData({ showEditPartnerModal: 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 === 'agreed') {
wx.showToast({ title: '双方已同意解绑,正在处理中', icon: 'none' });
wx.navigateTo({ url: '/pages/unbind/unbind' });
} else {
this.doRequestUnbind();
}
},
doRequestUnbind: function() {
var self = this;
wx.showModal({
title: '💔 解除绑定',
content: '发起解绑请求后,对方需要在72小时内确认同意。\n\n对方同意后,所有情侣记录将被永久删除(记忆日、日记、相册、纪念日、情话、歌曲、打卡),仅保留双方个人资料。\n\n你也可以在对方确认前撤销请求。',
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 + ' 发起了解绑请求。\n\n同意后,所有情侣记录将被永久删除(记忆日、日记、相册、歌曲、打卡),仅保留双方个人资料。\n\n此操作不可恢复!',
cancelText: '取消',
confirmText: '同意解绑',
confirmColor: '#FF4757',
success: function(r) {
if (r.confirm) {
wx.showLoading({ title: '处理中...' });
api.unbindRespond({ agree: true }).then(function() {
wx.hideLoading();
wx.showToast({ title: '已同意解绑', icon: 'success' });
wx.removeStorageSync('coupleId');
wx.removeStorageSync('partnerId');
wx.removeStorageSync('partnerName');
wx.removeStorageSync('partnerAvatar');
wx.removeStorageSync('petHasPet');
setTimeout(function() {
wx.reLaunch({ url: '/pages/index/index' });
}, 1500);
}).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.data.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, inviteMessage } = this.data;
if (!inviteTargetId) { wx.showToast({ title: '请输入对方ID', icon: 'none' }); return; }
if (inviteTargetId.length < 6) { wx.showToast({ title: 'ID为6位数字', icon: 'none' }); return; }
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() {
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,
imageUrl: '/images/share.png'
};
},
// 从分享链接进入时处理邀请绑定
handleShareInvite: function(inviterId) {
if (!inviterId) return;
this.setData({ shareInviterId: inviterId, showShareBindModal: true, shareDisagree: false });
},
acceptShareBind: async function() {
var self = this;
try {
wx.showLoading({ title: '处理中...' });
const res = await api.acceptShareInvite({ inviter_id: this.data.shareInviterId });
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 });
},
// 页面跳转
manageRelationship: function() { wx.navigateTo({ url: '/pages/unbind/unbind' }); },
goToSettings: function() { this._savePosBeforeLeave(); wx.navigateTo({ url: '/pages/settings/settings' }); },
goHome: function() { this._savePosBeforeLeave(); wx.redirectTo({ url: '/pages/index/index' }); }
});