refactor: 优化代码结构并修复类型问题

- 移除未使用的TabPane组件
- 修复类型定义和导入方式
- 优化mock数据源的环境变量判断逻辑
- 更新文档结构并归档旧文件
- 添加新的UI组件和Memo组件
- 调整API路径和响应处理
This commit is contained in:
2026-03-23 12:41:35 +08:00
parent a037843851
commit 2b86715c09
363 changed files with 39305 additions and 40622 deletions

View File

@@ -1,8 +1,6 @@
/**
* [MOCK] A/B测试数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
* [MOCK] A/B测试数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启<E697B6><E590AF>? */
export interface TestVariant {
id: string;
@@ -246,7 +244,7 @@ class ApiABTestDataSource implements IABTestDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const abTestDataSource: IABTestDataSource = useMock
? new MockABTestDataSource()
: new ApiABTestDataSource();

View File

@@ -106,10 +106,8 @@ class ApiAdOptimizationDataSource implements IAdOptimizationDataSource {
// ============================================
/**
* [MOCK] Ad Optimization Mock数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
* [MOCK] Ad Optimization Mock数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启<E697B6><E590AF>? */
class MockAdOptimizationDataSource implements IAdOptimizationDataSource {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockAdOptimizationDataSource';
@@ -256,10 +254,9 @@ class MockAdOptimizationDataSource implements IAdOptimizationDataSource {
}
// ============================================
// 导出数据源实
// ============================================
// 导出数据源实<EFBFBD><EFBFBD>?// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const adOptimizationDataSource: IAdOptimizationDataSource = useMock
? new MockAdOptimizationDataSource()

View File

@@ -187,10 +187,8 @@ class ApiAfterSalesDataSource implements IAfterSalesDataSource {
// ============================================
/**
* [MOCK] AfterSales Mock数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
* [MOCK] AfterSales Mock数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启<E697B6><E590AF>? */
class MockAfterSalesDataSource implements IAfterSalesDataSource {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockAfterSalesDataSource';
@@ -360,10 +358,9 @@ class MockAfterSalesDataSource implements IAfterSalesDataSource {
}
// ============================================
// 导出数据源实
// ============================================
// 导出数据源实<EFBFBD><EFBFBD>?// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const afterSalesDataSource: IAfterSalesDataSource = useMock
? new MockAfterSalesDataSource()

View File

@@ -9,10 +9,6 @@
import { IDataSource } from '@/types/datasource';
// ============================================
// 类型定义
// ============================================
export interface MetricData {
key: string;
label: string;
@@ -128,10 +124,6 @@ export interface AnalyticsData {
dashboards: Dashboard[];
}
// ============================================
// Analytics专用接口
// ============================================
export interface IAnalyticsDataSource {
fetchAllData(params?: AnalyticsQueryParams): Promise<AnalyticsData>;
fetchMetrics(): Promise<MetricData[]>;
@@ -148,10 +140,6 @@ export interface IAnalyticsDataSource {
toggleAlertRule(id: string, enabled: boolean): Promise<void>;
}
// ============================================
// API实现
// ============================================
class ApiAnalyticsDataSource implements IAnalyticsDataSource {
async fetchAllData(params?: AnalyticsQueryParams): Promise<AnalyticsData> {
const [metrics, chartData, productAnalytics, orderAnalytics, profitAnalytics, realtimeMetrics, alertRules, dashboards] = await Promise.all([
@@ -248,15 +236,6 @@ class ApiAnalyticsDataSource implements IAnalyticsDataSource {
}
}
// ============================================
// Mock实现
// ============================================
/**
* [MOCK] Analytics Mock数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
class MockAnalyticsDataSource implements IAnalyticsDataSource {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockAnalyticsDataSource';
@@ -407,29 +386,9 @@ class MockAnalyticsDataSource implements IAnalyticsDataSource {
private simulateDelay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Mock特定方法
reset(): void {
this.mockMetrics = [
{ key: '1', label: '总销售额', value: 1285000, unit: '¥', change: 12.5, changeType: 'up', icon: 'DollarOutlined', color: '#52c41a' },
{ key: '2', label: '订单数量', value: 3256, unit: '单', change: 8.3, changeType: 'up', icon: 'ShoppingCartOutlined', color: '#1890ff' },
{ key: '3', label: '访客数量', value: 45680, unit: '人', change: -2.1, changeType: 'down', icon: 'TeamOutlined', color: '#722ed1' },
{ key: '4', label: '转化率', value: 7.12, unit: '%', change: 0.5, changeType: 'up', icon: 'FundOutlined', color: '#fa8c16' },
{ key: '5', label: '平均客单价', value: 394.5, unit: '¥', change: 3.8, changeType: 'up', icon: 'BarChartOutlined', color: '#13c2c2' },
{ key: '6', label: '净利润', value: 285600, unit: '¥', change: 15.2, changeType: 'up', icon: 'LineChartOutlined', color: '#eb2f96' },
];
}
getMockData(): MetricData[] {
return this.mockMetrics;
}
}
// ============================================
// 导出数据源实例
// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const analyticsDataSource: IAnalyticsDataSource = useMock
? new MockAnalyticsDataSource()

View File

@@ -0,0 +1,57 @@
import http from '../http';
export const dashboardApi = {
getDashboardData: async (params: {
shop: string;
startDate?: string;
endDate?: string;
}) => {
try {
// 实际项目中这里应该调用真实的API
// const response = await http.get('/dashboard/data', { params });
// return response.data;
// 模拟数据
return {
kpiData: [
{
title: '总销售额',
value: '¥128,500',
change: 12.5,
status: 'up',
},
{
title: '订单数',
value: '2,850',
change: 8.2,
status: 'up',
},
{
title: '转化率',
value: '4.8%',
change: -1.2,
status: 'down',
},
{
title: '平均订单价值',
value: '¥45.1',
change: 3.5,
status: 'up',
},
],
trendData: [
{ date: '2024-01-01', sales: 12000, orders: 200 },
{ date: '2024-01-02', sales: 15000, orders: 250 },
{ date: '2024-01-03', sales: 18000, orders: 300 },
{ date: '2024-01-04', sales: 16000, orders: 280 },
{ date: '2024-01-05', sales: 20000, orders: 320 },
{ date: '2024-01-06', sales: 22000, orders: 350 },
{ date: '2024-01-07', sales: 19000, orders: 310 },
],
};
} catch (error) {
console.error('Error fetching dashboard data:', error);
throw error;
}
},
};

View File

@@ -1,3 +1,4 @@
export { userApi } from './user';
export { productApi } from './product';
export { orderApi } from './order';
export { orderApi } from './order';
export { dashboardApi } from './dashboard';

View File

@@ -1,8 +1,6 @@
/**
* [MOCK-ARBITRAGE] 跨平台套利数据源抽象
* 通过环境变量自动切换Mock/真实API
* AI注意: 这是唯一入口,业务代码必须调用此层
*
* [MOCK-ARBITRAGE] 跨平台套利数据源抽象<EFBFBD><EFBFBD>? * 通过环境变量自动切换Mock/真实API
* AI注意: 这是唯一入口业务代码必须调用此<E794A8><E6ADA4>? *
* @module services/arbitrageDataSource
* @author AI-Agent-1
* @created 2026-03-19

View File

@@ -1,8 +1,7 @@
/**
* [MOCK] AI决策自动化配置数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启
*/
* 仅在USE_MOCK=true时启<EFBFBD>? */
export type AutomationLevel = 'L1' | 'L2' | 'L3' | 'L4';
export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
@@ -419,7 +418,7 @@ class MockAutoExecutionDataSource implements IAutoExecutionDataSource {
}
class ApiAutoExecutionDataSource implements IAutoExecutionDataSource {
private baseUrl = '/api/auto-execution';
private baseUrl = '/api/v1/auto-execution';
async fetchConfigs(tenantId: string, shopId?: string): Promise<AutoExecutionConfig[]> {
const params = new URLSearchParams({ tenant_id: tenantId });
@@ -512,7 +511,7 @@ class ApiAutoExecutionDataSource implements IAutoExecutionDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const autoExecutionDataSource: IAutoExecutionDataSource = useMock
? new MockAutoExecutionDataSource()
: new ApiAutoExecutionDataSource();

View File

@@ -238,9 +238,9 @@ class ApiB2BTradeDataSource implements IB2BTradeDataSource {
// ============================================
/**
* [MOCK] B2B Trade Mock数据
* [MOCK] B2B Trade Mock数据<EFBFBD><EFBFBD>?
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启
* 仅在REACT_APP_USE_MOCK=true时启<EFBFBD><EFBFBD>?
*/
class MockB2BTradeDataSource implements IB2BTradeDataSource {
readonly __MOCK__ = true as const;
@@ -483,10 +483,10 @@ class MockB2BTradeDataSource implements IB2BTradeDataSource {
}
// ============================================
// 导出数据源实
// 导出数据源实<EFBFBD><EFBFBD>?
// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const b2bTradeDataSource: IB2BTradeDataSource = useMock
? new MockB2BTradeDataSource()

View File

@@ -1,8 +1,7 @@
/**
* [MOCK] 黑名单管理数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启
*/
* 仅在USE_MOCK=true时启<EFBFBD>? */
export interface BlacklistRecord {
id: string;
@@ -36,6 +35,29 @@ export interface BlacklistRecord {
updatedAt?: string;
}
export interface BlacklistRule {
id: string;
name: string;
description: string;
condition: string;
condition_type?: 'TRANSACTION' | 'BEHAVIOR' | 'COMPLIANCE';
blacklist_type?: 'FRAUD' | 'CHARGEBACK' | 'ABUSE' | 'OTHER';
risk_score?: number;
auto_blacklist?: boolean;
expiry_days?: number;
platforms?: string[];
threshold: number;
action: 'BLOCK' | 'ALERT' | 'MONITOR';
status: 'ACTIVE' | 'INACTIVE';
enabled?: boolean;
createdAt: string;
updatedAt: string;
created_at?: string;
updated_at?: string;
createdBy: string;
created_by?: string;
}
export interface RiskAssessment {
id: string;
orderId: string;
@@ -79,7 +101,7 @@ class MockBlacklistDataSource implements IBlacklistDataSource {
buyer_email: 'john.doe@example.com',
platform: 'AMAZON',
platform_buyer_id: 'amazon_001',
blacklist_reason: '多次恶意退',
blacklist_reason: '多次恶意退',
blacklist_type: 'FRAUD',
risk_score: 85,
blacklist_date: '2026-03-01',
@@ -89,7 +111,7 @@ class MockBlacklistDataSource implements IBlacklistDataSource {
updated_at: '2026-03-01',
type: 'CUSTOMER',
value: 'John Doe',
reason: '多次恶意退',
reason: '多次恶意退',
severity: 'HIGH',
source: 'MANUAL',
createdBy: 'admin',
@@ -279,7 +301,7 @@ class ApiBlacklistDataSource implements IBlacklistDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const blacklistDataSource: IBlacklistDataSource = useMock
? new MockBlacklistDataSource()
: new ApiBlacklistDataSource();

View File

@@ -1,7 +1,7 @@
/**
* [MOCK-002] 证书数据源抽象层
* 通过环境变量自动切换Mock/真实API
* AI注意: 这是唯一入口,业务代码必须调用此
* AI注意: 这是唯一入口,业务代码必须调用此文件
*
* @module services/certificateDataSource
* @author AI-Frontend-Team
@@ -15,25 +15,11 @@ import { BaseDataSource, BaseMockDataSource, DataSourceFactory } from './dataSou
export type { Certificate } from '@/types/certificate';
export { CertificateStatus, CertificateType };
// ============================================
// 真实API实现
// ============================================
/**
* 证书API数据源
* 调用真实后端API
*/
class ApiCertificateDataSource extends BaseDataSource<Certificate, CertificateQueryParams> {
constructor() {
super('/api/v1/certificate/certificates');
}
/**
* 更新证书状态(审核)
* @param id 证书ID
* @param status 新状态
* @param approvedBy 审核人
*/
async updateStatus(id: string, status: string, approvedBy?: string): Promise<Certificate> {
const response = await fetch(`${this.baseUrl}/${id}/status`, {
method: 'PUT',
@@ -44,33 +30,18 @@ class ApiCertificateDataSource extends BaseDataSource<Certificate, CertificateQu
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
// 更新成功后获取完整数据
const updated = await this.detail(id);
if (updated) return updated;
return result.data;
}
}
// ============================================
// Mock实现 (完全独立文件)
// ============================================
/**
* [MOCK] 证书Mock数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
class MockCertificateDataSource extends BaseMockDataSource<Certificate, CertificateQueryParams> {
/** Mock数据源名称 */
class MockCertificateDataSource extends BaseMockDataSource<Certificate, CertificateQueryParams> implements IDataSource<Certificate, CertificateQueryParams> {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockCertificateDataSource';
/** Mock数据 */
protected mockData: Certificate[] = [
{
id: '1',
@@ -156,12 +127,6 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
},
];
/**
* 更新证书状态(审核)
* @param id 证书ID
* @param status 新状态
* @param approvedBy 审核人
*/
async updateStatus(id: string, status: string, approvedBy?: string): Promise<Certificate> {
await this.delay(300);
@@ -184,10 +149,6 @@ class MockCertificateDataSource extends BaseMockDataSource<Certificate, Certific
}
}
// ============================================
// 导出数据源
// ============================================
export const certificateDataSource = DataSourceFactory.createWithMethods<
Certificate,
CertificateQueryParams,
@@ -199,8 +160,4 @@ export const certificateDataSource = DataSourceFactory.createWithMethods<
mockDataSource: MockCertificateDataSource,
});
/**
* Mock状态标记
* 用于调试和开发环境识别
*/
export { __MOCK__, __DATA_SOURCE_TYPE__ } from './dataSourceFactory';

View File

@@ -185,7 +185,7 @@ class ApiCrossBorderIntegrationDataSource implements ICrossBorderIntegrationData
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const crossBorderIntegrationDataSource: ICrossBorderIntegrationDataSource = useMock
? new MockCrossBorderIntegrationDataSource()
: new ApiCrossBorderIntegrationDataSource();

View File

@@ -204,7 +204,7 @@ class MockDynamicPricingDataSource implements IDynamicPricingDataSource {
const products = [
{ id: 'prod-001', name: '无线蓝牙耳机' },
{ id: 'prod-002', name: '智能手表' },
{ id: 'prod-003', name: '便携充电' },
{ id: 'prod-003', name: '便携充电' },
{ id: 'prod-004', name: '手机壳' },
{ id: 'prod-005', name: '数据线' },
];
@@ -464,7 +464,7 @@ class MockDynamicPricingDataSource implements IDynamicPricingDataSource {
}
class ApiDynamicPricingDataSource implements IDynamicPricingDataSource {
private baseUrl = '/api/pricing';
private baseUrl = '/api/v1/pricing';
async generatePricingDecision(productId: string, strategy?: PricingStrategy): Promise<PricingDecision> {
const response = await fetch(`${this.baseUrl}/decisions/generate`, {
@@ -565,7 +565,7 @@ class ApiDynamicPricingDataSource implements IDynamicPricingDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const dynamicPricingDataSource: IDynamicPricingDataSource = useMock
? new MockDynamicPricingDataSource()
: new ApiDynamicPricingDataSource();

View File

@@ -97,5 +97,5 @@ class ApiFinanceDataSource implements IFinanceDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const financeDataSource: IFinanceDataSource = useMock ? new MockFinanceDataSource() : new ApiFinanceDataSource();

View File

@@ -202,10 +202,8 @@ class ApiIndependentSiteDataSource implements IIndependentSiteDataSource {
// ============================================
/**
* [MOCK] IndependentSite Mock数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启用
*/
* [MOCK] IndependentSite Mock数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在REACT_APP_USE_MOCK=true时启<E697B6><E590AF>? */
class MockIndependentSiteDataSource implements IIndependentSiteDataSource, IMockDataSource<IndependentSite> {
readonly __MOCK__ = true as const;
readonly __MOCK_NAME__ = 'MockIndependentSiteDataSource';
@@ -373,10 +371,9 @@ class MockIndependentSiteDataSource implements IIndependentSiteDataSource, IMock
}
// ============================================
// 导出数据源实
// ============================================
// 导出数据源实<EFBFBD><EFBFBD>?// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const independentSiteDataSource: IIndependentSiteDataSource = useMock
? new MockIndependentSiteDataSource()

View File

@@ -1,8 +1,7 @@
/**
* [MOCK-010] 库存模块DataSource
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启
*/
* 仅在USE_MOCK=true时启<EFBFBD>? */
import { Inventory, InventoryStatus } from '../types/inventory';

View File

@@ -40,18 +40,16 @@ export interface ILeaderboardDataSource {
class ApiLeaderboardDataSource extends BaseDataSource<any, any> implements ILeaderboardDataSource {
constructor() {
super('/api/leaderboard');
super('/api/v1/leaderboard');
}
async fetchLeaderboard(period: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'ALL_TIME'): Promise<LeaderboardData> {
// 使用baseUrl属性
const response = await fetch(`${this.baseUrl}?period=${period}`);
if (!response.ok) throw new Error('Failed to fetch leaderboard');
return response.json();
}
async fetchMyRank(period: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'ALL_TIME'): Promise<MyRank> {
// 使用baseUrl属性
const response = await fetch(`${this.baseUrl}/my-rank?period=${period}`);
if (!response.ok) throw new Error('Failed to fetch my rank');
return response.json();
@@ -59,10 +57,8 @@ class ApiLeaderboardDataSource extends BaseDataSource<any, any> implements ILead
}
class MockLeaderboardDataSource extends BaseMockDataSource<any, any> implements ILeaderboardDataSource {
/** Mock数据源名称 */
readonly __MOCK_NAME__ = 'MockLeaderboardDataSource';
/** Mock数据 */
protected mockData: any[] = [];
private generateRankings(count: number, type: 'revenue' | 'roi' | 'growth'): LeaderboardEntry[] {
@@ -82,7 +78,6 @@ class MockLeaderboardDataSource extends BaseMockDataSource<any, any> implements
}
async fetchLeaderboard(period: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'ALL_TIME'): Promise<LeaderboardData> {
// 使用delay方法
await this.delay(500);
return {
revenue: { rankings: this.generateRankings(10, 'revenue'), total: 100 },
@@ -94,7 +89,6 @@ class MockLeaderboardDataSource extends BaseMockDataSource<any, any> implements
}
async fetchMyRank(period: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'ALL_TIME'): Promise<MyRank> {
// 使用delay方法
await this.delay(300);
return {
revenue: { rank: 15, percentile: 85 },
@@ -104,7 +98,6 @@ class MockLeaderboardDataSource extends BaseMockDataSource<any, any> implements
};
}
// 重写delay方法使其可访问
protected async delay(ms: number): Promise<void> {
return super.delay(ms);
}
@@ -119,8 +112,4 @@ export const leaderboardDataSource = DataSourceFactory.createWithMethods<
mockDataSource: MockLeaderboardDataSource,
});
/**
* Mock状态标记
* 用于调试和开发环境识别
*/
export { __MOCK__, __DATA_SOURCE_TYPE__ } from './dataSourceFactory';
export { __MOCK__, __DATA_SOURCE_TYPE__ } from './dataSourceFactory';

View File

@@ -1,8 +1,6 @@
/**
* [MOCK] 物流管理数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
* [MOCK] 物流管理数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启<E697B6><E590AF>? */
export interface LogisticsProvider {
id: string;
@@ -262,7 +260,7 @@ class ApiLogisticsDataSource implements ILogisticsDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const logisticsDataSource: ILogisticsDataSource = useMock
? new MockLogisticsDataSource()
: new ApiLogisticsDataSource();

View File

@@ -111,5 +111,5 @@ class ApiMarketingDataSource implements IMarketingDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const marketingDataSource: IMarketingDataSource = useMock ? new MockMarketingDataSource() : new ApiMarketingDataSource();

View File

@@ -1,8 +1,6 @@
/**
* [MOCK] 商户管理数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
* [MOCK] 商户管理数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启<E697B6><E590AF>? */
export interface Merchant {
id: string;
@@ -369,7 +367,7 @@ class ApiMerchantDataSource implements IMerchantDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const merchantDataSource: IMerchantDataSource = useMock
? new MockMerchantDataSource()
: new ApiMerchantDataSource();

View File

@@ -122,7 +122,7 @@ class ApiOmnichannelCommunicationDataSource implements IOmnichannelCommunication
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const omnichannelCommunicationDataSource: IOmnichannelCommunicationDataSource = useMock
? new MockOmnichannelCommunicationDataSource()
: new ApiOmnichannelCommunicationDataSource();

View File

@@ -131,7 +131,7 @@ class ApiOmnichannelMarketingDataSource implements IOmnichannelMarketingDataSour
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const omnichannelMarketingDataSource: IOmnichannelMarketingDataSource = useMock
? new MockOmnichannelMarketingDataSource()
: new ApiOmnichannelMarketingDataSource();

View File

@@ -1,95 +1,344 @@
/**
* [MOCK] OperationAgent Mock数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true或开发环境时启用
*/
import { Store, StoreBindingData, SyncResult, IOperationAgentService, Task, TaskCreateData, TaskType, TaskPriority, TaskStatus } from './operationAgentTypes';
import { http } from './http';
export interface StoreBindingData {
merchantId: string;
platform: string;
platformShopId: string;
name: string;
description?: string;
authInfo: Record<string, any>;
const MOCK_STORES: Store[] = [
{
id: 'store-001',
merchantId: 'merchant-1',
name: 'Amazon US Store',
platform: 'amazon',
platformShopId: 'AMZ-US-001',
description: 'Amazon美国站点主店铺',
status: 'active',
created_at: '2024-01-15T08:00:00Z',
updated_at: '2024-03-20T10:30:00Z',
},
{
id: 'store-002',
merchantId: 'merchant-1',
name: 'Shopee SG Store',
platform: 'shopee',
platformShopId: 'SHP-SG-001',
description: 'Shopee新加坡站点',
status: 'active',
created_at: '2024-02-10T09:00:00Z',
updated_at: '2024-03-18T14:20:00Z',
},
{
id: 'store-003',
merchantId: 'merchant-1',
name: 'AliExpress Store',
platform: 'aliexpress',
platformShopId: 'AE-001',
description: 'AliExpress主店铺',
status: 'pending',
created_at: '2024-03-01T10:00:00Z',
updated_at: '2024-03-15T16:45:00Z',
},
{
id: 'store-004',
merchantId: 'merchant-2',
name: 'TikTok Shop US',
platform: 'tiktok',
platformShopId: 'TT-US-001',
description: 'TikTok美国小店',
status: 'active',
created_at: '2024-02-20T11:00:00Z',
updated_at: '2024-03-19T09:15:00Z',
},
];
const MOCK_TASKS: Task[] = [
{
id: 'task-001',
merchantId: 'merchant-1',
storeId: 'store-001',
taskType: 'PRICING',
targetProducts: ['prod-001', 'prod-002', 'prod-003'],
constraints: { maxPrice: 100, minROI: 0.3, maxQuantity: 1000 },
priority: 'HIGH',
status: 'COMPLETED',
progress: 100,
description: '优化Amazon店铺商品定价',
logs: [
'任务开始: 2024-03-20T08:00:00Z',
'正在分析商品价格: 2024-03-20T08:05:00Z',
'正在优化定价策略: 2024-03-20T08:10:00Z',
'任务完成: 2024-03-20T08:15:00Z',
],
created_at: '2024-03-20T08:00:00Z',
updated_at: '2024-03-20T08:15:00Z',
completed_at: '2024-03-20T08:15:00Z',
},
{
id: 'task-002',
merchantId: 'merchant-1',
storeId: 'store-002',
taskType: 'LISTING',
targetProducts: ['prod-004', 'prod-005'],
constraints: { maxPrice: 50, maxQuantity: 500 },
priority: 'MEDIUM',
status: 'RUNNING',
progress: 60,
description: 'Shopee店铺商品上架',
logs: [
'任务开始: 2024-03-21T10:00:00Z',
'正在准备商品数据: 2024-03-21T10:05:00Z',
'正在上传商品信息: 2024-03-21T10:10:00Z',
],
created_at: '2024-03-21T10:00:00Z',
updated_at: '2024-03-21T10:20:00Z',
},
{
id: 'task-003',
merchantId: 'merchant-1',
storeId: 'store-001',
taskType: 'AD_OPTIMIZATION',
targetProducts: ['prod-001', 'prod-003'],
constraints: { minROI: 0.4 },
priority: 'LOW',
status: 'FAILED',
progress: 30,
description: '优化Amazon广告策略',
error: '广告API调用失败',
logs: [
'任务开始: 2024-03-21T14:00:00Z',
'正在获取广告数据: 2024-03-21T14:05:00Z',
'正在分析广告效果: 2024-03-21T14:10:00Z',
'发生错误: 2024-03-21T14:15:00Z',
],
created_at: '2024-03-21T14:00:00Z',
updated_at: '2024-03-21T14:15:00Z',
},
{
id: 'task-004',
merchantId: 'merchant-2',
storeId: 'store-004',
taskType: 'PRICING',
targetProducts: ['prod-006', 'prod-007'],
constraints: { maxPrice: 80, minROI: 0.25 },
priority: 'MEDIUM',
status: 'PENDING',
progress: 0,
description: 'TikTok店铺商品定价优化',
created_at: '2024-03-22T09:00:00Z',
updated_at: '2024-03-22T09:00:00Z',
},
];
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
class MockOperationAgentService implements IOperationAgentService {
private stores: Store[] = [...MOCK_STORES];
private tasks: Task[] = [...MOCK_TASKS];
async bindStore(data: StoreBindingData): Promise<Store> {
await delay(500);
const newStore: Store = {
id: `store-${Date.now()}`,
merchantId: data.merchantId,
name: data.name,
platform: data.platform,
platformShopId: data.platformShopId,
description: data.description || '',
status: 'pending',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
this.stores.push(newStore);
return newStore;
}
async getStores(merchantId: string): Promise<Store[]> {
await delay(300);
return this.stores.filter(s => s.merchantId === merchantId);
}
async getStore(storeId: string): Promise<Store> {
await delay(200);
const store = this.stores.find(s => s.id === storeId);
if (!store) {
throw new Error('Store not found');
}
return store;
}
async syncProducts(storeId: string): Promise<SyncResult> {
await delay(1000);
return {
success: true,
count: Math.floor(Math.random() * 100) + 50,
};
}
async syncOrders(storeId: string): Promise<SyncResult> {
await delay(800);
return {
success: true,
count: Math.floor(Math.random() * 50) + 20,
};
}
async updateProductPrice(storeId: string, productId: string, price: number): Promise<boolean> {
await delay(300);
return true;
}
async deactivateStore(storeId: string): Promise<Store> {
await delay(300);
const store = this.stores.find(s => s.id === storeId);
if (store) {
store.status = 'inactive';
store.updated_at = new Date().toISOString();
}
return store!;
}
async reactivateStore(storeId: string): Promise<Store> {
await delay(300);
const store = this.stores.find(s => s.id === storeId);
if (store) {
store.status = 'active';
store.updated_at = new Date().toISOString();
}
return store!;
}
// 任务相关方法
async getTasks(merchantId: string): Promise<Task[]> {
await delay(300);
return this.tasks.filter(t => t.merchantId === merchantId);
}
async getTask(taskId: string): Promise<Task> {
await delay(200);
const task = this.tasks.find(t => t.id === taskId);
if (!task) {
throw new Error('Task not found');
}
return task;
}
async createTask(data: TaskCreateData): Promise<Task> {
await delay(500);
const newTask: Task = {
id: `task-${Date.now()}`,
merchantId: data.merchantId,
storeId: data.storeId,
taskType: data.taskType,
targetProducts: data.targetProducts,
constraints: data.constraints,
priority: data.priority,
status: 'PENDING',
progress: 0,
description: data.description,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
this.tasks.push(newTask);
return newTask;
}
async cancelTask(taskId: string): Promise<boolean> {
await delay(300);
const task = this.tasks.find(t => t.id === taskId);
if (task) {
task.status = 'CANCELLED';
task.updated_at = new Date().toISOString();
}
return true;
}
async retryTask(taskId: string): Promise<boolean> {
await delay(300);
const task = this.tasks.find(t => t.id === taskId);
if (task) {
task.status = 'PENDING';
task.progress = 0;
task.error = undefined;
task.updated_at = new Date().toISOString();
}
return true;
}
}
export interface Store {
id: string;
merchantId: string;
name: string;
platform: string;
platformShopId: string;
description: string;
status: string;
created_at: string;
updated_at: string;
}
export interface SyncResult {
success: boolean;
count: number;
}
export class OperationAgentService {
/**
* 绑定店铺
*/
class ApiOperationAgentService implements IOperationAgentService {
async bindStore(data: StoreBindingData): Promise<Store> {
const response = await http.post<Store>('/api/operation-agent/stores', data);
return response.data;
}
/**
* 获取商户的店铺列表
*/
async getStores(merchantId: string): Promise<Store[]> {
const response = await http.get<Store[]>(`/api/operation-agent/stores/${merchantId}`);
return response.data;
}
/**
* 获取店铺详情
*/
async getStore(storeId: string): Promise<Store> {
const response = await http.get<Store>(`/api/operation-agent/stores/detail/${storeId}`);
return response.data;
}
/**
* 同步店铺商品
*/
async syncProducts(storeId: string): Promise<SyncResult> {
const response = await http.post<SyncResult>(`/api/operation-agent/stores/${storeId}/products/sync`);
return response.data;
}
/**
* 同步店铺订单
*/
async syncOrders(storeId: string): Promise<SyncResult> {
const response = await http.post<SyncResult>(`/api/operation-agent/stores/${storeId}/orders/sync`);
return response.data;
}
/**
* 更新商品价格
*/
async updateProductPrice(storeId: string, productId: string, price: number): Promise<boolean> {
const response = await http.put<boolean>(`/api/operation-agent/stores/${storeId}/products/${productId}/price`, { price });
return response.data;
}
/**
* 停用店铺
*/
async deactivateStore(storeId: string): Promise<Store> {
const response = await http.put<Store>(`/api/operation-agent/stores/${storeId}/deactivate`);
return response.data;
}
/**
* 重新激活店铺
*/
async reactivateStore(storeId: string): Promise<Store> {
const response = await http.put<Store>(`/api/operation-agent/stores/${storeId}/reactivate`);
return response.data;
}
// 任务相关方法
async getTasks(merchantId: string): Promise<Task[]> {
const response = await http.get<Task[]>(`/api/operation-agent/tasks/${merchantId}`);
return response.data;
}
async getTask(taskId: string): Promise<Task> {
const response = await http.get<Task>(`/api/operation-agent/tasks/detail/${taskId}`);
return response.data;
}
async createTask(data: TaskCreateData): Promise<Task> {
const response = await http.post<Task>('/api/operation-agent/tasks', data);
return response.data;
}
async cancelTask(taskId: string): Promise<boolean> {
const response = await http.put<boolean>(`/api/operation-agent/tasks/${taskId}/cancel`);
return response.data;
}
async retryTask(taskId: string): Promise<boolean> {
const response = await http.put<boolean>(`/api/operation-agent/tasks/${taskId}/retry`);
return response.data;
}
}
export const operationAgentService = new OperationAgentService();
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const operationAgentService: IOperationAgentService = useMock
? new MockOperationAgentService()
: new ApiOperationAgentService();
export type { Store, StoreBindingData, SyncResult, Task, TaskType, TaskPriority, TaskStatus };

View File

@@ -0,0 +1,84 @@
/**
* OperationAgent类型定义
*/
export interface StoreBindingData {
merchantId: string;
platform: string;
platformShopId: string;
name: string;
description?: string;
authInfo: Record<string, any>;
}
export interface Store {
id: string;
merchantId: string;
name: string;
platform: string;
platformShopId: string;
description: string;
status: string;
created_at: string;
updated_at: string;
}
export interface SyncResult {
success: boolean;
count: number;
}
export type TaskType = 'PRICING' | 'LISTING' | 'AD_OPTIMIZATION';
export type TaskPriority = 'HIGH' | 'MEDIUM' | 'LOW';
export type TaskStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
export interface TaskConstraints {
maxPrice?: number;
minROI?: number;
maxQuantity?: number;
}
export interface Task {
id: string;
merchantId: string;
storeId: string;
taskType: TaskType;
targetProducts: string[];
constraints: TaskConstraints;
priority: TaskPriority;
status: TaskStatus;
progress: number;
description?: string;
logs?: string[];
error?: string;
created_at: string;
updated_at: string;
completed_at?: string;
}
export interface TaskCreateData {
merchantId: string;
storeId: string;
taskType: TaskType;
targetProducts: string[];
constraints: TaskConstraints;
priority: TaskPriority;
description?: string;
}
export interface IOperationAgentService {
bindStore(data: StoreBindingData): Promise<Store>;
getStores(merchantId: string): Promise<Store[]>;
getStore(storeId: string): Promise<Store>;
syncProducts(storeId: string): Promise<SyncResult>;
syncOrders(storeId: string): Promise<SyncResult>;
updateProductPrice(storeId: string, productId: string, price: number): Promise<boolean>;
deactivateStore(storeId: string): Promise<Store>;
reactivateStore(storeId: string): Promise<Store>;
// 任务相关方法
getTasks(merchantId: string): Promise<Task[]>;
getTask(taskId: string): Promise<Task>;
createTask(data: TaskCreateData): Promise<Task>;
cancelTask(taskId: string): Promise<boolean>;
retryTask(taskId: string): Promise<boolean>;
}

View File

@@ -0,0 +1,168 @@
import { http } from './http';
import { PlatformAccount, PlatformAccountStats } from '@/types/platform';
export interface PlatformAuthDataSource {
list(filters?: { platform?: string; status?: string; shopId?: string }): Promise<PlatformAccount[]>;
getById(id: string): Promise<PlatformAccount | null>;
connect(data: { platform: string; accountName: string; accountId: string; shopId?: string; config?: Record<string, any> }): Promise<{ account: PlatformAccount; authUrl: string }>;
refresh(id: string): Promise<{ success: boolean; message: string }>;
disconnect(id: string): Promise<void>;
delete(id: string): Promise<void>;
getStats(): Promise<PlatformAccountStats>;
}
export class PlatformAuthApiDataSource implements PlatformAuthDataSource {
async list(filters?: { platform?: string; status?: string; shopId?: string }): Promise<PlatformAccount[]> {
const params = new URLSearchParams();
if (filters?.platform) params.append('platform', filters.platform);
if (filters?.status) params.append('status', filters.status);
if (filters?.shopId) params.append('shopId', filters.shopId);
const response = await http.get(`/api/platform-auth/list?${params.toString()}`);
return response.data.data;
}
async getById(id: string): Promise<PlatformAccount | null> {
const response = await http.get(`/api/platform-auth/${id}`);
return response.data.data;
}
async connect(data: { platform: string; accountName: string; accountId: string; shopId?: string; config?: Record<string, any> }): Promise<{ account: PlatformAccount; authUrl: string }> {
const response = await http.post('/api/platform-auth/connect', data);
return response.data.data;
}
async refresh(id: string): Promise<{ success: boolean; message: string }> {
const response = await http.post(`/api/platform-auth/refresh/${id}`);
return response.data.data;
}
async disconnect(id: string): Promise<void> {
await http.post(`/api/platform-auth/disconnect/${id}`);
}
async delete(id: string): Promise<void> {
await http.delete(`/api/platform-auth/${id}`);
}
async getStats(): Promise<PlatformAccountStats> {
const response = await http.get('/api/platform-auth/stats');
return response.data.data;
}
}
export class PlatformAuthMockDataSource implements PlatformAuthDataSource {
private mockAccounts: PlatformAccount[] = [
{
id: '1',
tenantId: 'tenant_1',
platform: 'AMAZON',
accountName: 'My Amazon Store',
accountId: 'amazon_123',
status: 'ACTIVE',
lastSyncAt: '2024-01-15T10:30:00Z',
createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-15T10:30:00Z',
},
{
id: '2',
tenantId: 'tenant_1',
platform: 'SHOPIFY',
accountName: 'my-shop.myshopify.com',
accountId: 'shopify_456',
status: 'ACTIVE',
lastSyncAt: '2024-01-15T09:15:00Z',
createdAt: '2024-01-01T00:00:00Z',
updatedAt: '2024-01-15T09:15:00Z',
},
{
id: '3',
tenantId: 'tenant_1',
platform: 'SHOPEE',
accountName: 'My Shopee Shop',
accountId: 'shopee_789',
status: 'EXPIRED',
lastSyncAt: '2023-12-01T08:00:00Z',
createdAt: '2023-06-01T00:00:00Z',
updatedAt: '2024-01-01T08:00:00Z',
},
{
id: '4',
tenantId: 'tenant_1',
platform: 'EBAY',
accountName: 'My eBay Store',
accountId: 'ebay_101',
status: 'INACTIVE',
createdAt: '2024-01-10T00:00:00Z',
updatedAt: '2024-01-10T00:00:00Z',
},
];
async list(filters?: { platform?: string; status?: string; shopId?: string }): Promise<PlatformAccount[]> {
let result = [...this.mockAccounts];
if (filters?.platform) {
result = result.filter(a => a.platform === filters.platform);
}
if (filters?.status) {
result = result.filter(a => a.status === filters.status);
}
return result;
}
async getById(id: string): Promise<PlatformAccount | null> {
return this.mockAccounts.find(a => a.id === id) || null;
}
async connect(data: { platform: string; accountName: string; accountId: string; shopId?: string; config?: Record<string, any> }): Promise<{ account: PlatformAccount; authUrl: string }> {
const account: PlatformAccount = {
id: Date.now().toString(),
tenantId: 'tenant_1',
platform: data.platform,
accountName: data.accountName,
accountId: data.accountId,
status: 'INACTIVE',
shopId: data.shopId,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
this.mockAccounts.push(account);
return {
account,
authUrl: `https://example.com/oauth/authorize?platform=${data.platform}`,
};
}
async refresh(id: string): Promise<{ success: boolean; message: string }> {
const account = this.mockAccounts.find(a => a.id === id);
if (account) {
account.status = 'ACTIVE';
account.lastSyncAt = new Date().toISOString();
}
return { success: true, message: 'Token refreshed successfully' };
}
async disconnect(id: string): Promise<void> {
const account = this.mockAccounts.find(a => a.id === id);
if (account) {
account.status = 'INACTIVE';
}
}
async delete(id: string): Promise<void> {
this.mockAccounts = this.mockAccounts.filter(a => a.id !== id);
}
async getStats(): Promise<PlatformAccountStats> {
return {
total: this.mockAccounts.length,
active: this.mockAccounts.filter(a => a.status === 'ACTIVE').length,
inactive: this.mockAccounts.filter(a => a.status === 'INACTIVE').length,
expired: this.mockAccounts.filter(a => a.status === 'EXPIRED').length,
error: this.mockAccounts.filter(a => a.status === 'ERROR').length,
};
}
}
export const platformAuthDataSource = process.env.REACT_APP_USE_MOCK === 'true'
? new PlatformAuthMockDataSource()
: new PlatformAuthApiDataSource();

View File

@@ -7,6 +7,23 @@
import { Product, ProductStatus } from '@/types/product';
import { IDataSource, IMockDataSource } from '@/types/datasource';
export type Platform = 'Amazon' | 'eBay' | 'Shopee' | 'TikTok' | 'Shopify';
export interface PlatformStatus {
platform: Platform;
status: 'LIVE' | 'PENDING' | 'SYNCING' | 'LISTED' | 'FAILED' | 'OFFLINE';
platformProductId?: string;
lastSyncAt?: string;
error?: string;
}
export interface ProductWithPlatform extends Product {
platformStatus: Record<Platform, PlatformStatus['status']>;
costPrice: number;
profit: number;
roi: number;
}
export interface ProfitMonitor {
id: string;
productId: string;
@@ -35,6 +52,21 @@ export interface ROIAnalysis {
status: 'ACTIVE' | 'COMPLETED' | 'PAUSED';
}
export interface PlatformSyncResult {
platform: Platform;
success: boolean;
platformProductId?: string;
error?: string;
}
export interface ProductDataSource extends IDataSource<ProductWithPlatform> {
listByPlatform(platform: Platform): Promise<ProductWithPlatform[]>;
listUnpublished(): Promise<ProductWithPlatform[]>;
syncToPlatform(productId: string, platform: Platform): Promise<PlatformSyncResult>;
syncToMultiplePlatforms(productId: string, platforms: Platform[]): Promise<Record<Platform, PlatformSyncResult>>;
getPlatformStats(): Promise<Record<Platform | 'all' | 'unpublished', { total: number; live: number; pending: number; failed: number }>>;
}
export class ProductApiDataSource implements IDataSource<Product> {
async list(): Promise<Product[]> {
return [];
@@ -65,54 +97,143 @@ export class ProductApiDataSource implements IDataSource<Product> {
}
}
export class ProductMockDataSource implements IMockDataSource<Product> {
private mockProducts: Product[] = [
export class ProductMockDataSource implements IMockDataSource<ProductWithPlatform>, ProductDataSource {
private mockProducts: ProductWithPlatform[] = [
{
id: '1',
name: '智能手机',
sku: 'PHONE-001',
description: '最新款智能手机',
price: 5999.99,
categories: ['电子产品'],
name: '工业温度传感器Pro',
sku: 'TP-TEMP-001',
description: '高精度工业温度传感器',
price: 89.99,
costPrice: 45.00,
profit: 44.99,
roi: 99.98,
categories: ['工业自动化'],
status: 'active',
stock: 100,
images: ['https://example.com/phone1.jpg', 'https://example.com/phone2.jpg'],
createdAt: new Date('2026-03-01'),
updatedAt: new Date('2026-03-10'),
stock: 256,
images: ['https://via.placeholder.com/80x80?text=Product'],
platformStatus: { Amazon: 'LIVE', eBay: 'LIVE', Shopee: 'PENDING', TikTok: 'OFFLINE', Shopify: 'OFFLINE' },
createdAt: new Date('2025-12-15'),
updatedAt: new Date('2026-03-18'),
},
{
id: '2',
name: '笔记本电脑',
sku: 'LAPTOP-001',
description: '高性能笔记本电脑',
price: 8999.99,
categories: ['电子产品'],
name: '压力传感器Digital',
sku: 'TP-PRES-002',
description: '数字压力传感器',
price: 129.99,
costPrice: 65.00,
profit: 64.99,
roi: 99.98,
categories: ['工业自动化'],
status: 'active',
stock: 50,
images: ['https://example.com/laptop1.jpg', 'https://example.com/laptop2.jpg'],
createdAt: new Date('2026-03-02'),
updatedAt: new Date('2026-03-11'),
stock: 128,
images: ['https://via.placeholder.com/80x80?text=Product'],
platformStatus: { Amazon: 'OFFLINE', eBay: 'OFFLINE', Shopee: 'OFFLINE', TikTok: 'OFFLINE', Shopify: 'OFFLINE' },
createdAt: new Date('2026-03-10'),
updatedAt: new Date('2026-03-10'),
},
{
id: '3',
name: '运动鞋',
sku: 'SHOE-001',
description: '轻便透气运动鞋',
price: 89.99,
categories: ['服装'],
name: '流量计Ultra',
sku: 'TP-FLOW-003',
description: '超声波流量计',
price: 299.99,
costPrice: 150.00,
profit: 149.99,
roi: 99.99,
categories: ['仪器仪表'],
status: 'active',
stock: 150,
images: ['https://example.com/shoe1.jpg', 'https://example.com/shoe2.jpg'],
createdAt: new Date('2026-03-03'),
updatedAt: new Date('2026-03-12'),
stock: 64,
images: ['https://via.placeholder.com/80x80?text=Product'],
platformStatus: { Amazon: 'OFFLINE', eBay: 'OFFLINE', Shopee: 'OFFLINE', TikTok: 'OFFLINE', Shopify: 'OFFLINE' },
createdAt: new Date('2026-03-15'),
updatedAt: new Date('2026-03-16'),
},
];
async list(): Promise<Product[]> {
async list(): Promise<ProductWithPlatform[]> {
return this.mockProducts;
}
async detail(id: string): Promise<Product> {
async listByPlatform(platform: Platform): Promise<ProductWithPlatform[]> {
return this.mockProducts.filter(p => p.platformStatus[platform] && p.platformStatus[platform] !== 'OFFLINE');
}
async listUnpublished(): Promise<ProductWithPlatform[]> {
return this.mockProducts.filter(p =>
Object.values(p.platformStatus).every(status => status === 'OFFLINE')
);
}
async syncToPlatform(productId: string, platform: Platform): Promise<PlatformSyncResult> {
const product = this.mockProducts.find(p => p.id === productId);
if (!product) {
return { platform, success: false, error: 'Product not found' };
}
product.platformStatus[platform] = 'SYNCING';
product.updatedAt = new Date();
await new Promise(resolve => setTimeout(resolve, 1000));
const success = Math.random() > 0.2;
if (success) {
product.platformStatus[platform] = 'LIVE';
return { platform, success: true, platformProductId: `${platform}-${productId}` };
} else {
product.platformStatus[platform] = 'FAILED';
return { platform, success: false, error: 'Sync failed' };
}
}
async syncToMultiplePlatforms(productId: string, platforms: Platform[]): Promise<Record<Platform, PlatformSyncResult>> {
const results: Record<Platform, PlatformSyncResult> = {} as any;
for (const platform of platforms) {
results[platform] = await this.syncToPlatform(productId, platform);
}
return results;
}
async getPlatformStats(): Promise<Record<Platform | 'all' | 'unpublished', { total: number; live: number; pending: number; failed: number }>> {
const stats: any = {
all: { total: this.mockProducts.length, live: 0, pending: 0, failed: 0 },
unpublished: { total: 0, live: 0, pending: 0, failed: 0 },
};
const platforms: Platform[] = ['Amazon', 'eBay', 'Shopee', 'TikTok', 'Shopify'];
platforms.forEach(p => {
stats[p] = { total: 0, live: 0, pending: 0, failed: 0 };
});
this.mockProducts.forEach(product => {
const hasPlatform = Object.values(product.platformStatus).some(s => s !== 'OFFLINE');
if (!hasPlatform) {
stats.unpublished.total++;
}
platforms.forEach(platform => {
const status = product.platformStatus[platform];
if (status && status !== 'OFFLINE') {
stats[platform].total++;
if (status === 'LIVE') {
stats[platform].live++;
stats.all.live++;
} else if (['PENDING', 'SYNCING', 'LISTED'].includes(status)) {
stats[platform].pending++;
stats.all.pending++;
} else if (['FAILED', 'SYNC_FAILED'].includes(status)) {
stats[platform].failed++;
stats.all.failed++;
}
}
});
});
return stats;
}
async detail(id: string): Promise<ProductWithPlatform> {
const product = this.mockProducts.find(p => p.id === id);
if (!product) {
throw new Error('Product not found');
@@ -120,17 +241,21 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
return product;
}
async create(data: Partial<Product>): Promise<Product> {
const newProduct: Product = {
async create(data: Partial<ProductWithPlatform>): Promise<ProductWithPlatform> {
const newProduct: ProductWithPlatform = {
id: `${this.mockProducts.length + 1}`,
name: data.name || '',
sku: data.sku || `SKU-${Date.now()}`,
description: data.description || '',
price: data.price || 0,
costPrice: data.costPrice || 0,
profit: data.profit || 0,
roi: data.roi || 0,
categories: data.categories || [],
status: data.status || 'active',
stock: data.stock || 0,
images: data.images || [],
platformStatus: data.platformStatus || { Amazon: 'OFFLINE', eBay: 'OFFLINE', Shopee: 'OFFLINE', TikTok: 'OFFLINE', Shopify: 'OFFLINE' },
createdAt: new Date(),
updatedAt: new Date(),
};
@@ -138,7 +263,7 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
return newProduct;
}
async update(id: string, data: Partial<Product>): Promise<Product> {
async update(id: string, data: Partial<ProductWithPlatform>): Promise<ProductWithPlatform> {
const index = this.mockProducts.findIndex(p => p.id === id);
if (index === -1) {
throw new Error('Product not found');
@@ -159,17 +284,17 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
this.mockProducts.splice(index, 1);
}
async getByCategory(category: string): Promise<Product[]> {
async getByCategory(category: string): Promise<ProductWithPlatform[]> {
return this.mockProducts.filter(p => p.categories?.includes(category));
}
async updateStatus(id: string, status: ProductStatus): Promise<Product | null> {
async updateStatus(id: string, status: ProductStatus): Promise<ProductWithPlatform | null> {
const existingProduct = this.mockProducts.find(p => p.id === id);
if (!existingProduct) {
return null;
}
const updatedProduct: Product = {
const updatedProduct: ProductWithPlatform = {
...existingProduct,
status,
updatedAt: new Date(),
@@ -187,47 +312,25 @@ export class ProductMockDataSource implements IMockDataSource<Product> {
this.mockProducts = [
{
id: '1',
name: '智能手机',
sku: 'PHONE-001',
description: '最新款智能手机',
price: 5999.99,
categories: ['电子产品'],
status: 'active',
stock: 100,
images: ['https://example.com/phone1.jpg', 'https://example.com/phone2.jpg'],
createdAt: new Date('2026-03-01'),
updatedAt: new Date('2026-03-10'),
},
{
id: '2',
name: '笔记本电脑',
sku: 'LAPTOP-001',
description: '高性能笔记本电脑',
price: 8999.99,
categories: ['电子产品'],
status: 'active',
stock: 50,
images: ['https://example.com/laptop1.jpg', 'https://example.com/laptop2.jpg'],
createdAt: new Date('2026-03-02'),
updatedAt: new Date('2026-03-11'),
},
{
id: '3',
name: '运动鞋',
sku: 'SHOE-001',
description: '轻便透气运动鞋',
name: '工业温度传感器Pro',
sku: 'TP-TEMP-001',
description: '高精度工业温度传感器',
price: 89.99,
categories: ['服装'],
costPrice: 45.00,
profit: 44.99,
roi: 99.98,
categories: ['工业自动化'],
status: 'active',
stock: 150,
images: ['https://example.com/shoe1.jpg', 'https://example.com/shoe2.jpg'],
createdAt: new Date('2026-03-03'),
updatedAt: new Date('2026-03-12'),
stock: 256,
images: ['https://via.placeholder.com/80x80?text=Product'],
platformStatus: { Amazon: 'LIVE', eBay: 'LIVE', Shopee: 'PENDING', TikTok: 'OFFLINE', Shopify: 'OFFLINE' },
createdAt: new Date('2025-12-15'),
updatedAt: new Date('2026-03-18'),
},
];
}
getMockData(): Product[] {
getMockData(): ProductWithPlatform[] {
return this.mockProducts;
}
}

View File

@@ -1,8 +1,7 @@
/**
* [MOCK-010] 自动选品数据源抽象层
* 通过环境变量自动切换Mock/真实API
* AI注意: 这是唯一入口,业务代码必须调用此
*
* AI注意: 这是唯一入口,业务代码必须调用此<EFBFBD><EFBFBD>? *
* @module services/productSelectionDataSource
* @author AI-Frontend-33
* @created 2026-03-20
@@ -512,10 +511,10 @@ class MockProductSelectionDataSource {
}
// ============================================
// 导出数据源实(环境变量控制)
// 导出数据源实<EFBFBD><EFBFBD>?(环境变量控制)
// ============================================
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const productSelectionDataSource = useMock
? new MockProductSelectionDataSource()

View File

@@ -100,5 +100,5 @@ class ApiReportsDataSource implements IReportsDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const reportsDataSource: IReportsDataSource = useMock ? new MockReportsDataSource() : new ApiReportsDataSource();

View File

@@ -1,8 +1,7 @@
/**
* [MOCK] 退货管理数据源
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启
*/
* 仅在USE_MOCK=true时启<EFBFBD><EFBFBD>? */
export interface SKUData {
id: string;
@@ -229,7 +228,7 @@ class ApiReturnDataSource implements IReturnDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const returnDataSource: IReturnDataSource = useMock
? new MockReturnDataSource()
: new ApiReturnDataSource();

View File

@@ -0,0 +1,173 @@
import { http } from './http';
export interface ServiceInfo {
name: string;
enabled: boolean;
initialized: boolean;
error?: string;
config?: {
name: string;
category: string;
description: string;
enabled: boolean;
memoryImpact: 'low' | 'medium' | 'high';
};
}
export interface ServiceStats {
total: number;
enabled: number;
disabled: number;
initialized: number;
failed: number;
byCategory: Record<string, { total: number; enabled: number; initialized: number }>;
byMemoryImpact: {
low: { total: number; enabled: number };
medium: { total: number; enabled: number };
high: { total: number; enabled: number };
};
}
export interface ServicePreset {
id: string;
name: string;
description: string;
serviceCount: number;
}
export interface ServiceManagerDataSource {
list(): Promise<{ services: ServiceInfo[]; groupedServices: Record<string, ServiceInfo[]>; stats: ServiceStats }>;
getStats(): Promise<ServiceStats>;
toggle(name: string, enabled: boolean): Promise<{ name: string; enabled: boolean; message: string }>;
batchToggle(services: string[], enabled: boolean): Promise<{ results: Array<{ name: string; success: boolean; error?: string }>; message: string }>;
applyPreset(preset: string): Promise<{ preset: string; enabledCount: number; message: string }>;
getPresets(): Promise<ServicePreset[]>;
getCategories(): Promise<Record<string, { label: string; color: string }>>;
}
class ServiceManagerApiDataSource implements ServiceManagerDataSource {
async list() {
const response = await http.get('/api/service-manager/list');
return response.data.data;
}
async getStats() {
const response = await http.get('/api/service-manager/stats');
return response.data.data;
}
async toggle(name: string, enabled: boolean) {
const response = await http.post(`/api/service-manager/toggle/${name}`, { enabled });
return response.data.data;
}
async batchToggle(services: string[], enabled: boolean) {
const response = await http.post('/api/service-manager/batch-toggle', { services, enabled });
return response.data.data;
}
async applyPreset(preset: string) {
const response = await http.post(`/api/service-manager/apply-preset/${preset}`);
return response.data.data;
}
async getPresets() {
const response = await http.get('/api/service-manager/presets');
return response.data.data;
}
async getCategories() {
const response = await http.get('/api/service-manager/categories');
return response.data.data;
}
}
class ServiceManagerMockDataSource implements ServiceManagerDataSource {
private mockServices: ServiceInfo[] = [
{ name: 'AuthService', enabled: true, initialized: true, config: { name: 'AuthService', category: 'CORE', description: '用户认证服务', enabled: true, memoryImpact: 'low' } },
{ name: 'TurboGateway', enabled: true, initialized: true, config: { name: 'TurboGateway', category: 'CORE', description: 'API网关与缓存', enabled: true, memoryImpact: 'medium' } },
{ name: 'ProductService', enabled: true, initialized: true, config: { name: 'ProductService', category: 'BUSINESS', description: '商品管理服务', enabled: true, memoryImpact: 'medium' } },
{ name: 'MemoryWatchdog', enabled: false, initialized: false, config: { name: 'MemoryWatchdog', category: 'TELEMETRY', description: '内存监控服务', enabled: false, memoryImpact: 'medium' } },
{ name: 'FederatedNode', enabled: false, initialized: false, config: { name: 'FederatedNode', category: 'NETWORK', description: '联邦节点服务', enabled: false, memoryImpact: 'high' } },
{ name: 'P2PConnection', enabled: false, initialized: false, config: { name: 'P2PConnection', category: 'NETWORK', description: 'P2P连接服务', enabled: false, memoryImpact: 'high' } },
{ name: 'AgentSwarm', enabled: false, initialized: false, config: { name: 'AgentSwarm', category: 'AI', description: 'Agent集群服务', enabled: false, memoryImpact: 'high' } },
{ name: 'ChatBot', enabled: false, initialized: false, config: { name: 'ChatBot', category: 'AI', description: 'AI聊天机器人', enabled: false, memoryImpact: 'high' } },
];
async list() {
const groupedServices = this.mockServices.reduce((acc, service) => {
const category = service.config?.category || 'BUSINESS';
if (!acc[category]) acc[category] = [];
acc[category].push(service);
return acc;
}, {} as Record<string, ServiceInfo[]>);
return {
services: this.mockServices,
groupedServices,
stats: {
total: this.mockServices.length,
enabled: this.mockServices.filter(s => s.enabled).length,
disabled: this.mockServices.filter(s => !s.enabled).length,
initialized: this.mockServices.filter(s => s.initialized).length,
failed: this.mockServices.filter(s => s.error).length,
byCategory: {},
byMemoryImpact: { low: { total: 0, enabled: 0 }, medium: { total: 0, enabled: 0 }, high: { total: 0, enabled: 0 } },
},
};
}
async getStats(): Promise<ServiceStats> {
return {
total: this.mockServices.length,
enabled: this.mockServices.filter(s => s.enabled).length,
disabled: this.mockServices.filter(s => !s.enabled).length,
initialized: this.mockServices.filter(s => s.initialized).length,
failed: this.mockServices.filter(s => s.error).length,
byCategory: {},
byMemoryImpact: { low: { total: 0, enabled: 0 }, medium: { total: 0, enabled: 0 }, high: { total: 0, enabled: 0 } },
};
}
async toggle(name: string, enabled: boolean) {
const service = this.mockServices.find(s => s.name === name);
if (service) service.enabled = enabled;
return { name, enabled, message: `服务 "${name}" 已${enabled ? '启用' : '禁用'}` };
}
async batchToggle(services: string[], enabled: boolean) {
return {
results: services.map(name => ({ name, success: true })),
message: `${enabled ? '启用' : '禁用'} ${services.length} 个服务`,
};
}
async applyPreset(preset: string) {
return { preset, enabledCount: 5, message: `已应用 "${preset}" 预设` };
}
async getPresets(): Promise<ServicePreset[]> {
return [
{ id: 'minimal', name: '最小模式', description: '仅启动核心服务', serviceCount: 10 },
{ id: 'standard', name: '标准模式', description: '启动默认启用的服务', serviceCount: 20 },
{ id: 'development', name: '开发模式', description: '核心+业务服务', serviceCount: 30 },
{ id: 'full', name: '完整模式', description: '启动所有服务', serviceCount: 100 },
];
}
async getCategories() {
return {
CORE: { label: '核心服务', color: 'blue' },
BUSINESS: { label: '业务服务', color: 'green' },
TELEMETRY: { label: '遥测服务', color: 'orange' },
SECURITY: { label: '安全服务', color: 'red' },
NETWORK: { label: '网络服务', color: 'purple' },
AI: { label: 'AI服务', color: 'cyan' },
};
}
}
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const serviceManagerDataSource: ServiceManagerDataSource = useMock
? new ServiceManagerMockDataSource()
: new ServiceManagerApiDataSource();

View File

@@ -1,7 +1,6 @@
/**
* [MOCK-SETTINGS] Settings模块DataSource
* AI注意: 这是DataSource抽象层实
* 仅在USE_MOCK=true时启用Mock
* AI注意: 这是DataSource抽象层实<EFBFBD>? * 仅在USE_MOCK=true时启用Mock
*/
export interface CostTemplate {
@@ -146,7 +145,37 @@ export interface User {
parentId?: string;
createdAt: string;
lastLoginAt?: string;
lastLogin?: string; // 与 lastLoginAt 同义
lastLogin?: string;
}
export interface ConfigCategory {
id: string;
name: string;
key: string;
description?: string;
parentId?: string | null;
order: number;
createdAt: string;
}
export interface ConfigChangeLog {
id: string;
configKey: string;
oldValue: string;
newValue: string;
changedBy: string;
changedAt: string;
reason?: string;
}
export interface Tenant {
id: string;
name: string;
key: string;
status: 'active' | 'inactive';
plan: string;
createdAt: string;
expiresAt?: string;
}
export interface ISettingsDataSource {
@@ -422,5 +451,5 @@ class ApiSettingsDataSource implements ISettingsDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const settingsDataSource: ISettingsDataSource = useMock ? new MockSettingsDataSource() : new ApiSettingsDataSource();

View File

@@ -149,7 +149,6 @@ class MockShopReportDataSource implements IShopReportDataSource {
{ id: 'shop-005', name: '店铺E', platform: 'TIKTOK' },
];
// 生成模拟报表
const reportTypes: ReportType[] = ['SALES', 'PROFIT', 'ORDER'];
const timeDimensions: TimeDimension[] = ['DAILY', 'WEEKLY', 'MONTHLY'];
@@ -323,7 +322,7 @@ class MockShopReportDataSource implements IShopReportDataSource {
}
class ApiShopReportDataSource implements IShopReportDataSource {
private baseUrl = '/api/shop-reports';
private baseUrl = '/api/v1/shop-reports';
async generateReport(params: {
tenant_id: string;
@@ -386,7 +385,7 @@ class ApiShopReportDataSource implements IShopReportDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const shopReportDataSource: IShopReportDataSource = useMock
? new MockShopReportDataSource()
: new ApiShopReportDataSource();

View File

@@ -289,7 +289,7 @@ class ApiStoreCreationDataSource implements IStoreCreationDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const storeCreationDataSource: IStoreCreationDataSource = useMock
? new MockStoreCreationDataSource()
: new ApiStoreCreationDataSource();

View File

@@ -100,5 +100,5 @@ class ApiSuppliersDataSource implements ISuppliersDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const suppliersDataSource: ISuppliersDataSource = useMock ? new MockSuppliersDataSource() : new ApiSuppliersDataSource();

View File

@@ -86,5 +86,5 @@ class ApiTaskCenterDataSource implements ITaskCenterDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const taskCenterDataSource: ITaskCenterDataSource = useMock ? new MockTaskCenterDataSource() : new ApiTaskCenterDataSource();

View File

@@ -147,7 +147,7 @@ class ApiUnifiedFulfillmentDataSource implements IUnifiedFulfillmentDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const unifiedFulfillmentDataSource: IUnifiedFulfillmentDataSource = useMock
? new MockUnifiedFulfillmentDataSource()
: new ApiUnifiedFulfillmentDataSource();

View File

@@ -1,8 +1,6 @@
/**
* [MOCK] 用户资产数据
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
* [MOCK] 用户资产数据<EFBFBD><EFBFBD>? * AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启<E697B6><E590AF>? */
export type MemberLevel = 'BRONZE' | 'SILVER' | 'GOLD' | 'PLATINUM' | 'DIAMOND';
@@ -12,15 +10,15 @@ export interface UserAsset {
userId: string;
userName: string;
email: string;
userEmail?: string; // email 同义
userEmail?: string; // <EFBFBD><EFBFBD>?email 同义
memberLevel: MemberLevel;
points: number;
memberScore?: number; // points 同义
memberScore?: number; // <EFBFBD><EFBFBD>?points 同义
totalSpent: number;
availableBalance: number;
availablePoints?: number; // availableBalance 同义
availablePoints?: number; // <EFBFBD><EFBFBD>?availableBalance 同义
frozenBalance: number;
frozenPoints?: number; // frozenBalance 同义
frozenPoints?: number; // <EFBFBD><EFBFBD>?frozenBalance 同义
cashbackBalance?: number;
couponCount?: number;
totalOrders: number;
@@ -63,13 +61,13 @@ export interface PointsRecord {
source: string;
description: string;
createdAt: string;
// 额外字段,用PointsManage 页面
// 额外字段,用<EFBFBD><EFBFBD>?PointsManage 页面
tenantId?: string;
shopId?: string;
traceId?: string;
businessType?: 'TOC' | 'TOB';
points?: number; // amount 同义
sourceType?: string; // source 同义
points?: number; // <EFBFBD><EFBFBD>?amount 同义
sourceType?: string; // <EFBFBD><EFBFBD>?source 同义
status?: 'PENDING' | 'CONFIRMED' | 'FROZEN' | 'EXPIRED' | 'CANCELLED';
expiredAt?: string;
sourceId?: string;
@@ -295,7 +293,7 @@ class ApiUserAssetDataSource implements IUserAssetDataSource {
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const userAssetDataSource: IUserAssetDataSource = useMock
? new MockUserAssetDataSource()
: new ApiUserAssetDataSource();

View File

@@ -6,7 +6,6 @@
import { User } from '../types/user';
// 用户数据接口
export interface UserDataSource {
list(params?: {
page?: number;
@@ -39,7 +38,6 @@ export interface UserDataSource {
} | null>;
}
// 用户DataSource实现
export class UserDataSourceImpl implements UserDataSource {
async list(params?: {
page?: number;
@@ -47,8 +45,6 @@ export class UserDataSourceImpl implements UserDataSource {
role?: string;
status?: string;
}): Promise<{ data: User[]; total: number }> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockUsers: User[] = [
{
id: 'cust_1',
@@ -105,8 +101,6 @@ export class UserDataSourceImpl implements UserDataSource {
}
async get(id: string): Promise<User | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockUsers: User[] = [
{
id: 'cust_1',
@@ -145,8 +139,6 @@ export class UserDataSourceImpl implements UserDataSource {
}
async create(user: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const newUser: User = {
...user,
id: `user_${Date.now()}`,
@@ -158,8 +150,6 @@ export class UserDataSourceImpl implements UserDataSource {
}
async update(id: string, user: Partial<User>): Promise<User | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingUser = await this.get(id);
if (!existingUser) {
return null;
@@ -175,14 +165,10 @@ export class UserDataSourceImpl implements UserDataSource {
}
async delete(id: string): Promise<boolean> {
// 这里应该调用实际的API
// 暂时返回Mock数据
return true;
}
async updateStatus(id: string, status: string): Promise<User | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const existingUser = await this.get(id);
if (!existingUser) {
return null;
@@ -198,8 +184,6 @@ export class UserDataSourceImpl implements UserDataSource {
}
async search(keyword: string): Promise<User[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockUsers: User[] = [
{
id: 'cust_1',
@@ -241,8 +225,6 @@ export class UserDataSourceImpl implements UserDataSource {
}
async getByRole(role: string): Promise<User[]> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const mockUsers: User[] = [
{
id: 'cust_1',
@@ -287,8 +269,6 @@ export class UserDataSourceImpl implements UserDataSource {
lastLogin: Date;
};
} | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
const user = await this.get(userId);
if (!user) {
return null;
@@ -307,5 +287,4 @@ export class UserDataSourceImpl implements UserDataSource {
}
}
// 导出DataSource实例
export const userDataSource = new UserDataSourceImpl();