# 商品服务管理 — 测试用例

> **依据：** 《商品服务管理功能需求.md》v1.0.1、《商品服务管理技术方案.md》v1.0.1  
> **范围：** 平台端 **商品服务** CRUD；`IGoodsServiceFacade` 契约；协作验证 `GET /agri/seller/goods/serviceOptions`（商品模块挂载）  
> **排除：** 商家端维护服务目录（GS2）、服务分组/多语言、恢复已删、按服务检索全平台商品、C 端完整 E2E（P20/P21 在商品模块用例验证）  
> **环境：** RuoYi v3.9.2；平台接口 `/agri/goodsService`；平台管理员 Token；UI 为平台管理端 + **Playwright（Chromium/Chrome）**

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| GSV-UT-xxx | 单元测试 | JUnit 5 + Mockito（Service / Validator / Facade） |
| GSV-API-xxx | 接口测试 | Apifox / REST Assured + 平台 Token |
| GSV-UI-xxx | 界面测试 | Playwright（Chromium，模拟 Chrome） |

---

## 一、单元测试

### GSV-UT-001 服务名称未删记录唯一-新增重复失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 名称唯一校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 GS3 |
| **前置条件** | 库中已有未删「正品保证」 |
| **测试步骤** | `insert(dto)`，`serviceName=正品保证` |
| **预期结果** | 抛业务异常；msg「服务名称已存在」 |

### GSV-UT-002 编辑名称唯一排除自身

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 名称唯一校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §6.2 |
| **前置条件** | ID=1 名「正品保证」；ID=2 名「极速退款」 |
| **测试步骤** | 编辑 ID=1 改名为「极速退款」/ 保持「正品保证」 |
| **预期结果** | 前者失败；后者通过 |

### GSV-UT-003 逻辑删除后同名可再新增

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 名称唯一 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证唯一仅针对 del_flag=0 |
| **前置条件** | 「正品保证」已逻辑删除 |
| **测试步骤** | 新增「正品保证」 |
| **预期结果** | 通过；新 `service_id` |

### GSV-UT-004 服务名称为空拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | `validate(dto)`，`serviceName` 空 |
| **预期结果** | 失败；「请输入服务名称」 |

### GSV-UT-005 简介为空拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | `serviceIntro` 空 |
| **预期结果** | 失败；「请输入简介」 |

### GSV-UT-006 图标为空拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | `serviceIcon` 空 |
| **预期结果** | 失败；「请上传图标」 |

### GSV-UT-007 排序为负数拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 sort_no ≥0 |
| **前置条件** | — |
| **测试步骤** | `sortNo=-1` |
| **预期结果** | 失败；「排序须为非负整数」 |

### GSV-UT-008 default_show_flag 非法值拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 字段校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证仅 0/1 |
| **前置条件** | — |
| **测试步骤** | `defaultShowFlag=2` |
| **预期结果** | 校验失败 |

### GSV-UT-009 新增默认 default_show_flag=1

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 默认值 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证技术方案 §4 |
| **前置条件** | Body 未传 defaultShowFlag |
| **测试步骤** | `insert(dto)` |
| **预期结果** | 库中 `default_show_flag=1` |

### GSV-UT-010 listAllEnabled 仅 del_flag=0

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | IGoodsServiceFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 Facade 过滤 |
| **前置条件** | 2 条未删、1 条已删 |
| **测试步骤** | `listAllEnabled()` |
| **预期结果** | 返回 2 条；按 sort_no 升序 |

### GSV-UT-011 listDefaultShow 仅 default_show_flag=1

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | IGoodsServiceFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 GS5 |
| **前置条件** | 3 条未删：2 条默认显示、1 条否 |
| **测试步骤** | `listDefaultShow()` |
| **预期结果** | 返回 2 条 |

### GSV-UT-012 isServiceEnabled 已删返回 false

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | IGoodsServiceFacade |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证商品保存校验 |
| **前置条件** | serviceId 对应 del_flag=2 |
| **测试步骤** | `isServiceEnabled(id)` |
| **预期结果** | `false` |

### GSV-UT-013 existsGoodsRef 有未删商品快照返回 true

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除前置 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito Mapper |
| **测试目的** | 验证 GS7 |
| **前置条件** | snapshot 关联 goods.del_flag=0 |
| **测试步骤** | `existsGoodsRef(serviceId)` |
| **预期结果** | `true` |

### GSV-UT-014 existsGoodsRef 无关联返回 false

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除前置 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证删服务正向 |
| **前置条件** | 无 snapshot 行 |
| **测试步骤** | `existsGoodsRef(serviceId)` |
| **预期结果** | `false` |

### GSV-UT-015 单独删除成功置 del_flag=2

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除 Service |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证逻辑删除 |
| **前置条件** | `existsGoodsRef=false` |
| **测试步骤** | `removeById(1)` |
| **预期结果** | `del_flag=2`；不物理 DELETE |

### GSV-UT-016 单独删除有关联商品阻断

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除 Service |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 GS7 |
| **前置条件** | `existsGoodsRef=true` |
| **测试步骤** | `removeById(1)` |
| **预期结果** | 失败；msg 含「已被商品使用」 |

### GSV-UT-017 批量删除任一条失败整批不删

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 批量删除 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 GS8 |
| **前置条件** | ID=1 无关联；ID=2 有关联 |
| **测试步骤** | `removeByIds([1,2])` |
| **预期结果** | 抛异常；1、2 均仍为 del_flag=0 |

### GSV-UT-018 批量删除全部通过

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 批量删除 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 GS8 正向 |
| **前置条件** | 两条均无关联 |
| **测试步骤** | `removeByIds([1,2])` |
| **预期结果** | 两条 `del_flag=2` |

### GSV-UT-019 列表排序 sort_no 再 create_time

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 列表查询 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 GS4 |
| **前置条件** | sort_no 0/0/1 三条 |
| **测试步骤** | `selectList(query)` |
| **预期结果** | 前两条按 create_time 升序，第三条在后 |

### GSV-UT-020 编辑不更新 snapshot 表

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 编辑隔离 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 GS13/P19 |
| **前置条件** | 已有商品 snapshot |
| **测试步骤** | `update` 改 service_name；断言未调用 snapshotMapper.update |
| **预期结果** | 仅 `biz_goods_service` 变更 |

### GSV-UT-021 表结构无 shop_id（GS1）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 数据模型 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit / 架构测试（可选） |
| **测试目的** | 验证全平台一份 |
| **前置条件** | `BizGoodsService` 实体 |
| **测试步骤** | 断言无 `shopId` 字段 |
| **预期结果** | 无店铺维度字段 |

### GSV-UT-022 改 default_show 不调用 snapshot 写

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 默认显示 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 GS6 |
| **前置条件** | 已有 snapshot |
| **测试步骤** | `update` 仅改 `default_show_flag` |
| **预期结果** | snapshot 行数与内容不变 |

---

## 二、接口测试

### GSV-API-001 列表查询成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox / REST Assured |
| **测试目的** | 验证列表正向 |
| **前置条件** | 平台 Token；`agri:goodsService:list`；库中 ≥1 条未删 |
| **测试步骤** | `GET /agri/goodsService/list?pageNum=1&pageSize=10` |
| **预期结果** | `code=200`；`rows` 含 serviceName、serviceIntro、serviceIcon、defaultShowFlag；`total≥1` |

### GSV-API-002 列表按 sort_no 升序

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS4 |
| **前置条件** | 预置 sort_no=0,1,2 三条 |
| **测试步骤** | `GET /list?pageSize=50` |
| **预期结果** | `rows` 中 sortNo 非递减 |

### GSV-API-003 列表 serviceName 模糊检索

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §4.3（若实现） |
| **前置条件** | 存在「正品保证」「极速退款」 |
| **测试步骤** | `GET /list?serviceName=正品` |
| **预期结果** | 仅命中「正品保证」；未实现则记为跳过并注明 |

### GSV-API-004 列表不含已逻辑删除

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 del_flag 过滤 |
| **前置条件** | 一条已删「已删服务」 |
| **测试步骤** | `GET /list` |
| **预期结果** | `rows` 中无该名称 |

### GSV-API-005 无 list 权限拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 @PreAuthorize |
| **前置条件** | Token 无 `agri:goodsService:list` |
| **测试步骤** | `GET /list` |
| **预期结果** | HTTP 403 或 `code=403` |

### GSV-API-006 详情查询成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /{id} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证编辑回显 |
| **前置条件** | serviceId=1 存在 |
| **测试步骤** | `GET /agri/goodsService/1` |
| **预期结果** | `code=200`；含 serviceId、sortNo、defaultShowFlag |

### GSV-API-007 详情不存在

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /{id} |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 异常流程 |
| **前置条件** | id=99999 或已删 |
| **测试步骤** | `GET /agri/goodsService/99999` |
| **预期结果** | 失败；msg「不存在或已删除」 |

### GSV-API-008 新增服务成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §5 正向 |
| **前置条件** | `agri:goodsService:add`；名称未占用 |
| **测试步骤** | `POST /` Body：name/intro/icon/defaultShowFlag=1/sortNo=0 |
| **预期结果** | `code=200`；列表可查到；`del_flag=0` |

### GSV-API-009 新增名称重复

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS3 |
| **前置条件** | 已有「正品保证」 |
| **测试步骤** | 再 POST 同名 |
| **预期结果** | `code≠200`；msg「服务名称已存在」 |

### GSV-API-010 新增缺少必填字段

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §5.2 |
| **前置条件** | — |
| **测试步骤** | 分别缺 serviceName、serviceIntro、serviceIcon 三次请求 |
| **预期结果** | 均失败；对应提示文案 |

### GSV-API-011 编辑服务成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6 正向 |
| **前置条件** | serviceId=1；新名称未占用 |
| **测试步骤** | `PUT /` 改 intro、sortNo |
| **预期结果** | `code=200`；GET 详情字段已更新 |

### GSV-API-012 编辑名称与他人重复

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS3 |
| **前置条件** | ID=1；ID=2 名「极速退款」 |
| **测试步骤** | 编辑 ID=1 改名为「极速退款」 |
| **预期结果** | 失败；名称已存在 |

### GSV-API-013 单独删除成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | DELETE /{ids} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §8.1 |
| **前置条件** | 无商品关联；`agri:goodsService:remove` |
| **测试步骤** | `DELETE /agri/goodsService/{id}` |
| **预期结果** | `code=200`；列表不可见；库 `del_flag=2` |

### GSV-API-014 删除有关联商品阻断

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | DELETE /{ids} |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS7 |
| **前置条件** | 商品 snapshot 引用该 serviceId |
| **测试步骤** | `DELETE /{id}` |
| **预期结果** | `code=500`；msg 含「已被商品使用」；`del_flag` 仍为 0 |

### GSV-API-015 批量删除整批失败

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | DELETE 批量 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 GS8 |
| **前置条件** | ID=1 无关联；ID=2 有关联 |
| **测试步骤** | `DELETE /1,2` |
| **预期结果** | `code=500`；`data.reasons` 数组；1、2 均未删 |

### GSV-API-016 批量删除全部成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | DELETE 批量 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS8 正向 |
| **前置条件** | 3、4 均无关联 |
| **测试步骤** | `DELETE /3,4` |
| **预期结果** | `code=200`；两条均不可列表见 |

### GSV-API-017 无 remove 权限拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证权限 |
| **前置条件** | Token 无 remove |
| **测试步骤** | `DELETE /1` |
| **预期结果** | 403 |

### GSV-API-018 编辑后商品 snapshot 不变（协作）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务 + 商品 |
| **测试项** | P19 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 GS13 |
| **前置条件** | 商品已保存含服务快照；记录 snapshot 原 service_name |
| **测试步骤** | `PUT /agri/goodsService` 改服务名；`GET /agri/goods/{goodsId}` |
| **预期结果** | 商品详情 snapshot 仍为 **旧名称** |

### GSV-API-019 商家 serviceOptions 含未删项

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务（协作） |
| **测试项** | GET /agri/seller/goods/serviceOptions |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 §3.6 |
| **前置条件** | 商家 Token + `X-Shop-Id`；平台有 2 条未删服务 |
| **测试步骤** | `GET .../serviceOptions` |
| **预期结果** | `code=200`；`data` 含 serviceId、defaultShowFlag、sortNo |

### GSV-API-020 serviceOptions 不含已删服务

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务（协作） |
| **测试项** | serviceOptions |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证删后商家不可选 |
| **前置条件** | 「已删项」逻辑删除 |
| **测试步骤** | `GET .../serviceOptions` |
| **预期结果** | 响应中无该 serviceId |

### GSV-API-021 保存商品非法 serviceId 拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品（协作） |
| **测试项** | POST/PUT seller/goods |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 serviceIds 校验 |
| **前置条件** | serviceId=999 不存在或已删 |
| **测试步骤** | 保存商品 `serviceIds:[999]` |
| **预期结果** | 失败；非法服务项提示 |

### GSV-API-022 保存商品写 snapshot

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品（协作） |
| **测试项** | P18 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured + DB 断言 |
| **测试目的** | 验证快照写入 |
| **前置条件** | 服务 ID=1 名「正品保证」 |
| **测试步骤** | `POST/PUT` 商品 `serviceIds:[1]`；查 `biz_goods_service_snapshot` |
| **预期结果** | 有行；`service_name=正品保证` 与目录一致 |

### GSV-API-023 逻辑删服务后 C 端/详情不展示（协作）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务 + C 端 |
| **测试项** | P20 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 GS14 |
| **前置条件** | 商品仅有服务 1 的快照；服务 1 已逻辑删除 |
| **测试步骤** | 调 C 端商品详情 API（或平台商品详情 services 字段） |
| **预期结果** | 服务列表为空或不含该项 |

### GSV-API-024 商家再保存剔除已删服务（协作）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品（协作） |
| **测试项** | P21 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 GS15 |
| **前置条件** | 商品 snapshot 含已删 serviceId；商家编辑页不展示该项 |
| **测试步骤** | `PUT` 保存商品（不改其他字段） |
| **预期结果** | snapshot 中无已删 serviceId |

### GSV-API-025 新增服务后 serviceOptions 立即可见

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务 |
| **测试项** | 即时生效 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §5.3 |
| **前置条件** | — |
| **测试步骤** | `POST` 新服务 → 立即 `GET serviceOptions` |
| **预期结果** | 含新 serviceId |

### GSV-API-026 分页参数边界

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 异常/边界 |
| **前置条件** | 数据 >10 条 |
| **测试步骤** | `pageSize=1`；`pageNum=2` |
| **预期结果** | `rows.length=1`；`total` 正确 |

### GSV-API-027 无 add 权限 POST 拒绝

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 权限 |
| **测试类型** | 接口测试 |
| **测试工具** | REST Assured |
| **测试目的** | 验证 add 权限 |
| **前置条件** | 仅 list 权限 |
| **测试步骤** | `POST /` |
| **预期结果** | 403 |

### GSV-API-028 响应结构 code/msg/data

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 统一响应 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 RuoYi AjaxResult |
| **前置条件** | — |
| **测试步骤** | 成功/失败各调 1 次接口 |
| **预期结果** | 均含 `code`、`msg`；失败时 `data` 可为 null 或 reasons |

---

## 三、界面测试（Playwright）

> **浏览器：** `chromium` 或 `channel: 'chrome'`；**baseURL：** 平台管理端地址；登录账号须具备 `agri:goodsService:*` 权限。

### GSV-UI-001 登录并进入商品服务管理页

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 菜单导航 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证菜单可达 |
| **前置条件** | 平台管理员账号；服务已启动 |
| **测试步骤** | 1. 打开登录页 2. 输入账号密码登录 3. 侧栏进入「商品服务管理」 |
| **预期结果** | URL/面包屑正确；列表区域可见 |

### GSV-UI-002 列表展示必填列

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 列表 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §4.1 |
| **前置条件** | 库中 ≥1 条服务 |
| **测试步骤** | 查看表头与首行 |
| **预期结果** | 可见：服务名称、简介、图标、默认显示、操作（编辑/删除） |

### GSV-UI-003 列表按排序展示顺序

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 列表排序 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS4 |
| **前置条件** | 预置 sort 不同三条 |
| **测试步骤** | 刷新列表对比行顺序 |
| **预期结果** | 与 sort_no 升序一致 |

### GSV-UI-004 名称模糊搜索（若实现）

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 检索 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §4.3 |
| **前置条件** | 多条服务 |
| **测试步骤** | 输入服务名称关键字点搜索 |
| **预期结果** | 仅显示匹配行；无搜索框则跳过 |

### GSV-UI-005 新增服务完整流程

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 添加 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §5 正向 |
| **前置条件** | 有 add 权限；唯一名称 |
| **测试步骤** | 1. 点「新增」2. 填名称/简介/上传图标/默认显示=是/排序=0 3. 确定 |
| **预期结果** | 成功提示；列表出现新行且字段正确 |

### GSV-UI-006 新增必填校验-名称为空

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 表单校验 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §5.2 |
| **前置条件** | 打开新增弹窗 |
| **测试步骤** | 名称留空点确定 |
| **预期结果** | 表单项红字或 toast「请输入服务名称」；不提交 |

### GSV-UI-007 新增必填校验-未上传图标

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 表单校验 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §5.2 |
| **前置条件** | 打开新增弹窗 |
| **测试步骤** | 填名称简介不上传图标提交 |
| **预期结果** | 提示「请上传图标」 |

### GSV-UI-008 新增名称重复提示

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 唯一性 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS3 |
| **前置条件** | 列表已有「正品保证」 |
| **测试步骤** | 新增同名服务提交 |
| **预期结果** | 提示「服务名称已存在」 |

### GSV-UI-009 编辑服务并保存

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 编辑 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §6 |
| **前置条件** | 存在可编辑行 |
| **测试步骤** | 点编辑→改简介、排序、默认显示→保存 |
| **预期结果** | 成功；列表/再次打开表单为新区值 |

### GSV-UI-010 图标上传预览

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 图标 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §11 |
| **前置条件** | 新增/编辑表单 |
| **测试步骤** | 上传 jpg/png 小图 |
| **预期结果** | 预览区显示缩略图 |

### GSV-UI-011 单独删除二次确认成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §8.1 |
| **前置条件** | 无商品关联的服务行 |
| **测试步骤** | 点删除→确认框点确定 |
| **预期结果** | 成功提示；该行从列表消失 |

### GSV-UI-012 单独删除取消

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 异常/取消流程 |
| **前置条件** | 可删行 |
| **测试步骤** | 点删除→确认框点取消 |
| **预期结果** | 列表行仍在 |

### GSV-UI-013 删除有关联商品阻断提示

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS7 |
| **前置条件** | 服务已被某商品 snapshot 引用 |
| **测试步骤** | 点删除→确认 |
| **预期结果** | 错误提示含「已被商品使用」或指引先处理商品；行仍在 |

### GSV-UI-014 批量删除整批失败汇总

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 批量删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS8、§11 |
| **前置条件** | 勾选 1 条可删 + 1 条不可删 |
| **测试步骤** | 批量删除→确认 |
| **预期结果** | 提示「整批操作已取消」或汇总 reasons；两条均仍在 |

### GSV-UI-015 批量删除全部成功

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 批量删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS8 正向 |
| **前置条件** | 勾选 2 条均可删 |
| **测试步骤** | 批量删除→确认 |
| **预期结果** | 成功；勾选行均消失 |

### GSV-UI-016 无权限隐藏新增/删除按钮

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 权限 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证菜单权限 |
| **前置条件** | 仅 list 权限账号 |
| **测试步骤** | 进入列表页 |
| **预期结果** | 无「新增」、行内无「删除」或点击 403 |

### GSV-UI-017 空列表引导文案

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 空状态 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 §11 |
| **前置条件** | 无未删服务（或测试库清空） |
| **测试步骤** | 打开列表 |
| **预期结果** | 空状态提示；引导「添加服务」类文案 |

### GSV-UI-018 默认显示字段文案清晰

| 要素 | 内容 |
|------|------|
| **测试模块** | 商品服务管理 |
| **测试项** | 表单文案 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright |
| **测试目的** | 验证 GS5 理解成本 |
| **前置条件** | 打开新增/编辑 |
| **测试步骤** | 查看「默认显示」标签或帮助说明 |
| **预期结果** | 含「商家发品时默认勾选」类说明；非「C 端强制展示」 |

---

## 四、用例统计

| 类型 | 数量 | 编号段 |
|------|------|--------|
| 单元测试 | 22 | GSV-UT-001～022 |
| 接口测试 | 28 | GSV-API-001～028 |
| 界面测试 | 18 | GSV-UI-001～018 |
| **合计** | **68** | — |

---

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

| 规则 | 对应用例（示例） |
|------|------------------|
| GS1 | GSV-UT-021 |
| GS2 | GSV-API-005/017/027；GSV-UI-016（商家无维护入口，接口无 seller CRUD） |
| GS3 | GSV-UT-001～003；GSV-API-009/012；GSV-UI-008 |
| GS4 | GSV-UT-019；GSV-API-002；GSV-UI-003 |
| GS5 | GSV-UT-009/011；GSV-API-019；GSV-UI-018 |
| GS6 | GSV-UT-022 |
| GS7 | GSV-UT-013～016；GSV-API-014；GSV-UI-013 |
| GS8 | GSV-UT-017/018；GSV-API-015/016；GSV-UI-014/015 |
| GS9 | （商品状态不变，商品模块用例；本模块删/改不触达 goods_status） |
| GS10 | GSV-API-014（删不自动取消勾选，须商品编辑） |
| GS11 | 全用例无会员步骤 |
| GS12 | 本模块无店铺字段用例 GSV-UT-021 |
| GS13 | GSV-UT-020；GSV-API-018 |
| GS14 | GSV-API-023 |
| GS15 | GSV-API-024 |
| P18～P21 | GSV-API-018/022/023/024 |

---

## 六、测试数据建议

| 数据 | 用途 |
|------|------|
| 平台管理员（全权限） | UI/API 正向 |
| 仅 list 权限账号 | GSV-API-005、GSV-UI-016 |
| 服务 A「正品保证」default=1 sort=0 | 默认勾选、排序 |
| 服务 B「极速退款」default=0 | 非默认勾选 |
| 无关联商品的服务 | 删除正向 |
| 已被商品 snapshot 引用的服务 | 删除阻断、GSV-UI-013 |
| 已逻辑删除的同名服务 | GSV-UT-003 复用名称 |
| 商家 Token + 当前店铺 | GSV-API-019～024 |
| 含 serviceIds 的测试商品 | 快照/P19/P20/P21 |

---

## 七、Playwright 配置要点（参考）

```javascript
// playwright.config.js 片段
use: {
  channel: 'chrome', // 或 browserName: 'chromium'
  baseURL: process.env.PLATFORM_BASE_URL,
  screenshot: 'only-on-failure',
},
```

```javascript
// 登录 fixture 示例
await page.goto('/login');
await page.fill('[name=username]', process.env.ADMIN_USER);
await page.fill('[name=password]', process.env.ADMIN_PASS);
await page.click('button:has-text("登录")');
await page.goto('/agri/goodsService'); // 以实际路由为准
```

---

*文档版本：v1.0 · 关联《商品服务管理功能需求.md》v1.0.1、《商品服务管理技术方案.md》v1.0.1*
