前端对接包花厂集采

包花厂集采 11-04 接口变更

不参与等级免报价、货架按场次品种等级供应商分、供货单返回配货进度、多人同时盘点;覆盖供应商小程序、仓库 PDA、运营后台

端
供应商小程序 / 仓库 PDA / 运营后台
后端服务
supplier + admin
状态
已上测
测试分支
supplier/test + bulky-test/admin
更新
2026-11-04
接口数
17

Markdown 原文(给 AI 用):https://doc.xfun.fun/bulk-purchase-1104-api.md

总览

2026-11-04 包花厂集采四项改动里,需要前端对接的部分:

#接口端变化
①POST /bulkPurchase/quote/submit供应商小程序只传参与的等级,不参与的等级不填价
②POST /bulkPurchase/quote/update供应商小程序同 ①
③POST /bulkPurchase/quote/adjustPrice供应商小程序只填参与的等级
④POST /bulkPurchase/demand/detail供应商小程序不参与的等级 mySupplyLabelNum、myPrice 为 null
⑤POST /bulkPurchase/quote/history供应商小程序新版本 rankPrices 只含参与的等级
⑥POST /bulkPurchase/order/list供应商小程序返回 printedLabelNum、scannedLabelNum;新增 ranks[].printedLabelNum、ranks[].shelfCode
⑦POST /bulkPurchase/order/detail供应商小程序同 ⑥
⑧POST /wms/bulkPurchase/order/list仓库 PDA新增 shelfCodes;关键字可搜任一等级货架
⑨POST /wms/bulkPurchase/order/detail仓库 PDA新增 shelfCodes、ranks[].shelfCode、ranks[].printedLabelNum
⑩POST /wms/bulkPurchase/print/page仓库 PDA新增 ranks[].shelfCode;标签 shelfCode 为等级货架
⑪POST /wms/bulkPurchase/print/normal、/print/reprint仓库 PDA返回标签的 shelfCode 为等级货架
⑫POST /wms/bulkPurchase/label/resolve仓库 PDAshelfCode 为标签等级的货架;inventoryName 恒为 null
⑬POST /wms/bulkPurchase/scan仓库 PDA不需要先开始盘点;按货架扫码时不传 orderId
⑭POST /wms/bulkPurchase/inventory/start、/inventory/release仓库 PDA可以不调用
⑮POST /wms/bulkPurchase/scan/revoke、/inventory/submit仓库 PDA任何仓库人员都可操作
⑯POST /bulkPurchase/order/detail运营后台新增 ranks[].shelfCode
⑰POST /bulkPurchase/confirm/quoteList运营后台新报价的 rankPrices 只含参与的等级

通用约定

枚举

枚举取值
rankCode 等级0 无等级 · 1 A · 2 B · 3 C · 4 D · 5 E · 6 O
status 供货单状态10 待签到 · 20 待盘点 · 30 待结算 · 40 已结算 · 90 已取消
rejectReason 扫码拒绝原因null 成功 · 2 重复扫码 · 3 标签已作废 · 4 属于其他供货单 · 5 标签不存在 · 6 供货单状态不允许盘点

货架码口径

后面接口里的 shelfCode、shelfCodes 都按这里的口径。

字段含义
ranks[].shelfCode该等级的货架码,摆货、贴标看这个。同场次、同品种、同等级、同供应商的供货单是同一个值,不同供应商不同,格式 A-001:场次内流水,满 999 进位到 B-001,如 A-007
shelfCodes仓库端供货单列表、详情:这张单各等级的货架码,按等级顺序去重,如 ["A-007","A-008"]
整单 shelfCode第一个中选等级的货架,只用于排序和兼容旧页面。一张单有多个等级时,不能只展示它
标签 shelfCode该标签等级的货架码

例:同场次两份玫瑰计划,供应商甲中选 A、B 级,乙中选 A 级:

text
甲的供货单:ranks[A].shelfCode = A-001,ranks[B].shelfCode = A-002,shelfCodes = ["A-001","A-002"]
乙的供货单:ranks[A].shelfCode = A-001,shelfCodes = ["A-001"]

接口

POST/bulkPurchase/quote/submit首次提交报价

变更:不参与的等级可以不传;传了且可供扎数为 0 时不填价格

请求参数

字段类型必填说明
demandIdLong必填采购计划 ID
rankPricesList必填各等级报价,至少一个等级的可供扎数大于 0
rankPrices[].rankCodeInteger必填等级,见枚举 rankCode;只能传计划开放的等级,同一等级不能重复
rankPrices[].supplyLabelNumInteger可选可供扎数。0 或不填表示不参与该等级
rankPrices[].priceBigDecimal可选单价(元/扎)。可供扎数大于 0 时必填;可供为 0 时不填,传了也忽略

参与的等级(可供扎数大于 0)仍要满足:可供扎数 ≥ 该等级最小提交量、≤ 最大提交量、≤ 收购扎数(含追加);价格大于 0、最多两位小数、不高于该等级最高价、不超过 1000 元。

请求示例

计划开放 A、B、C 三个等级,只供 A、B:

json
{
  "demandId": 58,
  "rankPrices": [
    { "rankCode": 1, "supplyLabelNum": 600, "price": 2.50 },
    { "rankCode": 2, "supplyLabelNum": 200, "price": 1.80 }
  ]
}

C 级也可以写成 { "rankCode": 3, "supplyLabelNum": 0 },效果相同。

响应

成功时 data 为 "报价提交成功"。

响应示例

json
{ "code": 0, "msg": "success", "data": "报价提交成功", "message": "success", "valid": true }

错误码 / 失败文案

msg触发场景前端处理
该需求不包含等级 C传了计划没开放的等级toast;表单只展示计划开放的等级
至少要有一个等级的可供扎数大于 0全部等级都不参与toast
同一等级不能重复出现rankCode 重复toast
A 级价格必须大于0参与的等级没填价或填 0toast,定位到该等级
A 级可供 50 扎,低于该等级最小提交量 100 扎;不供这个等级请填 0参与的等级可供量不足toast
A 级报价 3.10 元/扎,超过该等级最高价 3.00 元/扎价格超过最高价toast

规则

POST/bulkPurchase/quote/update修改报价

变更:入参、规则、失败文案同「POST /bulkPurchase/quote/submit · 首次提交报价」

成功时 data 为 "报价修改成功"。内容与当前版本完全一致时不生成新版本。

POST/bulkPurchase/quote/adjustPrice定采前调价

变更:只需填当前报价中参与的等级(可供扎数大于 0)

请求参数

字段类型必填说明
demandIdLong必填采购计划 ID
reasonString必填调价原因
rankPricesList必填必须包含当前报价中全部参与的等级;其他等级传了也忽略
rankPrices[].rankCodeInteger必填等级,见枚举 rankCode
rankPrices[].priceBigDecimal必填新单价(元/扎)

请求示例

json
{
  "demandId": 58,
  "reason": "市场价下调",
  "rankPrices": [
    { "rankCode": 1, "price": 2.40 },
    { "rankCode": 2, "price": 1.70 }
  ]
}

响应

成功时 data 为 "报价修改成功"。

响应示例

json
{ "code": 0, "msg": "success", "data": "调价成功", "message": "success", "valid": true }

错误码 / 失败文案

msg触发场景前端处理
需要对 A、B 全部参与供货的等级填写价格漏填参与的等级toast
您没有参与供货的等级,无法调价当前报价没有可供扎数大于 0 的等级toast
同一等级不能重复出现rankCode 重复toast

POST/bulkPurchase/demand/detail集采需求详情

变更:不参与的等级我的报价为空

请求参数

字段类型必填说明
idLong必填采购计划 ID

请求示例

json
{ "id": 58 }

响应

只列本次有变化的字段,其余不变。

字段类型说明
ranks[].rankCodeInteger等级,列出计划开放的全部等级
ranks[].mySupplyLabelNumInteger我在该等级报的可供扎数;不参与或未报为 null,表单回填为空
ranks[].myPriceBigDecimal我在该等级报的单价;不参与或未报为 null

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": {
    "id": 58,
    "ranks": [
      { "rankCode": 1, "mySupplyLabelNum": 600, "myPrice": 2.50 },
      { "rankCode": 2, "mySupplyLabelNum": 200, "myPrice": 1.80 },
      { "rankCode": 3, "mySupplyLabelNum": null, "myPrice": null }
    ]
  }
}
说明

前端按「可供为 0 或 null 即不参与」统一处理。

POST/bulkPurchase/quote/history我的报价版本历史

变更:新版本的 rankPrices 只含参与的等级

同一份历史里各版本参与的等级可能不同,按 rankCode 对齐展示,缺的等级显示「不参与」。

POST/bulkPurchase/order/list我的供货单列表

变更:返回配货进度 printedLabelNum、scannedLabelNum;新增 ranks[].printedLabelNum、ranks[].shelfCode

请求参数

字段类型必填说明
pageIndexInteger可选页码,从 1 开始,默认 1
pageSizeInteger可选每页条数,默认 10
statusInteger可选见枚举 status;不传为全部
roundNoString可选场次 yyyy-MM-dd
keywordString可选供货单号 / 需求编号

请求示例

json
{ "pageIndex": 1, "pageSize": 10, "status": 30 }

响应

只列本次新增的字段。

字段类型说明
records[].printedLabelNumInteger变更。整单已打标签扎数,各等级 printedLabelNum 之和;配货进度的分母
records[].scannedLabelNumInteger变更。整单已扫码入库扎数,各等级 scannedLabelNum 之和;配货进度的分子
records[].shelfCodeString整单货架码,口径见「货架码口径」
records[].ranks[].shelfCodeString新增。该等级的货架码
records[].ranks[].printedLabelNumInteger新增。该等级已打标签扎数(包花厂打印生成的标签张数,一张一扎)
records[].ranks[].scannedLabelNumInteger该等级已扫码入库扎数(盘点扫码合格)
说明

配货进度 = scannedLabelNum / printedLabelNum。printedLabelNum 为 0 时还没打标签,显示「未打标签」,不要算百分比。撤销扫码后 scannedLabelNum 会减少;补打、增量打印会让 printedLabelNum 增加,重打不变。

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": {
    "current": 1, "size": 10, "total": 1,
    "records": [
      {
        "id": 43,
        "orderNo": "GH20261026364310",
        "shelfCode": "A-001",
        "printedLabelNum": 40,
        "scannedLabelNum": 18,
        "ranks": [
          { "rankCode": 2, "rankName": "B", "shelfCode": "A-001", "confirmLabelNum": 500, "printedLabelNum": 30, "scannedLabelNum": 15 },
          { "rankCode": 3, "rankName": "C", "shelfCode": "A-002", "confirmLabelNum": 300, "printedLabelNum": 10, "scannedLabelNum": 3 }
        ]
      }
    ]
  }
}

POST/bulkPurchase/order/detail我的供货单详情

变更:返回 printedLabelNum、scannedLabelNum;新增 ranks[].printedLabelNum、ranks[].shelfCode,含义同「POST /bulkPurchase/order/list · 我的供货单列表」

请求参数

字段类型必填说明
idLong必填供货单 ID

请求示例

json
{ "id": 43 }

POST/wms/bulkPurchase/order/list待作业供货单列表

变更:新增 shelfCodes;关键字可搜任一等级的货架码;按整单货架码 + ID 排序

请求参数

字段类型必填说明
pageIndexInteger可选页码,从 1 开始,默认 1
pageSizeInteger可选每页条数,默认 10
keywordString可选供货单号 / 货架码 / 供应商 / 品种 / 需求编号;输入任一等级的货架码都能搜到这张单,所以按货架找单直接搜货架码
roundNoString可选场次 yyyy-MM-dd
statusInteger可选见枚举 status

请求示例

json
{ "pageIndex": 1, "pageSize": 10, "roundNo": "2026-11-05", "keyword": "A-001" }

响应

只列本次新增的字段。

字段类型说明
records[].shelfCodesList新增。这张单各等级的货架码,按等级顺序去重;列表上展示这个,不要只展示整单 shelfCode

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": {
    "current": 1, "size": 10, "total": 2,
    "records": [
      { "id": 31, "orderNo": "GH2026110510019000001", "supplierName": "甲花卉", "shelfCode": "A-001", "shelfCodes": ["A-001", "A-002"] },
      { "id": 32, "orderNo": "GH2026110510019000002", "supplierName": "乙花卉", "shelfCode": "A-001", "shelfCodes": ["A-001"] }
    ]
  }
}

POST/wms/bulkPurchase/order/detail供货单详情

变更:新增 shelfCodes、ranks[].shelfCode,含义见「货架码口径」

请求参数

字段类型必填说明
idLong必填供货单 ID

请求示例

json
{ "id": 31 }

POST/wms/bulkPurchase/print/page打印页数据

变更:新增 ranks[].shelfCode;ranks[].labels[].shelfCode 为该等级的货架码

请求参数

字段类型必填说明
idLong必填供货单 ID

请求示例

json
{ "id": 31 }

响应

字段类型说明
shelfCodeString整单货架码,口径见「货架码口径」
ranks[].shelfCodeString新增。该等级的货架码,打印页按等级分组展示
ranks[].labels[].shelfCodeString变更。标签上印的货架码,为该标签等级的货架

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": {
    "orderId": 31,
    "orderNo": "GH2026110510019000001",
    "shelfCode": "A-001",
    "ranks": [
      { "rankCode": 1, "rankName": "A", "shelfCode": "A-001",
        "labels": [ { "labelCode": "GH2026110510019000001-1-0001", "rankCode": 1, "seqNo": 1, "shelfCode": "A-001" } ] },
      { "rankCode": 2, "rankName": "B", "shelfCode": "A-002",
        "labels": [ { "labelCode": "GH2026110510019000001-2-0001", "rankCode": 2, "seqNo": 1, "shelfCode": "A-002" } ] }
    ]
  }
}

POST/wms/bulkPurchase/print/normal正常/增量打印

变更:返回标签的 shelfCode 为该标签等级的货架码,入参不变

POST /wms/bulkPurchase/print/reprint(重打)返回的标签同样按等级货架码。

POST/wms/bulkPurchase/label/resolve首码识别供货单

变更:shelfCode 为标签等级的货架;inventoryName 恒为 null

请求参数

字段类型必填说明
labelCodeString必填标签码

请求示例

json
{ "labelCode": "GH2026110510019000001-2-0001" }

响应

只列本次有变化的字段。

字段类型说明
shelfCodeString变更。该标签等级所在货架码
inventoryNameString变更。恒为 null,不提示「某某正在盘点」

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": { "scannable": true, "orderId": 31, "orderNo": "GH2026110510019000001", "rankCode": 2, "seqNo": 1, "shelfCode": "A-002", "inventoryName": null }
}

POST/wms/bulkPurchase/scan扫码盘点

变更:不需要先调「开始盘点」;按货架连续扫码时不传 orderId

请求参数

字段类型必填说明
labelCodeString必填标签码
orderIdLong可选当前作业的供货单 ID。传了:扫到别家标签会被拒(rejectReason = 4),适合按单盘点;不传:扫到哪张单的标签就计入哪张单,适合按货架扫(同一供应商多个计划的单会放在同一个货架)

请求示例

按货架扫:

json
{ "labelCode": "GH2026110510019000002-1-0003" }

响应

字段类型说明
successBoolean是否计数成功
rejectReasonInteger拒绝原因,见枚举 rejectReason
messageString提示文案,直接展示
actualLabelNumInteger传了 orderId 时返回该单累计实际产出;不传为 null
ranksList传了 orderId 时返回该单各等级进度(含 ranks[].shelfCode);不传为 null

响应示例

json
{
  "code": 0, "msg": "success", "message": "success", "valid": true,
  "data": { "success": true, "rejectReason": null, "message": "扫码成功", "actualLabelNum": null, "ranks": null }
}
注意

扫码响应外层 code 恒为 0,被拒时看 data.success = false 和 data.message,不能只看外层。

POST/wms/bulkPurchase/inventory/start开始盘点

变更:不占用供货单,扫码不依赖它,可以不调

只校验供货单处于待盘点,返回 "已开始盘点"。POST /wms/bulkPurchase/inventory/release(暂停盘点)直接返回 "已暂停",没有任何作用。PDA 可以去掉「开始 / 暂停盘点」按钮。

POST/wms/bulkPurchase/scan/revoke撤销扫码

变更:任何仓库人员都能撤销任何人扫的标签

入参 labelCode 不变。供货单须仍在待盘点。POST /wms/bulkPurchase/inventory/submit(提交盘点)同样任何仓库人员都能提交。

POST/bulkPurchase/order/detail运营后台供货单详情

变更:新增 ranks[].shelfCode

请求参数

字段类型必填说明
idLong必填供货单 ID

请求示例

json
{ "id": 31 }

响应

字段类型说明
shelfCodeString整单货架码,口径见「货架码口径」
ranks[].shelfCodeString新增。该等级的货架码

响应示例

json
{
  "code": 0, "msg": "success",
  "data": {
    "id": 31, "orderNo": "GH2026110510019000001", "shelfCode": "A-001",
    "ranks": [
      { "rankCode": 1, "rankName": "A", "shelfCode": "A-001", "confirmLabelNum": 100 },
      { "rankCode": 2, "rankName": "B", "shelfCode": "A-002", "confirmLabelNum": 0 }
    ]
  }
}

运营后台供货单列表 POST /bulkPurchase/order/list 只返回整单 shelfCode,不带等级货架,也不支持按货架码搜索。

POST/bulkPurchase/confirm/quoteList定采报价列表

变更:新报价的 rankPrices 只含参与的等级

报价只含可供大于 0 的等级。按计划等级画固定列时,缺的等级显示「不参与」或「-」,不要显示 0 元。

联调注意

注意

同一供应商同场次同品种有多个计划时,几张单的同等级货放在同一个货架。PDA 如果「先选单再连续扫」并传了 orderId,扫到同货架另一张单的标签会提示「该标签属于其他供货单」。按货架扫码请不传 orderId。