mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-02 18:18:06 +08:00
184 lines
6.9 KiB
JavaScript
184 lines
6.9 KiB
JavaScript
const got = require('@/utils/got');
|
||
const showdown = require('showdown');
|
||
const { parseDate } = require('@/utils/parse-date');
|
||
const timezone = require('@/utils/timezone');
|
||
module.exports = async (ctx) => {
|
||
const baseurl = `https://leetcode.cn`;
|
||
const url = `${baseurl}/graphql/`;
|
||
const headers = {
|
||
'content-type': 'application/json',
|
||
};
|
||
const emoji = {
|
||
Medium: '🟡',
|
||
Easy: '🟢',
|
||
Hard: '🔴',
|
||
};
|
||
// 获取每日一题
|
||
const data = (
|
||
await got({
|
||
method: 'post',
|
||
url,
|
||
json: {
|
||
operationName: 'questionOfToday',
|
||
query: `query questionOfToday {
|
||
todayRecord {
|
||
date
|
||
userStatus
|
||
question {
|
||
questionId
|
||
frontendQuestionId: questionFrontendId
|
||
difficulty
|
||
title
|
||
titleCn: translatedTitle
|
||
titleSlug
|
||
}
|
||
}
|
||
}`,
|
||
variables: {},
|
||
},
|
||
headers,
|
||
})
|
||
).data.data;
|
||
const questionTitle = data.todayRecord[0].question.titleSlug;
|
||
const questionUrl = `${baseurl}/problems/${questionTitle}/`;
|
||
|
||
// 获取题目内容
|
||
const question = (
|
||
await got({
|
||
method: 'post',
|
||
url,
|
||
json: {
|
||
operationName: 'questionData',
|
||
query: `query questionData($titleSlug: String!) {
|
||
question(titleSlug: $titleSlug) {
|
||
questionId
|
||
questionFrontendId
|
||
categoryTitle
|
||
boundTopicId
|
||
title
|
||
titleSlug
|
||
content
|
||
translatedTitle
|
||
translatedContent
|
||
isPaidOnly
|
||
difficulty
|
||
likes
|
||
}
|
||
}`,
|
||
variables: {
|
||
titleSlug: questionTitle,
|
||
},
|
||
},
|
||
headers,
|
||
})
|
||
).data.data.question;
|
||
const diffEmoji = emoji[question.difficulty] || '';
|
||
// 获取题解(点赞前3)
|
||
const articles = (
|
||
await got({
|
||
method: 'post',
|
||
url,
|
||
json: {
|
||
operationName: 'questionSolutionArticles',
|
||
query: `query questionSolutionArticles($questionSlug: String!, $skip: Int, $first: Int, $orderBy: SolutionArticleOrderBy, $userInput: String, $tagSlugs: [String!]) {
|
||
questionSolutionArticles(questionSlug: $questionSlug, skip: $skip, first: $first, orderBy: $orderBy, userInput: $userInput, tagSlugs: $tagSlugs) {
|
||
totalNum
|
||
edges {
|
||
node {
|
||
...solutionArticle
|
||
__typename
|
||
}
|
||
__typename
|
||
}
|
||
__typename
|
||
}
|
||
}
|
||
fragment solutionArticle on SolutionArticleNode {
|
||
uuid
|
||
title
|
||
slug
|
||
createdAt
|
||
thumbnail
|
||
author {
|
||
username
|
||
}
|
||
summary
|
||
}`,
|
||
variables: {
|
||
questionSlug: questionTitle,
|
||
first: 3,
|
||
skip: 0,
|
||
orderBy: 'MOST_UPVOTE',
|
||
},
|
||
},
|
||
headers,
|
||
})
|
||
).data.data.questionSolutionArticles.edges;
|
||
// 获取题解内容
|
||
const articleContent = (
|
||
await Promise.all(
|
||
articles.map((art) =>
|
||
got({
|
||
method: 'post',
|
||
url,
|
||
json: {
|
||
operationName: 'solutionDetailArticle',
|
||
query: `query solutionDetailArticle($slug: String!, $orderBy: SolutionArticleOrderBy!) {
|
||
solutionArticle(slug: $slug, orderBy: $orderBy) {
|
||
...solutionArticle
|
||
content
|
||
question {
|
||
questionTitleSlug
|
||
__typename
|
||
}
|
||
}
|
||
}
|
||
fragment solutionArticle on SolutionArticleNode {
|
||
uuid
|
||
title
|
||
slug
|
||
createdAt
|
||
thumbnail
|
||
author {
|
||
username
|
||
}
|
||
summary
|
||
}`,
|
||
variables: {
|
||
slug: art.node.slug,
|
||
orderBy: 'DEFAULT',
|
||
},
|
||
},
|
||
headers,
|
||
})
|
||
)
|
||
)
|
||
).map((v) => v.data.data.solutionArticle);
|
||
const converter = new showdown.Converter();
|
||
const handleText = (s) => {
|
||
// 处理多语言代码展示问题
|
||
s = s.replace(/(```)([a-zA-Z0-9-+#]+)\s*?(\[.*?\])?\n/g, '\r\n###$2\r\n$1$2\r\n');
|
||
return s;
|
||
};
|
||
ctx.state.data = {
|
||
title: 'LeetCode 每日一题题解',
|
||
description: 'LeetCode 每日一题题解',
|
||
link: questionUrl,
|
||
item: [
|
||
{
|
||
title: `每日一题-${question.translatedTitle}${diffEmoji}`,
|
||
link: questionUrl,
|
||
description: question.translatedContent,
|
||
pubDate: timezone(parseDate(data.todayRecord[0].date), +8),
|
||
},
|
||
...articleContent.map((art, i) => ({
|
||
title: art.title,
|
||
link: `${questionUrl}/solution/${art.slug}`,
|
||
description: converter.makeHtml(handleText(art.content)),
|
||
pubDate: timezone(parseDate(articles[i].node.createdAt), +8),
|
||
author: art.author.username,
|
||
})),
|
||
],
|
||
};
|
||
};
|