This commit is contained in:
2026-05-28 00:30:56 +08:00
parent e834912f2c
commit 031c8c1cc7
4 changed files with 365 additions and 332 deletions
@@ -188,8 +188,18 @@ const selectOathSkill = (skill: { skillId: string; enable: boolean }) => {
/* ─── Equipped items list ─── */ /* ─── Equipped items list ─── */
const partOrder = [ const partOrder = [
"武器", "上衣", "下装", "头肩", "腰带", "鞋", "武器",
"项链", "手镯", "戒指", "辅助装备", "魔法石", "耳环", "上衣",
"下装",
"头肩",
"腰带",
"鞋",
"项链",
"手镯",
"戒指",
"辅助装备",
"魔法石",
"耳环",
]; ];
const equById = (id: string) => infoStore.equips.find((item) => item.id === id); const equById = (id: string) => infoStore.equips.find((item) => item.id === id);
@@ -201,16 +211,25 @@ const adaptation = (part: string) => {
const rarityColor = (rarity: string): string => { const rarityColor = (rarity: string): string => {
switch (rarity) { switch (rarity) {
case "太初": return "text-[#5aff62]"; case "太初":
return "text-[#5aff62]";
case "史诗": case "史诗":
case "智慧产物": return "text-[#fcb600]"; case "智慧产物":
case "神话": return "text-[#f8c63d]"; return "text-[#fcb600]";
case "神器": return "text-[#ef28c1]"; case "神话":
case "稀有": return "text-[#9879da]"; return "text-[#f8c63d]";
case "传说": return "text-[#ff7700]"; case "神器":
case "勇者": return "text-[#ff6666]"; return "text-[#ef28c1]";
case "高级": return "text-[#68d5ed]"; case "稀有":
default: return "text-[#fcb600]"; return "text-[#9879da]";
case "传说":
return "text-[#ff7700]";
case "勇者":
return "text-[#ff6666]";
case "高级":
return "text-[#68d5ed]";
default:
return "text-[#fcb600]";
} }
}; };
@@ -300,10 +319,7 @@ const clearChangeSources = () => configStore.clearChangeSource();
<span class="shrink-0 font-medium">{{ oathSuit.point }}点</span> <span class="shrink-0 font-medium">{{ oathSuit.point }}点</span>
</div> </div>
<!-- Oath skill selector --> <!-- Oath skill selector -->
<div <div v-if="oathSkillsSorted.length" class="flex items-center justify-center gap-4 pt-1">
v-if="oathSkillsSorted.length"
class="flex items-center justify-center gap-4 pt-1"
>
<button <button
v-for="skill in oathSkillsSorted" v-for="skill in oathSkillsSorted"
:key="skill.id" :key="skill.id"
@@ -370,7 +386,7 @@ const clearChangeSources = () => configStore.clearChangeSource();
:class=" :class="
rarityColor(equById(configStore.config.equips[part]?.id ?? '')?.rarity ?? '') rarityColor(equById(configStore.config.equips[part]?.id ?? '')?.rarity ?? '')
" "
>{{ equById(configStore.config.equips[part]?.id ?? '')?.name ?? "—" }}</span >{{ equById(configStore.config.equips[part]?.id ?? "")?.name ?? "—" }}</span
> >
</div> </div>
</div> </div>
@@ -115,7 +115,7 @@ const hasVisibleResult = computed(
<EquList <EquList
v-model:part="equippedPart" v-model:part="equippedPart"
:detail="configStore.config.equips" :detail="configStore.config.equips"
:with-sub-weapon="(infoStore.infos?.alter?.includes('vegabond') ?? false)" :with-sub-weapon="infoStore.infos?.alter?.includes('vegabond') ?? false"
:with-pet="true" :with-pet="true"
/> />
</div> </div>
@@ -25,9 +25,7 @@ const basic = computed(() => {
}, },
{ {
label: "施放时间", label: "施放时间",
value: !info.attribute.castingTime value: !info.attribute.castingTime ? "瞬发" : `${info.attribute.castingTime.toFixed(1)}秒`,
? "瞬发"
: `${info.attribute.castingTime.toFixed(1)}秒`,
}, },
{ label: "魔法值", value: info.attribute.consumeMp }, { label: "魔法值", value: info.attribute.consumeMp },
{ {
@@ -40,8 +38,7 @@ const basic = computed(() => {
const descLines = computed(() => skillInfo.value?.descDetail.split("\n") ?? []); const descLines = computed(() => skillInfo.value?.descDetail.split("\n") ?? []);
const detailLines = computed(() => { const detailLines = computed(() => {
const items = const items = skillInfo.value?.attribute.optionDesc?.split("\n").filter((item) => !!item) ?? [];
skillInfo.value?.attribute.optionDesc?.split("\n").filter((item) => !!item) ?? [];
return items.map((a) => { return items.map((a) => {
// highlight value placeholder prefix // highlight value placeholder prefix
const beforeReplace = a.match(/^(.+?)\s*(\{value\d+\}.*)$/); const beforeReplace = a.match(/^(.+?)\s*(\{value\d+\}.*)$/);
@@ -53,8 +50,7 @@ const detailLines = computed(() => {
matches.forEach((match) => { matches.forEach((match) => {
const key = match.replace(/[{}]/g, ""); const key = match.replace(/[{}]/g, "");
if (/^value.+/.test(key)) { if (/^value.+/.test(key)) {
const value = const value = skillInfo.value?.attribute.optionValue[key as `value${string}`] ?? "-";
skillInfo.value?.attribute.optionValue[key as `value${string}`] ?? "-";
a = a.replace( a = a.replace(
match, match,
`<span style="padding:0 2px;color:var(--color-skill-value,#4AA256)">${value}</span>`, `<span style="padding:0 2px;color:var(--color-skill-value,#4AA256)">${value}</span>`,
@@ -70,7 +66,10 @@ const hasEvolution = computed(() => (skillInfo.value?.evolution?.length ?? 0) >
</script> </script>
<template> <template>
<div v-if="!skillInfo" class="flex items-center justify-center h-16 text-xs text-muted-foreground"> <div
v-if="!skillInfo"
class="flex items-center justify-center h-16 text-xs text-muted-foreground"
>
加载中… 加载中…
</div> </div>
@@ -139,7 +138,9 @@ const hasEvolution = computed(() => (skillInfo.value?.evolution?.length ?? 0) >
<div class="text-xs font-semibold text-purple-400 mb-1.5">{{ evo.name }}</div> <div class="text-xs font-semibold text-purple-400 mb-1.5">{{ evo.name }}</div>
<div <div
class="text-xs leading-relaxed text-muted-foreground whitespace-pre-wrap max-h-36 overflow-y-auto" class="text-xs leading-relaxed text-muted-foreground whitespace-pre-wrap max-h-36 overflow-y-auto"
>{{ evo.descDetail }}</div> >
{{ evo.descDetail }}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -337,15 +337,23 @@ const resetAllSkills = () => {
: '', : '',
]" ]"
/> />
<div v-if="activeSkillId === skill.id.toString()" class="action-row" @click.stop> <div
<button class="skill-btn" @click.stop="resetLv(skill.id.toString())">«</button> v-if="activeSkillId === skill.id.toString()"
class="action-row"
@click.stop
>
<button class="skill-btn" @click.stop="resetLv(skill.id.toString())">
«
</button>
<button class="skill-btn" @click.stop="stepLv(skill.id.toString(), -1)"> <button class="skill-btn" @click.stop="stepLv(skill.id.toString(), -1)">
‹ ‹
</button> </button>
<button class="skill-btn" @click.stop="stepLv(skill.id.toString(), 1)"> <button class="skill-btn" @click.stop="stepLv(skill.id.toString(), 1)">
› ›
</button> </button>
<button class="skill-btn" @click.stop="setMaxLv(skill.id.toString())">»</button> <button class="skill-btn" @click.stop="setMaxLv(skill.id.toString())">
»
</button>
</div> </div>
<div <div
v-else v-else
@@ -391,8 +399,14 @@ const resetAllSkills = () => {
: '', : '',
]" ]"
/> />
<div v-if="activeSkillId === cell.id.toString()" class="action-row" @click.stop> <div
<button class="skill-btn" @click.stop="resetLv(cell.id.toString())">«</button> v-if="activeSkillId === cell.id.toString()"
class="action-row"
@click.stop
>
<button class="skill-btn" @click.stop="resetLv(cell.id.toString())">
«
</button>
<button class="skill-btn" @click.stop="stepLv(cell.id.toString(), -1)"> <button class="skill-btn" @click.stop="stepLv(cell.id.toString(), -1)">
‹ ‹
</button> </button>
@@ -616,7 +630,9 @@ const resetAllSkills = () => {
> >
形态 {{ mode }} 形态 {{ mode }}
</div> </div>
<div class="mt-0.5 text-[10px] text-muted-foreground leading-tight line-clamp-2"> <div
class="mt-0.5 text-[10px] text-muted-foreground leading-tight line-clamp-2"
>
{{ skill.vps[mode - 1]?.name || "—" }} {{ skill.vps[mode - 1]?.name || "—" }}
</div> </div>
</button> </button>