/** * [MOCK-AFTER-001] AfterSales数据源抽象层 * AI注意: 这是数据源抽象层,业务组件通过此层获取数据 * 仅在REACT_APP_USE_MOCK=true时启用Mock * * @module services/afterSalesDataSource * @created 2026-03-19 */ import { IDataSource } from '@/types/datasource'; // ============================================ // 类型定义 // ============================================ export interface OrderItem { id: string; skuId: string; productName: string; quantity: number; unitPrice: number; totalPrice: number; } export interface ReturnApplication { id: string; orderId: string; returnReason: string; returnDescription: string; returnItems: string[]; images: string[]; contactPhone: string; status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'PROCESSING' | 'COMPLETED' | 'CANCELLED'; createdAt: string; updatedAt: string; } export interface AfterSalesQueryParams { orderId?: string; status?: string; startDate?: string; endDate?: string; } // ============================================ // AfterSales专用接口 // ============================================ export interface IAfterSalesDataSource { fetchOrderItems(orderId: string): Promise; submitReturn(data: Partial): Promise; fetchReturnApplications(params?: AfterSalesQueryParams): Promise; fetchReturnDetail(id: string): Promise; updateReturnStatus(id: string, status: string): Promise; } // ============================================ // API实现 // ============================================ class ApiAfterSalesDataSource implements IAfterSalesDataSource { async fetchOrderItems(orderId: string): Promise { const response = await fetch(`/api/v1/orders/${orderId}/items`); const result = await response.json(); return result.data; } async submitReturn(data: Partial): Promise { const response = await fetch('/api/v1/returns', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); const result = await response.json(); return result.data; } async fetchReturnApplications(params?: AfterSalesQueryParams): Promise { const query = new URLSearchParams(params as any).toString(); const response = await fetch(`/api/v1/returns?${query}`); const result = await response.json(); return result.data; } async fetchReturnDetail(id: string): Promise { const response = await fetch(`/api/v1/returns/${id}`); const result = await response.json(); return result.data; } async updateReturnStatus(id: string, status: string): Promise { const response = await fetch(`/api/v1/returns/${id}/status`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status }), }); const result = await response.json(); return result.data; } } // ============================================ // Mock实现 // ============================================ /** * [MOCK] AfterSales Mock数据源 * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在REACT_APP_USE_MOCK=true时启用 */ class MockAfterSalesDataSource implements IAfterSalesDataSource { readonly __MOCK__ = true as const; readonly __MOCK_NAME__ = 'MockAfterSalesDataSource'; private mockOrderItems: Record = { 'order-001': [ { id: 'item_001', skuId: 'SKU_001', productName: 'Wireless Bluetooth Headphones', quantity: 2, unitPrice: 29.99, totalPrice: 59.98 }, { id: 'item_002', skuId: 'SKU_002', productName: 'USB-C Charging Cable', quantity: 5, unitPrice: 4.99, totalPrice: 24.95 }, ], }; private mockReturns: ReturnApplication[] = [ { id: 'RET-001', orderId: 'order-001', returnReason: 'DEFECTIVE', returnDescription: 'Product arrived damaged', returnItems: ['item_001'], images: [], contactPhone: '+1 555-0123', status: 'PENDING', createdAt: '2026-03-18T10:00:00Z', updatedAt: '2026-03-18T10:00:00Z', }, ]; async fetchOrderItems(orderId: string): Promise { await this.simulateDelay(500); return this.mockOrderItems[orderId] || [ { id: 'item_001', skuId: 'SKU_001', productName: 'Wireless Bluetooth Headphones', quantity: 2, unitPrice: 29.99, totalPrice: 59.98 }, { id: 'item_002', skuId: 'SKU_002', productName: 'USB-C Charging Cable', quantity: 5, unitPrice: 4.99, totalPrice: 24.95 }, ]; } async submitReturn(data: Partial): Promise { await this.simulateDelay(1000); const newReturn: ReturnApplication = { id: `RET-${Date.now()}`, orderId: data.orderId || '', returnReason: data.returnReason || '', returnDescription: data.returnDescription || '', returnItems: data.returnItems || [], images: data.images || [], contactPhone: data.contactPhone || '', status: 'PENDING', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; this.mockReturns.push(newReturn); return newReturn; } async fetchReturnApplications(params?: AfterSalesQueryParams): Promise { await this.simulateDelay(300); let result = [...this.mockReturns]; if (params?.orderId) { result = result.filter(r => r.orderId === params.orderId); } if (params?.status) { result = result.filter(r => r.status === params.status); } return result; } async fetchReturnDetail(id: string): Promise { await this.simulateDelay(200); const ret = this.mockReturns.find(r => r.id === id); return ret ? { ...ret } : null; } async updateReturnStatus(id: string, status: string): Promise { await this.simulateDelay(300); const index = this.mockReturns.findIndex(r => r.id === id); if (index === -1) throw new Error('Return application not found'); this.mockReturns[index] = { ...this.mockReturns[index], status: status as ReturnApplication['status'], updatedAt: new Date().toISOString(), }; return this.mockReturns[index]; } private simulateDelay(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } // Mock特定方法 reset(): void { this.mockReturns = [ { id: 'RET-001', orderId: 'order-001', returnReason: 'DEFECTIVE', returnDescription: 'Product arrived damaged', returnItems: ['item_001'], images: [], contactPhone: '+1 555-0123', status: 'PENDING', createdAt: '2026-03-18T10:00:00Z', updatedAt: '2026-03-18T10:00:00Z', }, ]; } getMockData(): ReturnApplication[] { return this.mockReturns; } } // ============================================ // 导出数据源实例 // ============================================ const useMock = process.env.REACT_APP_USE_MOCK === 'true'; export const afterSalesDataSource: IAfterSalesDataSource = useMock ? new MockAfterSalesDataSource() : new ApiAfterSalesDataSource(); export const __MOCK__ = useMock; export const __DATA_SOURCE_TYPE__ = useMock ? 'mock' : 'api';