/** * [MOCK-AD-001] Ad Optimization数据源抽象层 * AI注意: 这是数据源抽象层,业务组件通过此层获取数据 * 仅在REACT_APP_USE_MOCK=true时启用Mock * * @module services/adOptimizationDataSource * @created 2026-03-19 */ // ============================================ // 类型定义 // ============================================ export interface OptimizationSuggestion { id: string; adId: string; adName: string; currentCPC: number; suggestedCPC: number; currentROI: number; expectedROI: number; currentSpend: number; suggestedSpend: number; confidence: number; status: 'pending' | 'applied' | 'rejected'; } export interface AdPerformance { id: string; date: string; clicks: number; conversions: number; spend: number; roi: number; } export interface AdOptimizationQueryParams { adId?: string; startDate?: string; endDate?: string; } export interface AdOptimizationData { suggestions: OptimizationSuggestion[]; performance: AdPerformance[]; } // ============================================ // Ad Optimization专用接口 // ============================================ export interface IAdOptimizationDataSource { optimize(params?: AdOptimizationQueryParams): Promise; fetchSuggestions(): Promise; fetchPerformance(): Promise; applySuggestion(id: string): Promise; rejectSuggestion(id: string): Promise; } // ============================================ // API实现 // ============================================ class ApiAdOptimizationDataSource implements IAdOptimizationDataSource { async optimize(params?: AdOptimizationQueryParams): Promise { const [suggestions, performance] = await Promise.all([ this.fetchSuggestions(), this.fetchPerformance(), ]); return { suggestions, performance }; } async fetchSuggestions(): Promise { const response = await fetch('/api/v1/ad/optimization/suggestions'); const result = await response.json(); return result.data; } async fetchPerformance(): Promise { const response = await fetch('/api/v1/ad/optimization/performance'); const result = await response.json(); return result.data; } async applySuggestion(id: string): Promise { const response = await fetch(`/api/v1/ad/optimization/suggestions/${id}/apply`, { method: 'POST', }); const result = await response.json(); return result.data; } async rejectSuggestion(id: string): Promise { const response = await fetch(`/api/v1/ad/optimization/suggestions/${id}/reject`, { method: 'POST', }); const result = await response.json(); return result.data; } } // ============================================ // Mock实现 // ============================================ /** * [MOCK] Ad Optimization Mock数据源 * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在REACT_APP_USE_MOCK=true时启用 */ class MockAdOptimizationDataSource implements IAdOptimizationDataSource { readonly __MOCK__ = true as const; readonly __MOCK_NAME__ = 'MockAdOptimizationDataSource'; private mockSuggestions: OptimizationSuggestion[] = [ { id: '1', adId: 'AD001', adName: '智能手表推广', currentCPC: 1.5, suggestedCPC: 1.2, currentROI: 3.2, expectedROI: 4.5, currentSpend: 1000, suggestedSpend: 1200, confidence: 0.85, status: 'pending', }, { id: '2', adId: 'AD002', adName: '无线耳机促销', currentCPC: 0.8, suggestedCPC: 1.0, currentROI: 2.8, expectedROI: 3.5, currentSpend: 800, suggestedSpend: 900, confidence: 0.90, status: 'pending', }, { id: '3', adId: 'AD003', adName: '智能音箱新品', currentCPC: 2.0, suggestedCPC: 1.8, currentROI: 2.5, expectedROI: 3.2, currentSpend: 1200, suggestedSpend: 1000, confidence: 0.80, status: 'pending', }, ]; private mockPerformance: AdPerformance[] = [ { id: '1', date: '2026-03-12', clicks: 1200, conversions: 120, spend: 1800, roi: 3.2 }, { id: '2', date: '2026-03-13', clicks: 1300, conversions: 135, spend: 1950, roi: 3.4 }, { id: '3', date: '2026-03-14', clicks: 1100, conversions: 105, spend: 1650, roi: 3.1 }, { id: '4', date: '2026-03-15', clicks: 1400, conversions: 150, spend: 2100, roi: 3.3 }, { id: '5', date: '2026-03-16', clicks: 1500, conversions: 165, spend: 2250, roi: 3.5 }, { id: '6', date: '2026-03-17', clicks: 1600, conversions: 180, spend: 2400, roi: 3.6 }, { id: '7', date: '2026-03-18', clicks: 1700, conversions: 195, spend: 2550, roi: 3.8 }, ]; async optimize(params?: AdOptimizationQueryParams): Promise { await this.simulateDelay(1500); const [suggestions, performance] = await Promise.all([ this.fetchSuggestions(), this.fetchPerformance(), ]); return { suggestions, performance }; } async fetchSuggestions(): Promise { await this.simulateDelay(300); return [...this.mockSuggestions]; } async fetchPerformance(): Promise { await this.simulateDelay(200); return [...this.mockPerformance]; } async applySuggestion(id: string): Promise { await this.simulateDelay(200); const index = this.mockSuggestions.findIndex(s => s.id === id); if (index === -1) throw new Error('Suggestion not found'); this.mockSuggestions[index] = { ...this.mockSuggestions[index], status: 'applied' }; return this.mockSuggestions[index]; } async rejectSuggestion(id: string): Promise { await this.simulateDelay(200); const index = this.mockSuggestions.findIndex(s => s.id === id); if (index === -1) throw new Error('Suggestion not found'); this.mockSuggestions[index] = { ...this.mockSuggestions[index], status: 'rejected' }; return this.mockSuggestions[index]; } private simulateDelay(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } // Mock特定方法 reset(): void { this.mockSuggestions = [ { id: '1', adId: 'AD001', adName: '智能手表推广', currentCPC: 1.5, suggestedCPC: 1.2, currentROI: 3.2, expectedROI: 4.5, currentSpend: 1000, suggestedSpend: 1200, confidence: 0.85, status: 'pending', }, { id: '2', adId: 'AD002', adName: '无线耳机促销', currentCPC: 0.8, suggestedCPC: 1.0, currentROI: 2.8, expectedROI: 3.5, currentSpend: 800, suggestedSpend: 900, confidence: 0.90, status: 'pending', }, { id: '3', adId: 'AD003', adName: '智能音箱新品', currentCPC: 2.0, suggestedCPC: 1.8, currentROI: 2.5, expectedROI: 3.2, currentSpend: 1200, suggestedSpend: 1000, confidence: 0.80, status: 'pending', }, ]; } getMockData(): OptimizationSuggestion[] { return this.mockSuggestions; } } // ============================================ // 导出数据源实例 // ============================================ const useMock = process.env.REACT_APP_USE_MOCK === 'true'; export const adOptimizationDataSource: IAdOptimizationDataSource = useMock ? new MockAdOptimizationDataSource() : new ApiAdOptimizationDataSource(); export const __MOCK__ = useMock; export const __DATA_SOURCE_TYPE__ = useMock ? 'mock' : 'api';