mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-14 09:38:13 +08:00
♻️ 名片组件抽离,wiki添加名片信息
This commit is contained in:
45
src/components/overlay/top-namecard.vue
Normal file
45
src/components/overlay/top-namecard.vue
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<v-list
|
||||||
|
:style="{ backgroundImage: props.data.name === '原神·印象' ? 'none' : `url(${props.data.bg})` }"
|
||||||
|
class="top-nc-box"
|
||||||
|
@click="toNameCard(props.data)"
|
||||||
|
>
|
||||||
|
<v-list-item :title="props.data.name">
|
||||||
|
<template #subtitle>
|
||||||
|
<span :title="props.data.desc">{{ props.data.desc }}</span>
|
||||||
|
</template>
|
||||||
|
<template #prepend>
|
||||||
|
<v-img width="80px" style="margin-right: 10px" :src="props.data.icon" />
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
interface TopNamecardProps {
|
||||||
|
data: TGApp.App.NameCard.Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TopNamecardEmits {
|
||||||
|
(e: "selected", data: TGApp.App.NameCard.Item): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TopNamecardProps>();
|
||||||
|
const emit = defineEmits<TopNamecardEmits>();
|
||||||
|
|
||||||
|
function toNameCard(item: TGApp.App.NameCard.Item) {
|
||||||
|
emit("selected", item);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.top-nc-box {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
border: 1px solid var(--common-shadow-2);
|
||||||
|
border-radius: 10px 50px 50px 10px;
|
||||||
|
background-color: var(--box-bg-1);
|
||||||
|
background-position: right;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font-title);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- todo 角色名片 -->
|
|
||||||
<template>
|
<template>
|
||||||
<div class="twc-box" v-if="data !== undefined">
|
<div class="twc-box" v-if="data !== undefined">
|
||||||
<div class="twc-brief">
|
<div class="twc-brief">
|
||||||
@@ -50,6 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<TopNamecard :data="nameCard" @selected="toNameCard" />
|
||||||
<TwcMaterials :data="data.materials" />
|
<TwcMaterials :data="data.materials" />
|
||||||
<TwcSkills :data="data.skills" />
|
<TwcSkills :data="data.skills" />
|
||||||
<TwcConstellations :data="data.constellation" />
|
<TwcConstellations :data="data.constellation" />
|
||||||
@@ -94,17 +94,20 @@
|
|||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</v-expansion-panels>
|
</v-expansion-panels>
|
||||||
</div>
|
</div>
|
||||||
|
<ToNamecard v-if="hasNc" v-model="showNc" :data="nameCard" />
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref, watch } from "vue";
|
import { computed, onMounted, ref, watch } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
import { WikiCharacterData } from "../../data";
|
import { WikiCharacterData, AppNameCardsData, AppCharacterData } from "../../data";
|
||||||
import Mys from "../../plugins/Mys";
|
import Mys from "../../plugins/Mys";
|
||||||
import { createTGWindow } from "../../utils/TGWindow";
|
import { createTGWindow } from "../../utils/TGWindow";
|
||||||
import { parseHtmlText } from "../../utils/toolFunc";
|
import { parseHtmlText } from "../../utils/toolFunc";
|
||||||
import showSnackbar from "../func/snackbar";
|
import showSnackbar from "../func/snackbar";
|
||||||
import TItembox, { TItemBoxData } from "../main/t-itembox.vue";
|
import TItembox, { TItemBoxData } from "../main/t-itembox.vue";
|
||||||
|
import ToNamecard from "../overlay/to-namecard.vue";
|
||||||
|
import TopNamecard from "../overlay/top-namecard.vue";
|
||||||
|
|
||||||
import TwcConstellations from "./twc-constellations.vue";
|
import TwcConstellations from "./twc-constellations.vue";
|
||||||
import TwcMaterials from "./twc-materials.vue";
|
import TwcMaterials from "./twc-materials.vue";
|
||||||
@@ -115,6 +118,7 @@ interface TwcCharacterProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TwcCharacterProps>();
|
const props = defineProps<TwcCharacterProps>();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const data = ref<TGApp.App.Character.WikiItem>();
|
const data = ref<TGApp.App.Character.WikiItem>();
|
||||||
const box = computed(() => {
|
const box = computed(() => {
|
||||||
@@ -132,7 +136,9 @@ const box = computed(() => {
|
|||||||
clickable: false,
|
clickable: false,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const router = useRouter();
|
const hasNc = ref(false);
|
||||||
|
const showNc = ref(false);
|
||||||
|
const nameCard = ref<TGApp.App.NameCard.Item>();
|
||||||
|
|
||||||
async function loadData(): Promise<void> {
|
async function loadData(): Promise<void> {
|
||||||
const res = WikiCharacterData.find((item) => item.id === props.item.id);
|
const res = WikiCharacterData.find((item) => item.id === props.item.id);
|
||||||
@@ -144,6 +150,13 @@ async function loadData(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.value = res;
|
data.value = res;
|
||||||
|
const appC = AppCharacterData.find((i) => i.name === data.value?.name);
|
||||||
|
if (appC !== undefined) {
|
||||||
|
hasNc.value = true;
|
||||||
|
nameCard.value = AppNameCardsData.find((i) => i.name === appC.nameCard);
|
||||||
|
} else {
|
||||||
|
hasNc.value = false;
|
||||||
|
}
|
||||||
showSnackbar({
|
showSnackbar({
|
||||||
text: `成功获取角色 ${props.item.name} 的 Wiki 数据`,
|
text: `成功获取角色 ${props.item.name} 的 Wiki 数据`,
|
||||||
color: "success",
|
color: "success",
|
||||||
@@ -182,6 +195,11 @@ async function toBirth(date: string): Promise<void> {
|
|||||||
const birth = date.replace("月", "/").replace("日", "");
|
const birth = date.replace("月", "/").replace("日", "");
|
||||||
await router.push({ name: "留影叙佳期", params: { date: birth } });
|
await router.push({ name: "留影叙佳期", params: { date: birth } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toNameCard(): void {
|
||||||
|
if (showNc.value === true) showNc.value = false;
|
||||||
|
showNc.value = true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
.twc-box {
|
.twc-box {
|
||||||
|
|||||||
@@ -10,19 +10,10 @@
|
|||||||
@keyup.enter="searchNamecard"
|
@keyup.enter="searchNamecard"
|
||||||
/>
|
/>
|
||||||
<div class="tw-nc-list">
|
<div class="tw-nc-list">
|
||||||
<v-virtual-scroll :items="sortNameCardsData" :item-height="80" class="cards-list">
|
<v-virtual-scroll :items="sortNameCardsData" :item-height="80">
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<v-list
|
<TopNamecard :data="item" @selected="toNameCard" />
|
||||||
:style="{ backgroundImage: item.name === '原神·印象' ? 'none' : `url(${item.bg})` }"
|
<div style="height: 10px" />
|
||||||
class="card-box"
|
|
||||||
@click="toNameCard(item)"
|
|
||||||
>
|
|
||||||
<v-list-item :title="item.name" :subtitle="item.desc">
|
|
||||||
<template #prepend>
|
|
||||||
<v-img width="80px" style="margin-right: 10px" :src="item.icon" />
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</template>
|
</template>
|
||||||
</v-virtual-scroll>
|
</v-virtual-scroll>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,6 +36,7 @@ import { onMounted, ref } from "vue";
|
|||||||
|
|
||||||
import showSnackbar from "../../components/func/snackbar";
|
import showSnackbar from "../../components/func/snackbar";
|
||||||
import ToNamecard from "../../components/overlay/to-namecard.vue";
|
import ToNamecard from "../../components/overlay/to-namecard.vue";
|
||||||
|
import TopNamecard from "../../components/overlay/top-namecard.vue";
|
||||||
import { AppNameCardsData } from "../../data";
|
import { AppNameCardsData } from "../../data";
|
||||||
|
|
||||||
const curNameCard = ref<TGApp.App.NameCard.Item>();
|
const curNameCard = ref<TGApp.App.NameCard.Item>();
|
||||||
@@ -135,19 +127,6 @@ function searchNamecard() {
|
|||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-box {
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
border: 1px solid var(--common-shadow-2);
|
|
||||||
border-radius: 10px 50px 50px 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
background-color: var(--box-bg-1);
|
|
||||||
background-position: right;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: var(--font-title);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-arrow {
|
.card-arrow {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -38,18 +38,7 @@
|
|||||||
<!-- 右侧内容-->
|
<!-- 右侧内容-->
|
||||||
<div class="right-wrap">
|
<div class="right-wrap">
|
||||||
<div v-if="curCardName !== '' && selectedSeries !== -1 && !loading">
|
<div v-if="curCardName !== '' && selectedSeries !== -1 && !loading">
|
||||||
<v-list
|
<TopNamecard :data="curCard" @selected="openImg()" />
|
||||||
v-if="curCard"
|
|
||||||
class="achi-series"
|
|
||||||
:style="{ backgroundImage: `url(${curCard.bg})` }"
|
|
||||||
@click="openImg()"
|
|
||||||
>
|
|
||||||
<v-list-item :title="curCard.name" :subtitle="curCard.desc">
|
|
||||||
<template #prepend>
|
|
||||||
<v-img width="80px" style="margin-right: 10px" :src="curCard.icon" />
|
|
||||||
</template>
|
|
||||||
</v-list-item>
|
|
||||||
</v-list>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="(achievement, index) in renderSelect"
|
v-for="(achievement, index) in renderSelect"
|
||||||
@@ -125,6 +114,7 @@ import showSnackbar from "../../components/func/snackbar";
|
|||||||
import ToAchiInfo from "../../components/overlay/to-achiInfo.vue";
|
import ToAchiInfo from "../../components/overlay/to-achiInfo.vue";
|
||||||
import ToLoading from "../../components/overlay/to-loading.vue";
|
import ToLoading from "../../components/overlay/to-loading.vue";
|
||||||
import ToNamecard from "../../components/overlay/to-namecard.vue";
|
import ToNamecard from "../../components/overlay/to-namecard.vue";
|
||||||
|
import TopNamecard from "../../components/overlay/top-namecard.vue";
|
||||||
import { AppAchievementSeriesData, AppNameCardsData } from "../../data";
|
import { AppAchievementSeriesData, AppNameCardsData } from "../../data";
|
||||||
import TSUserAchi from "../../plugins/Sqlite/modules/userAchi.js";
|
import TSUserAchi from "../../plugins/Sqlite/modules/userAchi.js";
|
||||||
import { useAchievementsStore } from "../../store/modules/achievements";
|
import { useAchievementsStore } from "../../store/modules/achievements";
|
||||||
@@ -627,19 +617,6 @@ async function getAchiData(
|
|||||||
<!-- 右侧成就 -->
|
<!-- 右侧成就 -->
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
/* 成就卡片 */
|
/* 成就卡片 */
|
||||||
.achi-series {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
border: 1px solid var(--common-shadow-2);
|
|
||||||
border-radius: 10px 50px 50px 10px;
|
|
||||||
background-color: var(--box-bg-1);
|
|
||||||
background-position: right;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
cursor: pointer;
|
|
||||||
font-family: var(--font-title);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-achi {
|
.card-achi {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
2
src/plugins/Mys/types/Collection.d.ts
vendored
2
src/plugins/Mys/types/Collection.d.ts
vendored
@@ -47,7 +47,7 @@ declare namespace TGApp.Plugins.Mys.Collection {
|
|||||||
* @property {boolean} is_following 是否关注
|
* @property {boolean} is_following 是否关注
|
||||||
* @property {number} post_num 帖子数量
|
* @property {number} post_num 帖子数量
|
||||||
* @property {number} post_updated_at 帖子更新时间(秒级时间戳)
|
* @property {number} post_updated_at 帖子更新时间(秒级时间戳)
|
||||||
* @property {number} status 状态 // todo: 未知
|
* @property {number} status 状态
|
||||||
* @property {string} title 标题
|
* @property {string} title 标题
|
||||||
* @property {number} uid 用户 ID
|
* @property {number} uid 用户 ID
|
||||||
* @property {number} view_num 浏览量
|
* @property {number} view_num 浏览量
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ async function getLatestAchiVersion(): Promise<string> {
|
|||||||
*/
|
*/
|
||||||
async function getSeries(id?: number): Promise<TGApp.Sqlite.Achievement.SeriesTable[]> {
|
async function getSeries(id?: number): Promise<TGApp.Sqlite.Achievement.SeriesTable[]> {
|
||||||
const db = await TGSqlite.getDB();
|
const db = await TGSqlite.getDB();
|
||||||
let res: TGApp.Sqlite.Achievement.SeriesTable[] = [];
|
let res: TGApp.Sqlite.Achievement.SeriesTable[];
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
res = await db.select<TGApp.Sqlite.Achievement.SeriesTable>(
|
res = await db.select<TGApp.Sqlite.Achievement.SeriesTable>(
|
||||||
"SELECT * FROM AchievementSeries ORDER BY `order`;",
|
"SELECT * FROM AchievementSeries ORDER BY `order`;",
|
||||||
@@ -65,7 +65,7 @@ async function getSeries(id?: number): Promise<TGApp.Sqlite.Achievement.SeriesTa
|
|||||||
*/
|
*/
|
||||||
async function getAchievements(id?: string): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
|
async function getAchievements(id?: string): Promise<TGApp.Sqlite.Achievement.SingleTable[]> {
|
||||||
const db = await TGSqlite.getDB();
|
const db = await TGSqlite.getDB();
|
||||||
let res: TGApp.Sqlite.Achievement.SingleTable[] = [];
|
let res: TGApp.Sqlite.Achievement.SingleTable[];
|
||||||
if (id === undefined) {
|
if (id === undefined) {
|
||||||
res = await db.select<TGApp.Sqlite.Achievement.SingleTable>(
|
res = await db.select<TGApp.Sqlite.Achievement.SingleTable>(
|
||||||
"SELECT * FROM Achievements ORDER BY isCompleted,`order`;",
|
"SELECT * FROM Achievements ORDER BY isCompleted,`order`;",
|
||||||
|
|||||||
Reference in New Issue
Block a user