/** * [MOCK-010] 库存模块DataSource * AI注意: 这是Mock实现,不是真实业务逻辑 * 仅在USE_MOCK=true时启用 */ import { Inventory, InventoryStatus } from '../types/inventory'; export interface Warehouse { id: string; name: string; code: string; address: string; city: string; country: string; capacity: number; currentUsage: number; status: 'active' | 'inactive' | 'maintenance'; manager: string; phone: string; email: string; createdAt: string; updatedAt: string; } export interface InventoryForecast { id: string; productId: string; productName: string; sku: string; currentStock: number; forecastedDemand: number; recommendedOrder: number; leadTime: number; riskLevel: 'low' | 'medium' | 'high'; date: string; } export interface InventoryQueryParams { productId?: string; status?: InventoryStatus; warehouseId?: string; page?: number; pageSize?: number; } export interface InventoryDataSource { list(params?: InventoryQueryParams): Promise<{ data: Inventory[]; total: number }>; get(id: string): Promise; create(inventory: Omit): Promise; update(id: string, inventory: Partial): Promise; updateStock(id: string, quantity: number): Promise; getByProductId(productId: string): Promise; getByWarehouseId(warehouseId: string): Promise; getLowStockAlerts(threshold: number): Promise; getInventoryStatistics(): Promise<{ totalItems: number; totalStock: number; lowStockItems: number; outOfStockItems: number; warehouseDistribution: Record; }>; fetchWarehouses(): Promise; getInventoryForecasts(): Promise; } export class InventoryDataSourceImpl implements InventoryDataSource { async list(params?: InventoryQueryParams): Promise<{ data: Inventory[]; total: number }> { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_2', productId: '2', productName: '无线耳机', quantity: 200, threshold: 30, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-11'), createdAt: new Date('2026-02-02'), updatedAt: new Date('2026-03-11'), }, { id: 'inv_3', productId: '3', productName: '运动鞋', quantity: 150, threshold: 25, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-12'), createdAt: new Date('2026-02-03'), updatedAt: new Date('2026-03-12'), }, { id: 'inv_4', productId: '4', productName: '智能手机', quantity: 5, threshold: 10, status: InventoryStatus.LOW_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-09'), createdAt: new Date('2026-02-04'), updatedAt: new Date('2026-03-09'), }, { id: 'inv_5', productId: '5', productName: '平板电脑', quantity: 0, threshold: 15, status: InventoryStatus.OUT_OF_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-08'), createdAt: new Date('2026-02-05'), updatedAt: new Date('2026-03-08'), }, ]; let filteredInventory = mockInventory; if (params?.productId) { filteredInventory = filteredInventory.filter(i => i.productId === params.productId); } if (params?.status) { filteredInventory = filteredInventory.filter(i => i.status === params.status); } if (params?.warehouseId) { filteredInventory = filteredInventory.filter(i => i.warehouseId === params.warehouseId); } const page = params?.page || 1; const pageSize = params?.pageSize || 10; const start = (page - 1) * pageSize; const end = start + pageSize; const paginatedInventory = filteredInventory.slice(start, end); return { data: paginatedInventory, total: filteredInventory.length, }; } async get(id: string): Promise { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_2', productId: '2', productName: '无线耳机', quantity: 200, threshold: 30, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-11'), createdAt: new Date('2026-02-02'), updatedAt: new Date('2026-03-11'), }, ]; const inventory = mockInventory.find(i => i.id === id); return inventory || null; } async create(inventory: Omit): Promise { const newInventory: Inventory = { ...inventory, id: `inv_${Date.now()}`, createdAt: new Date(), updatedAt: new Date(), }; return newInventory; } async update(id: string, inventory: Partial): Promise { const existingInventory = await this.get(id); if (!existingInventory) { return null; } const updatedInventory: Inventory = { ...existingInventory, ...inventory, updatedAt: new Date(), }; return updatedInventory; } async updateStock(id: string, quantity: number): Promise { const existingInventory = await this.get(id); if (!existingInventory) { return null; } const newQuantity = existingInventory.quantity + quantity; let status: InventoryStatus; if (newQuantity <= 0) { status = InventoryStatus.OUT_OF_STOCK; } else if (newQuantity < existingInventory.threshold) { status = InventoryStatus.LOW_STOCK; } else { status = InventoryStatus.IN_STOCK; } const updatedInventory: Inventory = { ...existingInventory, quantity: newQuantity, status, lastStockUpdate: new Date(), updatedAt: new Date(), }; return updatedInventory; } async getByProductId(productId: string): Promise { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_2', productId: '2', productName: '无线耳机', quantity: 200, threshold: 30, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-11'), createdAt: new Date('2026-02-02'), updatedAt: new Date('2026-03-11'), }, ]; return mockInventory.filter(i => i.productId === productId); } async getByWarehouseId(warehouseId: string): Promise { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_2', productId: '2', productName: '无线耳机', quantity: 200, threshold: 30, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-11'), createdAt: new Date('2026-02-02'), updatedAt: new Date('2026-03-11'), }, { id: 'inv_3', productId: '3', productName: '运动鞋', quantity: 150, threshold: 25, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-12'), createdAt: new Date('2026-02-03'), updatedAt: new Date('2026-03-12'), }, ]; return mockInventory.filter(i => i.warehouseId === warehouseId); } async getLowStockAlerts(threshold: number): Promise { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_4', productId: '4', productName: '智能手机', quantity: 5, threshold: 10, status: InventoryStatus.LOW_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-09'), createdAt: new Date('2026-02-04'), updatedAt: new Date('2026-03-09'), }, { id: 'inv_5', productId: '5', productName: '平板电脑', quantity: 0, threshold: 15, status: InventoryStatus.OUT_OF_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-08'), createdAt: new Date('2026-02-05'), updatedAt: new Date('2026-03-08'), }, ]; return mockInventory.filter(i => i.quantity <= threshold); } async getInventoryStatistics(): Promise<{ totalItems: number; totalStock: number; lowStockItems: number; outOfStockItems: number; warehouseDistribution: Record; }> { const mockInventory: Inventory[] = [ { id: 'inv_1', productId: '1', productName: '智能手表', quantity: 100, threshold: 20, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-10'), createdAt: new Date('2026-02-01'), updatedAt: new Date('2026-03-10'), }, { id: 'inv_2', productId: '2', productName: '无线耳机', quantity: 200, threshold: 30, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-11'), createdAt: new Date('2026-02-02'), updatedAt: new Date('2026-03-11'), }, { id: 'inv_3', productId: '3', productName: '运动鞋', quantity: 150, threshold: 25, status: InventoryStatus.IN_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-12'), createdAt: new Date('2026-02-03'), updatedAt: new Date('2026-03-12'), }, { id: 'inv_4', productId: '4', productName: '智能手机', quantity: 5, threshold: 10, status: InventoryStatus.LOW_STOCK, warehouseId: 'warehouse_1', warehouseName: '北京仓库', lastStockUpdate: new Date('2026-03-09'), createdAt: new Date('2026-02-04'), updatedAt: new Date('2026-03-09'), }, { id: 'inv_5', productId: '5', productName: '平板电脑', quantity: 0, threshold: 15, status: InventoryStatus.OUT_OF_STOCK, warehouseId: 'warehouse_2', warehouseName: '上海仓库', lastStockUpdate: new Date('2026-03-08'), createdAt: new Date('2026-02-05'), updatedAt: new Date('2026-03-08'), }, ]; const totalItems = mockInventory.length; const totalStock = mockInventory.reduce((sum, item) => sum + item.quantity, 0); const lowStockItems = mockInventory.filter(i => i.status === InventoryStatus.LOW_STOCK).length; const outOfStockItems = mockInventory.filter(i => i.status === InventoryStatus.OUT_OF_STOCK).length; const warehouseDistribution: Record = {}; mockInventory.forEach(item => { if (item.warehouseName) { warehouseDistribution[item.warehouseName] = (warehouseDistribution[item.warehouseName] || 0) + item.quantity; } }); return { totalItems, totalStock, lowStockItems, outOfStockItems, warehouseDistribution, }; } async fetchWarehouses(): Promise { return [ { id: 'warehouse_1', name: '北京仓库', code: 'BJ-WH-001', address: '北京市朝阳区建国路88号', city: '北京', country: '中国', capacity: 10000, currentUsage: 7500, status: 'active', manager: '张三', phone: '010-12345678', email: 'zhangsan@example.com', createdAt: '2026-01-01', updatedAt: '2026-03-15', }, { id: 'warehouse_2', name: '上海仓库', code: 'SH-WH-001', address: '上海市浦东新区张江路100号', city: '上海', country: '中国', capacity: 15000, currentUsage: 12000, status: 'active', manager: '李四', phone: '021-87654321', email: 'lisi@example.com', createdAt: '2026-01-15', updatedAt: '2026-03-16', }, ]; } async getInventoryForecasts(): Promise { return [ { id: 'forecast_1', productId: '1', productName: '智能手表', sku: 'WATCH-001', currentStock: 100, forecastedDemand: 150, recommendedOrder: 50, leadTime: 7, riskLevel: 'low', date: '2026-03-21', }, { id: 'forecast_2', productId: '2', productName: '无线耳机', sku: 'EARPHONE-001', currentStock: 200, forecastedDemand: 180, recommendedOrder: 0, leadTime: 5, riskLevel: 'low', date: '2026-03-21', }, { id: 'forecast_3', productId: '4', productName: '智能手机', sku: 'PHONE-001', currentStock: 5, forecastedDemand: 50, recommendedOrder: 45, leadTime: 10, riskLevel: 'high', date: '2026-03-21', }, ]; } } export const inventoryDataSource = new InventoryDataSourceImpl();