Skip to content

Commit

Permalink
feat(route): dxy board
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyRL committed Oct 24, 2024
1 parent 9a651fe commit 5be3638
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 10 deletions.
96 changes: 96 additions & 0 deletions lib/routes/dxy/board.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Route } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
import { phoneBaseUrl, webBaseUrl, generateNonce, sign, getPost } from './utils';
import { config } from '@/config';
import { BoardInfo, PostListData } from './types';

export const route: Route = {
path: '/bbs/board/:boardId',
categories: ['bbs'],
example: '/dxy/bbs/board/46',
parameters: { specialId: '板块 ID,可在对应板块页 URL 中找到' },
name: '板块',
maintainers: ['TonyRL'],
radar: [
{
source: ['www.dxy.cn/bbs/newweb/pc/category/:boardIdId'],
target: '/bbs/board/:boardIdId',
},
{
source: ['3g.dxy.cn/bbs/board/:boardIdId'],
target: '/bbs/board/:boardIdId',
},
],
handler,
};

async function handler(ctx) {
const { boardId } = ctx.req.param();
const { limit = '20' } = ctx.req.query();

const boardDetail = (await cache.tryGet(`dxy:board:detail:${boardId}`, async () => {
const detailParams = {
boardId,
timestamp: Date.now(),
noncestr: generateNonce(8, 'number'),
};

const detail = await ofetch(`${phoneBaseUrl}/bbsapi/bbs/board/detail`, {
query: {
...detailParams,
sign: sign(detailParams),
},
});
if (detail.code !== 'success') {
throw new Error(detail.message);
}
return detail.data;
})) as BoardInfo;

const boardList = (await cache.tryGet(
`dxy:board:list:${boardId}`,
async () => {
const listParams = {
boardId,
postType: '0',
orderType: '1',
pageNum: '1',
pageSize: limit,
timestamp: Date.now(),
noncestr: generateNonce(8, 'number'),
};

const recommendList = await ofetch(`${phoneBaseUrl}/bbsapi/bbs/board/post/list`, {
query: {
...listParams,
sign: sign(listParams),
},
});
if (recommendList.code !== 'success') {
throw new Error(recommendList.message);
}
return recommendList.data;
},
config.cache.routeExpire,
false
)) as PostListData;

const list = boardList.result.map((item) => ({
title: item.subject,
author: item.postUser.nickname,
category: [boardDetail.title],
link: `${webBaseUrl}/bbs/newweb/pc/post/${item.postId}`,
postId: item.postId,
}));

const items = await Promise.all(list.map((item) => getPost(item, cache.tryGet)));

return {
title: boardDetail.title,
description: `${boardDetail.postCount} 內容 ${boardDetail.followCount} 关注`,
link: `${webBaseUrl}/bbs/newweb/pc/category/${boardId}`,
image: boardDetail.boardAvatar,
item: items,
};
}
2 changes: 1 addition & 1 deletion lib/routes/dxy/profile/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async function handler(ctx) {
description: postInfo.simpleBody,
pubDate: parseDate(createdTime, 'x'),
author: postInfo.postUser.nickname,
category: postInfo.boardInfo.title,
category: [postInfo.boardInfo.title],
link: `${webBaseUrl}/bbs/newweb/pc/post/${entityId}`,
postId: entityId,
};
Expand Down
2 changes: 1 addition & 1 deletion lib/routes/dxy/special.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async function handler(ctx) {
description: postInfo.simpleBody,
pubDate: parseDate(dataTime, 'x'),
author: postInfo.postUser.nickname,
category: postInfo.postSpecial.specialName,
category: [postInfo.postSpecial.specialName],
link: `${webBaseUrl}/bbs/newweb/pc/post/${entityId}`,
postId: entityId,
};
Expand Down
85 changes: 85 additions & 0 deletions lib/routes/dxy/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
interface BoardPerm {
errCode: number;
}
interface PostPerm {
errCode: number;
}

export interface BoardInfo {
id: number;
boardId: number;
title: string;
shortTitle: string;
postCount: number;
followCount: number;
boardAvatar: string;
boardPerm: BoardPerm;
followStatus: boolean;
}

interface PostUser {
userId: number;
avatar: string;
username: string;
nickname: string;
bbsStatus: number;
userTitle: UserTitle;
}

interface PostDetail {
postId: number;
boardId: number;
reads: number;
pv: number;
subject: string;
postUser: PostUser;
screenUrlList: string[];
videoScreen: boolean;
isEditorRecommend: boolean;
}

export interface PostListData {
pageNum: number;
pageSize: number;
total: number;
result: PostDetail[];
empty: boolean;
}

interface UserTitle {
type: number;
titles: string[];
}

interface TagInfo {
tagName: string;
}

interface Post {
id: number;
createTime: number;
subject: string;
body: string;
reads: number;
pv: number;
ipLocation: string;
isCurrentUser: boolean;
anonymous: boolean;
boardInfo: BoardInfo;
postPerm: PostPerm;
showStatus: boolean;
postUser: PostUser;
hintInfos: false[];
isDisableRepost: boolean;
tagInfos: TagInfo[];
isVoteActivityPost: boolean;
isShowCaseTag: boolean;
isPaidContent: boolean;
isNeedPay: boolean;
}

export interface PostData {
code: string;
message: string;
data: Post;
}
25 changes: 17 additions & 8 deletions lib/routes/dxy/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import CryptoJS from 'crypto-js';
import got from '@/utils/got';
import { load } from 'cheerio';
import ofetch from '@/utils/ofetch';
import * as cheerio from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import { PostData } from './types';

const APP_SIGN_KEY = '4bTogwpz7RzNO2VTFtW7zcfRkAE97ox6ZSgcQi7FgYdqrHqKB7aGqEZ4o7yssa2aEXoV3bQwh12FFgVNlpyYk2Yjm9d2EZGeGu3';
const phoneBaseUrl = 'https://3g.dxy.cn';
Expand Down Expand Up @@ -39,8 +40,8 @@ const getPost = (item, tryGet) =>
noncestr: generateNonce(8, 'number'),
};

const { data: post } = await got('https://www.dxy.cn/bbs/newweb/post/detail', {
searchParams: {
const post = await ofetch<PostData>('https://www.dxy.cn/bbs/newweb/post/detail', {
query: {
...postParams,
sign: sign(postParams),
},
Expand All @@ -49,16 +50,24 @@ const getPost = (item, tryGet) =>
throw new Error(post.message);
}

const $ = load(post.data.body, null, false);
const $ = cheerio.load(post.data.body, null, false);

$('img').each((_, img) => {
img = $(img);
img.removeAttr('data-osrc');
img.removeAttr('data-hsrc');
if (img.data('osrc')) {
img.attr('src', img.data('osrc'));
img.removeAttr('data-osrc');
}
if (img.data('hsrc')) {
img.attr('src', img.data('hsrc'));
img.removeAttr('data-hsrc');
}
});

item.description = $.html();
item.updated = parseDate(post.data.lastEditTime, 'x');
item.pubDate = parseDate(post.data.createTime, 'x');
item.updated = post.data.lastEditTime ? parseDate(post.data.lastEditTime, 'x') : item.pubDate;
item.category = [...new Set([item.category, ...post.data.tagInfos.map((tag) => tag.tagName)])];

return item;
});
Expand Down

0 comments on commit 5be3638

Please sign in to comment.