Files
makemd/dashboard/src/services/adOptimizationDataSource.ts
wurenzhi 0dac26d781 feat: 添加MSW模拟服务和数据源集成
refactor: 重构页面组件移除冗余Layout组件

feat: 实现WebSocket和事件总线系统

feat: 添加队列和调度系统

docs: 更新架构文档和服务映射

style: 清理重复接口定义使用数据源

chore: 更新依赖项配置

feat: 添加运行时系统和领域引导

ci: 配置ESLint边界检查规则

build: 添加Redis和WebSocket依赖

test: 添加MSW浏览器环境入口

perf: 优化数据获取逻辑使用统一数据源

fix: 修复类型定义和状态管理问题
2026-03-19 01:39:34 +08:00

221 lines
6.7 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.
/**
* [MOCK-AD-001] Ad Optimization数据源抽象层
* AI注意: 这是数据源抽象层,业务组件通过此层获取数据
* 仅在REACT_APP_USE_MOCK=true时启用Mock
*
* @module services/adOptimizationDataSource
* @created 2026-03-19
*/
import { IMockDataSource } from '@/types/datasource';
// ============================================
// 类型定义
// ============================================
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<AdOptimizationData>;
fetchSuggestions(): Promise<OptimizationSuggestion[]>;
fetchPerformance(): Promise<AdPerformance[]>;
applySuggestion(id: string): Promise<OptimizationSuggestion>;
rejectSuggestion(id: string): Promise<OptimizationSuggestion>;
}
// ============================================
// API实现
// ============================================
class ApiAdOptimizationDataSource implements IAdOptimizationDataSource {
async optimize(params?: AdOptimizationQueryParams): Promise<AdOptimizationData> {
const [suggestions, performance] = await Promise.all([
this.fetchSuggestions(),
this.fetchPerformance(),
]);
return { suggestions, performance };
}
async fetchSuggestions(): Promise<OptimizationSuggestion[]> {
const response = await fetch('/api/v1/ad/optimization/suggestions');
const result = await response.json();
return result.data;
}
async fetchPerformance(): Promise<AdPerformance[]> {
const response = await fetch('/api/v1/ad/optimization/performance');
const result = await response.json();
return result.data;
}
async applySuggestion(id: string): Promise<OptimizationSuggestion> {
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<OptimizationSuggestion> {
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, IMockDataSource {
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<AdOptimizationData> {
await this.simulateDelay(1500);
const [suggestions, performance] = await Promise.all([
this.fetchSuggestions(),
this.fetchPerformance(),
]);
return { suggestions, performance };
}
async fetchSuggestions(): Promise<OptimizationSuggestion[]> {
await this.simulateDelay(300);
return [...this.mockSuggestions];
}
async fetchPerformance(): Promise<AdPerformance[]> {
await this.simulateDelay(200);
return [...this.mockPerformance];
}
async applySuggestion(id: string): Promise<OptimizationSuggestion> {
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<OptimizationSuggestion> {
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<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// ============================================
// 导出数据源实例
// ============================================
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';