Files
my-mom-system/mom-backend/docs/Testing/采购计划单-API测试文档.md
2026-03-06 02:12:34 +08:00

710 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 采购计划单 后端 API 测试文档
> 依据 PRD《mom系统采购计划单-页面开发说明文档》与后端 `MpPurchaseController` 编写,用于接口联调与测试。
> 采购计划单为扁平表结构erp_mp_purchase同一 purchase_code 下可有多条物料记录。
---
## 1. 约定说明
| 项目 | 说明 |
|------|------|
| 基础路径 | 网关/应用根路径 + 下表 path`http://host:port/erp/mp/purchase` |
| 认证 | 需登录态,请求头带 Token`Authorization: Bearer xxx` |
| 分页 | 列表接口支持 `pageNum``pageSize`,响应含 `rows``total` |
| 通用响应 | 非分页接口通常为 `{ code, msg, data }`code=200 表示成功 |
| 单据状态 | PREPARE=开立/草稿, APPROVED=已审核, REJECTED=退回 |
| 业务状态 | NORMAL=正常, PAUSE=暂停, CANCEL=取消, COMPLETED=完成 |
---
## 2. 接口总览
| 序号 | 功能 | 方法 | 路径 | 说明 |
|------|------|------|------|------|
| 1 | 明细视图列表 | GET | `/erp/mp/purchase/list` | 扁平列表,每行一条物料 |
| 2 | 单据视图列表 | GET | `/erp/mp/purchase/docList` | 按 purchase_code 聚合 |
| 3 | 底部汇总 | GET | `/erp/mp/purchase/summary` | 采购数量/已订数量合计 |
| 4 | 获取详情(ID) | GET | `/erp/mp/purchase/{purchaseId}` | 按 ID 获取单条记录 |
| 5 | 获取详情(编码) | GET | `/erp/mp/purchase/detail/{purchaseCode}` | 表头+明细行聚合 |
| 6 | 生成编码 | GET | `/erp/mp/purchase/genCode` | 生成 CGJH000XXX |
| 7 | 新增 | POST | `/erp/mp/purchase` | 创建采购计划 |
| 8 | 修改 | PUT | `/erp/mp/purchase` | 更新采购计划 |
| 9 | 删除(ID) | DELETE | `/erp/mp/purchase/{purchaseIds}` | 按 ID 删除(支持多个) |
| 10 | 删除(编码) | DELETE | `/erp/mp/purchase/byCode/{purchaseCode}` | 按编码删除整单 |
| 11 | 审核 | PUT | `/erp/mp/purchase/approve/{purchaseIds}` | 批量审核 |
| 12 | 反审核 | PUT | `/erp/mp/purchase/unapprove/{purchaseIds}` | 批量反审核 |
| 13 | 导出 | POST | `/erp/mp/purchase/export` | 导出 Excel |
| 14 | 从MBOM生成 | POST | `/erp/mp/purchase/generate/{mbomId}` | 根据物料清单生成 |
---
## 3. 接口详细说明
### 3.1 明细视图列表GET /erp/mp/purchase/list
**请求参数Query**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| pageNum | integer | 否 | 页码,默认 1 |
| pageSize | integer | 否 | 每页条数,默认 100 |
| salesOrderCode | string | 否 | 销售订单号/跟单单号(模糊) |
| purchaseCode | string | 否 | 单据编码(模糊) |
| itemCode | string | 否 | 物料编码(模糊) |
| itemName | string | 否 | 物料名称(模糊) |
| needType | integer | 否 | 用料需求0=订单用料1=库存备料 |
| params[beginDate] | string | 否 | 开始日期 yyyy-MM-dd |
| params[endDate] | string | 否 | 结束日期 yyyy-MM-dd |
| params[itemTypeId] | string | 否 | 物料分类ID快捷筛选 |
**响应示例:**
```json
{
"total": 70,
"rows": [
{
"purchaseId": 31,
"purchaseCode": "CGJH000033",
"purchaseDate": "2026-02-06",
"status": "APPROVED",
"businessType": "原材料",
"businessStatus": "NORMAL",
"needType": 0,
"salesOrderCode": "XSDD000091",
"deliveryDate": "2026-02-27",
"planCode": "SCJH000096",
"itemId": 100,
"itemCode": "1000000002",
"itemName": "微星 MAG B760M MORTAR WIFI DDR5 主板",
"specification": "",
"unitName": "台",
"demandQty": 60.00,
"availableQty": -30.00,
"purchaseQty": 60.00,
"orderedQty": 0.00,
"operatorName": "admin"
}
],
"code": 200,
"msg": "查询成功"
}
```
**curl 测试命令:**
```bash
# 明细视图 - 基本查询
curl -X GET "http://localhost:8080/erp/mp/purchase/list?pageNum=1&pageSize=100&needType=0" \
-H "Authorization: Bearer {token}"
# 明细视图 - 按销售订单号搜索
curl -X GET "http://localhost:8080/erp/mp/purchase/list?salesOrderCode=XSDD000091&pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
# 明细视图 - 按物料编码搜索
curl -X GET "http://localhost:8080/erp/mp/purchase/list?itemCode=1000000002&pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
# 明细视图 - 按日期范围搜索
curl -X GET "http://localhost:8080/erp/mp/purchase/list?params%5BbeginDate%5D=2026-02-01&params%5BendDate%5D=2026-02-28&pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
```
---
### 3.2 单据视图列表GET /erp/mp/purchase/docList
**请求参数Query**
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| pageNum | integer | 否 | 页码,默认 1 |
| pageSize | integer | 否 | 每页条数,默认 100 |
| purchaseCode | string | 否 | 单据编码(模糊) |
| status | string | 否 | 单据状态PREPARE/APPROVED/REJECTED |
| businessStatus | string | 否 | 业务状态NORMAL/PAUSE/CANCEL/COMPLETED |
| needType | integer | 否 | 用料需求 |
| params[beginDate] | string | 否 | 开始日期 |
| params[endDate] | string | 否 | 结束日期 |
**响应示例:**
```json
{
"total": 31,
"rows": [
{
"purchaseId": 31,
"purchaseCode": "CGJH000033",
"purchaseDate": "2026-02-06",
"status": "APPROVED",
"businessType": "原材料",
"businessStatus": "NORMAL",
"deptName": "采购部",
"operatorName": "admin",
"approverName": "admin",
"approveDate": "2026-02-06 14:30:00",
"purchaseQty": 180.00,
"orderedQty": 60.00
}
],
"code": 200,
"msg": "查询成功"
}
```
**curl 测试命令:**
```bash
# 单据视图 - 基本查询
curl -X GET "http://localhost:8080/erp/mp/purchase/docList?pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
# 单据视图 - 按状态筛选(仅草稿)
curl -X GET "http://localhost:8080/erp/mp/purchase/docList?status=PREPARE&pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
# 单据视图 - 按业务状态筛选
curl -X GET "http://localhost:8080/erp/mp/purchase/docList?businessStatus=NORMAL&pageNum=1&pageSize=100" \
-H "Authorization: Bearer {token}"
```
---
### 3.3 底部汇总GET /erp/mp/purchase/summary
返回当前查询条件下的采购数量和已订数量合计。查询条件与明细视图列表一致。
**响应示例:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"totalPurchaseQty": 15084075.00,
"totalOrderedQty": 68549.00
}
}
```
**curl 测试命令:**
```bash
# 汇总 - 全量
curl -X GET "http://localhost:8080/erp/mp/purchase/summary" \
-H "Authorization: Bearer {token}"
# 汇总 - 带搜索条件
curl -X GET "http://localhost:8080/erp/mp/purchase/summary?salesOrderCode=XSDD000091" \
-H "Authorization: Bearer {token}"
```
---
### 3.4 获取详情 - 按 IDGET /erp/mp/purchase/{purchaseId}
返回单条采购计划记录(扁平结构,对应一个物料行)。
**curl 测试命令:**
```bash
curl -X GET "http://localhost:8080/erp/mp/purchase/31" \
-H "Authorization: Bearer {token}"
```
---
### 3.5 获取详情 - 按编码GET /erp/mp/purchase/detail/{purchaseCode}
按 purchaseCode 聚合返回表头+物料明细行,用于查看/编辑页面。
**响应示例:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"purchaseCode": "CGJH000032",
"purchaseDate": "2026-02-07",
"status": "PREPARE",
"businessType": "原材料",
"businessStatus": "NORMAL",
"needType": 0,
"planId": 96,
"planCode": "SCJH000096",
"salesOrderId": 81,
"salesOrderCode": "XSDD000081",
"salesUserName": "周桂东",
"deliveryDate": "2026-01-23",
"deptId": null,
"deptName": null,
"operatorId": 1,
"operatorName": "admin",
"operatorName2": null,
"approverId": null,
"approverName": null,
"approveDate": null,
"totalQuantity": 170,
"remark": null,
"headerItemCode": "0103000002",
"headerItemName": "组装电脑5400",
"lines": [
{
"purchaseId": 101,
"purchaseCode": "CGJH000032",
"itemCode": "1000000001",
"itemName": "英特尔Core i5-14600KF",
"specification": "",
"unitName": "台",
"demandDate": "2026-02-18",
"demandQty": 10.00,
"availableQty": -30.00,
"purchaseQty": 170.00,
"orderedQty": 0.00,
"remark": ""
},
{
"purchaseId": 102,
"purchaseCode": "CGJH000032",
"itemCode": "1000000002",
"itemName": "微星 MAG B760M 主板",
"specification": "",
"unitName": "台",
"demandDate": "2026-02-18",
"demandQty": 10.00,
"availableQty": 5.00,
"purchaseQty": 5.00,
"orderedQty": 0.00,
"remark": ""
}
]
}
}
```
**curl 测试命令:**
```bash
curl -X GET "http://localhost:8080/erp/mp/purchase/detail/CGJH000032" \
-H "Authorization: Bearer {token}"
```
---
### 3.6 生成编码GET /erp/mp/purchase/genCode
自动生成下一个采购计划编码格式CGJH + 6位流水号。
**响应示例:**
```json
{
"code": 200,
"msg": "操作成功",
"data": "CGJH000034"
}
```
**curl 测试命令:**
```bash
curl -X GET "http://localhost:8080/erp/mp/purchase/genCode" \
-H "Authorization: Bearer {token}"
```
---
### 3.7 新增采购计划POST /erp/mp/purchase
新增单条物料的采购计划记录。若需创建包含多条物料的单据,需多次调用此接口使用相同的 purchaseCode。
**请求体:**
```json
{
"purchaseCode": "CGJH000034",
"purchaseDate": "2026-02-07",
"businessType": "原材料",
"businessStatus": "NORMAL",
"needType": 0,
"planId": 96,
"planCode": "SCJH000096",
"salesOrderId": 81,
"salesOrderCode": "XSDD000081",
"salesUserName": "周桂东",
"deliveryDate": "2026-01-23",
"itemId": 201,
"itemCode": "1000000001",
"itemName": "英特尔Core i5-14600KF",
"specification": "",
"unitName": "台",
"demandQty": 170.00,
"demandDate": "2026-02-18",
"availableQty": -30.00,
"purchaseQty": 170.00,
"totalQuantity": 170,
"remark": ""
}
```
**响应示例:**
```json
{
"code": 200,
"msg": "操作成功",
"purchaseId": 201
}
```
**curl 测试命令:**
```bash
curl -X POST "http://localhost:8080/erp/mp/purchase" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"purchaseCode": "CGJH000034",
"purchaseDate": "2026-02-07",
"businessType": "原材料",
"needType": 0,
"planCode": "SCJH000096",
"salesOrderCode": "XSDD000081",
"itemCode": "1000000001",
"itemName": "英特尔Core i5-14600KF",
"unitName": "台",
"demandQty": 170.00,
"purchaseQty": 170.00
}'
```
---
### 3.8 修改采购计划PUT /erp/mp/purchase
更新单条采购计划记录,必须包含 purchaseId。
**请求体:**
```json
{
"purchaseId": 201,
"purchaseQty": 200.00,
"demandDate": "2026-02-20",
"remark": "修改采购数量"
}
```
**curl 测试命令:**
```bash
curl -X PUT "http://localhost:8080/erp/mp/purchase" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"purchaseId": 201,
"purchaseQty": 200.00,
"remark": "修改采购数量"
}'
```
---
### 3.9 删除 - 按 IDDELETE /erp/mp/purchase/{purchaseIds}
批量删除(逻辑删除)。仅允许草稿(PREPARE)和退回(REJECTED)状态。
**路径参数:**
| 参数名 | 类型 | 说明 |
|--------|------|------|
| purchaseIds | Long[] | 采购计划ID多个用逗号分隔 |
**curl 测试命令:**
```bash
# 单条删除
curl -X DELETE "http://localhost:8080/erp/mp/purchase/201" \
-H "Authorization: Bearer {token}"
# 批量删除
curl -X DELETE "http://localhost:8080/erp/mp/purchase/201,202,203" \
-H "Authorization: Bearer {token}"
```
**错误场景测试:**
```bash
# 尝试删除已审核状态的记录(应返回错误)
curl -X DELETE "http://localhost:8080/erp/mp/purchase/31" \
-H "Authorization: Bearer {token}"
# 预期: {"code": 500, "msg": "编码为[CGJH000033]的单据不是草稿/退回状态,不允许删除!"}
```
---
### 3.10 删除 - 按编码DELETE /erp/mp/purchase/byCode/{purchaseCode}
按采购计划编码删除同一单据下所有物料行(单据视图使用)。
**curl 测试命令:**
```bash
curl -X DELETE "http://localhost:8080/erp/mp/purchase/byCode/CGJH000034" \
-H "Authorization: Bearer {token}"
```
---
### 3.11 审核PUT /erp/mp/purchase/approve/{purchaseIds}
批量审核采购计划。支持逗号分隔的 ID 字符串。同一 purchaseCode 下所有行同时审核。
**路径参数:**
| 参数名 | 类型 | 说明 |
|--------|------|------|
| purchaseIds | String | 采购计划ID多个用逗号分隔 |
**前置条件:** 单据状态必须为 PREPARE草稿
**curl 测试命令:**
```bash
# 单条审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/approve/201" \
-H "Authorization: Bearer {token}"
# 批量审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/approve/201,202,203" \
-H "Authorization: Bearer {token}"
```
**响应示例:**
```json
{
"code": 200,
"msg": "成功审核 3 条单据"
}
```
**错误场景测试:**
```bash
# 尝试审核已审核的记录
curl -X PUT "http://localhost:8080/erp/mp/purchase/approve/31" \
-H "Authorization: Bearer {token}"
# 预期: {"code": 500, "msg": "编码为[CGJH000033]的单据不是草稿状态,不能审核!"}
```
---
### 3.12 反审核PUT /erp/mp/purchase/unapprove/{purchaseIds}
批量反审核采购计划。支持逗号分隔的 ID 字符串。同一 purchaseCode 下所有行同时反审核。
反审核后状态变为 PREPARE草稿清空审核员和审核日期。
**路径参数:**
| 参数名 | 类型 | 说明 |
|--------|------|------|
| purchaseIds | String | 采购计划ID多个用逗号分隔 |
**前置条件:** 单据状态必须为 APPROVED已审核
**curl 测试命令:**
```bash
# 单条反审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/unapprove/31" \
-H "Authorization: Bearer {token}"
# 批量反审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/unapprove/31,32,33" \
-H "Authorization: Bearer {token}"
```
**响应示例:**
```json
{
"code": 200,
"msg": "成功反审核 1 条单据"
}
```
**错误场景测试:**
```bash
# 尝试反审核草稿状态的记录
curl -X PUT "http://localhost:8080/erp/mp/purchase/unapprove/201" \
-H "Authorization: Bearer {token}"
# 预期: {"code": 500, "msg": "编码为[CGJH000034]的单据不是已审核状态,不能反审核!"}
```
---
### 3.13 导出POST /erp/mp/purchase/export
导出采购计划列表到 Excel 文件。请求参数与明细视图列表一致。
**curl 测试命令:**
```bash
curl -X POST "http://localhost:8080/erp/mp/purchase/export" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-o "采购计划单.xlsx"
```
---
### 3.14 从 MBOM 生成采购计划POST /erp/mp/purchase/generate/{mbomId}
根据物料清单(MBOM)中供应方式为"采购"的物料,自动生成采购计划。
**路径参数:**
| 参数名 | 类型 | 说明 |
|--------|------|------|
| mbomId | Long | 物料清单ID |
**curl 测试命令:**
```bash
curl -X POST "http://localhost:8080/erp/mp/purchase/generate/1" \
-H "Authorization: Bearer {token}"
```
**响应示例:**
```json
{
"code": 200,
"msg": "成功生成 5 条采购计划"
}
```
---
## 4. 典型测试流程
### 4.1 完整业务流程测试
```bash
# 步骤1: 生成编码
curl -X GET "http://localhost:8080/erp/mp/purchase/genCode" -H "Authorization: Bearer {token}"
# 记录返回的编码,如 CGJH000034
# 步骤2: 新增采购计划(第一条物料)
curl -X POST "http://localhost:8080/erp/mp/purchase" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"purchaseCode": "CGJH000034",
"purchaseDate": "2026-02-07",
"businessType": "原材料",
"needType": 0,
"itemCode": "1000000001",
"itemName": "英特尔Core i5-14600KF",
"unitName": "台",
"demandQty": 170.00,
"purchaseQty": 170.00
}'
# 记录返回的 purchaseId
# 步骤3: 新增同单据第二条物料
curl -X POST "http://localhost:8080/erp/mp/purchase" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"purchaseCode": "CGJH000034",
"purchaseDate": "2026-02-07",
"businessType": "原材料",
"needType": 0,
"itemCode": "1000000002",
"itemName": "微星 MAG B760M 主板",
"unitName": "台",
"demandQty": 170.00,
"purchaseQty": 170.00
}'
# 步骤4: 查询明细视图,验证新增数据
curl -X GET "http://localhost:8080/erp/mp/purchase/list?purchaseCode=CGJH000034" \
-H "Authorization: Bearer {token}"
# 步骤5: 查询单据视图,验证聚合
curl -X GET "http://localhost:8080/erp/mp/purchase/docList?purchaseCode=CGJH000034" \
-H "Authorization: Bearer {token}"
# 步骤6: 查询详情
curl -X GET "http://localhost:8080/erp/mp/purchase/detail/CGJH000034" \
-H "Authorization: Bearer {token}"
# 步骤7: 查询汇总
curl -X GET "http://localhost:8080/erp/mp/purchase/summary?purchaseCode=CGJH000034" \
-H "Authorization: Bearer {token}"
# 步骤8: 审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/approve/{purchaseId}" \
-H "Authorization: Bearer {token}"
# 步骤9: 验证审核后状态
curl -X GET "http://localhost:8080/erp/mp/purchase/detail/CGJH000034" \
-H "Authorization: Bearer {token}"
# 预期: status=APPROVED, approverName 不为空
# 步骤10: 反审核
curl -X PUT "http://localhost:8080/erp/mp/purchase/unapprove/{purchaseId}" \
-H "Authorization: Bearer {token}"
# 步骤11: 验证反审核后状态
curl -X GET "http://localhost:8080/erp/mp/purchase/detail/CGJH000034" \
-H "Authorization: Bearer {token}"
# 预期: status=PREPARE, approverName=null
# 步骤12: 删除
curl -X DELETE "http://localhost:8080/erp/mp/purchase/byCode/CGJH000034" \
-H "Authorization: Bearer {token}"
```
### 4.2 边界条件测试
| 测试点 | 操作 | 预期结果 |
|--------|------|----------|
| 删除已审核单据 | DELETE /erp/mp/purchase/{已审核ID} | 返回错误:不允许删除 |
| 审核非草稿单据 | PUT /approve/{非PREPARE的ID} | 返回错误:不是草稿状态 |
| 反审核非审核单据 | PUT /unapprove/{非APPROVED的ID} | 返回错误:不是已审核状态 |
| 查询不存在的编码 | GET /detail/CGJH999999 | 返回错误:采购计划单不存在 |
| 重复编码新增 | POST 使用已存在的编码 | 返回错误:编码已存在 |
| 空列表汇总 | GET /summary?purchaseCode=不存在 | 返回 {totalPurchaseQty: 0, totalOrderedQty: 0} |
---
## 5. PRD 对照验证
| PRD 接口要求 | 后端实现 | 状态 |
|-------------|----------|------|
| 查询采购计划列表 (明细视图) | GET /erp/mp/purchase/list | ✅ 已实现 |
| 查询采购计划列表 (单据视图) | GET /erp/mp/purchase/docList | ✅ 已实现 |
| 底部汇总统计 | GET /erp/mp/purchase/summary | ✅ 已实现 |
| 获取详情 (按ID) | GET /erp/mp/purchase/{purchaseId} | ✅ 已实现 |
| 获取详情 (按编码, 表头+明细) | GET /erp/mp/purchase/detail/{purchaseCode} | ✅ 已实现 |
| 生成采购计划编码 | GET /erp/mp/purchase/genCode | ✅ 已实现 |
| 新增采购计划 | POST /erp/mp/purchase | ✅ 已实现 |
| 修改采购计划 | PUT /erp/mp/purchase | ✅ 已实现 |
| 删除采购计划 (按ID) | DELETE /erp/mp/purchase/{purchaseIds} | ✅ 已实现 |
| 删除采购计划 (按编码) | DELETE /erp/mp/purchase/byCode/{purchaseCode} | ✅ 已实现 |
| 审核采购计划 (支持批量) | PUT /erp/mp/purchase/approve/{purchaseIds} | ✅ 已实现 |
| 反审核采购计划 (支持批量) | PUT /erp/mp/purchase/unapprove/{purchaseIds} | ✅ 已实现 |
| 导出 | POST /erp/mp/purchase/export | ✅ 已实现 |
| 从MBOM生成 | POST /erp/mp/purchase/generate/{mbomId} | ✅ 已实现 |
| 生产计划列表 (引入用) | 复用 GET /erp/mp/plan/list | ✅ 已有 |
| 物料选择 | 复用 GET /md/item/list (或类似) | ✅ 已有 |