前端对接仓库配货 / 打包

打包负责人物资申领

负责人提交(含批量)/撤销申领,仓管分批出库、手动完成、拒绝;状态机、按钮显隐字段、出库记录,以及进销存出入库权限与库房库存口径

端
梦花仓管小程序
后端服务
gallery
更新
2026-11-04
接口数
14

Markdown 原文(给 AI 用):https://doc.xfun.fun/wms-material-apply-api.md

梦花仓管小程序 · 进销存

后端模块 xm-bulky-mall-gallery(与 /supplier/wms/inventory/* 同一服务)。

通用约定

跟 /supplier/wms/inventory/* 一样:base https://api.xunmengvip.cn/xm-bulky-mall-gallery,全部 POST + JSON body,鉴权、{ code, msg, data, success } 包装(success 是布尔,等价于 code === 0;失败时 HTTP 状态码仍是 200,别用状态码判断成败)、index / size 分页都照旧。失败响应的 msg 是可以直接 toast 的中文,速查见「报错文案速查」。

说明

入参怪癖

/apply/sku/stock、/apply/detail、/apply/cancel、/apply/finish 复用通用的 IdQo,入参字段名都叫 id。其中 /apply/sku/stock 的 id 传的是 skuId,不是申领单 ID,其余才是申领单 ID。

角色与状态机

后端从两处判定当前账号的身份,不需要前端传角色来鉴权:

角色判定依据能做什么
仓库管理员账号命中配置的仓管角色看全部申领单、出库、手动完成、拒绝。不能提交申领(除非同时也是负责人)
打包负责人xm_bulky_team.leader_id = 当前账号,且团队为启用状态提交申领、撤销自己提交且未出库的单、只看自己带的大区的单
两者都不是—调任意申领接口都会收到 无物资申领权限

一个账号可以同时是仓管和负责人,这种情况下列表默认看全部;前端有「角色切换」时,把当前视角作为 roleName 传给 /apply/page(见「POST /supplier/wms/apply/page」)。

申领单状态

status名称说明
10待审核负责人提交后的初始态。此时 库存不动,不占用、不冻结
20审核通过历史数据状态,新单据不会再进入该状态
30已拒绝仓管拒绝,rejectReason 可能为空字符串。仅未出库的待审核单可拒
40已撤销申领人本人撤回,仅未出库的待审核单可撤
50部分申领已出库但累计出库数量 < 申领数量,可继续出库或手动完成
60已完成累计出库 = 申领数量时自动完成,或仓管对部分申领单手动完成
text
10 待审核 ──出库(未领满)──▶ 50 部分申领 ──出库(领满)──▶ 60 已完成(completeType=1 自动)
   │   └──出库(一次领满)─────────────────────────────▶ 60 已完成(completeType=1 自动)
   │                       50 部分申领 ──手动完成────▶ 60 已完成(completeType=2 手动)
   ├──拒绝──▶ 30 已拒绝
   └──撤销──▶ 40 已撤销

completeType:0 未完成、1 自动完成、2 手动完成、3 历史完成。

说明

待审核不占库存

提交时只校验一次「申领数量 ≤ 库房剩余可用」,之后不做任何预占。所以两张待审核的单可能都显示能发,实际出库时第二张可能因库房库存不够失败。出库失败的 toast 要能正常展示,不要假设提交通过就一定能足量出库。

说明

手动完成不补数也不退库

手动完成只是关闭单据:issuedQuantity、remainingQuantity、progressPercent 保持完成时的值,不再允许出库,也不调整任何库存。

负责人侧

POST/supplier/wms/apply/sku/stock查询物资库房剩余可用库存

调用方:负责人 / 仓管

选好物资后调用,用于在申领数量输入框旁边展示「当前可申领上限」,也可用于出库弹窗展示库房可发数量。

请求参数

字段类型必填说明
idLong必填物资 SKU ID(不是申领单 ID),取自 /supplier/wms/inventory/sku/list 的 skuId

响应

字段类型说明
skuIdLong物资 SKU ID
skuNameString物资名称(即「物资类别」)
specificationString物资规格
unitNameString计量单位
availableStockInteger库房剩余可用 = 全局实物 − 各大区已分配剩余

响应示例

json
{
  "skuId": 1012,
  "skuName": "打包纸箱",
  "specification": "60×40×40",
  "unitName": "个",
  "availableStock": 320
}

POST/supplier/wms/apply/create提交物资申领

调用方:仅负责人

请求参数

字段类型必填说明
skuIdLong必填物资 SKU ID
teamIdInteger可选申领大区。负责人只带 1 个大区时可以不传;带多个大区必传,不传报「请选择申领大区」。传了非自己带的大区报「无权为该大区申领」
quantityInteger必填申领数量,≥ 1 且不能超过 availableStock
voucherUrlsString可选凭证图片,JSON 数组的字符串,不是数组对象。最多 5 个元素,整串 ≤ 512 字符;不传或空串表示无凭证
remarkString可选备注,≤ 255 字符
重要

voucherUrls 是字符串,不是数组

后端字段类型是 String,前端要自己 JSON.stringify 后再放进 body。512 字符是整串长度,包含引号和逗号,OSS 地址长的话 5 张可能放不下,提交前先量一次 voucherUrls.length。

请求示例

json
{ "skuId": 1012, "teamId": 3, "quantity": 50, "voucherUrls": "[\"https://oss/a.jpg\",\"https://oss/b.jpg\"]", "remark": "本周加班" }

传 "voucherUrls": ["https://oss/a.jpg"](数组对象)会报「凭证图片格式错误」。

响应

字段类型说明
idLong新建申领单 ID,可直接跳详情或生成二维码
applyNoString申领单号,SL + yyyyMMdd + 3 位序列
skuIdLong申领物资 SKU ID

响应示例

json
{ "id": 88, "applyNo": "SL20261104001", "skuId": 1012 }

POST/supplier/wms/apply/batchCreate批量提交物资申领

调用方:仅负责人

同一物资类别(skuName 相同)下一次申领多个规格,每个规格各生成一张申领单。整批在一个事务里,任一规格校验失败整批不提交。

请求参数

字段类型必填说明
itemsArray必填规格明细,1 ~ 100 项,skuId 不能重复,且必须属于同一物资类别
items[].skuIdLong必填物资 SKU ID
items[].quantityInteger必填申领数量,≥ 1 且不能超过该规格的 availableStock
teamIdInteger可选申领大区,规则同「POST /supplier/wms/apply/create」
voucherUrlsString可选本批共用的凭证图片,格式同单个提交
remarkString可选本批共用的备注,≤ 255 字符

请求示例

json
{
  "teamId": 3,
  "items": [
    { "skuId": 1012, "quantity": 50 },
    { "skuId": 1013, "quantity": 20 }
  ],
  "remark": "本周加班"
}

响应

data 为数组,每项字段同「POST /supplier/wms/apply/create」的响应(id / applyNo / skuId),顺序按 skuId 升序。

POST/supplier/wms/apply/cancel撤销物资申领

调用方:仅申领人本人

入参 { "id": 申领单ID },响应 data 为 null。

只有 申领人本人、单据处于 待审核且 尚未出库时才能撤销,否则返回 仅申请人可以撤销尚未出库的待审核申领单。并发下状态已被别人改掉时返回 申领单状态已变更,请刷新后重试,收到后刷新列表。

列表与详情

POST/supplier/wms/apply/page申领列表

调用方:负责人 / 仓管

请求参数

字段类型必填说明
indexInteger可选页码,默认 1
sizeInteger可选页大小,默认 10
statusInteger可选10/20/30/40/50/60,不传查全部。传其他值报「申领状态不合法」
skuIdLong可选物资 SKU ID
teamIdInteger可选申领大区 ID
startTimeString可选申请开始时间,yyyy-MM-dd HH:mm:ss,按申领时间 ≥ 过滤
endTimeString可选申请结束时间,yyyy-MM-dd HH:mm:ss,按申领时间 ≤ 过滤;早于 startTime 报「开始时间不能晚于结束时间」
roleNameString可选当前视角角色名。传 "打包负责人" 时只看自己带的大区
说明

roleName 的作用范围

  • 非仓管账号:无论传不传 roleName,永远只能看到自己带的大区的单。
  • 仓管账号:默认看全部;只有当它 同时也是负责人、且传了 roleName="打包负责人" 时,才收窄到自己带的大区。
  • 字符串必须 精确等于 打包负责人,拼错就当没传。与 /supplier/wms/inventory/team/list 的 roleName 是同一套约定。

列表按申领单 ID 倒序。

响应

records[] 单项:

字段类型说明
idLong申领单 ID
applyNoString申领单号
teamIdInteger申领大区 ID
teamNameString申领大区名称
skuIdLong申领物资 SKU ID
skuNameString物资名称(即「物资类别」)
specificationString物资规格
unitNameString计量单位
applicantNameString申领负责人姓名
applyQuantityInteger申领数量
issuedQuantityInteger累计出库数量,未出库为 0
remainingQuantityInteger未出库数量 = 申领数量 − 累计出库数量
progressPercentNumber出库进度百分比,保留两位小数,如 40.00
statusInteger申领状态,见「申领单状态」
statusDescString状态中文,直接展示
rejectReasonString拒绝原因,未拒绝或仓管没填时为空字符串
createTimeDateTime申领时间
auditTimeDateTime拒绝时间或历史审批时间,可能为 null
completeTypeInteger完成方式:0 未完成、1 自动完成、2 手动完成、3 历史完成
completeTimeDateTime完成时间,未完成为 null
completeOperatorIdLong完成人 ID
completeOperatorNameString完成人名称(自动完成时为最后一次出库人)
canCancelBoolean是否显示「撤销」:待审核、未出库、本人提交
canAuditBoolean是否显示「拒绝」:待审核、未出库、当前账号是仓管
canOutboundBoolean是否显示「出库」:待审核或部分申领、仍有剩余、当前账号是仓管
canFinishBoolean是否显示「手动完成」:部分申领、当前账号是仓管

响应示例

json
{
  "id": 88,
  "applyNo": "SL20261104001",
  "teamId": 3,
  "teamName": "昆明一区",
  "skuId": 1012,
  "skuName": "打包纸箱",
  "specification": "60×40×40",
  "unitName": "个",
  "applicantName": "李四",
  "applyQuantity": 50,
  "issuedQuantity": 20,
  "remainingQuantity": 30,
  "progressPercent": 40.00,
  "status": 50,
  "statusDesc": "部分申领",
  "rejectReason": "",
  "createTime": "2026-11-04 09:12:33",
  "auditTime": null,
  "completeType": 0,
  "completeTime": null,
  "completeOperatorId": 0,
  "completeOperatorName": "",
  "canCancel": false,
  "canAudit": false,
  "canOutbound": true,
  "canFinish": true
}
提示

按钮显隐直接用 can* 字段

这四个布尔是后端按「状态 + 出库进度 + 当前账号」算好的,不要在前端自己推。同一条单据对不同人返回的值不同,这是预期的。

POST/supplier/wms/apply/detail申领详情

调用方:仓管 / 本大区负责人

入参 { "id": 申领单ID }。返回列表项的全部字段,另外多出:

字段类型说明
remarkString申领备注,无备注时为空字符串
voucherInfoString[]这里是真数组,可直接喂给图片预览组件(提交时是字符串,返回时是数组)
auditorNameString拒绝人或历史审批人姓名,没有时为空字符串
outboundRecordsArray出库记录,按出库时间、明细 ID 升序,字段见「POST /supplier/wms/apply/item/page」
cancelTimeDateTime撤销时间,未撤销为 null
cancelOperatorIdLong撤销操作人 ID
cancelOperatorNameString撤销操作人名称

非仓管账号查非自己大区的单,返回 申领记录不存在(不是无权限),前端按「记录不存在」处理即可。

POST/supplier/wms/apply/item/page出库记录分页

调用方:仓管 / 本大区负责人

请求参数

字段类型必填说明
idLong必填申领单 ID
indexInteger可选页码,默认 1
sizeInteger可选页大小,默认 10

响应

records[] 单项,按出库时间、明细 ID 升序:

字段类型说明
idLong出库明细 ID
applyIdLong所属申领单 ID
quantityInteger本次出库数量
issuedQuantityInteger本次出库后的累计出库数量
entryIdLong本次生成的大区入库批次 ID
traceIdLong本次生成的库房出库流水 ID
operatorIdLong出库操作人 ID
operatorNameString出库操作人名称
createTimeDateTime出库时间

可见范围同详情:非仓管查非自己大区的单返回 申领记录不存在。

仓管操作

POST/supplier/wms/apply/outbound申领出库

调用方:仅仓管

对待审核或部分申领的单出库一次,可多次分批出库。每次出库从库房划拨到申领大区(生成一条大区入库批次和一条库房出库流水),并按累计数量自动流转状态:未领满 → 50 部分申领,领满 → 60 已完成(completeType=1)。

请求参数

字段类型必填说明
idLong必填申领单 ID
quantityInteger必填本次出库数量,≥ 1,且 ≤ 剩余可出库数量(remainingQuantity)、≤ 当前库房剩余可用

请求示例

json
{ "id": 88, "quantity": 20 }

响应

字段类型说明
itemIdLong本次新增的出库明细 ID
quantityInteger本次出库数量
issuedQuantityInteger本次出库后的累计出库数量
remainingQuantityInteger未出库数量
progressPercentNumber出库进度百分比,保留两位小数
statusInteger出库后的申领状态(50 或 60)

响应示例

json
{ "itemId": 501, "quantity": 20, "issuedQuantity": 20, "remainingQuantity": 30, "progressPercent": 40.00, "status": 50 }
注意

15 秒防重

同一张申领单 15 秒内只能出库一次(/outbound 与 /approve 共用),重复点击返回 该申领单过去15秒内进行过出库,请刷新页面,确认未进行重复操作后再次点击。出库按钮提交后要置灰,成功后刷新详情。

出库弹窗建议把数量默认填成 remainingQuantity,上限取 remainingQuantity 与 /apply/sku/stock 的 availableStock 的较小值。

POST/supplier/wms/apply/approve申领出库(兼容入口)

调用方:仅仓管

与「POST /supplier/wms/apply/outbound」逻辑完全相同,只是数量字段名不同,响应也相同。新页面直接用 /outbound。

字段类型必填说明
idLong必填申领单 ID
issuedQuantityInteger必填本次出库数量,规则同 /outbound 的 quantity

POST/supplier/wms/apply/finish手动完成

调用方:仅仓管

入参 { "id": 申领单ID },响应 data 为 null。

只有 部分申领(已出库且未领满)的单可以手动完成,否则返回 仅部分申领单可以手动完成。完成后状态 60、completeType=2,记录完成时间和完成人;数量和库存都不变。对已完成的单重复调用直接返回成功。

POST/supplier/wms/apply/reject拒绝申领

调用方:仅仓管

入参 { "id": 申领单ID, "rejectReason": "库存留给昆明二区" }。rejectReason 后端 不强制(≤ 255 字符),产品要求必填请前端自己拦。响应 data 为 null。

只有 待审核且未出库的单能拒绝;已出库(部分申领)的单不能拒绝,只能手动完成。

说明

并发下的统一反馈

出库、手动完成、拒绝、撤销都带状态条件更新。两个仓管同时操作,后操作的那个会拿到 申领单状态已变更,请刷新后重试 或 申领单状态已变更或不允许出库,请刷新后重试。收到这类文案时自动刷新列表并关闭弹窗。

进销存出入库权限与库存口径

申领链路依赖下面三个进销存接口的规则,前端出入库页、库存页要按此渲染。

POST/supplier/wms/inventory/inbound/create新增入库

仅仓库管理员可调用,非仓管返回 非仓库管理员,无进销存操作权限。仓管可以选库房或任意大区入库,入口按角色隐藏即可。

POST/supplier/wms/inventory/outbound/create新增出库

出库来源谁能操作不满足时的报错
teamId = 0(库房)仅仓库管理员非仓库管理员,无进销存操作权限
teamId > 0(大区)仓库管理员,或 该大区的打包负责人无该大区出库权限

打包负责人可以登记本大区的物资消耗,但不能从库房直接出货(库房物资通过申领出库发到大区)。出库页的团队选择器按角色渲染:仓管给全量,负责人只给 /supplier/wms/inventory/team/list 传 roleName="打包负责人" 后返回的大区。

POST/supplier/wms/inventory/stock/page库存页

teamId = 0 那一行的 teamStock 是「库房剩余可用」:

text
库房剩余可用 = 全局实物库存 − Σ(各大区批次剩余)

大区行的 teamStock 是该大区剩余。每行都带 availableStock,值同库房剩余可用;欠库时两者都允许为负数。全局实物库存字段不在手机端返回。

提示

发到大区的物资不在库房行重复展示,所以库房行比全局实物小。文案上建议把库房行标成「库房剩余可用」,避免仓管以为库存丢了。

搭页面时会用到的进销存接口

申领相关页面不需要新的下拉数据接口,直接复用:

用途接口说明
选申领大区/supplier/wms/inventory/team/list传 {"roleName":"打包负责人"} 拿到「库房 + 自己带的大区」。申领页要把 teamId=0 的库房项过滤掉,只留大区。只有 1 个大区时可以隐藏选择器、提交时不传 teamId
选物资/supplier/wms/inventory/sku/list传 {"skuName":"纸箱"} 或 {"specification":"60"} 模糊搜。返回 skuId / skuName / specification / unitName。「物资类别」对应 skuName,「物资规格」对应 specification

推荐的提交页交互顺序

  1. team/list(带 roleName)→ 过滤掉库房 → 大区下拉;只有一个就选中并隐藏
  2. sku/list → 物资类别 / 规格下拉,选中拿到 skuId;同一类别多选规格时走 batchCreate
  3. apply/sku/stock(id 传 skuId)→ 展示「库房剩余可用 N 个」,作为数量输入框的 max
  4. 上传凭证(可选)→ JSON.stringify(urls),本地先校验张数 ≤ 5、长度 ≤ 512
  5. apply/create 或 apply/batchCreate → 用返回的 id 跳详情或回列表刷新

报错文案速查

msg出现在建议处理
无物资申领权限全部申领接口既不是仓管也不是负责人,隐藏整个申领入口;提交接口非负责人也报此文案
非仓库管理员,无进销存操作权限outbound / approve / finish / reject / 库房出入库隐藏仓管操作按钮
无该大区出库权限inventory/outbound/create出库页团队下拉按角色收窄
请选择申领大区create / batchCreate负责人带多个大区却没传 teamId,前端设为必填
无权为该大区申领create / batchCreateteamId 不在自己带的大区里,一般是前端串了数据
物资不存在或已停用sku/stock / create / outbound刷新物资下拉
规格[60×40×40]库存不足或数量不合法,最大可申请量: 320create / batchCreate重新拉 sku/stock 刷新上限
每批须包含1至100个规格batchCreate限制多选数量
重复规格: 1012batchCreate同一规格只能出现一次
批量申领包含不存在或停用的规格batchCreate刷新物资下拉
批量申领只能选择同一物资类别batchCreate只允许在同一 skuName 下多选规格
凭证图片最多上传5张create / batchCreate上传组件限 5 张
凭证图片URL文本不能超过512个字符create / batchCreate提交前本地量长度
凭证图片格式错误create / batchCreate大概率是传了数组而不是字符串
申领状态不合法pagestatus 只能传 10/20/30/40/50/60
开始时间不能晚于结束时间page校验时间区间
申领记录不存在detail / item/page / 各操作接口越权查看或单据已删,回列表
仅申请人可以撤销尚未出库的待审核申领单cancel刷新列表,按 canCancel 显隐
仅部分申领单可以手动完成finish刷新详情,按 canFinish 显隐
本次出库数量不能超过剩余可出库数量outbound / approve出库弹窗 max = remainingQuantity
库房库存不足,当前可发数量: 12outbound / approve改小数量,或先入库再出
该申领单过去15秒内进行过出库,请刷新页面,确认未进行重复操作后再次点击outbound / approve刷新详情确认出库记录
申领单状态已变更或不允许出库,请刷新后重试outbound / approve自动刷新列表并关弹窗
申领单状态已变更,请刷新后重试cancel / finish / reject / outbound自动刷新列表并关弹窗

联调注意