# PDA 批次码 — 接口说明
> 模块:`MesBatchSnController` / `MesJbLogController`
> 权限:`mes:mesBatchSn:view`(列表/详情)、`mes:mesBatchSn:edit`(新增/绑定)、`mes:mesJbLog:api`(解绑)
> 服务地址示例:`http://127.0.0.1:8980`
> 绑定上限:系统配置 `mes.batch.count`(每批次最多绑定工件数)
> PDA 统一返回 `CommonResp`(`result` / `message` / `data`);PC 列表仍用 `listData`(直接返回 `Page`)。
> PDA 请统一使用 **POST**(表单或 query 参数均可)。
> **须先登录 MES**,请求携带会话(见下方「鉴权说明」)。
---
## 鉴权说明(Apifox / PDA 测试必读)
本模块接口**需要登录**,未登录或 Session 过期时,HTTP 状态码仍为 `200`,但响应体是 **HTML 登录页**(`
登录 - MES生产管理系统`),不是 JSON。
| 现象 | 原因 |
|------|------|
| 返回 HTML 登录页 | Cookie / `__sid` 失效、未登录、或账号无权限 |
| 返回 HTML **403 您的操作权限不足** | 已登录,但账号缺少接口所需权限(见下表) |
| Apifox 显示 200 但解析失败 | 把登录页 HTML 当成了 JSON |
**正确做法(任选其一):**
1. **Cookie 方式(Apifox 推荐)**
- 浏览器登录 MES → F12 → 复制 `jeesite.session.id`
- 请求头:`Cookie: jeesite.session.id=你的会话ID`
2. **参数方式(PDA 常用)**
- 每个请求附带:`__ajax=json`、`__sid=登录后的会话ID`
**Apifox 示例:**
```bash
curl --location --request POST \
'http://127.0.0.1:8980/js/a/mes/mesJbLog/getBatchInfo' \
--header 'Cookie: jeesite.session.id=你的会话ID' \
--data-urlencode 'batchSn=20260702172138' \
--data-urlencode '__ajax=json'
```
**权限要求:**
| 接口 | 权限 | 后台勾选位置 |
|------|------|----------------|
| `pda/listData` | `mes:mesBatchSn:view` | 生产管理 → 批次码记录表 |
| `createBatchSn` / `bindProduct` | `mes:mesBatchSn:edit` | 生产管理 → 批次码记录表 |
| `getBatchInfo` / `addSave` | `mes:mesJbLog:api` | **APP模块权限 → 批次解绑** |
> `getBatchInfo` 虽用于「批次详情查工件」,但代码挂在 `MesJbLogController`,权限标识为 `mes:mesJbLog:api`(与解绑共用)。PDA 测试账号须勾选此项,否则会 **403**。
授权后重新登录,成功时 `getBatchInfo` 应返回 JSON,`Content-Type` 含 `json`,`data` 为数组(可为 `[]`)。
---
## 页面流程(4 步)
```text
① pda/listData 批次码列表(模块首页)→ 点行时缓存整行 row
↓ 底部「新增批次码」
② mesBatchSn/createBatchSn 按产线自动生成批次码
↓ 点击列表中的批次码
③ mesJbLog/getBatchInfo 详情 — 仅刷新已绑定工件列表(data[])
↓ 详情头信息用 ① 的 row,不要用 ③ 拼批次头
④ mesBatchSn/bindProduct 扫描绑定工件码
mesJbLog/addSave 解绑单个工件码
```
---
## 1. 批次码列表(模块首页)
**请求URL:** `/js/a/mes/mesBatchSn/pda/listData`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| pageNo | 否 | int | 页码,默认 1 |
| pageSize | 否 | int | 每页条数,默认 20 |
| batchSn | 否 | string | 批次码 |
| lineSn | 否 | string | 产线编号 |
| isJs | 否 | string | `1` 未用完 / `2` 已用完 |
| createDate_gte | 否 | string | 创建时间起,`yyyy-MM-dd HH:mm` |
| createDate_lte | 否 | string | 创建时间止 |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesBatchSn/pda/listData?pageNo=1&pageSize=20'
```
**返回示例:**
```json
{
"result": "true",
"message": "成功",
"data": {
"pageNo": 1,
"pageSize": 20,
"count": 2,
"list": [
{
"id": "1999999999999999991",
"batchSn": "20260702172138",
"lineSn": "HEVXT",
"nums": 1,
"isJs": "1",
"instockStatus": "0",
"createBy": "system",
"createDate": "2026-07-02 17:21:38",
"updateDate": "2026-07-02 17:22:10"
}
]
}
}
```
**返回字段说明(data.list[] 单条):**
| 字段 | 类型 | 说明 |
|------|------|------|
| id | string | 主键,绑定工件时必传 |
| batchSn | string | 批次码(扫码值) |
| lineSn | string | 产线编号,如 HEVXT |
| nums | long | 已绑定工件数量 |
| isJs | string | `1` 未用完 / `2` 已用完 |
| instockStatus | string | `0` 待入库 / `1` 已入库 |
| createDate | string | 创建时间 |
**下一步:** 点「新增批次码」→ 接口 2;点某行批次码 → 接口 3,传 `batchSn`
---
## 2. 新增批次码
**请求URL:** `/js/a/mes/mesBatchSn/createBatchSn`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| lineSn | 是 | string | 产线编号 |
新建后状态为 **待装中**(`batchStatus=3`),经生产入库接口成功后才改为 **仓库中**(`0`)。
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesBatchSn/createBatchSn?lineSn=HEVXT'
```
**返回示例:**
```json
{
"result": "true",
"message": "成功",
"data": {
"batchSn": "20260707103045"
}
}
```
**失败示例:**
```json
{
"result": "false",
"message": "参数错误",
"data": null
}
```
**说明:** 批次码按 `yyyyMMddHHmmss` 自动生成,初始 `nums=0`
**下一步:** 回到列表刷新,或带 `batchSn` 进入接口 3 详情
---
## 3. 批次码详情 — 已绑定工件
**请求URL:** `/js/a/mes/mesJbLog/getBatchInfo`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| batchSn | 是 | string | 批次码 |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesJbLog/getBatchInfo?batchSn=20260702172138'
```
### 与 PC 详情页的关系(重要)
PC 端「批次码记录表详情」(`mesBatchSn/info`) 展示两块数据,**来源不同**:
| PC 页面区块 | 数据来源 | PDA 如何获取 |
|-------------|----------|--------------|
| 批次码、产线编号、创建人、创建/更新时间 | `MesBatchSn` 主表 | **接口 1 列表行**(点进详情时把该行缓存下来) |
| 产品信息(工件码、绑定时间) | `mes_product` 按 `batch_sn` 查询 | **本接口** `getBatchInfo` 的 `data[]` |
源码(`MesJbLogController.getBatchInfo`)逻辑:
1. 校验 `batchSn` 在 `mes_batch_sn` 中存在,不存在则失败
2. 查询 `mes_product.batch_sn = batchSn` 的工件列表
3. **`resp.setData(mp)` 只放 `List`,不把批次主表 `MesBatchSn` 放进响应**
因此:**不是接口漏了产品信息,而是批次头信息本来就不在这个接口里**;PDA 详情页需「列表行 + 本接口」拼出与 PC 一致的页面。
### 返回示例(实测 `batchSn=20260702172138`)
有绑定工件时:
```json
{
"result": "true",
"message": "成功",
"data": [
{
"isNewRecord": false,
"id": "2072880747628806144",
"createDate": "2026-07-03 11:10",
"updateDate": "2026-07-03 13:28",
"createBy": "system",
"updateBy": "system",
"sn": "0476966613765586",
"psn": "",
"title": "",
"state": "1",
"remark": "",
"batchSn": "20260702172138",
"weight": "",
"cate": "HEVXT",
"bindDate": "2026-07-03 13:28:50",
"bindBy": "system"
}
]
}
```
> 结构固定为 `MesProduct` 全字段;`id`、`bindBy`、`updateDate` 等随记录变化。`title` 在库中常为空;产品类型看 `cate`(如 `HEVXT`)。PC「产品信息」只展示 `sn`、`bindDate` 两列,与上表一致。
未绑定任何工件时(批次存在但 `nums=0`):
```json
{
"result": "true",
"message": "成功",
"data": []
}
```
**失败示例:**
```json
{
"result": "false",
"message": "批次信息不存在",
"data": null
}
```
### 返回字段说明
**`data[]` 单条(`MesProduct` 实体,Jackson 序列化全字段):**
| 字段 | 类型 | 说明 | PDA 详情是否常用 |
|------|------|------|------------------|
| sn | string | 工件码 | **是**(对应 PC「产品信息-工件码」) |
| bindDate | string | 绑定时间 `yyyy-MM-dd HH:mm` | **是**(对应 PC「产品信息-绑定时间」) |
| bindBy | string | 绑定人账号 | 可选 |
| batchSn | string | 所属批次码 | 可与入参对照 |
| title | string | 产品名称 | 库中常为空,不必展示 |
| cate | string | 产品类型/产线类别 | 有值时展示,如 `HEVXT` |
| state | string | 工件状态 | 字典 `mes_product_status` |
| psn / remark / weight | string | 生产批号、备注、重量 | 一般可忽略 |
| id / createDate / updateDate 等 | — | JeeSite 公共字段 | 可忽略 |
> PC 详情「产品信息」表格只渲染 `sn`、`bindDate` 两列;接口实际返回完整 `MesProduct`,字段比 PC 展示更多。
### PDA 详情页组装建议
```text
进入详情时携带列表行 row(接口 1):
row.batchSn、row.lineSn、row.nums、row.isJs、row.instockStatus、row.createDate …
再调 getBatchInfo(batchSn=row.batchSn):
data[] → 工件列表(sn、bindDate)
页面结构对齐 PC:
头部:批次码、产线编号(来自 row)
列表:产品信息(来自 data[])
底部:创建人、创建/更新时间(来自 row)
```
**下一步:** `row.isJs != '2'` 且 `row.instockStatus != '1'` 时可绑定 → 接口 4;每行工件可解绑 → 接口 5
---
## 4. 绑定工件码
**请求URL:** `/js/a/mes/mesBatchSn/bindProduct`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| id | 是 | string | 批次码记录主键(列表 `id`) |
| sn | 是 | string | 工件码(扫码或手输) |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesBatchSn/bindProduct' \
--data-urlencode 'id=1999999999999999991' \
--data-urlencode 'sn=WP202607020001'
```
**返回示例:**
```json
{
"result": "true",
"message": "绑定成功"
}
```
**常见失败 message:**
| message | 原因 |
|---------|------|
| 参数错误 | id 或 sn 为空 |
| 批次码不存在 | id 无效 |
| 当前批次码已用完,不能继续绑定 | isJs=2 |
| 该批次码已入库,不能继续绑定 | instockStatus=1 |
| 批次码绑定数量已满 | nums ≥ mes.batch.count |
| 工件码不存在 | sn 不在 mes_product |
| 该工件已绑定批次码 | 工件已有 batchSn |
**下一步:** 绑定成功后刷新接口 3
---
## 5. 解绑工件码
**请求URL:** `/js/a/mes/mesJbLog/addSave`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| batchSn | 是 | string | 批次码 |
| sn | 是 | string | 要解绑的工件码 |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesJbLog/addSave' \
--data-urlencode 'batchSn=20260702172138' \
--data-urlencode 'sn=WP202607020001'
```
**返回示例:**
```json
{
"result": "true",
"message": "操作成功",
"data": {}
}
```
**常见失败 message:**
| message | 原因 |
|---------|------|
| 参数错误 | batchSn 或 sn 为空 |
| 批次码信息不存在 | 批次码无效 |
| 当前批次已出货,不能解绑 | 已有出货记录 |
| 当前工件已解绑 | 该 sn 未绑定此批次 |
**说明:** 解绑单个工件,`nums` 自动减 1,并写入解绑记录
**下一步:** 解绑成功后刷新接口 3
---
## 附录 A:新增批次码(手工指定码,可选)
**请求URL:** `/js/a/mes/mesBatchSn/save`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| isNewRecord | 是 | boolean | 固定 `true` |
| lineSn | 是 | string | 产线编号 |
| batchSn | 否 | string | 留空则自动生成 |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesBatchSn/save' \
--data-urlencode 'isNewRecord=true' \
--data-urlencode 'lineSn=HEVXT'
```
---
## 附录 B:产线当前可用批次(产线侧辅助)
**请求URL:** `/js/a/mes/mesBatchSn/getBatchSn`
**请求方式:** `POST`
**参数:**
| 参数名 | 必选 | 类型 | 说明 |
|--------|------|------|------|
| lineSn | 是 | string | 产线编号 |
**参数示例:**
```bash
curl --location --request POST 'http://127.0.0.1:8980/js/a/mes/mesBatchSn/getBatchSn?lineSn=HEVXT'
```
**返回示例:**
```json
{
"result": "true",
"message": "成功",
"data": {
"batchSn": "20260702172138"
}
}
```
**说明:** 返回产线下未用完且未达绑定上限的批次码;无可用时 `batchSn` 为空字符串
---
## 与 ERP 生产入库的关系
批次码绑定工件后(`nums > 0`),可在 **PDA 生产入库** 模块勾选该批次提交 ERP 入库,详见 [PDA生产入库接口说明.md](./PDA生产入库接口说明.md)。入库成功后 `instockStatus=1`,不可再绑定。