diff --git a/lib/v2/bilibili/maintainer.js b/lib/v2/bilibili/maintainer.js
index 8fa28bc0d8a13d..4100e9d807e359 100644
--- a/lib/v2/bilibili/maintainer.js
+++ b/lib/v2/bilibili/maintainer.js
@@ -30,7 +30,7 @@ module.exports = {
'/user/channel/:uid/:sid/:disableEmbed?': ['weirongxu'],
'/user/coin/:uid/:disableEmbed?': ['DIYgod'],
'/user/collection/:uid/:sid/:disableEmbed?': ['shininome'],
- '/user/dynamic/:uid/:routeParams?': ['DIYgod', 'zytomorrow', 'JimenezLi'],
+ '/user/dynamic/:uid/:routeParams?': ['DIYgod', 'zytomorrow', 'CaoMeiYouRen', 'JimenezLi'],
'/user/fav/:uid/:disableEmbed?': ['DIYgod'],
'/user/followers/:uid/:loginUid': ['Qixingchen'],
'/user/followings/:uid/:loginUid': ['Qixingchen'],
diff --git a/lib/v2/mihoyo/bbs/img-ranking.js b/lib/v2/mihoyo/bbs/img-ranking.js
new file mode 100644
index 00000000000000..92d11c8477f166
--- /dev/null
+++ b/lib/v2/mihoyo/bbs/img-ranking.js
@@ -0,0 +1,106 @@
+const got = require('@/utils/got');
+const { art } = require('@/utils/render');
+const path = require('path');
+const { parseDate } = require('@/utils/parse-date');
+const { DATA_MAP, RANKING_TYPE_MAP } = require('./static-data');
+
+const renderDescription = (description, images) => art(path.join(__dirname, '../templates/description.art'), { description, images });
+
+const getGameInfo = (game) => ({
+ gids: DATA_MAP[game]?.gids,
+ title: DATA_MAP[game]?.title,
+});
+const getForumInfo = (game, forum_type) => {
+ forum_type = forum_type || DATA_MAP[game]?.default_forum || 'tongren';
+ const forum = DATA_MAP[game]?.forums?.[forum_type];
+ return {
+ forum_id: forum?.forum_id,
+ title: `${forum?.title}榜`,
+ };
+};
+const getCateInfo = (game, forum_type, cate_type) => {
+ forum_type = forum_type || DATA_MAP[game]?.default_forum || 'tongren';
+ const forum = DATA_MAP[game]?.forums?.[forum_type];
+ const default_cate = forum?.default_cate;
+ if (!default_cate) {
+ return {
+ title: '',
+ cate_id: '0',
+ };
+ }
+ cate_type = cate_type || default_cate;
+ return {
+ title: `${forum?.cates?.[cate_type]?.title}榜`,
+ cate_id: forum?.cates?.[cate_type]?.cate_id,
+ };
+};
+const getRankingTypeInfo = (game, ranking_type) => {
+ ranking_type = ranking_type || DATA_MAP[game]?.default_ranking_type || 'daily';
+ return {
+ id: RANKING_TYPE_MAP[ranking_type]?.id,
+ title: RANKING_TYPE_MAP[ranking_type]?.title,
+ };
+};
+
+module.exports = async (ctx) => {
+ const { game } = ctx.params;
+ const routeParams = Object.fromEntries(new URLSearchParams(ctx.params.routeParams));
+ const { forumType: forum_type = 'tongren', cateType: cate_type, rankingType: ranking_type, lastId: last_id = '' } = routeParams;
+ const page_size = ctx.query.limit || '20';
+ const { gids, title: game_title } = getGameInfo(game);
+ if (!gids) {
+ throw new Error('未知的游戏!');
+ }
+ const { forum_id, title: forum_title } = getForumInfo(game, forum_type);
+ if (!forum_id) {
+ throw new Error(`${game_title} 的排行榜不存在!`);
+ }
+ const { cate_id, title: cate_title } = getCateInfo(game, forum_type, cate_type);
+ const { id: type, title: type_title } = getRankingTypeInfo(game, ranking_type);
+ const query = new URLSearchParams({
+ gids,
+ forum_id,
+ cate_id,
+ type,
+ page_size,
+ last_id,
+ }).toString();
+ const url = `https://bbs-api.miyoushe.com/post/wapi/getImagePostList?${query}`;
+ const response = await got({
+ method: 'get',
+ url,
+ });
+ const list = response?.data?.data?.list;
+ if (!list) {
+ throw new Error('未获取到数据!');
+ }
+ const title = `米游社-${game_title}-${forum_title}${cate_title ? `-${cate_title}` : ''}-${type_title}`;
+ const items = list.map((e) => {
+ const author = e.user.nickname;
+ const title = e.post.subject;
+ const link = `https://bbs.mihoyo.com/ys/article/${e.post.post_id}`;
+ let describe = e.post.content || '';
+ try {
+ describe = JSON.parse(e.post.content).describe;
+ } catch (error) {
+ if (!(error instanceof SyntaxError)) {
+ throw error;
+ }
+ }
+ const description = renderDescription(describe || '', [e.post.cover, ...e.post.images]);
+ const pubDate = parseDate(e.post.created_at * 1000);
+ return {
+ author,
+ title,
+ link,
+ description,
+ pubDate,
+ };
+ });
+ const data = {
+ title,
+ link: url,
+ item: items,
+ };
+ ctx.state.data = data;
+};
diff --git a/lib/v2/mihoyo/bbs.js b/lib/v2/mihoyo/bbs/official.js
similarity index 100%
rename from lib/v2/mihoyo/bbs.js
rename to lib/v2/mihoyo/bbs/official.js
diff --git a/lib/v2/mihoyo/bbs/static-data.js b/lib/v2/mihoyo/bbs/static-data.js
new file mode 100644
index 00000000000000..2f33f98f07f8c4
--- /dev/null
+++ b/lib/v2/mihoyo/bbs/static-data.js
@@ -0,0 +1,137 @@
+// 排行榜基本数据
+const DATA_MAP = {
+ bh2: {
+ title: '崩坏学园2',
+ gids: 3,
+ default_forum: 'tongren',
+ default_ranking_type: 'weekly',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 40,
+ },
+ },
+ },
+ bh3: {
+ title: '崩坏3',
+ gids: 1,
+ default_forum: 'tongren',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 4,
+ default_cate: 'illustration',
+ cates: {
+ comic: {
+ title: '漫画',
+ cate_id: 3,
+ },
+ illustration: {
+ title: '插画',
+ cate_id: 4,
+ },
+ cos: {
+ title: 'COS',
+ cate_id: 17,
+ },
+ },
+ },
+ },
+ },
+ ys: {
+ title: '原神',
+ gids: 2,
+ default_forum: 'tongren',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 29,
+ default_cate: 'illustration',
+ cates: {
+ manual: {
+ title: '手工',
+ cate_id: 1,
+ },
+ qute: {
+ title: 'Q版',
+ cate_id: 2,
+ },
+ comic: {
+ title: '漫画',
+ cate_id: 3,
+ },
+ illustration: {
+ title: '插画',
+ cate_id: 4,
+ },
+ },
+ },
+ cos: {
+ title: 'COS',
+ forum_id: 49,
+ },
+ },
+ },
+ wd: {
+ title: '未定事件簿',
+ gids: 4,
+ default_forum: 'tongren',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 38,
+ },
+ },
+ },
+ sr: {
+ title: '崩坏:星穹铁道',
+ gids: 6,
+ default_forum: 'tongren',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 56,
+ },
+ },
+ },
+ zzz: {
+ title: '绝区零',
+ gids: 8,
+ },
+ dby: {
+ title: '大别野',
+ gids: 5,
+ default_forum: 'tongren',
+ forums: {
+ tongren: {
+ title: '同人',
+ forum_id: 39,
+ },
+ cos: {
+ title: 'COS',
+ forum_id: 47,
+ },
+ },
+ },
+};
+
+// 排行榜分类
+const RANKING_TYPE_MAP = {
+ daily: {
+ id: 1,
+ title: '日榜',
+ },
+ weekly: {
+ id: 2,
+ title: '周榜',
+ },
+ monthly: {
+ id: 3,
+ title: '月榜',
+ },
+};
+
+module.exports = {
+ DATA_MAP,
+ RANKING_TYPE_MAP,
+};
diff --git a/lib/v2/mihoyo/maintainer.js b/lib/v2/mihoyo/maintainer.js
index 4d7a38452c7896..d7e5821f3c438f 100644
--- a/lib/v2/mihoyo/maintainer.js
+++ b/lib/v2/mihoyo/maintainer.js
@@ -1,4 +1,5 @@
module.exports = {
+ '/bbs/img-ranking/:game/:routeParams?': ['CaoMeiYouRen'],
'/bbs/official/:gids/:type?/:page_size?/:last_id?': ['CaoMeiYouRen'],
'/sr/:location?/:category?': ['shinanory'],
'/ys/:location?/:category?': ['nczitzk'],
diff --git a/lib/v2/mihoyo/radar.js b/lib/v2/mihoyo/radar.js
index eddd24ca3e6ff3..17dd1eac02a377 100644
--- a/lib/v2/mihoyo/radar.js
+++ b/lib/v2/mihoyo/radar.js
@@ -21,9 +21,15 @@ module.exports = {
'mihoyo.com': {
_name: '米哈游',
bbs: [
+ {
+ title: '米游社 - 同人榜',
+ docs: 'https://docs.rsshub.app/routes/game#mi-ha-you',
+ source: '/:game/imgRanking/:forum_id/:ranking_id/:cate_id',
+ target: `/mihoyo/bbs/img-ranking/:game`,
+ },
{
title: '米游社 - 官方公告',
- docs: 'https://docs.rsshub.app/routes/game#mi-ha-you-mi-you-she-guan-fang-gong-gao',
+ docs: 'https://docs.rsshub.app/routes/game#mi-ha-you',
source: ['/:game/home/28', '/:game/home/6', '/:game/home/31', '/:game/home/33', '/:game/home/53', '/:game/home/58'],
target: (params, url) => {
const GITS_MAP = {
diff --git a/lib/v2/mihoyo/router.js b/lib/v2/mihoyo/router.js
index e6933cfbef6d3d..d9cdb704ad3ec5 100644
--- a/lib/v2/mihoyo/router.js
+++ b/lib/v2/mihoyo/router.js
@@ -1,5 +1,6 @@
module.exports = function (router) {
- router.get('/bbs/official/:gids/:type?/:page_size?/:last_id?', require('./bbs'));
+ router.get('/bbs/img-ranking/:game/:routeParams?', require('./bbs/img-ranking'));
+ router.get('/bbs/official/:gids/:type?/:page_size?/:last_id?', require('./bbs/official'));
router.get('/sr/:location?/:category?', require('./sr/news'));
router.get('/ys/:location?/:category?', require('./ys/news'));
};
diff --git a/website/docs/routes/game.md b/website/docs/routes/game.md
index 29afb5ec66c8d3..8b1ef3f3c9fbd1 100644
--- a/website/docs/routes/game.md
+++ b/website/docs/routes/game.md
@@ -747,6 +747,52 @@ Example:`https://www.iyingdi.com/tz/people/55547` ,id 是 `55547`
+### 米游社 - 同人榜 {#mi-ha-you-mi-you-she---tong-ren-bang}
+
+
+
+| 键 | 含义 | 接受的值 | 默认值 |
+| ----------- | ----------------------------------- | ------------------------------------------------------------ | ------------ |
+| forumType | 主榜类型(仅原神、大别野有cos主榜) | tongren/cos | tongren |
+| cateType | 子榜类型(仅崩坏三、原神有子榜) | 崩坏三:illustration/comic/cos;原神:illustration/comic/qute/manual | illustration |
+| rankingType | 排行榜类型(崩坏二没有日榜) | daily/weekly/monthly | daily |
+| lastId | 当前页id(用于分页) | 数字 | 1 |
+
+游戏缩写(目前绝区零还没有同人榜
+
+| 崩坏三 | 原神 | 崩坏二 | 未定事件簿 | 星穹铁道 | 大别野 |
+| ------ | ---- | ------ | ---------- | -------- | ------ |
+| bh3 | ys | bh2 | wd | sr | dby |
+
+主榜类型
+
+| 同人榜 | COS榜 |
+| ------- | ----- |
+| tongren | cos |
+
+子榜类型
+
+崩坏三 子榜
+
+| 插画 | 漫画 | COS |
+| ------------ | ----- | ---- |
+| illustration | comic | cos |
+
+
+原神 子榜
+
+| 插画 | 漫画 | Q版 | 手工 |
+| ------------ | ----- | ---- | ------ |
+| illustration | comic | qute | manual |
+
+排行榜类型
+
+| 日榜 | 周榜 | 月榜 |
+| ----- | ------ | ------- |
+| daily | weekly | monthly |
+
+
+
### 米游社 - 官方公告 {#mi-ha-you-mi-you-she---guan-fang-gong-gao}
diff --git a/website/docs/routes/programming.md b/website/docs/routes/programming.md
index c7a74910a63715..221f0d7571b97d 100644
--- a/website/docs/routes/programming.md
+++ b/website/docs/routes/programming.md
@@ -1125,7 +1125,7 @@ Stay up to date on the latest React news, tutorials, resources, and more. Delive
-### 用户专栏 {#jue-jin-yong-hu-zhuan-lan}
+### 用户文章 {#jue-jin-yong-hu-wen-zhang}
diff --git a/website/docs/routes/social-media.md b/website/docs/routes/social-media.md
index f1665627ddebaa..ea22923f37e956 100644
--- a/website/docs/routes/social-media.md
+++ b/website/docs/routes/social-media.md
@@ -42,7 +42,7 @@ Tiny Tiny RSS 会给所有 iframe 元素添加 `sandbox="allow-scripts"` 属性
### UP 主动态 {#bilibili-up-zhu-dong-tai}
-
+
| 键 | 含义 | 接受的值 | 默认值 |
| -- | ---- | ------- | ------ |