mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-13 09:28:14 +08:00
🎨 还差尘歌壶跟大地图探索没写
This commit is contained in:
31
src/components/itembox/tib-ur-avatar.vue
Normal file
31
src/components/itembox/tib-ur-avatar.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<TItemBox :model-value="box" />
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// vue
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import TItemBox, { TItemBoxData } from "../main/t-itembox.vue";
|
||||||
|
|
||||||
|
interface TibUrAvatarProps {
|
||||||
|
modelValue: TGApp.Sqlite.Record.Avatar
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TibUrAvatarProps>();
|
||||||
|
const box = ref({} as TItemBoxData);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
box.value = {
|
||||||
|
size: "80px",
|
||||||
|
height: "80px",
|
||||||
|
ltSize: "30px",
|
||||||
|
bg: `/icon/bg/${props.modelValue.star}-Star.webp`,
|
||||||
|
icon: `/WIKI/character/icon/${props.modelValue.id}.webp`,
|
||||||
|
lt: `/icon/element/${props.modelValue.element}元素.webp`,
|
||||||
|
rt: props.modelValue.constellation.toString() || "0",
|
||||||
|
rtSize: "20px",
|
||||||
|
innerText: `${props.modelValue.name}`,
|
||||||
|
innerHeight: 20,
|
||||||
|
display: "inner",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<span>{{ modelValue.innerText }}</span>
|
<span>{{ modelValue.innerText }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div v-if="modelValue.display==='outer'" class="tib-outer">
|
<div v-if="modelValue.display==='outer'" class="tib-outer">
|
||||||
<slot name="outer-icon">
|
<slot name="outer-icon">
|
||||||
<img v-show="modelValue.outerIcon" :src="modelValue.outerIcon" alt="outer-icon">
|
<img v-show="modelValue.outerIcon" :src="modelValue.outerIcon" alt="outer-icon">
|
||||||
@@ -34,7 +35,6 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
@@ -147,6 +147,22 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tib-rt {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: v-bind(props["modelValue"]["rtSize"]);
|
||||||
|
height: v-bind(props["modelValue"]["rtSize"]);
|
||||||
|
background: rgb(0 0 0 / 50%);
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-family: Genshin, serif;
|
||||||
|
color: #faf7e8;
|
||||||
|
}
|
||||||
|
|
||||||
.tib-inner {
|
.tib-inner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
@@ -187,4 +203,10 @@ const getOuterFont = computed(() => `${props.modelValue.outerHeight / 2}px`);
|
|||||||
font-size: v-bind(getOuterFont);
|
font-size: v-bind(getOuterFont);
|
||||||
text-shadow: 0 0 5px #000;
|
text-shadow: 0 0 5px #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tib-outer img {
|
||||||
|
width: v-bind(getOuterHeight);
|
||||||
|
height: v-bind(getOuterHeight);
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
43
src/components/userRecord/tur-overview-grid.vue
Normal file
43
src/components/userRecord/tur-overview-grid.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tur-o-g-box">
|
||||||
|
<TurOverviewSub title="活跃天数" :text="data.activeDays" />
|
||||||
|
<TurOverviewSub title="成就达成数" :text="data.achievementNumber" />
|
||||||
|
<TurOverviewSub title="获得角色数" :text="data.avatarNumber" />
|
||||||
|
<TurOverviewSub title="解锁传送点" :text="data.wayPoints" />
|
||||||
|
<TurOverviewSub title="解锁秘境" :text="data.domainNumber" />
|
||||||
|
</div>
|
||||||
|
<div class="tur-o-g-box">
|
||||||
|
<TurOverviewSub title="风神瞳" :text="data.anemoCulus" />
|
||||||
|
<TurOverviewSub title="岩神瞳" :text="data.geoCulus" />
|
||||||
|
<TurOverviewSub title="深境螺旋" :text="data.sprialAbyss" />
|
||||||
|
<TurOverviewSub title="雷神瞳" :text="data.electroCulus" />
|
||||||
|
<TurOverviewSub title="草神瞳" :text="data.dendroCulus" />
|
||||||
|
</div>
|
||||||
|
<div class="tur-o-g-box">
|
||||||
|
<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" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
// vue
|
||||||
|
import { computed } from "vue";
|
||||||
|
import TurOverviewSub from "./tur-overview-sub.vue";
|
||||||
|
|
||||||
|
interface TurOverviewGridProps {
|
||||||
|
modelValue: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TurOverviewGridProps>();
|
||||||
|
const data = computed(() => JSON.parse(props.modelValue) as TGApp.Sqlite.Record.Stats);
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tur-o-g-box {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
grid-column-gap: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
52
src/components/userRecord/tur-overview-sub.vue
Normal file
52
src/components/userRecord/tur-overview-sub.vue
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tur-box">
|
||||||
|
<div class="tur-title">
|
||||||
|
<slot name="title">
|
||||||
|
{{ title }}
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div class="tur-text">
|
||||||
|
<slot name="val-text">
|
||||||
|
{{ text }}
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
interface TAOProps {
|
||||||
|
title: string,
|
||||||
|
text: string | number,
|
||||||
|
}
|
||||||
|
|
||||||
|
defineProps<TAOProps>();
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.tur-box {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: rgb(0 0 0 / 10%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tur-title {
|
||||||
|
font-family: Genshin, serif;
|
||||||
|
font-size: 20px;
|
||||||
|
color: rgb(255 255 255 / 80%);
|
||||||
|
text-shadow: 0 0 10px rgb(0 0 0 / 80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tur-text {
|
||||||
|
font-family: Genshin-Light, serif;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: rgb(255 255 255 / 80%);
|
||||||
|
text-shadow: #fec90b 0 0 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
<div class="ur-box">
|
<div class="ur-box">
|
||||||
<div class="ur-top">
|
<div class="ur-top">
|
||||||
<div class="ur-top-title">
|
<div class="ur-top-title">
|
||||||
原神战绩 更新于 {{ recordData.updated }}
|
<span v-if="recordData.role">{{ getTitle() }}</span>
|
||||||
|
<span v-else>原神战绩</span>
|
||||||
|
更新于 {{ recordData.updated }}
|
||||||
</div>
|
</div>
|
||||||
<v-btn variant="outlined" class="ur-top-btn" @click="refresh">
|
<v-btn variant="outlined" class="ur-top-btn" @click="refresh">
|
||||||
更新数据
|
更新数据
|
||||||
@@ -13,28 +15,39 @@
|
|||||||
<img src="/src/assets/icons/arrow-right.svg" alt="overview">
|
<img src="/src/assets/icons/arrow-right.svg" alt="overview">
|
||||||
<span>数据总览</span>
|
<span>数据总览</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="ur-overview-grid">
|
<TurOverviewGrid v-if="recordData.stats" :model-value="recordData.stats" />
|
||||||
<!-- <TurOverview title="活跃天数" :text="recordData.stats.active_day_number" />-->
|
<div class="ur-sub-title">
|
||||||
|
<img src="/src/assets/icons/arrow-right.svg" alt="overview">
|
||||||
|
<span>我的角色</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="recordData.avatars" class="ur-avatar-grid">
|
||||||
|
<TibUrAvatar v-for="avatar in JSON.parse(recordData.avatars) as TGApp.Sqlite.Record.Avatar[]" :key="avatar.id" :model-value="avatar" />
|
||||||
|
</div>
|
||||||
|
<div class="ur-sub-title">
|
||||||
|
<img src="/src/assets/icons/arrow-right.svg" alt="overview">
|
||||||
|
<span>世界探索</span>
|
||||||
|
</div>
|
||||||
|
{{ recordData.worldExplore }}
|
||||||
|
<div class="ur-sub-title">
|
||||||
|
<img src="/src/assets/icons/arrow-right.svg" alt="overview">
|
||||||
|
<span>尘歌壶</span>
|
||||||
|
</div>
|
||||||
|
{{ recordData.homes }}
|
||||||
</div>
|
</div>
|
||||||
{{ recordData }}
|
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
// vue
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||||
import TurOverview from "../../components/userRecord/tur-overview.vue";
|
import TurOverviewGrid from "../../components/userRecord/tur-overview-grid.vue";
|
||||||
// tauri
|
import TibUrAvatar from "../../components/itembox/tib-ur-avatar.vue";
|
||||||
import { fs } from "@tauri-apps/api";
|
|
||||||
// store
|
// store
|
||||||
import { useAppStore } from "../../store/modules/app";
|
|
||||||
import { useUserStore } from "../../store/modules/user";
|
import { useUserStore } from "../../store/modules/user";
|
||||||
// utils
|
// utils
|
||||||
import TGRequest from "../../web/request/TGRequest";
|
import TGRequest from "../../web/request/TGRequest";
|
||||||
import TGSqlite from "../../plugins/Sqlite";
|
import TGSqlite from "../../plugins/Sqlite";
|
||||||
|
|
||||||
// store
|
// store
|
||||||
const appStore = useAppStore();
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
// loading
|
// loading
|
||||||
@@ -45,7 +58,6 @@ const loadingTitle = ref("");
|
|||||||
const recordData = ref({} as TGApp.Sqlite.Record.SingleTable);
|
const recordData = ref({} as TGApp.Sqlite.Record.SingleTable);
|
||||||
const recordCookie = computed(() => userStore.getCookieGroup2() as Record<string, string>);
|
const recordCookie = computed(() => userStore.getCookieGroup2() as Record<string, string>);
|
||||||
const user = computed(() => userStore.getCurAccount());
|
const user = computed(() => userStore.getCurAccount());
|
||||||
const filePath = computed(() => `${appStore.dataPath.userDataDir}/recordData.json`);
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingTitle.value = "正在加载战绩数据";
|
loadingTitle.value = "正在加载战绩数据";
|
||||||
@@ -58,8 +70,6 @@ async function initUserRecordData () {
|
|||||||
const recordGet = await TGSqlite.getUserRecord(user.value.gameUid);
|
const recordGet = await TGSqlite.getUserRecord(user.value.gameUid);
|
||||||
if (recordGet !== false) {
|
if (recordGet !== false) {
|
||||||
recordData.value = recordGet;
|
recordData.value = recordGet;
|
||||||
} else {
|
|
||||||
await refresh();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +85,11 @@ async function refresh () {
|
|||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTitle () {
|
||||||
|
const role = JSON.parse(recordData.value.role) as TGApp.Sqlite.Record.Role;
|
||||||
|
return `${role.nickname} [Lv.${role.level}] [${recordData.value.uid}]`;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.ur-box {
|
.ur-box {
|
||||||
@@ -128,9 +143,9 @@ async function refresh () {
|
|||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ur-overview-grid {
|
.ur-avatar-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(5, 1fr);
|
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,17 +45,33 @@ function transRole (data: TGApp.Game.Record.Role): string {
|
|||||||
* @returns {string} 转换后的角色列表
|
* @returns {string} 转换后的角色列表
|
||||||
*/
|
*/
|
||||||
function transAvatar (data: TGApp.Game.Record.Avatar[]): string {
|
function transAvatar (data: TGApp.Game.Record.Avatar[]): string {
|
||||||
|
const elementMap: Record<string, string> = {
|
||||||
|
Anemo: "风",
|
||||||
|
Geo: "岩",
|
||||||
|
Electro: "雷",
|
||||||
|
Hydro: "水",
|
||||||
|
Pyro: "火",
|
||||||
|
Cryo: "冰",
|
||||||
|
Dendro: "草",
|
||||||
|
};
|
||||||
const avatars: TGApp.Sqlite.Record.Avatar[] = data.map(item => {
|
const avatars: TGApp.Sqlite.Record.Avatar[] = data.map(item => {
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
element: item.element,
|
element: elementMap[item.element],
|
||||||
fetter: item.fetter,
|
fetter: item.fetter,
|
||||||
level: item.level,
|
level: item.level,
|
||||||
star: item.rarity,
|
star: item.rarity === 105 ? 5 : item.rarity,
|
||||||
constellation: item.actived_constellation_num,
|
constellation: item.actived_constellation_num,
|
||||||
isShow: item.is_chosen ? 1 : 0,
|
isShow: item.is_chosen ? 1 : 0,
|
||||||
} as TGApp.Sqlite.Record.Avatar;
|
} as TGApp.Sqlite.Record.Avatar;
|
||||||
|
}).sort((a, b) => {
|
||||||
|
// 先按星级降序
|
||||||
|
if (a.star !== b.star) {
|
||||||
|
return b.star - a.star;
|
||||||
|
}
|
||||||
|
// 再按 id 降序
|
||||||
|
return b.id - a.id;
|
||||||
});
|
});
|
||||||
return JSON.stringify(avatars);
|
return JSON.stringify(avatars);
|
||||||
}
|
}
|
||||||
@@ -96,7 +112,6 @@ function transStat (data: TGApp.Game.Record.Stats): string {
|
|||||||
function transWorld (data: TGApp.Game.Record.WorldExplore[]): string {
|
function transWorld (data: TGApp.Game.Record.WorldExplore[]): string {
|
||||||
const worlds: TGApp.Sqlite.Record.WorldExplore[] = data.map(item => {
|
const worlds: TGApp.Sqlite.Record.WorldExplore[] = data.map(item => {
|
||||||
let offerings;
|
let offerings;
|
||||||
console.log(item.Offerings);
|
|
||||||
if (item.Offerings !== undefined) {
|
if (item.Offerings !== undefined) {
|
||||||
offerings = item.Offerings.map(offering => {
|
offerings = item.Offerings.map(offering => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user