同步小程序与管理端更新,完善抽烟记录和解绑冷静期
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
// 仅保存本次进程内的数据,不写入手机本地存储。
|
||||
const TTL = 45000;
|
||||
const policies = {
|
||||
coupleInfo: 300000, getBgConfig: 300000,
|
||||
timelineList: TTL, timelineDetail: TTL, albumList: TTL, photos: TTL,
|
||||
diaryList: TTL, diaryDetail: TTL, diaryCommentList: TTL,
|
||||
songsList: TTL, checkinList: TTL, checkinStats: TTL, checkinDetail: TTL,
|
||||
smokingInfo: TTL,
|
||||
petInfo: TTL, petAchievements: TTL, activityLogList: TTL
|
||||
};
|
||||
const groups = {
|
||||
couple: ['coupleInfo'], timeline: ['timelineList', 'timelineDetail'],
|
||||
album: ['albumList', 'photos'], diary: ['diaryList', 'diaryDetail', 'diaryCommentList'],
|
||||
songs: ['songsList'], checkin: ['checkinList', 'checkinStats', 'checkinDetail'],
|
||||
pet: ['petInfo', 'petAchievements'], background: ['getBgConfig']
|
||||
};
|
||||
let entries = new Map();
|
||||
let versions = {};
|
||||
let scope = '';
|
||||
let epoch = 0;
|
||||
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 signature(actions) {
|
||||
currentScope();
|
||||
return epoch + ':' + actions.map(action => action + ':' + (versions[action] || 0)).join('|');
|
||||
}
|
||||
function invalidate(actions) {
|
||||
currentScope();
|
||||
actions.forEach(action => { versions[action] = (versions[action] || 0) + 1; });
|
||||
entries.forEach((entry, key) => { if (actions.indexOf(entry.action) >= 0) entries.delete(key); });
|
||||
}
|
||||
function stable(value) {
|
||||
if (Array.isArray(value)) return value.map(stable);
|
||||
if (value && typeof value === 'object') {
|
||||
const out = {};
|
||||
Object.keys(value).sort().forEach(key => {
|
||||
if (value[key] !== undefined && value[key] !== null) out[key] = stable(value[key]);
|
||||
});
|
||||
return out;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function copy(value) { return value == null ? value : JSON.parse(JSON.stringify(value)); }
|
||||
async function read(action, data, fetch) {
|
||||
currentScope();
|
||||
if (!policies[action]) return fetch();
|
||||
const key = action + ':' + JSON.stringify(stable(data || {}));
|
||||
let entry = entries.get(key);
|
||||
if (entry && entry.pending) return entry.pending.then(copy);
|
||||
if (entry && Date.now() - entry.time < policies[action]) return copy(entry.value);
|
||||
entry = { action };
|
||||
// 不缓存失败;失效或身份切换后,旧请求不能写回缓存。
|
||||
entries.set(key, entry);
|
||||
entry.pending = Promise.resolve().then(fetch).then(value => {
|
||||
if (entries.get(key) === entry) {
|
||||
entry.value = copy(value); entry.time = Date.now(); entry.pending = null;
|
||||
// 限制详情/分页缓存数量,避免长时间浏览占用过多内存。
|
||||
if (entries.size > 150) entries.delete(entries.keys().next().value);
|
||||
}
|
||||
return value;
|
||||
}, error => {
|
||||
if (entries.get(key) === entry) entries.delete(key);
|
||||
throw error;
|
||||
});
|
||||
return entry.pending.then(copy);
|
||||
}
|
||||
function mutation(action, result) {
|
||||
if (result && (result.error || result.success === false)) return;
|
||||
if (/^(logout|respondInvitation|acceptShareInvite|unbindRequest|unbindRespond|unbindCancel)$/.test(action)) { clear(); return; }
|
||||
let group;
|
||||
if (/^(updateProfile|updatePartnerProfile|updateCoupleInfo|updateLocation|updateIpLocation|uploadAvatar|uploadPartnerAvatar)$/.test(action)) group = 'couple';
|
||||
else if (/^timeline(Add|Update|Delete)$/.test(action)) group = 'timeline';
|
||||
else if (/^(album(Add|Update|Delete)|photo(Add|Update|Delete|Upload))$/.test(action)) group = 'album';
|
||||
else if (/^diary(Add|Update|Delete|CommentAdd|CommentDelete)$/.test(action)) group = 'diary';
|
||||
else if (/^songs(Add|Update|Delete)$/.test(action)) group = 'songs';
|
||||
else if (action === "smokingAction") { invalidate(["smokingInfo"]); group = "checkin"; }
|
||||
else if (/^checkin(Add|Do|Delete)$/.test(action)) { invalidate(groups.pet); group = 'checkin'; }
|
||||
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(groups.timeline.concat(groups.diary, groups.checkin));
|
||||
}
|
||||
module.exports = { read, invalidate, mutation, clear, signature, policies, TTL };
|
||||
Reference in New Issue
Block a user