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
+16 -4
View File
@@ -1,7 +1,8 @@
// 仅保存本次进程内的数据,不写入手机本地存储。
const TTL = 45000;
const TTL = 300000;
const policies = {
coupleInfo: 300000, getBgConfig: 300000,
coupleInfo: TTL, getBgConfig: TTL, myInfo: TTL, storageInfo: TTL, announcement: TTL,
checkAuth: 30000, unbindStatus: 30000,
timelineList: TTL, timelineDetail: TTL, albumList: TTL, photos: TTL,
diaryList: TTL, diaryDetail: TTL, diaryCommentList: TTL,
songsList: TTL, checkinList: TTL, checkinStats: TTL, checkinDetail: TTL,
@@ -18,12 +19,20 @@ let entries = new Map();
let versions = {};
let scope = '';
let epoch = 0;
let remoteRevision;
function currentScope() {
const next = String(wx.getStorageSync('userId') || '') + ':' + String(wx.getStorageSync('coupleId') || '');
if (next !== scope) { scope = next; clear(); }
return scope;
}
function clear() { entries.clear(); versions = {}; epoch++; }
function clear() { entries.clear(); versions = {}; remoteRevision = undefined; epoch++; }
function applyRemoteRevision(revision) {
currentScope();
if (!revision) return false;
if (remoteRevision === undefined) { remoteRevision = revision; return false; }
if (remoteRevision === revision) return false;
clear(); remoteRevision = revision; return true;
}
function signature(actions) {
currentScope();
return epoch + ':' + actions.map(action => action + ':' + (versions[action] || 0)).join('|');
@@ -82,7 +91,10 @@ function mutation(action, result) {
else if (/^pet(Adopt|DailyAction|Rename)$/.test(action)) group = 'pet';
else if (/^(setBgImage|deleteBgImage)$/.test(action)) group = 'background';
if (group) invalidate(groups[group].concat(['activityLogList']));
if (group === 'couple') invalidate(['myInfo','checkAuth']);
if (action === 'smokingCardVisible') invalidate(['checkAuth','myInfo']);
if (/^(upload|photoUpload|uploadAvatar|uploadPartnerAvatar|setBgImage|deleteBgImage|setAlbumCover|photoDelete|albumDelete|accountDelete)$/.test(action) || (action === 'storageOrderStatus' && result && result.status === 'paid')) invalidate(['storageInfo']);
// 展示作者资料的列表也需要更新头像/昵称。
if (group === 'couple') invalidate(groups.timeline.concat(groups.diary, groups.checkin));
}
module.exports = { read, invalidate, mutation, clear, signature, policies, TTL };
module.exports = { read, invalidate, mutation, clear, signature, policies, TTL, applyRemoteRevision };