/** * 同步管理:失败入队,启动时重试 * Why:自建后端、HTTPS 链路、定时任务任一环节抖动都会导致单次写入丢失。本地队列兜底,保证最终一致。 */ const api = require('./api') const QUEUE_KEY = 'pending_sync_queue' function loadQueue() { try { return wx.getStorageSync(QUEUE_KEY) || [] } catch (e) { return [] } } function saveQueue(q) { try { wx.setStorageSync(QUEUE_KEY, q) } catch (e) {} } function enqueue(item) { const q = loadQueue() q.push({ ...item, ts: Date.now() }) saveQueue(q) } async function dispatch(item) { if (item.kind === 'person') return api.person(item.action, item.data) if (item.kind === 'anniversary') return api.anniversary(item.action, item.data) throw new Error('unknown sync kind: ' + item.kind) } // 立即尝试同步;失败入队 async function syncOrEnqueue(item) { try { const res = await dispatch(item) if (res && res.success === false) throw new Error(res.error || 'server returned failure') return true } catch (err) { console.warn('[sync] 失败已入队:', item.kind, item.action, err.message || err) enqueue(item) return false } } // 尝试 flush 整个队列,失败的留下下次再试 async function flush() { const q = loadQueue() if (q.length === 0) return { flushed: 0, remaining: 0 } const remaining = [] let flushed = 0 for (const item of q) { try { const res = await dispatch(item) if (res && res.success === false) throw new Error(res.error || 'server returned failure') flushed++ } catch (err) { remaining.push(item) } } saveQueue(remaining) if (flushed > 0) console.log(`[sync] 队列 flush 完成:成功 ${flushed},剩余 ${remaining.length}`) return { flushed, remaining: remaining.length } } function getPendingCount() { return loadQueue().length } module.exports = { syncOrEnqueue, flush, getPendingCount }