♻️ 部分分区动态获取,重构部分调用

This commit is contained in:
目棃
2025-01-17 16:06:36 +08:00
parent da78d27239
commit c9f74537b0
18 changed files with 216 additions and 185 deletions

View File

@@ -7,10 +7,10 @@
v-for="(item, index) in channelList"
:key="index"
class="toc-list-item"
:class="{ active: props.gid === item.gid }"
:class="props.gid === item.gid.toString() ? 'active' : ''"
@click="toChannel(item)"
>
<img :src="item.icon" alt="icon" />
<TMiImg :src="item.icon" alt="icon" :ori="true" />
<span>{{ item.title }}</span>
</div>
</div>
@@ -18,25 +18,30 @@
</TOverlay>
</template>
<script lang="ts" setup>
import TMiImg from "@comp/app/t-mi-img.vue";
import TOverlay from "@comp/app/t-overlay.vue";
import showSnackbar from "@comp/func/snackbar.js";
import { storeToRefs } from "pinia";
import { useRouter } from "vue-router";
import { onMounted, shallowRef } from "vue";
import { type NewsType, useAppStore } from "@/store/modules/app.js";
import type { ToChannelItem } from "@/web/constant/bbs.js";
import TGConstant from "@/web/constant/TGConstant.js";
import apiHubReq from "@/web/request/apiHubReq.js";
type ChannelItem = { icon: string; title: string; gid: number };
type ToChannelProps = { gid?: string; curType?: string };
const router = useRouter();
const { recentNewsType } = storeToRefs(useAppStore());
const channelList = TGConstant.BBS.CHANNELS;
const channelList = shallowRef<Array<ChannelItem>>();
const props = defineProps<ToChannelProps>();
const visible = defineModel<boolean>({ default: false });
async function toChannel(item: ToChannelItem): Promise<void> {
if (props.gid === item.gid) {
onMounted(async () => {
const allGames = await apiHubReq.game();
channelList.value = allGames.map((i) => ({ icon: i.app_icon, title: i.name, gid: i.id }));
});
async function toChannel(item: ChannelItem): Promise<void> {
if (props.gid === item.gid.toString()) {
showSnackbar.warn("当前已经在该频道");
return;
}
@@ -48,7 +53,7 @@ async function toChannel(item: ToChannelItem): Promise<void> {
link = link.replace("{type}", "notice");
recentNewsType.value = "notice";
}
await router.push(link);
window.location.href = link;
}
</script>
<style lang="css" scoped>

View File

@@ -3,7 +3,7 @@
<div class="tops-box">
<div class="tops-top">查找{{ search }}</div>
<div class="tops-act">
<span>分区{{ getGameName(Number(game)) }}</span>
<span>分区{{ gameName }}</span>
<v-btn :loading="load" size="small" class="tops-btn" @click="searchPosts()" rounded>
加载更多({{ results.length }})
</v-btn>
@@ -21,9 +21,9 @@ import TOverlay from "@comp/app/t-overlay.vue";
import TPostCard from "@comp/app/t-postcard.vue";
import showSnackbar from "@comp/func/snackbar.js";
import Mys from "@Mys/index.js";
import { onMounted, ref, shallowRef, watch } from "vue";
import { computed, onMounted, ref, shallowRef, watch } from "vue";
import { getGameName } from "@/utils/toolFunc.js";
import TGBbs from "@/utils/TGBbs.js";
type ToPostSearchProps = { gid: string; keyword?: string };
@@ -35,6 +35,9 @@ const game = ref<string>("2");
const isLast = ref<boolean>(false);
const load = ref<boolean>(false);
const results = shallowRef<Array<TGApp.Plugins.Mys.Post.FullData>>([]);
const gameName = computed<string>(
() => TGBbs.channels.find((v) => v.gid.toString() === game.value)?.title || "未知分区",
);
onMounted(async () => {
game.value = props.gid;

View File

@@ -5,10 +5,9 @@
<v-select
v-model="curGid"
class="home-tool-select"
:items="gameSelectList"
item-title="title"
item-value="gid"
:items="gameList"
:hide-details="true"
item-value="gid"
variant="outlined"
label="分区"
>
@@ -27,7 +26,7 @@
<div
v-bind="props"
class="select-item sub"
:class="{ selected: item.raw.gid === curGid }"
:class="item.raw.gid === curGid ? 'selected' : ''"
>
<img
:src="item.raw.icon"
@@ -39,7 +38,7 @@
</div>
</template>
</v-select>
<TGameNav :model-value="Number(curGid)" />
<TGameNav :model-value="curGid" />
</div>
<div class="home-select">
<v-select
@@ -70,7 +69,7 @@ import { type Component, computed, onMounted, ref, shallowRef, watch } from "vue
import { useAppStore } from "@/store/modules/app.js";
import { ShowItemEnum, useHomeStore } from "@/store/modules/home.js";
import TGLogger from "@/utils/TGLogger.js";
import TGConstant from "@/web/constant/TGConstant.js";
import apiHubReq from "@/web/request/apiHubReq.js";
type SFComp = Component & {
__file?: string;
@@ -78,6 +77,7 @@ type SFComp = Component & {
__name?: string;
__scopeId?: string;
};
type SelectItem = { icon: string; title: string; gid: number };
const { devMode, isLogin } = storeToRefs(useAppStore());
const homeStore = useHomeStore();
@@ -88,8 +88,8 @@ const showItemsAll: Array<ShowItemEnum> = [
ShowItemEnum.position,
];
const gameSelectList = TGConstant.BBS.CHANNELS;
const curGid = ref<string>(gameSelectList[0].gid);
const curGid = ref<number>(2);
const gameList = shallowRef<Array<SelectItem>>();
const loadItems = shallowRef<Array<ShowItemEnum>>([]);
const components = shallowRef<Array<SFComp>>([]);
@@ -102,6 +102,11 @@ onMounted(async () => {
// @ts-expect-error-next-line The import.meta meta-property is not allowed in files which will build into CommonJS output.
const isProdEnv = import.meta.env.MODE === "production";
if (isProdEnv && devMode.value) devMode.value = false;
if (isLogin.value) {
await showLoading.start("正在加载首页小部件");
const allGames = await apiHubReq.game();
gameList.value = allGames.map((i) => ({ icon: i.app_icon, title: i.name, gid: i.id }));
}
await loadComp();
});
@@ -190,8 +195,8 @@ async function loadEnd(item: SFComp): Promise<void> {
}
.home-tool-select {
width: 200px;
max-width: 200px;
width: 250px;
max-width: 250px;
}
.home-select {

View File

@@ -18,9 +18,10 @@
>
<template #selection="{ item }">
<div class="select-item main">
<img
<TMiImg
v-if="item.raw.icon"
:src="item.raw.icon"
:ori="true"
:alt="item.raw.text"
:title="item.raw.text"
class="icon"
@@ -34,7 +35,13 @@
class="select-item sub"
:class="{ selected: item.raw.gid === curGid }"
>
<img v-if="item.raw.icon" :src="item.raw.icon" :alt="item.raw.text" class="icon" />
<TMiImg
v-if="item.raw.icon"
:src="item.raw.icon"
:alt="item.raw.text"
class="icon"
:ori="true"
/>
<span>{{ item.raw.text }}</span>
</div>
</template>
@@ -126,7 +133,6 @@ import { useRoute, useRouter } from "vue-router";
import TGLogger from "@/utils/TGLogger.js";
import { createPost } from "@/utils/TGWindow.js";
import { getGameIcon, getGameName } from "@/utils/toolFunc.js";
import ApiHubReq from "@/web/request/apiHubReq.js";
type SortSelect = { text: string; value: number; icon: string };
@@ -198,16 +204,19 @@ watch(
// 初始化
async function loadForums(): Promise<void> {
const allGames = await ApiHubReq.game();
const allForums = await ApiHubReq.forum();
const gameList: Array<SortSelectGame> = [];
for (const gameForum of allForums) {
const gameFind = allGames.find((i) => i.id === gameForum.game_id);
if (!gameFind) continue;
const gameItem: SortSelectGame = {
gid: gameForum.game_id,
icon: getGameIcon(gameForum.game_id),
icon: gameFind.app_icon,
forum: gameForum.forums
.sort((a, b) => a.order - b.order)
.map((i) => ({ text: i.name, value: i.id, icon: i.icon_pure })),
text: getGameName(gameForum.game_id),
text: gameFind.name,
};
gameList.push(gameItem);
}

View File

@@ -68,9 +68,9 @@ import { computed, onMounted, reactive, ref, shallowRef } from "vue";
import { useRoute, useRouter } from "vue-router";
import { type NewsType, NewsTypeEnum, useAppStore } from "@/store/modules/app.js";
import TGBbs from "@/utils/TGBbs.js";
import TGLogger from "@/utils/TGLogger.js";
import { createPost } from "@/utils/TGWindow.js";
import { getGameName } from "@/utils/toolFunc.js";
type PostData = { [key in NewsType]: Ref<Array<TGApp.Plugins.Mys.Post.FullData>> };
type RawItem = { isLast: boolean; name: string; lastId: number };
@@ -78,9 +78,11 @@ type RawData = { [key in NewsType]: Ref<RawItem> };
const router = useRouter();
const { recentNewsType } = storeToRefs(useAppStore());
const tabValues: Readonly<Array<NewsType>> = ["notice", "activity", "news"];
const { gid } = <{ gid: string }>useRoute().params;
const gameName = getGameName(Number(gid));
const tabValues: Readonly<Array<NewsType>> = ["notice", "activity", "news"];
const gameName = TGBbs.channels.find((v) => v.gid.toString() === gid)?.title || "未知分区";
const loading = ref<boolean>(false);
const showList = ref<boolean>(false);
const showSearch = ref<boolean>(false);

View File

@@ -16,7 +16,7 @@
<v-select
v-model="curGame"
class="post-switch-item"
:items="topicInfo?.game_info_list"
:items="getGameList(topicInfo?.game_info_list)"
item-title="name"
:item-value="(item) => item"
variant="outlined"
@@ -25,8 +25,8 @@
<template #selection="{ item }">
<div class="select-item main">
<img
v-if="getGameIcon(item.raw.id)"
:src="getGameIcon(item.raw.id)"
v-if="item.raw.icon"
:src="item.raw.icon"
:alt="item.raw.name"
:title="item.raw.name"
class="icon"
@@ -37,8 +37,8 @@
<template #item="{ props, item }">
<div v-bind="props" class="select-item sub" :class="{ selected: item.raw.id === curGid }">
<img
v-if="getGameIcon(item.raw.id)"
:src="getGameIcon(item.raw.id)"
v-if="item.raw.icon"
:src="item.raw.icon"
:alt="item.raw.name"
:title="item.raw.name"
class="icon"
@@ -95,10 +95,11 @@ import { computed, onMounted, ref, shallowRef, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { createPost } from "@/utils/TGWindow.js";
import { getGameIcon } from "@/utils/toolFunc.js";
import apiHubReq from "@/web/request/apiHubReq.js";
type SortSelect = { text: string; value: number };
type PostMiniData = { isLast: boolean; lastId: string; total: number };
type GameList = TGApp.Plugins.Mys.Topic.GameInfo & { icon?: string };
const route = useRoute();
const router = useRouter();
@@ -107,10 +108,11 @@ const curGid = ref<number>(0);
const curSortType = ref<0 | 1 | 2>(0);
const search = ref<string>("");
const curTopic = ref<string>("");
const allGames = shallowRef<Array<TGApp.BBS.Game.Item>>([]);
const postRaw = shallowRef<PostMiniData>({ isLast: false, lastId: "", total: 0 });
const topicInfo = shallowRef<TGApp.Plugins.Mys.Topic.InfoData>();
const posts = shallowRef<Array<TGApp.Plugins.Mys.Post.FullData>>([]);
const curGame = shallowRef<TGApp.Plugins.Mys.Topic.GameInfo>();
const curGame = shallowRef<GameList>();
const sortList = computed<Array<SortSelect>>(() => {
if (!topicInfo.value) return [];
if (!topicInfo.value.good_post_exist) {
@@ -135,6 +137,7 @@ onMounted(async () => {
curGid.value = Number(gid);
curTopic.value = topic;
await showLoading.start(`正在加载话题${topic}信息`);
allGames.value = await apiHubReq.game();
const info = await Mys.Post.getTopicFullInfo(gid, topic);
if ("retcode" in info) {
await showLoading.end();
@@ -142,10 +145,13 @@ onMounted(async () => {
return;
}
topicInfo.value = info;
let tmpGame: GameList | undefined;
if (curGame.value === undefined) {
curGame.value = info.game_info_list.find((i) => i.id === curGid.value);
tmpGame = info.game_info_list.find((i) => i.id === curGid.value);
}
if (curGame.value === undefined) curGame.value = info.game_info_list[0];
if (tmpGame === undefined) tmpGame = info.game_info_list[0];
const gameFind = allGames.value.find((i) => i.id === tmpGame?.id);
curGame.value = { ...tmpGame, icon: gameFind?.app_icon };
await firstLoad();
});
@@ -226,6 +232,14 @@ function searchPost(): void {
if (isNaN(numCheck)) showSearch.value = true;
else createPost(search.value);
}
function getGameList(gameList: TGApp.Plugins.Mys.Topic.GameInfo[] | undefined): GameList[] {
if (!gameList) return [];
return gameList.map((item) => {
const game = allGames.value.find((i) => i.id === item.id);
return { ...item, icon: game?.app_icon };
});
}
</script>
<style lang="css" scoped>
.post-topic-top {
@@ -337,7 +351,6 @@ function searchPost(): void {
.icon {
width: 28px;
height: 28px;
border-radius: 4px;
}
}
</style>

View File

@@ -7,9 +7,9 @@
import showSnackbar from "@comp/func/snackbar.js";
import { JSEncrypt } from "jsencrypt";
import TGBbs from "@/utils/TGBbs.js";
import TGHttp from "@/utils/TGHttp.js";
import { getDeviceInfo } from "@/utils/toolFunc.js";
import TGConstant from "@/web/constant/TGConstant.js";
const PUB_KEY_STR: Readonly<string> = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDvekdPMHN3AYhm/vktJT+YJr7cI5DcsNKqdsx5DZX0gDuWFuIjzdwButrIYPNmRJ1G8ybDIF7oDW2eEpm5sMbL9zs
@@ -53,14 +53,14 @@ export async function getCaptcha(
const body = { area_code: rsaEncrypt("+86"), mobile: rsaEncrypt(phone) };
const header: Record<string, string> = {
"x-rpc-aigis": aigis || "",
"x-rpc-app_version": TGConstant.BBS.VERSION,
"x-rpc-app_version": TGBbs.version,
"x-rpc-client_type": "2",
"x-rpc-app_id": "bll8iq97cem8",
"x-rpc-device_fp": device_fp,
"x-rpc-device_name": device_name,
"x-rpc-device_id": device_id,
"x-rpc-device_model": device_model,
"user-agent": TGConstant.BBS.UA_MOBILE,
"user-agent": TGBbs.ua,
"content-type": "application/json",
referer: "https://user.miyoushe.com/",
"x-rpc-game_biz": "hk4e_cn",
@@ -115,14 +115,14 @@ export async function doCaptchaLogin(
};
const header = {
"x-rpc-aigis": aigis || "",
"x-rpc-app_version": TGConstant.BBS.VERSION,
"x-rpc-app_version": TGBbs.version,
"x-rpc-client_type": "2",
"x-rpc-app_id": "bll8iq97cem8",
"x-rpc-device_fp": device_fp,
"x-rpc-device_name": device_name,
"x-rpc-device_id": device_id,
"x-rpc-device_model": device_model,
"user-agent": TGConstant.BBS.UA_MOBILE,
"user-agent": TGBbs.ua,
};
const resp = await TGHttp<TGApp.Plugins.Mys.CaptchaLogin.LoginResponse | TGApp.BBS.Response.Base>(
url,

52
src/types/BBS/Game.d.ts vendored Normal file
View File

@@ -0,0 +1,52 @@
/**
* @file types/BBS/Game.d.ts
* @description 游戏相关的类型定义
* @since Beta v0.6.8
*/
declare namespace TGApp.BBS.Game {
/**
* @description 游戏列表返回
* @since Beta v0.6.8
* @interface ListResp
* @extends TGApp.BBS.Response.BaseWithData
* @property {Array<Item>} data.list 游戏列表
* @return ListResp
*/
type ListResp = TGApp.BBS.Response.BaseWithData & { data: { list: Array<Item> } };
/**
* @description 游戏列表项
* @since Beta v0.6.8
* @interface Item
* @property {number} id 游戏 ID
* @property {string} name 游戏名称
* @property {string} en_name 游戏英文名称
* @property {string} app_icon 游戏图标
* @property {string} icon 游戏图标
* @property {string} search_trend_word 搜索热词
* @property {string} level_image 游戏等级图标
* @property {string} level_text_color 游戏等级文字颜色
* @property {number} topic_num 游戏话题数
* @property {string} op_name 运营名称
* @property {string} main_color 主色调 AB9756
* @property {boolean} has_wiki 是否有百科
* @property {Array<unknown>} game_sort_config 游戏分类配置
* @return Item
*/
type Item = {
id: number;
name: string;
en_name: string;
app_icon: string;
icon: string;
search_trend_word: string;
level_image: string;
level_text_color: string;
topic_num: number;
op_name: string;
main_color: string;
has_wiki: boolean;
game_sort_config: Array<unknown>;
};
}

49
src/utils/TGBbs.ts Normal file
View File

@@ -0,0 +1,49 @@
/**
* @file utils/TGBbs.ts
* @description 关于 BBS 的工具函数
* @since Beta v0.6.8
*/
const BBS_VERSION: Readonly<string> = "2.80.1";
const BBS_UA_MOBILE: Readonly<string> = `Mozilla/5.0 (Linux; Android 12) Mobile miHoYoBBS/${BBS_VERSION}`;
/**
* @description 频道列表
* @since Beta v0.6.8
* @interface ChannelItem
* @property {string} title - 频道名称
* @property {number} gid - 频道 gid
* @property {string} mini - 频道简称
* @return ToChannelItem
*/
type ChannelItem = { title: string; gid: number; mini: string };
/**
* @description 渠道列表
* @since Beta v0.6.8
* @type {Array<ChannelItem>}
*/
const CHANNEL_LIST: Readonly<Array<ChannelItem>> = [
{ title: "原神", gid: 2, mini: "ys" },
{ title: "崩坏:星穹铁道", gid: 6, mini: "sr" },
{ title: "绝区零", gid: 8, mini: "zzz" },
{ title: "崩坏3", gid: 1, mini: "bh3" },
{ title: "崩坏2", gid: 3, mini: "bh2" },
{ title: "未定事件簿", gid: 4, mini: "wd" },
{ title: "大别野", gid: 5, mini: "dby" },
];
/**
* @description 获取游戏id
* @since Beta v0.6.8
* @param {string} mini
* @returns {string}
*/
export function getGameId(mini: string): number {
const game = CHANNEL_LIST.find((item) => item.mini === mini);
return game ? game.gid : 0;
}
const TGBbs = { version: BBS_VERSION, ua: BBS_UA_MOBILE, channels: CHANNEL_LIST };
export default TGBbs;

View File

@@ -16,7 +16,7 @@ import { getDeviceInfo } from "./toolFunc.js";
import { useAppStore } from "@/store/modules/app.js";
import { useUserStore } from "@/store/modules/user.js";
import TGConstant from "@/web/constant/TGConstant.js";
import TGBbs from "@/utils/TGBbs.js";
import BBSApi from "@/web/request/bbsReq.js";
import OtherApi from "@/web/request/otherReq.js";
import PassportApi from "@/web/request/passportReq.js";
@@ -623,10 +623,10 @@ class Client {
let deviceInfo = useAppStore().deviceInfo;
if (localFp === "0000000000000") deviceInfo = await OtherApi.fp(deviceInfo);
const data = {
"user-agent": TGConstant.BBS.UA_MOBILE,
"user-agent": TGBbs.ua,
"x-rpc-client_type": "2",
"x-rpc-device_id": deviceInfo.device_id,
"x-rpc-app_version": TGConstant.BBS.VERSION,
"x-rpc-app_version": TGBbs.version,
"x-rpc-device_fp": deviceInfo.device_fp,
};
await this.callback(arg.callback, data);

View File

@@ -11,7 +11,7 @@ import { emit } from "@tauri-apps/api/event";
import TGClient from "./TGClient.js";
import { createPost } from "./TGWindow.js";
import { getGameId } from "@/utils/toolFunc.js";
import TGBbs from "@/utils/TGBbs.js";
/**
* @function parsePost
@@ -124,7 +124,7 @@ export async function parseLink(
const result = url.pathname.match(regex);
if (!result) return false;
const [, game, topicId] = result;
const id = getGameId(game);
const id = TGBbs.channels.find((item) => item.mini === game)?.gid;
await emit("active_deep_link", `router?path=/posts/topic/${id}/${topicId}`);
return true;
}

View File

@@ -12,7 +12,6 @@ import { v4 } from "uuid";
import { score } from "wcag-color";
import { AppCharacterData, AppWeaponData } from "@/data/index.js";
import TGConstant from "@/web/constant/TGConstant.js";
/**
* @description 时间戳转换为时间字符串
@@ -273,39 +272,6 @@ export function decodeRegExp(data: string): string {
return res;
}
/**
* @description 根据 gid 获取游戏名称
* @since Beta v0.6.7
* @param {number} gid
* @returns {string}
*/
export function getGameName(gid: number): string {
const game = TGConstant.BBS.CHANNELS.find((item) => item.gid === gid.toString());
return game ? game.title : "未知游戏";
}
/**
* @description 获取游戏id
* @since Beta v0.6.7
* @param {string} mini
* @returns {string}
*/
export function getGameId(mini: string): string {
const game = TGConstant.BBS.CHANNELS.find((item) => item.mini === mini);
return game ? game.gid : "0";
}
/**
* @description 根据id获取游戏图标
* @since Beta v0.6.8
* @param {number|string} gid
* @returns {string|undefined}
*/
export function getGameIcon(gid: number | string): string | undefined {
const game = TGConstant.BBS.CHANNELS.find((item) => item.gid === gid.toString());
return game ? game.icon : undefined;
}
/**
* @description 根据id获取对应角色/武器数据
* @since Beta v0.6.8

View File

@@ -101,10 +101,9 @@ import { onMounted, onUnmounted, ref, shallowRef } from "vue";
import { useRoute } from "vue-router";
import { useAppStore } from "@/store/modules/app.js";
import TGBbs from "@/utils/TGBbs.js";
import TGLogger from "@/utils/TGLogger.js";
import { createTGWindow } from "@/utils/TGWindow.js";
import { CHANNEL_LIST } from "@/web/constant/bbs.js";
import TGConstant from "@/web/constant/TGConstant.js";
const appVersion = ref<string>();
const postId = Number(useRoute().params.post_id);
@@ -117,8 +116,8 @@ const postData = shallowRef<TGApp.Plugins.Mys.Post.FullData>();
let shareTimer: NodeJS.Timeout | null = null;
function getGameIcon(gameId: number): string {
const find = TGConstant.BBS.CHANNELS.find((item) => item.gid === gameId.toString());
if (find) return find.icon;
const find = TGBbs.channels.find((item) => item.gid === gameId);
if (find) return `/platforms/mhy/${find.mini}.webp`;
return "/platforms/mhy/mys.webp";
}
@@ -229,6 +228,7 @@ async function parseContent(content: string): Promise<string> {
break;
default:
await TGLogger.Warn(`[t-post][${postId}][parseContent] Unknown key: ${key}`);
// @ts-expect-error unknown key
result.push({ insert: data[key] });
break;
}
@@ -243,7 +243,7 @@ async function createPostJson(postId: number): Promise<void> {
}
function toPost(): void {
const channel = CHANNEL_LIST.find((item) => item.gid === postData.value?.post.game_id.toString());
const channel = TGBbs.channels.find((item) => item.gid === postData.value?.post.game_id);
if (channel) {
window.open(`https://miyoushe.com/${channel.mini}/#/article/${postId}`);
} else {

View File

@@ -1,13 +0,0 @@
/**
* @file web/constant/TGConstant.ts
* @description 常量
* @since Beta v0.6.3
*/
import { BBS_UA_MOBILE, BBS_VERSION, CHANNEL_LIST } from "./bbs.js";
const TGConstant = {
BBS: { VERSION: BBS_VERSION, UA_MOBILE: BBS_UA_MOBILE, CHANNELS: CHANNEL_LIST },
};
export default TGConstant;

View File

@@ -1,75 +0,0 @@
/**
* @file web/constant/bbs.ts
* @description 常量-应用数据
* @since Beta v0.6.8
*/
export const BBS_VERSION: Readonly<string> = "2.80.1";
export const BBS_UA_MOBILE: Readonly<string> = `Mozilla/5.0 (Linux; Android 12) Mobile miHoYoBBS/${BBS_VERSION}`;
/**
* @description 频道列表
* @since Beta v0.6.5
* @interface ToChannelItem
* @property {string} title - 频道名称
* @property {string} icon - 频道图标
* @property {string} gid - 频道 gid
* @property {string} mini - 频道简称
* @return ToChannelItem
*/
export interface ToChannelItem {
title: string;
icon: string;
gid: string;
mini: string;
}
/**
* @description 渠道列表
* @since Beta v0.6.5
* @type {Array<ToChannelItem>}
*/
export const CHANNEL_LIST: Readonly<Array<ToChannelItem>> = [
{
title: "原神",
icon: "/platforms/mhy/ys.webp",
gid: "2",
mini: "ys",
},
{
title: "崩坏:星穹铁道",
icon: "/platforms/mhy/sr.webp",
gid: "6",
mini: "sr",
},
{
title: "绝区零",
icon: "/platforms/mhy/zzz.webp",
gid: "8",
mini: "zzz",
},
{
title: "崩坏3",
icon: "/platforms/mhy/bh3.webp",
gid: "1",
mini: "bh3",
},
{
title: "崩坏2",
icon: "/platforms/mhy/bh2.webp",
gid: "3",
mini: "bh2",
},
{
title: "未定事件簿",
icon: "/platforms/mhy/wd.webp",
gid: "4",
mini: "wd",
},
{
title: "大别野",
icon: "/platforms/mhy/dby.webp",
gid: "5",
mini: "dby",
},
];

View File

@@ -26,6 +26,20 @@ async function getAllGamesForums(): Promise<Array<TGApp.BBS.Forum.GameForum>> {
).data.list;
}
/**
* @description 获取所有分区
* @since Beta v0.6.8
* @return {Promise<Array<TGApp.BBS.Game.Item>>}
*/
async function getGameList(): Promise<Array<TGApp.BBS.Game.Item>> {
return (
await TGHttp<TGApp.BBS.Game.ListResp>(`${Mahwbu}getGameList`, {
method: "GET",
headers: { "Content-Type": "application/json", referer: Referer },
})
).data.list;
}
/**
* @description 获取投票信息
* @since Beta v0.6.2
@@ -80,6 +94,7 @@ const apiHubReq = {
vote: { info: getVotes, result: getVoteResult },
home: homeNew,
forum: getAllGamesForums,
game: getGameList,
};
export default apiHubReq;

View File

@@ -1,13 +1,13 @@
/**
* @file web/request/otherReq.ts
* @description Other API
* @since Beta v0.6.3
* @since Beta v0.6.8
*/
import TGBbs from "@/utils/TGBbs.js";
import TGHttp from "@/utils/TGHttp.js";
import TGLogger from "@/utils/TGLogger.js";
import { getInitDeviceInfo } from "@/utils/toolFunc.js";
import TGConstant from "@/web/constant/TGConstant.js";
/**
* @description 获取设备指纹
@@ -85,8 +85,8 @@ async function getDeviceFp(
device_fp: info.device_fp,
};
const header: Record<string, string> = {
"user-agent": TGConstant.BBS.UA_MOBILE,
"x-rpc-app_version": TGConstant.BBS.VERSION,
"user-agent": TGBbs.ua,
"x-rpc-app_version": TGBbs.version,
"x-rpc-client_type": "5",
"x-requested-with": "com.mihoyo.hyperion",
Referer: "https://webstatic.mihoyo.com/",

View File

@@ -6,8 +6,8 @@
import Md5 from "js-md5";
import TGBbs from "@/utils/TGBbs.js";
import { getDeviceInfo, getRandomString } from "@/utils/toolFunc.js";
import { BBS_VERSION } from "@/web/constant/bbs.js";
/**
* @description salt 类型
@@ -34,7 +34,7 @@ const Salt: Readonly<Record<keyof typeof SaltType, string>> = {
X6: "t0qEgfub6cvueAPgR5m9aQWWVciEer7v",
PROD: "t0qEgfub6cvueAPgR5m9aQWWVciEer7v",
};
const UserAgent: Readonly<string> = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) miHoYoBBS/${BBS_VERSION}`;
const UserAgent: Readonly<string> = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) miHoYoBBS/${TGBbs.version}`;
/**
* @description 获取随机数
@@ -126,7 +126,7 @@ export function getRequestHeader(
): Record<string, string> {
return {
"user-agent": UserAgent,
"x-rpc-app_version": BBS_VERSION,
"x-rpc-app_version": TGBbs.version,
"x-rpc-client_type": "5",
"x-requested-with": "com.mihoyo.hyperion",
referer: "https://webstatic.mihoyo.com",