feat: add account deletion, announcements and subscription renewal
Support personal records and persistent smoking visibility. Add upload quota preflight, file cleanup, privacy entry, image caching and revision-based page refresh across the backend, admin and mini program.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const { getLayout } = require('../../utils/layout');
|
||||
// pages/settings/settings.js
|
||||
const { api, getImageUrl, API_BASE, uploadFileCompat } = require('../../utils/request');
|
||||
const { requestSubscribe, getSubscribeStatus } = require('../../utils/subscribe');
|
||||
const { requestSubscribe, getSubscribeStatus, isTemplateConfigured, subscribeErrorMessage } = require('../../utils/subscribe');
|
||||
const { guardStorageSpace } = require('../../utils/storage-guard');
|
||||
Page({
|
||||
onResize: function() { this.setData(getLayout()); },
|
||||
@@ -23,6 +23,7 @@ Page({
|
||||
// 消息通知设置
|
||||
showSubscribeModal: false,
|
||||
subscribeStatus: {},
|
||||
notifyAvailable: typeof isTemplateConfigured === 'function' && isTemplateConfigured('notify'),
|
||||
subscribeItems: [],
|
||||
subscribeLoading: false,
|
||||
|
||||
@@ -63,6 +64,25 @@ Page({
|
||||
wx.switchTab({ url: '/pages/profile/profile' });
|
||||
},
|
||||
|
||||
deleteAccount: async function() {
|
||||
if(this._deletingAccount)return;
|
||||
this._deletingAccount=true;
|
||||
try {
|
||||
const preview=await api.accountDeletionPreview();
|
||||
const counts=preview.summary.counts;
|
||||
const text='已上传文件 '+counts.files+' 个,相册 '+counts.albums+' 个,照片 '+counts.photos+' 张,日记 '+counts.diaries+' 篇,记忆日 '+counts.timeline+' 条,打卡 '+counts.checkins+' 条,抽烟记录 '+counts.smoking+' 条,生理期日记录 '+counts.period+' 条。';
|
||||
const labels={past_song:'歌曲',past_diary_comment:'评论',past_period_record:'生理期周期',past_period_sex_record:'亲密记录',past_storage_order:'订单',past_subscribe_template:'消息订阅'};
|
||||
const more=Object.keys(labels).map(key=>labels[key]+' '+((preview.summary.record_counts||{})[key]||0)+' 条').join(',');
|
||||
const confirm=options=>new Promise(resolve=>wx.showModal({...options,success:r=>resolve(r.confirm),fail:()=>resolve(false)}));
|
||||
if(!await confirm({title:'注销账号前,请确认',content:text+' 其他数据:'+more+'。注销后,账号、所有内容及文件关联会被删除,无法恢复;剩余空间权益将失效。',confirmText:'继续注销',confirmColor:'#B74768'}))return;
|
||||
if(!await confirm({title:'最后一次确认',content:'确定永久注销并删除全部数据?独占文件将从存储中清理;与其他用户重复的物理文件只移除你的关联,不会删除他人的内容。',confirmText:'确认注销',confirmColor:'#B74768'}))return;
|
||||
wx.showLoading({title:'正在注销',mask:true});
|
||||
await api.accountDelete({confirmed:true,confirmation_text:'注销并删除全部数据',confirmation_token:preview.confirmation_token});
|
||||
getApp().finishAccountDeletion();
|
||||
wx.reLaunch({url:'/pages/index/index'});
|
||||
} catch(error) {wx.showToast({title:error.error||'注销失败,请稍后重试',icon:'none',duration:3000});}
|
||||
finally {wx.hideLoading();this._deletingAccount=false;}
|
||||
},
|
||||
// 加载解绑状态
|
||||
loadUnbindStatus: function() {
|
||||
var self = this;
|
||||
@@ -82,7 +102,7 @@ Page({
|
||||
|
||||
noop: function() {},
|
||||
|
||||
// ===== 消息通知管理(统一使用一个模板) =====
|
||||
// ===== 消息通知管理(按场景独立授权) =====
|
||||
showSubscribeModal: async function() {
|
||||
this.setData({ showSubscribeModal: true, subscribeLoading: true });
|
||||
try {
|
||||
@@ -110,6 +130,18 @@ Page({
|
||||
this.setData({ showAboutModal: false });
|
||||
},
|
||||
|
||||
openPrivacyContract: function() {
|
||||
if (typeof wx.openPrivacyContract !== 'function') {
|
||||
wx.showToast({ title: '请升级微信后查看隐私协议', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
wx.openPrivacyContract({
|
||||
fail: function() {
|
||||
wx.showToast({ title: '隐私协议暂时无法打开,请稍后重试', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// ===== 联系我们 =====
|
||||
showContactModal: function() {
|
||||
this.setData({ showContactModal: true });
|
||||
@@ -120,7 +152,12 @@ Page({
|
||||
|
||||
toggleSubscribe: async function(e) {
|
||||
const type = 'notify';
|
||||
const current = this.data.subscribeChecked;
|
||||
if (typeof isTemplateConfigured === 'function' && !isTemplateConfigured(type)) {
|
||||
wx.showToast({title:'该提醒暂未配置模板',icon:'none'});
|
||||
return;
|
||||
}
|
||||
const field = 'subscribeChecked';
|
||||
const current = this.data[field];
|
||||
|
||||
// 防止重复点击
|
||||
if (this._subscribing) return;
|
||||
@@ -130,8 +167,8 @@ Page({
|
||||
// 取消订阅
|
||||
try {
|
||||
await api.unsubscribeTemplate({ template_type: type });
|
||||
this.setData({ subscribeChecked: false });
|
||||
wx.setStorageSync('subscribed_notify', false);
|
||||
this.setData({ [field]: false });
|
||||
wx.setStorageSync('subscribed_' + type, false);
|
||||
wx.showToast({ title: '已关闭通知', icon: 'success' });
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '操作失败', icon: 'none' });
|
||||
@@ -141,33 +178,35 @@ Page({
|
||||
try {
|
||||
const results = await requestSubscribe(type);
|
||||
if (results[type]) {
|
||||
this.setData({ subscribeChecked: true });
|
||||
wx.setStorageSync('subscribed_notify', true);
|
||||
this.setData({ [field]: true });
|
||||
wx.setStorageSync('subscribed_' + type, true);
|
||||
wx.showToast({ title: '已开启通知', icon: 'success' });
|
||||
} else {
|
||||
wx.showToast({ title: '订阅被拒绝,可在设置中重新开启', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '订阅失败', icon: 'none' });
|
||||
wx.showModal({title:'无法订阅提醒',content:subscribeErrorMessage(e),showCancel:false});
|
||||
}
|
||||
}
|
||||
|
||||
this._subscribing = false;
|
||||
},
|
||||
|
||||
renewSubscribe: async function() {
|
||||
renewSubscribe: async function(e) {
|
||||
const type = 'notify';
|
||||
const field = 'subscribeChecked';
|
||||
if (this._subscribing) return;
|
||||
this._subscribing = true;
|
||||
try {
|
||||
const results = await requestSubscribe('notify');
|
||||
if (results.notify) {
|
||||
this.setData({ subscribeChecked: true });
|
||||
const results = await requestSubscribe(type);
|
||||
if (results[type]) {
|
||||
this.setData({ [field]: true });
|
||||
wx.showToast({ title: '已订阅一次提醒', icon: 'success' });
|
||||
} else {
|
||||
wx.showToast({ title: '本次未授权提醒', icon: 'none' });
|
||||
}
|
||||
} catch (e) {
|
||||
wx.showToast({ title: '订阅失败,请重试', icon: 'none' });
|
||||
wx.showModal({title:'无法订阅提醒',content:subscribeErrorMessage(e),showCancel:false});
|
||||
} finally {
|
||||
this._subscribing = false;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
</view>
|
||||
|
||||
<view class="section-heading">关系与账号</view>
|
||||
<view class="j-profile-setting" wx:if="{{bindingKnown && !hasPartner}}" bindtap="deleteAccount"><view class="setting-info"><view class="j-small-title" style="color:#B74768">注销账号</view><view class="j-caption">未绑定时可注销,确认后删除全部个人数据</view></view><text class="j-link">›</text></view>
|
||||
<!-- 操作记录 -->
|
||||
<view class="j-profile-setting" bindtap="goToHistory">
|
||||
<view class="setting-info">
|
||||
@@ -73,6 +74,14 @@
|
||||
<text class="j-link">›</text>
|
||||
</view>
|
||||
|
||||
<view class="j-profile-setting" bindtap="openPrivacyContract">
|
||||
<view class="setting-info">
|
||||
<view class="j-small-title">隐私协议</view>
|
||||
<view class="j-caption">查看本小程序的隐私保护指引</view>
|
||||
</view>
|
||||
<text class="j-link">›</text>
|
||||
</view>
|
||||
|
||||
<!-- 联系我们 -->
|
||||
<view class="j-profile-setting" bindtap="showContactModal">
|
||||
<view class="setting-info">
|
||||
@@ -133,11 +142,11 @@
|
||||
<text class="subscribe-icon">💕</text>
|
||||
</view>
|
||||
<view class="subscribe-info">
|
||||
<text class="subscribe-name">操作通知</text>
|
||||
<text class="subscribe-desc">TA有新的操作时通知你</text>
|
||||
<text class="subscribe-name">操作与打卡通知</text>
|
||||
<text class="subscribe-desc">{{notifyAvailable ? 'TA有新动态或完成打卡时通知你' : '暂未配置当前小程序的通知模板'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<switch checked="{{subscribeChecked}}" bindchange="toggleSubscribe" color="#B74768" style="transform:scale(0.75);" />
|
||||
<switch disabled="{{!notifyAvailable}}" checked="{{subscribeChecked}}" bindchange="toggleSubscribe" color="#B74768" style="transform:scale(0.75);" />
|
||||
</view>
|
||||
|
||||
<!-- 状态提示 -->
|
||||
@@ -148,11 +157,11 @@
|
||||
</block>
|
||||
<block wx:else>
|
||||
<text class="tip-icon">💡</text>
|
||||
<text class="tip-text">开启并授权后,可接收一次TA的操作提醒</text>
|
||||
<text class="tip-text">开启并授权后,可接收一次TA的提醒</text>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<button wx:if="{{subscribeChecked}}" class="subscribe-renew" bindtap="renewSubscribe">订阅一次 TA 的提醒</button>
|
||||
<button wx:if="{{notifyAvailable && subscribeChecked}}" class="subscribe-renew" bindtap="renewSubscribe">订阅一次 TA 的提醒</button>
|
||||
|
||||
<!-- 说明 -->
|
||||
<view class="subscribe-note">
|
||||
|
||||
Reference in New Issue
Block a user