diff --git a/lib/routes/comic-fuz/magazine.ts b/lib/routes/comic-fuz/magazine.ts
new file mode 100644
index 000000000..0d6c09072
--- /dev/null
+++ b/lib/routes/comic-fuz/magazine.ts
@@ -0,0 +1,97 @@
+import { load } from 'cheerio';
+
+import type { Route } from '@/types';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+
+export const route: Route = {
+ path: '/magazine/:id',
+ categories: ['anime'],
+ example: '/comic-fuz/magazine/27860',
+ parameters: { id: 'ComicFuz中对应的杂志id' },
+ features: {
+ requireConfig: false,
+ requirePuppeteer: false,
+ antiCrawler: false,
+ supportBT: false,
+ supportPodcast: false,
+ supportScihub: false,
+ },
+ radar: [
+ {
+ source: ['comic-fuz.com/magazine/:id'],
+ target: '/magazine/:id',
+ },
+ ],
+ name: '杂志详情',
+ maintainers: ['xiaobailoves'],
+
+ handler: async (ctx) => {
+ const { id } = ctx.req.param();
+ const baseUrl = 'https://comic-fuz.com';
+ const openUrl = `${baseUrl}/magazine/${id}`;
+ const imgUrl = `https://img.comic-fuz.com`;
+
+ const response = await ofetch(openUrl, {
+ headers: {
+ Referer: 'https://comic-fuz.com/',
+ 'Accept-Language': 'ja,en-US;q=0.9,en;q=0.8',
+ },
+ });
+
+ const $ = load(response);
+ const nextDataText = $('#__NEXT_DATA__').text();
+
+ if (!nextDataText) {
+ throw new Error('无法解析页面数据,请检查杂志 ID 是否正确或页面结构是否变动');
+ }
+
+ const nextData = JSON.parse(nextDataText);
+ const pageProps = nextData.props?.pageProps;
+
+ if (!pageProps) {
+ throw new Error('无法解析页面 Props 数据');
+ }
+
+ const magazineTitle = pageProps.magazineName || '';
+
+ const magazineDescription = pageProps.pickupMagazineIssue?.longDescription || '';
+
+ const issues = pageProps.magazineIssues || [];
+
+ const items = issues.map((item: any) => {
+ const amount = item.paidPoint || 0;
+ const statusText = amount > 0 ? '付费' : '无料';
+
+ let thumb = item.thumbnailUrl;
+ if (thumb && thumb.startsWith('/')) {
+ thumb = `${imgUrl}${thumb}`;
+ }
+
+ const rawDate = item.updatedDate ? item.updatedDate.replace(/\s*発売/, '').trim() : '';
+
+ return {
+ title: `${magazineTitle} - ${item.magazineIssueName}`,
+ link: `${baseUrl}/magazine/viewer/${item.magazineIssueId}`,
+ description: `
+ ${thumb ? `
` : ''}
+
价格: ${amount} 金币/银币
+发售日期: ${item.updatedDate}
+截止日期: ${item.endDate || '无'}
+ ${item.longDescription ? `${item.longDescription}
` : ''} + `, + pubDate: rawDate ? parseDate(rawDate, 'YYYY/MM/DD') : undefined, + guid: `comicfuz-magazine-id-${item.magazineIssueId}`, + category: [statusText], + }; + }); + + return { + title: `COMIC FUZ - ${magazineTitle}`, + link: openUrl, + description: magazineDescription, + item: items, + language: 'ja', + }; + }, +}; diff --git a/lib/routes/comic-fuz/manga.ts b/lib/routes/comic-fuz/manga.ts new file mode 100644 index 000000000..341e85f95 --- /dev/null +++ b/lib/routes/comic-fuz/manga.ts @@ -0,0 +1,106 @@ +import { load } from 'cheerio'; + +import type { Route } from '@/types'; +import ofetch from '@/utils/ofetch'; +import { parseDate } from '@/utils/parse-date'; + +export const route: Route = { + path: '/manga/:id', + categories: ['anime'], + example: '/comic-fuz/manga/218', + parameters: { id: 'ComicFuz中对应的漫画id' }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['comic-fuz.com/manga/:id'], + target: '/manga/:id', + }, + ], + name: '漫画详情', + maintainers: ['xiaobailoves'], + + handler: async (ctx) => { + const { id } = ctx.req.param(); + const baseUrl = 'https://comic-fuz.com'; + const openUrl = `${baseUrl}/manga/${id}`; + const imgUrl = `https://img.comic-fuz.com`; + + const response = await ofetch(openUrl, { + headers: { + Referer: 'https://comic-fuz.com/', + 'Accept-Language': 'ja,en-US;q=0.9,en;q=0.8', + }, + }); + + const $ = load(response); + const nextDataText = $('#__NEXT_DATA__').text(); + + if (!nextDataText) { + throw new Error('无法解析页面数据,请检查漫画 ID 是否正确或页面结构是否变动'); + } + + const nextData = JSON.parse(nextDataText); + const pageProps = nextData.props?.pageProps; + + if (!pageProps) { + throw new Error('无法解析页面 Props 数据'); + } + + const mangaTitle = $('title').text().trim(); + const mangaAuthor = pageProps.authorships?.map((item: any) => item.author?.authorName).join(', ') || ''; + const mangaDescription = pageProps.manga?.longDescription || ''; + + const chapterGroups = pageProps.chapters || []; + + const allChapters = chapterGroups.flatMap((group: any) => group.chapters || []); + + const items = allChapters.map((chapter: any) => { + const pointInfo = chapter.pointConsumption; + const amount = pointInfo?.amount || 0; + + let statusText = ''; + if (pointInfo && Object.keys(pointInfo).length === 0) { + statusText = '无料'; + } else if (amount > 0) { + statusText = '付费'; + } + + let thumb = chapter.thumbnailUrl; + if (thumb && thumb.startsWith('/')) { + thumb = `${imgUrl}${thumb}`; + } + + const fullTitle = `${chapter.chapterMainName}${chapter.chapterSubName ? ` - ${chapter.chapterSubName}` : ''}`; + + return { + title: fullTitle, + link: `${baseUrl}/manga/viewer/${chapter.chapterId}`, + description: ` + ${thumb ? `价格: ${amount} 金币/铜币
` : ''} + `, + guid: `comicfuz-comic-id-${chapter.chapterId}`, + category: statusText, + author: mangaAuthor, + pubDate: chapter.updatedDate ? parseDate(chapter.updatedDate, 'YYYY/MM/DD') : undefined, + upvotes: chapter.numberOfLikes || 0, + comments: chapter.numberOfComments || 0, + }; + }); + + return { + title: `COMIC FUZ - ${mangaTitle}`, + link: openUrl, + description: mangaDescription, + item: items, + language: 'ja', + }; + }, +}; diff --git a/lib/routes/comic-fuz/namespace.ts b/lib/routes/comic-fuz/namespace.ts new file mode 100644 index 000000000..501252acb --- /dev/null +++ b/lib/routes/comic-fuz/namespace.ts @@ -0,0 +1,7 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: 'COMIC FUZ', + url: 'comic-fuz.com', + lang: 'ja', +}; \ No newline at end of file