const { getLayout } = require('../../utils/layout'); // pages/settings/settings.js const { api, getImageUrl, API_BASE, uploadFileCompat } = require('../../utils/request'); const { requestSubscribe, getSubscribeStatus } = require('../../utils/subscribe'); Page({ onResize: function() { this.setData(getLayout()); }, data: { showBgModal: false, bgPreview: '', bgFilePath: '', hasPartner: false, bindingKnown: false, bindingError:false, // 解绑状态 unbindStatus: '', // '' / 'pending' / 'agreed' / 'rejected' / 'cancelled' / 'expired' unbindIsRequester: false, // 当前用户是否是发起方 unbindRequesterName: '', // 发起方昵称 unbindRemaining: 0, // 剩余秒数 // 消息通知设置 showSubscribeModal: false, subscribeStatus: {}, subscribeItems: [], subscribeLoading: false, // 我们past showAboutModal: false, // 联系我们 showContactModal: false, }, onLoad: function() { this.setData(getLayout());}, onPullDownRefresh: function() { wx.stopPullDownRefresh(); }, onShow: async function() { this.setData({ bindingKnown: false, bindingError:false }); try { var info = await api.coupleInfo(); var hasPartner = !!(info && !info.not_bound && info.id); this.setData({ hasPartner: hasPartner, bindingKnown: true }); if (hasPartner) { wx.setStorageSync('coupleId', info.id); this.loadUnbindStatus(); } else { wx.removeStorageSync('coupleId'); this.setData({ unbindStatus: '', unbindIsRequester: false, unbindRequesterName: '' }); } } catch (e) { this.setData({bindingError:true}); console.error('获取绑定状态失败', e); } }, goBind: function() { getApp().globalData.openProfileBind = true; wx.switchTab({ url: '/pages/profile/profile' }); }, // 加载解绑状态 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() {}); }, noop: function() {}, // ===== 消息通知管理(统一使用一个模板) ===== showSubscribeModal: async function() { this.setData({ showSubscribeModal: true, subscribeLoading: true }); try { // forceRefresh=true 确保从后端获取最新状态 const status = await getSubscribeStatus(true); this.setData({ subscribeStatus: status, subscribeChecked: !!status['notify'], subscribeLoading: false }); } catch (e) { this.setData({ subscribeLoading: false }); } }, hideSubscribeModal: function() { this.setData({ showSubscribeModal: false }); }, // ===== 我们past ===== showAboutModal: function() { this.setData({ showAboutModal: true }); }, hideAboutModal: function() { this.setData({ showAboutModal: false }); }, // ===== 联系我们 ===== showContactModal: function() { this.setData({ showContactModal: true }); }, hideContactModal: function() { this.setData({ showContactModal: false }); }, toggleSubscribe: async function(e) { const type = 'notify'; const current = this.data.subscribeChecked; // 防止重复点击 if (this._subscribing) return; this._subscribing = true; if (current) { // 取消订阅 try { await api.unsubscribeTemplate({ template_type: type }); this.setData({ subscribeChecked: false }); wx.setStorageSync('subscribed_notify', false); wx.showToast({ title: '已关闭通知', icon: 'success' }); } catch (e) { wx.showToast({ title: '操作失败', icon: 'none' }); } } else { // 请求订阅授权 try { const results = await requestSubscribe(type); if (results[type]) { this.setData({ subscribeChecked: true }); wx.setStorageSync('subscribed_notify', true); wx.showToast({ title: '已开启通知', icon: 'success' }); } else { wx.showToast({ title: '订阅被拒绝,可在设置中重新开启', icon: 'none' }); } } catch (e) { wx.showToast({ title: '订阅失败', icon: 'none' }); } } this._subscribing = false; }, renewSubscribe: async function() { if (this._subscribing) return; this._subscribing = true; try { const results = await requestSubscribe('notify'); if (results.notify) { this.setData({ subscribeChecked: true }); wx.showToast({ title: '已订阅一次提醒', icon: 'success' }); } else { wx.showToast({ title: '本次未授权提醒', icon: 'none' }); } } catch (e) { wx.showToast({ title: '订阅失败,请重试', icon: 'none' }); } finally { this._subscribing = false; } }, // ===== 背景图 ===== showBgModal: async function() { this.setData({ showBgModal: true, bgPreview: '', bgFilePath: '' }); try { var cfg = await api.getBgConfig(); if (!this.data.bgFilePath) this.setData({ bgPreview: cfg && cfg.image ? getImageUrl(cfg.image) : '' }); } catch (e) { console.error(e); } }, hideBgModal: function() { this.setData({ showBgModal: false }); }, // 背景编辑页左滑返回设置页面 bgTouchStartX: 0, bgTouchStartY: 0, onBgTouchStart: function(e) { this.bgTouchStartX = e.touches[0].clientX; this.bgTouchStartY = e.touches[0].clientY; }, onBgTouchEnd: function(e) { var dx = this.bgTouchStartX - e.changedTouches[0].clientX; var dy = Math.abs(this.bgTouchStartY - e.changedTouches[0].clientY); if (dx < 20 && dy < 20) return; if (Math.abs(dx) > dy && dx > 80) this.hideBgModal(); }, chooseBgImage: function() { var self = this; wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success: function(res) { self.setData({ bgPreview: res.tempFilePaths[0], bgFilePath: res.tempFilePaths[0] }); } }); }, saveBgImage: async function() { var fp = this.data.bgFilePath; if (!fp) { if (this.data.bgPreview) { wx.showToast({ title: '背景已设置', icon: 'success' }); this.hideBgModal(); return; } wx.showToast({ title: '请先选择图片', icon: 'none' }); return; } var self = this; wx.showLoading({ title: '上传中...' }); try { var data = await uploadFileCompat({ url: API_BASE + '/setBgImage', filePath: fp, name: 'bg', formData: {} }); wx.hideLoading(); if (data && data.path) { var imgUrl = getImageUrl(data.path); wx.showToast({ title: '背景已保存 ✨', icon: 'success' }); self.setData({ bgPreview: imgUrl, bgFilePath: '' }); self.hideBgModal(); } else { var errMsg = (data && data.error) || '上传失败'; if (data && data.code) errMsg += ' (错误码: ' + data.code + ')'; wx.showToast({ title: errMsg, icon: 'none' }); } } catch(e) { wx.hideLoading(); var errMsg = (e && e.error) || '上传失败'; if (e && e.code) errMsg += ' (错误码: ' + e.code + ')'; wx.showToast({ title: errMsg, icon: 'none' }); } }, removeBgImage: async function() { try { await api.deleteBgImage(); } catch(e) {} wx.showToast({ title: '已恢复默认', icon: 'success' }); this.setData({ bgPreview: '', bgFilePath: '' }); this.hideBgModal(); }, // ===== 解除绑定(根据状态显示不同操作)===== showUnbind: 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(); wx.navigateTo({ url: '/pages/unbind/unbind' }); }).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' }); }); } } }); } } }); }, // 导航 goToHistory: function() { wx.navigateTo({ url: '/pages/history/history' }); }, goHome: function() { wx.switchTab({ url: '/pages/index/index' }); }, goToProfile: function() { wx.navigateBack(); }, });