feat(route): feng (#9858)
This commit is contained in:
parent
cdb3ed67d4
commit
6c14613158
12
docs/bbs.md
12
docs/bbs.md
|
|
@ -696,6 +696,18 @@ pageClass: routes
|
|||
|
||||
<Route author="nczitzk" example="/creaders/headline" path="/creaders/headline"/>
|
||||
|
||||
## 威锋
|
||||
|
||||
### 社区
|
||||
|
||||
<Route author="TonyRL" example="/feng/forum/1" path="/feng/forum/:id/:type?" :paramsDesc="['版块 ID,可在版块 URL 找到', '排序,见下表,默认为 `all`']" radar="1" rssbud="1">
|
||||
|
||||
| 最新回复 | 最新发布 | 热门 | 精华 |
|
||||
| ------ | ---- | --- | ------- |
|
||||
| newest | all | hot | essence |
|
||||
|
||||
</Route>
|
||||
|
||||
## 文学城
|
||||
|
||||
### 博客
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
const { parseDate } = require('@/utils/parse-date');
|
||||
const { baseUrl, getForumMeta, getThreads, getThread } = require('./utils');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const topicId = Number(ctx.params.id);
|
||||
const { type = 'all' } = ctx.params;
|
||||
|
||||
const forumMeta = await getForumMeta(topicId, ctx);
|
||||
const topicMeta = forumMeta.dataList.find((data) => data.topicId === topicId);
|
||||
const threads = (await getThreads(topicId, type, ctx)).data.dataList.map((data) => ({
|
||||
title: data.title,
|
||||
pubDate: parseDate(data.dateline * 1000),
|
||||
author: data.userBaseInfo.userName,
|
||||
link: `${baseUrl}/post/${data.tid}`,
|
||||
tid: data.tid,
|
||||
}));
|
||||
|
||||
const posts = await Promise.all(
|
||||
threads.map(async (item) => {
|
||||
const thread = await getThread(item.tid, topicId, ctx);
|
||||
if (thread.status.code === 0) {
|
||||
const img = art(path.join(__dirname, 'templates/img.art'), {
|
||||
images: thread.data.thread.fengTalkImage.length ? thread.data.thread.fengTalkImage : undefined,
|
||||
});
|
||||
item.description = thread.data.thread.message + img;
|
||||
} else {
|
||||
item.description = art(path.join(__dirname, 'templates/deleted.art'), {});
|
||||
}
|
||||
delete item.tid;
|
||||
return item;
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${topicMeta.topicName} - 社区 - 威锋 - 千万果粉大本营`,
|
||||
description: topicMeta.topicDescription,
|
||||
link: `${baseUrl}/forum/${topicId}`,
|
||||
item: posts,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
'feng.com': {
|
||||
_name: '威锋',
|
||||
'.': [
|
||||
{
|
||||
title: '社区',
|
||||
docs: 'https://docs.rsshub.app/bbs.html#wei-feng',
|
||||
source: ['/forum/photo/:id', '/forum/:id'],
|
||||
target: '/feng/forum/:id',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = (router) => {
|
||||
router.get('/forum/:id/:type?', require('./forum'));
|
||||
};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<img src="https://www.feng.com/_nuxt/img/yishanchu.368ead2.png" alt="威锋">
|
||||
<div align="center">帖子已被删除</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{{ if images }}
|
||||
<br>
|
||||
{{ each images }}
|
||||
<img src="{{ $value.split('?')[0] }}" alt="">
|
||||
{{ /each }}
|
||||
{{ /if }}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
const CryptoJS = require('crypto-js');
|
||||
const got = require('@/utils/got');
|
||||
const config = require('@/config').value;
|
||||
const apiUrl = 'https://api.wfdata.club';
|
||||
const baseUrl = 'https://www.feng.com';
|
||||
const KEY = '2b7e151628aed2a6';
|
||||
|
||||
// https://juejin.cn/post/6844904066468806664
|
||||
const getXRequestId = (apiUrl) => {
|
||||
const path = new URL(apiUrl).pathname; // split search params
|
||||
const plainText = CryptoJS.enc.Utf8.parse('url=' + path + '$time=' + Date.now() + '000000');
|
||||
const iv = CryptoJS.enc.Utf8.parse(KEY);
|
||||
const encrypted = CryptoJS.AES.encrypt(plainText, iv, {
|
||||
iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
}).toString();
|
||||
return encrypted;
|
||||
};
|
||||
|
||||
const getCategory = (topicId, ctx) => {
|
||||
const url = `${apiUrl}/v1/topic/category`;
|
||||
return ctx.cache.tryGet(
|
||||
url,
|
||||
async () => {
|
||||
const response = await got(url, {
|
||||
headers: {
|
||||
Referer: `${baseUrl}/forum/${topicId}`,
|
||||
'X-Request-Id': getXRequestId(url),
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
const getForumMeta = async (topicId, ctx) => {
|
||||
const categoryData = await getCategory(topicId, ctx);
|
||||
return Object.values(categoryData.data.dataList).find((item) => item.dataList.find((i) => i.topicId === topicId));
|
||||
};
|
||||
|
||||
const getThreads = (topicId, type, ctx) => {
|
||||
const url = `${apiUrl}/v1/topic/${topicId}/thread?topicId=${topicId}&type=${type}&pageCount=50&order=${type === 'newest' ? 'replyTime' : 'postTime'}&page=1`;
|
||||
return ctx.cache.tryGet(
|
||||
url,
|
||||
async () => {
|
||||
const response = await got(url, {
|
||||
headers: {
|
||||
Referer: `${baseUrl}/forum/${topicId}`,
|
||||
'X-Request-Id': getXRequestId(url),
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
config.cache.routeExpire,
|
||||
false
|
||||
);
|
||||
};
|
||||
|
||||
const getThread = (tid, topicId, ctx) => {
|
||||
const url = `${apiUrl}/v1/thread/${tid}`;
|
||||
return ctx.cache.tryGet(url, async () => {
|
||||
const response = await got(url, {
|
||||
headers: {
|
||||
Referer: `${baseUrl}/forum/${topicId}`,
|
||||
'X-Request-Id': getXRequestId(url),
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
baseUrl,
|
||||
getForumMeta,
|
||||
getThreads,
|
||||
getThread,
|
||||
};
|
||||
Loading…
Reference in New Issue