更新记录

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 用:断料和压库存是同一个问题的两面 —— 该备多少、什么时候下单,得算,不能凭感觉。

一张库存明细表进去,出来的是:每个料号的安全库存、再订货点、建议批量、还能卖几天,以及「紧急 / 待补 / 正常 / 超储 / 呆滞」五种状态。

购买前必读

  1. 只支持 Android(minSdkVersion 23,Android 6.0 起)。iOS 与鸿蒙本版本未实现,市场平台声明里已标不支持。
  2. 不连 ERP、不连数据库。插件只接受 CSV 文本 / 文件路径 / 结构化数组三种输入。数据怎么从 ERP 导出、算完怎么回写,是你那一层的集成工作;插件不猜你的表结构,也不用你的账号去读任何系统。
  3. 公式是教科书版本,参数得你自己给准。安全库存的准确度 90% 取决于「日均用量」和「日用量标准差」这两列准不准。拿三个月出库记录随手除一下天数,算出来的数字看着像模像样,其实是垃圾。插件会做体检提示(见下),但它替不了你对业务的理解。
  4. 服务水平不是越高越好。95% 到 99%,安全库存大概翻 1.4 倍;99% 到 99.9% 再翻 1.4 倍。多备的货是压着的钱,插件用 stockCurve 把这根曲线摊开给你看,选哪一档是经营决策。
  5. 不做需求预测。日均用量与标准差由你从历史数据算好再传进来。插件不猜未来,只把「给定这些波动,该备多少」算准。

解决什么问题

  • 「这个料还能撑几天?」 现有 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 件,而不是等库存掉到某个整数才动。

状态判定顺序

先看会不会断,再看压不压钱:

  1. 日均 ≤ 0 → 无消耗(不补货)
  2. 覆盖天数 < 提前期 → 紧急
  3. 可用量 < 再订货点 → 待补
  4. 距上次出库 ≥ 180 天 → 呆滞
  5. 覆盖天数 > 120 → 超储
  6. 其余 → 正常

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。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无系统权限。读取调用方用系统文件选择器交过来的文件(路径或 content:// 授权),写出走应用外部私有目录。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集、不上传任何数据,不访问网络,不写日志。库存明细只在内存中解析与计算;补货建议由调用方决定是否落盘,默认写应用外部私有目录。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。