From 65789b18beac0dcfe35eac8ea4f40c28d0c31b0d Mon Sep 17 00:00:00 2001 From: Jurangren Date: Sat, 20 Dec 2025 00:15:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=20Nysoure=20=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E5=B9=B6=E9=87=8D=E6=9E=84=20VikaACG=20=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 更新 Nysoure 平台的 API 和基础 URL 至新域名 nysoure.com。 * 将 VikaACG 从基于正则匹配 HTML 的搜索改为调用官方 JSON API。 * 为 VikaACG 引入了完整的接口类型定义及更健壮的错误处理。 * 优化了 VikaACG 的搜索请求参数,并支持从 API 获取总结果数。 --- src/platforms/gal/Nysoure.ts | 6 +-- src/platforms/gal/VikaACG.ts | 90 ++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/src/platforms/gal/Nysoure.ts b/src/platforms/gal/Nysoure.ts index 6335dee..99e2fee 100644 --- a/src/platforms/gal/Nysoure.ts +++ b/src/platforms/gal/Nysoure.ts @@ -1,13 +1,13 @@ import { fetchClient } from "../../utils/httpClient"; import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types"; -const API_URL = "https://res.nyne.dev/api/resource/search"; -const BASE_URL = "https://res.nyne.dev/resources/"; +const API_URL = "https://nysoure.com/api/resource/search"; +const BASE_URL = "https://nysoure.com/resources/"; interface NysoureItem { id: number; title: string; -} +} interface NysoureResponse { success: boolean; diff --git a/src/platforms/gal/VikaACG.ts b/src/platforms/gal/VikaACG.ts index 50489ec..d9caf39 100644 --- a/src/platforms/gal/VikaACG.ts +++ b/src/platforms/gal/VikaACG.ts @@ -1,8 +1,30 @@ import { fetchClient } from "../../utils/httpClient"; import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types"; -const API_URL = "https://www.vikacg.com/wp-json/b2/v1/getPostList"; -const REGEX = /

(?.*?)<\/a>/gs; +const API_URL = "https://www.vikacg.com/api/vikacg/v1/getPosts"; + +/** + * 响应体最小类型(按你贴的 JSON) + */ +type VikaGetPostsResponse = { + status?: string; + code?: number; + message?: string; + statusMessage?: string; + data?: { + list?: Array<{ + id: number; + title: string; + // 其他字段这里不需要就不展开了 + }>; + count?: number; + paged?: number; + page_count?: number; + pages?: number; + }; +}; + +const POST_URL = (id: number) => `https://www.vikacg.com/p/${id}`; async function searchVikaACG(game: string): Promise { const searchResult: PlatformSearchResult = { @@ -17,26 +39,17 @@ async function searchVikaACG(game: string): Promise { "Content-Type": "application/json", }, body: JSON.stringify({ - paged: 1, - post_paged: 1, - post_count: 1000, // Hardcoded limit, larger values may cause timeouts - post_type: "post-1", - post_cat: [6], - post_order: "modified", - post_meta: [ - "user", - "date", - "des", - "cats", - "like", - "comment", - "views", - "video", - "download", - "hide", - ], - metas: {}, + order: "updated_at", + sort: "desc", + status: null, search: game, + page_count: 50, + paged: 1, + category: null, + tag: null, + rating: null, + is_pinned: false, + user_id: null, }), }); @@ -44,28 +57,25 @@ async function searchVikaACG(game: string): Promise { throw new Error(`资源平台 SearchAPI 响应异常状态码 ${response.status}`); } - // The response is a JSON-encoded string containing HTML. - // .json() will parse the JSON and unescape the string content. - const html: string = await response.text(); - - const decodedHtml = html.replaceAll('\\/', '/').replaceAll('\\\\', '\\').replaceAll('\\"', '"').replace(/\\u([\d\w]{4})/gi, (match, grp) => { - return String.fromCharCode(parseInt(grp, 16)); - }); - const matches = decodedHtml.matchAll(REGEX); + const json: VikaGetPostsResponse = await response.json(); - const items: SearchResultItem[] = []; - for (const match of matches) { - if (match.groups?.NAME && match.groups?.URL) { - items.push({ - name: match.groups.NAME.trim(), - url: match.groups.URL, - }); - } + if (json.status !== "success" || !json.data) { + const msg = json.message || json.statusMessage || "接口返回非 success"; + throw new Error(`资源平台 SearchAPI 返回异常:${msg}`); } - searchResult.items = items; - searchResult.count = items.length; + const list = json.data.list ?? []; + const items: SearchResultItem[] = list + .filter((p) => typeof p?.id === "number" && typeof p?.title === "string") + .map((p) => ({ + name: p.title.trim(), + url: POST_URL(p.id), + })); + searchResult.items = items; + + // ✅ 建议 count 用后端总数(data.count),否则用本页长度兜底 + searchResult.count = typeof json.data.count === "number" ? json.data.count : items.length; } catch (error) { if (error instanceof Error) { searchResult.error = error.message; @@ -86,4 +96,4 @@ const VikaACG: Platform = { search: searchVikaACG, }; -export default VikaACG; \ No newline at end of file +export default VikaACG;