♻️ wiki材料项组件提取&UI改版

This commit is contained in:
BTMuli
2025-12-19 18:26:13 +08:00
parent 216f10efbd
commit 86013fac72
6 changed files with 158 additions and 171 deletions

View File

@@ -1,12 +1,12 @@
<!-- 背包材料物品项 -->
<template>
<div :title="props.info.name" class="pb-mi-box" @click="toMaterial()">
<div class="pb-mi-left">
<div :title="props.info.name" class="pwm-box" @click="toMaterial()">
<div class="pwm-left">
<img :src="`/icon/bg/${props.info.star}-Star.webp`" alt="bg" class="bg" />
<img :src="`/icon/material/${props.info.id}.webp`" alt="icon" class="icon" />
</div>
<div class="pb-mi-right">{{ props.info.name }}</div>
<div class="pb-mi-id">{{ props.info.type }}·{{ props.info.id }}</div>
<div class="pwm-right">{{ props.info.name }}</div>
<div class="pwm-extra">{{ props.info.type }}·{{ props.info.id }}</div>
<div class="pb-mi-cnt">{{ item.count }}</div>
</div>
</template>
@@ -51,7 +51,7 @@ const idColor = computed<string>(() => getOdStarColor(props.info.star));
<style lang="scss" scoped>
@use "@styles/github.styles.scss" as github-styles;
.pb-mi-box {
.pwm-box {
position: relative;
display: flex;
overflow: hidden;
@@ -66,7 +66,7 @@ const idColor = computed<string>(() => getOdStarColor(props.info.star));
cursor: pointer;
}
.pb-mi-left {
.pwm-left {
position: relative;
height: 100%;
flex-shrink: 0;
@@ -81,7 +81,7 @@ const idColor = computed<string>(() => getOdStarColor(props.info.star));
}
}
.pb-mi-right {
.pwm-right {
position: relative;
overflow: hidden;
max-width: 100%;
@@ -92,7 +92,7 @@ const idColor = computed<string>(() => getOdStarColor(props.info.star));
word-break: break-all;
}
.pb-mi-id {
.pwm-extra {
position: absolute;
z-index: 1;
right: 2px;

View File

@@ -0,0 +1,74 @@
<!-- WIKI 材料项 -->
<template>
<div :title="props.material.name" class="pw-mi-box">
<div class="pw-mi-left">
<img :src="`/icon/bg/${props.material.star}-Star.webp`" alt="bg" class="bg" />
<img :src="`/icon/material/${props.material.id}.webp`" alt="icon" class="icon" />
</div>
<div class="pw-mi-right">{{ props.material.name }}</div>
<div class="pw-mi-extra">{{ props.material.type }}·{{ props.material.id }}</div>
</div>
</template>
<script lang="ts" setup>
import { getOdStarColor } from "@utils/colorFunc.js";
import { computed } from "vue";
type PbMaterialItemProps = { material: TGApp.App.Material.WikiItem };
const props = defineProps<PbMaterialItemProps>();
const idColor = computed<string>(() => getOdStarColor(props.material.star));
</script>
<style lang="scss" scoped>
@use "@styles/github.styles.scss" as github-styles;
.pw-mi-box {
position: relative;
display: flex;
overflow: hidden;
height: 48px;
align-items: center;
justify-content: flex-start;
padding-right: 8px;
border: 1px solid var(--common-shadow-1);
border-radius: 4px;
background: var(--box-bg-1);
column-gap: 4px;
}
.pw-mi-left {
position: relative;
height: 100%;
flex-shrink: 0;
aspect-ratio: 1;
.bg,
.icon {
position: absolute;
top: 0;
width: 100%;
height: 100%;
}
}
.pw-mi-right {
position: relative;
overflow: hidden;
max-width: 100%;
color: var(--box-text-2);
font-size: 14px;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
}
.pw-mi-extra {
position: absolute;
z-index: 1;
right: 2px;
bottom: 0;
color: v-bind(idColor); /* stylelint-disable-line value-keyword-case */
font-size: 8px;
font-style: italic;
opacity: 0.8;
}
</style>

View File

@@ -1,39 +1,31 @@
<!-- 角色/武器材料列表 -->
<template>
<div class="twc-materials-grid">
<div
class="twc-material-box"
v-for="(item, index) in props.data"
<div class="pw-ml-box">
<PwMaterialItem
v-for="(material, index) in materialList"
:key="index"
@click="checkData(item, index)"
>
<div class="twc-material-left">
<div class="twc-material-bg">
<img :src="`/icon/bg/${item.star}-Star.webp`" alt="bg" />
</div>
<div class="twc-material-icon">
<img :src="`/icon/material/${item.id}.webp`" alt="icon" />
</div>
</div>
<div class="twc-material-right">{{ item.name }}</div>
</div>
:material
@click="checkData(material, index)"
/>
</div>
<TwoMaterial :data="curData" v-model="showOverlay">
<TwoMaterial v-model="showOverlay" :data="curData">
<template #left>
<div class="card-arrow" @click="switchMaterial(false)">
<img src="@/assets/icons/arrow-right.svg" alt="right" />
<img alt="right" src="@/assets/icons/arrow-right.svg" />
</div>
</template>
<template #right>
<div class="card-arrow" @click="switchMaterial(true)">
<img src="@/assets/icons/arrow-right.svg" alt="right" />
<img alt="right" src="@/assets/icons/arrow-right.svg" />
</div>
</template>
</TwoMaterial>
</template>
<script lang="ts" setup>
import showSnackbar from "@comp/func/snackbar.js";
import { ref, shallowRef } from "vue";
import { ref, shallowRef, watch } from "vue";
import PwMaterialItem from "./pw-material-item.vue";
import TwoMaterial from "./two-material.vue";
import { WikiMaterialData } from "@/data/index.js";
@@ -43,6 +35,7 @@ type TwcMaterialsProp = { data: Array<TGApp.App.Calendar.Material> };
const props = defineProps<TwcMaterialsProp>();
const showOverlay = ref<boolean>(false);
const curIndex = ref<number>(0);
const materialList = shallowRef<Array<TGApp.App.Material.WikiItem>>(loadData());
const curData = shallowRef<TGApp.App.Material.WikiItem>({
id: 0,
name: "",
@@ -53,16 +46,25 @@ const curData = shallowRef<TGApp.App.Material.WikiItem>({
convert: [],
});
function checkData(item: TGApp.App.Calendar.Material, index: number): void {
if (showOverlay.value) showOverlay.value = false;
const material = WikiMaterialData.find((m) => m.id === item.id);
if (material) {
curData.value = material;
curIndex.value = index;
showOverlay.value = true;
return;
watch(
() => props.data,
() => (materialList.value = loadData()),
);
function loadData(): Array<TGApp.App.Material.WikiItem> {
const tmp: Array<TGApp.App.Material.WikiItem> = [];
for (const d of props.data) {
const material = WikiMaterialData.find((m) => m.id === d.id);
if (material) tmp.push(material);
}
showSnackbar.warn(`材料 ${item.name} 暂无详细信息`);
return tmp;
}
function checkData(item: TGApp.App.Material.WikiItem, index: number): void {
if (showOverlay.value) showOverlay.value = false;
curData.value = item;
curIndex.value = index;
showOverlay.value = true;
}
function switchMaterial(isNext: boolean): void {
@@ -91,58 +93,13 @@ function switchMaterial(isNext: boolean): void {
}
</script>
<style lang="css" scoped>
.twc-materials-grid {
.pw-ml-box {
display: grid;
width: 100%;
grid-gap: 5px;
gap: 8px;
grid-template-columns: repeat(3, 1fr);
}
.twc-material-box {
position: relative;
display: flex;
height: 45px;
border: 1px solid var(--common-shadow-1);
border-radius: 5px;
background: var(--box-bg-1);
cursor: pointer;
gap: 10px;
}
.twc-material-left {
width: 45px;
height: 45px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.twc-material-bg,
.twc-material-icon {
position: absolute;
top: 0;
width: 45px;
height: 45px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.twc-material-bg img,
.twc-material-icon img {
width: 100%;
height: 100%;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
object-fit: cover;
}
.twc-material-right {
display: flex;
align-items: center;
justify-content: center;
color: var(--box-text-2);
font-size: 14px;
}
.card-arrow {
position: relative;
display: flex;

View File

@@ -1,5 +1,6 @@
<!-- 角色WIKI详情 -->
<template>
<div class="twc-box" v-if="data !== undefined">
<div v-if="data !== undefined" class="twc-box">
<div class="twc-brief">
<TItembox :model-value="box" />
<div class="twc-brief-info">
@@ -8,11 +9,11 @@
<span>{{ data.name }}</span>
<span>{{ data.title }}</span>
<img
title="前往观测枢"
alt="observer"
@click="toWiki()"
v-if="props.item.contentId !== 0"
alt="observer"
src="/platforms/mhy/observer.webp"
title="前往观测枢"
@click="toWiki()"
/>
</div>
<div class="twc-bi-desc">{{ data.description }}</div>
@@ -55,8 +56,8 @@
</div>
</div>
</div>
<TopNameCard :data="nameCard" @selected="showNc = !showNc" v-if="nameCard" />
<TwcMaterials :data="data.materials" />
<TopNameCard v-if="nameCard" :data="nameCard" @selected="showNc = !showNc" />
<PwMaterialList :data="data.materials" />
<TwcSkills :data="data.skills" />
<TwcConstellations :data="data.constellation" />
<v-expansion-panels class="twc-text-item">
@@ -65,9 +66,9 @@
<template #text>
<v-expansion-panels variant="popout">
<v-expansion-panel
expand-icon="mdi-menu-down"
v-for="(item, index) in data?.talks"
:key="index"
expand-icon="mdi-menu-down"
>
<template #title>
<span class="twc-text-item-title">{{ item.Title }}</span>
@@ -84,9 +85,9 @@
<template #text>
<v-expansion-panels variant="popout">
<v-expansion-panel
expand-icon="mdi-menu-down"
v-for="(item, index) in data.stories"
:key="index"
expand-icon="mdi-menu-down"
>
<template #title>
<span class="twc-text-item-title">{{ item.Title }}</span>
@@ -102,7 +103,7 @@
<ToNameCard v-if="hasNc" v-model="showNc" :data="nameCard" />
</div>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import TItembox, { type TItemBoxData } from "@comp/app/t-itemBox.vue";
import ToNameCard from "@comp/app/to-nameCard.vue";
import TopNameCard from "@comp/app/top-nameCard.vue";
@@ -112,8 +113,8 @@ import { parseHtmlText } from "@utils/toolFunc.js";
import { computed, onMounted, ref, shallowRef, watch } from "vue";
import { useRouter } from "vue-router";
import PwMaterialList from "./pw-material-list.vue";
import TwcConstellations from "./twc-constellations.vue";
import TwcMaterials from "./twc-materials.vue";
import TwcSkills from "./twc-skills.vue";
import { AppCharacterData, AppNameCardsData, getWikiCharacterById } from "@/data/index.js";

View File

@@ -1,31 +1,32 @@
<!-- 武器WIKI详情 -->
<template>
<div class="tww-box" v-if="data !== undefined">
<div v-if="data" class="tww-box">
<div class="tww-brief">
<TItemBox :model-value="box" />
<div class="tww-brief-info">
<div class="tww-brief-title">
<span>{{ data.name }}</span>
<img
title="前往观测枢"
alt="observer"
@click="toWiki()"
v-if="props.item.contentId !== 0"
alt="observer"
src="/platforms/mhy/observer.webp"
title="前往观测枢"
@click="toWiki()"
/>
</div>
<v-rating
v-if="data.affix"
class="tww-brief-rating"
v-model="select"
:length="selectItems.length"
:size="24"
class="tww-brief-rating"
dense
/>
<div class="tww-brief-desc">{{ data.description }}</div>
</div>
</div>
<TwcMaterials :data="data.materials" />
<v-expansion-panels class="tww-affix" v-if="data.affix">
<PwMaterialList :data="data.materials" />
<v-expansion-panels v-if="data.affix" class="tww-affix">
<v-expansion-panel expand-icon="mdi-menu-down">
<template #title>
<span class="tww-text-title">{{ data.affix.Name }}-精炼 {{ select }}</span>
@@ -40,9 +41,9 @@
</v-expansion-panels>
<v-expansion-panels class="tww-story">
<v-expansion-panel
expand-icon="mdi-menu-down"
v-for="(story, index) in data.story"
:key="index"
expand-icon="mdi-menu-down"
>
<template #title>
<span class="tww-text-title">
@@ -63,7 +64,7 @@ import { toObcPage } from "@utils/TGWindow.js";
import { parseHtmlText } from "@utils/toolFunc.js";
import { computed, onMounted, ref, shallowRef, watch } from "vue";
import TwcMaterials from "./twc-materials.vue";
import PwMaterialList from "./pw-material-list.vue";
import { WikiWeaponData } from "@/data/index.js";
@@ -153,10 +154,6 @@ async function toWiki(): Promise<void> {
}
}
.tww-brief-info :last-child {
cursor: pointer;
}
.tww-brief-rating {
color: var(--common-text-title);
}

View File

@@ -1,21 +1,22 @@
<!-- 材料WIKI -->
<template>
<v-app-bar>
<template #prepend>
<div class="twm-top-prepend">
<div class="title">
<img src="/source/UI/wikiGCG.webp" alt="icon" />
<img alt="icon" src="/source/UI/wikiGCG.webp" />
<span>材料图鉴</span>
</div>
<v-select
v-model="selectType"
:items="materialTypes"
item-title="type"
:hide-details="true"
:clearable="true"
width="250px"
label="材料类别"
:hide-details="true"
:items="materialTypes"
density="compact"
item-title="type"
label="材料类别"
variant="outlined"
width="250px"
>
<template #item="{ props, item }">
<v-list-item v-bind="props">
@@ -31,12 +32,12 @@
<div class="twm-top-append">
<v-text-field
v-model="search"
variant="outlined"
density="compact"
prepend-inner-icon="mdi-magnify"
label="搜索"
:single-line="true"
:hide-details="true"
:single-line="true"
density="compact"
label="搜索"
prepend-inner-icon="mdi-magnify"
variant="outlined"
@keydown.enter="searchMaterial()"
@click:prepend-inner="searchMaterial()"
/>
@@ -44,36 +45,30 @@
</template>
</v-app-bar>
<div class="twm-box">
<div
<PwMaterialItem
v-for="material in sortMaterialsData"
:key="material.id"
:material
class="twm-item"
v-for="item in sortMaterialsData"
:key="item.id"
@click="toMaterial(item)"
:title="item.name"
>
<div class="twm-item-left">
<img class="twm-item-bg" :src="`/icon/bg/${item.star}-Star.webp`" alt="bg" />
<img class="twm-item-icon" :src="`/icon/material/${item.id}.webp`" alt="icon" />
</div>
<div class="twm-item-right">{{ item.name }}</div>
<div class="twm-item-id">{{ item.id }}</div>
</div>
@click="toMaterial(material)"
/>
</div>
<TwoMaterial v-model="visible" :data="curMaterial" v-if="curMaterial">
<TwoMaterial v-if="curMaterial" v-model="visible" :data="curMaterial">
<template #left>
<div class="card-arrow" @click="switchMaterial(false)">
<img src="@/assets/icons/arrow-right.svg" alt="right" />
<img alt="right" src="@/assets/icons/arrow-right.svg" />
</div>
</template>
<template #right>
<div class="card-arrow" @click="switchMaterial(true)">
<img src="@/assets/icons/arrow-right.svg" alt="right" />
<img alt="right" src="@/assets/icons/arrow-right.svg" />
</div>
</template>
</TwoMaterial>
</template>
<script lang="ts" setup>
import showSnackbar from "@comp/func/snackbar.js";
import PwMaterialItem from "@comp/pageWiki/pw-material-item.vue";
import TwoMaterial from "@comp/pageWiki/two-material.vue";
import { onMounted, ref, shallowRef, watch } from "vue";
@@ -215,43 +210,6 @@ function searchMaterial(): void {
cursor: pointer;
}
.twm-item-left {
position: relative;
width: 45px;
height: 45px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.twm-item-bg,
.twm-item-icon {
position: absolute;
top: 0;
width: 45px;
height: 45px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.twm-item-right {
position: relative;
overflow: hidden;
max-width: calc(100% - 50px);
color: var(--box-text-2);
font-size: 14px;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
}
.twm-item-id {
position: absolute;
right: 4px;
bottom: 2px;
font-size: 8px;
opacity: 0.6;
}
.card-arrow {
position: relative;
display: flex;