Files
makemd/dashboard/src/services/inventoryDataSource.ts
wurenzhi eafa1bbe94 feat: 添加货币和汇率管理功能
refactor: 重构前端路由和登录逻辑

docs: 更新业务闭环、任务和架构文档

style: 调整代码格式和文件结构

chore: 更新依赖项和配置文件
2026-03-19 19:08:15 +08:00

473 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* [MOCK-010] 库存模块DataSource
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
import { Inventory } from '../types/inventory';
// 库存数据接口
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>;
updateStock(id: string, quantity: number): Promise<Inventory | null>;
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>;
}>;
}
// 库存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'),
},
];
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<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'),
},
];
const inventory = mockInventory.find(i => i.id === id);
return inventory || null;
}
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(),
};
return newInventory;
}
async update(id: string, inventory: Partial<Inventory>): Promise<Inventory | null> {
// 这里应该调用实际的API
// 暂时返回Mock数据
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<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';
}
const updatedInventory: Inventory = {
...existingInventory,
quantity: newQuantity,
status,
lastStockUpdate: new Date(),
updatedAt: new Date(),
};
return updatedInventory;
}
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);
}
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);
}
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);
}
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,
};
}
}
// 导出DataSource实例
export const inventoryDataSource = new InventoryDataSourceImpl();