diff --git a/index.html b/index.html
index de526cd..314c019 100644
--- a/index.html
+++ b/index.html
@@ -768,6 +768,7 @@
@@ -1695,7 +1757,7 @@ createApp({
// ===== 云端同步(离线优先:本地 localStorage 仍是唯一真相,同步只是额外把数据推到服务器)=====
const sync = reactive({
status: 'idle', user: null, pending: 0, lastSyncAt: null, lastError: '',
- serverUsers: null, apiBase: '', busy: false
+ serverUsers: null, apiBase: '', busy: false, hold: null
});
const syncPanelOpen = ref(false);
const loginForm = ref({ username: '', password: '' });
@@ -1743,21 +1805,27 @@ createApp({
return rows;
});
- const syncStatusText = computed(() => ({
- idle: '未登录·仅存本机',
- ready: sync.pending > 0 ? `待上传 ${sync.pending} 项` : '已同步',
- syncing: '同步中…',
- offline: '连不上服务器·本地照常用',
- error: '同步出错'
- })[sync.status] || sync.status);
+ const syncStatusText = computed(() => {
+ if (sync.hold) return '有冲突·已暂停同步';
+ return ({
+ idle: '未登录·仅存本机',
+ ready: sync.pending > 0 ? `待上传 ${sync.pending} 项` : '已同步',
+ syncing: '同步中…',
+ offline: '连不上服务器·本地照常用',
+ error: '同步出错'
+ })[sync.status] || sync.status;
+ });
- const syncStatusClass = computed(() => ({
- idle: 'text-slate-500 bg-slate-100',
- ready: sync.pending > 0 ? 'text-amber-700 bg-amber-100' : 'text-emerald-700 bg-emerald-100',
- syncing: 'text-indigo-700 bg-indigo-100',
- offline: 'text-amber-700 bg-amber-100',
- error: 'text-rose-700 bg-rose-100'
- })[sync.status] || 'text-slate-500 bg-slate-100');
+ const syncStatusClass = computed(() => {
+ if (sync.hold) return 'text-amber-700 bg-amber-100';
+ return ({
+ idle: 'text-slate-500 bg-slate-100',
+ ready: sync.pending > 0 ? 'text-amber-700 bg-amber-100' : 'text-emerald-700 bg-emerald-100',
+ syncing: 'text-indigo-700 bg-indigo-100',
+ offline: 'text-amber-700 bg-amber-100',
+ error: 'text-rose-700 bg-rose-100'
+ })[sync.status] || 'text-slate-500 bg-slate-100';
+ });
const syncTimeText = computed(() => {
if (!sync.lastSyncAt) return '';
@@ -1837,6 +1905,7 @@ createApp({
async function runMerge(diff, winner) {
// 合并前留一份本机快照。远端值落地是不可逆的,出意外至少数据还在。
window.WHTSync.snapshotLocal('login-merge-' + winner);
+ window.WHTSync.releaseSync(); // 用户已拍板,解除同步冻结
const excludeRecords = winner === 'remote' ? diff.conflict : [];
const excludeAdjust = winner === 'remote' ? diff.adjustConflict : [];
@@ -1865,10 +1934,13 @@ createApp({
mergeInfo.value = null;
});
- // 先不合并:保持登录但不动任何数据。同步面板会留一个入口重新进来。
+ // 先不合并:保持登录但冻结自动同步。
+ // 必须冻结 —— 否则下一次改动触发的 syncNow 会把远端值静默盖到本机冲突日上,
+ // 用户看到的就是「我选了不处理,数据却自己变了」。
const deferMerge = () => {
mergeOpen.value = false;
- showToast('已跳过合并,本机数据未改动');
+ window.WHTSync.holdSync('login-conflict');
+ showToast('已暂停自动同步,本机数据未改动');
};
const reopenMerge = () => withBusy(async () => {
@@ -1946,6 +2018,7 @@ createApp({
sync.lastSyncAt = s.lastSyncAt;
sync.lastError = s.lastError;
sync.serverUsers = s.serverUsers;
+ sync.hold = s.hold;
});
sync.apiBase = window.WHTSync.getApiBase() === location.origin ? '' : window.WHTSync.getApiBase();
// 探一下服务端在不在、有没有账号,决定设置页该显示「创建账号」还是「登录」