Files
dcalc/frontend/src/pages/Character/Result/components/Info.vue
T
imelonandCopilot 18ac23caa3 dev
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 00:18:02 +08:00

326 lines
9.8 KiB
Vue

<template>
<div class="bg-#000000bf w-266px flex-1 overflow-hidden flex flex-col">
<div class="h-177px flex-shrink-0">
<EquList
:detail="props.equs"
:with-sub-weapon="(infoStore.infos?.subweapons?.length ?? 0) > 0"
:avatar="props.avatar"
v-show="display == 'equ'"
></EquList>
<Oath :detail="props.oaths" v-show="display == 'oath'"></Oath>
</div>
<div class="flex flex-wrap border-y-1px my-1px border-y-solid border-#FFFF/10 gap-1% px-1%">
<template v-for="info in props.info" :key="info.id">
<div
class="flex box-border mt-2px"
:style="{ width: info.value.toString().includes('/') ? '100%' : '49%' }"
>
<div class="w-60px text-#836832">{{ info.name }}</div>
<div class="ml-auto text-#3ea74e">{{ info.value }}</div>
</div>
</template>
</div>
<div class="border-y-1px border-y-solid my-1px border-#FFFF/10 bg-black">
<div class="flex items-center px-5px" v-if="suit">
<img
:src="getImageURL(`/equipment${suit.imageUrl}`)"
alt=""
class="w-20px h-20px object-contain"
/>
<div class="flex px-5px flex-1" :class="rarityClass(suit.rarity)">
<span class="flex-1 mr-auto block">{{ suit.name }} 套装</span>
<span class="w-50px text-right block">
{{ suit.rarity }} {{ lvFormat(suit.level, suit.rarity) }}
</span>
<span class="w-50px text-right block">{{ suit.point }}点</span>
</div>
</div>
<!-- <div class="flex justify-end mr-10px text-#836832" v-if="correction > 0">
补正:{{ correction }}点
</div> -->
<div class="flex items-center px-5px" v-if="oathSuit">
<img
:src="getImageURL(`/equipment${oathSuit.imageUrl}`)"
alt=""
class="w-20px h-20px object-contain"
/>
<div class="flex px-5px flex-1" :class="rarityClass(oathSuit.rarity)">
<span class="flex-1 mr-auto block">{{ oathSuit.name }} 誓约</span>
<span class="w-50px text-right block">
{{ oathSuit.rarity }} {{ lvFormat(oathSuit.level, oathSuit.rarity) }}
</span>
<span class="w-50px text-right block">{{ oathSuit.point }}点</span>
</div>
</div>
<div v-if="oathSkills" class="flex justify-around my-5px oath-skill">
<!-- :class="['flex-1', skill.active ? 'bg-#3ea74e text-white' : 'bg-#000000bf text-#836832']" -->
<template v-for="skill in oathSkills" :key="skill.id">
<div
class="flex items-center px-5px flex-col skill-item"
:class="{ active: skill.active, disabled: !skill.enable }"
@click="changeSkillId(skill)"
>
<div
:style="{
backgroundImage: `url(${getImageURL(`${skill.imageUrl}`)})`,
backgroundSize: 'contain',
}"
class="w-28px h-28px skill-icon"
/>
<!-- <span class="pt-4px">{{ skill.name }}</span> -->
</div>
</template>
</div>
</div>
<div
class="border-y-1px border-y-solid my-1px border-#FFFF/10 flex-1 flex flex-col overflow-hidden"
>
<div class="flex">
<div class="flex-1 flex items-center justify-center bg-#221A08 text-#9A7E4A">
穿戴{{ display == 'equ' ? '装备' : '誓约' }}信息
</div>
</div>
<div class="flex-1 overflow-y-auto">
<template v-if="display == 'equ'">
<template v-for="part in partOrder" :key="part">
<div class="flex p-2px partItem gap-5px">
<img
:src="getImageURL(`/equipment/part/${part}.png`)"
alt=""
class="w-20px h-20px object-contain"
/>
<div class="flex items-center justify-center" v-if="adaptation(part) > 0">
<img
:src="getImageURL(`/equipment/adaptation/${adaptation(part)}.png`)"
alt=""
class="w-11px h-10px object-contain"
/>
</div>
<div
class="flex items-center"
v-if="props.equs[part]?.reinforce > 0"
:class="props.equs[part]?.reinforceType == 1 ? 'artifact' : 'advanced'"
>
+{{ props.equs[part]?.reinforce }}
</div>
<div class="rare" v-if="props.equs[part]?.refine > 0">
({{ props.equs[part]?.refine }})
</div>
<div :class="rarityClass(equ(props.equs?.[part]?.id)?.rarity ?? '')">
{{ equ(props.equs?.[part]?.id)?.name }}
</div>
</div>
</template>
</template>
<template v-else>
<template v-for="part in oathOrder" :key="part">
<div class="flex p-2px partItem gap-5px">
<img
:src="getImageURL(`/equipment/part/${part == '11' ? '誓约' : '星蕴石'}.png`)"
alt=""
class="w-20px h-20px object-contain"
/>
<div class="flex items-center justify-center" v-if="oathAdaptation(part) > 0">
<img
:src="getImageURL(`/equipment/adaptation/${oathAdaptation(part)}.png`)"
alt=""
class="w-11px h-10px object-contain"
/>
</div>
<!-- <div
class="flex items-center"
v-if="props.equs[part]?.reinforce > 0"
:class="props.equs[part]?.reinforceType == 1 ? 'artifact' : 'advanced'"
>
+{{ props.equs[part]?.reinforce }}
</div> -->
<!-- <div class="rare" v-if="props.equs[part]?.refine > 0">
({{ props.equs[part]?.refine }})
</div> -->
{{ equ(props.equs?.[part]?.id) }}
<div :class="rarityClass(equ(props.oaths?.[part]?.id)?.rarity ?? '')">
{{ equ(props.oaths?.[part]?.id)?.name }}
</div>
</div>
</template>
</template>
</div>
</div>
<!-- <div class="h-40px w-full"></div> -->
</div>
</template>
<script setup lang="ts" name="Info">
import { getImageURL } from '@/utils/images'
import { rarityClass } from '@/utils'
import type { IResultUserInfo, IResultSuit } from '@/api/calc/type'
import EquList from '@/components/dnf/Equipment/List/index.vue'
import Oath from '@/components/dnf/Equipment/Oath/index.vue'
import type { IConfigEquip, IConfigOath } from '@/stores/config'
import { useInfoStore } from '@/stores'
const props = defineProps<{
info: IResultUserInfo[]
suits: {
suit?: IResultSuit
oath?: IResultSuit
correction?: number
}
equs: Record<string, IConfigEquip>
oaths: Record<string, IConfigOath>
avatar: string
display: 'oath' | 'equ'
}>()
const partOrder = [
'武器',
'上衣',
'下装',
'头肩',
'腰带',
'鞋',
'项链',
'手镯',
'戒指',
'辅助装备',
'魔法石',
'耳环',
]
const oathOrder = Array.from({ length: 12 }, (_, i) => (11 - i).toString())
const infoStore = useInfoStore()
const activeSkillId = defineModel('activeSkillId', { default: '0' })
const suit = computed(() => {
return props.suits.suit
})
const oathSuit = computed(() => {
return props.suits.oath
})
const correction = computed(() => {
return props.suits.correction ?? 0
})
const changeSkillId = (skill: { skillId: string; enable: boolean }) => {
// console.log(skill)
if (!skill.enable) return
if (activeSkillId.value !== skill.skillId) {
activeSkillId.value = skill.skillId
}
}
const oathSkills = computed(() => {
const skillOrder = ['2', '1', '3']
const res = [...(props.suits.oath?.skills ?? [])].sort((left, right) => {
const leftIndex = skillOrder.indexOf(left.skillId)
const rightIndex = skillOrder.indexOf(right.skillId)
const normalizedLeftIndex = leftIndex === -1 ? skillOrder.length : leftIndex
const normalizedRightIndex = rightIndex === -1 ? skillOrder.length : rightIndex
return normalizedLeftIndex - normalizedRightIndex
})
return res?.map((a) => ({
...a,
active:
(a.enable && a.id == props.suits.oath?.id) || (a.enable && a.skillId == activeSkillId.value),
}))
})
const equ = (id: string) => {
if (props.display == 'oath') {
// console.log(props.oaths, id)
return infoStore.oaths.find((e) => e.id == id)
}
return infoStore.equips.find((e) => e.id == id)
}
const adaptation = (part: string) => {
return Math.min(
equ(props.equs?.[part]?.id)?.max_adaptation ?? 0,
props.equs[part]?.adaptation ?? 0,
)
}
const oathAdaptation = (part: string) => {
return Math.min(
equ(props.oaths?.[part]?.id)?.max_adaptation ?? 0,
props.oaths[part]?.adaptation ?? 0,
)
}
const lvFormat = (lv: number, rarity: string) => {
if (rarity == '太初') return ''
switch (lv) {
case 1:
return 'I'
case 2:
return 'II'
case 3:
return 'III'
case 4:
return 'IV'
case 5:
return 'V'
default:
return ''
}
}
</script>
<style scoped lang="scss">
.partItem {
display: flex;
align-items: center;
}
.partItem:nth-child(2n + 1) {
background-color: #0b090b;
}
.partItem:nth-child(2n) {
background-color: #000100;
}
.oath-skill {
.skill-item {
&.active {
}
&:not(.active) {
filter: grayscale(100%);
}
.skill-icon {
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
}
&.disabled .skill-icon {
position: relative;
filter: grayscale(100%);
&::after {
content: ' ';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
background-image: url('@/assets/img/oath/disabled.png');
background-size: cover;
background-position: center;
}
}
}
}
</style>