feat: 新增多模块功能与服务实现
新增广告计划、用户资产、B2B交易、合规规则等核心模型 实现爬虫工作器、贸易服务、现金流预测等业务服务 添加RBAC权限测试、压力测试等测试用例 完善扩展程序的消息处理与内容脚本功能 重构应用入口与文档生成器 更新项目规则与业务闭环分析文档
This commit is contained in:
146
extension/src/content/index.ts
Normal file
146
extension/src/content/index.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Logger } from '../utils/Logger';
|
||||
|
||||
const logger = new Logger('ContentScript');
|
||||
|
||||
logger.info('Content script loaded', { url: window.location.href });
|
||||
|
||||
const platform = detectPlatform();
|
||||
|
||||
function detectPlatform(): string {
|
||||
const hostname = window.location.hostname;
|
||||
|
||||
if (hostname.includes('tiktok')) return 'tiktok';
|
||||
if (hostname.includes('temu')) return 'temu';
|
||||
if (hostname.includes('shopee')) return 'shopee';
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
logger.info('Content script received message', { type: message.type, platform });
|
||||
|
||||
switch (message.type) {
|
||||
case 'EXTRACT_PAGE_DATA':
|
||||
const data = extractPageData(message.payload?.selectors);
|
||||
sendResponse({ success: true, data });
|
||||
break;
|
||||
|
||||
case 'GET_PAGE_ORDERS':
|
||||
const orders = extractOrders();
|
||||
sendResponse({ success: true, orders });
|
||||
break;
|
||||
|
||||
case 'GET_PAGE_RETURNS':
|
||||
const returns = extractReturns();
|
||||
sendResponse({ success: true, returns });
|
||||
break;
|
||||
|
||||
case 'CHECK_LOGIN_STATUS':
|
||||
const isLoggedIn = checkLoginStatus();
|
||||
sendResponse({ success: true, isLoggedIn });
|
||||
break;
|
||||
|
||||
default:
|
||||
sendResponse({ success: false, error: 'Unknown message type' });
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
function extractPageData(selectors?: Record<string, string>): Record<string, any> {
|
||||
const data: Record<string, any> = {};
|
||||
|
||||
if (!selectors) {
|
||||
return data;
|
||||
}
|
||||
|
||||
for (const [key, selector] of Object.entries(selectors)) {
|
||||
const element = document.querySelector(selector);
|
||||
if (element) {
|
||||
data[key] = element.textContent?.trim() || '';
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function extractOrders(): any[] {
|
||||
const orders: any[] = [];
|
||||
|
||||
const orderElements = document.querySelectorAll('[data-order-id]');
|
||||
|
||||
for (const el of orderElements) {
|
||||
const orderId = el.getAttribute('data-order-id');
|
||||
const statusEl = el.querySelector('[data-order-status]');
|
||||
const amountEl = el.querySelector('[data-order-amount]');
|
||||
|
||||
if (orderId) {
|
||||
orders.push({
|
||||
orderId,
|
||||
platform,
|
||||
status: statusEl?.textContent?.trim() || 'UNKNOWN',
|
||||
totalAmount: parseFloat(amountEl?.textContent?.replace(/[^0-9.]/g, '') || '0'),
|
||||
currency: getCurrencyForPlatform(platform),
|
||||
extractedAt: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Orders extracted', { count: orders.length, platform });
|
||||
|
||||
return orders;
|
||||
}
|
||||
|
||||
function extractReturns(): any[] {
|
||||
const returns: any[] = [];
|
||||
|
||||
const returnElements = document.querySelectorAll('[data-return-id]');
|
||||
|
||||
for (const el of returnElements) {
|
||||
const returnId = el.getAttribute('data-return-id');
|
||||
const orderId = el.getAttribute('data-order-id');
|
||||
const statusEl = el.querySelector('[data-return-status]');
|
||||
|
||||
if (returnId) {
|
||||
returns.push({
|
||||
returnId,
|
||||
orderId,
|
||||
platform,
|
||||
status: statusEl?.textContent?.trim() || 'UNKNOWN',
|
||||
extractedAt: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
logger.info('Returns extracted', { count: returns.length, platform });
|
||||
|
||||
return returns;
|
||||
}
|
||||
|
||||
function checkLoginStatus(): boolean {
|
||||
const loginIndicators = {
|
||||
tiktok: () => !!document.querySelector('[data-user-avatar]'),
|
||||
temu: () => !!document.querySelector('[data-user-name]'),
|
||||
shopee: () => !!document.querySelector('[data-shop-name]'),
|
||||
};
|
||||
|
||||
const checker = loginIndicators[platform as keyof typeof loginIndicators];
|
||||
|
||||
if (checker) {
|
||||
return checker();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getCurrencyForPlatform(platform: string): string {
|
||||
const currencies: Record<string, string> = {
|
||||
tiktok: 'USD',
|
||||
temu: 'USD',
|
||||
shopee: 'MYR',
|
||||
};
|
||||
|
||||
return currencies[platform] || 'USD';
|
||||
}
|
||||
|
||||
export { extractPageData, extractOrders, extractReturns, checkLoginStatus };
|
||||
Reference in New Issue
Block a user