From d799646446f6217d08528584b8dd412351c15fa0 Mon Sep 17 00:00:00 2001 From: Rongrong <15956627+Rongronggg9@users.noreply.github.com> Date: Sat, 27 Nov 2021 15:42:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(route):=20add=20=E5=8D=8E=E5=8D=97?= =?UTF-8?q?=E7=90=86=E5=B7=A5=E5=A4=A7=E5=AD=A6=E6=95=99=E5=8A=A1=E5=A4=84?= =?UTF-8?q?=E5=AD=A6=E9=99=A2=E9=80=9A=E7=9F=A5=20(#8110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/university.md | 10 ++ lib/router.js | 1 + lib/routes/universities/scut/jwc/school.js | 121 +++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 lib/routes/universities/scut/jwc/school.js diff --git a/docs/university.md b/docs/university.md index 4dd2b117af..068faaa428 100644 --- a/docs/university.md +++ b/docs/university.md @@ -996,6 +996,16 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS +### 教务处学院通知 + + + +| 全部 | 选课 | 考试 | 信息 | +| ---- | ------ | ---- | ---- | +| all | course | exam | info | + + + ### 教务处新闻动态 diff --git a/lib/router.js b/lib/router.js index cfbfb5a058..2383030b4d 100644 --- a/lib/router.js +++ b/lib/router.js @@ -849,6 +849,7 @@ router.get('/tju/sse/:type?', lazyloadRouteHandler('./routes/universities/tju/ss // 华南理工大学 router.get('/scut/jwc/notice/:category?', lazyloadRouteHandler('./routes/universities/scut/jwc/notice')); +router.get('/scut/jwc/school/:category?', lazyloadRouteHandler('./routes/universities/scut/jwc/school')); router.get('/scut/jwc/news', lazyloadRouteHandler('./routes/universities/scut/jwc/news')); // 温州商学院 diff --git a/lib/routes/universities/scut/jwc/school.js b/lib/routes/universities/scut/jwc/school.js new file mode 100644 index 0000000000..0075a528b9 --- /dev/null +++ b/lib/routes/universities/scut/jwc/school.js @@ -0,0 +1,121 @@ +const got = require('@/utils/got'); +const url = require('url'); +const querystring = require('querystring'); + +const baseUrl = 'http://jw.scut.edu.cn'; +const refererUrl = baseUrl + '/dist/'; + +const listPageUrl = baseUrl + '/zhinan/cms/toPosts.do?category=1'; +const listApiUrl = baseUrl + '/zhinan/jw/api/v2/findInformNotice.do'; +const articleApiUrl = baseUrl + '/zhinan/jw/api/v2/getArticleInfo.do'; + +const getArticleUrlById = (id) => `${baseUrl}/zhinan/cms/article/view.do?type=posts&id=${id}`; +const getArticleMobileUrlById = (id) => `${baseUrl}/dist/#/detail/index?id=${id}&type=notice`; + +const categoryMap = { + all: { title: '全部', tag: '0' }, + course: { title: '选课', tag: '1' }, + exam: { title: '考试', tag: '2' }, + info: { title: '信息', tag: '6' }, +}; + +const convertTimezoneToCST = (date) => { + const timeZone = 8; + const serverOffset = date.getTimezoneOffset() / 60; + + return new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)); +}; + +const generateArticlePubDate = (createDateStr) => { + const date = new Date(createDateStr); + date.setHours(8); + date.setMinutes(0); + date.setSeconds(0); + date.setMilliseconds(0); + + return convertTimezoneToCST(date); +}; + +const isRedirectPage = (data) => !!data.link; + +const resolveRelativeUrl = (html) => html.replace(/src="\//g, `src="${url.resolve(baseUrl, '.')}`).replace(/href="\//g, `href="${url.resolve(baseUrl, '.')}`); + +const apiSuccessAssert = (data) => { + if (!data.success) { + throw Error('article api error'); + } +}; + +const generateArticleLink = (id) => `

链接:电脑版 | 手机版

`; + +const generateArticleFullText = (data) => resolveRelativeUrl(data.content) + generateArticleLink(data.id); + +module.exports = async (ctx) => { + const categoryName = ctx.params.category || 'all'; + const categoryMeta = categoryMap[categoryName]; + + const qs = querystring.stringify({ + category: 1, + pageNo: 1, + pageSize: 20, + tag: categoryMeta.tag, + }); + + const listApiResponse = await got({ + method: 'post', + url: `${listApiUrl}?${qs}`, + headers: { + Referer: refererUrl, + }, + }); + apiSuccessAssert(listApiResponse.data); + + const articleMetaArray = listApiResponse.data.data.list; + const out = await Promise.all( + articleMetaArray.map(async (articleMeta) => { + const articleUrl = getArticleUrlById(articleMeta.id); + + const cache = await ctx.cache.get(articleUrl); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + + const qs = querystring.stringify({ + id: articleMeta.id, + categoryType: '', + }); + const articleApiResponse = await got({ + method: 'post', + url: `${articleApiUrl}?${qs}`, + headers: { + Referer: refererUrl, + }, + }); + apiSuccessAssert(articleApiResponse.data); + + const articleData = articleApiResponse.data.data; + articleData.id = articleMeta.id; + + let articleFullText = null; + if (!isRedirectPage(articleData)) { + articleFullText = generateArticleFullText(articleData); + } + + const item = { + title: articleData.name, + link: articleUrl, + description: articleFullText, + pubDate: generateArticlePubDate(articleData.createDate).toUTCString(), + }; + + ctx.cache.set(articleUrl, JSON.stringify(item)); + return item; + }) + ); + + ctx.state.data = { + title: '华南理工大学教务处学院通知 - ' + categoryMeta.title, + link: listPageUrl, + item: out, + }; +};