Skip to content

Commit

Permalink
♻️ uid 直接读取数据库,优化渲染
Browse files Browse the repository at this point in the history
  • Loading branch information
BTMuli committed Aug 31, 2023
1 parent f842da0 commit 1bdc614
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 78 deletions.
45 changes: 34 additions & 11 deletions src/components/gachaRecord/gro-dataview.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<template>
<div v-if="!loading" class="gro-dv-container">
<div class="gro-dv-container">
<div class="gro-dvt-title">
<span>{{ title }}</span>
<span>{{ props.dataVal.length }}</span>
</div>
<div class="gro-dvt-subtitle">{{ startDate }} ~ {{ endDate }}</div>
<div class="gro-dvt-subtitle">
<span v-show="props.dataVal.length === 0">暂无数据</span>
<span v-show="props.dataVal.length !== 0">{{ startDate }} ~ {{ endDate }}</span>
</div>
<div class="gro-mid-list">
<div class="gro-ml-item">
<span>4☆已垫</span>
Expand Down Expand Up @@ -64,7 +67,7 @@
</template>
<script lang="ts" setup>
// vue
import { onMounted, ref } from "vue";
import { onMounted, ref, watch } from "vue";
interface GachaDataViewProps {
dataType: "new" | "avatar" | "weapon" | "normal";
Expand Down Expand Up @@ -147,24 +150,27 @@ function getTitle(type: "top" | "5" | "4" | "3"): string {
if (props.dataType === "normal") return "常驻祈愿";
return "";
} else if (type === "5") {
// 5星物品统计
return `${star5List.value.length} [${(star5List.value.length / props.dataVal.length).toFixed(
2,
)}%]`;
// 5星物品统计 00.00%
return `${star5List.value.length} [${((star5List.value.length * 100) / props.dataVal.length)
.toFixed(2)
.padStart(5, "0")}%]`;
} else if (type === "4") {
// 4星物品统计
return `${star4List.value.length} [${(star4List.value.length / props.dataVal.length).toFixed(
2,
)}%]`;
return `${star4List.value.length} [${((star4List.value.length * 100) / props.dataVal.length)
.toFixed(2)
.padStart(5, "0")}%]`;
} else {
// 3星物品统计
return `${star3count.value} [${(star3count.value / props.dataVal.length).toFixed(2)}%]`;
return `${star3count.value} [${((star3count.value * 100) / props.dataVal.length)
.toFixed(2)
.padStart(5, "0")}%]`;
}
}
// 获取5星平均抽数
function getStar5Avg(): string {
const resetList = star5List.value.map((item) => item.gachaCount);
if (resetList.length === 0) return "0";
const total = resetList.reduce((a, b) => a + b);
return (total / star5List.value.length).toFixed(2);
}
Expand All @@ -177,6 +183,23 @@ function getIcon(itemId: string, type: string): string {
return "/WIKI/weapon/icon/" + itemId + ".webp";
}
}
// 监听数据变化
watch(
() => props.dataVal,
(newVal) => {
star5List.value = [];
star4List.value = [];
reset5count.value = 0;
reset4count.value = 0;
star3count.value = 0;
startDate.value = "";
endDate.value = "";
star5avg.value = "";
tab.value = "5";
loadData();
},
);
</script>
<style lang="css" scoped>
.gro-dv-container {
Expand Down
39 changes: 27 additions & 12 deletions src/components/gachaRecord/gro-overview.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
<template>
<div class="gro-o-container">
<gro-dataview v-if="newData.length > 0" :data-val="newData" data-type="new" />
<gro-dataview :data-val="normalData" data-type="normal" />
<gro-dataview :data-val="avatarData" data-type="avatar" />
<gro-dataview :data-val="weaponData" data-type="weapon" />
<div
class="gro-o-container"
:style="{
gridTemplateColumns: newData.length !== 0 ? 'repeat(4, 1fr)' : 'repeat(3, 1fr)',
}"
>
<gro-dataview v-if="newData.length !== 0" v-model:data-val="newData" data-type="new" />
<gro-dataview v-model:data-val="normalData" data-type="normal" />
<gro-dataview v-model:data-val="avatarData" data-type="avatar" />
<gro-dataview v-model:data-val="weaponData" data-type="weapon" />
</div>
</template>
<script lang="ts" setup>
// vue
import { watch } from "vue";
import GroDataview from "./gro-dataview.vue";
interface GachaOverviewProps {
modelValue: TGApp.Sqlite.GachaRecords.SingleTable[];
}
const props = defineProps<GachaOverviewProps>();
// data
const newData = props.modelValue.filter((item) => item.uigfType === "100");
const normalData = props.modelValue.filter((item) => item.uigfType === "200");
const avatarData = props.modelValue.filter((item) => item.uigfType === "301");
const weaponData = props.modelValue.filter((item) => item.uigfType === "302");
const getColNum = newData.length === 0 ? 3 : 4;
let newData = props.modelValue.filter((item) => item.uigfType === "100");
let normalData = props.modelValue.filter((item) => item.uigfType === "200");
let avatarData = props.modelValue.filter((item) => item.uigfType === "301");
let weaponData = props.modelValue.filter((item) => item.uigfType === "302");
// 监听数据变化
watch(
() => props.modelValue,
(newVal) => {
newData = newVal.filter((item) => item.uigfType === "100");
normalData = newVal.filter((item) => item.uigfType === "200");
avatarData = newVal.filter((item) => item.uigfType === "301");
weaponData = newVal.filter((item) => item.uigfType === "302");
},
);
</script>
<style lang="css" scoped>
.gro-o-container {
display: grid;
width: 100%;
height: 100%;
grid-gap: 10px;
grid-template-columns: repeat(v-bind(getColNum), 1fr);
transition: all 0.3s ease-in-out;
}
</style>
124 changes: 69 additions & 55 deletions src/pages/User/Gacha.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
<ToLoading v-model="loading" :title="loadingTitle" />
<v-app-bar class="gacha-top-bar">
<template #prepend>
<v-app-bar-title>
<span>祈愿记录</span>
<span v-if="isLogin()"> - {{ user.nickname }} UID:{{ user.gameUid }}</span>
</v-app-bar-title>
<v-app-bar-title> 祈愿记录 </v-app-bar-title>
</template>
<template #default>
<v-select
v-model="uidCur"
class="gacha-top-select"
:items="selectItem"
variant="underlined"
/>
<v-spacer />
</template>
<v-spacer />
<template #append>
<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>
Expand All @@ -30,37 +35,42 @@
</template>
<script lang="ts" setup>
// vue
import { onMounted, ref } from "vue";
import { onMounted, ref, watch } from "vue";
import showSnackbar from "../../components/func/snackbar";
import showConfirm from "../../components/func/confirm";
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";
// store
import { useUserStore } from "../../store/modules/user";
// utils
import { exportUigfData, readUigfData, verifyUigfData } from "../../utils/UIGF";
import TGSqlite from "../../plugins/Sqlite";
// todo: 不读取用户数据,直接读取数据库,获取 uid 列表,然后根据 uid 获取祈愿数据
// store
const userStore = useUserStore();
// loading
const loading = ref<boolean>(true);
const loadingTitle = ref<string>();
// data
const user = userStore.getCurAccount();
const selectItem = ref<string[]>([]);
const uidCur = ref<string>("");
const gachaListCur = ref<TGApp.Sqlite.GachaRecords.SingleTable[]>([]);
const tab = ref<string>("");
onMounted(async () => {
loadingTitle.value = `正在获取用户 ${user.gameUid} 的祈愿数据`;
gachaListCur.value = await TGSqlite.getGachaRecords(user.gameUid);
loadingTitle.value = `正在获取祈愿 UID 列表`;
selectItem.value = await TGSqlite.getUidList();
if (selectItem.value.length === 0) {
showSnackbar({
color: "error",
text: `暂无祈愿数据,请先导入祈愿数据`,
});
loading.value = false;
return;
}
uidCur.value = selectItem.value[0];
loadingTitle.value = `正在获取祈愿数据,默认 UID:${uidCur.value}`;
gachaListCur.value = await TGSqlite.getGachaRecords(uidCur.value);
loadingTitle.value = `正在渲染数据`;
tab.value = "echarts";
loading.value = false;
Expand All @@ -69,11 +79,6 @@ onMounted(async () => {
});
});
// 判断用户是否登录
function isLogin(): boolean {
return user?.gameUid !== undefined;
}
// 导入按钮点击事件
async function handleImportBtn(): Promise<void> {
const selectedFile = await dialog.open({
Expand All @@ -95,38 +100,31 @@ async function handleImportBtn(): Promise<void> {
return;
}
const remoteData = await readUigfData(<string>selectedFile);
if (remoteData.info.uid !== user.gameUid) {
await showConfirm({
title: "UID 不匹配,是否继续导入?",
text: `当前 UID:${user.gameUid},导入 UID:${remoteData.info.uid}`,
const res = await showConfirm({
title: "是否导入祈愿数据?",
text: `UID:${remoteData.info.uid} 共 ${remoteData.list.length} 条数据`,
});
if (!res) {
showSnackbar({
color: "grey",
text: `已取消祈愿数据导入`,
});
return;
}
loadingTitle.value = "正在导入祈愿数据";
loading.value = true;
if (remoteData.list.length === 0) {
loading.value = false;
showSnackbar({
color: "error",
text: `导入的祈愿数据为空`,
});
} else {
const res = await showConfirm({
title: "是否导入祈愿数据?",
text: `UID:${remoteData.info.uid} 共 ${remoteData.list.length} 条数据`,
await TGSqlite.mergeUIGF(remoteData.info.uid, remoteData.list);
loading.value = false;
showSnackbar({
text: `成功导入 ${remoteData.list.length} 条祈愿数据`,
});
if (!res) {
showSnackbar({
color: "grey",
text: `已取消祈愿数据导入`,
});
return;
}
loadingTitle.value = "正在导入祈愿数据";
loading.value = true;
if (remoteData.list.length === 0) {
loading.value = false;
showSnackbar({
color: "error",
text: `导入的祈愿数据为空`,
});
} else {
await TGSqlite.mergeUIGF(user.gameUid, remoteData.list);
loading.value = false;
showSnackbar({
text: `成功导入 ${remoteData.list.length} 条祈愿数据`,
});
}
}
} else {
showSnackbar({
Expand All @@ -138,17 +136,17 @@ async function handleImportBtn(): Promise<void> {
// 导出按钮点击事件
async function handleExportBtn(): Promise<void> {
const gachaList = await TGSqlite.getGachaRecords(user.gameUid);
const gachaList = await TGSqlite.getGachaRecords(uidCur.value);
if (gachaList.length === 0) {
showSnackbar({
color: "error",
text: `用户 ${user.gameUid} 暂无祈愿数据`,
text: `UID ${uidCur.value} 暂无祈愿数据`,
});
return;
}
const res = await showConfirm({
title: `是否导出祈愿数据?`,
text: `UID:${user.gameUid},共 ${gachaList.length} 条数据`,
text: `UID:${uidCur.value},共 ${gachaList.length} 条数据`,
});
if (!res) {
showSnackbar({
Expand All @@ -158,7 +156,7 @@ async function handleExportBtn(): Promise<void> {
return;
}
const file = await dialog.save({
defaultPath: `UIGF_${user.gameUid}.json`,
defaultPath: `UIGF_${uidCur.value}.json`,
filters: [
{
name: `UIGF`,
Expand All @@ -175,20 +173,36 @@ async function handleExportBtn(): Promise<void> {
}
loadingTitle.value = "正在导出祈愿数据";
loading.value = true;
await exportUigfData(user.gameUid, gachaList, file);
await exportUigfData(uidCur.value, gachaList, file);
loading.value = false;
showSnackbar({
text: `祈愿数据已成功导出`,
});
}
// 监听 UID 变化
watch(uidCur, async (newUid) => {
gachaListCur.value = await TGSqlite.getGachaRecords(newUid);
showSnackbar({
text: `成功获取 ${gachaListCur.value.length} 条祈愿数据`,
});
});
</script>
<style lang="css" scoped>
.gacha-top-bar {
display: flex;
align-items: center;
justify-content: space-between;
background: rgb(0 0 0/50%);
color: #f4d8a8;
font-family: var(--font-title);
}
.gacha-top-select {
height: 60px;
margin-left: 20px;
}
.gacha-top-btn {
margin: 0 10px;
background: #393b40;
Expand Down
13 changes: 13 additions & 0 deletions src/plugins/Sqlite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,19 @@ class Sqlite {
return res;
}

/**
* @description 获取已有 uid 列表
* @since Alpha v0.2.0
* @returns {Promise<string[]>}
*/
public async getUidList(): Promise<string[]> {
const db = await Database.load(this.dbPath);
const sql = "SELECT DISTINCT uid FROM GachaRecords";
const res: Array<{ uid: string }> = await db.select(sql);
await db.close();
return res.map((item) => item.uid);
}

/**
* @description 获取指定 uid 的用户角色数据
* @since Alpha v0.2。3
Expand Down

0 comments on commit 1bdc614

Please sign in to comment.