♻️ 祈愿数据单独备份、恢复

This commit is contained in:
BTMuli
2023-09-01 09:39:14 +08:00
parent 1bdc614940
commit 09317afac6
4 changed files with 162 additions and 43 deletions

View File

@@ -149,6 +149,8 @@ function getTitle(type: "top" | "5" | "4" | "3"): string {
if (props.dataType === "weapon") return "武器祈愿";
if (props.dataType === "normal") return "常驻祈愿";
return "";
} else if (props.dataVal.length === 0) {
return "暂无数据";
} else if (type === "5") {
// 5星物品统计 00.00%
return `${star5List.value.length} [${((star5List.value.length * 100) / props.dataVal.length)

View File

@@ -2,7 +2,7 @@
<ToLoading v-model="loading" :title="loadingTitle" />
<v-app-bar class="gacha-top-bar">
<template #prepend>
<v-app-bar-title> 祈愿记录 </v-app-bar-title>
<v-app-bar-title> 祈愿记录</v-app-bar-title>
</template>
<template #default>
<v-select
@@ -14,7 +14,9 @@
<v-spacer />
</template>
<template #append>
<v-btn prepend-icon="mdi-import" class="gacha-top-btn" @click="handleImportBtn"> 导入</v-btn>
<v-btn prepend-icon="mdi-import" class="gacha-top-btn" @click="handleImportBtn()">
导入
</v-btn>
<v-btn prepend-icon="mdi-export" class="gacha-top-btn" @click="handleExportBtn"> 导出</v-btn>
</template>
</v-app-bar>
@@ -22,6 +24,20 @@
<v-tabs v-model="tab" align-tabs="start" class="gacha-tab" direction="vertical">
<v-tab value="echarts">图表概览</v-tab>
<v-tab value="overview">数据概览</v-tab>
<div class="gacha-tab-bottom">
<v-btn class="gacha-tab-btn" variant="outlined" @click="backupGacha">
<v-icon>mdi-cloud-download</v-icon>
<span>备份</span>
</v-btn>
<v-btn class="gacha-tab-btn" variant="outlined" @click="deleteGacha">
<v-icon>mdi-delete</v-icon>
<span>删除</span>
</v-btn>
<v-btn class="gacha-tab-btn" variant="outlined" @click="restoreGacha">
<v-icon>mdi-cloud-upload</v-icon>
<span>恢复</span>
</v-btn>
</div>
</v-tabs>
<v-window v-model="tab" class="gacha-window">
<v-window-item value="echarts" class="gacha-window-item">
@@ -42,9 +58,9 @@ import ToLoading from "../../components/overlay/to-loading.vue";
import GroEcharts from "../../components/gachaRecord/gro-echarts.vue";
import GroOverview from "../../components/gachaRecord/gro-overview.vue";
// tauri
import { dialog } from "@tauri-apps/api";
import { dialog, path } from "@tauri-apps/api";
// utils
import { exportUigfData, readUigfData, verifyUigfData } from "../../utils/UIGF";
import { backupUigfData, exportUigfData, readUigfData, verifyUigfData } from "../../utils/UIGF";
import TGSqlite from "../../plugins/Sqlite";
// loading
@@ -80,16 +96,30 @@ onMounted(async () => {
});
// 导入按钮点击事件
async function handleImportBtn(): Promise<void> {
const selectedFile = await dialog.open({
multiple: false,
filters: [
{
name: "UIGF",
extensions: ["json"],
},
],
});
async function handleImportBtn(savePath?: string): Promise<void> {
let selectedFile;
if (savePath) {
selectedFile = await dialog.open({
multiple: false,
filters: [
{
name: "UIGF",
extensions: ["json"],
},
],
defaultPath: savePath,
});
} else {
selectedFile = await dialog.open({
multiple: false,
filters: [
{
name: "UIGF",
extensions: ["json"],
},
],
});
}
if (selectedFile) {
const check = await verifyUigfData(<string>selectedFile);
if (!check) {
@@ -125,6 +155,9 @@ async function handleImportBtn(): Promise<void> {
showSnackbar({
text: `成功导入 ${remoteData.list.length} 条祈愿数据`,
});
setTimeout(() => {
window.location.reload();
}, 1000);
}
} else {
showSnackbar({
@@ -180,6 +213,88 @@ async function handleExportBtn(): Promise<void> {
});
}
// 恢复UID祈愿数据相当于导入祈愿数据不过目录固定
async function restoreGacha(): Promise<void> {
const backupPath = `${await path.appLocalDataDir()}userData`;
await handleImportBtn(backupPath);
}
// 备份当前 UID 的祈愿数据
async function backupGacha(): Promise<void> {
if (gachaListCur.value.length === 0) {
showSnackbar({
color: "error",
text: `暂无祈愿数据`,
});
return;
}
const res = await showConfirm({
title: `是否备份祈愿数据?`,
text: `UID${uidCur.value},共 ${gachaListCur.value.length} 条数据`,
});
if (!res) {
showSnackbar({
color: "grey",
text: `已取消祈愿数据备份`,
});
return;
}
loadingTitle.value = "正在备份祈愿数据";
loading.value = true;
await backupUigfData(uidCur.value, gachaListCur.value);
loading.value = false;
showSnackbar({
text: `已成功备份 ${uidCur.value} 的祈愿数据`,
});
}
// 删除当前 UID 的祈愿数据
async function deleteGacha(): Promise<void> {
if (gachaListCur.value.length === 0) {
showSnackbar({
color: "error",
text: `暂无祈愿数据`,
});
return;
}
const firstConfirm = await showConfirm({
title: `是否删除祈愿数据?`,
text: `UID${uidCur.value},共 ${gachaListCur.value.length} 条数据`,
});
if (!firstConfirm) {
showSnackbar({
color: "grey",
text: `已取消祈愿数据删除`,
});
return;
}
const uidList = await TGSqlite.getUidList();
let secondConfirm: string | boolean = "";
if (uidList.length <= 1) {
secondConfirm = await showConfirm({
title: "删除后数据库将为空,确定删除?",
text: `UID${uidCur.value},共 ${gachaListCur.value.length} 条数据`,
});
}
if (secondConfirm === false) {
showSnackbar({
color: "grey",
text: `已取消祈愿数据删除`,
});
return;
}
loadingTitle.value = `正在删除${uidCur.value}的祈愿数据`;
loading.value = true;
await TGSqlite.deleteGachaRecords(uidCur.value);
loading.value = false;
showSnackbar({
text: `已成功删除 ${uidCur.value} 的祈愿数据`,
});
setTimeout(() => {
window.location.reload();
}, 1000);
}
// 监听 UID 变化
watch(uidCur, async (newUid) => {
gachaListCur.value = await TGSqlite.getGachaRecords(newUid);
@@ -225,6 +340,21 @@ watch(uidCur, async (newUid) => {
font-family: var(--font-title);
}
.gacha-tab-bottom {
position: absolute;
bottom: 0;
display: flex;
width: 100%;
flex-direction: column;
padding: 10px;
gap: 15px;
}
.gacha-tab-btn {
background: var(--common-shadow-t-2);
color: var(--common-text-content);
}
.gacha-window {
width: 100%;
height: 100%;

View File

@@ -196,7 +196,6 @@ import { useAchievementsStore } from "../../store/modules/achievements";
import { useUserStore } from "../../store/modules/user";
// utils
import { backupUiafData, restoreUiafData } from "../../utils/UIAF";
import { backupUigfData, restoreUigfData } from "../../utils/UIGF";
import { backupAbyssData, backupCookieData } from "../../web/utils/backupData";
import { restoreAbyssData, restoreCookieData } from "../../web/utils/restoreData";
import TGSqlite from "../../plugins/Sqlite";
@@ -354,7 +353,7 @@ async function confirmRefreshUser(): Promise<void> {
async function confirmBackup(): Promise<void> {
const res = await showConfirm({
title: "确认备份数据吗?",
text: "若已备份将会被覆盖",
text: "若已备份将会被覆盖,祈愿数据备份请到对应页面执行",
});
if (!res) {
showSnackbar({
@@ -377,15 +376,6 @@ async function confirmBackup(): Promise<void> {
const abyss = await TGSqlite.getAbyss();
loadingSub.value = "正在备份深渊数据";
await backupAbyssData(abyss);
if (userInfo.value.uid === "-1") {
loadingSub.value = "用户未登录,跳过祈愿数据备份";
} else {
loadingSub.value = "正在获取祈愿数据";
const gameUid = userStore.getCurAccount().gameUid;
const gacha = await TGSqlite.getGachaRecords(gameUid);
loadingSub.value = "正在备份祈愿数据";
await backupUigfData(gameUid, gacha);
}
loadingSub.value = "";
loading.value = false;
showSnackbar({ text: "数据已备份!" });
@@ -395,7 +385,7 @@ async function confirmBackup(): Promise<void> {
async function confirmRestore(): Promise<void> {
const resConfirm = await showConfirm({
title: "确认恢复数据吗?",
text: "请确保存在备份数据",
text: "请确保存在备份数据,祈愿数据恢复请到对应页面执行",
});
if (!resConfirm) {
showSnackbar({
@@ -423,22 +413,6 @@ async function confirmRestore(): Promise<void> {
if (!res) {
fail.push("深渊数据");
}
if (userInfo.value.uid === "-1") {
showSnackbar({
color: "grey",
text: "用户未登录,跳过祈愿数据恢复",
});
await new Promise(() => {
setTimeout(() => {}, 1500);
});
} else {
loadingSub.value = "正在恢复祈愿数据";
const gameUid = userStore.getCurAccount().gameUid;
res = await restoreUigfData(gameUid);
if (!res) {
fail.push("祈愿数据");
}
}
fail.length > 0
? showSnackbar({ text: `${fail.join("、")} 恢复失败!`, color: "error" })
: showSnackbar({ text: "数据已恢复!" });

View File

@@ -2,7 +2,7 @@
* @file plugins Sqlite index.ts
* @description Sqlite 数据库操作类
* @author BTMuli<bt-muli@outlook.com>
* @since Alpha v0.2.3
* @since Beta v0.3.0
*/
// tauri
@@ -497,6 +497,19 @@ class Sqlite {
return res;
}
/**
* @description 删除指定 uid 的祈愿数据
* @since Beta v0.3.0
* @param {string} uid 用户 uid
* @returns {Promise<void>}
*/
public async deleteGachaRecords(uid: string): Promise<void> {
const db = await Database.load(this.dbPath);
const sql = `DELETE FROM GachaRecords WHERE uid = '${uid}'`;
await db.execute(sql);
await db.close();
}
/**
* @description 合并祈愿数据
* @since Alpha v0.2.3