This commit is contained in:
2025-04-02 22:54:17 +08:00
parent 5b03724adf
commit cc93acd743
18 changed files with 476 additions and 62 deletions
+1
View File
@@ -26,6 +26,7 @@ export interface ICharacterInfo {
name: string
equVersion: string
equips: IEquipment[]
stones: IEquipment[]
enchants: IEnchantingInfo[]
emblems: IEnchantingInfo[]
weapons: string[]
@@ -1,13 +1,25 @@
<template>
<div class="flex flex-col mx-10px">
<calc-collapse title="武器">
<calc-collapse title="武器/称号/宠物">
<Weapon></Weapon>
</calc-collapse>
<calc-collapse title="套装">
<Suit></Suit>
<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="通宝">
<Universal></Universal>
<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>
@@ -17,10 +29,16 @@ import { useInfoStore } from '@/stores/info'
import { getImageURL } from '@/utils/images'
import Suit from './components/Suit.vue'
import Weapon from './components/Weapon.vue'
import Stone from './components/Stone.vue'
import Universal from './components/Universal.vue'
import StoneUniversal from './components/StoneUniversal.vue'
import StoneOld from './components/StoneOld.vue'
import { useConfigStore } from '@/stores'
const props = defineProps<{
alter: string
}>()
const equTab = ref(0)
const stoneTab = ref(0)
</script>
@@ -0,0 +1,93 @@
<!-- 每排总计6+4+4,共计14个排列 -->
<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"
/>
</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)"/>
</template>
<template v-else>
<EquipmentIcon/>
</template>
</template>
</div>
</div>
</template>
<script lang="ts" setup>
import type { IEquipment } from '@/api/info/type'
import { useConfigStore, useInfoStore } from '@/stores'
import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
import EquipmentRaritySelect from '@/components/dnf/Equipment/RaritySelect/index.vue'
const infoStore = useInfoStore()
const configStore = useConfigStore()
const curSuit = ref(16201)
const curRarity = ref()
const props = defineProps<{
rowCount?:number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
const suits = computed(() => {
const uniqueSuits = new Map<number, { name: string; value: number; imageUrl: string }>()
infoStore.suits.forEach((a) => {
if (!uniqueSuits.has(a.suitId)) {
uniqueSuits.set(a.suitId, { name: a.name, value: a.suitId, imageUrl: a.imageUrl })
}
})
return Array.from(uniqueSuits.values())
})
const suitEquipments = computed(() => {
const equs = infoStore.stones.filter((a) => a.suit.includes(curSuit.value.toString()) && a.suit.length === 1 )
const res: (IEquipment | undefined)[] = []
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),
)
})
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)
})
}
</script>
@@ -0,0 +1,58 @@
`<!-- 每排总计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)" />
</template>
</div>
</template>
<script lang="ts" setup StoneUniversal>
import type { IEquipment } from '@/api/info/type'
import { useConfigStore, useInfoStore } from '@/stores'
import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const props = defineProps<{
rowCount ?:number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
const infoStore = useInfoStore()
const configStore = useConfigStore()
const equs = computed(() => {
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),
);
['手镯','项链','戒指','','辅助装备','魔法石','耳环',''].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) => {
// 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
})
</script>
`
@@ -0,0 +1,44 @@
<!-- 每排总计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)" />
</template>
</div>
</template>
<script lang="ts" setup StoneUniversal>
import type { IEquipment } from '@/api/info/type'
import { useConfigStore, useInfoStore } from '@/stores'
import { getImageURL } from '@/utils/images'
import EquipmentIcon from '@/components/dnf/Equipment/Icon/index.vue'
const props = defineProps<{
rowCount ?:number
}>()
const rowCount = Math.max(props.rowCount ?? 0, 14)
const infoStore = useInfoStore()
const configStore = useConfigStore()
const equs = computed(() => {
const items = infoStore.stones.filter(
(equip) => equip.categorize.includes('通宝'),
)
const res: (IEquipment | undefined)[] = []
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),
)
})
})
return res
})
</script>
@@ -24,7 +24,7 @@
<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="chooseEqu(equip)"/>
<EquipmentIcon :equipment="equip" :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id" @click="configStore.chooseEqu(equip)"/>
</template>
<template v-else>
@@ -82,19 +82,11 @@ const suitEquipments = computed(() => {
return res
})
const chooseEqu = async(equip: IEquipment | undefined) => {
if (equip && configStore.config.equips[equip.itemDetailType]) {
configStore.config.equips[equip.itemDetailType].id = equip.id
}
// await configStore.calc()
}
const handleDoubleClick = () => {
if(!curRarity.value) return
if(curRarity.value == '太初') return
suitEquipments.value.filter(a=>!!a && a.rarity == curRarity.value).splice(0,11).forEach((a) => {
chooseEqu(a)
configStore.chooseEqu(a)
})
}
@@ -3,7 +3,7 @@
<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="chooseEqu(equip)" />
<EquipmentIcon :inactive="configStore.config.equips[equip?.itemDetailType ?? '']?.id != equip?.id" :equipment="equip" @click="configStore.chooseEqu(equip)" />
</template>
</div>
</template>
@@ -39,10 +39,4 @@ const equs = computed(() => {
})
return res
})
const chooseEqu = async(equip: IEquipment | undefined) => {
if (equip && configStore.config.equips[equip.itemDetailType]) {
configStore.config.equips[equip.itemDetailType].id = equip.id
}
}
</script>
@@ -3,7 +3,7 @@
<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="chooseWeapon(weapon)"/>
<EquipmentIcon :equipment="weapon" :inactive="configStore.config.equips['武器']?.id != weapon?.id" @click="configStore.chooseEqu(weapon)"/>
</template>
</div>
</template>
@@ -40,10 +40,4 @@ const weapons = computed(() => {
return res
})
const chooseWeapon = (weapon: IEquipment | undefined) => {
if (weapon) {
configStore.config.equips['武器'].id = weapon.id
}
console.log(configStore.config)
}
</script>
@@ -80,7 +80,7 @@ export default defineComponent({
)
}
}
if (['reinforce_type', 'reinforce'].includes(name)) {
if (['reinforceType', 'reinforce','adaptation'].includes(name)) {
parts = basicInfoStore.parts.filter((e) => !['称号', '宠物'].includes(e))
}
} else {
@@ -105,7 +105,7 @@ export default defineComponent({
const emblem_1 = currentInfo<string | number>('emblem_1')
// 增幅
const reinforce_type = currentInfo<string | number>('reinforce_type', 1)
const reinforce_type = currentInfo<string | number>('reinforceType', 1)
// 增幅数值
const reinforce = currentInfo<string | number>('reinforce')
@@ -150,8 +150,8 @@ export default defineComponent({
<div class="equ-profile-item">
<div class="row-name">增幅</div>
<calc-select v-model={reinforce_type.value} class="flex-1 !h-20px">
<calc-option value={0}>增幅</calc-option>
<calc-option value={1}>强化</calc-option>
<calc-option value={0}>强化</calc-option>
<calc-option value={1}>增幅</calc-option>
</calc-select>
<calc-select v-model={reinforce.value} class="flex-1 !h-20px">
{renderList(31, (i) => (
+16 -1
View File
@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import { useInfoStore } from './info'
import api from '@/api'
import type { IEquipment } from '@/api/info/type'
// | '上衣'
// | '头肩'
// | '下装'
@@ -27,6 +28,7 @@ export interface IConfig {
upgrade: number
refine: number
adaptation: number
fusion: string
}
>
jades: Record<string, number>
@@ -42,6 +44,7 @@ const defaultEqusConfig = {
upgrade: 0,
refine: 0,
adaptation: 0,
fusion: '',
}
export const useConfigStore = defineStore('configStore', () => {
@@ -102,6 +105,17 @@ export const useConfigStore = defineStore('configStore', () => {
return await api.calc(config.value)
}
const chooseEqu = async(equip: IEquipment | undefined,isFusion:boolean = false) => {
if (equip && config.value.equips[equip.itemDetailType]) {
const key = isFusion ? 'fusion' : 'id'
if (config.value.equips[equip.itemDetailType][key] == equip.id) {
config.value.equips[equip.itemDetailType][key] = ""
} else {
config.value.equips[equip.itemDetailType][key] = equip.id
}
}
}
const result = useAsyncState(
() => {
@@ -119,6 +133,7 @@ export const useConfigStore = defineStore('configStore', () => {
loadConfig,
saveConfig,
calc,
result
result,
chooseEqu
}
})
+3
View File
@@ -16,6 +16,8 @@ export const useInfoStore = defineStore('infoStore', () => {
const emblems = computed(() => infos.value?.emblems ?? [])
const stones = computed(() => infos.value?.stones ?? [])
const parts = [
'头肩',
'上衣',
@@ -49,5 +51,6 @@ export const useInfoStore = defineStore('infoStore', () => {
enchants,
emblems,
parts,
stones
}
})