feat: 开发采集、采集箱和商品编辑功能
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* 采集引擎入口 - 扫描当前页面
|
||||
* 从 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
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user