💄 尘歌壶UI迭代

#221
This commit is contained in:
BTMuli
2026-03-03 17:59:12 +08:00
parent 7b8be1adf9
commit a2df7b2d22
4 changed files with 195 additions and 22 deletions

View File

@@ -1,19 +0,0 @@
<template>
<div v-if="modelValue.length === 0">暂无数据</div>
<div v-else class="tur-hg-box">
<TurHomeSub v-for="(home, index) in modelValue" :key="index" :data="home" />
</div>
</template>
<script lang="ts" setup>
import TurHomeSub from "./tur-home-sub.vue";
defineProps<{ modelValue: Array<TGApp.Sqlite.Record.Home> }>();
</script>
<style lang="css" scoped>
.tur-hg-box {
display: grid;
width: 100%;
gap: 8px;
grid-template-columns: repeat(3, 1fr);
}
</style>

View File

@@ -0,0 +1,84 @@
<template>
<div :title="props.name" class="tur-hi-box">
<img ref="TurHiiRef" :src="props.icon" alt="bg" class="tur-hi-bg" @error="handleIconError" />
<img v-if="isErr" alt="empty" class="tur-hi-empty" src="/UI/app/empty.webp" />
<span class="tur-hi-name">{{ props.name }}</span>
</div>
</template>
<script lang="ts" setup>
import useAppStore from "@store/app.js";
import { str2Color } from "@utils/colorFunc.js";
import { storeToRefs } from "pinia";
import { computed, ref, useTemplateRef } from "vue";
type TurHomeNameProps = { name: string; icon: string };
const { theme } = storeToRefs(useAppStore());
const props = defineProps<TurHomeNameProps>();
const isErr = ref<boolean>(false);
const iconEl = useTemplateRef<HTMLImageElement>("TurHiiRef");
const isDarkMode = computed<boolean>(() => theme.value === "dark");
const color = computed<string>(() =>
tag2Color(`${props.name}_${encodeURIComponent(props.icon)}`, isDarkMode.value),
);
const bg = computed<string>(() => `rgba(${color.value.slice(4, -1)}, 0.5)`);
function handleIconError(e: Event) {
console.debug(e);
if (!iconEl.value) return;
isErr.value = true;
iconEl.value.style.display = "none";
}
function tag2Color(str: string, isDarkMode: boolean = false): string {
const adjust = isDarkMode ? 90 : 120;
return str2Color(str, adjust);
}
</script>
<style lang="scss" scoped>
.tur-hi-box {
position: relative;
display: flex;
overflow: hidden;
width: 100%;
height: 100%;
flex-shrink: 0;
align-items: center;
justify-content: center;
border-radius: 4px;
background: var(--box-bg-1);
}
.tur-hi-bg {
z-index: 0;
width: 100%;
height: 100%;
flex-shrink: 0;
object-fit: cover;
}
.tur-hi-empty {
width: 48px;
height: 48px;
object-fit: contain;
}
.tur-hi-name {
position: absolute;
z-index: 1;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 0 6px;
backdrop-filter: blur(10px);
background: v-bind(bg);
border-bottom-left-radius: 12px;
color: v-bind(color);
line-height: 24px;
text-shadow: 0 0 4px rgb(0 0 0 / 50%);
}
</style>

View File

@@ -0,0 +1,109 @@
<!-- 尘歌壶数据汇总 -->
<template>
<div class="tur-ho-container">
<div class="tur-hoc-overview">
<div v-if="overview" class="tur-hoco-item">
<img :src="overview.comfortIcon" alt="icon" />
<span>{{ overview.comfortName }}</span>
</div>
<div class="tur-hoco-item">
<span>{{ props.homes.length }}</span>
<span>解锁洞天</span>
</div>
<div class="tur-hoco-item">
<span>{{ overview.level ?? 0 }}</span>
<span>信任等阶</span>
</div>
<div class="tur-hoco-item">
<span>{{ overview.comfort ?? 0 }}</span>
<span>最高洞天仙力</span>
</div>
<div class="tur-hoco-item">
<span>{{ overview.furniture ?? 0 }}</span>
<span>获得摆设数</span>
</div>
<div class="tur-hoco-item">
<span>{{ overview.visit ?? 0 }}</span>
<span>历史访客数</span>
</div>
</div>
<div v-if="props.homes.length > 0" class="tur-hoc-list">
<TurHomeName
v-for="(item, idx) in props.homes"
:key="idx"
:icon="item.bg"
:name="item.name"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import TurHomeName from "./tur-home-item.vue";
type TurHomeOverviewProps = { homes: Array<TGApp.Sqlite.Record.Home> };
const props = defineProps<TurHomeOverviewProps>();
const overview = computed<TGApp.Sqlite.Record.Home>(() => props.homes[0] ?? undefined);
</script>
<style lang="scss" scoped>
@use "@styles/github.styles.scss" as github-styles;
.tur-ho-container {
position: relative;
display: flex;
width: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
row-gap: 8px;
}
.tur-hoc-overview {
position: relative;
display: flex;
width: 100%;
flex-wrap: wrap;
align-items: center;
justify-content: center;
column-gap: 16px;
}
.tur-hoco-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
row-gap: 4px;
img {
width: 24px;
height: 24px;
}
span {
&:first-child {
color: var(--tgc-yellow-1);
font-family: var(--font-text);
text-shadow: 0 0 2px #0d1117;
}
&:last-child {
font-family: var(--font-title);
font-size: 16px;
}
}
}
.tur-hoc-list {
position: relative;
display: grid;
width: 100%;
align-items: center;
justify-content: center;
gap: 8px;
grid-template-columns: repeat(auto-fit, minmax(360px, 0.5fr));
}
</style>

View File

@@ -60,9 +60,8 @@
<PhCompCard title="世界探索">
<TurWorldGrid :worlds="recordData.worldExplore" />
</PhCompCard>
<!-- TODO: 优化UI -->
<PhCompCard title="尘歌壶">
<TurHomeGrid :model-value="recordData.homes" />
<TurHomeOverview :homes="recordData.homes" />
</PhCompCard>
</div>
<div v-else class="ur-empty">
@@ -76,7 +75,7 @@ import showLoading from "@comp/func/loading.js";
import showSnackbar from "@comp/func/snackbar.js";
import PhCompCard from "@comp/pageHome/ph-comp-card.vue";
import TurAvatarGrid from "@comp/userRecord/tur-avatar-grid.vue";
import TurHomeGrid from "@comp/userRecord/tur-home-grid.vue";
import TurHomeOverview from "@comp/userRecord/tur-home-overview.vue";
import TurOverviewGrid from "@comp/userRecord/tur-overview-grid.vue";
import TurRoleInfo from "@comp/userRecord/tur-role-info.vue";
import TurWorldGrid from "@comp/userRecord/tur-world-grid.vue";