mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
✨ feat(backup): 成就数据备份
This commit is contained in:
@@ -113,7 +113,7 @@ import { useAchievementsStore } from "../store/modules/achievements";
|
||||
import { TGAppData } from "../data";
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
import { ReadAllTGData, ReadTGDataByIndex, ReadTGDataByKey, UpdateTGDataByKey } from "../utils/TGIndex";
|
||||
import { getUiafHeader, readUiafData, verifyUiafData } from "../utils/UIAF";
|
||||
import { getUiafHeader, getUiafStatus, readUiafData, verifyUiafData, backupUiafData, timestampToDate } from "../utils/UIAF";
|
||||
|
||||
// Store
|
||||
const achievementsStore = useAchievementsStore();
|
||||
@@ -266,14 +266,7 @@ async function importJson () {
|
||||
const localTime = localData.completed_time;
|
||||
// 如果本地数据不存在,或者本地数据的 timeStamp 小于远程数据的 timeStamp,更新数据
|
||||
if (data.timestamp !== 0) {
|
||||
const finishTime = new Date(data.timestamp * 1000).toLocaleString("zh", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
});
|
||||
const finishTime = timestampToDate(data.timestamp);
|
||||
if (finishTime !== localTime || localData.progress !== data.current) {
|
||||
// eslint-disable-next-line camelcase
|
||||
localData.completed_time = finishTime;
|
||||
@@ -307,6 +300,8 @@ async function importJson () {
|
||||
await UpdateTGDataByKey("AchievementSeries", data);
|
||||
}),
|
||||
);
|
||||
loadingTitle.value = "正在备份数据";
|
||||
await backupAchievementData();
|
||||
loadingTitle.value = "正在刷新数据";
|
||||
seriesDB = await ReadAllTGData("AchievementSeries");
|
||||
const finishAchievments = seriesDB.reduce((a, b) => {
|
||||
@@ -321,6 +316,13 @@ async function importJson () {
|
||||
selectedIndex.value = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 备份成就数据
|
||||
async function backupAchievementData () {
|
||||
const achievements = await ReadAllTGData("Achievements");
|
||||
await backupUiafData(achievements);
|
||||
}
|
||||
|
||||
// 导出
|
||||
async function exportJson () {
|
||||
// 判断是否有数据
|
||||
@@ -340,24 +342,11 @@ async function exportJson () {
|
||||
};
|
||||
// 转换数据
|
||||
UiafData.list = achievements.map((data) => {
|
||||
let status;
|
||||
// 计算点数但是没有完成
|
||||
if (data.progress !== 0 && data.completed === false) {
|
||||
status = 1;
|
||||
// 已完成且未计算点数
|
||||
} else if (data.progress === 0 && data.completed === true) {
|
||||
status = 2;
|
||||
// 已完成且已计算点数
|
||||
} else if (data.progress !== 0 && data.completed === true) {
|
||||
status = 3;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
return {
|
||||
id: data.id,
|
||||
timestamp: data.completed ? Math.round(new Date(data.completed_time).getTime() / 1000) : 0,
|
||||
timestamp: data.completed && data.completed_time ? Math.round(new Date(data.completed_time).getTime() / 1000) : 0,
|
||||
current: data.progress,
|
||||
status,
|
||||
status: getUiafStatus(data.completed, data.progress),
|
||||
};
|
||||
});
|
||||
const isSave = await dialog.save({
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
设置
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item prepend-icon="mdi-folder" title="打开用户数据目录" @click="openMergeData" />
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据备份" @click="tryConfirm('backup')" />
|
||||
<v-list-item prepend-icon="mdi-content-save" title="数据恢复" @click="tryConfirm('restore')" />
|
||||
<v-list-item prepend-icon="mdi-delete" title="清除用户缓存" @click="tryConfirm('delUser')" />
|
||||
<v-list-item prepend-icon="mdi-delete" title="清除临时数据" @click="tryConfirm('delTemp')" />
|
||||
<v-list-item prepend-icon="mdi-cog" title="恢复默认设置" @click="tryConfirm('delApp')" />
|
||||
@@ -120,8 +121,8 @@
|
||||
</v-list-subheader>
|
||||
<v-divider inset class="border-opacity-75" />
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地应用数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.appDataDir }}</v-list-item-subtitle>
|
||||
<v-list-item-title>本地临时数据路径</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ appStore.dataPath.tempDataDir }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item prepend-icon="mdi-folder">
|
||||
<v-list-item-title>本地用户数据路径</v-list-item-title>
|
||||
@@ -145,14 +146,15 @@ import { getBuildTime } from "../utils/TGBuild";
|
||||
import TLoading from "../components/t-loading.vue";
|
||||
import TConfirm from "../components/t-confirm.vue";
|
||||
// tauri
|
||||
import { dialog, fs, app, os, tauri } from "@tauri-apps/api";
|
||||
import { fs, app, os, tauri } from "@tauri-apps/api";
|
||||
// store
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
import { useHomeStore } from "../store/modules/home";
|
||||
import { useHk4eStore } from "../store/modules/hk4e";
|
||||
import { useAchievementsStore } from "../store/modules/achievements";
|
||||
// utils
|
||||
import { WriteTGData, DeleteTGData } from "../utils/TGIndex";
|
||||
import { WriteTGData, DeleteTGData, ReadAllTGData } from "../utils/TGIndex";
|
||||
import { backupUiafData, restoreUiafData } from "../utils/UIAF";
|
||||
// data
|
||||
import { getDataList } from "../data/init";
|
||||
|
||||
@@ -203,17 +205,19 @@ function toOuter (url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
// 打开用户数据目录
|
||||
async function openMergeData () {
|
||||
await dialog.open({
|
||||
defaultPath: appStore.dataPath.userDataDir,
|
||||
filters: [],
|
||||
});
|
||||
}
|
||||
|
||||
// open confirm
|
||||
function tryConfirm (oper: string) {
|
||||
switch (oper) {
|
||||
case "backup":
|
||||
confirmText.value = "确认备份数据吗?";
|
||||
confirmOper.value = "backup";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "restore":
|
||||
confirmText.value = "确认恢复数据吗?";
|
||||
confirmOper.value = "restore";
|
||||
confirmShow.value = true;
|
||||
break;
|
||||
case "delTemp":
|
||||
confirmText.value = "确认清除临时数据吗?";
|
||||
confirmOper.value = "delTemp";
|
||||
@@ -250,6 +254,12 @@ function tryConfirm (oper: string) {
|
||||
// transfer confirm oper
|
||||
async function doConfirm (oper: string) {
|
||||
switch (oper) {
|
||||
case "backup":
|
||||
await backupData();
|
||||
break;
|
||||
case "restore":
|
||||
await restoreData();
|
||||
break;
|
||||
case "delTemp":
|
||||
await delTempData();
|
||||
break;
|
||||
@@ -275,6 +285,28 @@ async function doConfirm (oper: string) {
|
||||
}
|
||||
|
||||
// confirmOper
|
||||
async function backupData () {
|
||||
const achievements = await ReadAllTGData("achievements");
|
||||
await backupUiafData(achievements);
|
||||
snackbarText.value = "数据已备份!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
}
|
||||
|
||||
async function restoreData () {
|
||||
const res = await restoreUiafData();
|
||||
if (res !== false) {
|
||||
achievementsStore.flushData(res.total, res.completed);
|
||||
snackbarText.value = "数据已恢复!";
|
||||
snackbarColor.value = "success";
|
||||
snackbar.value = true;
|
||||
} else {
|
||||
snackbarText.value = "未检测到备份数据!";
|
||||
snackbarColor.value = "error";
|
||||
snackbar.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
async function delTempData () {
|
||||
await fs.removeDir("tempData", {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
@@ -290,10 +322,6 @@ async function delUserData () {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
recursive: true,
|
||||
});
|
||||
await fs.removeDir("tempData", {
|
||||
dir: fs.BaseDirectory.AppLocalData,
|
||||
recursive: true,
|
||||
});
|
||||
getDataList.map(async (item) => {
|
||||
await WriteTGData(item.name, item.data);
|
||||
});
|
||||
@@ -301,7 +329,6 @@ async function delUserData () {
|
||||
snackbar.value = true;
|
||||
achievementsStore.init();
|
||||
await fs.createDir("userData", { dir: fs.BaseDirectory.AppLocalData });
|
||||
await fs.createDir("tempData", { dir: fs.BaseDirectory.AppLocalData });
|
||||
}
|
||||
|
||||
// 恢复默认配置
|
||||
@@ -309,7 +336,7 @@ function initAppData () {
|
||||
appStore.init();
|
||||
homeStore.init();
|
||||
achievementsStore.init();
|
||||
snackbarText.value = "已恢复默认配置!";
|
||||
snackbarText.value = "已恢复默认配置!即将刷新页面...";
|
||||
snackbar.value = true;
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
|
||||
Reference in New Issue
Block a user