个人编程网站

进销存(JXC)软件开发技术积累与分享

进销存系统智能库存分布与多仓库调拨优化

引言

对于拥有多个仓库的进销存企业,如何合理分配库存、优化调拨路线、降低库存成本是一个非常关键的问题。本文介绍智能库存分布与多仓库调拨优化的实现方案。

问题分析

多仓库库存管理面临的主要挑战:

智能库存分配模型

// 智能库存分配服务
class SmartInventoryAllocation {
  constructor(warehouseModel, inventoryModel, demandModel) {
    this.Warehouse = warehouseModel;
    this.Inventory = inventoryModel;
    this.Demand = demandModel;
  }

  // 计算各仓库最优库存分配
  async calculateOptimalAllocation(productId, totalStock) {
    // 1. 获取需求预测
    const demandForecast = await this.getDemandForecast(productId);

    // 2. 获取各仓库属性
    const warehouses = await this.Warehouse.findAll();

    // 3. 计算各仓库权重
    const warehouseWeights = this.calculateWarehouseWeights(warehouses, demandForecast);

    // 4. 考虑安全库存约束
    const allocations = this.optimizeWithConstraints(
      warehouseWeights,
      totalStock,
      warehouses
    );

    return allocations;
  }

  // 根据需求预测计算仓库权重
  calculateWarehouseWeights(warehouses, demandForecast) {
    return warehouses.map(wh => {
      // 需求优先级(基于需求预测)
      const demandScore = demandForecast.byRegion[wh.region] || 0;

      // 仓库等级得分
      const levelScore = { A: 100, B: 80, C: 60, D: 40 }[wh.level] || 60;

      // 距离得分(越近越容易配送)
      const distanceScore = 100 - (wh.avgDeliveryDays * 10);

      // 成本得分(运营成本越低越好)
      const costScore = 100 - (wh.operatingCostRate * 100);

      // 能力得分(仓库容量和吞吐能力)
      const capacityScore = Math.min(100, (wh.availableCapacity / wh.totalCapacity) * 100);

      // 综合权重计算
      const weight = (
        demandScore * 0.35 +
        levelScore * 0.15 +
        distanceScore * 0.20 +
        costScore * 0.15 +
        capacityScore * 0.15
      );

      return { warehouse: wh, weight: Math.max(0, weight) };
    }).sort((a, b) => b.weight - a.weight);
  }

  // 优化分配(带约束)
  optimizeWithConstraints(weightedWarehouses, totalStock, allWarehouses) {
    const allocations = [];
    let remainingStock = totalStock;

    // 安全库存要求
    const safetyStockMap = {};
    for (const wh of allWarehouses) {
      safetyStockMap[wh.id] = wh.minStock || 100;
    }

    // 按权重分配
    const totalWeight = weightedWarehouses.reduce((sum, w) => sum + w.weight, 0);

    for (const { warehouse, weight } of weightedWarehouses) {
      // 计算分配比例
      const ratio = weight / totalWeight;

      // 考虑安全库存
      const safetyStock = safetyStockMap[warehouse.id];
      const currentStock = warehouse.currentStock || 0;
      const minAllocation = Math.max(0, safetyStock - currentStock);

      // 计算建议库存
      const targetStock = Math.floor(totalStock * ratio);
      const allocation = Math.max(minAllocation, targetStock);

      if (allocation <= remainingStock) {
        allocations.push({
          warehouseId: warehouse.id,
          warehouseName: warehouse.name,
          currentStock: currentStock,
          recommendedStock: allocation,
          adjustment: allocation - currentStock,
          priority: weight
        });
        remainingStock -= allocation;
      }
    }

    // 处理剩余库存(分配给权重最高的仓库)
    if (remainingStock > 0 && allocations.length > 0) {
      allocations[0].recommendedStock += remainingStock;
      allocations[0].adjustment += remainingStock;
    }

    return allocations;
  }

  // 获取需求预测
  async getDemandForecast(productId) {
    // 调用需求预测服务
    const forecast = await DemandForecastService.predict(productId, 30);

    return {
      total: forecast.total,
      byRegion: forecast.regionalDemand,
      byWarehouse: forecast.warehouseDemand
    };
  }
}

智能调拨建议算法

// 智能调拨推荐服务
class SmartTransferRecommendation {
  constructor(inventoryModel, transferModel, orderModel) {
    this.Inventory = inventoryModel;
    this.Transfer = transferModel;
    this.Order = orderModel;
  }

  // 生成调拨建议
  async generateRecommendations() {
    const recommendations = [];

    // 1. 基于库存预警生成调拨
    const stockAlerts = await this.checkStockAlerts();
    recommendations.push(...stockAlerts);

    // 2. 基于需求预测生成调拨
    const demandTransfers = await this.checkDemandBasedTransfers();
    recommendations.push(...demandTransfers);

    // 3. 基于库存优化生成调拨
    const optimizationTransfers = await this.checkOptimizationTransfers();
    recommendations.push(...optimizationTransfers);

    // 4. 过滤和排序
    return this.filterAndSortRecommendations(recommendations);
  }

  // 检查库存预警
  async checkStockAlerts() {
    const alerts = [];
    const products = await this.Inventory.getAllProducts();

    for (const product of products) {
      const inventories = await this.Inventory.findByProduct(product.id);

      for (const inv of inventories) {
        // 库存不足预警
        if (inv.quantity <= inv.minStock) {
          // 查找附近有库存的仓库
          const excessWarehouses = inventories.filter(
            i => i.quantity > i.maxStock * 0.7 && i.warehouseId !== inv.warehouseId
          );

          if (excessWarehouses.length > 0) {
            alerts.push({
              type: 'stock_alert',
              priority: 'high',
              fromWarehouse: excessWarehouses[0],
              toWarehouse: inv,
              product: product,
              suggestedQty: inv.minStock - inv.quantity + 50,
              reason: `库存不足预警:${inv.warehouseName}当前库存${inv.quantity},低于最小库存${inv.minStock}`
            });
          }
        }

        // 库存积压预警
        if (inv.quantity >= inv.maxStock) {
          alerts.push({
            type: 'overstock_alert',
            priority: 'medium',
            fromWarehouse: inv,
            toWarehouse: null, // 需要人工决策
            product: product,
            suggestedQty: inv.quantity - inv.maxStock * 0.8,
            reason: `库存积压预警:${inv.warehouseName}当前库存${inv.quantity},超过最大库存${inv.maxStock}`
          });
        }
      }
    }

    return alerts;
  }

  // 基于需求预测的调拨
  async checkDemandBasedTransfers() {
    const transfers = [];
    const products = await this.Inventory.getAllProducts();

    for (const product of products) {
      // 获取未来30天需求预测
      const forecast = await DemandForecastService.predict(product.id, 30);
      const inventories = await this.Inventory.findByProduct(product.id);

      // 计算各仓库预测需求
      for (const inv of inventories) {
        const regionalDemand = forecast.regionalDemand[inv.warehouse.region] || 0;
        const expectedStock = regionalDemand - inv.quantity;

        // 如果预测缺货,调拨优先级高
        if (expectedStock < 0) {
          // 查找过剩仓库
          const sourceWarehouses = inventories.filter(
            i => i.quantity > i.minStock * 2 && i.id !== inv.id
          );

          if (sourceWarehouses.length > 0) {
            transfers.push({
              type: 'demand_based',
              priority: 'high',
              fromWarehouse: sourceWarehouses[0],
              toWarehouse: inv,
              product: product,
              suggestedQty: Math.abs(expectedStock) + 20,
              reason: `需求预测调拨:预测${inv.warehouseName}30天后缺货${Math.abs(expectedStock)}件`
            });
          }
        }
      }
    }

    return transfers;
  }

  // 过滤并排序建议
  filterAndSortRecommendations(recommendations) {
    // 过滤掉已经在处理中的调拨
    const activeTransfers = this.Transfer.getActive();
    const activeProductWarehouse = new Set(
      activeTransfers.map(t => `${t.productId}-${t.fromWarehouseId}-${t.toWarehouseId}`)
    );

    const filtered = recommendations.filter(r => {
      const key = `${r.product.id}-${r.fromWarehouse?.id}-${r.toWarehouse?.id}`;
      return !activeProductWarehouse.has(key);
    });

    // 按优先级排序
    const priorityOrder = { high: 0, medium: 1, low: 2 };
    return filtered.sort((a, b) => {
      return priorityOrder[a.priority] - priorityOrder[b.priority];
    });
  }

  // 计算最优调拨路径
  async calculateOptimalRoute(fromWarehouse, toWarehouse, productId) {
    // 获取所有仓库作为中转点
    const warehouses = await this.Warehouse.findAll();

    // 直接调拨
    const directRoute = {
      from: fromWarehouse,
      to: toWarehouse,
      distance: this.calculateDistance(fromWarehouse, toWarehouse),
      cost: this.calculateTransferCost(fromWarehouse, toWarehouse, productId)
    };

    // 查找可能的中转仓库
    const potentialTransit = warehouses.filter(wh => {
      return wh.id !== fromWarehouse.id &&
        wh.id !== toWarehouse.id &&
        wh.enableTransit === true;
    });

    // 计算中转路线
    const transitRoutes = potentialTransit.map(transit => {
      const route1 = this.calculateDistance(fromWarehouse, transit);
      const route2 = this.calculateDistance(transit, toWarehouse);
      return {
        from: fromWarehouse,
        transit: transit,
        to: toWarehouse,
        distance: route1 + route2,
        cost: this.calculateTransferCost(fromWarehouse, transit, productId) +
          this.calculateTransferCost(transit, toWarehouse, productId)
      };
    });

    // 选择最优路线
    const routes = [directRoute, ...transitRoutes]
      .filter(r => r.cost < directRoute.cost * 1.5) // 排除成本过高的中转
      .sort((a, b) => a.cost - b.cost);

    return routes[0];
  }

  // 计算距离
  calculateDistance(w1, w2) {
    if (w1.city === w2.city) return 0;
    // 简化的距离计算,实际应该调用地图API
    return Math.abs(w1.latitude - w2.latitude) + Math.abs(w1.longitude - w2.longitude);
  }

  // 计算调拨成本
  calculateTransferCost(from, to, productId) {
    const distance = this.calculateDistance(from, to);
    const product = Product.findById(productId);
    const weight = product.weight || 1;

    // 基础运费 + 里程费 + 保险费
    const baseCost = 50;
    const distanceCost = distance * 0.5;
    const insuranceCost = product.unitPrice * 0.001;

    return baseCost + distanceCost * weight + insuranceCost;
  }
}

调拨优化指标

指标 目标 计算方法
库存周转率 提升 20% (出库数量 / 平均库存) × 100%
缺货率 低于 2% (缺货订单数 / 总订单数) × 100%
调拨成功率 高于 95% (完成调拨数 / 发起调拨数) × 100%
调拨成本占比 低于 3% 调拨总成本 / 销售毛利 × 100%
平均调拨时长 低于 48 小时 (完成时间 - 发起时间) 平均值

可视化库存分布

通过数据可视化展示库存分布和调拨建议:

// 库存分布可视化数据
class InventoryVisualization {
  // 获取地图可视化数据
  async getMapVisualizationData() {
    const warehouses = await this.Warehouse.findAll();
    const inventories = await this.Inventory.getAll();

    return {
      type: 'FeatureCollection',
      features: warehouses.map(wh => {
        const inventory = inventories.filter(i => i.warehouseId === wh.id);
        return {
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [wh.longitude, wh.latitude]
          },
          properties: {
            name: wh.name,
            code: wh.code,
            level: wh.level,
            totalStock: inventory.reduce((sum, i) => sum + i.quantity, 0),
            productCount: inventory.length,
            alertLevel: this.calculateAlertLevel(inventory)
          }
        };
      })
    };
  }

  // 计算告警级别
  calculateAlertLevel(inventory) {
    const alertProducts = inventory.filter(i =>
      i.quantity <= i.minStock || i.quantity >= i.maxStock
    );

    if (alertProducts.length > 5) return 'high';
    if (alertProducts.length > 0) return 'medium';
    return 'normal';
  }

  // 获取库存趋势图表数据
  async getInventoryTrend(productId, days = 30) {
    const trends = await this.Inventory.getDailyTrend(productId, days);

    return {
      labels: trends.map(t => t.date),
      datasets: [{
        label: '库存量',
        data: trends.map(t => t.quantity),
        borderColor: '#36a2eb',
        backgroundColor: 'rgba(54, 162, 235, 0.1)'
      }, {
        label: '安全库存',
        data: trends.map(() => trends[0].minStock),
        borderColor: '#ff6384',
        borderDash: [5, 5]
      }, {
        label: '最大库存',
        data: trends.map(() => trends[0].maxStock),
        borderColor: '#4bc0c0',
        borderDash: [5, 5]
      }]
    };
  }
}

总结

智能库存分布与多仓库调拨优化的核心价值:

通过智能化的库存分布和调拨优化,企业可以显著降低库存成本,提高配送效率,减少缺货和积压情况。

← 下一篇:进销存系统供应商智能评估与分级管理