diff --git a/lib/v2/yicai/dt.js b/lib/v2/yicai/dt.js new file mode 100644 index 00000000000000..e7f84400bfd0a4 --- /dev/null +++ b/lib/v2/yicai/dt.js @@ -0,0 +1,107 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const types = { + article: 2, + report: 3, + visualization: 4, +}; + +module.exports = async (ctx) => { + const { type = 'article', category = '0' } = ctx.params; + const limit = ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30; + + const rootUrl = 'https://dt.yicai.com'; + const apiUrl = new URL('api/getNewsList', rootUrl).href; + const currentUrl = new URL(type, rootUrl).href; + + const { data: response } = await got(apiUrl, { + searchParams: { + page: 1, + rid: types[type], + cid: category, + pageSize: limit, + }, + }); + + let items = response.data.data.slice(0, limit).map((item) => ({ + title: item.newstitle, + link: new URL(item.url, rootUrl).href, + description: art(path.join(__dirname, 'templates/description.art'), { + image: { + src: item.originPic, + alt: item.newstitle, + }, + intro: item.newsnotes, + }), + author: item.creatername, + category: [item.channelrootname, item.channelname, item.NewsTypeName].filter((c) => c), + guid: `yicai-dt-${item.newsid}`, + pubDate: parseDate(item.utc_createdate), + updated: parseDate(item.utc_lastdate), + enclosure_url: item.originVideo, + enclosure_type: item.originVideo ? `video/${item.originVideo.split(/\./).pop()}` : undefined, + upvotes: item.newsscore ?? 0, + })); + + items = await Promise.all( + items.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data: detailResponse } = await got(item.link); + + const content = cheerio.load(detailResponse); + + content('div.logintips').remove(); + + content('img').each((_, e) => { + e = content(e); + + content(e).replaceWith( + art(path.join(__dirname, 'templates/description.art'), { + image: { + src: e.prop('data-original') ?? e.prop('src'), + alt: e.prop('alt'), + width: e.prop('width'), + height: e.prop('height'), + }, + }) + ); + }); + + item.description += art(path.join(__dirname, 'templates/description.art'), { + description: content('div.txt').html(), + }); + item.author = content('div.authortime h3').text(); + item.enclosure_url = ''; + item.enclosure_type = 'video/mp4'; + + return item; + }) + ) + ); + + const { data: currentResponse } = await got(currentUrl); + + const $ = cheerio.load(currentResponse); + + const title = $('title').text(); + const image = $('div.logo a img').prop('src'); + const icon = new URL($('link[rel="shortcut icon"]').prop('href'), rootUrl).href; + + ctx.state.data = { + item: items, + title: `${$(`a[data-cid="${category}"]`).text()}${title}`, + link: currentUrl, + description: $('meta[name="keywords"]').prop('content'), + language: 'zh', + image, + icon, + logo: icon, + subtitle: $('meta[name="description"]').prop('content'), + author: title.split(/_/).pop(), + allowEmpty: true, + }; +}; diff --git a/lib/v2/yicai/maintainer.js b/lib/v2/yicai/maintainer.js index 00afadad51b5ae..49e59b905f2b14 100644 --- a/lib/v2/yicai/maintainer.js +++ b/lib/v2/yicai/maintainer.js @@ -1,6 +1,7 @@ module.exports = { '/author/:id?': ['nczitzk'], '/brief': ['sanmmm', 'nczitzk'], + '/dt/:column?/:category?': ['nczitzk'], '/feed/:id?': ['nczitzk'], '/headline': ['nczitzk'], '/latest': ['nczitzk'], diff --git a/lib/v2/yicai/radar.js b/lib/v2/yicai/radar.js index 1dc2bd77707321..12c434df0e66d6 100644 --- a/lib/v2/yicai/radar.js +++ b/lib/v2/yicai/radar.js @@ -51,5 +51,169 @@ module.exports = { target: '/yicai/author/:id', }, ], + dt: [ + { + title: 'DT 财经 - 可视化 - 全部', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/0', + }, + { + title: 'DT 财经 - 可视化 - 新流行', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/39', + }, + { + title: 'DT 财经 - 可视化 - 新趋势', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/40', + }, + { + title: 'DT 财经 - 可视化 - 商业黑马', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/41', + }, + { + title: 'DT 财经 - 可视化 - 新品', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/42', + }, + { + title: 'DT 财经 - 可视化 - 营销', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/43', + }, + { + title: 'DT 财经 - 可视化 - 大公司', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/44', + }, + { + title: 'DT 财经 - 可视化 - 城市生活', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/visualization'], + target: '/yicai/dt/visualization/45', + }, + { + title: 'DT 财经 - 文章 - 全部', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/0', + }, + { + title: 'DT 财经 - 文章 - 新流行', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/31', + }, + { + title: 'DT 财经 - 文章 - 新趋势', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/32', + }, + { + title: 'DT 财经 - 文章 - 商业黑马', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/33', + }, + { + title: 'DT 财经 - 文章 - 新品', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/34', + }, + { + title: 'DT 财经 - 文章 - 营销', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/35', + }, + { + title: 'DT 财经 - 文章 - 大公司', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/36', + }, + { + title: 'DT 财经 - 文章 - 城市生活', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/article'], + target: '/yicai/dt/article/38', + }, + { + title: 'DT 财经 - 报告 - 全部', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/0', + }, + { + title: 'DT 财经 - 报告 - 人群观念', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/9', + }, + { + title: 'DT 财经 - 报告 - 人群行为', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/22', + }, + { + title: 'DT 财经 - 报告 - 美妆个护', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/23', + }, + { + title: 'DT 财经 - 报告 - 3C数码', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/24', + }, + { + title: 'DT 财经 - 报告 - 营销趋势', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/25', + }, + { + title: 'DT 财经 - 报告 - 服饰鞋包', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/27', + }, + { + title: 'DT 财经 - 报告 - 互联网', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/28', + }, + { + title: 'DT 财经 - 报告 - 城市与居住', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/29', + }, + { + title: 'DT 财经 - 报告 - 消费趋势', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/30', + }, + { + title: 'DT 财经 - 报告 - 生活趋势', + docs: 'https://docs.rsshub.app/routes/traditional-media#di-yi-cai-jing-dt-cai-jing', + source: ['/report'], + target: '/yicai/dt/report/37', + }, + ], }, }; diff --git a/lib/v2/yicai/router.js b/lib/v2/yicai/router.js index eb10737d5a2d7f..3dc1750de68312 100644 --- a/lib/v2/yicai/router.js +++ b/lib/v2/yicai/router.js @@ -1,6 +1,7 @@ module.exports = function (router) { router.get('/author/:id?', require('./author')); router.get('/brief', require('./brief')); + router.get('/dt/:column?/:category?', require('./dt')); router.get('/feed/:id?', require('./feed')); router.get('/headline', require('./headline')); router.get('/latest', require('./latest')); diff --git a/lib/v2/yicai/templates/description.art b/lib/v2/yicai/templates/description.art index 790b2de1f6f6b9..83b5eb0b7f690f 100644 --- a/lib/v2/yicai/templates/description.art +++ b/lib/v2/yicai/templates/description.art @@ -1,11 +1,39 @@ -{{ if thumb }} - +{{ if !video?.src && image?.src }} + {{ /if }} -{{ if video }} - + +{{ if intro }} +
{{ intro }}
{{ /if }} + +{{ if video?.src }} + +{{ /if }} + {{ if description }} -{{ description }}
+ {{@ description }} {{ /if }} \ No newline at end of file diff --git a/lib/v2/yicai/utils.js b/lib/v2/yicai/utils.js index 6414d8cfbd5624..749c9c83454d7f 100644 --- a/lib/v2/yicai/utils.js +++ b/lib/v2/yicai/utils.js @@ -22,9 +22,15 @@ module.exports = { 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, + image: { + src: item.originPic, + alt: item.NewsTitle, + }, + video: { + src: item.VideoUrl, + type: item.VideoUrl?.split(/\./).pop() ?? undefined, + }, + intro: item.NewsNotes, }), })); diff --git a/website/docs/routes/traditional-media.mdx b/website/docs/routes/traditional-media.mdx index 1b685e0b83a6b6..8a5709a28054fc 100644 --- a/website/docs/routes/traditional-media.mdx +++ b/website/docs/routes/traditional-media.mdx @@ -961,6 +961,52 @@ This route adds the missing photo and Link element. (Offical RSS doesn't have Li