diff --git a/docs/other.md b/docs/other.md index 256ee7374..595e1921a 100644 --- a/docs/other.md +++ b/docs/other.md @@ -782,7 +782,9 @@ type 为 all 时,category 参数不支持 cost 和 free ### 专题 + 此为专题广场更新提示=>集合型而非单篇文章.与下方"专题内文章更新"存在明显区别! + ### 专题内文章更新 @@ -960,6 +962,50 @@ type 为 all 时,category 参数不支持 cost 和 free +## 学堂在线 + +### 课程信息 + + + +课程信息类型 + +| 课程开始时间 | 课程结束时间 | 课程进度 | +| ------------ | ------------ | -------- | +| start | end | status | + + + +### 课程列表 + + + +课程模式 + +| 自主 | 随堂 | 付费 | 全部 | +| ---- | ---- | ---- | ---- | +| 0 | 1 | 2 | -1 | + +课程状态 + +| 即将开课 | 已开课 | 已结课 | 全部 | +| -------- | ------ | ------ | ---- | +| 1 | 2 | 3 | -1 | + +课程认证类型 + +| 签字认证 | 认证开放 | 全部 | +| -------- | -------- | ---- | +| 1 | 2 | -1 | + +学科分类 + +| 全部 | 计算机 | 经管·会计 | 创业 | 电子 | 工程 | 环境·地球 | 医学·健康 | 生命科学 | 数学 | 物理 | 化学 | 社科·法律 | 文学 | 历史 | 哲学 | 艺术·设计 | 外语 | 教育 | 其他 | 大学先修课 | 公共管理 | 建筑 | 职场 | 全球胜任力 | +| ---- | ------ | --------- | ---- | ---- | ---- | --------- | --------- | -------- | ---- | ---- | ---- | --------- | ---- | ---- | ---- | --------- | ---- | ---- | ---- | ---------- | -------- | ---- | ---- | ---------- | +| -1 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 201 | 2550 | 2783 | 2952 | 6200 | + + + ## 异次元软件世界 ### 首页 diff --git a/lib/router.js b/lib/router.js index 56470d9d0..42ebc8742 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1538,4 +1538,8 @@ router.get('/afdian/dynamic/:uid', require('./routes/afdian/dynamic')); // 《明日方舟》游戏 router.get('/arknights/news', require('./routes/arknights/news')); +// 学堂在线 +router.get('/xuetangx/course/:cid/:type', require('./routes/xuetangx/course_info')); +router.get('/xuetangx/course/list/:mode/:credential/:status/:type?', require('./routes/xuetangx/course_list')); + module.exports = router; diff --git a/lib/routes/xuetangx/course_info.js b/lib/routes/xuetangx/course_info.js new file mode 100644 index 000000000..108447e5d --- /dev/null +++ b/lib/routes/xuetangx/course_info.js @@ -0,0 +1,51 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const { cid, type } = ctx.params; + const link = `http://www.xuetangx.com/courses/${cid}/about`; + const res = await got(link); + const $ = cheerio.load(res.data); + + const courseTitle = $('#title1').text(); + const infoTag = $('#course_data'); + let title, + description = '', + startTime, + endTime, + status; + switch (type) { + case 'start': + title = '开课时间'; + startTime = infoTag.attr('data-start'); + description = `开课时间: ${startTime ? new Date(startTime).toUTCString() : '暂无'}`; + break; + case 'end': + title = '结课时间'; + endTime = infoTag.attr('data-end'); + description = `结课时间: ${endTime ? new Date(endTime).toUTCString() : '永久开课'}`; + break; + case 'status': + title = '课程进度'; + status = infoTag.attr('data-serialized'); + description = `课程进度: ${Number(status) > -1 ? `连载至第${status}讲` : '暂无'}`; + break; + } + const item = []; + if (title && description) { + item.push({ + title, + description, + link, + guid: description, + }); + } + + ctx.state.data = { + title: `${courseTitle} - ${title}`, + description: `${courseTitle} - ${title}`, + link, + item, + allowEmpty: true, + }; +}; diff --git a/lib/routes/xuetangx/course_list.js b/lib/routes/xuetangx/course_list.js new file mode 100644 index 000000000..ab7935208 --- /dev/null +++ b/lib/routes/xuetangx/course_list.js @@ -0,0 +1,57 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +module.exports = async (ctx) => { + const { type = '', credential, mode, status } = ctx.params; + const baseUrl = 'http://www.xuetangx.com'; + const link = `${baseUrl}/courses`; + const query = { + page_type: type, + course_mode: mode, + process: status, + credential, + }; + Object.keys(query).forEach((key) => Number(query[key]) === -1 && (query[key] = '')); + const res = await got(link, { + query, + }); + const $ = cheerio.load(res.data); + + const item = $('#list_style .list_inner') + .map((_, node) => { + const $item = cheerio.load(node); + const title = $item('.coursetitle').text(); + const link = `${baseUrl}${$item('.coursename > a').attr('href')}`; + const posterImg = baseUrl + $item('.course-cover').attr('src'); + const baseInfo = $item('.coursename_ref') + .text() + .trim() + .replace(/\s+/g, '/'); + const teacherInfo = $item('div.fl.name > ul > li:nth-child(1)').text(); + const extraInfo = $item('div.fl.name > ul > li:nth-child(2)') + .text() + .replace('$', ''); + const description = ` + ${baseInfo}
+ ${teacherInfo}
+ ${extraInfo}
+ ${$item('.txt')}
+ ${$item('.ctxt')}
+
+ `; + return { + title, + link, + description, + }; + }) + .get(); + + ctx.state.data = { + title: `学堂在线-课程列表`, + description: `学堂在线-课程列表`, + link, + item, + allowEmpty: true, + }; +};