Skill: jinqianfei/warehouse-network-analysis (version 1.0.0)

--- name: warehouse-network-analysis description: "基于客户门店数据，结合企业实际仓配网络，进行仓配网络规划分析。包括：门店分布统计、城市定位、配送距离测算、区域划分建议、报货周期规划、干线发运规划。为企业设仓方案、配送方案、调拨方案提供数据支撑。" allowed-tools: Bash(python3:*), read, write --- # 仓配网络规划分析 Skill ## 完整分析逻辑 ### 流程图 ``` Step 0: 确认约束参数（向用户询问） ↓ Step 1: 数据读取与基础统计 ↓ Step 2: 城市定位与配送距离 ↓ Step 3: FSL指派（匹配配送基地） ↓ Step 4: RDC选择（约束优化） ⭐ 核心 ↓ Step 5: 构建网络层级（含TC中转） ↓ Step 6: 报货周期 & 干线发运 ``` --- ## 概述 本Skill用于分析企业客户门店分布数据，生成仓配网络规划建议。帮助企业决策： - **设仓方案** - 在哪里建仓库最合适 - **配送方案** - 怎么分配配送路线 - **调拨方案** - 如何调配库存 - **报货周期** - 各区域报货频率和时效 - **干线发运** - 仓库之间的调拨计划 ## 输入 - Excel文件（.xlsx格式） - 包含字段：城市、省市区、地址等信息 - 或包含：机构编码、机构名称、省、市、区、详细地址 --- ## 第一部分：企业实际仓配网络（必须参考） ### 1.1 现有配送基地（17个基地） | 基地名称 | 省份 | 区域定位 | |----------|------|----------| | 成都仓 | 四川省 | 西南区域中心 | | 杭州仓 | 浙江省 | 长三角南翼 | | 合肥仓 | 安徽省 | 皖中区域 | | 济南仓 | 山东省 | 山东区域 | | 廊坊仓 | 河北省 | 京津冀核心 | | 南京仓 | 江苏省 | 长三角北翼/华东中心 | | 泉州仓 | 福建省 | 闽南区域 | | 上海仓 | 上海市 | 长三角核心 | | 广州仓 | 广东省 | 华南区域 | | 沈阳仓 | 辽宁省 | 东北区域 | | 太原仓 | 山西省 | 山西区域 | | 武汉仓 | 湖北省 | 华中区域 | | 西安仓 | 陕西省 | 西北区域 | | 长沙仓 | 湖南省 | 湘赣区域 | | 郑州仓 | 河南省 | 中原区域 | | 哈尔滨仓 | 黑龙江省 | 黑龙江区域 | | 兰州仓 | 甘肃省 | 甘青区域 | | 南昌仓 | 江西省 | 江西区域 | | 石家庄仓 | 河北省 | 冀中南区域 | ### 1.2 报货周期规则 各基地报货遵循以下规则： | 报货计划 | 配送频次 | 典型时效 | |----------|----------|----------| | 一日一配 | 每天发车 | 1天 | | 一周三次 | 周一/周三/周五等 | 1天 | | 一周二次 | 周一+周四 或 周二+周五 | 1-2天 | | 一周一次 | 仅某一天 | 2-3天 | **时效分级**： - 次日达：24小时内到达 - 1-2天：24-48小时 - 2-3天：48-72小时 - 三日达：72小时 ### 1.3 干线发运周期规则 仓库之间的干线运输规则： | 发车规则 | 说明 | 典型在途时长 | |----------|------|---------------| | 次日发车 | 当日报货，次日发车 | 24-48小时 | | 当日发车 | 当日报货，当日发车 | 视距离 | | 周一/周二/... | 指定日期发车 | 按计划 | **运输时效分级**： - 当日达：当日到达 - 次日达：次日到达 - 三日达：2-3天到达 - 四日达及以上：3天以上 --- ## 第二部分：设仓决策逻辑（核心方法论） ### 2.1 核心原则 **原则一：门店密度驱动的"区域重心法"** - 将库存部署在离需求（门店集群）最近的地方 - 最大化区域覆盖，最小化出库干线运输距离 - 在每个门店密集的区域内寻找"重心"设立RDC（区域中心仓库） **原则二：成本最优的"轴辐式"多级网络结构** - RDC（设仓）：全国设少数几个大仓，集中存储，形成库存规模效应 - FSL（配送基地）：在更靠近终端市场的区域设立前置仓或转运中心，负责区域内的"共配" - 货物从RDC批量调拨至FSL，再由FSL执行最后一公里配送 **原则三：核心与外围分治** - 对于门店密度较低的"长尾"区域，采用外包的代发模式 - 通过委托第三方物流（3PL）进行"代发"，将固定成本转化为可变成本 ### 2.2 计算规则流程 ``` 输入分析 ↓ FSL指派（预定义服务地图 → 指派FSL） ↓ RDC选择（在企业现有基地中，时效最短+成本最优） ↓ 检查RDC→FSL是否有直达干线 ↓ ├─ 有 → 直接调拨 ↓ ├─ 无 → 寻找TC中转仓 ↓ 选择链路最短/成本最低的TC ↓ 定义例外策略（代发模式标记） ``` #### 2.3 TC中转仓核心原则 - **必须有干线**：FDC→TC、TC→FSL之间必须有企业内部干线调拨线路 - **TC数量最少**：在满足条件的情况下，中转仓数量尽量少 - **链路最短**：整个配送链路综合成本最优、距离最短 --- ## 第三部分：分析流程 **注意**：在开始分析前，需要先向用户确认约束参数（见Step 4.1） ### Step 0: 确认约束参数（向用户询问） ``` 请提供以下约束参数，以便进行优化分析： 1. 设仓数量上限是多少？（如：6个） 2. 覆盖率目标是多少？（如：80%以上） 3. 时效要求是什么？（如：1-2天） 4. 是否有必须使用的仓库？（如：成都仓） 5. 是否有禁止使用的仓库？（如：不用某仓） 用户输入后，记录约束参数，然后继续Step 1-6。 ``` ### Step 1: 数据读取与基础统计 ```python import pandas as pd df = pd.read_excel('数据文件.xlsx') print('行数:', len(df)) print('列名:', list(df.columns)) # 统计各城市/省份门店数量 city_counts = df['城市'].value_counts() province_counts = df['省份'].value_counts() ``` ### Step 2: 城市定位与配送距离 - 获取各城市经纬度坐标（内置城市坐标库） - 计算各城市到仓库的距离 - 距离分档：短途(≤300km)/中途(300-600km)/长途(>600km) ### Step 3: 匹配配送基地（FSL指派） 基于实际仓配网络，为每个门店城市匹配配送基地（FSL）： | 区域 | 主要配送基地 | |------|--------------| | 京津冀 | 廊坊仓、石家庄仓 | | 长三角 | 上海仓、南京仓、杭州仓 | | 华中 | 武汉仓、长沙仓 | | 华南 | 广州仓 | | 西南 | 成都仓 | | 西北 | 西安仓、兰州仓 | | 东北 | 沈阳仓、哈尔滨仓 | | 中原 | 郑州仓、太原仓 | | 山东 | 济南仓 | ### Step 4: 选择RDC（设仓优化） **核心逻辑**：基于企业现有仓配网络基地，在客户约束条件下，以"时效最短+成本最优"为目标，选择RDC。 #### 4.1 约束参数（需向用户询问） | 参数 | 说明 | 示例 | |------|------|------| | **设仓数量上限** | 最多可设仓数量（RDC数） | 3个、5个、6个等 | | **最大中转次数** | TC中转最大跳数 | 1次、2次等 | | **覆盖率目标** | RDC覆盖门店比例（越高越好） | 80%、90%、100%等 | | 时效要求 | 门店到仓库的最大允许时效 | 次日达、1-2天、2-3天 | | **强制仓库** | 某些区域必须使用的仓库 | 必须用成都仓 | | **禁止仓库** | 某些区域禁止使用的仓库 | 不用某仓 | **注意**：以上约束均基于企业当前仓配网络和干线网络进行优化选择。 **开始分析前需确认**： ``` 请提供以下约束参数： 1. 设仓数量上限是多少？（如6个） 2. 最大中转次数？（如2次） 3. 时效要求是什么？（如1-2天） 4. 是否有必须使用的仓库？（如：成都仓） 5. 是否有禁止使用的仓库？（如：不用某仓） ``` #### 4.2 覆盖率定义 **RDC覆盖门店**：门店的配送链路能连接到RDC，包括： | 情况 | 配送链路 | 是否RDC覆盖 | |------|----------|-------------| | **RDC = FSL** | RDC → 门店（FSL有库存直配） | ✅ 是 | | **RDC → FSL（有直达）** | RDC → FSL → 门店 | ✅ 是 | | **RDC → TC → FSL（中转）** | RDC → TC → FSL → 门店 | ✅ 是 | | **无法连接** | 无有效干线链路 | ❌ 否（FSL直配） #### 4.3 优化目标 ``` 优化目标：min(总成本) 约束条件： - 时效满足要求（基于当前干线网络时效） - 设仓数量 ≤ 上限 - 覆盖率 ≥ 目标（如80%） - 强制仓库必须使用 - 禁止仓库不使用 - 中转次数 ≤ 最大中转次数 ``` **约束条件说明**： - 所有约束均基于企业当前仓配网络（17个配送基地） - 所有约束均基于企业当前干线网络（76条干线线路） - 选择RDC时需要检查与FSL之间的干线连通性 - 选择TC时需要检查RDC→TC和TC→FSL的干线连接 **成本构成**： - 设仓成本：仓储出入库操作成本（装卸、拣货、复核等） - 干线调拨成本：RDC→FSL 或 RDC→TC→FSL 运输成本 - 配送成本：FSL→门店 最后一公里配送成本 ``` min(总成本) = 设仓成本 + 干线调拨成本 + 配送成本 ``` - 配送成本：FSL→门店配送成本 #### 4.4 选择算法 ``` 1. 获取所有配送基地（FSL） - 从企业现有配送网络中获取 2. 每个FSL都是RDC（都需要设仓） - 因为FSL需要库存才能直接配送 3. 计算配送链路 - 检查RDC→FSL是否有直达 - 如无直达，寻找TC中转 4. 输出： - RDC列表（=FSL列表） - 覆盖率 = 100%（每个门店都被覆盖） - 链路类型分布（同仓/直达/中转） ``` #### 4.5 输出示例 ``` 输入： - 配送基地列表：21个 输出： RDC数量: 21个（每个FSL都设仓） 配送链路分布： - 同仓直配（RDC=FSL）: 1789家 (86%) - 直达调拨: 0家 (0%) - TC中转调拨: 147家 (7%) - 无链路（需新增）: 141家 (7%) 覆盖率: 100%（所有门店都能被配送） ``` ### Step 5: 构建网络层级（RDC→FSL，含TC中转） **核心逻辑**：将步骤4选定的RDC与步骤3指派的FSL关联，形成完整配送链路。 #### 5.1 链路匹配规则 | 类型 | 链路 | 说明 | 是否RDC覆盖 | |------|------|------|-------------| | **直接调拨** | RDC → FSL → 门店 | RDC到FSL有直达干线 | ✅ 是 | | **TC中转** | RDC → TC → FSL → 门店 | 无直达，需要中转仓 | ✅ 是 | | **代发模式** | 无有效链路 | 建议3PL代发 | ❌ 否 | #### 5.2 TC中转仓选择逻辑 **选择条件**： - FDC→TC 之间必须有干线调拨线路 - TC→FSL 之间必须有干线调拨线路 - TC仓数量尽量少 - 链路尽量短（综合成本最优） **选择步骤**： ``` 1. 检查RDC→FSL是否有直达干线 → 有：直接调拨 → 无：进入步骤2 2. 寻找可用的TC中转仓 遍历所有仓库，找出同时满足： - RDC→TC有干线 - TC→FSL有干线 3. 选择最优TC - 优先选择链路最短的组合 - 次选成本最低的组合 ``` **示例**： ``` 场景：成都仓 → 泉州仓 分析：无直达干线 方案A：成都 → 长沙 → 泉州 (链路短) ✓ 方案B：成都 → 广州 → 泉州 选择：长沙仓 ``` #### 5.3 链路成本权衡 | 考量因素 | 优先级 | |----------|--------| | 干线跳转次数最少 | 高 | | 综合运输距离最短 | 高 | | 时效满足 | 中 | | 成本最优 | 中 | #### 5.4 覆盖率计算 ``` 覆盖率 = (RDC覆盖门店数) / (总门店数) = (直接调拨 + TC中转) / 总门店数 输出： - 直接调拨门店数 - TC中转门店数 - 代发模式门店数 - 总覆盖率 ``` ### Step 6: 报货周期规划 根据配送距离和门店数量，确定报货频次： | 配送距离 | 门店数量 | 建议报货计划 | |----------|----------|--------------| | ≤100km | 任意 | 一日一配 | | 100-300km | ≥10家 | 一周三次 | | 100-300km | <10家 | 一周二次 | | >300km | 任意 | 一周一次/二次 | ### Step 6: 干线发运规划 对于需要跨仓库调拨的情况，规划干线发运： | 起始仓库 | 目的仓库 | 建议发车日 | 预计时效 | |----------|----------|------------|----------| | 杭州仓 | 上海仓 | 周二/周六 | 次日达 | | 南京仓 | 廊坊仓 | 周四 | 三日达 | | 长沙仓 | 南昌仓 | 周一/周五 | 当日达 | | 廊坊仓 | 石家庄仓 | 周五 | 次日达 | --- ## 第四部分：输出文件 - `{原文件名}_分析.xlsx` - 包含所有分析结果的Excel文件 ### Sheet结构 | Sheet名称 | 内容 | |-----------|------| | 可视化图表 | 4张分析图表（省份分布/城市TOP10/仓库分布/省份仓库分配） | | 省份分布 | 各省份门店数量 | | 城市分布 | 各城市门店数量 | | 配送基地匹配 | 各城市对应的配送基地 | | 报货周期建议 | 各区域报货频次和时效建议 | | 干线发运计划 | 仓库间调拨计划 | | 配送链路规划 | RDC→FSL完整链路（含TC中转） | --- ## 第五部分：适用场景 1. **新客户拓展** - 评估新区域是否值得设仓 2. **仓库选址** - 优化仓库位置 3. **配送优化** - 规划配送路线 4. **成本分析** - 评估物流成本 5. **门店分布分析** - 了解客户分布情况 6. **报货周期设计** - 制定区域报货计划 7. **干线网络规划** - 规划仓库间调拨路线 --- ## 注意事项 - **必须参考实际网络**：本Skill内置了企业实际运营的17个配送基地信息，规划时必须优先考虑现有资源 - **图表使用英文标签**避免中文乱码 - 本分析基于直线距离，实际配送路线可能更长 - 建议结合实际交通数据进行修正 - 区域划分需结合业务需求调整 - **代发 vs 共配**：低密度区域优先考虑代发模式而非自建网络

path: analyze.py
content: #!/usr/bin/env python3
"""
仓配网络规划分析脚本
用法: python3 analyze.py <excel文件路径>
"""

import pandas as pd
import math
import sys

# 内置城市坐标库
CITIES_COORDS = {
    '武汉': (114.3055, 30.5928), '成都': (104.0655, 30.6595), '重庆': (106.5514, 29.5637),
    '南昌': (115.8582, 28.6820), '西安': (108.9398, 34.3416), '贵阳': (106.7134, 26.5780),
    '昆明': (102.8329, 24.8801), '荆州': (112.2394, 30.3269), '襄阳': (112.1226, 32.0101),
    '宜昌': (111.2862, 30.6918), '郑州': (113.6254, 34.7466), '开封': (114.3074, 34.7971),
    '南阳': (112.5287, 33.0004), '新乡': (113.9267, 35.3029), '漯河': (114.0166, 33.5818),
    '宜宾': (104.6431, 28.7518), '景德镇': (117.2014, 29.2689), '西双版纳': (100.7970, 21.9588)
}

def calc_distance(lng1, lat1, lng2, lat2):
    """计算两点间距离(km)"""
    R = 6371
    dLat = math.radians(lat2 - lat1)
    dLng = math.radians(lng2 - lng1)
    a = math.sin(dLat/2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dLng/2)**2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    return round(R * c, 1)

def analyze(file_path, warehouse_lng=114.3055, warehouse_lat=30.5928):
    """分析函数"""
    df = pd.read_excel(file_path)
    
    # 1. 基础统计
    print("="*60)
    print("一、门店分布统计")
    print("="*60)
    
    # 城市统计
    city_stats = df.groupby('城市').size().reset_index(name='门店数')
    city_stats = city_stats.sort_values('门店数', ascending=False)
    print("\n各城市门店数量:")
    print(city_stats.to_string(index=False))
    
    # 省份统计
    if '省' in df.columns:
        province_stats = df.groupby('省').size().reset_index(name='门店数')
        province_stats = province_stats.sort_values('门店数', ascending=False)
        print("\n各省份门店数量:")
        print(province_stats.to_string(index=False))
    
    # 2. 配送距离
    print("\n" + "="*60)
    print("二、配送距离测算")
    print("="*60)
    
    for _, row in city_stats.iterrows():
        city = row['城市']
        if city in CITIES_COORDS:
            lng, lat = CITIES_COORDS[city]
            dist = calc_distance(warehouse_lng, warehouse_lat, lng, lat)
            tag = '短途' if dist <= 300 else '中途' if dist <= 600 else '长途'
            print(f"{city}: {dist}km ({tag})")
    
    print("\n分析完成！")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("用法: python3 analyze.py <excel文件路径>")
        sys.exit(1)
    
    analyze(sys.argv[1])

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)