mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
@@ -1,21 +1,18 @@
|
||||
<template>
|
||||
<div v-if="!props.modelValue">暂无数据</div>
|
||||
<div v-if="props.modelValue.length === 0">暂无数据</div>
|
||||
<div v-else class="tur-ag-box">
|
||||
<TibUrAvatar v-for="avatar in data" :key="avatar.id" :model-value="avatar" />
|
||||
<TibUrAvatar v-for="avatar in props.modelValue" :key="avatar.id" :model-value="avatar" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
|
||||
import TibUrAvatar from "../itembox/tib-ur-avatar.vue";
|
||||
|
||||
interface TurAvatarGridProps {
|
||||
modelValue?: string;
|
||||
modelValue: TGApp.Sqlite.Record.Avatar[];
|
||||
}
|
||||
|
||||
const props = defineProps<TurAvatarGridProps>();
|
||||
const data = computed<TGApp.Sqlite.Record.Avatar[]>(() => JSON.parse(<string>props.modelValue));
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-ag-box {
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
<template>
|
||||
<div v-if="!props.modelValue">暂无数据</div>
|
||||
<div v-if="props.modelValue.length === 0">暂无数据</div>
|
||||
<div v-else class="tur-hg-box">
|
||||
<TurHomeSub v-for="(home, index) in homes" :key="index" :data="home" />
|
||||
<TurHomeSub v-for="(home, index) in props.modelValue" :key="index" :data="home" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
|
||||
import TurHomeSub from "./tur-home-sub.vue";
|
||||
|
||||
interface TurHomeGridProps {
|
||||
modelValue?: string;
|
||||
modelValue: TGApp.Sqlite.Record.Home[];
|
||||
}
|
||||
|
||||
const props = defineProps<TurHomeGridProps>();
|
||||
const homes = computed<TGApp.Sqlite.Record.Home[]>(() => {
|
||||
const res = JSON.parse(props.modelValue ?? "[]");
|
||||
if (res.length > 0) {
|
||||
return res;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-hg-box {
|
||||
|
||||
@@ -2,22 +2,34 @@
|
||||
<div v-if="!props.modelValue">暂无数据</div>
|
||||
<div v-else>
|
||||
<div class="tur-og-box-3">
|
||||
<TurOverviewSub title="活跃天数" :text="data.activeDays" icon="/source/UI/userRecord.webp" />
|
||||
<TurOverviewSub title="深境螺旋" :text="data.sprialAbyss" icon="/source/UI/userAbyss.webp" />
|
||||
<TurOverviewSub title="幻想真境剧诗" :text="data.combatRole" icon="/icon/material/201.webp" />
|
||||
<TurOverviewSub
|
||||
title="活跃天数"
|
||||
:text="props.modelValue.activeDays"
|
||||
icon="/source/UI/userRecord.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="深境螺旋"
|
||||
:text="props.modelValue.sprialAbyss"
|
||||
icon="/source/UI/userAbyss.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="幻想真境剧诗"
|
||||
:text="props.modelValue.combatRole"
|
||||
icon="/icon/material/201.webp"
|
||||
/>
|
||||
</div>
|
||||
<div class="tur-og-box">
|
||||
<TurOverviewSub
|
||||
title="获得角色数"
|
||||
:text="data.avatarNumber"
|
||||
:text="props.modelValue.avatarNumber"
|
||||
icon="/source/UI/userAvatar.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="满好感角色数"
|
||||
:text="data.avatarFetter"
|
||||
:text="props.modelValue.avatarFetter"
|
||||
icon="/icon/material/105.webp"
|
||||
/>
|
||||
<TurOverviewSub title="成就达成数" :text="data.achievementNumber" icon="icon">
|
||||
<TurOverviewSub title="成就达成数" :text="props.modelValue.achievementNumber" icon="icon">
|
||||
<template #icon>
|
||||
<img
|
||||
src="../../assets/icons/achievements.svg"
|
||||
@@ -27,33 +39,58 @@
|
||||
/>
|
||||
</template>
|
||||
</TurOverviewSub>
|
||||
<TurOverviewSub title="解锁传送点" :text="data.wayPoints" icon="/icon/material/220005.webp" />
|
||||
<TurOverviewSub title="解锁秘境" :text="data.domainNumber" />
|
||||
<TurOverviewSub title="火神瞳" :text="data.pyroCulus" icon="/icon/material/107028.webp" />
|
||||
<TurOverviewSub title="风神瞳" :text="data.anemoCulus" icon="/icon/material/107001.webp" />
|
||||
<TurOverviewSub title="岩神瞳" :text="data.geoCulus" icon="/icon/material/107003.webp" />
|
||||
<TurOverviewSub title="雷神瞳" :text="data.electroCulus" icon="/icon/material/107014.webp" />
|
||||
<TurOverviewSub title="草神瞳" :text="data.dendroCulus" icon="/icon/material/107017.webp" />
|
||||
<TurOverviewSub title="水神瞳" :text="data.hydroCulus" icon="/icon/material/107023.webp" />
|
||||
<TurOverviewSub title="华丽宝箱数" :text="data.luxuriousChest" />
|
||||
<TurOverviewSub title="珍贵宝箱数" :text="data.preciousChest" />
|
||||
<TurOverviewSub title="精致宝箱数" :text="data.exquisiteChest" />
|
||||
<TurOverviewSub title="普通宝箱数" :text="data.commonChest" />
|
||||
<TurOverviewSub title="奇馈宝箱数" :text="data.magicChest" />
|
||||
<TurOverviewSub
|
||||
title="解锁传送点"
|
||||
:text="props.modelValue.wayPoints"
|
||||
icon="/icon/material/220005.webp"
|
||||
/>
|
||||
<TurOverviewSub title="解锁秘境" :text="props.modelValue.domainNumber" />
|
||||
<TurOverviewSub
|
||||
title="火神瞳"
|
||||
:text="props.modelValue.pyroCulus"
|
||||
icon="/icon/material/107028.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="风神瞳"
|
||||
:text="props.modelValue.anemoCulus"
|
||||
icon="/icon/material/107001.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="岩神瞳"
|
||||
:text="props.modelValue.geoCulus"
|
||||
icon="/icon/material/107003.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="雷神瞳"
|
||||
:text="props.modelValue.electroCulus"
|
||||
icon="/icon/material/107014.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="草神瞳"
|
||||
:text="props.modelValue.dendroCulus"
|
||||
icon="/icon/material/107017.webp"
|
||||
/>
|
||||
<TurOverviewSub
|
||||
title="水神瞳"
|
||||
:text="props.modelValue.hydroCulus"
|
||||
icon="/icon/material/107023.webp"
|
||||
/>
|
||||
<TurOverviewSub title="华丽宝箱数" :text="props.modelValue.luxuriousChest" />
|
||||
<TurOverviewSub title="珍贵宝箱数" :text="props.modelValue.preciousChest" />
|
||||
<TurOverviewSub title="精致宝箱数" :text="props.modelValue.exquisiteChest" />
|
||||
<TurOverviewSub title="普通宝箱数" :text="props.modelValue.commonChest" />
|
||||
<TurOverviewSub title="奇馈宝箱数" :text="props.modelValue.magicChest" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
|
||||
import TurOverviewSub from "./tur-overview-sub.vue";
|
||||
|
||||
interface TurOverviewGridProps {
|
||||
modelValue?: string;
|
||||
modelValue: TGApp.Sqlite.Record.Stats;
|
||||
}
|
||||
|
||||
const props = defineProps<TurOverviewGridProps>();
|
||||
const data = computed<TGApp.Sqlite.Record.Stats>(() => JSON.parse(<string>props.modelValue));
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-og-box {
|
||||
|
||||
91
src/components/userRecord/tur-role-info.vue
Normal file
91
src/components/userRecord/tur-role-info.vue
Normal file
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="tur-ri-box">
|
||||
<div class="tur-ri-avatar">
|
||||
<img alt="avatar" :src="props.modelValue.avatar" />
|
||||
</div>
|
||||
<div class="tur-ri-content">
|
||||
<div class="tur-ri-title">
|
||||
<span>{{ props.modelValue.nickname }}</span>
|
||||
<span>{{ props.modelValue.level }}</span>
|
||||
</div>
|
||||
<div class="tur-ri-subtitle">
|
||||
<span>UID:{{ props.uid }}</span>
|
||||
<span>({{ props.modelValue.region }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
interface TurRoleInfoProps {
|
||||
uid: number;
|
||||
modelValue: TGApp.Sqlite.Record.Role;
|
||||
}
|
||||
|
||||
const props = defineProps<TurRoleInfoProps>();
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-ri-box {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tur-ri-avatar {
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.tur-ri-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tur-ri-title {
|
||||
display: flex;
|
||||
height: 25px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
column-gap: 5px;
|
||||
|
||||
:first-child {
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
:last-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 5px;
|
||||
border-radius: 5px;
|
||||
background: var(--tgc-od-blue);
|
||||
color: var(--tgc-white-1);
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.tur-ri-subtitle {
|
||||
display: flex;
|
||||
height: 15px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
column-gap: 10px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
@@ -1,22 +1,17 @@
|
||||
<template>
|
||||
<div v-if="!props.modelValue">暂无数据</div>
|
||||
<div v-if="props.modelValue.length === 0">暂无数据</div>
|
||||
<div v-else class="tur-wg-box">
|
||||
<TurWorldSub v-for="area in getData()" :key="area.id" :data="area" />
|
||||
<TurWorldSub v-for="area in props.modelValue" :key="area.id" :data="area" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import TurWorldSub from "./tur-world-sub.vue";
|
||||
|
||||
interface TurWorldGridProps {
|
||||
modelValue?: string;
|
||||
modelValue: TGApp.Sqlite.Record.WorldExplore[];
|
||||
}
|
||||
|
||||
const props = defineProps<TurWorldGridProps>();
|
||||
|
||||
function getData(): TGApp.Sqlite.Record.WorldExplore[] {
|
||||
if (!props.modelValue) return [];
|
||||
return JSON.parse(props.modelValue);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.tur-wg-box {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<template #prepend>
|
||||
<div class="uc-top-title">
|
||||
<img alt="icon" src="/source/UI/userAvatar.webp" />
|
||||
<span>原神战绩</span>
|
||||
<span>我的角色</span>
|
||||
<v-btn variant="outlined" @click="showSelect = true">筛选角色</v-btn>
|
||||
<v-btn variant="outlined" @click="resetSelect = true">重置筛选</v-btn>
|
||||
</div>
|
||||
@@ -224,6 +224,7 @@ async function loadUid(): Promise<void> {
|
||||
} else {
|
||||
uidCur.value = uidList.value[0];
|
||||
}
|
||||
console.log(uidCur.value, user.value.gameUid);
|
||||
}
|
||||
|
||||
async function loadRole(): Promise<void> {
|
||||
|
||||
@@ -1,48 +1,75 @@
|
||||
<template>
|
||||
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" />
|
||||
<div class="ur-box">
|
||||
<div class="ur-top">
|
||||
<v-app-bar>
|
||||
<template #prepend>
|
||||
<div class="ur-top-title">
|
||||
<span v-if="!isEmpty">{{ getTitle() }} 更新于 {{ recordData.updated }}</span>
|
||||
<span v-else>原神战绩【暂无数据】</span>
|
||||
<img alt="icon" src="/source/UI/userRecord.webp" />
|
||||
<span>原神战绩</span>
|
||||
<v-select
|
||||
variant="outlined"
|
||||
v-model="uidCur"
|
||||
:items="uidList"
|
||||
:hide-details="true"
|
||||
title="游戏UID"
|
||||
/>
|
||||
</div>
|
||||
<div class="ur-top-btns" data-html2canvas-ignore>
|
||||
<v-btn class="ur-top-btn" @click="refresh()">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-refresh</v-icon>
|
||||
</template>
|
||||
更新数据
|
||||
</v-btn>
|
||||
<v-btn class="ur-top-btn" @click="shareRecord()">
|
||||
<template #prepend>
|
||||
<v-icon>mdi-share</v-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template #append>
|
||||
<div class="ur-top-btns">
|
||||
<v-btn prepend-icon="mdi-refresh" class="ur-top-btn" @click="refreshRecord()">更新</v-btn>
|
||||
<v-btn
|
||||
prepend-icon="mdi-share"
|
||||
class="ur-top-btn"
|
||||
@click="shareRecord()"
|
||||
:disabled="recordData === undefined"
|
||||
>
|
||||
分享
|
||||
</v-btn>
|
||||
<v-btn
|
||||
prepend-icon="mdi-delete"
|
||||
class="ur-top-btn"
|
||||
@click="deleteRecord()"
|
||||
:disabled="recordData === undefined"
|
||||
>
|
||||
删除
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
</v-app-bar>
|
||||
<div class="ur-box" v-if="recordData">
|
||||
<div class="ur-box-title">
|
||||
<TurRoleInfo :model-value="recordData.role" :uid="uidCur ?? 0" />
|
||||
<span>Render by TeyvatGuide v{{ version }}</span>
|
||||
</div>
|
||||
<TSubLine>数据总览</TSubLine>
|
||||
<TurOverviewGrid v-model="recordData.stats" />
|
||||
<TurOverviewGrid :model-value="recordData.stats" />
|
||||
<TSubLine>角色信息</TSubLine>
|
||||
<TurAvatarGrid v-model="recordData.avatars" />
|
||||
<TurAvatarGrid :model-value="recordData.avatars" />
|
||||
<TSubLine>世界探索</TSubLine>
|
||||
<TurWorldGrid v-model="recordData.worldExplore" />
|
||||
<TurWorldGrid :model-value="recordData.worldExplore" />
|
||||
<TSubLine>尘歌壶</TSubLine>
|
||||
<TurHomeGrid v-model="recordData.homes" />
|
||||
<TurHomeGrid :model-value="recordData.homes" />
|
||||
</div>
|
||||
<div class="ur-empty" v-else>
|
||||
<img alt="empty" src="/source/UI/empty.webp" />
|
||||
<span>DATA NOT FOUND</span>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
|
||||
import showConfirm from "../../components/func/confirm.js";
|
||||
import showSnackbar from "../../components/func/snackbar.js";
|
||||
import TSubLine from "../../components/main/t-subline.vue";
|
||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||
import TurAvatarGrid from "../../components/userRecord/tur-avatar-grid.vue";
|
||||
import TurHomeGrid from "../../components/userRecord/tur-home-grid.vue";
|
||||
import TurOverviewGrid from "../../components/userRecord/tur-overview-grid.vue";
|
||||
import TurRoleInfo from "../../components/userRecord/tur-role-info.vue";
|
||||
import TurWorldGrid from "../../components/userRecord/tur-world-grid.vue";
|
||||
import TGSqlite from "../../plugins/Sqlite/index.js";
|
||||
import TSUserRecord from "../../plugins/Sqlite/modules/userRecord.js";
|
||||
import { useUserStore } from "../../store/modules/user.js";
|
||||
import TGLogger from "../../utils/TGLogger.js";
|
||||
import { generateShareImg } from "../../utils/TGShare.js";
|
||||
@@ -50,7 +77,7 @@ import TGRequest from "../../web/request/TGRequest.js";
|
||||
|
||||
// store
|
||||
const userStore = storeToRefs(useUserStore());
|
||||
const user = userStore.account.value;
|
||||
const user = computed<TGApp.Sqlite.Account.Game>(() => userStore.account.value);
|
||||
|
||||
// loading
|
||||
const loading = ref<boolean>(false);
|
||||
@@ -58,107 +85,150 @@ const loadingTitle = ref<string>();
|
||||
const loadingSub = ref<string>();
|
||||
|
||||
// data
|
||||
const isEmpty = ref<boolean>(true);
|
||||
const recordData = ref<TGApp.Sqlite.Record.SingleTable>(<TGApp.Sqlite.Record.SingleTable>{});
|
||||
const uidCur = ref<number>();
|
||||
const uidList = ref<number[]>([]);
|
||||
const recordData = ref<TGApp.Sqlite.Record.RenderData>();
|
||||
const version = ref<string>();
|
||||
|
||||
onMounted(async () => {
|
||||
await TGLogger.Info("[UserRecord][onMounted] 打开角色战绩页面");
|
||||
loadingTitle.value = "正在加载战绩数据";
|
||||
loading.value = true;
|
||||
await initUserRecordData();
|
||||
version.value = await getVersion();
|
||||
await loadUid();
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
async function initUserRecordData(): Promise<void> {
|
||||
const recordGet = await TGSqlite.getUserRecord(user.gameUid);
|
||||
if (recordGet !== false) {
|
||||
await TGLogger.Info(`[UserRecord][initUserRecordData][${user.gameUid}] 成功加载战绩数据`);
|
||||
recordData.value = recordGet;
|
||||
isEmpty.value = false;
|
||||
watch(
|
||||
() => uidCur.value,
|
||||
async () => await loadRecord(),
|
||||
);
|
||||
|
||||
async function loadUid(): Promise<void> {
|
||||
uidList.value = await TSUserRecord.getAllUid();
|
||||
if (uidList.value.length === 0) uidList.value = [Number(user.value.gameUid)];
|
||||
if (uidList.value.includes(Number(user.value.gameUid))) {
|
||||
uidCur.value = Number(user.value.gameUid);
|
||||
} else {
|
||||
await TGLogger.Info(`[UserRecord][initUserRecordData][${user.gameUid}] 未找到战绩数据`);
|
||||
isEmpty.value = true;
|
||||
uidCur.value = uidList.value[0];
|
||||
}
|
||||
}
|
||||
|
||||
async function refresh(): Promise<void> {
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.gameUid}] 刷新战绩数据`);
|
||||
async function loadRecord(): Promise<void> {
|
||||
recordData.value = undefined;
|
||||
if (!uidCur.value) return;
|
||||
const record = await TSUserRecord.getRecord(uidCur.value);
|
||||
if (!record) return;
|
||||
recordData.value = record;
|
||||
}
|
||||
|
||||
async function refreshRecord(): Promise<void> {
|
||||
if (!user.value) return;
|
||||
if (uidCur.value && uidCur.value.toString() !== user.value.gameUid) {
|
||||
const switchConfirm = await showConfirm({
|
||||
title: "是否切换游戏账户",
|
||||
text: `确认则尝试切换至${uidCur.value}`,
|
||||
});
|
||||
if (switchConfirm) {
|
||||
await useUserStore().switchGameAccount(uidCur.value.toString());
|
||||
await refreshRecord();
|
||||
return;
|
||||
}
|
||||
const confirm = await showConfirm({
|
||||
title: "确定刷新?",
|
||||
text: `用户${user.value.gameUid}与当前UID${uidCur.value}不一致`,
|
||||
});
|
||||
if (!confirm) {
|
||||
showSnackbar({ text: "已取消战绩数据刷新", color: "cancel" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}] 刷新战绩数据`);
|
||||
loadingTitle.value = "正在获取战绩数据";
|
||||
loading.value = true;
|
||||
if (!userStore.cookie.value) {
|
||||
showSnackbar({
|
||||
text: "请先登录",
|
||||
color: "error",
|
||||
});
|
||||
showSnackbar({ text: "请先登录", color: "error" });
|
||||
loading.value = false;
|
||||
await TGLogger.Warn(`[UserRecord][refresh][${user.gameUid}] 未登录`);
|
||||
await TGLogger.Warn(`[UserRecord][refresh][${user.value.gameUid}] 未登录`);
|
||||
return;
|
||||
}
|
||||
const cookie = {
|
||||
account_id: userStore.cookie.value.account_id,
|
||||
cookie_token: userStore.cookie.value.cookie_token,
|
||||
};
|
||||
const res = await TGRequest.User.getRecord(cookie, user);
|
||||
const res = await TGRequest.User.getRecord(cookie, user.value);
|
||||
if (!("retcode" in res)) {
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.gameUid}] 获取战绩数据成功`);
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.gameUid}]`, false);
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}] 获取战绩数据成功`);
|
||||
await TGLogger.Info(`[UserRecord][refresh][${user.value.gameUid}]`, false);
|
||||
await TGLogger.Info(JSON.stringify(res), false);
|
||||
loadingTitle.value = "正在保存战绩数据";
|
||||
await TGSqlite.saveUserRecord(res, user.gameUid);
|
||||
await initUserRecordData();
|
||||
await TSUserRecord.saveRecord(Number(user.value.gameUid), res);
|
||||
await loadUid();
|
||||
if (recordData.value === undefined) await loadRecord();
|
||||
} else {
|
||||
showSnackbar({
|
||||
text: `[${res.retcode}] ${res.message}`,
|
||||
color: "error",
|
||||
});
|
||||
await TGLogger.Error(`[UserRecord][refresh][${user.gameUid}] 获取战绩数据失败`);
|
||||
await TGLogger.Error(`[UserRecord][refresh][${user.gameUid}] ${res.retcode} ${res.message}`);
|
||||
showSnackbar({ text: `[${res.retcode}] ${res.message}`, color: "error" });
|
||||
await TGLogger.Error(`[UserRecord][refresh][${user.value.gameUid}] 获取战绩数据失败`);
|
||||
await TGLogger.Error(
|
||||
`[UserRecord][refresh][${user.value.gameUid}] ${res.retcode} ${res.message}`,
|
||||
);
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
function getTitle(): string {
|
||||
const role = <TGApp.Sqlite.Record.Role>JSON.parse(recordData.value.role);
|
||||
return `${role.nickname} Lv.${role.level}【${recordData.value.uid}】`;
|
||||
}
|
||||
|
||||
async function shareRecord(): Promise<void> {
|
||||
await TGLogger.Info(`[UserRecord][shareRecord][${user.gameUid}] 生成分享图片`);
|
||||
if (!recordData.value) {
|
||||
showSnackbar({ text: "未找到战绩数据,请尝试刷新", color: "warn" });
|
||||
return;
|
||||
}
|
||||
await TGLogger.Info(`[UserRecord][shareRecord][${user.value.gameUid}] 生成分享图片`);
|
||||
const recordBox = <HTMLElement>document.querySelector(".ur-box");
|
||||
const fileName = `【原神战绩】-${user.gameUid}`;
|
||||
const fileName = `【原神战绩】-${user.value.gameUid}`;
|
||||
loadingTitle.value = "正在生成图片";
|
||||
loadingSub.value = `${fileName}.png`;
|
||||
loading.value = true;
|
||||
await generateShareImg(fileName, recordBox);
|
||||
loadingSub.value = "";
|
||||
loading.value = false;
|
||||
await TGLogger.Info(`[UserRecord][shareRecord][${user.gameUid}] 生成分享图片成功`);
|
||||
await TGLogger.Info(`[UserRecord][shareRecord][${user.value.gameUid}] 生成分享图片成功`);
|
||||
}
|
||||
|
||||
async function deleteRecord(): Promise<void> {
|
||||
if (!uidCur.value) {
|
||||
showSnackbar({ text: "未找到当前UID", color: "error" });
|
||||
return;
|
||||
}
|
||||
const confirm = await showConfirm({
|
||||
title: "确定删除?",
|
||||
text: `将删除${uidCur.value}对应的战绩数据`,
|
||||
});
|
||||
if (!confirm) {
|
||||
showSnackbar({ text: "已取消删除战绩数据", color: "cancel" });
|
||||
return;
|
||||
}
|
||||
await TSUserRecord.deleteUid(uidCur.value);
|
||||
showSnackbar({ text: `成功删除${uidCur.value}的战绩数据` });
|
||||
await loadUid();
|
||||
await loadRecord();
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
.ur-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--box-bg-1);
|
||||
row-gap: 5px;
|
||||
}
|
||||
|
||||
.ur-top {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid var(--common-shadow-2);
|
||||
}
|
||||
|
||||
.ur-top-title {
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
gap: 10px;
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--common-text-title);
|
||||
font-family: var(--font-title);
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.ur-top-btns {
|
||||
@@ -172,4 +242,29 @@ async function shareRecord(): Promise<void> {
|
||||
color: var(--btn-text);
|
||||
font-family: var(--font-text);
|
||||
}
|
||||
|
||||
.ur-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border: 1px solid var(--common-shadow-1);
|
||||
border-radius: 5px;
|
||||
background: var(--box-bg-1);
|
||||
row-gap: 5px;
|
||||
}
|
||||
|
||||
.ur-box-title {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ur-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--font-title);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { app } from "@tauri-apps/api";
|
||||
import Database from "@tauri-apps/plugin-sql";
|
||||
|
||||
import initDataSql from "./sql/initData.js";
|
||||
import { insertAppData, insertRecordData } from "./sql/insertData.js";
|
||||
import { insertAppData } from "./sql/insertData.js";
|
||||
|
||||
class Sqlite {
|
||||
/**
|
||||
@@ -131,35 +131,6 @@ class Sqlite {
|
||||
await this.initDB();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 保存战绩数据
|
||||
* @since Beta v0.3.3
|
||||
* @param {TGApp.Game.Record.FullData} data 战绩数据
|
||||
* @param {string} uid 用户 uid
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
public async saveUserRecord(data: TGApp.Game.Record.FullData, uid: string): Promise<void> {
|
||||
const db = await this.getDB();
|
||||
const sql = insertRecordData(data, uid);
|
||||
await db.execute(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取战绩数据
|
||||
* @since Beta v0.3.3
|
||||
* @param {string} uid 用户 uid
|
||||
* @returns {Promise<TGApp.Sqlite.Record.SingleTable|false>}
|
||||
*/
|
||||
public async getUserRecord(uid: string): Promise<TGApp.Sqlite.Record.SingleTable | false> {
|
||||
const db = await this.getDB();
|
||||
const sql = `SELECT *
|
||||
FROM UserRecord
|
||||
WHERE uid = '${uid}'`;
|
||||
const res: TGApp.Sqlite.Record.SingleTable[] = await db.select(sql);
|
||||
if (res.length === 0) return false;
|
||||
return res[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 检测特定表是否存在
|
||||
* @since Beta v0.4.5
|
||||
|
||||
@@ -59,18 +59,18 @@ function getInsertSql(uid: string, data: TGApp.Game.Avatar.DetailList): string {
|
||||
*/
|
||||
async function getAllUid(): Promise<string[]> {
|
||||
const db = await TGSqlite.getDB();
|
||||
type resType = Array<{ uid: string }>;
|
||||
type resType = Array<{ uid: number }>;
|
||||
const res = await db.select<resType>("SELECT DISTINCT uid FROM UserCharacters;");
|
||||
return res.map((i) => i.uid);
|
||||
return res.map((i) => i.uid.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取用户角色数据
|
||||
* @since Beta v0.5.3
|
||||
* @param {string} uid 用户 uid
|
||||
* @param {number} uid 用户 uid
|
||||
* @returns {Promise<TGApp.Sqlite.Character.UserRole[]>}
|
||||
*/
|
||||
async function getAvatars(uid: string): Promise<TGApp.Sqlite.Character.UserRole[]> {
|
||||
async function getAvatars(uid: number): Promise<TGApp.Sqlite.Character.UserRole[]> {
|
||||
const db = await TGSqlite.getDB();
|
||||
type resType = Array<TGApp.Sqlite.Character.UserRoleDB>;
|
||||
const res = await db.select<resType>("SELECT * FROM UserCharacters WHERE uid = ?;", [uid]);
|
||||
|
||||
133
src/plugins/Sqlite/modules/userRecord.ts
Normal file
133
src/plugins/Sqlite/modules/userRecord.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @file plugins/Sqlite/modules/userRecord.ts
|
||||
* @description Sqlite-用户战绩模块
|
||||
* @since Beta v0.6.0
|
||||
*/
|
||||
|
||||
import { timestampToDate } from "../../../utils/toolFunc.js";
|
||||
import TGSqlite from "../index.js";
|
||||
import { transUserRecord } from "../utils/transUserRecord.js";
|
||||
|
||||
/**
|
||||
* @description 获取插入Sql
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid - 游戏UID
|
||||
* @param {TGApp.Sqlite.Record.SingleTable} data - 战绩数据
|
||||
* @returns {string}
|
||||
*/
|
||||
function getInsertSql(uid: number, data: TGApp.Sqlite.Record.SingleTable): string {
|
||||
return `
|
||||
INSERT INTO UserRecord(uid, role, avatars, stats, worldExplore, homes, updated)
|
||||
VALUES (${uid}, '${data.role}', '${data.avatars}', '${data.stats}',
|
||||
'${data.worldExplore}', '${data.homes}', '${data.updated}')
|
||||
ON CONFLICT(uid) DO UPDATE
|
||||
SET role = '${data.role}',
|
||||
avatars = '${data.avatars}',
|
||||
stats = '${data.stats}',
|
||||
worldExplore = '${data.worldExplore}',
|
||||
homes = '${data.homes}',
|
||||
updated = '${data.updated}';
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析数据库数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Sqlite.Record.SingleTable} data - 数据库数据
|
||||
* @returns {TGApp.Sqlite.Record.RenderData} 渲染数据
|
||||
*/
|
||||
function parseRecord(data: TGApp.Sqlite.Record.SingleTable): TGApp.Sqlite.Record.RenderData {
|
||||
return {
|
||||
uid: data.uid,
|
||||
role: JSON.parse(data.role),
|
||||
avatars: JSON.parse(data.avatars),
|
||||
stats: JSON.parse(data.stats),
|
||||
worldExplore: JSON.parse(data.worldExplore),
|
||||
homes: JSON.parse(data.homes),
|
||||
updated: data.updated,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 转换数据库数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid - 游戏UID
|
||||
* @param {TGApp.Game.Record.FullData} data - 战绩数据
|
||||
* @returns {TGApp.Sqlite.Record.SingleTable}
|
||||
*/
|
||||
function transRecord(
|
||||
uid: number,
|
||||
data: TGApp.Game.Record.FullData,
|
||||
): TGApp.Sqlite.Record.SingleTable {
|
||||
const transData = transUserRecord(uid, data);
|
||||
return {
|
||||
uid: uid,
|
||||
role: JSON.stringify(transData.role),
|
||||
avatars: JSON.stringify(transData.avatars),
|
||||
stats: JSON.stringify(transData.stats),
|
||||
worldExplore: JSON.stringify(transData.worldExplore),
|
||||
homes: JSON.stringify(transData.homes),
|
||||
updated: timestampToDate(new Date().getTime()),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取UID列表
|
||||
* @since Beta v0.6.0
|
||||
* @returns {Promise<number[]>}
|
||||
*/
|
||||
async function getAllUid(): Promise<number[]> {
|
||||
const db = await TGSqlite.getDB();
|
||||
type resType = Array<{ uid: number }>;
|
||||
const res = await db.select<resType>("SELECT DISTINCT uid FROM UserRecord;");
|
||||
return res.map((e) => e.uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取指定UID的战绩数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid - 游戏UID
|
||||
* @returns {Promise<TGApp.Sqlite.Record.RenderData | false>}
|
||||
*/
|
||||
async function getRecord(uid: number): Promise<TGApp.Sqlite.Record.RenderData | false> {
|
||||
const db = await TGSqlite.getDB();
|
||||
const res = await db.select<TGApp.Sqlite.Record.SingleTable[]>(
|
||||
"SELECT * FROM UserRecord WHERE uid = ?;",
|
||||
[uid],
|
||||
);
|
||||
if (res.length === 0) return false;
|
||||
return parseRecord(res[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 保存战绩数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid - 游戏UID
|
||||
* @param {TGApp.Game.Record.FullData} data - 战绩数据
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function saveRecord(uid: number, data: TGApp.Game.Record.FullData): Promise<void> {
|
||||
const db = await TGSqlite.getDB();
|
||||
const sql = getInsertSql(uid, transRecord(uid, data));
|
||||
await db.execute(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 删除战绩数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function deleteUid(uid: number): Promise<void> {
|
||||
const db = await TGSqlite.getDB();
|
||||
await db.execute("DELETE FROM UserRecord WHERE uid=?;", [uid]);
|
||||
}
|
||||
|
||||
const TSUserRecord = {
|
||||
getAllUid,
|
||||
getRecord,
|
||||
saveRecord,
|
||||
deleteUid,
|
||||
};
|
||||
|
||||
export default TSUserRecord;
|
||||
@@ -4,9 +4,6 @@
|
||||
* @since Beta v0.6.0
|
||||
*/
|
||||
|
||||
import { timestampToDate } from "../../../utils/toolFunc.js";
|
||||
import { transUserRecord } from "../utils/transUserRecord.js";
|
||||
|
||||
/**
|
||||
* @description 插入应用数据
|
||||
* @since Alpha v0.2.0
|
||||
@@ -22,28 +19,3 @@ export function insertAppData(key: string, value: string): string {
|
||||
updated = datetime('now', 'localtime');
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 插入原神战绩数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Game.Record.FullData} data 原神战绩数据
|
||||
* @param {string} uid 用户 UID
|
||||
* @returns {string} sql
|
||||
*/
|
||||
export function insertRecordData(data: TGApp.Game.Record.FullData, uid: string): string {
|
||||
const transData = transUserRecord(data);
|
||||
const timeNow = timestampToDate(new Date().getTime());
|
||||
transData.uid = uid;
|
||||
return `
|
||||
INSERT INTO UserRecord(uid, role, avatars, stats, worldExplore, homes, updated)
|
||||
VALUES ('${transData.uid}', '${transData.role}', '${transData.avatars}', '${transData.stats}',
|
||||
'${transData.worldExplore}', '${transData.homes}', '${timeNow}')
|
||||
ON CONFLICT(uid) DO UPDATE
|
||||
SET role = '${transData.role}',
|
||||
avatars = '${transData.avatars}',
|
||||
stats = '${transData.stats}',
|
||||
worldExplore = '${transData.worldExplore}',
|
||||
homes = '${transData.homes}',
|
||||
updated = '${timeNow}';
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -1,49 +1,53 @@
|
||||
/**
|
||||
* @file plugins/Sqlite/utils/transUserRecord.ts
|
||||
* @description Sqlite 数据转换 用户战绩数据转换模块
|
||||
* @since Beta v0.5.5
|
||||
* @since Beta v0.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description 将通过 api 获取到的用户战绩数据转换为数据库中的数据
|
||||
* @since Beta v0.4.3
|
||||
* @description 将通过 api 获取到的用户战绩数据转换为渲染用的数据
|
||||
* @since Beta v0.6.0
|
||||
* @param {number} uid - 用户UID
|
||||
* @param {TGApp.Game.Record.FullData} data 用户战绩数据
|
||||
* @returns {TGApp.Sqlite.Record.SingleTable} 转换后的用户战绩数据
|
||||
* @returns {TGApp.Sqlite.Record.RenderData} 转换后的用户战绩数据
|
||||
*/
|
||||
export function transUserRecord(data: TGApp.Game.Record.FullData): TGApp.Sqlite.Record.SingleTable {
|
||||
export function transUserRecord(
|
||||
uid: number,
|
||||
data: TGApp.Game.Record.FullData,
|
||||
): TGApp.Sqlite.Record.RenderData {
|
||||
return {
|
||||
uid: "",
|
||||
uid: uid,
|
||||
role: transRole(data.role),
|
||||
avatars: transAvatar(data.avatars),
|
||||
avatars: data.avatars.map(transAvatar).sort((a, b) => b.star - a.star || b.id - a.id),
|
||||
stats: transStat(data.stats),
|
||||
worldExplore: JSON.stringify(transWorld(data.world_explorations)),
|
||||
homes: transHome(data.homes),
|
||||
worldExplore: transWorld(data.world_explorations),
|
||||
homes: data.homes.map(transHome),
|
||||
updated: "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将角色信息转换为数据库中的数据
|
||||
* @since Alpha v0.2.0
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Game.Record.Role} data 角色信息
|
||||
* @returns {string} 转换后的角色信息
|
||||
* @returns {TGApp.Sqlite.Record.Role} 转换后的角色信息
|
||||
*/
|
||||
function transRole(data: TGApp.Game.Record.Role): string {
|
||||
const role: TGApp.Sqlite.Record.Role = {
|
||||
function transRole(data: TGApp.Game.Record.Role): TGApp.Sqlite.Record.Role {
|
||||
return {
|
||||
nickname: data.nickname,
|
||||
region: data.region,
|
||||
level: data.level,
|
||||
avatar: data.game_head_icon,
|
||||
};
|
||||
return JSON.stringify(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将角色列表转换为数据库中的数据
|
||||
* @since Alpha v0.2.0
|
||||
* @param {TGApp.Game.Record.Avatar[]} data 角色列表
|
||||
* @returns {string} 转换后的角色列表
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Game.Record.Avatar} data 角色列表
|
||||
* @returns {TGApp.Sqlite.Record.Avatar} 转换后的角色列表
|
||||
*/
|
||||
function transAvatar(data: TGApp.Game.Record.Avatar[]): string {
|
||||
function transAvatar(data: TGApp.Game.Record.Avatar): TGApp.Sqlite.Record.Avatar {
|
||||
const elementMap: Record<string, string> = {
|
||||
Anemo: "风",
|
||||
Geo: "岩",
|
||||
@@ -53,44 +57,26 @@ function transAvatar(data: TGApp.Game.Record.Avatar[]): string {
|
||||
Cryo: "冰",
|
||||
Dendro: "草",
|
||||
};
|
||||
const avatars: TGApp.Sqlite.Record.Avatar[] = data
|
||||
.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
element: elementMap[item.element],
|
||||
fetter: item.fetter,
|
||||
level: item.level,
|
||||
star: item.rarity === 105 ? 5 : item.rarity,
|
||||
constellation: item.actived_constellation_num,
|
||||
isShow: item.is_chosen ? <const>1 : <const>0,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => {
|
||||
// 先按星级降序
|
||||
if (a.star !== b.star) {
|
||||
return b.star - a.star;
|
||||
}
|
||||
// 再按 id 降序
|
||||
return b.id - a.id;
|
||||
});
|
||||
return JSON.stringify(avatars);
|
||||
return {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
element: elementMap[data.element],
|
||||
fetter: data.fetter,
|
||||
level: data.level,
|
||||
star: data.rarity === 105 ? 5 : data.rarity,
|
||||
constellation: data.actived_constellation_num,
|
||||
isShow: data.is_chosen ? 1 : 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 将统计信息转换为数据库中的数据
|
||||
* @since Beta v0.5.5
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Game.Record.Stats} data 统计信息
|
||||
* @return {string} 转换后的统计信息
|
||||
* @return {TGApp.Sqlite.Record.Stats } 转换后的统计信息
|
||||
*/
|
||||
function transStat(data: TGApp.Game.Record.Stats): string {
|
||||
let combatRole: string;
|
||||
if (!data.role_combat.is_unlock) {
|
||||
combatRole = "未解锁";
|
||||
} else {
|
||||
combatRole = `第 ${data.role_combat.max_round_id} 幕`;
|
||||
}
|
||||
const stats: TGApp.Sqlite.Record.Stats = {
|
||||
function transStat(data: TGApp.Game.Record.Stats): TGApp.Sqlite.Record.Stats {
|
||||
return {
|
||||
activeDays: data.active_day_number,
|
||||
achievementNumber: data.achievement_number,
|
||||
avatarNumber: data.avatar_number,
|
||||
@@ -104,14 +90,13 @@ function transStat(data: TGApp.Game.Record.Stats): string {
|
||||
hydroCulus: data.hydroculus_number,
|
||||
pyroCulus: data.pyroculus_number,
|
||||
sprialAbyss: data.spiral_abyss,
|
||||
combatRole: combatRole,
|
||||
combatRole: data.role_combat.is_unlock ? `第 ${data.role_combat.max_round_id} 幕` : "未解锁",
|
||||
luxuriousChest: data.luxurious_chest_number,
|
||||
preciousChest: data.precious_chest_number,
|
||||
exquisiteChest: data.exquisite_chest_number,
|
||||
commonChest: data.common_chest_number,
|
||||
magicChest: data.magic_chest_number,
|
||||
};
|
||||
return JSON.stringify(stats);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,22 +155,19 @@ function transWorld(data: TGApp.Game.Record.WorldExplore[]): TGApp.Sqlite.Record
|
||||
|
||||
/**
|
||||
* @description 将住宅信息转换为数据库中的数据
|
||||
* @since Alpha v0.2.0
|
||||
* @param {TGApp.Game.Record.Home[]} data 住宅信息
|
||||
* @returns {string} 转换后的住宅信息
|
||||
* @since Beta v0.6.0
|
||||
* @param {TGApp.Game.Record.Home} data 住宅信息
|
||||
* @returns {TGApp.Sqlite.Record.Home} 转换后的住宅信息
|
||||
*/
|
||||
function transHome(data: TGApp.Game.Record.Home[]): string {
|
||||
const homes: TGApp.Sqlite.Record.Home[] = data.map((item) => {
|
||||
return {
|
||||
comfortIcon: item.comfort_level_icon,
|
||||
comfortName: item.comfort_level_name,
|
||||
name: item.name,
|
||||
level: item.level,
|
||||
comfort: item.comfort_num,
|
||||
furniture: item.item_num,
|
||||
visit: item.visit_num,
|
||||
bg: item.icon,
|
||||
};
|
||||
});
|
||||
return JSON.stringify(homes);
|
||||
function transHome(data: TGApp.Game.Record.Home): TGApp.Sqlite.Record.Home {
|
||||
return {
|
||||
comfortIcon: data.comfort_level_icon,
|
||||
comfortName: data.comfort_level_name,
|
||||
name: data.name,
|
||||
level: data.level,
|
||||
comfort: data.comfort_num,
|
||||
furniture: data.item_num,
|
||||
visit: data.visit_num,
|
||||
bg: data.icon,
|
||||
};
|
||||
}
|
||||
|
||||
58
src/types/Sqlite/Record.d.ts
vendored
58
src/types/Sqlite/Record.d.ts
vendored
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* @file types/Sqlite/Record.d.ts
|
||||
* @description Sqlite 原神战绩相关类型定义文件
|
||||
* @since Beta v0.5.5
|
||||
* @since Beta v0.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description Sqlite 原神战绩相关类型定义命名空间
|
||||
* @since Beta v0.5.5
|
||||
* @since Beta v0.6.0
|
||||
* @namespace Record
|
||||
* @memberof TGApp.Sqlite
|
||||
*/
|
||||
@@ -14,40 +14,64 @@ declare namespace TGApp.Sqlite.Record {
|
||||
/**
|
||||
* @description 原神战绩数据表
|
||||
* @interface SingleTable
|
||||
* @since Alpha v0.2.0
|
||||
* @property {string} uid - UID
|
||||
* @description 下面的数据在数据库中以 string 类型存储
|
||||
* @property {Role} role - 角色信息
|
||||
* @property {Avatar[]} avatars - 角色列表
|
||||
* @property {Stats} stats - 统计信息
|
||||
* @property {WorldExplore} worldExplore - 世界探索信息
|
||||
* @property {Home[]} homes - 尘歌壶信息
|
||||
* @since Beta v0.6.0
|
||||
* @property {number} uid - UID
|
||||
* @property {string} role - 角色信息
|
||||
* @property {string} avatars - 角色列表
|
||||
* @property {string} stats - 统计信息
|
||||
* @property {string} worldExplore - 世界探索信息
|
||||
* @property {string} homes - 尘歌壶信息
|
||||
* @property {string} updated - 更新时间
|
||||
* @return SingleTable
|
||||
*/
|
||||
interface SingleTable {
|
||||
uid: string;
|
||||
role: string; // Role
|
||||
avatars: string; // Avatar[]
|
||||
stats: string; // Stats
|
||||
worldExplore: string; // WorldExplore
|
||||
homes: string; // Home[]
|
||||
uid: number;
|
||||
role: string;
|
||||
avatars: string;
|
||||
stats: string;
|
||||
worldExplore: string;
|
||||
homes: string;
|
||||
updated: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 渲染用数据
|
||||
* @interface RenderData
|
||||
* @since Beta v0.6.0
|
||||
* @property {number} uid - UID
|
||||
* @property {Role} role - 用户信息
|
||||
* @property {Avatar[]} avatars - 角色列表
|
||||
* @property {Stats} stats - 统计信息
|
||||
* @property {WorldExplore[]} worldExplore - 世界探索信息
|
||||
* @property {Home[]} homes - 尘歌壶信息
|
||||
* @property {string} updated - 更新时间
|
||||
* @returns RenderData
|
||||
*/
|
||||
interface RenderData {
|
||||
uid: number;
|
||||
role: Role;
|
||||
avatars: Avatar[];
|
||||
stats: Stats;
|
||||
worldExplore: WorldExplore[];
|
||||
homes: Home[];
|
||||
updated: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 角色信息类型
|
||||
* @interface Role
|
||||
* @since Alpha v0.2.0
|
||||
* @since Beta v0.6.0
|
||||
* @property {string} nickname - 角色昵称
|
||||
* @property {string} region - 区域
|
||||
* @property {number} level - 等级
|
||||
* @property {string} avatar - 头像
|
||||
* @return Role
|
||||
*/
|
||||
interface Role {
|
||||
nickname: string;
|
||||
region: string;
|
||||
level: number;
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user