This commit is contained in:
2025-05-15 23:15:57 +08:00
parent 723ceb5f6f
commit 900d8e8560
86 changed files with 2350 additions and 1905 deletions
@@ -1,34 +1,34 @@
<template>
<div class="mx-10px">
<calc-collapse title="武器/称号/宠物/秘宝">
<calc-tabs v-model="anotherTab" class="!mb-2">
<calc-tab :value="0">武器</calc-tab>
<calc-tab :value="1">称号/宠物/秘宝</calc-tab>
<calc-tab :value="2" v-if="infoStore.infos?.alter.includes('vegabond')">副武器</calc-tab>
</calc-tabs>
<Weapon v-show="anotherTab === 0"></Weapon>
<Else v-show="anotherTab === 1"></Else>
<SubWeapon v-show="anotherTab === 2"></SubWeapon>
</calc-collapse>
<calc-collapse title="套装/通宝">
<calc-tabs v-model="equTab" class="!mb-2">
<calc-tab :value="0">套装</calc-tab>
<calc-tab :value="1">通宝</calc-tab>
</calc-tabs>
<Suit v-show="equTab === 0"></Suit>
<Universal v-show="equTab === 1"></Universal>
</calc-collapse>
<calc-collapse title="融合石">
<calc-tabs v-model="stoneTab" class="!mb-2">
<calc-tab :value="0">套装</calc-tab>
<calc-tab :value="1">通宝</calc-tab>
<calc-tab :value="2">其他</calc-tab>
</calc-tabs>
<Stone v-show="stoneTab == 0"></Stone>
<StoneUniversal v-show="stoneTab == 1"></StoneUniversal>
<StoneOld v-show="stoneTab == 2"></StoneOld>
</calc-collapse>
</div>
<div class="mx-10px">
<calc-collapse title="武器/称号/宠物/秘宝">
<calc-tabs v-model="anotherTab" class="!mb-2">
<calc-tab :value="0">武器</calc-tab>
<calc-tab :value="1">称号/宠物/秘宝</calc-tab>
<calc-tab :value="2" v-if="infoStore.infos?.alter.includes('vegabond')">副武器</calc-tab>
</calc-tabs>
<Weapon v-show="anotherTab === 0"></Weapon>
<Else v-show="anotherTab === 1"></Else>
<SubWeapon v-show="anotherTab === 2"></SubWeapon>
</calc-collapse>
<calc-collapse title="套装/通宝">
<calc-tabs v-model="equTab" class="!mb-2">
<calc-tab :value="0">套装</calc-tab>
<calc-tab :value="1">通宝</calc-tab>
</calc-tabs>
<Suit v-show="equTab === 0"></Suit>
<Universal v-show="equTab === 1"></Universal>
</calc-collapse>
<calc-collapse title="融合石">
<calc-tabs v-model="stoneTab" class="!mb-2">
<calc-tab :value="0">套装</calc-tab>
<calc-tab :value="1">通宝</calc-tab>
<calc-tab :value="2">其他</calc-tab>
</calc-tabs>
<Stone v-show="stoneTab == 0"></Stone>
<StoneUniversal v-show="stoneTab == 1"></StoneUniversal>
<StoneOld v-show="stoneTab == 2"></StoneOld>
</calc-collapse>
</div>
</template>
<script lang="ts" setup name="Index">
@@ -46,7 +46,4 @@ const infoStore = useInfoStore()
const equTab = ref(0)
const stoneTab = ref(0)
const anotherTab = ref(0)
</script>
@@ -3,7 +3,11 @@
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equ, _) in equs" :key="_">
<EquipmentIcon :equipment="equ" :inactive="configStore.config.equips[equ?.itemDetailType ?? '']?.id != equ?.id" @click="configStore.chooseEqu(equ)"/>
<EquipmentIcon
:equipment="equ"
:inactive="configStore.config.equips[equ?.itemDetailType ?? '']?.id != equ?.id"
@click="configStore.chooseEqu(equ)"
/>
</template>
</div>
</template>
@@ -23,30 +27,23 @@ const infoStore = useInfoStore()
const configStore = useConfigStore()
const equs = computed(() => {
const items = infoStore.equips.filter(
(equip) => ['称号','宠物'].includes(equip.itemDetailType),
)
const items = infoStore.equips.filter((equip) => ['称号', '宠物'].includes(equip.itemDetailType))
const res: (IEquipment | undefined)[] = []
Array.from(new Set(items.map((item) => item.itemDetailType))).forEach((type) => {
const equList = items.filter((item) => item.itemDetailType === type)
equList.sort((a, b) => {
if (a.itemType !== b.itemType) {
return b.itemType.localeCompare(a.itemType)
return b.itemType.localeCompare(a.itemType)
}
const rarityOrder = ['传说', '神器', '稀有']
return rarityOrder.indexOf(a.rarity) - rarityOrder.indexOf(b.rarity)
})
res.push(
...equList
)
res.push(...equList)
const remind = rowCount - (res.length % rowCount)
res.push(...Array(remind + rowCount).fill(undefined))
})
const treasure = infoStore.equips.filter(
(equip) => equip.categorize.includes('秘宝'),
)
res.push(...treasure,...Array(rowCount-treasure.length).fill(undefined))
const treasure = infoStore.equips.filter((equip) => equip.categorize.includes('秘宝'))
res.push(...treasure, ...Array(rowCount - treasure.length).fill(undefined))
return res
})
</script>
@@ -3,35 +3,39 @@
<template>
<div>
<div class="flex flex-col gap-10px pb-10px">
<!-- 套装选择tab -->
<div class="flex flex-wrap w-100%">
<template v-for="(suit, _) in suits" :key="_">
<div class="flex items-center justify-center">
<img
class="w-35px h-35px object-contain"
:src="getImageURL('equipment' + suit.imageUrl)"
:alt="suit.name"
:style="{ filter: curSuit === suit.value ? '' : 'grayscale(100%)' }"
@click="curSuit = suit.value"
@dblclick="handleDoubleClick"
<!-- 套装选择tab -->
<div class="flex flex-wrap w-100%">
<template v-for="(suit, _) in suits" :key="_">
<div class="flex items-center justify-center">
<img
class="w-35px h-35px object-contain"
:src="getImageURL('equipment' + suit.imageUrl)"
:alt="suit.name"
:style="{ filter: curSuit === suit.value ? '' : 'grayscale(100%)' }"
@click="curSuit = suit.value"
@dblclick="handleDoubleClick"
/>
</div>
</template>
</div>
<EquipmentRaritySelect v-model="curRarity" />
</div>
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equip, _) in suitEquipments" :key="_">
<template v-if="equip?.rarity == curRarity || !curRarity">
<EquipmentIcon
:equipment="equip"
:inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id"
@click="configStore.chooseEqu(equip, true)"
/>
</div>
</template>
<template v-else>
<EquipmentIcon />
</template>
</template>
</div>
<EquipmentRaritySelect v-model="curRarity" />
</div>
<div class="flex flex-wrap gap-4px content-start" :style="{width: `${rowCount * 32}px`}">
<template v-for="(equip,_) in suitEquipments" :key="_">
<template v-if="equip?.rarity == curRarity || !curRarity">
<EquipmentIcon :equipment="equip" :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id" @click="configStore.chooseEqu(equip,true)"/>
</template>
<template v-else>
<EquipmentIcon/>
</template>
</template>
</div>
</div>
</template>
@@ -48,7 +52,7 @@ const curSuit = ref(16201)
const curRarity = ref()
const props = defineProps<{
rowCount?:number
rowCount?: number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
@@ -64,30 +68,30 @@ const suits = computed(() => {
})
const suitEquipments = computed(() => {
const equs = infoStore.stones.filter((a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1 )
const equs = infoStore.stones.filter(
(a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1,
)
const res: (IEquipment | undefined)[] = []
const raritiyList = ['神器','传说','史诗']
const raritiyList = ['神器', '传说', '史诗']
raritiyList.forEach((rarity) => {
const equ : (IEquipment | undefined)[] = equs.filter((a) => a.rarity === rarity)
equ.splice(5,0,undefined)
equ.splice(9,0,undefined)
res.push(
...equ,
...Array(Math.max(0,rowCount - equ.length)).fill(undefined),
)
const equ: (IEquipment | undefined)[] = equs.filter((a) => a.rarity === rarity)
equ.splice(5, 0, undefined)
equ.splice(9, 0, undefined)
res.push(...equ, ...Array(Math.max(0, rowCount - equ.length)).fill(undefined))
})
return res
})
const handleDoubleClick = () => {
if(!curRarity.value) return
if(curRarity.value == '太初') return
suitEquipments.value.filter(a=>!!a && a.rarity == curRarity.value).splice(0,11).forEach((a) => {
configStore.chooseEqu(a,true)
})
if (!curRarity.value) return
if (curRarity.value == '太初') return
suitEquipments.value
.filter((a) => !!a && a.rarity == curRarity.value)
.splice(0, 11)
.forEach((a) => {
configStore.chooseEqu(a, true)
})
}
</script>
@@ -1,9 +1,13 @@
`<!-- 每排总计6+4+4,共计14个排列 -->
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{width: `${rowCount * 32}px`}">
<template v-for="(equip,_) in equs" :key="_">
<EquipmentIcon :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id" :equipment="equip" @click="configStore.chooseEqu(equip,true)" />
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equip, _) in equs" :key="_">
<EquipmentIcon
:inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id"
:equipment="equip"
@click="configStore.chooseEqu(equip, true)"
/>
</template>
</div>
</template>
@@ -15,7 +19,7 @@ import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const props = defineProps<{
rowCount ?:number
rowCount?: number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
@@ -23,24 +27,22 @@ const infoStore = useInfoStore()
const configStore = useConfigStore()
const equs = computed(() => {
const items = infoStore.stones.filter(
(equip) => equip.categorize.includes('神界'),
)
const items = infoStore.stones.filter((equip) => equip.categorize.includes('神界'))
const res: (IEquipment | undefined)[] = []
res.push(
...items.filter((a) => a.rarity === '太初'),
...Array(Math.max(0,rowCount - items.filter((a) => a.rarity === '太初').length)).fill(undefined),
);
...Array(Math.max(0, rowCount - items.filter((a) => a.rarity === '太初').length)).fill(
undefined,
),
)
['手镯','项链','戒指','','辅助装备','魔法石','耳环',''].forEach((cat) => {
const equ: (IEquipment | undefined)[] = items.filter((a) => a.rarity === '史诗' && a.itemDetailType == cat)
res.push(
...equ,
...Array(Math.max(0, 7 - equ.length)).fill(undefined),
;['手镯', '项链', '戒指', '', '辅助装备', '魔法石', '耳环', ''].forEach((cat) => {
const equ: (IEquipment | undefined)[] = items.filter(
(a) => a.rarity === '史诗' && a.itemDetailType == cat,
)
res.push(...equ, ...Array(Math.max(0, 7 - equ.length)).fill(undefined))
})
// const categorize = Array.from(new Set(items.map((item) => item.categorize)))
// raritiyList.forEach((rarity) => {
// categorize.forEach((cat) => {
@@ -1,9 +1,13 @@
<!-- 每排总计6+4+4,共计14个排列 -->
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{width: `${rowCount * 32}px`}">
<template v-for="(equip,_) in equs" :key="_">
<EquipmentIcon :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id" :equipment="equip" @click="configStore.chooseEqu(equip,true)" />
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equip, _) in equs" :key="_">
<EquipmentIcon
:inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.fusion != equip?.id"
:equipment="equip"
@click="configStore.chooseEqu(equip, true)"
/>
</template>
</div>
</template>
@@ -15,7 +19,7 @@ import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const props = defineProps<{
rowCount ?:number
rowCount?: number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
@@ -23,20 +27,17 @@ const infoStore = useInfoStore()
const configStore = useConfigStore()
const equs = computed(() => {
const items = infoStore.stones.filter(
(equip) => equip.categorize.includes('通宝'),
)
const items = infoStore.stones.filter((equip) => equip.categorize.includes('通宝'))
const res: (IEquipment | undefined)[] = []
const raritiyList = ['神器','史诗']
const raritiyList = ['神器', '史诗']
const categorize = Array.from(new Set(items.map((item) => item.categorize)))
raritiyList.forEach((rarity) => {
categorize.forEach((cat) => {
const equ : (IEquipment | undefined)[] = items.filter((a) => a.rarity === rarity && a.categorize === cat)
equ.splice(5,0,undefined)
res.push(
...equ,
...Array(Math.max(0,rowCount - equ.length)).fill(undefined),
const equ: (IEquipment | undefined)[] = items.filter(
(a) => a.rarity === rarity && a.categorize === cat,
)
equ.splice(5, 0, undefined)
res.push(...equ, ...Array(Math.max(0, rowCount - equ.length)).fill(undefined))
})
})
return res
@@ -3,7 +3,11 @@
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(weapon, _) in weapons" :key="_">
<EquipmentIcon :equipment="weapon" :inactive="configStore.config.equips['副武器']?.id != weapon?.id" @click="configStore.chooseEqu(weapon,false,true)"/>
<EquipmentIcon
:equipment="weapon"
:inactive="configStore.config.equips['副武器']?.id != weapon?.id"
@click="configStore.chooseEqu(weapon, false, true)"
/>
</template>
</div>
</template>
@@ -40,5 +44,4 @@ const weapons = computed(() => {
})
return res
})
</script>
@@ -3,35 +3,39 @@
<template>
<div>
<div class="flex flex-col gap-10px pb-10px">
<!-- 套装选择tab -->
<div class="flex flex-wrap w-100%">
<template v-for="(suit, _) in suits" :key="_">
<div class="flex items-center justify-center">
<img
class="w-35px h-35px object-contain"
:src="getImageURL('equipment' + suit.imageUrl)"
:alt="suit.name"
:style="{ filter: curSuit === suit.value ? '' : 'grayscale(100%)' }"
@click="curSuit = suit.value"
@dblclick="handleDoubleClick"
<!-- 套装选择tab -->
<div class="flex flex-wrap w-100%">
<template v-for="(suit, _) in suits" :key="_">
<div class="flex items-center justify-center">
<img
class="w-35px h-35px object-contain"
:src="getImageURL('equipment' + suit.imageUrl)"
:alt="suit.name"
:style="{ filter: curSuit === suit.value ? '' : 'grayscale(100%)' }"
@click="curSuit = suit.value"
@dblclick="handleDoubleClick"
/>
</div>
</template>
</div>
<EquipmentRaritySelect v-model="curRarity" />
</div>
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equip, _) in suitEquipments" :key="_">
<template v-if="equip?.rarity == curRarity || !curRarity">
<EquipmentIcon
:equipment="equip"
:inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id"
@click="configStore.chooseEqu(equip)"
/>
</div>
</template>
<template v-else>
<EquipmentIcon />
</template>
</template>
</div>
<EquipmentRaritySelect v-model="curRarity" />
</div>
<div class="flex flex-wrap gap-4px content-start" :style="{width: `${rowCount * 32}px`}">
<template v-for="(equip,_) in suitEquipments" :key="_">
<template v-if="equip?.rarity == curRarity || !curRarity">
<EquipmentIcon :equipment="equip" :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id" @click="configStore.chooseEqu(equip)"/>
</template>
<template v-else>
<EquipmentIcon/>
</template>
</template>
</div>
</div>
</template>
@@ -48,7 +52,7 @@ const curSuit = ref(16201)
const curRarity = ref()
const props = defineProps<{
rowCount?:number
rowCount?: number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
@@ -64,30 +68,44 @@ const suits = computed(() => {
})
const suitEquipments = computed(() => {
const equs = infoStore.equips.filter((a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1 )
const equs = infoStore.equips.filter(
(a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1,
)
const res: (IEquipment | undefined)[] = []
const raritiyList = ['神器','传说','史诗']
const raritiyList = ['神器', '传说', '史诗']
raritiyList.forEach((rarity) => {
const equ : (IEquipment | undefined)[] = equs.filter((a) => a.rarity === rarity && !a.name.includes('黑牙'))
equ.splice(5,0,undefined)
equ.splice(9,0,undefined)
res.push(
...equ,
...Array(Math.max(0,rowCount - equ.length)).fill(undefined),
const equ: (IEquipment | undefined)[] = equs.filter(
(a) => a.rarity === rarity && !a.name.includes('黑牙'),
)
equ.splice(5, 0, undefined)
equ.splice(9, 0, undefined)
res.push(...equ, ...Array(Math.max(0, rowCount - equ.length)).fill(undefined))
})
const remind = equs.filter(a=>a.rarity == '太初' || a.name.includes('黑牙')).sort((a,b)=>(a.rarity == '太初' ? 1 : 0) - (b.rarity == '太初' ? 1 : 0))
res.push(undefined,undefined,...remind.filter(a=>a.itemDetailType == '项链'),undefined,...remind.filter(a=>a.itemDetailType == '手镯'),undefined,...remind.filter(a=>a.itemDetailType == '戒指'),...Array(Math.max(0,rowCount - remind.length -4)).fill(undefined))
const remind = equs
.filter((a) => a.rarity == '太初' || a.name.includes('黑牙'))
.sort((a, b) => (a.rarity == '太初' ? 1 : 0) - (b.rarity == '太初' ? 1 : 0))
res.push(
undefined,
undefined,
...remind.filter((a) => a.itemDetailType == '项链'),
undefined,
...remind.filter((a) => a.itemDetailType == '手镯'),
undefined,
...remind.filter((a) => a.itemDetailType == '戒指'),
...Array(Math.max(0, rowCount - remind.length - 4)).fill(undefined),
)
return res
})
const handleDoubleClick = () => {
if(!curRarity.value) return
if(curRarity.value == '太初') return
suitEquipments.value.filter(a=>!!a && a.rarity == curRarity.value).splice(0,11).forEach((a) => {
configStore.chooseEqu(a)
})
if (!curRarity.value) return
if (curRarity.value == '太初') return
suitEquipments.value
.filter((a) => !!a && a.rarity == curRarity.value)
.splice(0, 11)
.forEach((a) => {
configStore.chooseEqu(a)
})
}
</script>
@@ -1,9 +1,13 @@
<!-- 每排总计6+4+4,共计14个排列 -->
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{width: `${rowCount * 32}px`}">
<template v-for="(equip,_) in equs" :key="_">
<EquipmentIcon :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id" :equipment="equip" @click="configStore.chooseEqu(equip)" />
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(equip, _) in equs" :key="_">
<EquipmentIcon
:inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id"
:equipment="equip"
@click="configStore.chooseEqu(equip)"
/>
</template>
</div>
</template>
@@ -15,7 +19,7 @@ import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const props = defineProps<{
rowCount ?:number
rowCount?: number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
@@ -27,15 +31,12 @@ const equs = computed(() => {
(equip) => equip.categorize === '通宝装备' || equip.categorize === '稀有装备 套装',
)
const res: (IEquipment | undefined)[] = []
const raritiyList = ['稀有','神器','传说','史诗']
const raritiyList = ['稀有', '神器', '传说', '史诗']
raritiyList.forEach((rarity) => {
const equ : (IEquipment | undefined)[] = items.filter((a) => a.rarity === rarity)
equ.splice(5,0,undefined)
equ.splice(9,0,undefined)
res.push(
...equ,
...Array(Math.max(0,rowCount - equ.length)).fill(undefined),
)
const equ: (IEquipment | undefined)[] = items.filter((a) => a.rarity === rarity)
equ.splice(5, 0, undefined)
equ.splice(9, 0, undefined)
res.push(...equ, ...Array(Math.max(0, rowCount - equ.length)).fill(undefined))
})
return res
})
@@ -3,7 +3,11 @@
<template>
<div class="flex flex-wrap gap-4px content-start" :style="{ width: `${rowCount * 32}px` }">
<template v-for="(weapon, _) in weapons" :key="_">
<EquipmentIcon :equipment="weapon" :inactive="configStore.config.equips['武器']?.id != weapon?.id" @click="configStore.chooseEqu(weapon)"/>
<EquipmentIcon
:equipment="weapon"
:inactive="configStore.config.equips['武器']?.id != weapon?.id"
@click="configStore.chooseEqu(weapon)"
/>
</template>
</div>
</template>
@@ -39,5 +43,4 @@ const weapons = computed(() => {
})
return res
})
</script>
@@ -1,5 +1,8 @@
<template>
<div class="w-340px bg-black flex flex-col h-90vh">
<calc-dialog lazy header="装备条件" v-model:visible="triggerVisible">
<options />
</calc-dialog>
<!-- 头部 选择是装备还是融合石 -->
<div class="flex bg-#101012 h-40px text-#6C5E4A font-bold">
<div
@@ -30,7 +33,7 @@
品质:<EquipmentRaritySelect v-model="curRarity" />
</div>
</div>
<div class="flex flex-1 items-center">
<div class="flex flex-1 items-center justify-between">
<div class="flex items-center">
套装:
<div class="flex items-center justify-center gap-2px">
@@ -47,26 +50,27 @@
</template>
</div>
</div>
<calc-button
icon="set"
title="装备触发条件"
@click="triggerVisible = !triggerVisible"
></calc-button>
</div>
</div>
<div class="overflow-y-auto gap-1 p-1 flex flex-col items-center flex-1 h-0">
<template v-for="item in equs" :key="item.name">
<template v-if="item.equs.length > 0">
<div class="item-head w-full">{{ item.name }}</div>
<div class="flex flex-wrap gap-4px justify-around w-full">
<template v-for="(equ, _) in item.equs" :key="_">
<EquipmentIcon
:inactive="!isActive(equ)"
:equipment="equ"
@click="chooseEqu(equ)"
/>
</template>
</div>
</template>
<template v-for="item in equs" :key="item.name">
<template v-if="item.equs.length > 0">
<div class="item-head w-full">{{ item.name }}</div>
<div class="flex flex-wrap gap-4px justify-around w-full">
<template v-for="(equ, _) in item.equs" :key="_">
<EquipmentIcon :inactive="!isActive(equ)" :equipment="equ" @click="chooseEqu(equ)" />
</template>
</div>
</template>
</div>
</template>
</div>
</div>
<div class="px-5px flex flex-col">
<div class="px-5px flex flex-col h-90vh">
<div class="flex flex-col overflow-hidden bg-black" v-if="curEquInfo">
<div class="item-head">基础信息</div>
<div class="flex-1 overflow-y-auto overflow-x-hidden bg-black w-240px">
@@ -127,6 +131,11 @@ import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
import Info from '@/components/dnf/Equipment/Info/index.vue'
import SuitInfo from '@/components/dnf/Equipment/SuitInfo/index.vue'
import { formatEqu, formatStone } from './formatData'
import options from './components/options.vue'
const props = defineProps<{
alter: string
}>()
const infoStore = useInfoStore()
const type = ref('equ')
@@ -137,6 +146,7 @@ const curSuitLv = ref({
rarity: '史诗',
lv: 1,
})
const triggerVisible = ref(false)
const raritiyList = ['稀有', '神器', '传说', '史诗', '太初']
@@ -0,0 +1,19 @@
<template>
<div class="flex flex-col gap-2 w-250px p-2">
<div v-for="option in info.options" :key="option.id" class="flex items-center gap-2">
<div class="w-60px text-end">{{ option.name }}</div>
<calc-select class="flex-1 !h-20px" :appendTo="dialogRef" v-model="config.config.options[option.id.toString()]">
<calc-option v-for="(item, index) in option.options" :key="index" :value="index">
{{ item }}
</calc-option>
</calc-select>
</div>
</div>
</template>
<script lang="ts" setup>
import { useConfigStore, useInfoStore } from '@/stores'
const dialogRef = inject("dialogRef", ref(null))
const config = useConfigStore()
const info = useInfoStore()
</script>
@@ -1,9 +1,8 @@
import type { IEquipment } from "@/api/info/type"
import type { IEquipment } from '@/api/info/type'
export const rowCount = 10
export const formatEqu = (total: IEquipment[],subweapons?:string[],curSuit
?:string) => {
export const formatEqu = (total: IEquipment[], subweapons?: string[], curSuit?: string) => {
// 武器
const item_weapon = total.filter((a) => a.itemType == '武器') ?? []
const weapons: (IEquipment | undefined)[] = []
@@ -25,14 +24,14 @@ export const formatEqu = (total: IEquipment[],subweapons?:string[],curSuit
// # region 副武器
const subWeapons: (IEquipment | undefined)[] = []
const item_sub_weapon = (
total.filter((a) => subweapons?.includes(a.itemDetailType)) ?? []
).sort((a, b) => {
if (a.categorize == b.categorize) {
return a.itemDetailType.localeCompare(b.itemDetailType)
}
return b.categorize.localeCompare(a.categorize)
})
const item_sub_weapon = (total.filter((a) => subweapons?.includes(a.itemDetailType)) ?? []).sort(
(a, b) => {
if (a.categorize == b.categorize) {
return a.itemDetailType.localeCompare(b.itemDetailType)
}
return b.categorize.localeCompare(a.categorize)
},
)
if (item_sub_weapon.length > 0) {
subWeapons.push(
...item_sub_weapon.map((a) => ({ ...a, itemType: '副武器' })),
@@ -130,7 +129,7 @@ export const formatEqu = (total: IEquipment[],subweapons?:string[],curSuit
]
}
export const formatStone = (total: IEquipment[],curSuit?:string) => {
export const formatStone = (total: IEquipment[], curSuit?: string) => {
// 套装
const item_suits = total.filter((equip) => equip.suit.length == 1)
const suits: (IEquipment | undefined)[] = []
@@ -215,10 +214,10 @@ export const formatStone = (total: IEquipment[],curSuit?:string) => {
const items_sj = total.filter((equip) => equip.categorize.includes('神界'))
const sj: (IEquipment | undefined)[] = []
// const raritiy = Array.from(new Set(items_suits_rzs.map((item) => item.rarity)))
sj.push(...items_sj, ...Array(rowCount * 2 - (items_sj.length%rowCount)).fill(undefined))
// const temp = items_suits_rzs.filter((item) => item.itemDetailType === part)
// const remind = temp.length % rowCount
// rzs.push(...temp, ...Array(temp.length == 0 ? rowCount-remind : remind).fill(undefined))
sj.push(...items_sj, ...Array(rowCount * 2 - (items_sj.length % rowCount)).fill(undefined))
// const temp = items_suits_rzs.filter((item) => item.itemDetailType === part)
// const remind = temp.length % rowCount
// rzs.push(...temp, ...Array(temp.length == 0 ? rowCount-remind : remind).fill(undefined))
return [
{
name: `${curSuit} 套装`,
@@ -101,23 +101,27 @@ export default defineComponent({
</div>
) : (
<>
<div class="equ-profile-item">
<div class="row-name">品级</div>
<calc-select v-model={id.value} class="flex-1 !h-20px">
{renderList(basicInfoStore.avatars[part.value] ?? [], (item) => (
<calc-option value={item.id}>{item.suit}</calc-option>
))}
</calc-select>
</div>
<div class="equ-profile-item">
<div class="row-name">属性</div>
<calc-select v-model={option.value} class="flex-1 !h-20px">
<calc-option value={0}>无</calc-option>
{renderList(basicInfoStore.avatars[part.value].find(a=>a.id == id.value)?.options ?? [], (item) => (
<calc-option value={item}>{item}</calc-option>
))}
</calc-select>
</div>
<div class="equ-profile-item">
<div class="row-name">品级</div>
<calc-select v-model={id.value} class="flex-1 !h-20px">
{renderList(basicInfoStore.avatars[part.value] ?? [], (item) => (
<calc-option value={item.id}>{item.suit}</calc-option>
))}
</calc-select>
</div>
<div class="equ-profile-item">
<div class="row-name">属性</div>
<calc-select v-model={option.value} class="flex-1 !h-20px">
<calc-option value={0}>无</calc-option>
{renderList(
basicInfoStore.avatars[part.value].find((a) => a.id == id.value)?.options ??
[],
(item) => (
<calc-option value={item}>{item}</calc-option>
),
)}
</calc-select>
</div>
</>
)}
{has_socket.value ? (
@@ -1,28 +1,32 @@
<template>
<div>
<template v-for="key in ['0','1','2','3']" :key="key">
<div class="flex gap-2 mt-5px">
<calc-select class="flex-1 !h-20px" v-model="configStore.config.jades[key].id">
<calc-option :value="0">无</calc-option>
<calc-option v-for="(item, index) in infoStore.jades" :key="item.id" :value="item.id">
{{item.name}}
</calc-option>
</calc-select>
<!-- <calc-slider
<template v-for="key in ['0', '1', '2', '3']" :key="key">
<div class="flex gap-2 mt-5px">
<calc-select class="flex-1 !h-20px" v-model="configStore.config.jades[key].id">
<calc-option :value="0">无</calc-option>
<calc-option v-for="(item, index) in infoStore.jades" :key="item.id" :value="item.id">
{{ item.name }}
</calc-option>
</calc-select>
<!-- <calc-slider
v-model="configStore.config.jades[key].value"
:formatValue="formatValue(configStore.config.jades[key].id)"
:min="Number(currentJade(configStore.config.jades[key].id)?.min)"
:max="Number(currentJade(configStore.config.jades[key].id)?.max)"
:step="Number(currentJade(configStore.config.jades[key].id)?.pre)"
></calc-slider> -->
<calc-select class="flex-1 !h-20px" v-model="configStore.config.jades[key].value">
<calc-option v-for="(item, index) in valueList(configStore.config.jades[key].id)" :key="item.id" :value="item.id">
{{item.value}}
</calc-option>
</calc-select>
</div>
</template>
</div>
<calc-select class="flex-1 !h-20px" v-model="configStore.config.jades[key].value">
<calc-option
v-for="(item, index) in valueList(configStore.config.jades[key].id)"
:key="item.id"
:value="item.id"
>
{{ item.value }}
</calc-option>
</calc-select>
</div>
</template>
</div>
</template>
<script setup lang="ts">
@@ -40,50 +44,50 @@ const currentJade = computed(() => {
return undefined
} else {
const res = []
const cur = infoStore.jades?.find(e => e.id == id) as IJade
const cur = infoStore.jades?.find((e) => e.id == id) as IJade
return cur
}
}
})
const formatValue = (id: number) => {
return (value:number) =>{
if(currentJade.value(id)?.unit.includes('等级')){
return `$等级 +${value}`
}
return `${getFloat(value, 1)}${currentJade.value(id)?.unit}`
return (value: number) => {
if (currentJade.value(id)?.unit.includes('等级')) {
return `$等级 +${value}`
}
return `${getFloat(value, 1)}${currentJade.value(id)?.unit}`
}
}
const valueList = computed(() => {
return function (id: number = -1) {
if (id == -1) {
return undefined
if (id == -1) {
return undefined
} else {
const res = []
const cur = infoStore.jades?.find((e) => e.id == id) as IJade
if (cur) {
const { max, min, unit, pre } = cur
//
if (unit.includes('等级')) {
res.push({
id: 1,
value: unit,
})
} else {
const res = []
const cur = infoStore.jades?.find(e => e.id == id) as IJade
if (cur) {
const { max, min, unit, pre } = cur
//
if (unit.includes('等级')) {
for (let i = Number(max) as number; i >= Number(min); ) {
if (i != 0) {
res.push({
id: 1,
value: unit
id: i,
value: (i > 0 ? '+' : '') + getFloat(i, 1) + unit,
})
} else {
for (let i = Number(max) as number; i >= Number(min);) {
if (i != 0) {
res.push({
id: i,
value: (i > 0 ? "+" : "") + getFloat(i, 1) + unit
})
}
i = Number((i - Number(pre)).toFixed(1))
}
}
return res
i = Number((i - Number(pre)).toFixed(1))
}
}
return res
}
})
}
}
})
</script>
+18 -18
View File
@@ -1,26 +1,26 @@
<template>
<div class="w-420px">
<calc-collapse class="w-100%" title="装备/时装打造(点击部位切换)">
<calc-tabs v-model="partTab" class="!mb-2">
<calc-tab :value="0">装备栏</calc-tab>
<calc-tab :value="1">时装栏</calc-tab>
</calc-tabs>
<equipment v-if="partTab === 0"></equipment>
<clothes v-if="partTab === 1"></clothes>
</calc-collapse>
<calc-collapse class="w-100%" title="辟邪玉">
<jade></jade>
</calc-collapse>
<calc-collapse class="w-100%" title="其它">
<sundry></sundry>
</calc-collapse>
</div>
<calc-collapse class="w-100%" title="装备/时装打造(点击部位切换)">
<calc-tabs v-model="partTab" class="!mb-2">
<calc-tab :value="0">装备栏</calc-tab>
<calc-tab :value="1">时装栏</calc-tab>
</calc-tabs>
<equipment v-if="partTab === 0"></equipment>
<clothes v-if="partTab === 1"></clothes>
</calc-collapse>
<calc-collapse class="w-100%" title="辟邪玉">
<jade></jade>
</calc-collapse>
<calc-collapse class="w-100%" title="其它">
<sundry></sundry>
</calc-collapse>
</div>
</template>
<script setup lang="ts">
import equipment from './components/Equipments.vue'
import clothes from './components/Avatars.vue';
import jade from './components/Jades.vue';
import sundry from './components/Sundry.vue';
import clothes from './components/Avatars.vue'
import jade from './components/Jades.vue'
import sundry from './components/Sundry.vue'
const partTab = ref(0)
</script>
+1 -1
View File
@@ -81,7 +81,7 @@ onUnmounted(() => {
align-items: center;
z-index: 2;
height: 40px;
gap : 10px;
gap: 10px;
}
.content {
+13 -4
View File
@@ -11,8 +11,17 @@
:equs="configStore.config.equips"
></Info>
</div>
<Skill v-if="!configStore.result.state.buffer" :data="configStore.result.state.skills" :standard="infoStore.standard"></Skill>
<BufferSkill v-else :data="configStore.result.state.skills" :stadard="infoStore.standard" :standard="infoStore.standard"></BufferSkill>
<Skill
v-if="!configStore.result.state.buffer"
:data="configStore.result.state.skills"
:standard="infoStore.standard"
></Skill>
<BufferSkill
v-else
:data="configStore.result.state.skills"
:stadard="infoStore.standard"
:standard="infoStore.standard"
></BufferSkill>
</div>
</template>
@@ -27,8 +36,8 @@ const configStore = useConfigStore()
const infoStore = useInfoStore()
const setStandard = () => {
if(!configStore?.result?.state?.uuid) return
infoStore.setStandard(configStore.result.state,configStore.skillCountConfig)
if (!configStore?.result?.state?.uuid) return
infoStore.setStandard(configStore.result.state, configStore.skillCountConfig)
}
const clearStandard = () => {
@@ -33,7 +33,9 @@
</div>
<div>{{ skill.name }}</div>
</div>
<div class="w-50px flex items-center justify-center">{{ typeof skill.cd === 'number' ? `${skill.cd.toFixed(1)}s` : '-' }}</div>
<div class="w-50px flex items-center justify-center">
{{ typeof skill.cd === 'number' ? `${skill.cd.toFixed(1)}s` : '-' }}
</div>
<component :is="formatDamage(skill)"></component>
</div>
</div>
@@ -82,7 +84,7 @@ const data = computed(() => {
// @ts-ignore
bValue = b[sort.value]
}
const key = ['MAIN', 'ATK','STRINT', 'ratio'].findIndex((a) => sort.value == a)
const key = ['MAIN', 'ATK', 'STRINT', 'ratio'].findIndex((a) => sort.value == a)
aValue = a.buff?.[key]
bValue = b.buff?.[key]
@@ -149,46 +151,52 @@ const formatDamage = (skill: IResultSkill) => {
'div',
{
class: 'flex items-center justify-center',
},[0, 1, 2, 3].map((index) => {
const value = skill.buff?.[index] - standardSkill.buff?.[index]
return h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '80px',
color: value >= 0 ? '#37fa38' : '#ff0000',
},
[0, 1, 2, 3].map((index) => {
const value = skill.buff?.[index] - standardSkill.buff?.[index]
return h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '80px',
color: value >= 0 ? '#37fa38' : '#ff0000',
},
},
},
`${value >= 0 ? '+':''}${index == 3
? `${Math.round(value).toLocaleString()}%`
: Math.round(value).toLocaleString()}`
)
}))
`${value >= 0 ? '+' : ''}${
index == 3
? `${Math.round(value).toLocaleString()}%`
: Math.round(value).toLocaleString()
}`,
)
}),
)
} else {
return h(
'div',
{
class: 'flex items-center justify-center',
},[0, 1, 2, 3].map((index) => {
const value = skill.buff?.[index]
return h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '80px',
},
[0, 1, 2, 3].map((index) => {
const value = skill.buff?.[index]
return h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '80px',
},
},
},
index == 3
? `${Math.round(value).toLocaleString()}%`
: Math.round(value).toLocaleString(),
)
}))
index == 3
? `${Math.round(value).toLocaleString()}%`
: Math.round(value).toLocaleString(),
)
}),
)
}
}
</script>
@@ -3,7 +3,7 @@
<div class="h-177px">
<EquList
:detail="props.equs"
:with-sub-weapon="(infoStore.infos?.subweapons?.length ?? 0)> 0"
:with-sub-weapon="(infoStore.infos?.subweapons?.length ?? 0) > 0"
></EquList>
</div>
<div class="flex flex-wrap border-y-1px my-1px border-y-solid border-#FFFF/10 gap-1% px-1%">
@@ -12,7 +12,7 @@
]"
:key="key"
class="item-head"
:style="{width: `${header.width}px`}"
:style="{ width: `${header.width}px` }"
@click="header.sortKey && sortValue(header.sortKey)"
>
{{ header.label }}
@@ -44,13 +44,18 @@
<component :is="formatDamage(skill)"></component>
</div>
</div>
<div v-if="!totalStandard" class="h-40px flex items-center justify-center text-18px border-t-1px border-t-solid border-t-#FFFF/15">{{showTotal.toFixed(0)}}</div>
<div
v-if="!totalStandard"
class="h-40px flex items-center justify-center text-18px border-t-1px border-t-solid border-t-#FFFF/15"
>
{{ showTotal.toFixed(0) }}
</div>
<div
v-else
class="h-40px flex items-center justify-center text-18px border-t-1px border-t-solid border-t-#FFFF/15"
:style="{color:showTotal >= 0 ? '#37fa38' : '#ff0000'}"
>
{{showTotal.toFixed(2)}}%
:style="{ color: showTotal >= 0 ? '#37fa38' : '#ff0000' }"
>
{{ showTotal.toFixed(2) }}%
</div>
</div>
</div>
@@ -84,11 +89,11 @@ const data = computed(() => {
// @ts-ignore
bValue = b[sort.value]
}
if( sort.value == 'total'){
if (sort.value == 'total') {
aValue = a.damage * skillCount(a).value
bValue = b.damage * skillCount(b).value
}
if(sort.value == 'dps'){
if (sort.value == 'dps') {
aValue = a.damage / a.cd
bValue = b.damage / b.cd
}
@@ -152,7 +157,7 @@ const totalStandard = computed(() => {
const showTotal = computed(() => {
if (!totalStandard.value || totalStandard.value == 0) return totalDamage.value
return (totalDamage.value - totalStandard.value) / totalStandard.value * 100
return ((totalDamage.value - totalStandard.value) / totalStandard.value) * 100
})
const formatDamage = (skill: IResultSkill) => {
@@ -101,7 +101,7 @@ export default defineComponent({
<div
class={[
'w-36px absolute h-48px flex flex-col box-border items-center py-3px z-2',
(skill.learnLv == 100 && skill.bind) ? '' : 'skill',
skill.learnLv == 100 && skill.bind ? '' : 'skill',
]}
onClick={(e) => {
e.stopPropagation()
@@ -10,25 +10,26 @@
}
.passive {
filter: grayscale(100%) invert(3%) sepia(14%) saturate(874%) hue-rotate(65deg) brightness(105%) contrast(102%);
filter: grayscale(100%) invert(3%) sepia(14%) saturate(874%) hue-rotate(65deg) brightness(105%)
contrast(102%);
}
.skill{
.skill {
background-image: url('./img/skill.png');
background-size: 100% 100%;
}
.skill-active{
.skill-active {
background-image: url('./img/skillActive.png');
background-size: 100% 100%;
}
.awake_50{
.awake_50 {
background-image: url('./img/awake_50.png');
background-size: 100% 100%;
}
.awake_85{
.awake_85 {
background-image: url('./img/awake_85.png');
background-size: 100% 100%;
}
+5 -2
View File
@@ -1,12 +1,15 @@
<template>
<div>
<div class="h-90vh w-auto overflow-y-auto overflow-x-hidden">
<SkillTree :skills="infoStore.skills" v-model:lvInfo="configStore.config.skills" v-model:bindAwake="configStore.config.bindAwake"></SkillTree>
<SkillTree
:skills="infoStore.skills"
v-model:lvInfo="configStore.config.skills"
v-model:bindAwake="configStore.config.bindAwake"
></SkillTree>
</div>
</div>
</template>
<script lang="ts" setup name="Index">
import { useInfoStore } from '@/stores/info'
import SkillTree from './components/SkillTree/index'
+9 -8
View File
@@ -18,21 +18,20 @@ export default defineComponent(async () => {
function choose_job(child: IAlterInfo) {
return async () => {
if (child.comment == '首页') {
return window.open("https://dnftools.com","_blank")
return window.open('https://dnftools.com', '_blank')
}
if (child.name == 'sponsor') {
return window.open((child.url ?? ''),"_blank")
return window.open(child.url ?? '', '_blank')
}
if (child.open) {
const options = child.options ?? []
if (options.length > 0) {
return
} else {
return window.open('/character/' + (child.value || child.name), '_blank')
}
else{
return window.open("/character/" + (child.value || child.name),"_blank")
}
}
}
}
// router.push("/character/" + alter)
}
@@ -40,12 +39,14 @@ export default defineComponent(async () => {
// let checkTimer: NodeJS.Timeout
const adventure = await api.adventures()
return () => (
<Fragment>
<div class="bg-no-repeat h-auto min-h-full pt-8 pb-12 pl-4" style={`background-image: url('${getImageURL('home.jpg')}');background-size: 100% 100%;`}>
<div
class="bg-no-repeat h-auto min-h-full pt-8 pb-12 pl-4"
style={`background-image: url('${getImageURL('home.jpg')}');background-size: 100% 100%;`}
>
{renderList(adventure, (job) => (
<div class="flex flex-row">
<div
+2 -2
View File
@@ -3,12 +3,12 @@
<Suspense>
<RouterView></RouterView>
</Suspense>
<render/>
<render />
</div>
</template>
<script lang="ts" name="index" setup>
import { useDialog } from '@/components/hooks/dialog';
import { useDialog } from '@/components/hooks/dialog'
const { render } = useDialog()
</script>