diff --git a/docs/traditional-media.md b/docs/traditional-media.md
index 5a8af46b9a..8b89581e7c 100644
--- a/docs/traditional-media.md
+++ b/docs/traditional-media.md
@@ -714,9 +714,111 @@ IT・科学 tech_science
## 第一财经
-### 直播区
+### 最新
-
'),
- pubDate: date(dateStr, +8),
- link: `${baseUrl}${url}`,
- };
- });
-
- ctx.state.data = {
- title: `第一财经 - 直播区`,
- description: `第一财经 - 直播区`,
- link: `${baseUrl}/brief`,
- item,
- };
-};
diff --git a/lib/v2/yicai/author.js b/lib/v2/yicai/author.js
new file mode 100644
index 0000000000..2f123e4eeb
--- /dev/null
+++ b/lib/v2/yicai/author.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/brief.js b/lib/v2/yicai/brief.js
new file mode 100644
index 0000000000..eeb1b6b1a7
--- /dev/null
+++ b/lib/v2/yicai/brief.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/feed.js b/lib/v2/yicai/feed.js
new file mode 100644
index 0000000000..04bafe8e97
--- /dev/null
+++ b/lib/v2/yicai/feed.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/headline.js b/lib/v2/yicai/headline.js
new file mode 100644
index 0000000000..a04e29937b
--- /dev/null
+++ b/lib/v2/yicai/headline.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/latest.js b/lib/v2/yicai/latest.js
new file mode 100644
index 0000000000..a01d4cb393
--- /dev/null
+++ b/lib/v2/yicai/latest.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/maintainer.js b/lib/v2/yicai/maintainer.js
new file mode 100644
index 0000000000..00afadad51
--- /dev/null
+++ b/lib/v2/yicai/maintainer.js
@@ -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'],
+};
diff --git a/lib/v2/yicai/news.js b/lib/v2/yicai/news.js
new file mode 100644
index 0000000000..1d51554b39
--- /dev/null
+++ b/lib/v2/yicai/news.js
@@ -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,
+ };
+};
diff --git a/lib/v2/yicai/radar.js b/lib/v2/yicai/radar.js
new file mode 100644
index 0000000000..a9341cdc0f
--- /dev/null
+++ b/lib/v2/yicai/radar.js
@@ -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',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/yicai/router.js b/lib/v2/yicai/router.js
new file mode 100644
index 0000000000..eb10737d5a
--- /dev/null
+++ b/lib/v2/yicai/router.js
@@ -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'));
+};
diff --git a/lib/v2/yicai/templates/description.art b/lib/v2/yicai/templates/description.art
new file mode 100644
index 0000000000..790b2de1f6
--- /dev/null
+++ b/lib/v2/yicai/templates/description.art
@@ -0,0 +1,11 @@
+{{ if thumb }}
+
+{{ /if }}
+{{ if video }}
+
+{{ /if }}
+{{ if description }}
+
{{ description }}
+{{ /if }} \ No newline at end of file diff --git a/lib/v2/yicai/utils.js b/lib/v2/yicai/utils.js new file mode 100644 index 0000000000..970e15bbab --- /dev/null +++ b/lib/v2/yicai/utils.js @@ -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; + }) + ) + ); + }, +}; diff --git a/lib/v2/yicai/video.js b/lib/v2/yicai/video.js new file mode 100644 index 0000000000..af738f25c6 --- /dev/null +++ b/lib/v2/yicai/video.js @@ -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, + }; +}; diff --git a/lib/v2/yicai/vip.js b/lib/v2/yicai/vip.js new file mode 100644 index 0000000000..8a49754ada --- /dev/null +++ b/lib/v2/yicai/vip.js @@ -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, + }; +};