mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
♻️ 深渊数据库重构,概览显示差距
This commit is contained in:
@@ -1,41 +1,70 @@
|
|||||||
<template>
|
<template>
|
||||||
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="20px">
|
<TOverlay v-model="visible" hide :to-click="onCancel" blur-val="20px">
|
||||||
<div class="hta-oo-box">
|
<div class="hta-oo-box">
|
||||||
|
<v-btn
|
||||||
|
:loading="loadShare"
|
||||||
|
class="hta-oob-share"
|
||||||
|
@click="share()"
|
||||||
|
data-html2canvas-ignore
|
||||||
|
variant="flat"
|
||||||
|
icon="mdi-share-variant"
|
||||||
|
size="24px"
|
||||||
|
/>
|
||||||
<div class="hta-oob-title">数据收集统计</div>
|
<div class="hta-oob-title">数据收集统计</div>
|
||||||
<div class="hta-oob-item">
|
<HtaOverviewLine
|
||||||
<span>当期深渊ID</span>
|
label="当期深渊ID"
|
||||||
<span>{{ props.data.ScheduleId }}</span>
|
:cur="dataCur.ScheduleId"
|
||||||
<span>上传记录总数</span>
|
:last="dataLast.ScheduleId"
|
||||||
<span>{{ props.data.RecordTotal }}</span>
|
:show-diff="false"
|
||||||
</div>
|
/>
|
||||||
|
<HtaOverviewLine
|
||||||
|
label="上传记录总数"
|
||||||
|
:cur="dataCur.RecordTotal"
|
||||||
|
:last="dataLast.RecordTotal"
|
||||||
|
/>
|
||||||
<div class="hta-oob-title">深渊数据统计</div>
|
<div class="hta-oob-title">深渊数据统计</div>
|
||||||
<div class="hta-oob-item">
|
<HtaOverviewLine
|
||||||
<span>总计深渊记录</span>
|
label="总计深渊记录"
|
||||||
<span>{{ props.data.SpiralAbyssTotal }}</span>
|
:cur="dataCur.SpiralAbyssTotal"
|
||||||
<span>通关深渊记录</span>
|
:last="dataLast.SpiralAbyssTotal"
|
||||||
<span>{{ props.data.SpiralAbyssPassed }}</span>
|
/>
|
||||||
<span>满星深渊记录</span>
|
<HtaOverviewLine
|
||||||
<span>{{ props.data.SpiralAbyssFullStar }}</span>
|
label="通关深渊记录"
|
||||||
<span>平均获取渊星</span>
|
:cur="dataCur.SpiralAbyssPassed"
|
||||||
<span>{{
|
:last="dataLast.SpiralAbyssPassed"
|
||||||
(props.data.SpiralAbyssStarTotal / props.data.SpiralAbyssTotal).toFixed(2)
|
/>
|
||||||
}}</span>
|
<HtaOverviewLine
|
||||||
<span>平均战斗次数</span>
|
label="满星深渊记录"
|
||||||
<span>{{
|
:cur="dataCur.SpiralAbyssFullStar"
|
||||||
(props.data.SpiralAbyssBattleTotal / props.data.SpiralAbyssTotal).toFixed(2)
|
:last="dataLast.SpiralAbyssFullStar"
|
||||||
}}</span>
|
/>
|
||||||
</div>
|
<HtaOverviewLine
|
||||||
|
label="平均获取渊星"
|
||||||
|
:cur="dataCur.SpiralAbyssStarTotal / dataCur.SpiralAbyssTotal"
|
||||||
|
:last="dataLast.SpiralAbyssStarTotal / dataLast.SpiralAbyssTotal"
|
||||||
|
/>
|
||||||
|
<HtaOverviewLine
|
||||||
|
label="平均战斗次数"
|
||||||
|
:cur="dataCur.SpiralAbyssBattleTotal / dataCur.SpiralAbyssTotal"
|
||||||
|
:last="dataLast.SpiralAbyssBattleTotal / dataLast.SpiralAbyssTotal"
|
||||||
|
/>
|
||||||
|
<div class="hta-oob-extra">更新于 {{ timestampToDate(props.data.cur.Timestamp) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</TOverlay>
|
</TOverlay>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
|
import { AbyssDataItem } from "../../pages/WIKI/Abyss.vue";
|
||||||
|
import { generateShareImg } from "../../utils/TGShare.js";
|
||||||
|
import { timestampToDate } from "../../utils/toolFunc.js";
|
||||||
import TOverlay from "../main/t-overlay.vue";
|
import TOverlay from "../main/t-overlay.vue";
|
||||||
|
|
||||||
|
import HtaOverviewLine from "./hta-overview-line.vue";
|
||||||
|
|
||||||
interface HtaOverlayOverviewProps {
|
interface HtaOverlayOverviewProps {
|
||||||
modelValue: boolean;
|
modelValue: boolean;
|
||||||
data: TGApp.Plugins.Hutao.Abyss.OverviewData;
|
data: AbyssDataItem<TGApp.Plugins.Hutao.Abyss.OverviewData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HtaOverlayOverviewEmits {
|
interface HtaOverlayOverviewEmits {
|
||||||
@@ -46,6 +75,9 @@ interface HtaOverlayOverviewEmits {
|
|||||||
|
|
||||||
const props = defineProps<HtaOverlayOverviewProps>();
|
const props = defineProps<HtaOverlayOverviewProps>();
|
||||||
const emits = defineEmits<HtaOverlayOverviewEmits>();
|
const emits = defineEmits<HtaOverlayOverviewEmits>();
|
||||||
|
const dataCur = computed(() => props.data.cur);
|
||||||
|
const dataLast = computed(() => props.data.last);
|
||||||
|
const loadShare = ref<boolean>(false);
|
||||||
|
|
||||||
const visible = computed({
|
const visible = computed({
|
||||||
get: () => props.modelValue,
|
get: () => props.modelValue,
|
||||||
@@ -58,42 +90,52 @@ function onCancel(): void {
|
|||||||
visible.value = false;
|
visible.value = false;
|
||||||
emits("cancel");
|
emits("cancel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function share(): Promise<void> {
|
||||||
|
loadShare.value = true;
|
||||||
|
const shareEl = <HTMLElement>document.querySelector(".hta-oo-box");
|
||||||
|
const fileName = `深渊数据统计_${timestampToDate(dataCur.value.Timestamp)}.png`;
|
||||||
|
await generateShareImg(fileName, shareEl, 2);
|
||||||
|
loadShare.value = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.hta-oo-box {
|
.hta-oo-box {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding: 10px;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 24px;
|
||||||
border: 1px solid var(--common-shadow-1);
|
border: 1px solid var(--common-shadow-1);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: var(--box-bg-1);
|
background: var(--box-bg-1);
|
||||||
|
row-gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hta-oo-box:nth-child(3) {
|
.hta-oob-share {
|
||||||
margin-top: 10px;
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hta-oob-title {
|
.hta-oob-title {
|
||||||
|
width: 100%;
|
||||||
border-bottom: 1px solid var(--common-shadow-4);
|
border-bottom: 1px solid var(--common-shadow-4);
|
||||||
color: var(--common-text-title);
|
color: var(--common-text-title);
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hta-oob-item {
|
.hta-oob-extra {
|
||||||
display: grid;
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
right: 4px;
|
||||||
|
bottom: 4px;
|
||||||
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: flex-end;
|
||||||
grid-gap: 5px;
|
font-size: 12px;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-oob-item :nth-child(2n-1) {
|
|
||||||
color: var(--box-text-2);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-oob-item :nth-child(2n) {
|
|
||||||
color: var(--box-text-3);
|
|
||||||
text-align: right;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
76
src/components/hutaoAbyss/hta-overview-line.vue
Normal file
76
src/components/hutaoAbyss/hta-overview-line.vue
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<div class="hta-ol-container">
|
||||||
|
<div class="hta-ol-title">{{ props.label }}</div>
|
||||||
|
<div class="hta-ol-val">
|
||||||
|
<div class="hta-olv-cur">{{ getNumStr(props.cur) }}</div>
|
||||||
|
<div
|
||||||
|
v-if="props.showDiff"
|
||||||
|
class="hta-olv-diff"
|
||||||
|
:title="`上期数据:${getNumStr(props.last)}`"
|
||||||
|
:class="{ 'hta-olv-up': isUp, 'hta-olv-down': !isUp }"
|
||||||
|
>
|
||||||
|
{{ getDiff(props.cur, props.last) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
interface HtaOverviewLineProps {
|
||||||
|
label: string;
|
||||||
|
cur: number;
|
||||||
|
last: number;
|
||||||
|
showDiff?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<HtaOverviewLineProps>(), {
|
||||||
|
showDiff: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const isUp = props.cur - props.last > 0;
|
||||||
|
|
||||||
|
function getNumStr(num: number): string {
|
||||||
|
if (Number.isInteger(num)) return num.toString();
|
||||||
|
return num.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDiff(cur: number, last: number): string {
|
||||||
|
if (cur === last) return "-";
|
||||||
|
if (cur > last) return `↑${getNumStr(cur - last)}`;
|
||||||
|
return `↓${getNumStr(last - cur)}`;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.hta-ol-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-ol-title {
|
||||||
|
color: var(--tgc-od-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-ol-val {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-olv-diff {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-olv-cur {
|
||||||
|
color: var(--tgc-od-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-olv-up {
|
||||||
|
color: var(--tgc-od-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-olv-down {
|
||||||
|
color: var(--tgc-od-green);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,38 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<ToLoading v-model="loading" :title="loadingTitle" :subtitle="loadingSub" />
|
<ToLoading v-model="loading" :title="loadT" />
|
||||||
<div class="hta-box">
|
<v-app-bar>
|
||||||
<div class="hta-top">
|
<template #prepend>
|
||||||
<v-tabs v-model="tab" align-tabs="start" class="hta-tab">
|
<div class="hta-top-prepend">
|
||||||
<v-tab value="use">角色使用</v-tab>
|
<img src="/source/UI/wikiAbyss.webp" alt="icon" />
|
||||||
<v-tab value="up">角色出场</v-tab>
|
<span>深渊统计</span>
|
||||||
<v-tab value="team">队伍出场</v-tab>
|
<v-select
|
||||||
<v-tab value="hold">角色持有</v-tab>
|
v-model="tab"
|
||||||
</v-tabs>
|
:items="abyssList"
|
||||||
<div class="hta-title">
|
item-title="label"
|
||||||
<span>胡桃数据库</span>
|
item-value="value"
|
||||||
<span @click="showDialog = true">更新于 {{ getUpdated() }}</span>
|
density="compact"
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
|
<template #append>
|
||||||
|
<div class="hta-top-append">
|
||||||
|
<span @click="show()" v-if="overview">
|
||||||
|
更新于 {{ timestampToDate(overview.cur.Timestamp) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</v-app-bar>
|
||||||
|
<div class="hta-box">
|
||||||
<v-window v-model="tab" class="hta-tab-item">
|
<v-window v-model="tab" class="hta-tab-item">
|
||||||
<v-window-item value="use">
|
<v-window-item value="use">
|
||||||
<HtaTabUse v-if="avatarUse.length > 0" v-model="avatarUse" />
|
<HtaTabUse v-if="abyssData.use !== null" :data="avatarUse" />
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="up">
|
<v-window-item value="up">
|
||||||
<HtaTabUp v-if="avatarUp.length > 0" v-model="avatarUp" />
|
<HtaTabUp v-if="abyssData.up !== null" :data="avatarUp" />
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="team">
|
<v-window-item value="team">
|
||||||
<HtaTabTeam v-model="teamCombination" />
|
<HtaTabTeam v-if="abyssData.team !== null" :data="teamCombination" />
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="hold">
|
<v-window-item value="hold">
|
||||||
<HtaTabHold v-model="avatarHold" />
|
<HtaTabHold v-if="abyssData.hold !== null" :data="avatarHold" />
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
</v-window>
|
</v-window>
|
||||||
</div>
|
</div>
|
||||||
<HtaOverlayOverview v-model="showDialog" :data="overview" />
|
<HtaOverlayOverview v-model="showDialog" :data="overview" />
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
// vue
|
import { onMounted, ref, watch } from "vue";
|
||||||
import { onMounted, ref } from "vue";
|
|
||||||
|
|
||||||
import HtaOverlayOverview from "../../components/hutaoAbyss/hta-overlay-overview.vue";
|
import HtaOverlayOverview from "../../components/hutaoAbyss/hta-overlay-overview.vue";
|
||||||
import HtaTabHold from "../../components/hutaoAbyss/hta-tab-hold.vue";
|
import HtaTabHold from "../../components/hutaoAbyss/hta-tab-hold.vue";
|
||||||
@@ -41,48 +51,152 @@ import HtaTabUp from "../../components/hutaoAbyss/hta-tab-up.vue";
|
|||||||
import HtaTabUse from "../../components/hutaoAbyss/hta-tab-use.vue";
|
import HtaTabUse from "../../components/hutaoAbyss/hta-tab-use.vue";
|
||||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||||
import Hutao from "../../plugins/Hutao/index.js";
|
import Hutao from "../../plugins/Hutao/index.js";
|
||||||
|
import { timestampToDate } from "../../utils/toolFunc.js";
|
||||||
|
|
||||||
|
enum AbyssTabEnum {
|
||||||
|
use = "角色使用",
|
||||||
|
up = "角色出场",
|
||||||
|
team = "队伍出场",
|
||||||
|
hold = "角色持有",
|
||||||
|
}
|
||||||
|
|
||||||
|
type AbyssTab = keyof typeof AbyssTabEnum;
|
||||||
|
type AbyssList = Array<{ label: AbyssTabEnum; value: AbyssTab }>;
|
||||||
|
export type AbyssDataItem<T> = { cur: T; last: T };
|
||||||
|
export type AbyssDataItemType<T extends AbyssTab> = AbyssDataItem<
|
||||||
|
T extends "use"
|
||||||
|
? TGApp.Plugins.Hutao.Abyss.AvatarUse[]
|
||||||
|
: T extends "up"
|
||||||
|
? TGApp.Plugins.Hutao.Abyss.AvatarUp[]
|
||||||
|
: T extends "team"
|
||||||
|
? TGApp.Plugins.Hutao.Abyss.TeamCombination[]
|
||||||
|
: TGApp.Plugins.Hutao.Abyss.AvatarHold[]
|
||||||
|
>;
|
||||||
|
type AbyssData = {
|
||||||
|
[key in AbyssTab]: AbyssDataItemType<key> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const abyssList: AbyssList = [
|
||||||
|
{ label: AbyssTabEnum.use, value: "use" },
|
||||||
|
{ label: AbyssTabEnum.up, value: "up" },
|
||||||
|
{ label: AbyssTabEnum.team, value: "team" },
|
||||||
|
{ label: AbyssTabEnum.hold, value: "hold" },
|
||||||
|
];
|
||||||
|
|
||||||
// loading
|
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const loadingTitle = ref<string>("");
|
const loadT = ref<string>("");
|
||||||
const loadingSub = ref<string>();
|
|
||||||
|
|
||||||
// overview overlay
|
|
||||||
const showDialog = ref<boolean>(false);
|
const showDialog = ref<boolean>(false);
|
||||||
|
|
||||||
// data
|
// data
|
||||||
const overview = ref<TGApp.Plugins.Hutao.Abyss.OverviewData>(
|
const overview = ref<AbyssDataItem<TGApp.Plugins.Hutao.Abyss.OverviewData>>();
|
||||||
<TGApp.Plugins.Hutao.Abyss.OverviewData>{},
|
const tab = ref<AbyssTab>("use");
|
||||||
|
const abyssData = ref<AbyssData>({ use: null, up: null, team: null, hold: null });
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => tab.value,
|
||||||
|
async () => await refreshData(tab.value),
|
||||||
);
|
);
|
||||||
const tab = ref<string>("use");
|
|
||||||
const avatarUse = ref<TGApp.Plugins.Hutao.Abyss.AvatarUse[]>([]);
|
|
||||||
const avatarUp = ref<TGApp.Plugins.Hutao.Abyss.AvatarUp[]>([]);
|
|
||||||
const teamCombination = ref<TGApp.Plugins.Hutao.Abyss.TeamCombination[]>([]);
|
|
||||||
const avatarHold = ref<TGApp.Plugins.Hutao.Abyss.AvatarHold[]>([]);
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
loadingTitle.value = "正在获取深渊数据";
|
loadT.value = "正在获取深渊数据";
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
loadingTitle.value = "正在获取深渊概览";
|
loadT.value = "正在获取深渊概览";
|
||||||
overview.value = await Hutao.Abyss.getOverview();
|
overview.value = {
|
||||||
loadingTitle.value = "正在获取深渊角色使用";
|
cur: await Hutao.Abyss.getOverview(),
|
||||||
avatarUse.value = await Hutao.Abyss.avatar.getUseRate();
|
last: await Hutao.Abyss.getOverview(true),
|
||||||
loadingTitle.value = "正在获取深渊角色出场";
|
};
|
||||||
avatarUp.value = await Hutao.Abyss.avatar.getUpRate();
|
loadT.value = "正在获取深渊数据";
|
||||||
loadingTitle.value = "正在获取深渊队伍出场";
|
const useData = await getData("use");
|
||||||
teamCombination.value = await Hutao.Abyss.getTeamCollect();
|
abyssData.value = { use: useData, up: null, team: null, hold: null };
|
||||||
loadingTitle.value = "正在获取深渊角色持有";
|
|
||||||
avatarHold.value = await Hutao.Abyss.avatar.getHoldRate();
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
function getUpdated(): string {
|
function show(): void {
|
||||||
return new Date(overview.value.Timestamp)
|
if (showDialog.value) showDialog.value = false;
|
||||||
.toLocaleString("zh-CN", { hour12: false })
|
showDialog.value = true;
|
||||||
.replace(/\//g, "-");
|
}
|
||||||
|
|
||||||
|
async function refreshData(type: AbyssTab): Promise<void> {
|
||||||
|
if (abyssData.value && abyssData.value[type] !== null) return;
|
||||||
|
if (loading.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
loadT.value = `正在获取 ${AbyssTabEnum[type]} 数据`;
|
||||||
|
const data = await getData(type);
|
||||||
|
switch (type) {
|
||||||
|
case "use":
|
||||||
|
abyssData.value.use = <AbyssDataItemType<"use">>data;
|
||||||
|
break;
|
||||||
|
case "up":
|
||||||
|
abyssData.value.up = <AbyssDataItemType<"up">>data;
|
||||||
|
break;
|
||||||
|
case "team":
|
||||||
|
abyssData.value.team = <AbyssDataItemType<"team">>data;
|
||||||
|
break;
|
||||||
|
case "hold":
|
||||||
|
abyssData.value.hold = <AbyssDataItemType<"hold">>data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getData(type: AbyssTab): Promise<AbyssDataItemType<AbyssTab>> {
|
||||||
|
switch (type) {
|
||||||
|
case "use":
|
||||||
|
return {
|
||||||
|
cur: await Hutao.Abyss.avatar.getUseRate(),
|
||||||
|
last: await Hutao.Abyss.avatar.getUseRate(true),
|
||||||
|
};
|
||||||
|
case "up":
|
||||||
|
return {
|
||||||
|
cur: await Hutao.Abyss.avatar.getUpRate(),
|
||||||
|
last: await Hutao.Abyss.avatar.getUpRate(true),
|
||||||
|
};
|
||||||
|
case "team":
|
||||||
|
return {
|
||||||
|
cur: await Hutao.Abyss.getTeamCollect(),
|
||||||
|
last: await Hutao.Abyss.getTeamCollect(true),
|
||||||
|
};
|
||||||
|
case "hold":
|
||||||
|
return {
|
||||||
|
cur: await Hutao.Abyss.avatar.getHoldRate(),
|
||||||
|
last: await Hutao.Abyss.avatar.getHoldRate(true),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
.hta-top-prepend {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--common-text-title);
|
||||||
|
font-family: var(--font-title);
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:last-child {
|
||||||
|
height: 50px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hta-top-append {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
|
||||||
.hta-box {
|
.hta-box {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -93,39 +207,6 @@ function getUpdated(): string {
|
|||||||
box-shadow: 0 0 10px var(--common-shadow-4);
|
box-shadow: 0 0 10px var(--common-shadow-4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hta-top {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
color: var(--common-text-title);
|
|
||||||
column-gap: 10px;
|
|
||||||
font-family: var(--font-title);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-tab {
|
|
||||||
height: 50px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-left: auto;
|
|
||||||
column-gap: 10px;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-title :last-child {
|
|
||||||
font-family: var(--font-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-title :last-child:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hta-tab-item {
|
.hta-tab-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 60px);
|
height: calc(100% - 60px);
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins Hutao api abyss.ts
|
* @file plugins/Hutao/api/abyss.ts
|
||||||
* @description Hutao API 深渊相关
|
* @description Hutao API 深渊相关
|
||||||
* @author BTMuli <bt-muli@outlook.com>
|
* @since Beta v0.6.2
|
||||||
* @since Alpha v0.2.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const BaseUrl = "https://homa.snapgenshin.com/";
|
const BaseUrl = "https://homa.snapgenshin.com/";
|
||||||
|
const AbyssUrl = `${BaseUrl}Statistics/`;
|
||||||
|
|
||||||
export const DataUploadApi = `${BaseUrl}Record/Upload?returningRank=false`;
|
export const DataUploadApi = `${BaseUrl}Record/Upload?returningRank=false`;
|
||||||
export const UidCheckApi = `${BaseUrl}Record/Check?Uid={uid}`;
|
export const OverviewApi = `${AbyssUrl}Overview`;
|
||||||
export const UidRankApi = `${BaseUrl}Record/Rank?Uid={uid}`;
|
export const AvatarUpRateApi = `${AbyssUrl}Avatar/AttendanceRate`;
|
||||||
export const OverviewApi = `${BaseUrl}Statistics/Overview`;
|
export const AvatarUseRateApi = `${AbyssUrl}Avatar/UtilizationRate`;
|
||||||
export const AvatarUpRateApi = `${BaseUrl}Statistics/Avatar/AttendanceRate`;
|
export const AvatarHoldRateApi = `${AbyssUrl}Avatar/HoldingRate`;
|
||||||
export const AvatarUseRateApi = `${BaseUrl}Statistics/Avatar/UtilizationRate`;
|
export const AvatarCollocationApi = `${AbyssUrl}Avatar/AvatarCollocation`;
|
||||||
export const AvatarHoldRateApi = `${BaseUrl}Statistics/Avatar/HoldingRate`;
|
export const WeaponCollocationApi = `${AbyssUrl}Weapon/WeaponCollocation`;
|
||||||
export const AvatarCollocationApi = `${BaseUrl}Statistics/Avatar/AvatarCollocation`;
|
export const TeamCombinationApi = `${AbyssUrl}Team/Combination`;
|
||||||
export const WeaponCollocationApi = `${BaseUrl}Statistics/Weapon/WeaponCollocation`;
|
|
||||||
export const TeamCombinationApi = `${BaseUrl}Statistics/Team/Combination`;
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins Hutao api index.ts
|
* @file plugins/Hutao/api/index.ts
|
||||||
* @description Hutao API
|
* @description Hutao API
|
||||||
* @author BTMuli <bt-muli@outlook.com>
|
|
||||||
* @since Alpha v0.2.0
|
* @since Alpha v0.2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -13,18 +12,12 @@ import {
|
|||||||
DataUploadApi,
|
DataUploadApi,
|
||||||
OverviewApi,
|
OverviewApi,
|
||||||
TeamCombinationApi,
|
TeamCombinationApi,
|
||||||
UidCheckApi,
|
|
||||||
UidRankApi,
|
|
||||||
WeaponCollocationApi,
|
WeaponCollocationApi,
|
||||||
} from "./abyss.js";
|
} from "./abyss.js";
|
||||||
|
|
||||||
const HutaoApi = {
|
const HutaoApi = {
|
||||||
Abyss: {
|
Abyss: {
|
||||||
upload: DataUploadApi,
|
upload: DataUploadApi,
|
||||||
user: {
|
|
||||||
check: UidCheckApi,
|
|
||||||
rank: UidRankApi,
|
|
||||||
},
|
|
||||||
overview: OverviewApi,
|
overview: OverviewApi,
|
||||||
avatar: {
|
avatar: {
|
||||||
upRate: AvatarUpRateApi,
|
upRate: AvatarUpRateApi,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins Hutao index.ts
|
* @file plugins/Hutao/index.ts
|
||||||
* @description Hutao 插件入口
|
* @description Hutao 插件入口
|
||||||
* @author BTMuli <bt-muli@outlook.com>
|
* @since Beta v0.6.2
|
||||||
* @since Beta v0.3.0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import getAvatarCollect from "./request/getAvatarCollect.js";
|
import getAvatarCollect from "./request/getAvatarCollect.js";
|
||||||
@@ -11,7 +10,6 @@ import getAvatarUpRate from "./request/getAvatarUpRate.js";
|
|||||||
import getAvatarUseRate from "./request/getAvatarUseRate.js";
|
import getAvatarUseRate from "./request/getAvatarUseRate.js";
|
||||||
import getOverview from "./request/getOverview.js";
|
import getOverview from "./request/getOverview.js";
|
||||||
import getTeamCollect from "./request/getTeamCollect.js";
|
import getTeamCollect from "./request/getTeamCollect.js";
|
||||||
import getWeaponCollect from "./request/getWeaponCollect.js";
|
|
||||||
import uploadData from "./request/uploadData.js";
|
import uploadData from "./request/uploadData.js";
|
||||||
import { transAvatars, transLocal } from "./utils/transLocal.js";
|
import { transAvatars, transLocal } from "./utils/transLocal.js";
|
||||||
|
|
||||||
@@ -25,7 +23,6 @@ const Hutao = {
|
|||||||
},
|
},
|
||||||
getOverview,
|
getOverview,
|
||||||
getTeamCollect,
|
getTeamCollect,
|
||||||
getWeaponCollect,
|
|
||||||
postData: uploadData,
|
postData: uploadData,
|
||||||
utils: {
|
utils: {
|
||||||
transData: transLocal,
|
transData: transLocal,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getAvatarCollect.ts
|
* @file plugins/Hutao/request/getAvatarCollect.ts
|
||||||
* @description 获取角色搭配数据
|
* @description 获取角色搭配数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,13 +9,17 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取角色搭配数据
|
* @description 获取角色搭配数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]>}
|
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]>}
|
||||||
*/
|
*/
|
||||||
async function getAvatarCollect(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]> {
|
async function getAvatarCollect(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.AvatarCollocation[]> {
|
||||||
const url = HutaoApi.Abyss.avatar.collect;
|
const url = HutaoApi.Abyss.avatar.collect;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarCollocationResponse>(url, {
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarCollocationResponse>(url, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
});
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getAvatarHoldRate.ts
|
* @file plugins/Hutao/request/getAvatarHoldRate.ts
|
||||||
* @description Hutao API 获取角色持有率数据请求方法
|
* @description Hutao API 获取角色持有率数据请求方法
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,12 +9,18 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取角色持有率数据
|
* @description 获取角色持有率数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @returns {Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]>}
|
* @returns {Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]>}
|
||||||
*/
|
*/
|
||||||
async function getAvatarHoldRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]> {
|
async function getAvatarHoldRate(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.AvatarHold[]> {
|
||||||
const url = HutaoApi.Abyss.avatar.holdRate;
|
const url = HutaoApi.Abyss.avatar.holdRate;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarHoldResponse>(url, { method: "GET" });
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarHoldResponse>(url, {
|
||||||
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getAvatarUpRate.ts
|
* @file plugins/Hutao/request/getAvatarUpRate.ts
|
||||||
* @description 获取角色上场率数据
|
* @description 获取角色上场率数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,12 +9,18 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取角色上场率数据
|
* @description 获取角色上场率数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]>}
|
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]>}
|
||||||
*/
|
*/
|
||||||
async function getAvatarUpRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]> {
|
async function getAvatarUpRate(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUp[]> {
|
||||||
const url = HutaoApi.Abyss.avatar.upRate;
|
const url = HutaoApi.Abyss.avatar.upRate;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUpResponse>(url, { method: "GET" });
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUpResponse>(url, {
|
||||||
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getAvatarUseRate.ts
|
* @file plugins/Hutao/request/getAvatarUseRate.ts
|
||||||
* @description 获取角色使用率
|
* @description 获取角色使用率
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,12 +9,18 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取角色使用率
|
* @description 获取角色使用率
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]>}
|
* @return {Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]>}
|
||||||
*/
|
*/
|
||||||
async function getAvatarUseRate(): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]> {
|
async function getAvatarUseRate(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.AvatarUse[]> {
|
||||||
const url = HutaoApi.Abyss.avatar.useRate;
|
const url = HutaoApi.Abyss.avatar.useRate;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUseResponse>(url, { method: "GET" });
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.AvatarUseResponse>(url, {
|
||||||
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getOverview.ts
|
* @file plugins/Hutao/request/getOverview.ts
|
||||||
* @description 获取深渊概览数据
|
* @description 获取深渊概览数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,12 +9,18 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取深渊概览数据
|
* @description 获取深渊概览数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.OverviewData>}
|
* @return {Promise<TGApp.Plugins.Hutao.Abyss.OverviewData>}
|
||||||
*/
|
*/
|
||||||
async function getOverview(): Promise<TGApp.Plugins.Hutao.Abyss.OverviewData> {
|
async function getOverview(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.OverviewData> {
|
||||||
const url = HutaoApi.Abyss.overview;
|
const url = HutaoApi.Abyss.overview;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.OverviewResponse>(url, { method: "GET" });
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.OverviewResponse>(url, {
|
||||||
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file plugins/Hutao/request/getTeamCollect.ts
|
* @file plugins/Hutao/request/getTeamCollect.ts
|
||||||
* @description 获取队伍搭配数据
|
* @description 获取队伍搭配数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
import TGHttp from "../../../utils/TGHttp.js";
|
||||||
@@ -9,13 +9,17 @@ import HutaoApi from "../api/index.js";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取队伍搭配数据
|
* @description 获取队伍搭配数据
|
||||||
* @since Beta v0.5.0
|
* @since Beta v0.6.2
|
||||||
|
* @param {boolean} isLast 是否获取上期数据
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]>}
|
* @return {Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]>}
|
||||||
*/
|
*/
|
||||||
async function getTeamCollect(): Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]> {
|
async function getTeamCollect(
|
||||||
|
isLast: boolean = false,
|
||||||
|
): Promise<TGApp.Plugins.Hutao.Abyss.TeamCombination[]> {
|
||||||
const url = HutaoApi.Abyss.team;
|
const url = HutaoApi.Abyss.team;
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.TeamCombinationResponse>(url, {
|
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.TeamCombinationResponse>(url, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
query: { Last: isLast },
|
||||||
});
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file plugins/Hutao/request/getWeaponCollect.ts
|
|
||||||
* @description 获取武器搭配
|
|
||||||
* @since Beta v0.5.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import TGHttp from "../../../utils/TGHttp.js";
|
|
||||||
import HutaoApi from "../api/index.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 获取武器搭配
|
|
||||||
* @since Beta v0.5.0
|
|
||||||
* @return {Promise<TGApp.Plugins.Hutao.Abyss.WeaponCollocation[]>}
|
|
||||||
*/
|
|
||||||
async function getWeaponCollect(): Promise<TGApp.Plugins.Hutao.Abyss.WeaponCollocation[]> {
|
|
||||||
const url = HutaoApi.Abyss.weapon;
|
|
||||||
const resp = await TGHttp<TGApp.Plugins.Hutao.Abyss.WeaponCollocationResponse>(url, {
|
|
||||||
method: "GET",
|
|
||||||
});
|
|
||||||
return resp.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getWeaponCollect;
|
|
||||||
Reference in New Issue
Block a user