Skip to content

Commit

Permalink
✨ 话题跳转
Browse files Browse the repository at this point in the history
  • Loading branch information
BTMuli committed Nov 15, 2024
1 parent b8afab0 commit afe53f3
Show file tree
Hide file tree
Showing 6 changed files with 503 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<div class="posts-top">
<img src="/source/UI/posts.png" alt="posts" />
<span>帖子</span>
<!-- todo 提供话题入口 -->
</div>
</template>
<div class="posts-switch">
Expand Down
237 changes: 237 additions & 0 deletions src/pages/common/PostTopic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
<template>
<ToLoading v-model="loading" :title="loadingTitle" />
<v-app-bar>
<template #prepend>
<div class="post-topic-top" v-if="topicInfo">
<img :src="topicInfo.topic.cover" alt="cover" />
<div class="post-topic-info">
<span>{{ topicInfo.topic.name }}({{ topic }})</span>
<span>{{ topicInfo.topic.desc }}</span>
</div>
</div>
</template>
<template #extension>
<TGameNav :model-value="curGid" v-if="curGid !== 0" />
</template>
<div class="post-topic-switch">
<v-select
v-model="curGame"
class="post-switch-item"
:items="topicInfo?.game_info_list"
item-title="name"
:item-value="(item) => item"
variant="outlined"
label="分区"
/>
<v-select
v-model="curSortType"
class="post-switch-item"
:items="sortOrderList"
item-title="text"
item-value="value"
variant="outlined"
label="排序"
/>
<v-text-field
v-model="search"
class="post-switch-item"
append-inner-icon="mdi-magnify"
label="请输入帖子 ID 或搜索词"
variant="outlined"
:single-line="true"
:hide-details="true"
@click:append="searchPost"
@keyup.enter="searchPost"
/>
<v-btn :rounded="true" class="post-fresh-btn" @click="freshPostData()">
<v-icon>mdi-refresh</v-icon>
<span>刷新</span>
</v-btn>
</div>
</v-app-bar>
<div class="post-topic-grid">
<div v-for="post in posts" :key="post.post.post_id">
<TPostCard :model-value="post" v-if="post" />
</div>
</div>
<div class="load-more">
<v-btn class="post-topic-btn" :rounded="true" @click="freshPostData()">
已加载:{{ posts.length }},加载更多
</v-btn>
</div>
<ToPostSearch :gid="curGid.toString()" v-model="showSearch" :keyword="search" />
</template>
<script lang="ts" setup>
import { onMounted, ref, toRaw, watch } from "vue";
import { useRoute } from "vue-router";
import showSnackbar from "../../components/func/snackbar.js";
import TGameNav from "../../components/main/t-gamenav.vue";
import TPostCard from "../../components/main/t-postcard.vue";
import ToLoading from "../../components/overlay/to-loading.vue";
import ToPostSearch from "../../components/post/to-postSearch.vue";
import Mys from "../../plugins/Mys/index.js";
import { createPost } from "../../utils/TGWindow.js";
const gid = <string>useRoute().params.gid;
const topic = <string>useRoute().params.topic;
const loading = ref<boolean>(false);
const loadingTitle = ref<string>("");
const showSearch = ref<boolean>(false);
const curGid = ref<number>(Number(gid));
const curSortType = ref<0 | 1 | 2>(0);
const search = ref<string>("");
const topicInfo = ref<TGApp.Plugins.Mys.Topic.InfoData>();
const posts = ref<TGApp.Plugins.Mys.Post.FullData[]>([]);
const lastPostId = ref<string>();
const isLastPage = ref<boolean>(false);
const curGame = ref<TGApp.Plugins.Mys.Topic.GameInfo>();
type SortSelect = { text: string; value: number };
// todo 根据实际情况修改
const sortOrderList: SortSelect[] = [
{ text: "默认排序", value: 0 },
{ text: "按时间排序", value: 1 },
{ text: "按热度排序", value: 2 },
];
onMounted(async () => await firstLoad());
watch(
() => curGame.value,
async () => await firstLoad(),
);
watch(
() => curSortType.value,
async () => await firstLoad(),
);
async function firstLoad(): Promise<void> {
loading.value = true;
loadingTitle.value = `正在加载话题${topic}信息`;
const info = await Mys.Post.getTopicFullInfo(gid, topic);
if ("retcode" in info) {
showSnackbar.error(`[${info.retcode}] ${info.message}`);
loading.value = false;
return;
}
topicInfo.value = info;
if (curGame.value === undefined) {
curGame.value = toRaw(info.game_info_list.find((i) => i.id === curGid.value));
}
if (curGame.value === undefined) curGame.value = info.game_info_list[0];
loadingTitle.value = `正在加载${curGame.value.name}帖子列表`;
const postList = await Mys.Post.getTopicPostList(gid, topic);
if ("retcode" in postList) {
showSnackbar.error(`[${postList.retcode}] ${postList.message}`);
loading.value = false;
return;
}
isLastPage.value = postList.is_last;
lastPostId.value = postList.last_id;
posts.value = postList.posts;
loading.value = false;
showSnackbar.success(`加载了 ${postList.posts.length} 条帖子`);
}
async function freshPostData(): Promise<void> {
if (isLastPage.value) {
showSnackbar.warn("已经到底了");
return;
}
loading.value = true;
loadingTitle.value = "正在加载帖子列表";
const postList = await Mys.Post.getTopicPostList(gid, topic, curSortType.value, lastPostId.value);
if ("retcode" in postList) {
showSnackbar.error(`[${postList.retcode}] ${postList.message}`);
loading.value = false;
return;
}
isLastPage.value = postList.is_last;
lastPostId.value = postList.last_id;
posts.value = posts.value.concat(postList.posts);
loading.value = false;
showSnackbar.success(`加载了 ${postList.posts.length} 条帖子`);
}
function searchPost(): void {
if (search.value === "") {
showSnackbar.warn("请输入搜索内容");
return;
}
const numCheck = Number(search.value);
if (isNaN(numCheck)) showSearch.value = true;
else createPost(search.value);
}
</script>
<style lang="css" scoped>
.post-topic-top {
display: flex;
overflow: hidden;
align-items: center;
justify-content: center;
padding-right: 5px;
border-radius: 5px;
background: var(--box-bg-2);
gap: 5px;
img {
width: 64px;
height: 64px;
}
.post-topic-info {
display: flex;
flex-direction: column;
gap: 5px;
:first-child {
color: var(--common-text-title);
font-family: var(--font-title);
font-size: 20px;
}
}
}
.post-topic-switch {
display: flex;
align-items: flex-end;
justify-content: center;
margin: 0 10px;
gap: 10px;
}
.post-switch-item {
width: 250px;
height: 50px;
}
.post-fresh-btn {
height: 40px;
background: var(--btn-bg-1);
color: var(--btn-text-1);
font-family: var(--font-title);
}
.dark .post-fresh-btn {
border: 1px solid var(--common-shadow-2);
}
.post-topic-grid {
display: grid;
padding: 5px;
font-family: var(--font-title);
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}
.load-more {
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
font-family: var(--font-title);
transition: all 0.3s linear;
}
</style>
55 changes: 55 additions & 0 deletions src/plugins/Mys/request/postReq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import TGHttp from "../../../utils/TGHttp.js";

// MysPostApiBaseUrl => Mpabu
const Mpabu = "https://bbs-api.mihoyo.com/post/wapi/";
// MysTopicApiBaseUrl => Mtapu
const Mtabu = "https://bbs-api.miyoushe.com/topic/wapi/";
const Referer = "https://bbs.mihoyo.com/";

/**
Expand Down Expand Up @@ -146,6 +148,59 @@ export async function getSubReplies(
return resp.data;
}

/**
* @description 获取特定话题信息
* @since Beta v0.6.3
* @param {string} gid 游戏分区 ID
* @param {string} topicId 话题 ID
* @return {Promise<TGApp.Plugins.Mys.Topic.InfoData|TGApp.BBS.Response.Base>}
*/
export async function getTopicFullInfo(
gid: string,
topicId: string,
): Promise<TGApp.Plugins.Mys.Topic.InfoData | TGApp.BBS.Response.Base> {
const resp = await TGHttp<TGApp.Plugins.Mys.Topic.InfoResponse>(`${Mtabu}getTopicFullInfo`, {
method: "GET",
headers: { referer: Referer },
query: { gids: gid, id: topicId },
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

/**
* @description 获取特定话题帖子列表
* @since Beta v0.6.3
* @param {string} gid 游戏分区 ID
* @param {string} topicId 话题 ID
* @param {string} orderType 排序方式
* @param {string} lastId 最后一条帖子 ID
* @param {number} size 每页大小
* @return {Promise<TGApp.Plugins.Mys.Topic.PostData|TGApp.BBS.Response.Base>}
*/
export async function getTopicPostList(
gid: string,
topicId: string,
orderType: number = 0,
lastId?: string,
size: number = 20,
): Promise<TGApp.Plugins.Mys.Topic.PostData | TGApp.BBS.Response.Base> {
const resp = await TGHttp<TGApp.Plugins.Mys.Topic.PostResponse>(`${Mpabu}getTopicPostList`, {
method: "GET",
headers: { referer: Referer },
query: {
gids: gid,
game_id: gid,
topic_id: topicId,
list_type: orderType,
last_id: lastId ?? "",
page_size: size,
},
});
if (resp.retcode !== 0) return <TGApp.BBS.Response.Base>resp;
return resp.data;
}

/**
* @description 搜索帖子
* @since Beta v0.6.2
Expand Down
Loading

0 comments on commit afe53f3

Please sign in to comment.