feat: 添加MSW模拟服务和数据源集成
refactor: 重构页面组件移除冗余Layout组件 feat: 实现WebSocket和事件总线系统 feat: 添加队列和调度系统 docs: 更新架构文档和服务映射 style: 清理重复接口定义使用数据源 chore: 更新依赖项配置 feat: 添加运行时系统和领域引导 ci: 配置ESLint边界检查规则 build: 添加Redis和WebSocket依赖 test: 添加MSW浏览器环境入口 perf: 优化数据获取逻辑使用统一数据源 fix: 修复类型定义和状态管理问题
This commit is contained in:
112
dashboard/src/services/marketingDataSource.ts
Normal file
112
dashboard/src/services/marketingDataSource.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* [MOCK-MARKETING] Marketing模块DataSource
|
||||
*/
|
||||
|
||||
export interface Ad {
|
||||
id: string;
|
||||
name: string;
|
||||
platform: string;
|
||||
campaign: string;
|
||||
status: 'active' | 'paused' | 'ended';
|
||||
budget: number;
|
||||
spent: number;
|
||||
clicks: number;
|
||||
impressions: number;
|
||||
conversions: number;
|
||||
ctr: number;
|
||||
cpc: number;
|
||||
roas: number;
|
||||
startDate: string;
|
||||
endDate?: string;
|
||||
}
|
||||
|
||||
export interface Competitor {
|
||||
id: string;
|
||||
name: string;
|
||||
platform: string;
|
||||
products: number;
|
||||
avgPrice: number;
|
||||
avgRating: number;
|
||||
reviewCount: number;
|
||||
lastUpdated: string;
|
||||
trackedProducts: string[];
|
||||
}
|
||||
|
||||
export interface IMarketingDataSource {
|
||||
fetchAds(params?: { platform?: string; status?: string }): Promise<Ad[]>;
|
||||
updateAd(id: string, data: Partial<Ad>): Promise<Ad>;
|
||||
|
||||
fetchCompetitors(): Promise<Competitor[]>;
|
||||
addCompetitor(data: Partial<Competitor>): Promise<Competitor>;
|
||||
removeCompetitor(id: string): Promise<void>;
|
||||
analyzeCompetitor(id: string): Promise<any>;
|
||||
}
|
||||
|
||||
class MockMarketingDataSource implements IMarketingDataSource {
|
||||
async fetchAds(params?: { platform?: string; status?: string }): Promise<Ad[]> {
|
||||
return [
|
||||
{ id: 'ad_001', name: 'Smart Watch Promo', platform: 'AMAZON', campaign: 'Spring Sale', status: 'active', budget: 500, spent: 325.50, clicks: 1250, impressions: 45000, conversions: 45, ctr: 2.78, cpc: 0.26, roas: 3.2, startDate: '2026-03-01' },
|
||||
{ id: 'ad_002', name: 'Headphones Deal', platform: 'AMAZON', campaign: 'Spring Sale', status: 'active', budget: 300, spent: 180.25, clicks: 890, impressions: 32000, conversions: 32, ctr: 2.78, cpc: 0.20, roas: 2.8, startDate: '2026-03-05' },
|
||||
{ id: 'ad_003', name: 'USB Cable Bundle', platform: 'EBAY', campaign: 'Clearance', status: 'paused', budget: 200, spent: 150.00, clicks: 600, impressions: 25000, conversions: 20, ctr: 2.40, cpc: 0.25, roas: 2.1, startDate: '2026-02-15', endDate: '2026-03-15' },
|
||||
];
|
||||
}
|
||||
|
||||
async updateAd(id: string, data: Partial<Ad>): Promise<Ad> {
|
||||
return { id, ...data } as Ad;
|
||||
}
|
||||
|
||||
async fetchCompetitors(): Promise<Competitor[]> {
|
||||
return [
|
||||
{ id: 'comp_001', name: 'TechGadget Pro', platform: 'AMAZON', products: 156, avgPrice: 45.99, avgRating: 4.3, reviewCount: 12500, lastUpdated: '2026-03-18', trackedProducts: ['SKU-001', 'SKU-002'] },
|
||||
{ id: 'comp_002', name: 'ElectroMart', platform: 'AMAZON', products: 89, avgPrice: 38.50, avgRating: 4.1, reviewCount: 8900, lastUpdated: '2026-03-17', trackedProducts: ['SKU-003'] },
|
||||
{ id: 'comp_003', name: 'GadgetWorld', platform: 'EBAY', products: 234, avgPrice: 32.00, avgRating: 4.5, reviewCount: 15600, lastUpdated: '2026-03-16', trackedProducts: [] },
|
||||
];
|
||||
}
|
||||
|
||||
async addCompetitor(data: Partial<Competitor>): Promise<Competitor> {
|
||||
return { ...data, id: `comp_${Date.now()}`, lastUpdated: new Date().toISOString() } as Competitor;
|
||||
}
|
||||
|
||||
async removeCompetitor(id: string): Promise<void> {}
|
||||
|
||||
async analyzeCompetitor(id: string): Promise<any> {
|
||||
return { pricingTrend: 'stable', topProducts: [], marketShare: 15 };
|
||||
}
|
||||
}
|
||||
|
||||
class ApiMarketingDataSource implements IMarketingDataSource {
|
||||
private baseUrl = '/api/marketing';
|
||||
|
||||
async fetchAds(params?: { platform?: string; status?: string }): Promise<Ad[]> {
|
||||
const query = new URLSearchParams(params as any).toString();
|
||||
const res = await fetch(`${this.baseUrl}/ads?${query}`);
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async updateAd(id: string, data: Partial<Ad>): Promise<Ad> {
|
||||
const res = await fetch(`${this.baseUrl}/ads/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async fetchCompetitors(): Promise<Competitor[]> {
|
||||
const res = await fetch(`${this.baseUrl}/competitors`);
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async addCompetitor(data: Partial<Competitor>): Promise<Competitor> {
|
||||
const res = await fetch(`${this.baseUrl}/competitors`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async removeCompetitor(id: string): Promise<void> {
|
||||
await fetch(`${this.baseUrl}/competitors/${id}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
async analyzeCompetitor(id: string): Promise<any> {
|
||||
const res = await fetch(`${this.baseUrl}/competitors/${id}/analyze`);
|
||||
return res.json();
|
||||
}
|
||||
}
|
||||
|
||||
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
|
||||
export const marketingDataSource: IMarketingDataSource = useMock ? new MockMarketingDataSource() : new ApiMarketingDataSource();
|
||||
Reference in New Issue
Block a user