feat(route): add 第一财经 (#10346)

* feat(route): add 第一财经

* docs: fix typo
This commit is contained in:
Ethan Shen
2022-07-29 19:20:22 +08:00
committed by GitHub
parent 160ae94037
commit 79e354593a
16 changed files with 452 additions and 37 deletions
+104 -2
View File
@@ -714,9 +714,111 @@ IT・科学 tech_science
## 第一财经
### 直播区
### 最新
<Route author="sanmmm" example="/yicai/brief" path="/yicai/brief" />
<Route author="nczitzk" example="/yicai/latest" path="/yicai/latest" />
### 头条
<Route author="nczitzk" example="/yicai/headline" path="/yicai/headline" />
### VIP 频道
<Route author="nczitzk" example="/yicai/vip/428" path="/yicai/vip/:id?" :paramsDesc="['频道 id,可在对应频道页中找到,默认为一元点金']" />
### 新闻
<Route author="nczitzk" example="/yicai/news" path="/yicai/news/:id?" :paramsDesc="['分类 id,见下表,可在对应分类页中找到,默认为新闻']" />
| Id | 名称 |
| ---------------------- | ------- |
| gushi | A 股 |
| kechuangban | 科创板 |
| hongguan | 大政 |
| jinrong | 金融 |
| quanqiushichang | 海外市场 |
| gongsi | 产经 |
| shijie | 全球 |
| kechuang | 科技 |
| quyu | 区域 |
| comment | 评论 |
| dafengwenhua | 商业人文 |
| books | 阅读周刊 |
| loushi | 地产 |
| automobile | 汽车 |
| china_financial_herald | 对话陆家嘴 |
| fashion | 时尚 |
| ad | 商业资讯 |
| info | 资讯 |
| jzfxb | 价值风向标 |
| shuducaijing | 数读财经 |
| shujujiepan | 数据解盘 |
| shudushenghuo | 数读生活 |
| cbndata | CBNData |
| dtcj | DT 财经 |
| xfsz | 消费数知 |
### 关注
<Route author="nczitzk" example="/yicai/feed/669" path="/yicai/feed/:id?" :paramsDesc="['主题 id,可在对应主题页中找到,默认为一财早报']">
::: tip 提示
全部主题词见 [此处](https://www.yicai.com/feed/alltheme)
:::
</Route>
### 视听
<Route author="nczitzk" example="/yicai/video" path="/yicai/video/:id?" :paramsDesc="['分类 id,见下表,可在对应分类页中找到,默认为视听']" />
| Id | 名称 |
| -------------------- | -------------- |
| youliao | 有料 |
| appshipin | 此刻 |
| yicaisudi | 速递 |
| caishang | 财商 |
| shiji | 史记 |
| jinrigushi | 今日股市 |
| tangulunjin | 谈股论金 |
| gongsiyuhangye | 公司与行业 |
| cjyxx | 财经夜行线 |
| 6thtradingday | 第六交易日 |
| cjfw | 财经风味 |
| chuangshidai | 创时代 |
| weilaiyaoqinghan | 未来邀请函 |
| tounaofengbao | 头脑风暴 |
| zhongguojingyingzhe | 中国经营者 |
| shichanglingjuli | 市场零距离 |
| huanqiucaijing | 环球财经视界 |
| zgjcqyjglsxftl | 中国杰出企业家管理思想访谈录 |
| jiemacaishang | 解码财商 |
| sxpl | 首席评论 |
| zhongguojingjiluntan | 中国经济论坛 |
| opinionleader | 意见领袖 |
| xinjinrong | 解码新金融 |
| diyidichan | 第一地产 |
| zhichedaren | 智车达人 |
| chuangtoufengyun | 创投风云 |
| chunxiangrensheng | 醇享人生 |
| diyishengyin | 第一声音 |
| sanliangboqianjin | 财智双全 |
| weilaiyaoqinghan | 未来邀请函 |
| zjdy | 主角 ▪ 大医 |
| leye | 乐业之城 |
| sanrenxing | 价值三人行 |
| yuandongli | 中国源动力 |
| pioneerzone | 直击引领区 |
### 正在
<Route author="sanmmm nczitzk" example="/yicai/brief" path="/yicai/brief" />
### 一财号
<Route author="nczitzk" example="/yicai/author/100005663" path="/yicai/author/:id?" :paramsDesc="['作者 id,可在对应作者页中找到,默认为第一财经研究院']" />
## 东方网
+1 -1
View File
@@ -1872,7 +1872,7 @@ router.get('/zcool/top', lazyloadRouteHandler('./routes/zcool/top')); // 兼容
router.get('/zcool/user/:uid', lazyloadRouteHandler('./routes/zcool/user'));
// 第一财经
router.get('/yicai/brief', lazyloadRouteHandler('./routes/yicai/brief.js'));
// router.get('/yicai/brief', lazyloadRouteHandler('./routes/yicai/brief.js'));
// 一兜糖
router.get('/yidoutang/index', lazyloadRouteHandler('./routes/yidoutang/index.js'));
-34
View File
@@ -1,34 +0,0 @@
const date = require('@/utils/date');
const got = require('@/utils/got');
module.exports = async (ctx) => {
const baseUrl = 'https://www.yicai.com';
const url = `${baseUrl}/api/ajax/getbrieflist`;
const query = {
pagesize: 30,
type: 0,
page: 0,
};
const response = await got(url, {
query,
});
const resList = response.data;
const item = resList.map((obj) => {
const { datekey, istop, url, newcontent, hm, indexTitle } = obj;
const dateStr = `${datekey.replace(/\./g, '-')} ${hm}`;
return {
title: indexTitle.length === newcontent.length ? indexTitle : `${indexTitle}...`,
description: [istop ? '置顶:' : '', newcontent].filter((str) => !!str).join('<br/>'),
pubDate: date(dateStr, +8),
link: `${baseUrl}${url}`,
};
});
ctx.state.data = {
title: `第一财经 - 直播区`,
description: `第一财经 - 直播区`,
link: `${baseUrl}/brief`,
item,
};
};
+26
View File
@@ -0,0 +1,26 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id ?? '100005663';
const currentUrl = `${rootUrl}/author/${id}.html`;
const apiUrl = `${rootUrl}/api/ajax/getlistbysid?id=${id}&page=1&pagesize=${ctx.query.limit ?? 30}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: `第一财经一财号 - ${$('title').text()}`,
link: currentUrl,
item: items,
};
};
+28
View File
@@ -0,0 +1,28 @@
const got = require('@/utils/got');
const timezone = require('@/utils/timezone');
const { parseDate } = require('@/utils/parse-date');
const { rootUrl } = require('./utils');
module.exports = async (ctx) => {
const currentUrl = `${rootUrl}/brief`;
const apiUrl = `${rootUrl}/api/ajax/getbrieflist?type=0&page=1&pagesize=${ctx.query.limit ?? 50}`;
const response = await got({
method: 'get',
url: apiUrl,
});
const items = response.data.map((item) => ({
title: item.indexTitle,
link: `${rootUrl}${item.url}`,
description: item.newcontent,
pubDate: timezone(parseDate(`${item.datekey} ${item.hm}`, 'YYYY.MM.DD HH:mm'), +8),
}));
ctx.state.data = {
title: '第一财经 - 正在',
link: currentUrl,
item: items,
};
};
+26
View File
@@ -0,0 +1,26 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id ?? '669';
const currentUrl = `${rootUrl}/feed/${id}`;
const apiUrl = `${rootUrl}/api/ajax/getlistbytid?id=${id}&page=0&pagesize=${ctx.query.limit ?? 30}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: `第一财经主题 - ${$('title').text()}`,
link: currentUrl,
item: items,
};
};
+13
View File
@@ -0,0 +1,13 @@
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const apiUrl = `${rootUrl}/api/ajax/getlistbycid?cid=48&type=1&page=1&pagesize=${ctx.query.limit ?? 30}`;
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: '第一财经 - 头条',
link: rootUrl,
item: items,
};
};
+13
View File
@@ -0,0 +1,13 @@
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const apiUrl = `${rootUrl}/api/ajax/getlatest?page=1&pagesize=${ctx.query.limit ?? 30}`;
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: '第一财经 - 最新',
link: rootUrl,
item: items,
};
};
+10
View File
@@ -0,0 +1,10 @@
module.exports = {
'/author/:id?': ['nczitzk'],
'/brief': ['sanmmm', 'nczitzk'],
'/feed/:id?': ['nczitzk'],
'/headline': ['nczitzk'],
'/latest': ['nczitzk'],
'/news/:id?': ['nczitzk'],
'/video/:id?': ['nczitzk'],
'/vip/:id?': ['nczitzk'],
};
+39
View File
@@ -0,0 +1,39 @@
const got = require('@/utils/got');
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id ?? '';
let channel;
if (id) {
const navUrl = `${rootUrl}/api/ajax/getnavs`;
const response = await got({
method: 'get',
url: navUrl,
});
for (const c of response.data.header.news) {
if (c.EnglishName === id || c.ChannelID === id) {
channel = {
id: c.ChannelID,
name: c.ChannelName,
slug: c.EnglishName,
};
break;
}
}
}
const currentUrl = `${rootUrl}/news${id ? `/${channel.slug}` : ''}`;
const apiUrl = `${rootUrl}/api/ajax/${id ? `getlistbycid?cid=${channel.id}` : 'getjuhelist?action=news'}&page=1&pagesize=${ctx.query.limit ?? 30}`;
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: `第一财经 - ${channel?.name ?? '新闻'}`,
link: currentUrl,
item: items,
};
};
+55
View File
@@ -0,0 +1,55 @@
module.exports = {
'yicai.com': {
_name: '第一财经',
'.': [
{
title: '最新',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-zui-xin',
source: ['/'],
target: '/yicai/latest',
},
{
title: '头条',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-tou-tiao',
source: ['/'],
target: '/yicai/headline',
},
{
title: 'VIP 频道',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-vip-pin-dao',
source: ['/vip/product/:id', '/'],
target: '/yicai/vip/:id',
},
{
title: '新闻',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-xin-wen',
source: ['/news/:id', '/news'],
target: '/yicai/news/:id',
},
{
title: '关注',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-guan-zhu',
source: ['/feed/:id', '/feed'],
target: '/yicai/feed/:id',
},
{
title: '视听',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-shi-ting',
source: ['/video/:id', '/video'],
target: '/yicai/video/:id',
},
{
title: '正在',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-zheng-zai',
source: ['/brief'],
target: '/yicai/brief',
},
{
title: '一财号',
docs: 'https://docs.rsshub.app/traditional-media.html#di-yi-cai-jing-yi-cai-hao',
source: ['/author/:id', '/author'],
target: '/yicai/author/:id',
},
],
},
};
+10
View File
@@ -0,0 +1,10 @@
module.exports = function (router) {
router.get('/author/:id?', require('./author'));
router.get('/brief', require('./brief'));
router.get('/feed/:id?', require('./feed'));
router.get('/headline', require('./headline'));
router.get('/latest', require('./latest'));
router.get('/news/:id?', require('./news'));
router.get('/video/:id?', require('./video'));
router.get('/vip/:id?', require('./vip'));
};
+11
View File
@@ -0,0 +1,11 @@
{{ if thumb }}
<img src="{{ thumb }}">
{{ /if }}
{{ if video }}
<video controls>
<source src="{{ video }}" type="video/mp4">
</video>
{{ /if }}
{{ if description }}
<p>{{ description }}</p>
{{ /if }}
+51
View File
@@ -0,0 +1,51 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const timezone = require('@/utils/timezone');
const { parseDate } = require('@/utils/parse-date');
const { art } = require('@/utils/render');
const path = require('path');
const rootUrl = 'https://www.yicai.com';
module.exports = {
rootUrl,
ProcessItems: async (apiUrl, tryGet) => {
const response = await got({
method: 'get',
url: apiUrl,
});
const items = response.data.map((item) => ({
title: item.NewsTitle,
link: /^http/.test(item.url) ? item.url : `${rootUrl}${item.AppID === 0 ? `/vip` : ''}${item.url}`,
author: item.NewsAuthor || item.NewsSource || item.CreaterName,
pubDate: timezone(parseDate(item.CreateDate), +8),
category: [item.ChannelName],
description: art(path.join(__dirname, 'templates/description.art'), {
thumb: item.originPic,
video: item.VideoUrl,
description: item.NewsNotes,
}),
}));
return await Promise.all(
items.map((item) =>
tryGet(item.link, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
});
const content = cheerio.load(detailResponse.data);
content('h1').remove();
content('.u-btn6, .m-smallshare, .topic-hot').remove();
item.description += content('.multiText, #multi-text, .txt').html() ?? '';
return item;
})
)
);
},
};
+39
View File
@@ -0,0 +1,39 @@
const got = require('@/utils/got');
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id ?? '';
let channel;
if (id) {
const navUrl = `${rootUrl}/api/ajax/getnavs`;
const response = await got({
method: 'get',
url: navUrl,
});
for (const c of response.data.header.video) {
if (c.EnglishName === id || c.ChannelID === id) {
channel = {
id: c.ChannelID,
name: c.ChannelName,
slug: c.EnglishName,
};
break;
}
}
}
const currentUrl = `${rootUrl}/video${id ? `/${channel.slug}` : ''}`;
const apiUrl = `${rootUrl}/api/ajax/${id ? `getlistbycid?cid=${channel.id}` : 'getjuhelist?action=video'}&page=1&pagesize=${ctx.query.limit ?? 30}`;
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: `第一财经 - ${channel?.name ?? '视听'}`,
link: currentUrl,
item: items,
};
};
+26
View File
@@ -0,0 +1,26 @@
const got = require('@/utils/got');
const cheerio = require('cheerio');
const { rootUrl, ProcessItems } = require('./utils');
module.exports = async (ctx) => {
const id = ctx.params.id ?? '428';
const currentUrl = `${rootUrl}/vip/product/${id}`;
const apiUrl = `${rootUrl}/api/ajax/getlistbypid?id=${id}&type=3&page=1&pagesize=${ctx.query.limit ?? 30}`;
const response = await got({
method: 'get',
url: currentUrl,
});
const $ = cheerio.load(response.data);
const items = await ProcessItems(apiUrl, ctx.cache.tryGet);
ctx.state.data = {
title: `第一财经VIP频道 - ${$('title').text()}`,
link: currentUrl,
item: items,
};
};