fix(data): 覆盖式导入与快照恢复前自动备份
- importJson / restoreSnapshot 覆盖前先写一份当前数据快照,误操作可回退 - 导入校验增加 id 唯一性检查,宽容读取路径保留首条 - 快照索引对同一时间点的重复写入去重 - 落盘失败时翻转 persistent,恢复后自动撤除告警 - 备份面板提示导入前数据已自动备份
This commit is contained in:
@@ -118,6 +118,7 @@ describe('BackupPanel 导入', () => {
|
||||
|
||||
expect(store.tasks.map((task) => task.title).sort()).toEqual(['新任务一', '新任务二'])
|
||||
expect(wrapper.text()).toContain('已从 backup.json 导入 2 个任务')
|
||||
expect(wrapper.text()).toContain('导入前的数据已自动备份')
|
||||
})
|
||||
|
||||
it('取消确认后数据保持不变', async () => {
|
||||
|
||||
@@ -59,9 +59,13 @@ function confirmImport(): void {
|
||||
const target = pending.value
|
||||
if (!target) return
|
||||
|
||||
// 记录导入前的数量,用于提示「旧数据已自动备份」是否真的发生了
|
||||
const beforeCount = store.tasks.length
|
||||
|
||||
try {
|
||||
const count = store.importJson(target.text)
|
||||
message.value = `已从 ${target.fileName} 导入 ${count} 个任务`
|
||||
const backupNote = beforeCount > 0 ? ',导入前的数据已自动备份' : ''
|
||||
message.value = `已从 ${target.fileName} 导入 ${count} 个任务${backupNote}`
|
||||
error.value = null
|
||||
} catch (cause) {
|
||||
error.value = cause instanceof Error ? cause.message : '导入失败'
|
||||
@@ -71,9 +75,12 @@ function confirmImport(): void {
|
||||
}
|
||||
|
||||
function restore(key: string): void {
|
||||
const beforeCount = store.tasks.length
|
||||
try {
|
||||
const count = store.restoreSnapshot(key)
|
||||
message.value = count > 0 ? `已从备份恢复 ${count} 个任务` : '该备份是空的,未做改动'
|
||||
const backupNote = beforeCount > 0 ? ',恢复前的数据已自动备份' : ''
|
||||
message.value =
|
||||
count > 0 ? `已从备份恢复 ${count} 个任务${backupNote}` : '该备份是空的,未做改动'
|
||||
error.value = null
|
||||
} catch (cause) {
|
||||
error.value = cause instanceof Error ? cause.message : '恢复失败'
|
||||
@@ -137,7 +144,8 @@ function formatTime(iso: string): string {
|
||||
>
|
||||
<p class="text-sm text-amber-900 dark:text-amber-200">
|
||||
将从「{{ pending.fileName }}」导入 {{ pending.count }} 个任务,
|
||||
<strong>并覆盖当前全部 {{ store.tasks.length }} 个任务</strong>。此操作不可撤销。
|
||||
<strong>并覆盖当前全部 {{ store.tasks.length }} 个任务</strong>。 覆盖前会自动把当前数据
|
||||
存一份到下方「自动备份」,选错文件也能从那里恢复。
|
||||
</p>
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user