feat: 新增学堂在线 (#2677)

* feat: 新增学堂在线课程信息

* feat: 学堂在线-课程列表
This commit is contained in:
sanmmmm 2019-07-24 11:51:46 +08:00 committed by DIYgod
parent cb0615ebe3
commit 6696f0de19
4 changed files with 158 additions and 0 deletions

View File

@ -782,7 +782,9 @@ type 为 all 时category 参数不支持 cost 和 free
### 专题
<Route author="SunShinenny" example="/sspai/topics" path="/sspai/topics">
此为专题广场更新提示=>集合型而非单篇文章.与下方"专题内文章更新"存在明显区别!
</Route>
### 专题内文章更新
@ -960,6 +962,50 @@ type 为 all 时category 参数不支持 cost 和 free
<Route author="xapool" example="/sina/csj" path="/sina/csj"/>
## 学堂在线
### 课程信息
<Route author="sanmmm" example="/xuetangx/course/course-v1:TsinghuaX+20240103X+2019_T1/status" path="/xuetangx/course/:cid/:type" :paramsDesc="['课程id, 从课程页URL中可得到', '课程信息类型']">
课程信息类型
| 课程开始时间 | 课程结束时间 | 课程进度 |
| ------------ | ------------ | -------- |
| start | end | status |
</Route>
### 课程列表
<Route author="sanmmm" example="/xuetangx/course/list/0/1/0" path="/xuetangx/course/list/:mode/:status/:credential/:type?" :paramsDesc="['课程模式', '课程状态', '课程认证类型', '学科分类 默认为`全部`']">
课程模式
| 自主 | 随堂 | 付费 | 全部 |
| ---- | ---- | ---- | ---- |
| 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 |
</Route>
## 异次元软件世界
### 首页

View File

@ -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;

View File

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

View File

@ -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}<br/>
${teacherInfo}<br/>
${extraInfo}<br/>
${$item('.txt')}<br/>
${$item('.ctxt')}<br/>
<img src="${posterImg}"/><br/>
`;
return {
title,
link,
description,
};
})
.get();
ctx.state.data = {
title: `学堂在线-课程列表`,
description: `学堂在线-课程列表`,
link,
item,
allowEmpty: true,
};
};