feat: monorepo 重构 + 新增 5 个平台适配器
项目从单体结构重构为 pnpm monorepo (shared/backend/frontend), 新增 YouTube、Instagram、Twitter/X、哔哩哔哩、微博 5 个平台适配器, 包含完整的单元测试和 E2E 测试覆盖。 - 完成 T-031~T-044: 5 个适配器实现、注册、配置和测试 - 重构前后端分离: Hono 后端 + Next.js 前端 - 151 个单元测试 + 21 个 Mock E2E + 25 个真实 E2E - 适配器基于真实 TikHub API 响应结构实现 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import type { ContentItem } from "@muse/shared";
|
||||
import { API_BASE_URL } from "@/lib/api";
|
||||
|
||||
async function fetchDetail(
|
||||
platform: string,
|
||||
id: string
|
||||
): Promise<ContentItem> {
|
||||
const res = await fetch(
|
||||
`${API_BASE_URL}/api/tikhub/${platform}/detail?id=${encodeURIComponent(id)}`
|
||||
);
|
||||
if (!res.ok) {
|
||||
const data = await res.json().catch(() => ({}));
|
||||
throw new Error(data.error || `请求失败: ${res.status}`);
|
||||
}
|
||||
const data = await res.json();
|
||||
return data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an item from TanStack Query's trending list cache.
|
||||
* Checks both platform-specific and "all" caches.
|
||||
*/
|
||||
function findCachedItem(
|
||||
queryClient: ReturnType<typeof useQueryClient>,
|
||||
platform: string,
|
||||
id: string
|
||||
): ContentItem | undefined {
|
||||
const keys = [["content", platform], ["content", "all"]];
|
||||
for (const key of keys) {
|
||||
const items = queryClient.getQueryData<ContentItem[]>(key);
|
||||
if (items) {
|
||||
const found = items.find(
|
||||
(item) => item.id === id && item.platform === platform
|
||||
);
|
||||
if (found) return found;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function useDetailQuery(platform: string, id: string) {
|
||||
const queryClient = useQueryClient();
|
||||
const cached = findCachedItem(queryClient, platform, id);
|
||||
|
||||
return useQuery<ContentItem>({
|
||||
queryKey: ["detail", platform, id],
|
||||
queryFn: () => fetchDetail(platform, id),
|
||||
// Skip API call if item already in trending cache
|
||||
enabled: !!platform && !!id && !cached,
|
||||
initialData: cached,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
retry: 1,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user