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, + }; +};