refactor: 重构紫缘社搜索并移除密码参数

* 移除 `zypassword` 参数,简化核心搜索函数接口。
* 紫缘社搜索逻辑重构,改为解析HTML获取数据,不再依赖API。
* 更新紫缘社平台名称为“紫缘社”,并调整其显示颜色。
* 优化紫缘社搜索结果的标题提取,优先使用中文标题。
This commit is contained in:
Jurangren
2025-10-05 18:10:49 +08:00
parent eed68a9a4d
commit 29f4e0c67c
3 changed files with 31 additions and 56 deletions

View File

@@ -14,13 +14,11 @@ function formatStreamEvent(data: object): string {
* @param game 要搜索的游戏名称。
* @param platforms 要使用的平台列表。
* @param writer 用于写入 SSE 事件的 WritableStreamDefaultWriter。
* @param zypassword (可选) 访问某些平台可能需要的密码。
*/
export async function handleSearchRequestStream(
game: string,
platforms: Platform[],
writer: WritableStreamDefaultWriter<Uint8Array>,
zypassword: string = "" // 添加 zypassword 参数
): Promise<void> {
// 记录搜索关键词
console.log(JSON.stringify({
@@ -36,8 +34,7 @@ export async function handleSearchRequestStream(
const searchPromises = platforms.map(async (platform) => {
try {
// 传递 zypassword 给平台搜索函数
const result = await platform.search(game, zypassword);
const result = await platform.search(game);
completed++;
const progress: StreamProgress = { completed, total };

View File

@@ -12,7 +12,6 @@ async function handleSearch(request: Request, env: Env, ctx: ExecutionContext, p
try {
const formData = await request.formData();
const game = formData.get("game") as string;
const zypassword = formData.get("zypassword") as string || ""; // 获取 zypassword
if (!game || typeof game !== 'string') {
@@ -27,7 +26,7 @@ async function handleSearch(request: Request, env: Env, ctx: ExecutionContext, p
// 将异步任务交给 waitUntil 来处理,确保它能完整执行
ctx.waitUntil(
handleSearchRequestStream(game.trim(), platforms, writer, zypassword) // 传递 zypassword
handleSearchRequestStream(game.trim(), platforms, writer)
.catch(err => console.error("Streaming error:", err))
.finally(() => writer.close())
);

View File

@@ -1,69 +1,48 @@
import { fetchClient } from "../../utils/httpClient";
import type { Platform, PlatformSearchResult, SearchResultItem } from "../../types";
const API_URL = "https://galzy.eu.org/api/fs/search";
const BASE_URL = "https://galzy.eu.org";
interface ZiYuanSheItem {
name: string;
parent: string;
}
interface ZiYuanSheResponse {
message: string;
data: {
content: ZiYuanSheItem[];
total: number;
};
}
async function searchZiYuanShe(game: string, zypassword: string = ""): Promise<PlatformSearchResult> {
async function searchZiYuanShe(game: string): Promise<PlatformSearchResult> {
const searchResult: PlatformSearchResult = {
name: "紫缘Gal",
name: "紫缘",
count: 0,
items: [],
};
try {
const payload = {
parent: "/",
keywords: game,
scope: 0,
page: 1,
per_page: 999999, // Corresponds to MAX_RESULTS
password: zypassword, // Pass the zypassword here
};
const response = await fetchClient(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const response = await fetchClient(`${BASE_URL}/search?q=${encodeURIComponent(game)}`);
if (!response.ok) {
throw new Error(`资源平台 SearchAPI 响应异常状态码 ${response.status}`);
}
const data = await response.json() as ZiYuanSheResponse;
const html = await response.text();
const tempContent = html.split('</script><script>self.__next_f.push([1,"')
const scriptContent = tempContent[tempContent.length - 1].split('\\n"])</script></body></html>')[0];
const cleanedScriptContent = scriptContent.substring(scriptContent.indexOf(':') + 1).replace(/\\"/g, '"');
const jsonData = JSON.parse(cleanedScriptContent);
const gameListData = jsonData[3].children[2][3].gameListData.hits;
if (data.message !== "success") {
throw new Error(`${data.message}`);
if (gameListData) {
const items: SearchResultItem[] = gameListData.map((item: any) => ({
name: (() => {
const zhTitle = item.titles.find((title: any) => title.lang === 'zh-Hans');
const jaTitle = item.titles.find((title: any) => title.lang === 'ja');
if (zhTitle) {
return zhTitle.title;
}
if (jaTitle) {
return jaTitle.title;
}
return item.titles[0]?.title || '';
})(),
url: `${BASE_URL}/${item.id}`,
}));
searchResult.items = items;
searchResult.count = items.length;
}
if (data.data.total !== data.data.content.length) {
throw new Error("访问密码错误");
}
const items: SearchResultItem[] = data.data.content.map(item => ({
name: item.name.trim(),
url: BASE_URL + item.parent + "/" + item.name,
}));
searchResult.items = items;
searchResult.count = items.length;
} catch (error) {
if (error instanceof Error) {
searchResult.error = error.message;
@@ -77,8 +56,8 @@ async function searchZiYuanShe(game: string, zypassword: string = ""): Promise<P
}
const ZiYuanShe: Platform = {
name: "紫缘Gal",
color: "white",
name: "紫缘",
color: "lime",
magic: false,
search: searchZiYuanShe,
};