From 81a26f30176b809f0718996452c76dbb14dcae35 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 14 Jul 2025 10:23:08 +0800 Subject: [PATCH] fix(route/mckinsey): update category mapping and improve route handling (#19587) --- lib/routes/mckinsey/cn/category-map.ts | 24 ++--- lib/routes/mckinsey/cn/index.ts | 117 ++++++++++++++++--------- 2 files changed, 86 insertions(+), 55 deletions(-) diff --git a/lib/routes/mckinsey/cn/category-map.ts b/lib/routes/mckinsey/cn/category-map.ts index 06c67d77a9..ee372bfef1 100644 --- a/lib/routes/mckinsey/cn/category-map.ts +++ b/lib/routes/mckinsey/cn/category-map.ts @@ -1,4 +1,4 @@ -const categories = { +export const categories = { // https://www.mckinsey.com.cn/wp-json/wp/v2/categories?parent=25&per_page=100 2: { name: '汽车', @@ -13,7 +13,7 @@ const categories = { slug: 'consumers', }, 5: { - name: '医药', + name: '医药与医疗', slug: 'healthcare-pharmaceuticals', }, 7: { @@ -24,17 +24,13 @@ const categories = { name: '制造业', slug: 'manufacturing', }, - 9: { - name: '私募', - slug: 'private-equity', - }, 10: { name: '技术,媒体与通信', slug: 'technology-media-and-telecom', }, 12: { name: '城市化与可持续发展', - slug: 'urbanization-sustainability-insights', + slug: 'urbanization-sustainability', }, 13: { name: '创新', @@ -56,22 +52,20 @@ const categories = { name: '洞见', slug: 'insights', }, - 37: { - name: '麦肯锡季刊', - slug: 'mckinsey-season-publication', - }, 41: { name: '资本项目和基础设施', slug: 'capital-projects-infrastructure', }, 42: { name: '旅游、运输和物流', - slug: 'transport-logistics', + slug: '交通运输与物流', + }, + 19139: { + name: '出海与国际化、转型', + slug: '出海与国际化、转型', }, 45: { name: '全球基础材料', - slug: 'global-basic-material', + slug: '全球基础材料', }, }; - -export { categories }; diff --git a/lib/routes/mckinsey/cn/index.ts b/lib/routes/mckinsey/cn/index.ts index 5313e073f7..b858818ccf 100644 --- a/lib/routes/mckinsey/cn/index.ts +++ b/lib/routes/mckinsey/cn/index.ts @@ -2,9 +2,10 @@ import { Route, ViewType } from '@/types'; import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; import { categories } from './category-map'; +import { load } from 'cheerio'; +import cache from '@/utils/cache'; const baseUrl = 'https://www.mckinsey.com.cn'; -const endpoint = `${baseUrl}/wp-json`; export const route: Route = { path: '/cn/:category?', @@ -13,9 +14,9 @@ export const route: Route = { example: '/mckinsey/cn', parameters: { category: { - description: '分类', - options: Object.entries(categories).map(([value, label]) => ({ value, label: label.name })), - default: '25', + description: '分类,留空为 `最新洞见`', + options: Object.entries(categories).map(([, label]) => ({ value: label.slug, label: label.name })), + default: '最新洞见', }, }, features: { @@ -29,52 +30,88 @@ export const route: Route = { name: '洞见', maintainers: ['laampui'], handler, - description: `| 分类 | 分类名 | -| ---- | ------------------ | -| 25 | 全部洞见 | -| 2 | 汽车 | -| 3 | 金融服务 | -| 4 | 消费者 | -| 5 | 医药 | -| 7 | 数字化 | -| 8 | 制造业 | -| 9 | 私募 | -| 10 | 技术,媒体与通信 | -| 12 | 城市化与可持续发展 | -| 13 | 创新 | -| 16 | 人才与领导力 | -| 18 | 宏观经济 | -| 19 | 麦肯锡全球研究院 | -| 37 | 麦肯锡季刊 | -| 41 | 资本项目和基础设施 | -| 42 | 旅游、运输和物流 | -| 45 | 全球基础材料 |`, + description: `| 分类 | 分类名 | +| ------------------------------- | ------------------ | +| | 全部洞见 | +| autos | 汽车 | +| banking-insurance | 金融服务 | +| consumers | 消费者 | +| healthcare-pharmaceuticals | 医药与医疗 | +| business-technology | 数字化 | +| manufacturing | 制造业 | +| technology-media-and-telecom | 技术,媒体与通信 | +| urbanization-sustainability | 城市化与可持续发展 | +| innovation | 创新 | +| talent-leadership | 人才与领导力 | +| macroeconomy | 宏观经济 | +| mckinsey-global-institute | 麦肯锡全球研究院 | +| capital-projects-infrastructure | 资本项目和基础设施 | +| 交通运输与物流 | 旅游、运输和物流 | +| 出海与国际化、转型 | 出海与国际化、转型 | +| 全球基础材料 | 全球基础材料 |`, }; async function handler(ctx) { const { category = '25' } = ctx.req.param(); - if (Number.isNaN(category)) { - categories.find((c) => c.slug === category); + + let categorySlug = ''; + if (category === '25') { + /* empty */ + } else if (categories[category]) { + // Category number for backwards compatibility + categorySlug = categories[category].slug; + } else { + // Category slug + const c = Object.values(categories).find((c) => c.slug === category); + categorySlug = c ? c.slug : ''; } + const link = `${baseUrl}/insights/${categorySlug ? `${categorySlug}/` : ''}`; - const posts = await ofetch(`${endpoint}/wp/v2/posts`, { - query: { - per_page: ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 50, - categories: category, - }, + const headers = { + 'accept-language': 'en-US,en;q=0.9', + 'sec-fetch-dest': 'document', + 'sec-fetch-mode': 'navigate', + 'sec-fetch-site': 'none', + }; + + const response = await ofetch(link, { + headers, }); + const $ = load(response); - const items = posts.map((item) => ({ - title: item.title.rendered, - description: item.content.rendered, - link: item.link, - guid: item.guid.rendered, - pubDate: parseDate(item.date_gmt), - })); + const list = $('.fl-post-grid-post') + .toArray() + .map((item) => { + const $item = $(item); + const a = $item.find('h2 a'); + return { + title: a.attr('title'), + description: $item.find('.fl-post-grid-content').html()?.trim(), + link: a.attr('href'), + pubDate: $item.find('[itemprop="datePublished"]').length ? parseDate($item.find('[itemprop="datePublished"]').attr('content')!) : undefined, + }; + }); + + const items = await Promise.all( + list.map((item) => + cache.tryGet(item.link, async () => { + const response = await ofetch(item.link, { + headers, + }); + const $ = load(response); + + item.description = $('.ast-post-format-').html() || item.description; + item.guid = $('link[rel="shortlink"]').attr('href'); + + return item; + }) + ) + ); return { - title: category ? `McKinsey Greater China - ${categories[category].name}` : `McKinsey Greater China`, - link: `${baseUrl}/${category === '25' ? categories[category].slug : `${categories[25].slug}/${categories[category].slug}`}/`, + title: $('head title').text(), + link, + image: $('meta[name="msapplication-TileImage"]').attr('content'), item: items, }; }