diff --git a/lib/v2/hoyolab/constant.js b/lib/v2/hoyolab/constant.js
index 29187f294..fd3dcabe6 100644
--- a/lib/v2/hoyolab/constant.js
+++ b/lib/v2/hoyolab/constant.js
@@ -7,7 +7,6 @@ const POST_FULL = '/community/post/wapi/getPostFull';
// 公告和资讯接口
const NEW_LIST = '/community/post/wapi/getNewsList';
-const ICON = 'https://img-os-static.hoyolab.com/favicon.ico';
// 源网站链接
const LINK = 'https://www.hoyolab.com';
@@ -16,32 +15,23 @@ const PRIVATE_IMG = '
{
const query = new URLSearchParams({
@@ -23,7 +26,7 @@ const getEventList = async ({ type, gids, size, language }) => {
const replaceImgDomain = (content) => content.replaceAll(PRIVATE_IMG, PUBLIC_IMG);
-const getPostContent = (ctx, list, { type, language }) =>
+const getPostContent = (ctx, list, { language }) =>
Promise.all(
list.map(async (row) => {
const post = row.post;
@@ -46,7 +49,11 @@ const getPostContent = (ctx, list, { type, language }) =>
if (content === language || !content) {
content = post.content;
}
- const description = replaceImgDomain(content);
+ const description = art(join(__dirname, 'templates/post.art'), {
+ hasCover: post.has_cover,
+ coverList: row.cover_list,
+ content: replaceImgDomain(content),
+ });
return {
// 文章标题
title: post.subject,
@@ -56,8 +63,6 @@ const getPostContent = (ctx, list, { type, language }) =>
description,
// 文章发布日期
pubDate: parseDate(post.created_at * 1000),
- // 如果有的话,文章分类
- category: `${GIDS_MAP[post.game_id]}-${TYPE_MAP[type]}`,
author,
};
});
@@ -73,15 +78,17 @@ module.exports = async (ctx) => {
language,
size: parseInt(ctx.query?.limit) || 15,
};
+ const gameInfo = await getI18nGameInfo(gids, language, ctx.cache.tryGet);
+ const typeInfo = await getI18nType(language, ctx.cache.tryGet);
const list = await getEventList(params);
const items = await getPostContent(ctx, list, params);
ctx.state.data = {
- title: `HoYoLAB-${GIDS_MAP[gids]}-${TYPE_MAP[type]}`,
- link: LINK,
+ title: `HoYoLAB-${gameInfo.name}-${typeInfo[type].title}`,
+ link: `${LINK}/circles/${gids}/${OFFICIAL_PAGE_TYPE[gids]}/official?page_type=${OFFICIAL_PAGE_TYPE[gids]}&page_sort=${typeInfo[type].sort}`,
item: items,
- image: ICON,
- icon: ICON,
- logo: ICON,
+ image: gameInfo.icon,
+ icon: gameInfo.icon,
+ logo: gameInfo.icon,
};
} catch (error) {
logger.error(error);
diff --git a/lib/v2/hoyolab/radar.js b/lib/v2/hoyolab/radar.js
index 95cb1aa60..d87e3bd48 100644
--- a/lib/v2/hoyolab/radar.js
+++ b/lib/v2/hoyolab/radar.js
@@ -4,7 +4,7 @@ module.exports = {
'.': [
{
title: '活动公告资讯',
- docs: 'https://docs.rsshub.app/routes/game#hoyolab-news',
+ docs: 'https://docs.rsshub.app/routes/game#hoyolab',
source: ['/', '/circles/:gid/:unknow/official'],
target: (params, url) => {
const typeMap = {
diff --git a/lib/v2/hoyolab/templates/post.art b/lib/v2/hoyolab/templates/post.art
new file mode 100644
index 000000000..8744cb1e6
--- /dev/null
+++ b/lib/v2/hoyolab/templates/post.art
@@ -0,0 +1,7 @@
+{{ if hasCover }}
+ {{ each coverList c }}
+ 
+ {{ /each }}
+{{ /if }}
+
+{{@ content }}
diff --git a/lib/v2/hoyolab/utils.js b/lib/v2/hoyolab/utils.js
new file mode 100644
index 000000000..17a005c30
--- /dev/null
+++ b/lib/v2/hoyolab/utils.js
@@ -0,0 +1,32 @@
+const got = require('@/utils/got');
+
+const getGameInfoList = (tryGet) =>
+ tryGet('hoyolab:gameNameList', async () => {
+ const { data } = await got('https://bbs-api-os-static.hoyolab.com/community/apihub/static/api/getAppConfig');
+ return JSON.parse(data.data.config.hoyolab_game_info_list);
+ });
+
+const getI18nGameInfo = async (gid, language, tryGet) => {
+ const gameNameList = await getGameInfoList(tryGet);
+ const game = gameNameList.find((item) => item.game_id === parseInt(gid, 10));
+ return {
+ name: game?.game_name_list.find((item) => item.locale === language)?.raw_name ?? game?.game_name_list.find((item) => item.locale === 'en-us')?.raw_name,
+ icon: game?.game_icon,
+ };
+};
+
+const getI18nType = (language, tryGet) =>
+ tryGet(`hoyolab:type:${language}`, async () => {
+ const { data } = await got(`https://webstatic.hoyoverse.com/admin/mi18n/bbs_oversea/m07281525151831/m07281525151831-${language}.json`);
+
+ return {
+ 1: { title: data.official_notify, sort: 'notices' },
+ 2: { title: data.official_activity, sort: 'events' },
+ 3: { title: data.official_info, sort: 'news' },
+ };
+ });
+
+module.exports = {
+ getI18nGameInfo,
+ getI18nType,
+};
diff --git a/website/docs/routes/game.mdx b/website/docs/routes/game.mdx
index ec9648aac..17192d6ea 100644
--- a/website/docs/routes/game.mdx
+++ b/website/docs/routes/game.mdx
@@ -236,11 +236,9 @@
## HoYoLAB {#hoyolab}
-### 公告 {#hoyolab-gong-gao}
-
-
- 语言 language
+### Official Announcement {#hoyolab-official-announcement}
+
| Language | Code |
| ---------------- | ----- |
| 简体中文 | zh-cn |
@@ -258,17 +256,13 @@
| Tiếng Việt | vi-vn |
| ภาษาไทย | th-th |
- 游戏 gids
+ | Honkai Impact 3rd | Genshin Impact | Tears of Themis | HoYoLAB | Honkai: Star Rail | Zenless Zone Zero |
+ | ----------------- | -------------- | --------------- | ------- | ----------------- | ----------------- |
+ | 1 | 2 | 4 | 5 | 6 | 8 |
- | 崩坏三 | 原神 | 未定事件簿 | HoYoLAB | 崩坏:星穹铁道 | 绝区零 |
- | ------ | ---- | ---------- | ------- | -------------- | ------ |
- | 1 | 2 | 4 | 5 | 6 | 8 |
-
- 公告类型 type
-
- | 公告 | 活动 | 资讯 |
- | ---- | ---- | ---- |
- | 1 | 2 | 3 |
+ | Notices | Events | Info |
+ | ------- | ------ | ---- |
+ | 1 | 2 | 3 |
## Indienova {#indienova}