2026-03-19 01:39:34 +08:00
|
|
|
|
/**
|
2026-03-19 19:08:15 +08:00
|
|
|
|
* [MOCK-010] 库存模块DataSource
|
|
|
|
|
|
* AI注意: 这是Mock实现,不是真实业务逻辑
|
|
|
|
|
|
* 仅在USE_MOCK=true时启用
|
2026-03-19 01:39:34 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
import { Inventory } from '../types/inventory';
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
// 库存数据接口
|
|
|
|
|
|
export interface InventoryDataSource {
|
|
|
|
|
|
list(params?: {
|
|
|
|
|
|
page?: number;
|
|
|
|
|
|
pageSize?: number;
|
|
|
|
|
|
productId?: string;
|
|
|
|
|
|
status?: string;
|
|
|
|
|
|
warehouseId?: string;
|
|
|
|
|
|
}): Promise<{ data: Inventory[]; total: number }>;
|
|
|
|
|
|
|
|
|
|
|
|
get(id: string): Promise<Inventory | null>;
|
|
|
|
|
|
|
|
|
|
|
|
create(inventory: Omit<Inventory, 'id' | 'createdAt' | 'updatedAt'>): Promise<Inventory>;
|
|
|
|
|
|
|
|
|
|
|
|
update(id: string, inventory: Partial<Inventory>): Promise<Inventory | null>;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
updateStock(id: string, quantity: number): Promise<Inventory | null>;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
getByProductId(productId: string): Promise<Inventory[]>;
|
|
|
|
|
|
|
|
|
|
|
|
getByWarehouseId(warehouseId: string): Promise<Inventory[]>;
|
|
|
|
|
|
|
|
|
|
|
|
getLowStockAlerts(threshold: number): Promise<Inventory[]>;
|
|
|
|
|
|
|
|
|
|
|
|
getInventoryStatistics(): Promise<{
|
|
|
|
|
|
totalItems: number;
|
|
|
|
|
|
totalStock: number;
|
|
|
|
|
|
lowStockItems: number;
|
|
|
|
|
|
outOfStockItems: number;
|
|
|
|
|
|
warehouseDistribution: Record<string, number>;
|
|
|
|
|
|
}>;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
// 库存DataSource实现
|
|
|
|
|
|
export class InventoryDataSourceImpl implements InventoryDataSource {
|
|
|
|
|
|
async list(params?: {
|
|
|
|
|
|
page?: number;
|
|
|
|
|
|
pageSize?: number;
|
|
|
|
|
|
productId?: string;
|
|
|
|
|
|
status?: string;
|
|
|
|
|
|
warehouseId?: string;
|
|
|
|
|
|
}): Promise<{ data: Inventory[]; total: number }> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: '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: '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: '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: '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'),
|
|
|
|
|
|
},
|
2026-03-19 01:39:34 +08:00
|
|
|
|
];
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
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,
|
|
|
|
|
|
};
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async get(id: string): Promise<Inventory | null> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: 'in_stock',
|
|
|
|
|
|
warehouseId: 'warehouse_1',
|
|
|
|
|
|
warehouseName: '北京仓库',
|
|
|
|
|
|
lastStockUpdate: new Date('2026-03-11'),
|
|
|
|
|
|
createdAt: new Date('2026-02-02'),
|
|
|
|
|
|
updatedAt: new Date('2026-03-11'),
|
|
|
|
|
|
},
|
2026-03-19 01:39:34 +08:00
|
|
|
|
];
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
const inventory = mockInventory.find(i => i.id === id);
|
|
|
|
|
|
return inventory || null;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async create(inventory: Omit<Inventory, 'id' | 'createdAt' | 'updatedAt'>): Promise<Inventory> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const newInventory: Inventory = {
|
|
|
|
|
|
...inventory,
|
|
|
|
|
|
id: `inv_${Date.now()}`,
|
|
|
|
|
|
createdAt: new Date(),
|
|
|
|
|
|
updatedAt: new Date(),
|
|
|
|
|
|
};
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
return newInventory;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async update(id: string, inventory: Partial<Inventory>): Promise<Inventory | null> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const existingInventory = await this.get(id);
|
|
|
|
|
|
if (!existingInventory) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
const updatedInventory: Inventory = {
|
|
|
|
|
|
...existingInventory,
|
|
|
|
|
|
...inventory,
|
|
|
|
|
|
updatedAt: new Date(),
|
|
|
|
|
|
};
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
return updatedInventory;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async updateStock(id: string, quantity: number): Promise<Inventory | null> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const existingInventory = await this.get(id);
|
|
|
|
|
|
if (!existingInventory) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const newQuantity = existingInventory.quantity + quantity;
|
|
|
|
|
|
let status: 'in_stock' | 'low_stock' | 'out_of_stock';
|
|
|
|
|
|
|
|
|
|
|
|
if (newQuantity <= 0) {
|
|
|
|
|
|
status = 'out_of_stock';
|
|
|
|
|
|
} else if (newQuantity < existingInventory.threshold) {
|
|
|
|
|
|
status = 'low_stock';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
status = 'in_stock';
|
|
|
|
|
|
}
|
2026-03-19 01:39:34 +08:00
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
const updatedInventory: Inventory = {
|
|
|
|
|
|
...existingInventory,
|
|
|
|
|
|
quantity: newQuantity,
|
|
|
|
|
|
status,
|
|
|
|
|
|
lastStockUpdate: new Date(),
|
|
|
|
|
|
updatedAt: new Date(),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return updatedInventory;
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async getByProductId(productId: string): Promise<Inventory[]> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: '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);
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async getByWarehouseId(warehouseId: string): Promise<Inventory[]> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: '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: '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);
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async getLowStockAlerts(threshold: number): Promise<Inventory[]> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: '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: '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);
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
async getInventoryStatistics(): Promise<{
|
|
|
|
|
|
totalItems: number;
|
|
|
|
|
|
totalStock: number;
|
|
|
|
|
|
lowStockItems: number;
|
|
|
|
|
|
outOfStockItems: number;
|
|
|
|
|
|
warehouseDistribution: Record<string, number>;
|
|
|
|
|
|
}> {
|
|
|
|
|
|
// 这里应该调用实际的API
|
|
|
|
|
|
// 暂时返回Mock数据
|
|
|
|
|
|
const mockInventory: Inventory[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 'inv_1',
|
|
|
|
|
|
productId: '1',
|
|
|
|
|
|
productName: '智能手表',
|
|
|
|
|
|
quantity: 100,
|
|
|
|
|
|
threshold: 20,
|
|
|
|
|
|
status: '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: '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: '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: '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: '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 === 'low_stock').length;
|
|
|
|
|
|
const outOfStockItems = mockInventory.filter(i => i.status === 'out_of_stock').length;
|
|
|
|
|
|
|
|
|
|
|
|
const warehouseDistribution: Record<string, number> = {};
|
|
|
|
|
|
mockInventory.forEach(item => {
|
|
|
|
|
|
warehouseDistribution[item.warehouseName] = (warehouseDistribution[item.warehouseName] || 0) + item.quantity;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
totalItems,
|
|
|
|
|
|
totalStock,
|
|
|
|
|
|
lowStockItems,
|
|
|
|
|
|
outOfStockItems,
|
|
|
|
|
|
warehouseDistribution,
|
|
|
|
|
|
};
|
2026-03-19 01:39:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-19 19:08:15 +08:00
|
|
|
|
// 导出DataSource实例
|
|
|
|
|
|
export const inventoryDataSource = new InventoryDataSourceImpl();
|