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:
2026-11-03 22:06:47 +08:00
parent 4c9708b562
commit 8be6d9b1ab
98 changed files with 1679 additions and 372 deletions
+26
View File
@@ -1,3 +1,5 @@
const { tryLoginRenewal } = require('../../utils/subscribe');
const announcementSession = require('../../utils/announcement-session');
const { itemsOf, totalOf } = require('../../utils/list-pagination');
let lastLocationReport = 0;
let locationReportUser = null;
@@ -9,8 +11,10 @@ const { diaryEntry } = require('../../utils/journal');
const { saveScrollPosition, resetScrollOnTabShow } = require('../../utils/scroll-pos');
Page(withDataCache({
onLoginSubscribeTap: function() { return tryLoginRenewal(); },
onResize: function() { this.setData(getLayout()); },
data: {
showAnnouncement:false, announcement:null,
userId: null,
coupleId: null,
@@ -53,6 +57,8 @@ Page(withDataCache({
},
onShow: function() {
this._announcementActive=true;
this.loadAnnouncement();
resetScrollOnTabShow(this, 'index');
const tabBar = this.getTabBar && this.getTabBar();
if (tabBar) tabBar.syncActive();
@@ -72,6 +78,26 @@ Page(withDataCache({
this.fetchIpLocation();
},
onHide: function() { this._announcementActive=false; },
onUnload: function() { this._announcementActive=false; },
loadAnnouncement: function() {
if(this._announcementLoading)return this._announcementLoading;
this._announcementLoading=(async()=>{
try {
const notice=await api.announcement();
if(this._announcementActive===false)return;
const userId=wx.getStorageSync('userId');
const show=announcementSession.shouldShow(notice,userId);
this.setData({announcement:notice, showAnnouncement:show});
if(show)announcementSession.markShown(notice,userId);
} catch(e) {} // 公告读取失败不阻塞首页。
})().finally(()=>{this._announcementLoading=null;});
return this._announcementLoading;
},
closeAnnouncement: function() {
this.setData({showAnnouncement:false});
},
preventNoticeMove: function() {},
// 保存滚动位置
onScroll: function(e) {
this._scrollTop = e.detail.scrollTop;