# 柔性排产 · 全流程模拟操作手册 > **面向**:产品演示、方案讲解、验收。 > **场景**:康尼芜湖「多品种小批量 + 设备可移动」柔性排产(高压线束 / PDU 共线)。 > **两种走法**:A 一键脚本(最快看全貌)|B 逐接口操作(贴近真实系统)。 > **现场真实单**:先跑 `python scripts/load_kangni.py`(或口令「导入完整生产路线」)替换演示 flex*,再用柔性排产;口径见 [demand-data-intake.md](./demand-data-intake.md) 附「完整生产路线」。 > 数据口径见 [demand-data-intake.md](./demand-data-intake.md);需求背景见 [demand-kangni-wuhu.md](./demand-kangni-wuhu.md)。 --- ## 第一部分 · 自然语言:一次排产到底发生了什么 用大白话把整条链讲一遍。假设计划员接到一张订单「高压线束总成 100 套,7 天后交」。 ### 1)设备不再绑死产线——「设备虚拟化」 传统做法:这条活固定走「线束产线」。但芜湖的现实是压接机今天在线束区、明天被调去 PDU 区。所以系统里**每台设备是一份独立档案**,记录它「能干哪几道工序、能不能移动、移动要多久、当前在哪个区、能装哪些模具」。产线不再是固定的钢筋水泥,而是**用的时候临时拼出来的**。 ### 2)同类设备汇成一个「产能池」 系统不问「哪条线」,只问「哪道工序」。所有能做压接的设备(4 台可移动压接机)汇成一个**压接能力池**;所有能焊接的(1 台激光焊接机)汇成**焊接池**。排产时从池子里**动态取设备**,谁空闲、谁装了合适模具就用谁。 ### 3)为这张订单临时拼一条「虚拟产线」 系统把订单按工艺路线展开成工序序列(来料检验→下线→压接→装配→测试→包装),然后逐道工序去对应能力池取一台设备,拼出一条**虚拟产线 VL-FO-001**: - 压接这道是瓶颈工序,从压接池挑一台负载最轻的压接机,并确认它装了适配模具(没装就算换型时间); - 如果这台压接机需要从别的区调过来,就把「移动耗时」插进时间轴(移动时不能生产); - 每道工序占用设备的一个时间槽,前道没干完后道不能开始。 排完这条虚拟产线就「拼完即用、用完即散」,设备回到池子等下一单。 ### 4)产能到底有多少——「瓶颈产能法」 不再用「设备台数×理论工时×拍脑袋 70%」。系统只认最慢那道工序: > 全厂日产能 = 瓶颈工序可用工时 ÷ 单件工时。 本场景里 PDU 的激光焊接只有 1 台(≈88 件/天),它就是天花板;而压接池 4 台并行看着能做 1920 件/天,那是虚高,没意义。**哪道最慢,产能就由它说了算。** ### 5)销售问「这批什么时候能交」——「交期承诺模拟」 系统不回答「按产能算 X 天」,而是把这张询单**试着插进当前排程**,给三个数: - 乐观(独占资源):最早能哪天完成; - 预计(和在制订单抢资源):大概率哪天完成; - 资源缺口:要更早,得加哪台设备 / 外包哪道工序。 ### 6)计划总在变——「动态重排」 - **紧急插单**:来一张 VIP 急单,冻结当前窗口重排,急单优先占瓶颈资源,其余顺延; - **设备故障**:某台设备停机,系统**实时把它从能力池剔除**,用剩下的重排。这里有个关键区别:可移动压接机坏一台,池子还有 3 台冗余,交期几乎不受影响;但激光焊接机就 1 台,一坏 PDU 直接停摆,系统立刻报「无可用设备」,提示上备机 / 外包 / 重新议交期。 **一句话总结**:任何时刻,系统都能回答计划员那三个问题——**现在能做什么、做多少、什么时候做完**。 --- ## 第二部分 · 走法 A:一键脚本模拟(最快) 不用起服务、不用点页面,一条命令把上面 6 步全跑出来,全中文可读输出。 ### 前置 ```powershell # 仓库根目录,已建好 .venv 并 pip install -r requirements.txt cd ``` ### 运行 ```powershell .venv\Scripts\python.exe scripts\flex_simulation.py ``` ### 输出会分 7 段(对应上面的业务流程) | 阶段 | 你会看到 | 怎么读 | | --- | --- | --- | | 阶段 0 主数据/产能池 | 区域、每个能力池的设备清单(★=瓶颈)、模具、订单 | 确认「压接池 4 台可移动 / 焊接池 1 台」这类池结构 | | 阶段 1 初始排产 | 5 条虚拟产线,每条逐工序打印:设备·模具·换型/移动/加工耗时·时间段 | 看「★瓶颈」那行是不是占了压接/焊接设备并挂了模具 | | 阶段 2 瓶颈产能法 | 各池日产能表 + 限制性瓶颈 | 看「限制性瓶颈=激光焊接 88 件/天」,对照台账法虚高 1920 | | 阶段 3 三模式对比 | 正排/倒排/瓶颈锚的延迟、准时单、最晚完工 | 压力下倒排明显更差(295h/0 准时),说明模式选择有意义 | | 阶段 4 交期承诺 | PDU 500 套的乐观/预计完工 + 缺口提示 | 看两个日期差多少,缺口指向焊接工序 | | 阶段 5 紧急插单 | 插单前后虚拟产线数、最晚完工、急单排入时段 | 看急单是否优先占了瓶颈 | | 阶段 6 设备故障 | 案例①压接机故障(有冗余)|案例②焊接机故障(停摆报错) | 对比「池化韧性」与「单点瓶颈」两种结局 | > 脚本是**内存态确定性**运行(种子固定),任何机器任何时间跑结果一致,适合反复演示。改数据后重跑即可。 --- ## 第三部分 · 走法 B:逐接口操作(贴近真实系统) 先起后端,再按「看主数据 → 排产 → 看产能 → 问交期」的顺序调接口;或直接打开前端右侧「柔性工作台」点选同一条链路。 ### 0)起服务 ```powershell .venv\Scripts\python.exe -m uvicorn server.main:app --reload --port 8000 ``` 以下命令用 PowerShell 的 `Invoke-RestMethod`(另起一个终端)。 ### 1)看柔性主数据与产能池(P0 只读) ```powershell Invoke-RestMethod http://localhost:8000/api/flex/world | ConvertTo-Json -Depth 6 ``` 返回:`zones` 区域、`pools` 能力池(含是否瓶颈/设备清单)、`equipment` 设备、`molds` 模具、`orders` 订单、以及最近一次排产的 `virtualLines` / `workOrders` / `conflicts`。 ### 2)执行一次柔性排产(P1 直通,写草稿) ```powershell $body = @{ sortMode = "BOTTLENECK" } | ConvertTo-Json Invoke-RestMethod -Method Post -ContentType "application/json" ` -Uri http://localhost:8000/api/flex/schedule -Body $body ``` - `sortMode` 可选 `ASC`(正排) / `DESC`(倒排) / `BOTTLENECK`(瓶颈锚),不传取默认瓶颈锚; - 可加 `orderIds=@(1,2)` 只排指定订单; - 返回摘要:`vlCount` 虚拟产线数、`woCount` 工单数、`makespan` 最晚完工、`onTimeCount` 准时单、`conflictCount` 冲突、`bottleneck` 瓶颈工序。 排完再调一次 `GET /api/flex/world` 看 `virtualLines`(每条虚拟产线的工序-设备-模具-时间)。 ### 3)瓶颈产能法分析(P0 只读) ```powershell Invoke-RestMethod http://localhost:8000/api/flex/capacity | ConvertTo-Json -Depth 5 ``` 返回各池 `dailyCapacity` 日产能、`workDays` 本版本工作量折合天数、`bottleneckPool` 限制性瓶颈池。 ### 4)交期承诺模拟(P0 只读沙盒,不改主干) ```powershell $body = @{ productCode = "PDU-UNIT"; quantity = 500 } | ConvertTo-Json Invoke-RestMethod -Method Post -ContentType "application/json" ` -Uri http://localhost:8000/api/flex/simulate-due -Body $body ``` 返回 `optimisticFinish` 乐观完工、`expectedFinish` 预计完工、`bottleneck` 瓶颈提示。 ### 接口速查 | 步骤 | 方法 | 端点 | 权级 | | --- | --- | --- | --- | | 看主数据/产能池/最新排产 | GET | `/api/flex/world` | P0 | | 执行柔性排产 | POST | `/api/flex/schedule` | P1 | | 瓶颈产能分析 | GET | `/api/flex/capacity` | P0 | | 交期承诺模拟 | POST | `/api/flex/simulate-due` | P0(沙盒) | --- ## 第四部分 · 走法 C:换成你的真实数据 模拟数据都在种子的 `flex*` 键里(`server/state/seed.py` 的 `_seed_flex`)。换真实数据**不用改引擎**,只需: 1. 按 [demand-data-intake.md](./demand-data-intake.md) 的 11 张表准备数据(P0 五张必填:区域 / 设备 / 工序 / 模具 / 工艺路线); 2. 逐表替换 `_seed_flex` 里对应的 `flexZones` / `flexEquipment` / `flexOperations` / `flexMolds` / `flexRoutings` / `flexBom` / `flexMaterials` / `flexTeams` / `flexCalendar` / `flexOrders` / `flexParams`; 3. 删除 `server/data/world.json`(若存在)让种子重播,或重启后端; 4. 重跑走法 A 或 B 即可。 字段口径一致即可,编码自定;**不要**把工厂名/产品名写进引擎或意图,保持行业无关。 --- ## 第五部分 · 验收清单(照着勾) - [ ] 阶段 0 能看到「压接池 4 台可移动 / 焊接池 1 台」的池结构与★瓶颈标记 - [ ] 阶段 1 每条虚拟产线工序顺序正确、压接工序挂了适配模具、可移动设备有移动耗时痕迹 - [ ] 阶段 2 限制性瓶颈=激光焊接(约 88 件/天),且明显低于压接池 - [ ] 阶段 3 倒排在压力场景下延迟明显高于正排/瓶颈锚(模式选择有意义) - [ ] 阶段 4 交期给出乐观/预计两个日期 + 缺口指向焊接 - [ ] 阶段 5 急单优先占瓶颈、其余顺延 - [ ] 阶段 6 压接机故障影响小(池化韧性)、焊接机故障 PDU 停摆并报 NO_CAPABILITY - [ ] `pytest tests/golden -q` 全绿(当前 48 passed) --- ## 常见问题 - **必须起后端吗?** 走法 A 不用,纯内存跑;走法 B/前端需要 `uvicorn`。 - **为什么三模式有时结果一样?** 交期宽松、产能有余时三模式趋同;只有产能吃紧才分化(脚本阶段 3 / 工作台「三模式对比」会压缩交期制造压力)。 - **重排是局部还是全量?** 故障与急单当前为**全量重排**(L4);缩池体现 L1;窗内 L2/L3 为后续切片。 - **前端在哪看?** 右侧「柔性工作台」+ 视口柔性甘特/产能池;也可继续用脚本/接口。 变更登记见 [`../CHANGELOG.md`](../CHANGELOG.md)。