/** * [MOCK-INVENTORY] Inventory模块DataSource */ export interface InventoryItem { id: string; sku: string; productName: string; quantity: number; availableQty: number; reservedQty: number; warehouseId: string; warehouseName: string; status: 'in_stock' | 'low_stock' | 'out_of_stock'; reorderPoint: number; lastRestocked: string; } export interface Warehouse { id: string; name: string; location: string; capacity: number; usedCapacity: number; status: 'active' | 'inactive' | 'maintenance'; contact: string; phone: string; } export interface InventoryForecast { sku: string; productName: string; currentStock: number; avgDailySales: number; daysOfStock: number; suggestedReorderQty: number; estimatedStockoutDate: string; confidence: number; } export interface IInventoryDataSource { fetchInventory(params?: { warehouseId?: string; status?: string }): Promise; updateInventory(id: string, data: Partial): Promise; fetchWarehouses(): Promise; saveWarehouse(data: Partial): Promise; deleteWarehouse(id: string): Promise; fetchForecast(): Promise; adjustStock(id: string, quantity: number, reason: string): Promise; } class MockInventoryDataSource implements IInventoryDataSource { async fetchInventory(params?: { warehouseId?: string; status?: string }): Promise { return [ { id: 'inv_001', sku: 'SKU-001', productName: 'Wireless Headphones', quantity: 500, availableQty: 450, reservedQty: 50, warehouseId: 'wh_001', warehouseName: 'US East', status: 'in_stock', reorderPoint: 100, lastRestocked: '2026-03-15' }, { id: 'inv_002', sku: 'SKU-002', productName: 'USB-C Cable', quantity: 80, availableQty: 75, reservedQty: 5, warehouseId: 'wh_001', warehouseName: 'US East', status: 'low_stock', reorderPoint: 100, lastRestocked: '2026-03-10' }, { id: 'inv_003', sku: 'SKU-003', productName: 'Phone Case', quantity: 0, availableQty: 0, reservedQty: 0, warehouseId: 'wh_002', warehouseName: 'US West', status: 'out_of_stock', reorderPoint: 50, lastRestocked: '2026-03-01' }, { id: 'inv_004', sku: 'SKU-004', productName: 'Smart Watch', quantity: 200, availableQty: 180, reservedQty: 20, warehouseId: 'wh_002', warehouseName: 'US West', status: 'in_stock', reorderPoint: 50, lastRestocked: '2026-03-12' }, ]; } async updateInventory(id: string, data: Partial): Promise { return { id, ...data } as InventoryItem; } async fetchWarehouses(): Promise { return [ { id: 'wh_001', name: 'US East Warehouse', location: 'New Jersey, USA', capacity: 10000, usedCapacity: 6500, status: 'active', contact: 'John Smith', phone: '+1-555-0100' }, { id: 'wh_002', name: 'US West Warehouse', location: 'California, USA', capacity: 8000, usedCapacity: 4200, status: 'active', contact: 'Jane Doe', phone: '+1-555-0200' }, { id: 'wh_003', name: 'EU Warehouse', location: 'Frankfurt, Germany', capacity: 5000, usedCapacity: 2800, status: 'active', contact: 'Hans Mueller', phone: '+49-555-0300' }, ]; } async saveWarehouse(data: Partial): Promise { return { ...data, id: data.id || `wh_${Date.now()}` } as Warehouse; } async deleteWarehouse(id: string): Promise {} async fetchForecast(): Promise { return [ { sku: 'SKU-001', productName: 'Wireless Headphones', currentStock: 500, avgDailySales: 25, daysOfStock: 20, suggestedReorderQty: 750, estimatedStockoutDate: '2026-04-07', confidence: 0.92 }, { sku: 'SKU-002', productName: 'USB-C Cable', currentStock: 80, avgDailySales: 15, daysOfStock: 5.3, suggestedReorderQty: 450, estimatedStockoutDate: '2026-03-23', confidence: 0.88 }, { sku: 'SKU-004', productName: 'Smart Watch', currentStock: 200, avgDailySales: 8, daysOfStock: 25, suggestedReorderQty: 240, estimatedStockoutDate: '2026-04-12', confidence: 0.95 }, ]; } async adjustStock(id: string, quantity: number, reason: string): Promise {} } class ApiInventoryDataSource implements IInventoryDataSource { private baseUrl = '/api/inventory'; async fetchInventory(params?: { warehouseId?: string; status?: string }): Promise { const query = new URLSearchParams(params as any).toString(); const res = await fetch(`${this.baseUrl}?${query}`); return res.json(); } async updateInventory(id: string, data: Partial): Promise { const res = await fetch(`${this.baseUrl}/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); return res.json(); } async fetchWarehouses(): Promise { const res = await fetch(`${this.baseUrl}/warehouses`); return res.json(); } async saveWarehouse(data: Partial): Promise { const res = await fetch(`${this.baseUrl}/warehouses`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); return res.json(); } async deleteWarehouse(id: string): Promise { await fetch(`${this.baseUrl}/warehouses/${id}`, { method: 'DELETE' }); } async fetchForecast(): Promise { const res = await fetch(`${this.baseUrl}/forecast`); return res.json(); } async adjustStock(id: string, quantity: number, reason: string): Promise { await fetch(`${this.baseUrl}/${id}/adjust`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ quantity, reason }) }); } } const useMock = process.env.REACT_APP_USE_MOCK === 'true'; export const inventoryDataSource: IInventoryDataSource = useMock ? new MockInventoryDataSource() : new ApiInventoryDataSource();