更新记录
1.0.0(2026-11-04)
首个版本:安全库存(需求与提前期双波动)、再订货点、EOQ 与按 MOQ/包装倍数取整的建议批量、可用天数、五种状态(紧急/待补/正常/超储/呆滞)、ABC 按年金额 80/95 分档、XYZ 按变异系数、服务水平曲线与缺货率、一张库存明细表批量测算、体检(缺提前期/缺单价/日均用量疑似填成月用量/MOQ 过大)、18 列 CSV 导出(带 BOM)。UTS→Kotlin 编译通过(index.kt 1511 行与 classes.dex 已生成),108 项回归测试全部通过;真机未执行(adb devices 为空),市场截图为 H5 渲染并标注示例数据。
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | √ | × | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
安全库存与补货建议
给仓库、采购、PMC 用:断料和压库存是同一个问题的两面 —— 该备多少、什么时候下单,得算,不能凭感觉。
一张库存明细表进去,出来的是:每个料号的安全库存、再订货点、建议批量、还能卖几天,以及「紧急 / 待补 / 正常 / 超储 / 呆滞」五种状态。
购买前必读
- 只支持 Android(
minSdkVersion 23,Android 6.0 起)。iOS 与鸿蒙本版本未实现,市场平台声明里已标不支持。 - 不连 ERP、不连数据库。插件只接受 CSV 文本 / 文件路径 / 结构化数组三种输入。数据怎么从 ERP 导出、算完怎么回写,是你那一层的集成工作;插件不猜你的表结构,也不用你的账号去读任何系统。
- 公式是教科书版本,参数得你自己给准。安全库存的准确度 90% 取决于「日均用量」和「日用量标准差」这两列准不准。拿三个月出库记录随手除一下天数,算出来的数字看着像模像样,其实是垃圾。插件会做体检提示(见下),但它替不了你对业务的理解。
- 服务水平不是越高越好。95% 到 99%,安全库存大概翻 1.4 倍;99% 到 99.9% 再翻 1.4 倍。多备的货是压着的钱,插件用
stockCurve把这根曲线摊开给你看,选哪一档是经营决策。 - 不做需求预测。日均用量与标准差由你从历史数据算好再传进来。插件不猜未来,只把「给定这些波动,该备多少」算准。
解决什么问题
- 「这个料还能撑几天?」 现有 120、日均 20,撑 6 天;采购提前期 7 天 —— 今天就该下单了,而不是等到低于某个整数才发现;
- 「安全库存到底该多少?」 拍脑袋定 100 件,结果旺季每周都断、淡季压三个月。按需求波动和提前期算出来是 39 件,差了两倍多;
- 「一次订多少?」 EOQ 说 11030,但供应商 MOQ 1000、整箱 500 —— 取整到 11500,多出的 470 件值不值得,插件把数摊开;
- 「几百个料号看不过来」 按年金额 ABC 分类,A 类往往就十几个,把精力放这里;C 类占金额 5%,按固定批量例行补就行;
- 「哪些其实是死库存?」 半年没出库但账上还有货,这类不是「安全库存不足」,是「根本不该再买」。
与同类的边界
| 你可能已有的 | 它做什么 | 本插件做什么 |
|---|---|---|
| ERP / 进销存自带的补货建议(易飞、管家婆、金蝶等) | 整套系统里的一页报表,要先把安全库存、提前期、MOQ 等参数在系统里配齐才能出数 | 纯函数,塞进已有的 App 里就能算。参数随表传进来,不依赖任何后台配置 |
| Inventory Planner($99–499/月)、Cin7 Core($349/月)、Ordoro($59/月)、inFlow($110/月)、Cogsy($199/月) | 联网 SaaS,按月订阅,要授权账号、要上传全部库存数据 | 本地算、零订阅、零上传;算完的结论可以留在你自己的 App 里 |
| Excel 模板(EOQ / 安全库存公式网上到处都有) | 公式散落在单元格里,加一列就崩;ABC 要手工排序;换个月份要重贴数据 | 列名认别名、缺列自动提示、ABC/XYZ 自动分类、一次出全部料号,导出可直接交付的 CSV |
本店 szhzy-bom-explode 多级 BOM 展开 |
算的是一批订单需要多少料(毛需求) | 算的是日常该备多少、什么时候下单(补货节奏)。一个看单,一个看仓 |
本店 szhzy-quote-cost 报价核算 |
算报价与成本 | 算库存周转与资金占用 |
本店 szhzy-xlsx-export / xlsx-import |
负责数据进出 Excel | 只管算,不碰 Excel 格式 |
快速上手
import { stockAdvise, stockBatch, stockCurve, stockExport } from '@/uni_modules/szhzy-stock-replenish'
// 1) 单料:日均 20 件、日标准差 5、提前期 7 天、提前期标准差 1 天
const one = stockAdvise({
code: 'LED-3528', name: '3528 白光灯珠',
onHand: 120, dailyMean: 20, dailySd: 5,
leadDays: 7, leadSd: 1,
price: 0.12, orderCost: 200, service: 0.95,
moq: 1000, pack: 500
})
// → safety: 39.4 rop: 179.4 lotQty: 11500 daysCover: 6 status: 'urgent'
// 2) 批量:一张库存明细表
const all = stockBatch({ csv: text })
// → rows[] summary{} warnings[] text(人读报告) csv(可直接落盘)
// 3) 服务水平曲线:95% 还是 99%?
const curve = stockCurve({ dailyMean: 20, dailySd: 5, leadDays: 7, leadSd: 1, low: 0.8, high: 0.99, step: 0.025 })
// 4) 导出 CSV(带 BOM,Excel 双击不乱码)
const out = stockExport({ csv: text, fileName: '补货建议.csv' })
// → path: /storage/emulated/0/Android/data/<包名>/files/documents/补货建议.csv
明细表格式
带表头,列名认这些别名(大小写与前后空格自动忽略):
| 列 | 别名 | 必填 | 说明 |
|---|---|---|---|
| 料号 | 物料编码 / 编码 / code / sku | 二者其一 | 与名称至少有一个 |
| 名称 | 物料名称 / 品名 / name | 二者其一 | 报告里用它标识 |
| 现有库存 | 库存 / 结存 / onhand / 现存量 | 建议 | 缺省按 0 |
| 在途 | 在途量 / 采购在途 / onorder | 否 | 缺省按 0 |
| 日均用量 | 日均 / 日耗 / daily / 平均日用量 | 必填 | 按最近 3–6 个月出库量 ÷ 天数 |
| 用量标准差 | 日用量标准差 / 标准差 / sd | 否 | 缺省按 0(安全库存只剩提前期波动) |
| 提前期 | 采购提前期 / lead / leadtime / 交期天数 | 必填 | 天 |
| 提前期标准差 | 交期标准差 / leadsd | 否 | 缺省按 0 |
| 单价 | price / 含税单价 | 建议 | 缺了算不了资金占用与 EOQ |
| 订货成本 | 每次订货成本 / ordercost | 否 | 缺了用 MOQ 当批量 |
| 持有率 | 年持有成本率 / holdrate | 否 | 缺省 0.2(20%/年) |
| 服务水平 | service / 服务水平率 | 否 | 缺省 0.95;写 95 也认(>1 自动 ÷100) |
| MOQ | 最小起订量 / 起订量 | 否 | 批量取整下限 |
| 包装倍数 | pack / 整箱数 / 装箱数 | 否 | 批量向上取整到整箱 |
| 距上次出库天数 | 未出库天数 / lastout / 停滞天数 | 否 | ≥180 天判呆滞 |
无表头(或表头认不出 ≥2 列)时按 料号,名称,现有库存,日均用量,提前期,单价 的位置读。
料号,名称,现有库存,在途,日均用量,用量标准差,提前期,提前期标准差,单价,订货成本,持有率,服务水平,MOQ,包装倍数,距上次出库天数
LED-3528,3528 白光灯珠,120,0,20,5,7,1,0.12,200,0.2,0.95,1000,500,3
PCB-4820,铝基板 48×20,860,200,12,3,21,3,1.85,300,0.2,0.95,500,100,5
CASE-A3,压铸外壳 A3,4200,0,4,1,30,5,6.4,400,0.2,0.98,200,50,210
口径与公式(可手算核对)
安全库存(需求与提前期都波动):
SS = z · √( LT·σd² + d²·σLT² )
z 由服务水平查标准正态分位数:90% → 1.2816,95% → 1.6449,97.5% → 1.96,99% → 2.3263,99.9% → 3.0902。
表内插值,超出 0.50–0.999 直接报错,不猜。
再订货点:
ROP = d · LT + SS
经济订货批量(年持有成本 = 单价 × 持有率):
EOQ = √( 2·D·S / (P·h) )
D 年需求(日均 × 365)、S 每次订货成本、P 单价、h 年持有率。
批量取整:先向上取到「包装倍数」的整数倍,再与 MOQ 取大。
覆盖天数 = 可用量(现有 + 在途)÷ 日均用量。
XYZ:CV = σd / d,CV < 0.5 为 X(平稳)、< 1.0 为 Y(有波动)、其余 Z(很不稳)。
ABC:按年金额(日均 × 365 × 单价)降序累计,≤80% 为 A,≤95% 为 B,其余 C。
手算一遍上例
日均 d = 20、σd = 5、LT = 7、σLT = 1、服务水平 95%(z = 1.6449):
SS = 1.6449 × √(7×25 + 400×1) = 1.6449 × √575 = 1.6449 × 23.979 = 39.44 → 39.4
ROP = 20×7 + 39.44 = 179.44 → 179.4
可用 120,覆盖 120 ÷ 20 = 6 天 < 提前期 7 天 → 紧急
EOQ = √(2×7300×200 ÷ (0.12×0.2)) = √(2920000 ÷ 0.024) = 11030.3
批量 = 向上取 500 的整数倍 → 11500,再与 MOQ 1000 取大 → 11500
即:这个料今天就该下单 11500 件,而不是等库存掉到某个整数才动。
状态判定顺序
先看会不会断,再看压不压钱:
- 日均 ≤ 0 → 无消耗(不补货)
- 覆盖天数 < 提前期 → 紧急
- 可用量 < 再订货点 → 待补
- 距上次出库 ≥ 180 天 → 呆滞
- 覆盖天数 > 120 → 超储
- 其余 → 正常
API
| 方法 | 入参 | 返回 |
|---|---|---|
stockAdvise(options) |
单个料号的各字段(见下表) | item.* + warnings[] |
stockBatch(options) |
csv 或 path 或 items[] |
rows[] / summary / warnings[] / skipped[] / text / csv |
stockCurve(options) |
dailyMean, dailySd, leadDays, leadSd, low, high, step |
points[](服务水平 → z / 安全库存 / ROP / 缺货 ppm)/ eoqQty |
stockExport(options) |
同 stockBatch + fileName / dir / bom |
path / bytes |
stockDefaults() |
— | 默认服务水平、持有率、输出目录、状态与分类说明 |
stockAdvise 的入参字段:code name onHand onOrder dailyMean dailySd leadDays leadSd price orderCost holdRate service moq pack lastOutDays。
rows[] 里每行的字段:codeText name onHand onOrder available dailyMean leadDays service zValue safety rop eoqQty lotQty daysCover status statusText action value annualValue unitPrice abc xyz cv overStock。
summary 字段:rows badRows urgent watch normal slow dead totalValue deadValue slowValue aCount bCount cCount aValue suggestAmount。
所有 API 返回统一信封 { ok, code, message, ... },不抛异常。
导出的 CSV 列(18 列)
料号、名称、现有、在途、可用、日均、提前期(天)、服务水平、安全库存、再订货点、建议批量、可用天数、状态、ABC、XYZ、库存金额、年金额、建议动作。
带 UTF-8 BOM,Excel 双击直接开;文件默认落 Android/data/<包名>/files/documents/,不需要任何存储权限。
错误码
| code | 含义 |
|---|---|
NO_KEY |
这一行既没有料号也没有名称 |
NO_DEMAND |
缺日均用量,或填成了负数 |
NO_LEAD |
缺采购提前期,或 ≤ 0 |
BAD_SERVICE |
服务水平不在 0.50–0.999 之间 |
NO_ITEM |
明细表里没有一行可用 |
EMPTY |
既没给 csv 也没给 path |
FILE_NOT_FOUND / READ_FAILED / OPEN_FAILED |
文件读不进来(权限、路径或内存) |
FILE_TOO_LARGE |
超过 12 MB,请按仓库或产品线拆分 |
CHARSET_UNSUPPORTED |
charset 写了个不存在的编码 |
NO_OUTPUT_DIR |
拿不到应用外部私有目录 |
体检提示(warnings)
| kind | 触发条件 | 为什么值得看 |
|---|---|---|
NO_DEMAND_STOCK |
日均 ≤ 0 但库存 > 0 | 是呆滞,还是停产线了?处理方式完全不同 |
NO_LEAD |
缺提前期 | 再订货点算不出来,这一行只能靠猜 |
BAD_SERVICE |
服务水平超出 0.50–0.999 | 八成是把 0.95 写成了 95% 或者反过来 |
NO_PRICE |
缺单价 | 算不了资金占用、EOQ 和 ABC |
UNIT_SUSPECT |
日均 × 30 > 库存 × 10 | 很像把月用量填成了日用量,会让建议批量虚高 30 倍 |
MOQ_TOO_BIG |
MOQ > 季度用量 | 按 MOQ 下单会一次压三个月的货,该跟供应商重谈 |
体检是先提示再算:有提示的行照常出建议,但结论要打个折扣看。
能力边界与已知限制
- 不做需求预测。日均与标准差必须由你从历史数据算好传入,插件不用移动平均、指数平滑去猜。
- 只算单层、单个仓库。多仓调拨、批次有效期(FEFO)、季节性波动需要在上层处理。
- 不考虑产能与在途分批。在途按一次性到货处理,分批到货请拆成多次调用。
- 提前期波动与需求波动按独立处理,公式不覆盖两者相关的情形。
- ABC 分档固定 80/95,这是帕累托经验值,不是行业标准;要别的阈值请在上层按
annualValue自己分。 - 状态阈值(180 天呆滞、120 天超储)是常见做法,不是行业标准,不同行业差别很大,需要按自己业务调时请改
core.uts里的判断。
验证状态
| 项 | 结果 |
|---|---|
Android 编译(cli launch app-android --compile true,真跑 kotlinc) |
通过,见 测试记录.md |
| 纯逻辑回归测试(Node 真实执行) | 通过 108 项 / 失败 0 项,见 测试记录.md |
| 真机运行(安装、点击、导出文件) | 未执行 —— 本机无在线 Android 设备,未做任何真机断言 |
| iOS / 鸿蒙 | 未实现,声明为不支持 |
授权
普通授权 ¥9.9 / 源码授权 ¥99,见 license.md。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 13
赞赏 0
下载 12739115
赞赏 1959
赞赏
京公网安备:11010802035340号