import { getPendingSyncRecords, markRecordSynced, cleanOldRecords } from './db'; import { deleteLocalImage } from './fs'; import { uploadImage, submitRecord } from '../api/mock'; let isSyncing = false; /** * 启动离线数据同步队列 * 核心逻辑: * 1. 查询所有未同步的数据 * 2. 如果有图片路径,先上传图片获取云端 URL * 3. 提交完整业务数据到后端 * 4. 成功后:将数据库记录置为已同步,并删除本地沙盒图片释放内存 */ export const startSyncQueue = async () => { if (isSyncing) return; // 简单判断当前网络是否可用 const networkType = await new Promise(resolve => { uni.getNetworkType({ success: (res) => resolve(res.networkType) }); }); if (networkType === 'none') { console.log('[Sync] 当前无网络,取消同步'); return; } isSyncing = true; console.log('[Sync] 开始执行同步队列...'); try { const pendingRecords = await getPendingSyncRecords(); if (pendingRecords.length === 0) { console.log('[Sync] 无待同步记录'); isSyncing = false; return; } for (let record of pendingRecords) { try { let payload = record.payload; // 1. 如果存在本地图片,先上传图片 if (record.local_img_path) { const uploadRes = await uploadImage(record.local_img_path); if (uploadRes && uploadRes.code === 200) { // 将云端 URL 赋值给业务 payload payload.cloudImageUrl = uploadRes.url; } else { throw new Error('图片上传失败'); } } // 2. 提交业务数据 const submitRes = await submitRecord(payload); if (submitRes && submitRes.code === 200) { // 3. 提交成功后:标记数据库状态 await markRecordSynced(record.id); // 4. 最重要:删除本地沙盒图片,释放 4G 设备的有限空间 if (record.local_img_path) { await deleteLocalImage(record.local_img_path); } console.log(`[Sync] 记录 ${record.id} 同步成功并已清理本地文件`); } else { throw new Error('业务数据提交失败'); } } catch (err) { console.error(`[Sync] 记录 ${record.id} 同步遇到错误,跳过等下次:`, err); // 单条失败不阻断循环,继续下一条 } } } catch (err) { console.error('[Sync] 同步队列执行异常:', err); } finally { isSyncing = false; // 如果一次同步了 20 条,可能还有,可以再次触发 } }; /** * 每日凌晨或空闲时清理超期废弃数据 */ export const runDailyCleanup = () => { console.log('[Sync] 执行超期数据清理...'); cleanOldRecords().catch(err => { console.error('[Sync] 清理失败:', err); }); };