# 供应商管理 — 测试用例

> 依据：`供应商管理功能需求.md`、`供应商管理技术方案.md`  
> **接口 Base Path（示例）**：`/tradeMarket/supplier`；鉴权与若依一致（Cookie / Token）。

**通用前置（无特殊说明）**：具备本模块按钮权限的账号已登录（`tradeMarket:supplier:list|query|add|edit|remove|assignAccount`）。库表 `biz_supplier` 中宜预置（`del_flag=0`）：

| 样本 | 编号 | 名称 | 类型 | 收费方式 | 要点 |
| --- | --- | --- | --- | --- | --- |
| **A** | `01` | 扎西牧民合作社 | 个体户(1) | 按户(1) | 身份证、无车辆 |
| **B** | `02` | 雪域牧业公司 | 企业(2) | 按头(2) | `feeStandard=10`；车牌 1 条 |
| **C** | `03` | 高原贸易有限公司 | 企业(2) | 按额(3) | `transactionFeeRate=2`，`managementFeeRate=1` |
| **U** | `04` | 待分配供应商 | 个体户(1) | 按户(1) | `account_assigned=0`，用于分配账号用例 |
| **A-done** | `05` | 已分配供应商 | 个体户(1) | 按户(1) | `account_assigned=1`，`assigned_login_name` 有值 |

**合法身份证（个体户）**：`110101199001011234`（与项目全局校验一致）。  
**合法统一社会信用代码（企业）**：`91510000MA62K0260E`。

**按户新增 Body 示例**：`supplierName=测试供应商甲`，`supplierType=1`，`identityNo=110101199001011234`，`contactPhone=13800138000`，`feeMethod=1`。

**界面（UI）测试**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）。

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-GYSGL-UT-001 | 编号生成 | 首条编号 | 单元测试 | JUnit5 | §2.4 | 库无编号记录 | `SupplierCodeGenerator.next()` | 返回 `01` |
| ZCZX-GYSGL-UT-002 | 编号生成 | 递增补零 | 单元测试 | JUnit5 | §2.4 | 最大号为 `08` | `next()` | 返回 `09` |
| ZCZX-GYSGL-UT-003 | 编号生成 | 上限拒绝 | 单元测试 | JUnit5 | §2.4 | 最大号为 `99` | `next()` | 抛异常；msg 含编号上限 |
| ZCZX-GYSGL-UT-004 | 参数校验 | 供应商名称 | 单元测试 | JUnit5 | 1～20 字 | 无 | 空、21 字、合法 trim | 空/超长失败；合法通过 |
| ZCZX-GYSGL-UT-005 | 参数校验 | 个体户身份证 | 单元测试 | JUnit5 | §3.4 | `supplierType=1` | 非法位、合法 18 位 | 非法失败；合法通过 |
| ZCZX-GYSGL-UT-006 | 参数校验 | 企业识别号 | 单元测试 | JUnit5 | §3.4 | `supplierType=2` | 非 18 位、合法 USCC | 非法失败；合法通过 |
| ZCZX-GYSGL-UT-007 | 参数校验 | 手机号 | 单元测试 | JUnit5 | 全局规则 | 无 | 10 位、合法 11 位 | 非法失败；合法通过 |
| ZCZX-GYSGL-UT-008 | 收费联动 | 按户清空费率 | 单元测试 | JUnit5 | §3.4 | `feeMethod=1` | `normalizeFeeFields(row)` | 三费率字段均为 null |
| ZCZX-GYSGL-UT-009 | 收费联动 | 按头必填标准 | 单元测试 | JUnit5 | §2.3 | `feeMethod=2` | 无标准、标准≤0、标准=10 | 前两种失败；10 通过 |
| ZCZX-GYSGL-UT-010 | 收费联动 | 按额费率范围 | 单元测试 | JUnit5 | §2.3 | `feeMethod=3` | 缺费率、-1%、101%、2%+1% | 非法失败；合法通过 |
| ZCZX-GYSGL-UT-011 | 车辆号牌 | 数量与格式 | 单元测试 | JUnit5 | §2.5 | 无 | 11 条、非法格式、2 条合法 | 超限/格式失败；合法通过 |
| ZCZX-GYSGL-UT-012 | 唯一性 | 名称重复 | 单元测试 | JUnit5+Mockito | §3.4 | 已存在同名未删 | `validateUniqueName` | 失败 |
| ZCZX-GYSGL-UT-013 | 唯一性 | 身份号重复 | 单元测试 | JUnit5+Mockito | §3.4 | 已存在同号未删 | `validateUniqueIdentity` | 失败 |
| ZCZX-GYSGL-UT-014 | Service | 新增落库 | 单元测试 | JUnit5+Mockito | 正常 | Mock Mapper | `insert` 按户样本 | `del_flag=0`；`supplier_code` 非空 |
| ZCZX-GYSGL-UT-015 | Service | 修改禁改编号 | 单元测试 | JUnit5 | §3.3.1 | 有记录 `01` | Body 传 `supplierCode=02` | 忽略或失败；库仍为 `01` |
| ZCZX-GYSGL-UT-016 | Service | 逻辑删除 | 单元测试 | JUnit5+Mockito | §3.5 | Mock Mapper | `remove(id)` | `del_flag=2` |
| ZCZX-GYSGL-UT-017 | Service | 删除有未结算单 | 单元测试 | JUnit5+Mockito | §5.5 | `hasUnsettledSettlement=true` | `remove` | 抛「存在未结算的结算单，无法删除」 |
| ZCZX-GYSGL-UT-018 | Mapper | 筛选排序 | 单元测试 | JUnit5 | §3.7 | 无 | 检查 XML | `del_flag=0`；编号/名称精确；`supplier_code ASC` |
| ZCZX-GYSGL-UT-019 | 登录名 | 拼音首字母+id | 单元测试 | JUnit5 | §2.6 | 无 | `TradingPartnerLoginNameGenerator.generate("扎西供应商",12L)` | `zxgys12` |
| ZCZX-GYSGL-UT-020 | 分配校验 | 未分配通过 | 单元测试 | JUnit5 | §3.4 | `account_assigned=0` | `validateForAssignAccount` | 通过 |
| ZCZX-GYSGL-UT-021 | 分配校验 | 已分配拒绝 | 单元测试 | JUnit5 | §3.4 | `account_assigned=1` | `validateForAssignAccount` | 失败；含「不可重复分配」 |
| ZCZX-GYSGL-UT-022 | Service | 分配账号成功 | 单元测试 | JUnit5+Mockito | §3.6 | U 未分配；Mock 用户服务 | `assignAccount(id,"admin")` | `account_assigned=1`；角色 **103** |
| ZCZX-GYSGL-UT-023 | Service | 重复分配 | 单元测试 | JUnit5+Mockito | §3.6 | A-done | `assignAccount` | 失败；未调创建用户 |
| ZCZX-GYSGL-UT-024 | Service | 删除联动删账号 | 单元测试 | JUnit5+Mockito | §3.5 | 已分配 `sys_user_id` | `deleteByIds` | 调用 `deleteLinkedAccount` |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-GYSGL-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman | §3.1.1 | 已登录；有 A/B/C | `GET .../list` | `rows`≤20；含 `supplierTypeName`；编号升序 |
| ZCZX-GYSGL-API-002 | 列表 | 编号精确 | 接口测试 | Postman | §2.8 | 有 A | `supplierCode=01` | 仅 A；`supplierCode=1` 不匹配 |
| ZCZX-GYSGL-API-003 | 列表 | 名称精确 | 接口测试 | Postman | §2.8 | 有 B | `supplierName=雪域牧业公司` | 仅 B；片段「雪域」无结果 |
| ZCZX-GYSGL-API-004 | 列表 | 组合筛选 | 接口测试 | Postman | 多条件 | 已登录 | 编号+名称同时满足 | 命中唯一行 |
| ZCZX-GYSGL-API-005 | 列表 | 不含已删除 | 接口测试 | Postman | 逻辑删除 | 已知 id 已删 | `GET list` | 无该 id |
| ZCZX-GYSGL-API-006 | 新增 | 按户合法 | 接口测试 | Postman | §5.1 | 已登录 | `POST` 按户 Body | `code=200`；`supplierCode` 为 2 位；费率字段空 |
| ZCZX-GYSGL-API-007 | 新增 | 按头合法 | 接口测试 | Postman | §2.3 | 已登录 | `POST` `feeMethod=2`，`feeStandard=10` | 成功；详情标准=10 |
| ZCZX-GYSGL-API-008 | 新增 | 按额合法 | 接口测试 | Postman | §2.3 | 已登录 | `POST` `feeMethod=3`，费率 2/1 | 成功；两费率入库 |
| ZCZX-GYSGL-API-009 | 新增 | 按头缺标准 | 接口测试 | Postman | §3.4 | 已登录 | `feeMethod=2` 无 `feeStandard` | 失败 |
| ZCZX-GYSGL-API-010 | 新增 | 按额缺费率 | 接口测试 | Postman | §3.4 | 已登录 | `feeMethod=3` 仅填交易费率 | 失败 |
| ZCZX-GYSGL-API-011 | 新增 | 费率超 100 | 接口测试 | Postman | §2.3 | 已登录 | `managementFeeRate=101` | 失败 |
| ZCZX-GYSGL-API-012 | 新增 | 名称重复 | 接口测试 | Postman | §5.1.4 | 已有 A 名称 | `POST` 同名 | 失败；msg 可区分 |
| ZCZX-GYSGL-API-013 | 新增 | 身份号重复 | 接口测试 | Postman | §5.1.4 | 已有 A 身份证 | `POST` 同 `identityNo` | 失败 |
| ZCZX-GYSGL-API-014 | 新增 | 手机号非法 | 接口测试 | Postman | §2.5 | 已登录 | `contactPhone=123` | 失败 |
| ZCZX-GYSGL-API-015 | 新增 | 企业类型错证 | 接口测试 | Postman | §2.5 | 已登录 | `supplierType=2`+身份证 | 失败 |
| ZCZX-GYSGL-API-016 | 新增 | 车辆超 10 条 | 接口测试 | Postman | §2.6 | 已登录 | `vehiclePlates` 长度 11 | 失败 |
| ZCZX-GYSGL-API-017 | 详情 | 有效 id | 接口测试 | Postman | §3.2.1 | 已登录 | `GET /{id}` | 含 `vehiclePlates` 数组及审计字段 |
| ZCZX-GYSGL-API-018 | 详情 | 无效/已删 id | 接口测试 | Postman | 异常 | 已登录 | 不存在或已删 | 失败或空 `data` |
| ZCZX-GYSGL-API-019 | 修改 | 合法改名称 | 接口测试 | Postman | §5.3 | 有 A | `PUT` 改 `businessLocation` | 成功；`supplierCode` 不变 |
| ZCZX-GYSGL-API-020 | 修改 | 收费方式切换 | 接口测试 | Postman | §2.3 | B 按头 | `PUT` 改 `feeMethod=3`+费率 | 成功；`feeStandard` 为空 |
| ZCZX-GYSGL-API-021 | 修改 | 传编号无效 | 接口测试 | Postman | §3.3.1 | 有 A | `PUT` 带 `supplierCode=99` | 编号仍为 `01` |
| ZCZX-GYSGL-API-022 | 修改 | 不存在 id | 接口测试 | Postman | 异常 | 已登录 | `PUT` 伪造 id | 失败 |
| ZCZX-GYSGL-API-023 | 删除 | 单条逻辑删 | 接口测试 | Postman | §5.5 | 无关联的新增行 | `DELETE /{id}` | 成功；列表不可见 |
| ZCZX-GYSGL-API-024 | 删除 | 有未结算单拒绝 | 接口测试 | Postman | §5.5 | 预置待结算单 | `DELETE` | 失败；提示未结算 |
| ZCZX-GYSGL-API-025 | 删除 | 重复删除 | 接口测试 | Postman | 幂等 | id 已删 | 再次 `DELETE` | 失败或不存在 |
| ZCZX-GYSGL-API-026 | 端到端 | CRUD 串联 | 接口测试 | Postman | §4 | 已登录 | `POST`→`list`→`GET`→`PUT`→`DELETE` | 每步成功；编号自动生成 |
| ZCZX-GYSGL-API-027 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET list` | 401 或统一未登录 |
| ZCZX-GYSGL-API-028 | 权限 | 无新增权限 | 接口测试 | Postman | §6 | 仅 list | `POST` | 无权限失败 |
| ZCZX-GYSGL-API-029 | 权限 | 无删除权限 | 接口测试 | Postman | §6 | 无 remove | `DELETE/{id}` | 无权限失败 |
| ZCZX-GYSGL-API-030 | 响应 | 失败可读 | 接口测试 | Postman | §8 | 已登录 | 触发重复名、按头缺标准、手机号错 | `msg` 可区分 |

---

## 三、界面测试用例（UI）

**测试工具**：**Playwright** + **Chromium**（`channel: 'chrome'` 使用本机 **Google Chrome**）。

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-GYSGL-UI-001 | 列表 | 默认展示 | UI 测试 | Playwright+Chrome | §5.2.3 | 已登录；有数据 | 进入「供应商管理」 | 含编号、名称、类型、识别号、电话、地点、车辆、收费方式、操作 |
| ZCZX-GYSGL-UI-002 | 列表 | 编号精确筛选 | UI 测试 | Playwright+Chrome | §2.8 | 有 A | 输入 `01`→搜索 | 仅 A |
| ZCZX-GYSGL-UI-003 | 列表 | 名称精确筛选 | UI 测试 | Playwright+Chrome | §2.8 | 有 B | 输入全名→搜索 | 仅 B；输入「雪域」无行 |
| ZCZX-GYSGL-UI-004 | 列表 | 重置 | UI 测试 | Playwright+Chrome | §5.2 | 已筛选 | 搜索→重置 | 条件清空；恢复默认列表 |
| ZCZX-GYSGL-UI-005 | 列表 | 编号升序 | UI 测试 | Playwright+Chrome | §5.2.2 | 有 A/B/C | 查看首列顺序 | `01` 在前 |
| ZCZX-GYSGL-UI-006 | 新增 | 按户计费 | UI 测试 | Playwright+Chrome | §5.1.2 | 已登录 | 新增→个体户→按户→填必填→确定 | 成功；列表新行；无费率字段值 |
| ZCZX-GYSGL-UI-007 | 新增 | 按头计费 | UI 测试 | Playwright+Chrome | §5.1.2 | 已登录 | 选按头→显示收费标准→填 10 元/头→确定 | 成功；详情可见标准 |
| ZCZX-GYSGL-UI-008 | 新增 | 按额计费 | UI 测试 | Playwright+Chrome | §5.1.2 | 已登录 | 选按额→填交易/管理费率→确定 | 成功；详情两费率正确 |
| ZCZX-GYSGL-UI-009 | 新增 | 收费联动隐藏 | UI 测试 | Playwright+Chrome | §5.1.2 | 新增弹窗 | 选按户 | 收费标准与两费率不可见或禁用 |
| ZCZX-GYSGL-UI-010 | 新增 | 类型切换标签 | UI 测试 | Playwright+Chrome | §5.1.2 | 新增 | 个体户↔企业 | 标签在「身份证号」「主体识别号」间切换 |
| ZCZX-GYSGL-UI-011 | 新增 | 编号只读 | UI 测试 | Playwright+Chrome | §2.4 | 打开新增 | 查看编号控件 | 只读或「保存后自动生成」 |
| ZCZX-GYSGL-UI-012 | 新增 | 缺必填 | UI 测试 | Playwright+Chrome | §5.1.4 | 新增 | 留空名称或手机→确定 | 校验失败；弹窗不关闭 |
| ZCZX-GYSGL-UI-013 | 新增 | 按头未填标准 | UI 测试 | Playwright+Chrome | §5.1.3 | 选按头 | 不填收费标准→确定 | 校验失败 |
| ZCZX-GYSGL-UI-014 | 新增 | 名称 20 字 | UI 测试 | Playwright+Chrome | §5.1.1 | 新增 | 输入超 20 字 | 无法继续输入或保存失败 |
| ZCZX-GYSGL-UI-015 | 新增 | 车辆多条 | UI 测试 | Playwright+Chrome | §2.6 | 新增 | 点「+」添加 2 个车牌→保存 | 列表/详情展示多条 |
| ZCZX-GYSGL-UI-016 | 新增 | 取消 | UI 测试 | Playwright+Chrome | §5.1.3 | 新增 | 填一半→取消 | 弹窗关闭；列表无新行 |
| ZCZX-GYSGL-UI-017 | 详情 | 只读完整 | UI 测试 | Playwright+Chrome | §5.4 | 有 C 按额 | 点「查看」 | 只读；展示费率与审计信息 |
| ZCZX-GYSGL-UI-018 | 编辑 | 修改地点 | UI 测试 | Playwright+Chrome | §5.3 | 有 A | 编辑→改经营地点→确定 | 列表已更新；编号不变 |
| ZCZX-GYSGL-UI-019 | 编辑 | 编号不可改 | UI 测试 | Playwright+Chrome | §5.3 | 编辑 A | 查看编号字段 | 只读 |
| ZCZX-GYSGL-UI-020 | 编辑 | 收费方式切换 | UI 测试 | Playwright+Chrome | §5.3 | B 按头 | 改按额并填费率→保存 | 详情无收费标准；有两费率 |
| ZCZX-GYSGL-UI-021 | 删除 | 确认删除 | UI 测试 | Playwright+Chrome | §5.5 | 无关联行 | 删除→确认 | 行消失 |
| ZCZX-GYSGL-UI-022 | 删除 | 取消删除 | UI 测试 | Playwright+Chrome | §5.5 | 任意行 | 删除→取消 | 行仍在 |
| ZCZX-GYSGL-UI-023 | 端到端 | 全流程 | UI 集成 | Playwright+Chrome | §4 | 权限齐备 | 新增(按户)→查→看→改→删 | 无报错；编号与收费规则正确 |
| ZCZX-GYSGL-UI-024 | 权限 | 只读角色 | UI 测试 | Playwright+Chrome | §6 | 无写权限 | 进入模块 | 无新增/编辑/删除 |
| ZCZX-GYSGL-UI-025 | 详情 | 从详情编辑 | UI 测试 | Playwright+Chrome | §5.4 | 查看 A | 点「编辑」 | 进入编辑弹窗；保存后回列表 |
| ZCZX-GYSGL-UI-026 | 列表 | 账号分配列 | UI 测试 | Playwright+Chrome | §5.2.3 | 有 U、A-done | 查看列表 | 未分配「否」；已分配「是」及登录名 |
| ZCZX-GYSGL-UI-027 | 分配账号 | 未分配成功 | UI 测试 | Playwright+Chrome | §5.6 | U；有 assignAccount 权限 | 分配账号→确认 | 成功提示；行变为已分配；无再次入口 |
| ZCZX-GYSGL-UI-028 | 分配账号 | 已分配无按钮 | UI 测试 | Playwright+Chrome | §5.6 | A-done | 查看操作列 | 无「分配账号」 |
| ZCZX-GYSGL-UI-029 | 权限 | 无分配权限 | UI 测试 | Playwright+Chrome | §6 | 无 assignAccount | 进入列表 | 无分配账号按钮 |

---

## Playwright 与谷歌浏览器（实施提示）

- 安装：`npm i -D @playwright/test`；`npx playwright install chrome`。  
- 配置：`use: { channel: 'chrome', locale: 'zh-CN', baseURL: 'http://localhost:80' }`；`storageState` 复用登录态。  
- 路由：`page.goto('/tradeMarket/supplier')`（以菜单 `component` 为准）。  
- 收费联动：切换「收费方式」后断言 `page.getByLabel('收费标准')` 可见性。  
- 车辆：`page.getByRole('button', { name: '+' })` 增加号牌行。  
- 删除：`page.getByRole('button', { name: '删除' })` + 确认对话框。

---

## 覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常流程 | UT-014 | API-006～008、017、019～020、026 | UI-006～008、017～020、023 |
| 异常流程 | UT-003、009～011、017 | API-009～016、022、024～025 | UI-012～013、021～022 |
| 业务约束 | UT-001～013、015 | API-002～004、012～015、021 | UI-002～003、009～011、019 |
| 编号生成 | UT-001～003 | API-006、021、026 | UI-011、019 |
| 收费联动 | UT-008～010 | API-007～011、020 | UI-007～009、020 |
| 唯一性 | UT-012～013 | API-012～013 | — |
| 逻辑删除 | UT-016 | API-005、023、025 | UI-021 |
| 权限/鉴权 | — | API-027～029、035 | UI-024、029 |
| 分配账号 | UT-019～023 | API-031～034 | UI-026～028 |

---

## 功能需求追溯（自查）

| 需求章节 | 要点 | 主要对应用例 |
| --- | --- | --- |
| §5.1 新增 | 字段、收费联动、编号 | UT-004～011、014；API-006～016；UI-006～016 |
| §5.2 列表 | 精确筛选、排序 | API-001～004；UI-001～005 |
| §5.3 修改 | 编号不可改、联动 | UT-015；API-019～021；UI-018～020 |
| §5.4 详情 | 只读 | API-017；UI-017、025 |
| §5.5 删除 | 逻辑删、未结算拦截 | UT-016～017；API-023～025；UI-021～022 |
| §2.3 收费方式 | 三档字段 | UT-008～010；API-007～011、020；UI-007～009 |
| §2.4 编号 | 01～99 | UT-001～003；API-006；UI-011 |
| §6 权限 | 按钮级 | API-027～029、035；UI-024、029 |
| §5.6 分配账号 | 一次、角色 103 | UT-019～023；API-031～034；UI-026～028 |

---

## 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 18、接口 30、UI 25；覆盖 CRUD、编号、收费联动、唯一性、车辆；Playwright+Chrome；前缀 **ZCZX-GYSGL** |
| 1.1 | 增补分配账号：单元 UT-019～024、接口 API-031～035、UI UI-026～029；样本 U/A-done |
| 1.3 | 删除拦截：UT-017、API-024 对齐未结算结算单 |
