mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
refactor(Mys): request 跟 utils 拿出来了
This commit is contained in:
@@ -59,45 +59,28 @@
|
|||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import TLoading from "../components/t-loading.vue";
|
import TLoading from "../components/t-loading.vue";
|
||||||
// tauri
|
// tauri
|
||||||
import { fs, http } from "@tauri-apps/api";
|
import { fs } from "@tauri-apps/api";
|
||||||
// store
|
// store
|
||||||
import useAppStore from "../store/modules/app";
|
import useAppStore from "../store/modules/app";
|
||||||
// plugin
|
// plugin
|
||||||
import Mys_Oper from "../plugins/Mys";
|
import MysOper from "../plugins/Mys";
|
||||||
// utils
|
// utils
|
||||||
import { createTGWindow } from "../utils/TGWindow";
|
import { createTGWindow } from "../utils/TGWindow";
|
||||||
// interface
|
// interface
|
||||||
import {
|
import { GachaData, GachaCard } from "../plugins/Mys/interface/gacha";
|
||||||
GachaResponse,
|
import { Post } from "../plugins/Mys/interface/post";
|
||||||
GachaData,
|
|
||||||
GachaPoolRender,
|
|
||||||
GACHA_POOL_API,
|
|
||||||
} from "../plugins/Mys/interface/gacha";
|
|
||||||
import {
|
|
||||||
PostResponse,
|
|
||||||
Post,
|
|
||||||
POST_FULL_API,
|
|
||||||
POST_FULL_REFERER,
|
|
||||||
} from "../plugins/Mys/interface/post";
|
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const poolInfo = ref([] as GachaPoolRender[]);
|
const poolInfo = ref([] as GachaCard[]);
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const empty = ref(false);
|
const empty = ref(false);
|
||||||
const timeGet = ref("");
|
const timeGet = ref("");
|
||||||
const timePass = ref(0);
|
const timePass = ref(0);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const responseGachaPool: GachaData[] = await http
|
const responseGachaPool: GachaData[] = await MysOper.Gacha.get();
|
||||||
.fetch<GachaResponse>(GACHA_POOL_API, {
|
const start_time = responseGachaPool[0].start_time;
|
||||||
method: "GET",
|
const end_time = responseGachaPool[0].end_time;
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
return response.data.data.list;
|
|
||||||
});
|
|
||||||
// 如果没有卡池信息则不进行后续操作
|
// 如果没有卡池信息则不进行后续操作
|
||||||
if (responseGachaPool.length === 0) {
|
if (responseGachaPool.length === 0) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -105,43 +88,11 @@ onMounted(async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
empty.value = false;
|
empty.value = false;
|
||||||
responseGachaPool.map(async (gachaPool: GachaData) => {
|
poolInfo.value = await MysOper.Gacha.card(responseGachaPool);
|
||||||
// 获取卡池 article post_id
|
getTimeNow(start_time, end_time);
|
||||||
const post_id = gachaPool.activity_url.split("/").pop();
|
setInterval(() => {
|
||||||
if (!post_id) return;
|
loading.value = false;
|
||||||
const gachaCover = await http
|
}, 1000);
|
||||||
.fetch<PostResponse>(POST_FULL_API.replace("{post_id}", post_id), {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
referer: POST_FULL_REFERER.replace("{post_id}", post_id),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
return response.data.data.post.post.images[0];
|
|
||||||
});
|
|
||||||
poolInfo.value.push({
|
|
||||||
title: gachaPool.title,
|
|
||||||
subtitle: gachaPool.content_before_act,
|
|
||||||
post_id: post_id,
|
|
||||||
cover: gachaCover,
|
|
||||||
characters: gachaPool.pool.map(character => ({
|
|
||||||
icon: character.icon,
|
|
||||||
url: character.url,
|
|
||||||
})),
|
|
||||||
voice: {
|
|
||||||
icon: gachaPool.voice_icon,
|
|
||||||
url: gachaPool.voice_url,
|
|
||||||
},
|
|
||||||
time: {
|
|
||||||
start: gachaPool.start_time,
|
|
||||||
end: gachaPool.end_time,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
getTimeNow(gachaPool.start_time, gachaPool.end_time);
|
|
||||||
setInterval(() => {
|
|
||||||
loading.value = false;
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function getTimeNow(start_time: string, end_time: string) {
|
function getTimeNow(start_time: string, end_time: string) {
|
||||||
@@ -165,23 +116,11 @@ function toOuter(url: string, title: string) {
|
|||||||
createTGWindow(url, "祈愿", title, 1200, 800, true);
|
createTGWindow(url, "祈愿", title, 1200, 800, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toPost(post_id: string) {
|
async function toPost(post_id: number) {
|
||||||
// 获取帖子内容
|
// 获取帖子内容
|
||||||
const post: Post = await http
|
const post: Post = (await MysOper.Post.get(post_id)).post;
|
||||||
.fetch(POST_FULL_API.replace("{post_id}", post_id), {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
referer: POST_FULL_REFERER.replace("{post_id}", post_id),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
return res.data as Promise<PostResponse>;
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
return res.data.post.post;
|
|
||||||
});
|
|
||||||
// 结构化渲染
|
// 结构化渲染
|
||||||
const parseDoc = Mys_Oper.PostParser(post.structured_content);
|
const parseDoc = MysOper.Post.parser(post.structured_content);
|
||||||
// 将解析后的 doc 保存到 文件
|
// 将解析后的 doc 保存到 文件
|
||||||
await fs.writeTextFile(
|
await fs.writeTextFile(
|
||||||
`${appStore.dataPath.temp}\\${post_id}_home.html`,
|
`${appStore.dataPath.temp}\\${post_id}_home.html`,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="loading">
|
<div v-if="loading">
|
||||||
<t-loading title="加载中..." />
|
<t-loading :title="loadingTitle" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<v-tabs v-model="tab" align-tabs="start" class="global-font">
|
<v-tabs v-model="tab" align-tabs="start" class="global-font">
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- todo 加载更多 -->
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="activity">
|
<v-window-item value="activity">
|
||||||
<div class="News-grid">
|
<div class="News-grid">
|
||||||
@@ -65,14 +66,13 @@
|
|||||||
</v-btn>
|
</v-btn>
|
||||||
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
<v-card-subtitle>id:{{ item.post_id }}</v-card-subtitle>
|
||||||
<div v-show="!appStore.devMode">
|
<div v-show="!appStore.devMode">
|
||||||
<v-btn v-show="item.status === ActivityStatus.STARTED" color="ms-2 card-btn-0"
|
<v-btn
|
||||||
>进行中</v-btn
|
class="ms-2"
|
||||||
>
|
:style="{
|
||||||
<v-btn v-show="item.status === ActivityStatus.FINISHED" color="ms-2 card-btn-2"
|
background: item.status_color + ' !important',
|
||||||
>已结束</v-btn
|
color: '#faf7e8 !important',
|
||||||
>
|
}"
|
||||||
<v-btn v-show="item.status === ActivityStatus.SELECTION" color="ms-2 card-btn-1"
|
>{{ item.status }}</v-btn
|
||||||
>评选中</v-btn
|
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<v-btn @click="toJson(item.post_id)" class="ms-2 card-btn" v-show="appStore.devMode">
|
<v-btn @click="toJson(item.post_id)" class="ms-2 card-btn" v-show="appStore.devMode">
|
||||||
@@ -84,6 +84,7 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- todo 加载更多 -->
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
<v-window-item value="news">
|
<v-window-item value="news">
|
||||||
<div class="News-grid">
|
<div class="News-grid">
|
||||||
@@ -116,6 +117,7 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- todo 加载更多 -->
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
</v-window>
|
</v-window>
|
||||||
</div>
|
</div>
|
||||||
@@ -126,31 +128,19 @@
|
|||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import TLoading from "../components/t-loading.vue";
|
import TLoading from "../components/t-loading.vue";
|
||||||
// tauri
|
// tauri
|
||||||
import { http, fs } from "@tauri-apps/api";
|
import { fs } from "@tauri-apps/api";
|
||||||
// store
|
// store
|
||||||
import useAppStore from "../store/modules/app";
|
import useAppStore from "../store/modules/app";
|
||||||
// tools
|
// tools
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import "../tools/svg-inject.js";
|
import "../tools/svg-inject.js";
|
||||||
// plugin
|
// plugin
|
||||||
import Mys_Oper from "../plugins/Mys";
|
import MysOper from "../plugins/Mys";
|
||||||
// utils
|
// utils
|
||||||
import { createTGWindow } from "../utils/TGWindow";
|
import { createTGWindow } from "../utils/TGWindow";
|
||||||
// interface
|
// interface
|
||||||
import {
|
import { Post } from "../plugins/Mys/interface/post";
|
||||||
Post,
|
import { NewsCard, NewsData } from "../plugins/Mys/interface/news";
|
||||||
PostResponse,
|
|
||||||
POST_FULL_API,
|
|
||||||
POST_FULL_REFERER,
|
|
||||||
} from "../plugins/Mys/interface/post";
|
|
||||||
import {
|
|
||||||
NewsResponse,
|
|
||||||
NewsType,
|
|
||||||
NEWS_LIST_API,
|
|
||||||
ActivityStatus,
|
|
||||||
NewsCard,
|
|
||||||
NewsItem,
|
|
||||||
} from "../plugins/Mys/interface/news";
|
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
@@ -159,6 +149,7 @@ const appStore = useAppStore();
|
|||||||
const renderMode = ref(appStore.structureRender);
|
const renderMode = ref(appStore.structureRender);
|
||||||
// loading
|
// loading
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
const loadingTitle = ref("正在加载");
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
const tab = ref("");
|
const tab = ref("");
|
||||||
@@ -167,56 +158,35 @@ const postData = ref({
|
|||||||
activity: [] as NewsCard[],
|
activity: [] as NewsCard[],
|
||||||
news: [] as NewsCard[],
|
news: [] as NewsCard[],
|
||||||
});
|
});
|
||||||
|
const noticeData = ref({} as NewsData);
|
||||||
|
const activityData = ref({} as NewsData);
|
||||||
|
const newsData = ref({} as NewsData);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const noticeRaw: NewsResponse = await http
|
loadingTitle.value = "正在获取公告数据...";
|
||||||
.fetch(NEWS_LIST_API.replace("{news_type}", NewsType.NOTICE.toString()))
|
noticeData.value = await MysOper.News.get.notice();
|
||||||
.then(res => res.data as Promise<NewsResponse>);
|
loadingTitle.value = "正在获取活动数据...";
|
||||||
const activityRaw: NewsResponse = await http
|
activityData.value = await MysOper.News.get.activity();
|
||||||
.fetch(NEWS_LIST_API.replace("{news_type}", NewsType.ACTIVITY.toString()))
|
loadingTitle.value = "正在获取新闻数据...";
|
||||||
.then(res => res.data as Promise<NewsResponse>);
|
newsData.value = await MysOper.News.get.news();
|
||||||
const newsRaw: NewsResponse = await http
|
loadingTitle.value = "正在渲染数据...";
|
||||||
.fetch(NEWS_LIST_API.replace("{news_type}", NewsType.NEWS.toString()))
|
|
||||||
.then(res => res.data as Promise<NewsResponse>);
|
|
||||||
postData.value = {
|
postData.value = {
|
||||||
notice: transData(noticeRaw, "notice"),
|
notice: MysOper.News.card.notice(noticeData.value),
|
||||||
activity: transData(activityRaw, "activity"),
|
activity: MysOper.News.card.activity(activityData.value),
|
||||||
news: transData(newsRaw, "news"),
|
news: MysOper.News.card.news(newsData.value),
|
||||||
};
|
};
|
||||||
tab.value = "notice";
|
tab.value = "notice";
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
function transData(rawData: NewsResponse, dataType: string): NewsCard[] {
|
async function toPost(post_id: number) {
|
||||||
const cardData: NewsCard[] = [];
|
|
||||||
rawData.data.list.map((item: NewsItem) => {
|
|
||||||
const postData: Post = item.post;
|
|
||||||
const card: NewsCard = {
|
|
||||||
title: postData.subject,
|
|
||||||
cover: postData.images.length === 0 ? postData.cover : postData.images[0],
|
|
||||||
post_id: postData.post_id,
|
|
||||||
subtitle: postData.post_id,
|
|
||||||
};
|
|
||||||
if (dataType === "activity") {
|
|
||||||
card.status = item.news_meta.activity_status;
|
|
||||||
const startTime = new Date(Number(item.news_meta.start_at_sec) * 1000).toLocaleDateString();
|
|
||||||
const endTime = new Date(Number(item.news_meta.end_at_sec) * 1000).toLocaleDateString();
|
|
||||||
card.subtitle = `${startTime} - ${endTime}`;
|
|
||||||
}
|
|
||||||
return cardData.push(card);
|
|
||||||
});
|
|
||||||
return cardData;
|
|
||||||
}
|
|
||||||
async function toPost(post_id: string) {
|
|
||||||
// 获取帖子内容
|
// 获取帖子内容
|
||||||
const post: Post = await getPost(post_id).then(res => {
|
const post: Post = (await MysOper.Post.get(post_id)).post;
|
||||||
return res.data.post.post;
|
|
||||||
});
|
|
||||||
let parseDoc: Document;
|
let parseDoc: Document;
|
||||||
// 获取渲染模式
|
// 获取渲染模式
|
||||||
if (renderMode.value) {
|
if (renderMode.value) {
|
||||||
// 结构化渲染
|
// 结构化渲染
|
||||||
parseDoc = Mys_Oper.PostParser(post.structured_content);
|
parseDoc = MysOper.Post.parser(post.structured_content);
|
||||||
} else {
|
} else {
|
||||||
// 原始渲染
|
// 原始渲染
|
||||||
parseDoc = new DOMParser().parseFromString(post.content, "text/html");
|
parseDoc = new DOMParser().parseFromString(post.content, "text/html");
|
||||||
@@ -229,10 +199,8 @@ async function toPost(post_id: string) {
|
|||||||
const postUrl = `file:\\\\\\${appStore.dataPath.temp}\\${post.post_id}.html`;
|
const postUrl = `file:\\\\\\${appStore.dataPath.temp}\\${post.post_id}.html`;
|
||||||
createTGWindow(postUrl, "MysPost", post.subject, 960, 720, false);
|
createTGWindow(postUrl, "MysPost", post.subject, 960, 720, false);
|
||||||
}
|
}
|
||||||
async function toJson(post_id: string) {
|
async function toJson(post_id: number) {
|
||||||
const post = await getPost(post_id).then(res => {
|
const post: string = (await MysOper.Post.get(post_id)).post.structured_content;
|
||||||
return res.data.post.post.structured_content;
|
|
||||||
});
|
|
||||||
// 将 json 保存到 文件
|
// 将 json 保存到 文件
|
||||||
await fs.writeTextFile(
|
await fs.writeTextFile(
|
||||||
`${appStore.dataPath.temp}\\${post_id}.json`,
|
`${appStore.dataPath.temp}\\${post_id}.json`,
|
||||||
@@ -240,19 +208,7 @@ async function toJson(post_id: string) {
|
|||||||
);
|
);
|
||||||
const logUrl = `file:\\\\\\${appStore.dataPath.temp}\\${post_id}.json`;
|
const logUrl = `file:\\\\\\${appStore.dataPath.temp}\\${post_id}.json`;
|
||||||
// 打开窗口
|
// 打开窗口
|
||||||
createTGWindow(logUrl, "MysPostJson", post_id, 960, 720, false);
|
createTGWindow(logUrl, "MysPostJson", post_id.toString(), 960, 720, false);
|
||||||
}
|
|
||||||
async function getPost(post_id: string): Promise<PostResponse> {
|
|
||||||
return http
|
|
||||||
.fetch(POST_FULL_API.replace("{post_id}", post_id), {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
referer: POST_FULL_REFERER.replace("{post_id}", post_id),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
return res.data as Promise<PostResponse>;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -288,19 +244,4 @@ async function getPost(post_id: string): Promise<PostResponse> {
|
|||||||
.card-btn svg path {
|
.card-btn svg path {
|
||||||
fill: #faf7e8;
|
fill: #faf7e8;
|
||||||
}
|
}
|
||||||
/* 进行中 */
|
|
||||||
.card-btn-0 {
|
|
||||||
background: #3c99aa !important;
|
|
||||||
color: #faf7e8 !important;
|
|
||||||
}
|
|
||||||
/* 评选中 */
|
|
||||||
.card-btn-1 {
|
|
||||||
background: #849cc7 !important;
|
|
||||||
color: #faf7e8 !important;
|
|
||||||
}
|
|
||||||
/* 已结束 */
|
|
||||||
.card-btn-2 {
|
|
||||||
background: #c7674b !important;
|
|
||||||
color: #faf7e8 !important;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,10 +5,37 @@
|
|||||||
* @since Alpha
|
* @since Alpha
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Post
|
||||||
|
import { getPostData } from "./request/post";
|
||||||
import { PostParser } from "./utils/parser";
|
import { PostParser } from "./utils/parser";
|
||||||
|
// Gacha
|
||||||
|
import { getGachaData } from "./request/gacha";
|
||||||
|
import { getGachaCard } from "./utils/gacha";
|
||||||
|
// News
|
||||||
|
import { getNoticeList, getActivityList, getNewsList } from "./request/news";
|
||||||
|
import { getNoticeCard, getActivityCard, getNewsCard } from "./utils/news";
|
||||||
|
|
||||||
const Mys_Oper = {
|
const MysOper = {
|
||||||
PostParser,
|
Post: {
|
||||||
|
get: getPostData,
|
||||||
|
parser: PostParser,
|
||||||
|
},
|
||||||
|
Gacha: {
|
||||||
|
get: getGachaData,
|
||||||
|
card: getGachaCard,
|
||||||
|
},
|
||||||
|
News: {
|
||||||
|
get: {
|
||||||
|
notice: getNoticeList,
|
||||||
|
activity: getActivityList,
|
||||||
|
news: getNewsList,
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
notice: getNoticeCard,
|
||||||
|
activity: getActivityCard,
|
||||||
|
news: getNewsCard,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Mys_Oper;
|
export default MysOper;
|
||||||
|
|||||||
@@ -7,19 +7,6 @@
|
|||||||
|
|
||||||
import { MysResponse } from "./base";
|
import { MysResponse } from "./base";
|
||||||
|
|
||||||
// 卡池 API
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 获取卡池信息的返回类型
|
|
||||||
* @since Alpha
|
|
||||||
* @see GachaResponse
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export const GACHA_POOL_API =
|
|
||||||
"https://api-takumi.mihoyo.com/common/blackboard/ys_obc/v1/gacha_pool?app_sn=ys_obc";
|
|
||||||
|
|
||||||
// 卡池接口
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 获取卡池信息的返回类型
|
* @description 获取卡池信息的返回类型
|
||||||
* @since Alpha
|
* @since Alpha
|
||||||
@@ -80,23 +67,23 @@ export interface GachaPool {
|
|||||||
/**
|
/**
|
||||||
* @description 用于渲染的卡池数据
|
* @description 用于渲染的卡池数据
|
||||||
* @since Alpha
|
* @since Alpha
|
||||||
* @interface GachaPoolRender
|
* @interface GachaCard
|
||||||
* @property {string} title 卡池标题
|
* @property {string} title 卡池标题
|
||||||
* @property {string} subtitle 卡池副标题
|
* @property {string} subtitle 卡池副标题
|
||||||
* @property {string} cover 卡池封面
|
* @property {string} cover 卡池封面
|
||||||
* @property {string} post_id 卡池对应帖子ID
|
* @property {number} post_id 卡池对应帖子ID
|
||||||
* @property {GachaPool[]} characters 卡池包含的角色
|
* @property {GachaPool[]} characters 卡池包含的角色
|
||||||
* @property {GachaPool} voice 卡池角色语音
|
* @property {GachaPool} voice 卡池角色语音
|
||||||
* @property time 卡池时间
|
* @property time 卡池时间
|
||||||
* @property {string} time.start 卡池开始时间
|
* @property {string} time.start 卡池开始时间
|
||||||
* @property {string} time.end 卡池结束时间
|
* @property {string} time.end 卡池结束时间
|
||||||
* @return {GachaPoolRender}
|
* @return {GachaCard}
|
||||||
*/
|
*/
|
||||||
export interface GachaPoolRender {
|
export interface GachaCard {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
cover: string;
|
cover: string;
|
||||||
post_id: string;
|
post_id: number;
|
||||||
characters: GachaPool[];
|
characters: GachaPool[];
|
||||||
voice: GachaPool;
|
voice: GachaPool;
|
||||||
time: {
|
time: {
|
||||||
|
|||||||
@@ -10,52 +10,6 @@ import { Post, Forum, Topic, PostStat } from "./post";
|
|||||||
import { User, SelfOperation } from "./user";
|
import { User, SelfOperation } from "./user";
|
||||||
import { ImageData, HelpSys } from "./utils";
|
import { ImageData, HelpSys } from "./utils";
|
||||||
|
|
||||||
// 咨讯 API
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 咨讯列表 API
|
|
||||||
* @since Alpha
|
|
||||||
* @param {number} ews_type 咨讯类型
|
|
||||||
* @see NewsType
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export const NEWS_LIST_API =
|
|
||||||
"https://bbs-api.mihoyo.com/post/wapi/getNewsList?gids=2&type={news_type}";
|
|
||||||
|
|
||||||
// 咨讯相关枚举数据
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 咨讯类型
|
|
||||||
* @enum NewsType
|
|
||||||
* @since Alpha
|
|
||||||
* @property {number} NOTICE 公告
|
|
||||||
* @property {number} ACTIVITY 活动
|
|
||||||
* @property {number} NEWS 咨讯
|
|
||||||
* @return {NewsType}
|
|
||||||
*/
|
|
||||||
export enum NewsType {
|
|
||||||
NOTICE = 1,
|
|
||||||
ACTIVITY = 2,
|
|
||||||
NEWS = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 活动状态
|
|
||||||
* @enum ActivityStatus
|
|
||||||
* @since Alpha
|
|
||||||
* @property {number} STARTED 进行中
|
|
||||||
* @property {number} FINISHED 已结束
|
|
||||||
* @property {number} SELECTION 评选中
|
|
||||||
* @return {ActivityStatus}
|
|
||||||
*/
|
|
||||||
export enum ActivityStatus {
|
|
||||||
STARTED = 1,
|
|
||||||
FINISHED = 2,
|
|
||||||
SELECTION = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 咨讯接口
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 咨讯返回数据
|
* @description 咨讯返回数据
|
||||||
* @since Alpha
|
* @since Alpha
|
||||||
@@ -155,15 +109,17 @@ export interface NewsMeta {
|
|||||||
* @interface NewsCard
|
* @interface NewsCard
|
||||||
* @property {string} title 标题
|
* @property {string} title 标题
|
||||||
* @property {string} cover 封面图片 URL
|
* @property {string} cover 封面图片 URL
|
||||||
* @property {string} post_id 帖子 ID
|
* @property {number} post_id 帖子 ID
|
||||||
* @property {string} subtitle 副标题
|
* @property {string} subtitle 副标题
|
||||||
* @property {number} status 活动状态,仅活动咨讯有
|
* @property {string} status 活动状态,仅活动咨讯有
|
||||||
|
* @property {string} status_color 活动状态按钮背景色,仅活动咨讯有
|
||||||
* @return {NewsCard}
|
* @return {NewsCard}
|
||||||
*/
|
*/
|
||||||
export interface NewsCard {
|
export interface NewsCard {
|
||||||
title: string;
|
title: string;
|
||||||
cover: string;
|
cover: string;
|
||||||
post_id: string;
|
post_id: number;
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
status?: number;
|
status?: string;
|
||||||
|
status_color?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,28 +10,6 @@ import { NewsMeta } from "./news";
|
|||||||
import { User, SelfOperation } from "./user";
|
import { User, SelfOperation } from "./user";
|
||||||
import { ImageData, HelpSys } from "./utils";
|
import { ImageData, HelpSys } from "./utils";
|
||||||
|
|
||||||
// Post API
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 帖子完整信息 API
|
|
||||||
* @since Alpha
|
|
||||||
* @see PostResponse
|
|
||||||
* @param {number} post_id 帖子 ID
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export const POST_FULL_API =
|
|
||||||
"https://bbs-api.mihoyo.com/post/wapi/getPostFull?gids=2&post_id={post_id}";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 帖子完整信息 Referer
|
|
||||||
* @since Alpha
|
|
||||||
* @param {number} post_id 帖子 ID
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export const POST_FULL_REFERER = "https://bbs.mihoyo.com/ys/article/{post_id}"; // 与 POST_FULL_API 中的 post_id 对应, 用于伪造 Referer
|
|
||||||
|
|
||||||
// Post Interface
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 帖子返回数据
|
* @description 帖子返回数据
|
||||||
* @since Alpha
|
* @since Alpha
|
||||||
|
|||||||
31
src/plugins/Mys/request/gacha.ts
Normal file
31
src/plugins/Mys/request/gacha.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys request gacha.ts
|
||||||
|
* @description Mys抽卡请求
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
import { GachaResponse, GachaData } from "../interface/gacha";
|
||||||
|
|
||||||
|
// 卡池 API
|
||||||
|
const GACHA_POOL_API =
|
||||||
|
"https://api-takumi.mihoyo.com/common/blackboard/ys_obc/v1/gacha_pool?app_sn=ys_obc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取卡池信息
|
||||||
|
* @since Alpha
|
||||||
|
* @return {Promise<GachaData[]>}
|
||||||
|
*/
|
||||||
|
export async function getGachaData(): Promise<GachaData[]> {
|
||||||
|
return await http
|
||||||
|
.fetch<GachaResponse>(GACHA_POOL_API, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
return res.data.data.list;
|
||||||
|
});
|
||||||
|
}
|
||||||
70
src/plugins/Mys/request/news.ts
Normal file
70
src/plugins/Mys/request/news.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys request news.ts
|
||||||
|
* @description Mys 插件咨讯请求
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
import { NewsData, NewsResponse } from "../interface/news";
|
||||||
|
|
||||||
|
// 咨讯 API
|
||||||
|
const NEWS_LIST_API =
|
||||||
|
"https://bbs-api.mihoyo.com/post/wapi/getNewsList?gids=2&page_size={page_size}&type={news_type}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 咨讯类型
|
||||||
|
* @enum NewsType
|
||||||
|
* @since Alpha
|
||||||
|
* @property {string} NOTICE 公告
|
||||||
|
* @property {string} ACTIVITY 活动
|
||||||
|
* @property {string} NEWS 咨讯
|
||||||
|
* @return {NewsType}
|
||||||
|
*/
|
||||||
|
enum NewsType {
|
||||||
|
NOTICE = "1",
|
||||||
|
ACTIVITY = "2",
|
||||||
|
NEWS = "3",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 Notice 列表
|
||||||
|
* @since Alpha
|
||||||
|
* @param {number} page_size 返回数量
|
||||||
|
* @return {Promise<NewsData>}
|
||||||
|
*/
|
||||||
|
export async function getNoticeList(page_size: number = 20): Promise<NewsData> {
|
||||||
|
const url = NEWS_LIST_API.replace("{page_size}", page_size.toString()).replace(
|
||||||
|
"{news_type}",
|
||||||
|
NewsType.NOTICE
|
||||||
|
);
|
||||||
|
return await http.fetch<NewsResponse>(url).then(res => res.data.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 Activity 列表
|
||||||
|
* @since Alpha
|
||||||
|
* @param {number} page_size 返回数量
|
||||||
|
* @return {Promise<NewsData>}
|
||||||
|
*/
|
||||||
|
export async function getActivityList(page_size: number = 20): Promise<NewsData> {
|
||||||
|
const url = NEWS_LIST_API.replace("{page_size}", page_size.toString()).replace(
|
||||||
|
"{news_type}",
|
||||||
|
NewsType.ACTIVITY
|
||||||
|
);
|
||||||
|
return await http.fetch<NewsResponse>(url).then(res => res.data.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取 News 列表
|
||||||
|
* @since Alpha
|
||||||
|
* @param {number} page_size 返回数量
|
||||||
|
* @return {Promise<NewsData>}
|
||||||
|
*/
|
||||||
|
export async function getNewsList(page_size: number = 20): Promise<NewsData> {
|
||||||
|
const url = NEWS_LIST_API.replace("{page_size}", page_size.toString()).replace(
|
||||||
|
"{news_type}",
|
||||||
|
NewsType.NEWS
|
||||||
|
);
|
||||||
|
return await http.fetch<NewsResponse>(url).then(res => res.data.data);
|
||||||
|
}
|
||||||
33
src/plugins/Mys/request/post.ts
Normal file
33
src/plugins/Mys/request/post.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys request post.ts
|
||||||
|
* @description Mys帖子请求
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { http } from "@tauri-apps/api";
|
||||||
|
import { PostResponse, PostData } from "../interface/post";
|
||||||
|
|
||||||
|
// 帖子 API
|
||||||
|
const POST_API = "https://bbs-api.mihoyo.com/post/wapi/getPostFull?gids=2&post_id={post_id}";
|
||||||
|
const POST_REFERER = "https://bbs.mihoyo.com/ys/article/{post_id}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取帖子信息
|
||||||
|
* @since Alpha
|
||||||
|
* @param {number} post_id 帖子 ID
|
||||||
|
* @return {Promise<PostData>}
|
||||||
|
*/
|
||||||
|
export async function getPostData(post_id: number): Promise<PostData> {
|
||||||
|
return await http
|
||||||
|
.fetch<PostResponse>(POST_API.replace("{post_id}", post_id.toString()), {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Referer: POST_REFERER.replace("{post_id}", post_id.toString()),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
return res.data.data.post;
|
||||||
|
});
|
||||||
|
}
|
||||||
46
src/plugins/Mys/utils/gacha.ts
Normal file
46
src/plugins/Mys/utils/gacha.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys utils gacha.ts
|
||||||
|
* @description Mys 插件抽卡工具
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getPostData } from "../request/post";
|
||||||
|
import { GachaCard, GachaData } from "../interface/gacha";
|
||||||
|
import { PostData } from "../interface/post";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 根据卡池信息转为渲染用的卡池信息
|
||||||
|
* @since Alpha
|
||||||
|
* @param {GachaData[]} gachaData 卡池信息
|
||||||
|
* @return {GachaCard[]}
|
||||||
|
*/
|
||||||
|
export async function getGachaCard(gachaData: GachaData[]): Promise<GachaCard[]> {
|
||||||
|
const gachaCard: GachaCard[] = [];
|
||||||
|
gachaData.map(async (data: GachaData) => {
|
||||||
|
const post_id: number | undefined = Number(data.activity_url.split("/").pop()) || undefined;
|
||||||
|
if (post_id === undefined) {
|
||||||
|
throw new Error("无法获取帖子 ID");
|
||||||
|
}
|
||||||
|
const post: PostData = await getPostData(post_id);
|
||||||
|
gachaCard.push({
|
||||||
|
title: data.title,
|
||||||
|
subtitle: data.content_before_act,
|
||||||
|
cover: post.cover?.url || post.post.images[0],
|
||||||
|
post_id: post_id,
|
||||||
|
characters: data.pool.map(character => ({
|
||||||
|
icon: character.icon,
|
||||||
|
url: character.url,
|
||||||
|
})),
|
||||||
|
voice: {
|
||||||
|
icon: data.voice_icon,
|
||||||
|
url: data.voice_url,
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
start: data.start_time,
|
||||||
|
end: data.end_time,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return gachaCard;
|
||||||
|
}
|
||||||
116
src/plugins/Mys/utils/news.ts
Normal file
116
src/plugins/Mys/utils/news.ts
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* @file plugins Mys utils news.ts
|
||||||
|
* @description Mys 插件咨讯工具
|
||||||
|
* @author BTMuli<bt-muli@outlook.com>
|
||||||
|
* @since Alpha
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NewsData, NewsItem, NewsCard } from "../interface/news";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 活动状态
|
||||||
|
* @enum ActivityStatus
|
||||||
|
* @since Alpha
|
||||||
|
* @property {string} STARTED 进行中
|
||||||
|
* @property {string} FINISHED 已结束
|
||||||
|
* @property {string} SELECTION 评选中
|
||||||
|
* @return {ActivityStatus}
|
||||||
|
*/
|
||||||
|
enum ActivityStatus {
|
||||||
|
STARTED = "进行中",
|
||||||
|
FINISHED = "已结束",
|
||||||
|
SELECTION = "评选中",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取活动状态
|
||||||
|
* @since Alpha
|
||||||
|
* @param {number} status 活动状态码
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function getActivityStatus(status: number): { status: ActivityStatus; color: string } {
|
||||||
|
switch (status) {
|
||||||
|
case 1:
|
||||||
|
return {
|
||||||
|
status: ActivityStatus.STARTED,
|
||||||
|
color: "#3c99aa",
|
||||||
|
};
|
||||||
|
case 2:
|
||||||
|
return {
|
||||||
|
status: ActivityStatus.FINISHED,
|
||||||
|
color: "#c7674b",
|
||||||
|
};
|
||||||
|
case 3:
|
||||||
|
return {
|
||||||
|
status: ActivityStatus.SELECTION,
|
||||||
|
color: "#849cc7",
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
status: ActivityStatus.FINISHED,
|
||||||
|
color: "#c7674b",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取渲染用公告数据
|
||||||
|
* @since Alpha
|
||||||
|
* @param {NewsData} noticeData 公告数据
|
||||||
|
* @return {NewsCard[]}
|
||||||
|
*/
|
||||||
|
export function getNoticeCard(noticeData: NewsData): NewsCard[] {
|
||||||
|
const noticeCard: NewsCard[] = [];
|
||||||
|
noticeData.list.map((item: NewsItem) => {
|
||||||
|
noticeCard.push({
|
||||||
|
title: item.post.subject,
|
||||||
|
cover: item.cover.url || item.post.cover || item.post.images[0],
|
||||||
|
post_id: Number(item.post.post_id),
|
||||||
|
subtitle: item.post.post_id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return noticeCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取渲染用活动数据
|
||||||
|
* @since Alpha
|
||||||
|
* @param {NewsData} activityData 活动数据
|
||||||
|
* @return {NewsCard[]}
|
||||||
|
*/
|
||||||
|
export function getActivityCard(activityData: NewsData): NewsCard[] {
|
||||||
|
const activityCard: NewsCard[] = [];
|
||||||
|
activityData.list.map((item: NewsItem) => {
|
||||||
|
const start_time = new Date(Number(item.news_meta.start_at_sec) * 1000).toLocaleDateString();
|
||||||
|
const end_time = new Date(Number(item.news_meta.end_at_sec) * 1000).toLocaleDateString();
|
||||||
|
const status_info = getActivityStatus(item.news_meta.activity_status);
|
||||||
|
activityCard.push({
|
||||||
|
title: item.post.subject,
|
||||||
|
cover: item.cover.url || item.post.cover || item.post.images[0],
|
||||||
|
post_id: Number(item.post.post_id),
|
||||||
|
subtitle: `${start_time} - ${end_time}`,
|
||||||
|
status: status_info.status,
|
||||||
|
status_color: status_info.color,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return activityCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取渲染用新闻数据
|
||||||
|
* @since Alpha
|
||||||
|
* @param {NewsData} newsData 新闻数据
|
||||||
|
* @return {NewsCard[]}
|
||||||
|
*/
|
||||||
|
export function getNewsCard(newsData: NewsData): NewsCard[] {
|
||||||
|
const newsCard: NewsCard[] = [];
|
||||||
|
newsData.list.map((item: NewsItem) => {
|
||||||
|
newsCard.push({
|
||||||
|
title: item.post.subject,
|
||||||
|
cover: item.cover.url || item.post.cover || item.post.images[0],
|
||||||
|
post_id: Number(item.post.post_id),
|
||||||
|
subtitle: item.post.post_id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return newsCard;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user