Files
ozon-seller-kit/extension-v1/src/collector/scan.ts
T

112 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 采集引擎入口 - 扫描当前页面
* 从 docs/extension/plan.md §6.7 移植(组装各模块)
*
* 淘宝/天猫优先从 SSR JSON 提取(window.__ICE_APP_CONTEXT__),
* 提取失败时降级到 DOM 采集。
*/
import { matchProfile } from '../profiles';
import { waitForAny } from './dom';
import { collectImages, type ImageMaterial } from './image';
import { collectTexts, type TextMaterial } from './text';
import { extractSSRData } from './ssr';
import { buildFromSSR } from './ssr-builder';
export type { ImageMaterial, TextMaterial };
export interface ScanResult {
platform: string;
itemId: string | null;
url: string;
texts: TextMaterial[];
images: ImageMaterial[];
scannedAt: number;
stats: Record<string, number>; // 分组统计
warnings: string[]; // 警告(如详情图为 0
}
export type { ImageMaterial, TextMaterial };
export async function scanCurrentPage(): Promise<ScanResult | null> {
const profile = matchProfile(location.href);
if (!profile) {
console.warn('[Seller Helper] 当前页面不支持采集:', location.href);
return null;
}
console.log('[Seller Helper] 开始采集:', profile.name, location.href);
// ★ 淘宝/天猫优先从 SSR JSON 提取
const ssrData = extractSSRData();
if (ssrData) {
console.log('[Seller Helper] 使用 SSR 数据(JSON');
const result = buildFromSSR(ssrData, profile);
console.log('[Seller Helper] SSR 采集完成:', {
texts: result.texts.length,
images: result.images.length,
stats: result.stats,
warnings: result.warnings
});
return result;
}
// 降级到 DOM 采集
console.log('[Seller Helper] SSR 数据不可用,降级到 DOM 采集');
// 等待页面就绪
const anchor = await waitForAny(profile.readySelectors, profile.readyTimeoutMs ?? 10_000);
if (!anchor) {
console.warn('[Seller Helper] 等待页面就绪超时');
// 不 return,页面可能部分可用,继续尝试
}
// 提取文本
const { materials: texts, missingRequired } = collectTexts(profile);
// 提取图片
const images = collectImages(profile);
// 统计各组数量
const stats: Record<string, number> = {};
for (const img of images) {
stats[img.groupKey] = (stats[img.groupKey] ?? 0) + 1;
}
// 生成警告
const warnings: string[] = [];
if (missingRequired.length > 0) {
warnings.push(`缺少必需字段: ${missingRequired.join(', ')}`);
}
if (images.length === 0) {
warnings.push('未扫描到任何图片/视频');
}
if (stats.detail === 0) {
warnings.push('详情图为 0 张,请滚动到页面底部后重新采集');
}
console.log('[Seller Helper] 采集完成:', {
texts: texts.length,
images: images.length,
stats,
warnings
});
return {
platform: profile.id,
itemId: profile.extractItemId(location.href),
url: location.href,
texts,
images,
scannedAt: Date.now(),
stats,
warnings
};
}
// 暴露到全局供 side panel 调用
if (typeof window !== 'undefined') {
(window as any).__SellerHelper = {
scan: scanCurrentPage
};
}