mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-16 09:58:13 +08:00
♻️ 代码结构调整
This commit is contained in:
@@ -34,32 +34,27 @@
|
||||
<ToArcBrith v-model="showOverlay" :data="current" :choice="isAether" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { computed, onMounted, ref, shallowRef, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import ToArcBrith from "../../components/pageArchive/to-arcBrith.vue";
|
||||
import { ArcBirDraw, ArcBirRole } from "../../data/index.js";
|
||||
import TGClient from "../../utils/TGClient.js";
|
||||
|
||||
const page = ref(1);
|
||||
const length = ref(0);
|
||||
const visible = ref(0);
|
||||
const renderItems = ref<TGApp.Archive.Birth.DrawItem[]>([]);
|
||||
const curSelect = ref<TGApp.Archive.Birth.RoleItem | null>(null);
|
||||
const selectedItem = ref<TGApp.Archive.Birth.DrawItem[]>([]);
|
||||
const current = ref<TGApp.Archive.Birth.DrawItem>();
|
||||
const isAether = ref<boolean>(false);
|
||||
const showOverlay = ref(false);
|
||||
const route = useRoute();
|
||||
|
||||
watch(
|
||||
() => page.value,
|
||||
() => {
|
||||
const start = (page.value - 1) * 12;
|
||||
const end = start + 12;
|
||||
selectedItem.value = renderItems.value.slice(start, end);
|
||||
},
|
||||
);
|
||||
const page = ref<number>(1);
|
||||
const length = ref<number>(0);
|
||||
const visible = ref(0);
|
||||
const renderItems = shallowRef<TGApp.Archive.Birth.DrawItem[]>([]);
|
||||
const curSelect = shallowRef<TGApp.Archive.Birth.RoleItem | null>(null);
|
||||
const current = shallowRef<TGApp.Archive.Birth.DrawItem>();
|
||||
const isAether = ref<boolean>(false);
|
||||
const showOverlay = ref<boolean>(false);
|
||||
|
||||
const selectedItem = computed<TGApp.Archive.Birth.DrawItem[]>(() => {
|
||||
return renderItems.value.slice((page.value - 1) * 12, page.value * 12);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => curSelect.value,
|
||||
@@ -73,7 +68,6 @@ watch(
|
||||
}
|
||||
length.value = Math.ceil(renderItems.value.length / 12);
|
||||
page.value = 1;
|
||||
selectedItem.value = renderItems.value.slice(0, 12);
|
||||
visible.value = length.value > 5 ? 5 : length.value;
|
||||
},
|
||||
);
|
||||
@@ -85,7 +79,6 @@ onMounted(() => {
|
||||
if (dataFind) curSelect.value = dataFind;
|
||||
} else {
|
||||
renderItems.value = ArcBirDraw;
|
||||
selectedItem.value = renderItems.value.slice(0, 12);
|
||||
}
|
||||
length.value = Math.ceil(renderItems.value.length / 12);
|
||||
visible.value = length.value > 5 ? 5 : length.value;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<TwoSelectC v-model="showSelect" @select-c="handleSelect" v-model:reset="resetSelect" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeMount, ref, watch } from "vue";
|
||||
import { onBeforeMount, ref, shallowRef, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import showDialog from "../../components/func/dialog.js";
|
||||
@@ -35,10 +35,10 @@ import { AppCharacterData } from "../../data/index.js";
|
||||
import { createObc } from "../../utils/TGWindow.js";
|
||||
|
||||
const id = useRoute().params.id.toString() ?? "0";
|
||||
const showSelect = ref(false);
|
||||
const resetSelect = ref(false);
|
||||
const cardsInfo = ref(AppCharacterData);
|
||||
const curItem = ref<TGApp.App.Character.WikiBriefInfo>({
|
||||
const showSelect = ref<boolean>(false);
|
||||
const resetSelect = ref<boolean>(false);
|
||||
const cardsInfo = shallowRef<TGApp.App.Character.WikiBriefInfo[]>(AppCharacterData);
|
||||
const curItem = shallowRef<TGApp.App.Character.WikiBriefInfo>({
|
||||
id: 0,
|
||||
contentId: 0,
|
||||
name: "",
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<Suspense>
|
||||
<TwoMaterial v-model="visible" :data="curMaterial">
|
||||
<TwoMaterial v-model="visible" :data="curMaterial" v-if="curMaterial">
|
||||
<template #left>
|
||||
<div class="card-arrow left" @click="switchMaterial(false)">
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" />
|
||||
@@ -70,47 +70,41 @@
|
||||
</Suspense>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { onMounted, ref, shallowRef, watch } from "vue";
|
||||
|
||||
import showSnackbar from "../../components/func/snackbar.js";
|
||||
import TwoMaterial from "../../components/pageWiki/two-material.vue";
|
||||
import { WikiMaterialData } from "../../data/index.js";
|
||||
|
||||
const curMaterial = ref<TGApp.App.Material.WikiItem>(<TGApp.App.Material.WikiItem>{});
|
||||
const sortMaterialsData = ref<Array<TGApp.App.Material.WikiItem>>([]);
|
||||
const curIndex = ref(0);
|
||||
const total = ref(0);
|
||||
const visible = ref(false);
|
||||
const curMaterial = shallowRef<TGApp.App.Material.WikiItem | undefined>();
|
||||
const sortMaterialsData = shallowRef<Array<TGApp.App.Material.WikiItem>>([]);
|
||||
const curIndex = ref<number>(0);
|
||||
const total = ref<number>(0);
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
interface MaterialType {
|
||||
type: string;
|
||||
number: number;
|
||||
}
|
||||
type MaterialType = { type: string; number: number };
|
||||
|
||||
const search = ref<string>();
|
||||
const selectType = ref<string | null>(null);
|
||||
const materialTypes = ref<MaterialType[]>([]);
|
||||
|
||||
onMounted(() => {
|
||||
WikiMaterialData.forEach((item: TGApp.App.Material.WikiItem) => {
|
||||
for (const item of WikiMaterialData) {
|
||||
const typeFindIndex = materialTypes.value.findIndex((itemT) => itemT.type === item.type);
|
||||
if (typeFindIndex !== -1) {
|
||||
materialTypes.value[typeFindIndex].number++;
|
||||
} else {
|
||||
if (typeFindIndex === -1) {
|
||||
const itemN: MaterialType = { type: item.type, number: 1 };
|
||||
materialTypes.value.push(itemN);
|
||||
continue;
|
||||
}
|
||||
});
|
||||
materialTypes.value[typeFindIndex].number++;
|
||||
}
|
||||
sortData(WikiMaterialData);
|
||||
showSnackbar.success(`成功获取${sortMaterialsData.value.length}条数据`);
|
||||
});
|
||||
|
||||
function getSelectMaterials(): TGApp.App.Material.WikiItem[] {
|
||||
if (selectType.value === null) {
|
||||
return WikiMaterialData;
|
||||
} else {
|
||||
return WikiMaterialData.filter((item) => item.type === selectType.value);
|
||||
}
|
||||
if (selectType.value === null) return WikiMaterialData;
|
||||
else return WikiMaterialData.filter((item) => item.type === selectType.value);
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -133,14 +127,10 @@ function toMaterial(item: TGApp.App.Material.WikiItem) {
|
||||
|
||||
function switchMaterial(isNext: boolean) {
|
||||
if (isNext) {
|
||||
if (curIndex.value === total.value - 1) {
|
||||
return;
|
||||
}
|
||||
if (curIndex.value === total.value - 1) return;
|
||||
curIndex.value++;
|
||||
} else {
|
||||
if (curIndex.value === 0) {
|
||||
return;
|
||||
}
|
||||
if (curIndex.value === 0) return;
|
||||
curIndex.value--;
|
||||
}
|
||||
curMaterial.value = sortMaterialsData.value[curIndex.value];
|
||||
|
||||
@@ -6,19 +6,19 @@
|
||||
label="搜索"
|
||||
:hide-details="true"
|
||||
variant="outlined"
|
||||
@click:prepend-inner="searchNamecard"
|
||||
@keyup.enter="searchNamecard"
|
||||
@click:prepend-inner="searchNameCard()"
|
||||
@keyup.enter="searchNameCard()"
|
||||
/>
|
||||
<div class="tw-nc-list">
|
||||
<v-virtual-scroll :items="sortNameCardsData" :item-height="80">
|
||||
<template #default="{ item }">
|
||||
<TopNamecard :data="item" @selected="toNameCard" />
|
||||
<TopNameCard :data="item" @selected="showNameCard(item)" />
|
||||
<div style="height: 10px" />
|
||||
</template>
|
||||
</v-virtual-scroll>
|
||||
</div>
|
||||
</div>
|
||||
<ToNamecard v-model="visible" :data="curNameCard">
|
||||
<ToNameCard v-model="visible" :data="curNameCard">
|
||||
<template #left>
|
||||
<div class="card-arrow left" @click="switchCard(false)">
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" />
|
||||
@@ -29,28 +29,26 @@
|
||||
<img src="../../assets/icons/arrow-right.svg" alt="right" />
|
||||
</div>
|
||||
</template>
|
||||
</ToNamecard>
|
||||
</ToNameCard>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import { onMounted, ref, shallowRef } from "vue";
|
||||
|
||||
import ToNamecard from "../../components/app/to-namecard.vue";
|
||||
import TopNamecard from "../../components/app/top-namecard.vue";
|
||||
import ToNameCard from "../../components/app/to-namecard.vue";
|
||||
import TopNameCard from "../../components/app/top-namecard.vue";
|
||||
import showSnackbar from "../../components/func/snackbar.js";
|
||||
import { AppNameCardsData } from "../../data/index.js";
|
||||
|
||||
const curNameCard = ref<TGApp.App.NameCard.Item>();
|
||||
const sortNameCardsData = ref<TGApp.App.NameCard.Item[]>([]);
|
||||
const curIndex = ref(0);
|
||||
const total = ref(0);
|
||||
const visible = ref(false);
|
||||
const search = ref("");
|
||||
const curNameCard = shallowRef<TGApp.App.NameCard.Item>();
|
||||
const sortNameCardsData = shallowRef<TGApp.App.NameCard.Item[]>([]);
|
||||
const curIndex = ref<number>(0);
|
||||
const total = ref<number>(0);
|
||||
const visible = ref<boolean>(false);
|
||||
const search = ref<string>();
|
||||
|
||||
onMounted(() => {
|
||||
sortData(AppNameCardsData);
|
||||
});
|
||||
onMounted(() => sortData(AppNameCardsData));
|
||||
|
||||
function sortData(data: TGApp.App.NameCard.Item[]) {
|
||||
function sortData(data: TGApp.App.NameCard.Item[]): void {
|
||||
sortNameCardsData.value = data.sort((a, b) => a.type - b.type || a.index - b.index);
|
||||
curIndex.value = 0;
|
||||
total.value = sortNameCardsData.value.length;
|
||||
@@ -58,48 +56,45 @@ function sortData(data: TGApp.App.NameCard.Item[]) {
|
||||
showSnackbar.success(`共搜索到 ${sortNameCardsData.value.length} 个结果`);
|
||||
}
|
||||
|
||||
function toNameCard(item: TGApp.App.NameCard.Item) {
|
||||
function showNameCard(item: TGApp.App.NameCard.Item): void {
|
||||
curNameCard.value = item;
|
||||
curIndex.value = sortNameCardsData.value.findIndex((i) => i.name === item.name);
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
function switchCard(isNext: boolean) {
|
||||
if (isNext) {
|
||||
if (curIndex.value === total.value - 1) {
|
||||
showSnackbar.warn("已经是最后一个了");
|
||||
return;
|
||||
}
|
||||
curIndex.value++;
|
||||
} else {
|
||||
if (curIndex.value === 0) {
|
||||
showSnackbar.warn("已经是第一个了");
|
||||
return;
|
||||
}
|
||||
curIndex.value--;
|
||||
function switchCard(isNext: boolean): void {
|
||||
if (isNext && curIndex.value === total.value - 1) {
|
||||
showSnackbar.warn("已经是最后一个了");
|
||||
return;
|
||||
}
|
||||
if (!isNext && curIndex.value === 0) {
|
||||
showSnackbar.warn("已经是第一个了");
|
||||
return;
|
||||
}
|
||||
curIndex.value += isNext ? 1 : -1;
|
||||
curNameCard.value = sortNameCardsData.value[curIndex.value];
|
||||
}
|
||||
|
||||
function searchNamecard() {
|
||||
if (!search.value) {
|
||||
function searchNameCard(): void {
|
||||
if (search.value === undefined) {
|
||||
sortData(AppNameCardsData);
|
||||
} else if (search.value === "") {
|
||||
return;
|
||||
}
|
||||
if (search.value === "") {
|
||||
if (sortNameCardsData.value.length === AppNameCardsData.length) {
|
||||
showSnackbar.warn("请先输入搜索内容");
|
||||
} else {
|
||||
sortData(AppNameCardsData);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const searchResult = AppNameCardsData.filter((item) => {
|
||||
return (
|
||||
item.name.includes(search.value) ||
|
||||
item.desc.includes(search.value) ||
|
||||
item.source.includes(search.value)
|
||||
);
|
||||
});
|
||||
sortData(searchResult);
|
||||
sortData(AppNameCardsData);
|
||||
return;
|
||||
}
|
||||
const searchResult = AppNameCardsData.filter(
|
||||
(item) =>
|
||||
item.name.includes(search.value!) ||
|
||||
item.desc.includes(search.value!) ||
|
||||
item.source.includes(search.value!),
|
||||
);
|
||||
sortData(searchResult);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
v-model:cur-item="curItem"
|
||||
:key="index"
|
||||
:data="item"
|
||||
@click="switchW(item)"
|
||||
@click="curItem = item"
|
||||
mode="weapon"
|
||||
/>
|
||||
</div>
|
||||
@@ -26,7 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeMount, ref } from "vue";
|
||||
import { onBeforeMount, ref, shallowRef } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import showDialog from "../../components/func/dialog.js";
|
||||
@@ -38,10 +38,10 @@ import { AppWeaponData } from "../../data/index.js";
|
||||
import { createObc } from "../../utils/TGWindow.js";
|
||||
|
||||
const id = useRoute().params.id.toString() ?? "0";
|
||||
const showSelect = ref(false);
|
||||
const resetSelect = ref(false);
|
||||
const cardsInfo = ref(AppWeaponData);
|
||||
const curItem = ref<TGApp.App.Weapon.WikiBriefInfo>({
|
||||
const showSelect = ref<boolean>(false);
|
||||
const resetSelect = ref<boolean>(false);
|
||||
const cardsInfo = shallowRef<Array<TGApp.App.Weapon.WikiBriefInfo>>(AppWeaponData);
|
||||
const curItem = shallowRef<TGApp.App.Weapon.WikiBriefInfo>({
|
||||
id: 0,
|
||||
contentId: 0,
|
||||
name: "",
|
||||
@@ -82,10 +82,6 @@ function handleSelectW(val: SelectedWValue) {
|
||||
cardsInfo.value = filterW;
|
||||
}
|
||||
|
||||
async function switchW(item: TGApp.App.Weapon.WikiBriefInfo): Promise<void> {
|
||||
curItem.value = item;
|
||||
}
|
||||
|
||||
async function toOuter(item?: TGApp.App.Weapon.WikiBriefInfo): Promise<void> {
|
||||
if (!item) return;
|
||||
if (item.contentId === 0) {
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
:key="index"
|
||||
:value="value"
|
||||
@click="firstLoad(value)"
|
||||
>{{ rawData[value].name }}
|
||||
>
|
||||
{{ rawData[value].name }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
@@ -71,78 +72,39 @@ import TGLogger from "../../utils/TGLogger.js";
|
||||
import { createPost } from "../../utils/TGWindow.js";
|
||||
import { getGameName } from "../../web/utils/tools.js";
|
||||
|
||||
// 类型定义
|
||||
enum NewsType {
|
||||
notice = "1",
|
||||
activity = "2",
|
||||
news = "3",
|
||||
}
|
||||
|
||||
type NewsKey = keyof typeof NewsType;
|
||||
type PostData = {
|
||||
[key in NewsKey]: TGApp.Plugins.Mys.Post.FullData[];
|
||||
};
|
||||
type PostData = { [key in TGApp.App.Store.NewsType]: TGApp.Plugins.Mys.Post.FullData[] };
|
||||
type RawData = {
|
||||
[key in NewsKey]: {
|
||||
isLast: boolean;
|
||||
name: string;
|
||||
lastId: number;
|
||||
};
|
||||
[key in TGApp.App.Store.NewsType]: { isLast: boolean; name: string; lastId: number };
|
||||
};
|
||||
|
||||
// 路由
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const gid = <string>useRoute().params.gid;
|
||||
const gameName = getGameName(Number(gid));
|
||||
// loading
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
// UI 数据
|
||||
const appStore = useAppStore();
|
||||
const tabValues: Readonly<Array<TGApp.App.Store.NewsType>> = ["notice", "activity", "news"];
|
||||
const showList = ref<boolean>(false);
|
||||
const showSearch = ref<boolean>(false);
|
||||
const tabValues = ref<Array<NewsKey>>(["notice", "activity", "news"]);
|
||||
const tabList = ["notice", "activity", "news"];
|
||||
const tab = computed({
|
||||
const tab = computed<TGApp.App.Store.NewsType>({
|
||||
get: () => {
|
||||
if (appStore.recentNewsType === "" || !tabList.includes(appStore.recentNewsType)) {
|
||||
return "notice";
|
||||
}
|
||||
return <NewsKey>appStore.recentNewsType;
|
||||
},
|
||||
set: (val) => {
|
||||
appStore.recentNewsType = val;
|
||||
if (!(appStore.recentNewsType satisfies TGApp.App.Store.NewsType)) return "notice";
|
||||
return appStore.recentNewsType;
|
||||
},
|
||||
set: (v) => (appStore.recentNewsType = v),
|
||||
});
|
||||
|
||||
// 渲染数据
|
||||
const search = ref<string>("");
|
||||
const postData = ref<PostData>({
|
||||
notice: [],
|
||||
activity: [],
|
||||
news: [],
|
||||
});
|
||||
const postData = ref<PostData>({ notice: [], activity: [], news: [] });
|
||||
const rawData = ref<RawData>({
|
||||
notice: {
|
||||
isLast: false,
|
||||
name: "公告",
|
||||
lastId: 0,
|
||||
},
|
||||
activity: {
|
||||
isLast: false,
|
||||
name: "活动",
|
||||
lastId: 0,
|
||||
},
|
||||
news: {
|
||||
isLast: false,
|
||||
name: "咨讯",
|
||||
lastId: 0,
|
||||
},
|
||||
notice: { isLast: false, name: "公告", lastId: 0 },
|
||||
activity: { isLast: false, name: "活动", lastId: 0 },
|
||||
news: { isLast: false, name: "咨讯", lastId: 0 },
|
||||
});
|
||||
|
||||
onMounted(async () => await firstLoad(tab.value));
|
||||
|
||||
async function firstLoad(key: NewsKey, refresh: boolean = false): Promise<void> {
|
||||
async function firstLoad(key: TGApp.App.Store.NewsType, refresh: boolean = false): Promise<void> {
|
||||
if (rawData.value[key].lastId !== 0) {
|
||||
if (!refresh) return;
|
||||
postData.value[key] = [];
|
||||
@@ -150,7 +112,7 @@ async function firstLoad(key: NewsKey, refresh: boolean = false): Promise<void>
|
||||
}
|
||||
showLoading.start(`正在获取${gameName}${rawData.value[key].name}数据...`);
|
||||
document.documentElement.scrollTo({ top: 0, behavior: "smooth" });
|
||||
const getData = await Mys.Painter.getNewsList(gid, NewsType[key]);
|
||||
const getData = await Mys.Painter.getNewsList(gid, TGApp.App.Store.NewsTypeEnum[key]);
|
||||
rawData.value[key].isLast = getData.is_last;
|
||||
rawData.value[key].lastId = getData.list.length;
|
||||
postData.value[key] = getData.list;
|
||||
@@ -165,7 +127,7 @@ async function switchAnno(): Promise<void> {
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
async function loadMore(key: NewsKey): Promise<void> {
|
||||
async function loadMore(key: TGApp.App.Store.NewsType): Promise<void> {
|
||||
loading.value = true;
|
||||
if (rawData.value[key].isLast) {
|
||||
showSnackbar.warn("已经是最后一页了");
|
||||
@@ -173,7 +135,12 @@ async function loadMore(key: NewsKey): Promise<void> {
|
||||
return;
|
||||
}
|
||||
showLoading.start(`正在获取${gameName}${rawData.value[key].name}数据...`);
|
||||
const getData = await Mys.Painter.getNewsList(gid, NewsType[key], 20, rawData.value[key].lastId);
|
||||
const getData = await Mys.Painter.getNewsList(
|
||||
gid,
|
||||
TGApp.App.Store.NewsTypeEnum[key],
|
||||
20,
|
||||
rawData.value[key].lastId,
|
||||
);
|
||||
rawData.value[key].lastId = rawData.value[key].lastId + getData.list.length;
|
||||
rawData.value[key].isLast = getData.is_last;
|
||||
postData.value[key] = postData.value[key].concat(getData.list);
|
||||
@@ -195,10 +162,10 @@ async function searchPost(): Promise<void> {
|
||||
const numCheck = Number(search.value);
|
||||
if (isNaN(numCheck)) {
|
||||
showSearch.value = true;
|
||||
} else {
|
||||
await createPost(search.value);
|
||||
showSearch.value = false;
|
||||
return;
|
||||
}
|
||||
await createPost(search.value);
|
||||
showSearch.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user