# 商品管理 — 测试用例

> **依据：** 《商品管理功能需求.md》v1.3.3、《商品管理技术方案.md》v1.2  
> **说明：** 需求 v1.3.3 新增 P18～P21（商品服务快照），本用例 **待增补** 服务勾选/快照相关用例。  
> **范围：** **平台端** `/agri/goods`（列表、详情、审核、下架）与 **商家端** `/agri/seller/goods`（发布、编辑、提交上架、下架）；`IGoodsFacade` / `IGoodsPurchaseFacade.canPurchase`；协作 `GET /agri/goods/categoryOptions`  
> **排除：** 订单扣库存 E2E、多 SKU、C 端商城完整页面、会员体系、平台代发/导出；子管理员细粒度权限（有则另补）  
> **环境：** RuoYi v3.9.2；平台 Token + 商家 Token + `X-Shop-Id`；UI 分平台端与商家端两套 Playwright 套件

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| GDS-UT-xxx | 单元测试 | JUnit 5 + Mockito（状态机/Service/Facade） |
| GDS-API-xxx | 接口测试 | Apifox / REST Assured + Token |
| GDS-UI-xxx | 界面测试 | Playwright（Chromium/Chrome） |

---

## 一、单元测试

### GDS-UT-001 提交上架：未上架且免审关→待审核

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | submit 状态机 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 §3.1、P4 |
| **前置条件** | `goods_status=0`；**全局** `default_audit_pass=0` |
| **测试步骤** | `submit(goodsId)` |
| **预期结果** | `goods_status=1`；首次写入 `submit_time` |

### GDS-UT-002 提交上架：未上架且免审开→出售中

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | submit 状态机 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §4.3 |
| **前置条件** | `goods_status=0`；**全局** `default_audit_pass=1` |
| **测试步骤** | `submit(goodsId)` |
| **预期结果** | `goods_status=2` |

### GDS-UT-003 提交上架：审核失败/已下架可重新提交

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | submit 状态机 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §4.6 |
| **前置条件** | status=3 或 4；免审关 |
| **测试步骤** | 分别 `submit` |
| **预期结果** | 均变为 1（待审核） |

### GDS-UT-004 提交上架：待审核/出售中拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | submit 状态机 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证非法 submit |
| **前置条件** | status=1 或 2 |
| **测试步骤** | `submit` |
| **预期结果** | 失败；状态不变 |

### GDS-UT-005 平台审核通过 1→2

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | audit |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §4.4 |
| **前置条件** | `goods_status=1` |
| **测试步骤** | `audit(pass=true)` |
| **预期结果** | `goods_status=2`；`audit_time` 有值 |

### GDS-UT-006 平台审核驳回须填原因

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | audit |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P10 |
| **前置条件** | status=1；`rejectReason` 为空 |
| **测试步骤** | `audit(pass=false)` |
| **预期结果** | 校验失败；status 仍为 1 |

### GDS-UT-007 审核驳回 1→3 写入原因

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | audit |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证驳回流程 |
| **前置条件** | status=1 |
| **测试步骤** | `audit(pass=false, reason="资料不全")` |
| **预期结果** | `goods_status=3`；`reject_reason` 已存 |

### GDS-UT-008 下架仅出售中 2→4

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | offShelf |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P5 |
| **前置条件** | status=2 |
| **测试步骤** | `offShelf(goodsId)` |
| **预期结果** | `goods_status=4`；`off_shelf_time` 有值 |

### GDS-UT-009 下架非出售中拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | offShelf |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §4.5 |
| **前置条件** | status=1 |
| **测试步骤** | `offShelf` |
| **预期结果** | 失败；status 不变 |

### GDS-UT-010 商家保存待审核仍为待审核

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | PUT 保存 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P14 |
| **前置条件** | status=1；记录 `submit_time` |
| **测试步骤** | `updateGoods` 改名称 |
| **预期结果** | status=1；`submit_time` **不变** |

### GDS-UT-011 商家保存出售中仍为出售中

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | PUT 保存 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §3.4、P16 |
| **前置条件** | status=2 |
| **测试步骤** | 修改 `salePrice`、`stock` |
| **预期结果** | status=2；价格库存已更新 |

### GDS-UT-012 PUT 拒收 goodsStatus 字段

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | PUT 保存 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P17 |
| **前置条件** | status=0 |
| **测试步骤** | body 含 `goodsStatus=2` |
| **预期结果** | 拒收或忽略；库中仍为 0 |

### GDS-UT-013 不可改回未上架（P17）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 状态约束 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证无撤回草稿 |
| **前置条件** | status=2 |
| **测试步骤** | 尝试将 status 设为 0（若存在内部方法） |
| **预期结果** | 失败；msg「当前状态不可改为未上架」 |

### GDS-UT-014 商品编号生成唯一

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | goods_sn |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P2、P13 |
| **前置条件** | Mock 序号生成 |
| **测试步骤** | 连续 `insertGoods` 两次 |
| **预期结果** | 两条 `goods_sn` 不同；格式 `G`+日期+序号 |

### GDS-UT-015 分类须为本店二级

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | categoryId 校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 P1、§8.9 |
| **前置条件** | 一级分类 ID 或他店二级 |
| **测试步骤** | 新增/保存商品 |
| **预期结果** | 校验失败 |

### GDS-UT-016 平台列表 SQL 排除 status=0

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 平台 list |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P12 |
| **前置条件** | 店内有 status 0、1 各一 |
| **测试步骤** | `selectPlatformList` |
| **预期结果** | 结果集不含 status=0 |

### GDS-UT-017 批量审核含非待审整批失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 批量 audit |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P7 |
| **前置条件** | ID 列表含 status 1 与 2 |
| **测试步骤** | `auditBatch` |
| **预期结果** | 失败；两条 status 均未变 |

### GDS-UT-018 批量下架含非出售中整批失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 批量 offShelf |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §9.2 |
| **前置条件** | 含 status 2 与 4 |
| **测试步骤** | `offShelfBatch` |
| **预期结果** | 失败；均无变更 |

### GDS-UT-019 `hasBlockingGoodsForShopDelete`

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | IGoodsFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证删店前置 |
| **前置条件** | 店内有 status=2 或 1 商品 |
| **测试步骤** | `hasBlockingGoodsForShopDelete(shopId)` |
| **预期结果** | `true` |

### GDS-UT-020 `existsByCategoryId`

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | IGoodsFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证删分类前置 |
| **前置条件** | 未删商品指向 categoryId |
| **测试步骤** | `existsByCategoryId` |
| **预期结果** | `true` |

### GDS-UT-021 `canPurchase` 出售中+开业+库存>0

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | IGoodsPurchaseFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 §4.4 正向 |
| **前置条件** | status=2；stock=10；店铺开业；分类可见 |
| **测试步骤** | `canPurchase(goodsId)` |
| **预期结果** | `allowed=true` |

### GDS-UT-022 `canPurchase` 库存为 0 失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | IGoodsPurchaseFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P15 |
| **前置条件** | status=2；stock=0 |
| **测试步骤** | `canPurchase` |
| **预期结果** | `allowed=false`；reason 含库存 |

### GDS-UT-023 `canPurchase` 店铺停业失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | IGoodsPurchaseFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 P9 |
| **前置条件** | 商品出售中；`isShopOpenForOrder=false` |
| **测试步骤** | `canPurchase` |
| **预期结果** | `allowed=false`；reason 含停业 |

### GDS-UT-024 重新 submit 不更新 submit_time

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | submit |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §3.1、P14 |
| **前置条件** | 已下架；已有 `submit_time=T1` |
| **测试步骤** | 再次 `submit` |
| **预期结果** | 状态变 1；`submit_time` 仍为 T1 |

### GDS-UT-025 stock/salePrice 字段校验

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §8.9 |
| **前置条件** | `stock=-1` 或 `salePrice` 非法 |
| **测试步骤** | Validator 校验 |
| **预期结果** | 不通过 |

### GDS-UT-026 商户冻结不改变商品状态

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理 |
| **测试项** | 联动 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 P8 |
| **前置条件** | 商品 status=2 |
| **测试步骤** | 模拟商户冻结事件（无商品 Service 调用） |
| **预期结果** | `goods_status` 仍为 2 |

---

## 二、接口测试 — 平台端

### GDS-API-001 平台列表不含未上架

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | GET /agri/goods/list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 P12 |
| **前置条件** | 平台 Token `agri:goods:list`；存在未上架与待审核商品 |
| **测试步骤** | `GET /list` |
| **预期结果** | `rows` 无 `goodsStatus=0` |

### GDS-API-002 平台列表多条件检索

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6 |
| **前置条件** | 测试数据齐全 |
| **测试步骤** | 分别按 `goodsSn`、`goodsName`、`shopName`、`goodsStatus`、`categoryId` 查询 |
| **预期结果** | 结果均满足条件；`categoryPath` 为「一级 > 二级」 |

### GDS-API-003 平台商品详情与操作标志

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | GET /{goodsId} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7、§8.7 |
| **前置条件** | 待审核商品 |
| **测试步骤** | `GET /agri/goods/{id}` |
| **预期结果** | 含 `rejectReason`、`submitTime`；`canAudit=true`；`canOffShelf=false` |

### GDS-API-004 平台审核通过

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | PUT /audit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证审核主流程 |
| **前置条件** | `agri:goods:audit`；status=1 |
| **测试步骤** | `PUT /audit` body：`goodsIds`, `pass=true` |
| **预期结果** | `code=200`；`goodsStatus=2` |

### GDS-API-005 平台审核驳回缺原因失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | PUT /audit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 P10 |
| **前置条件** | status=1 |
| **测试步骤** | `pass=false` 且无 `rejectReason` |
| **预期结果** | 失败；仍为待审核 |

### GDS-API-006 批量审核含非待审整批失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | PUT /audit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §8.2 |
| **前置条件** | 勾选待审+出售中 |
| **测试步骤** | 批量 `pass=true` |
| **预期结果** | 失败；提示含「非待审核」；状态均未变 |

### GDS-API-007 平台下架出售中商品

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | PUT /offShelf |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §9 |
| **前置条件** | `agri:goods:offshelf`；status=2 |
| **测试步骤** | `PUT /offShelf` 传 `goodsIds` |
| **预期结果** | `goodsStatus=4` |

### GDS-API-008 批量下架含非出售中失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | PUT /offShelf |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §9.2 |
| **前置条件** | 含出售中与已下架 |
| **测试步骤** | 批量下架 |
| **预期结果** | 整批失败；均无变更 |

### GDS-API-009 平台无 audit 权限 403

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7 权限 |
| **前置条件** | 无 `agri:goods:audit` |
| **测试步骤** | `PUT /audit` |
| **预期结果** | HTTP 403 |

### GDS-API-010 categoryOptions 平台筛类协作

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | GET /categoryOptions |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证分类协作 |
| **前置条件** | `agri:goods:list`；`shopId` 有分类 |
| **测试步骤** | `GET /agri/goods/categoryOptions?shopId=1` |
| **预期结果** | 返回二级 `label` 全路径 |

---

## 三、接口测试 — 商家端

### GDS-API-011 商家列表含未上架

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | GET /agri/seller/goods/list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §10.5 |
| **前置条件** | 商家 Token；`X-Shop-Id`；本店有草稿 |
| **测试步骤** | `GET /list` |
| **预期结果** | 含 `goodsStatus=0` 记录 |

### GDS-API-012 商家发布商品生成编号

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证发布主流程 |
| **前置条件** | 本店二级分类；`agri:seller:goods:add` |
| **测试步骤** | `POST /` §4.2.2 样例 JSON |
| **预期结果** | `code=200`；`goodsStatus=0`；返回 `goodsSn` 非空 |

### GDS-API-013 商家保存草稿不进平台列表

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | POST + 平台 list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证未上架隔离 |
| **前置条件** | 新建草稿 ID |
| **测试步骤** | 平台 `GET /agri/goods/list` 搜编号 |
| **预期结果** | 查不到该商品 |

### GDS-API-014 提交上架→待审核（免审关）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | PUT /{id}/submit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 submit 主流程 |
| **前置条件** | 草稿；**全局** `default_audit_pass=0` |
| **测试步骤** | `PUT .../submit` |
| **预期结果** | `data.goodsStatus=1`；平台 list 可见 |

### GDS-API-015 提交上架→出售中（免审开）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | PUT /{id}/submit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证免审店 |
| **前置条件** | 草稿；**全局** `default_audit_pass=1` |
| **测试步骤** | `PUT .../submit` |
| **预期结果** | `data.goodsStatus=2` |

### GDS-API-016 待审核编辑后仍为待审核

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 P14 |
| **前置条件** | status=1；记录 `submitTime` |
| **测试步骤** | `PUT` 改 `goodsName` |
| **预期结果** | `goodsStatus=1`；`submitTime` 不变 |

### GDS-API-017 商家 PUT 传 goodsStatus 无效

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 P17 |
| **前置条件** | 草稿 |
| **测试步骤** | body 含 `goodsStatus=2` |
| **预期结果** | 仍为 0 或拒收 |

### GDS-API-018 商家下架本店出售中

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | PUT /{id}/offShelf |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §10.3 |
| **前置条件** | 本店 status=2 |
| **测试步骤** | `PUT .../offShelf` |
| **预期结果** | `goodsStatus=4` |

### GDS-API-019 已下架重新提交上架

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | submit |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §4.6 |
| **前置条件** | status=4；免审关 |
| **测试步骤** | 可选 `PUT` 改价后 `submit` |
| **预期结果** | 变为 1 |

### GDS-API-020 跨店访问他店商品失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | GET /{id} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证店铺隔离 |
| **前置条件** | 当前店 A；商品属店 B |
| **测试步骤** | `GET /agri/seller/goods/{id}` |
| **预期结果** | 404/无权 |

### GDS-API-021 缺少 X-Shop-Id 拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 店铺上下文 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §8.6 |
| **前置条件** | 商家 Token；无店铺头 |
| **测试步骤** | `POST /` |
| **预期结果** | 失败；「请先选择当前店铺」 |

### GDS-API-022 分类非本店二级失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 P1 |
| **前置条件** | 他店或一级分类 ID |
| **测试步骤** | `POST` 指定 `categoryId` |
| **预期结果** | 校验失败；未入库 |

---

## 四、界面测试 — 平台端（Playwright）

> **前置：** 平台管理员已登录；菜单「商品管理」。

### GDS-UI-001 平台商品列表加载

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 列表页 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Chrome) |
| **测试目的** | 验证 §5.1 |
| **前置条件** | `agri:goods:list` |
| **测试步骤** | 进入商品管理列表 |
| **预期结果** | 列含店铺、编号、名称、售价、库存、销量、状态；**无** 未上架状态 Tab/行 |

### GDS-UI-002 平台按状态筛选

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 检索 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §6 |
| **前置条件** | 存在待审核商品 |
| **测试步骤** | 状态选「待审核」→查询 |
| **预期结果** | 列表均为待审核 |

### GDS-UI-003 平台详情审核通过

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 审核 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §7.3 |
| **前置条件** | 待审核商品；有 audit 权限 |
| **测试步骤** | 详情→审核通过→确认 |
| **预期结果** | 状态变出售中；列表同步 |

### GDS-UI-004 平台审核驳回必填原因

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 审核 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 P10 UI |
| **前置条件** | 待审核商品 |
| **测试步骤** | 选不通过→不填原因提交 |
| **预期结果** | 表单校验；仍为待审核 |

### GDS-UI-005 平台批量审核整批失败提示

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 批量审核 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §8.2 |
| **前置条件** | 勾选待审+出售中 |
| **测试步骤** | 批量通过 |
| **预期结果** | Toast 含「非待审核」；均无变更 |

### GDS-UI-006 平台下架出售中二次确认

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 下架 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §9.3 |
| **前置条件** | 出售中商品 |
| **测试步骤** | 下架→确认框确定 |
| **预期结果** | 确认文案含「C 端不可购买」；状态已下架 |

### GDS-UI-007 平台列表待审核显示审核按钮

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 操作显隐 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §15 |
| **前置条件** | 待审与出售中各一行 |
| **测试步骤** | 查看操作列 |
| **预期结果** | 待审有「审核」无「下架」；出售中相反 |

### GDS-UI-008 平台详情展示分类路径与驳回原因

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（平台） |
| **测试项** | 详情 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §7.2 |
| **前置条件** | 审核失败商品 |
| **测试步骤** | 打开详情 |
| **预期结果** | 展示 `一级 > 二级`、店铺、驳回原因 |

---

## 五、界面测试 — 商家端（Playwright）

> **前置：** 店铺经营账号登录；已选当前店铺。

### GDS-UI-009 商家商品列表含未上架

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 列表 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §10.5 |
| **前置条件** | 本店有草稿 |
| **测试步骤** | 进入商品管理 |
| **预期结果** | 可见「未上架」状态行 |

### GDS-UI-010 商家发布商品保存草稿

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 发布 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §10.2 |
| **前置条件** | 已维护二级分类 |
| **测试步骤** | 发布→填必填项→保存 |
| **预期结果** | 成功；列表未上架；展示系统编号 |

### GDS-UI-011 商家提交上架（免审关）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 提交上架 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 submit UI |
| **前置条件** | 草稿；店铺免审关 |
| **测试步骤** | 点击「提交上架」 |
| **预期结果** | 状态变待审核；平台端可检索到 |

### GDS-UI-012 商家待审核编辑不自动通过

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 编辑 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 P14 UI |
| **前置条件** | 待审核商品 |
| **测试步骤** | 编辑名称保存 |
| **预期结果** | 仍为待审核；平台仍为待审 |

### GDS-UI-013 商家出售中可下架

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 下架 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §10.4 |
| **前置条件** | 出售中商品 |
| **测试步骤** | 下架→确认 |
| **预期结果** | 状态已下架 |

### GDS-UI-014 商家分类下拉仅二级

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 发布表单 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 P1、C5 |
| **前置条件** | 打开发布页 |
| **测试步骤** | 展开商品分类下拉 |
| **预期结果** | 选项为「一级 > 二级」格式；无一级直挂 |

### GDS-UI-015 切换店铺后商品列表刷新

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 店铺上下文 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §10.1 |
| **前置条件** | 商户下 A、B 店商品不同 |
| **测试步骤** | 店 A 列表→切换店 B |
| **预期结果** | 列表变为 B 店数据 |

### GDS-UI-016 审核失败商品重新提交

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 重新上架 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §4.6 UI |
| **前置条件** | 审核失败；展示驳回原因 |
| **测试步骤** | 修改后点「提交上架」 |
| **预期结果** | 进入待审核或出售中（视免审开关） |

### GDS-UI-017 商家端无直接改出售中入口

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | P17 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证状态入口 |
| **前置条件** | 编辑未上架商品 |
| **测试步骤** | 查看表单状态控件 |
| **预期结果** | **无** 状态下拉直选「出售中」；须用提交上架 |

### GDS-UI-018 页头展示当前店铺名称

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品管理（商家） |
| **测试项** | 多店铺 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证防误操作 |
| **前置条件** | 已选店 |
| **测试步骤** | 进入商品管理 |
| **预期结果** | 页头/顶栏显示当前店铺名 |

---

## 六、用例统计

| 类型 | 数量 | 编号段 |
|------|------|--------|
| 单元测试 | 26 | GDS-UT-001～026 |
| 接口测试 | 22 | GDS-API-001～022 |
| 界面测试 | 18 | GDS-UI-001～018 |
| **合计** | **66** | — |

---

## 七、业务规则覆盖索引

| 规则 | 含义 | 对应用例（示例） |
|------|------|------------------|
| P1 | 一店一二级分类 | GDS-UT-015, GDS-API-022, GDS-UI-014 |
| P2/P13 | 编号系统唯一 | GDS-UT-014, GDS-API-012 |
| P3/P12 | 五状态；未上架不进平台 | GDS-UT-016, GDS-API-001/011/013 |
| P4 | 免审开关决定 submit 目标 | GDS-UT-001/002, GDS-API-014/015 |
| P5 | 仅待审可审、仅出售中可下架 | GDS-UT-005/008/009, GDS-API-004/007 |
| P6/P7 | 下架后可重提；批量整批失败 | GDS-UT-017/018, GDS-API-006/008, GDS-UI-005 |
| P8 | 商户/店铺变更不改商品状态 | GDS-UT-026 |
| P9/P15 | 停业/库存与 canPurchase | GDS-UT-021～023 |
| P10 | 驳回必填原因 | GDS-UT-006, GDS-API-005, GDS-UI-004 |
| P14 | 待审编辑不通过 | GDS-UT-010, GDS-API-016, GDS-UI-012 |
| P16 | 单规格一价一库存 | GDS-UT-011, GDS-API-012 |
| P17 | 状态仅 submit/audit/offShelf | GDS-UT-012/013, GDS-API-017, GDS-UI-017 |

| 端 | 正常流程 | 异常/约束 |
|----|----------|-----------|
| 平台 | GDS-API-001～004/007, GDS-UI-001～008 | GDS-API-005/006/008/009 |
| 商家 | GDS-API-011～015/018/019, GDS-UI-009～013 | GDS-API-017/020/021/022 |
| Facade | GDS-UT-019～023 | — |

---

## 八、测试数据建议

| 数据 | 用途 |
|------|------|
| 店铺 A 免审关 / 店铺 B 免审开 | submit 目标状态 |
| 各状态商品各 1 条（0～4） | 状态机、列表筛选 |
| 本店二级分类 | 发布/提交 |
| 出售中+库存 0 | canPurchase |
| 停业未删店铺+出售中商品 | 停业禁单 |
| 待审+出售中混合 | 批量审核/下架失败 |
| 平台/商家两套账号权限 | 403 用例 |

---

## 九、Playwright 执行说明

**平台端 `playwright.config`：**

```typescript
use: { baseURL: process.env.PLATFORM_URL || 'http://localhost:80', ...devices['Desktop Chrome'] }
```

**商家端（须带店铺）：**

```typescript
use: {
  baseURL: process.env.SELLER_URL || 'http://localhost:80/seller',
  extraHTTPHeaders: { 'X-Shop-Id': process.env.SHOP_ID || '1' },
}
```

**商家登录片段：**

```typescript
await page.goto('/login');
await page.fill('input[name="username"]', process.env.SELLER_USER!);
await page.fill('input[name="password"]', process.env.SELLER_PASS!);
await page.click('button:has-text("登")');
await page.getByText('张三农资店').click(); // 选当前店
await page.getByRole('menuitem', { name: '商品管理' }).click();
```

> **GDS-UI-001～008** 用平台配置；**GDS-UI-009～018** 用商家配置；选择器按实际 DOM 调整。

---

*文档版本：v1.0 · 关联《商品管理功能需求.md》v1.3.3、《商品管理技术方案.md》v1.2 · P18～P21 用例待补*
