幽境危战

close #157
This commit is contained in:
BTMuli
2025-07-01 22:08:36 +08:00
parent aaf38e4526
commit 131fbe389c
18 changed files with 217 additions and 48 deletions

View File

@@ -365,7 +365,7 @@ async function loadAccount(ac: string): Promise<void> {
return;
}
account.value = gameAccount;
showSnackbar.success(`成功切换到用户${uid}`);
showSnackbar.success(`成功切换到用户${uid.value}`);
}
async function confirmRefreshUser(ac: string): Promise<void> {

View File

@@ -0,0 +1,99 @@
<!-- 幽境危战赋光之人 -->
<template>
<div class="tuc-bling-item-comp" :title="props.bling.name">
<div class="bg">
<img :src="bg" alt="Avatar" />
</div>
<div class="icon">
<TMiImg :src="icon" :alt="props.bling.name" :ori="true" />
</div>
<div class="plus">
<img
src="/icon/challenge/bling.webp"
alt="Plus"
v-if="props.bling.is_plus"
title="恒昼辉光"
/>
<img src="/icon/challenge/buff.webp" alt="Buff" v-else title="辉光" />
</div>
</div>
</template>
<script lang="ts" setup>
import TMiImg from "@comp/app/t-mi-img.vue";
import { computed } from "vue";
import { AppCharacterData } from "@/data/index.js";
type TucblingItemProps = { bling: TGApp.Game.Challenge.ChallengeBling };
const props = defineProps<TucblingItemProps>();
const avatarR = computed<TGApp.App.Character.WikiBriefInfo | undefined>(() => {
const find = AppCharacterData.find((i) => i.id === props.bling.avatar_id);
if (find) return find;
return undefined;
});
const bg = computed<string>(() => {
if (avatarR.value) return `/icon/bg/${avatarR.value.star}-BGC.webp`;
return `/icon/bg/${props.bling.rarity > 5 ? 5 : props.bling.rarity}-BGC.webp`;
});
const icon = computed<string>(() => {
if (avatarR.value) return `/WIKI/character/${avatarR.value.id}.webp`;
return props.bling.image;
});
</script>
<style lang="scss" scoped>
.tuc-bling-item-comp {
position: relative;
display: flex;
width: 40px;
height: 40px;
align-items: flex-end;
justify-content: center;
border-radius: 50%;
}
.bg {
position: absolute;
z-index: 0;
overflow: hidden;
width: 100%;
height: 100%;
border-radius: 50%;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.icon {
position: relative;
z-index: 1;
overflow: hidden;
width: 36px;
height: 36px;
border-radius: 50%;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.plus {
position: absolute;
z-index: 2;
right: -2px;
bottom: -2px;
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
</style>

View File

@@ -0,0 +1,49 @@
<!-- 幽境危战玩家赋光之人 -->
<template>
<div class="tuc-blings-comp">
<div class="title">
<span>赋光之人</span>
<span>{{ plusLen }}/{{ props.data.length }}</span>
</div>
<div class="append">
<TucBlingItem :bling v-for="(bling, idx) in props.data" :key="idx" />
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import TucBlingItem from "./tuc-bling-item.vue";
type TucBlingsProps = { data: TGApp.Game.Challenge.ChallengeBlings };
const props = defineProps<TucBlingsProps>();
const plusLen = computed<number>(() => props.data.filter((i) => i.is_plus).length);
</script>
<style lang="scss" scoped>
.tuc-blings-comp {
position: relative;
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
color: var(--box-text-1);
}
.title {
position: relative;
display: flex;
align-items: center;
justify-content: center;
column-gap: 8px;
font-family: var(--font-title);
font-size: 18px;
}
.append {
display: flex;
align-items: center;
gap: 8px;
}
</style>

View File

@@ -1,11 +1,9 @@
<!-- 幽境危战单个怪物挑战 -->
<template>
<div class="tuc-challenge-item-comp" @click="console.log(props.data)">
<div class="tuc-challenge-item-comp">
<div class="top-title">
<div class="name">{{ props.data.name }} Lv.{{ props.data.monster.level }}</div>
<div class="tags">
<TucMonsterTag v-for="(tag, idx) in props.data.monster.tags" :key="idx" :data="tag" />
</div>
<TucMonsterTag v-for="(tag, idx) in props.data.monster.tags" :key="idx" :data="tag" />
<div class="append">
<span>战斗用时</span>
<span>{{ props.data.second }}</span>
@@ -45,9 +43,10 @@
<script lang="ts" setup>
import TItemBox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
import TMiImg from "@comp/app/t-mi-img.vue";
import TucMonsterTag from "@comp/userChallenge/tuc-monster-tag.vue";
import { getZhElement, parseHtmlText } from "@utils/toolFunc.js";
import TucMonsterTag from "./tuc-monster-tag.vue";
import { AppCharacterData } from "@/data/index.js";
type TucChallengeItemProps = { data: TGApp.Game.Challenge.ChallengeList };
@@ -114,28 +113,20 @@ function getTeamBox(avatar: TGApp.Game.Challenge.ChallengeTeam): TItemBoxData {
width: 100%;
align-items: center;
justify-content: flex-start;
column-gap: 12px;
column-gap: 8px;
.name {
font-family: var(--font-title);
font-size: 16px;
}
.tags {
position: relative;
display: flex;
align-items: center;
justify-content: center;
column-gap: 8px;
}
.append {
display: flex;
align-items: center;
margin-left: auto;
color: var(--box-text-2);
font-family: var(--font-title);
font-size: 14px;
font-size: 16px;
gap: 4px;
span {
@@ -226,16 +217,12 @@ function getTeamBox(avatar: TGApp.Game.Challenge.ChallengeTeam): TItemBoxData {
flex-direction: column;
align-items: flex-start;
justify-content: center;
row-gap: 8px;
row-gap: 12px;
span {
color: var(--box-text-1);
font-size: 14px;
line-height: 1.4;
font-size: 12px;
text-align: left;
white-space: pre-wrap;
word-break: break-all;
word-wrap: break-word;
:deep(span) {
font-weight: bold;

View File

@@ -45,7 +45,6 @@ function getElement(value: string): string {
}
function parseDesc(desc: string): Array<MonsterDesc> {
// {SPRITE_PRESET#11003}元素优势 => [{type: "element", value: "11003"}, {type: "text", value: "元素优势"}]
const regex = /{SPRITE_PRESET#(\d+)}([^{}]*)/g;
const result: Array<MonsterDesc> = [];
let match;
@@ -82,6 +81,7 @@ function parseDesc(desc: string): Array<MonsterDesc> {
color: var(--box-text-1);
font-family: var(--font-title);
font-size: 12px;
line-height: 16px;
}
&.buff-0 {

View File

@@ -1,6 +1,6 @@
<!-- 幽境危战单人/联机数据总览 -->
<template>
<div class="tuc-overview-comp" @click="onClick()">
<div class="tuc-overview-comp">
<div class="toc-top-title">
<div class="title">{{ props.title }}{{ props.data.has_data ? "" : " (无数据) " }}</div>
<div class="append" v-if="props.data.best">
@@ -8,7 +8,7 @@
<span>{{ props.data.best.second }}s</span>
<img
:title="getDiffTitle(props.data.best)"
:src="`/icon/medals/${props.data.best.icon}.webp`"
:src="`/icon/challenge/UI_LeyLineChallenge_Medal_${props.data.best.difficulty}.webp`"
alt="medal"
/>
</div>
@@ -21,19 +21,12 @@
</div>
</template>
<script lang="ts" setup>
import TucChallengeItem from "@comp/userChallenge/tuc-challenge-item.vue";
import TucChallengeItem from "./tuc-challenge-item.vue";
type TucOverviewProps = {
title: string;
data: TGApp.Game.Challenge.Challenge;
};
type TucOverviewProps = { title: string; data: TGApp.Game.Challenge.Challenge };
const props = defineProps<TucOverviewProps>();
function onClick(): void {
console.log(props.data);
}
function getDiffTitle(best: TGApp.Game.Challenge.ChallengeBest): string {
switch (best.difficulty) {
case 1:
@@ -73,8 +66,7 @@ function getDiffTitle(best: TGApp.Game.Challenge.ChallengeBest): string {
.title {
font-family: var(--font-title);
font-size: 16px;
font-weight: bold;
font-size: 18px;
}
.append {
@@ -85,11 +77,17 @@ function getDiffTitle(best: TGApp.Game.Challenge.ChallengeBest): string {
span {
font-size: 14px;
&:nth-child(2) {
color: var(--tgc-yellow-1);
font-family: var(--font-title);
font-size: 16px;
}
}
img {
width: 24px;
height: 24px;
width: 32px;
height: 32px;
object-fit: contain;
}
}

View File

@@ -7,6 +7,9 @@
<div class="icon">
<TMiImg :src="icon" :alt="props.avatar.name" :ori="true" />
</div>
<div class="buff" title="赋光之人">
<img src="/icon/challenge/buff.webp" alt="Buff" />
</div>
</div>
</template>
<script lang="ts" setup>
@@ -36,16 +39,11 @@ const icon = computed<string>(() => {
.tuc-pop-item-comp {
position: relative;
display: flex;
overflow: hidden;
width: 40px;
height: 40px;
align-items: flex-end;
justify-content: center;
border-radius: 50%;
&:hover {
filter: brightness(0.9);
}
}
.bg {
@@ -54,6 +52,7 @@ const icon = computed<string>(() => {
overflow: hidden;
width: 100%;
height: 100%;
border-radius: 50%;
img {
width: 100%;
@@ -65,8 +64,25 @@ const icon = computed<string>(() => {
.icon {
position: relative;
z-index: 1;
overflow: hidden;
width: 36px;
height: 36px;
border-radius: 50%;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.buff {
position: absolute;
z-index: 2;
right: 0;
bottom: 0;
width: 16px;
height: 16px;
img {
width: 100%;