diff --git a/lib/router.js b/lib/router.js
index deba3abdc..a4dcd40cf 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -368,6 +368,7 @@ router.get('/mihoyo/bh2/:type', lazyloadRouteHandler('./routes/mihoyo/bh2'));
router.get('/cctv/xwlb', lazyloadRouteHandler('./routes/cctv/xwlb'));
// 央视新闻
+router.get('/cctv/lm/:id?', require('./routes/cctv/lm'));
router.get('/cctv/:category', lazyloadRouteHandler('./routes/cctv/category'));
router.get('/cctv/photo/jx', lazyloadRouteHandler('./routes/cctv/jx'));
router.get('/cctv-special/:id?', lazyloadRouteHandler('./routes/cctv/special'));
diff --git a/lib/routes/cctv/lm.js b/lib/routes/cctv/lm.js
new file mode 100644
index 000000000..cb43a0e99
--- /dev/null
+++ b/lib/routes/cctv/lm.js
@@ -0,0 +1,78 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const timezone = require('@/utils/timezone');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id || 'xwzk';
+
+ const rootUrl = 'https://tv.cctv.com';
+ const apiRootUrl = 'https://api.cntv.cn';
+ const vdnRootUrl = 'https://vdn.apps.cntv.cn';
+
+ const currentUrl = `${rootUrl}/lm/${id}/videoset`;
+
+ const titleResponse = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+
+ const $ = cheerio.load(titleResponse.data);
+
+ const topId = titleResponse.data.match(/(TOPC\d{16})/)[1];
+ const apiUrl = `${apiRootUrl}/NewVideo/getVideoListByColumn?id=${topId}&n=20&sort=desc&p=1&mode=0&serviceId=tvcctv`;
+
+ const response = await got({
+ method: 'get',
+ url: apiUrl,
+ });
+
+ const list = response.data.data.list.map((item) => ({
+ url: item.url,
+ guid: item.guid,
+ image: item.image,
+ title: item.title,
+ pubDate: timezone(parseDate(item.time), +8),
+ link: `${vdnRootUrl}/api/getHttpVideoInfo.do?pid=${item.guid}`,
+ description: `${item.brief.replace(/\r\n/g, '
')}
`,
+ }));
+
+ const items = await Promise.all(
+ list.map(
+ async (item) =>
+ await ctx.cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ });
+ const data = detailResponse.data;
+
+ item.description += `
`;
+
+ for (const c of data.video.chapters) {
+ item.description += `
`;
+ }
+
+ for (let i = 2; data.video[`chapters${i}`]; i++) {
+ for (const c of data.video[`chapters${i}`]) {
+ item.description += `
`;
+ }
+ }
+
+ item.link = item.url;
+
+ delete item.url;
+ delete item.image;
+
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: $('title').text(),
+ link: currentUrl,
+ item: items,
+ description: $('meta[name=description]').attr('content'),
+ };
+};