# 承销商管理 — 测试用例

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

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

| 样本 | 编号 | 名称 | 类型 | 销售去向 | 要点 |
| --- | --- | --- | --- | --- | --- |
| **D1** | `01` | 扎西承销服务点 | 个体户(1) | 本市(1) | 身份证 |
| **D2** | `02` | 雪域贸易有限公司 | 企业(2) | 本省(2) | USCC |
| **D3** | `03` | 高原外向商行 | 企业(2) | 外省(3) | 经营地点有值 |
| **DU** | `04` | 待分配承销商 | 个体户(1) | 本市(1) | `account_assigned=0` |
| **DA** | `05` | 已分配承销商 | 企业(2) | 本省(2) | `account_assigned=1` |

**合法身份证**：`110101199001011234`。**合法 USCC**：`91510000MA62K0260E`。

**合法新增 Body 示例**：`distributorName=测试承销商甲`，`distributorType=1`，`identityNo=110101199001011234`，`contactPhone=13800138000`，`salesDestination=1`。

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

---

## 一、单元测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXSGL-UT-001 | 编号生成 | 首条编号 | 单元测试 | JUnit5 | §2.4 | 库无编号 | `DistributorCodeGenerator.next()` | 返回 `01` |
| ZCZX-CXSGL-UT-002 | 编号生成 | 递增补零 | 单元测试 | JUnit5 | §2.4 | 最大号 `08` | `next()` | 返回 `09` |
| ZCZX-CXSGL-UT-003 | 编号生成 | 上限拒绝 | 单元测试 | JUnit5 | §2.4 | 最大号 `99` | `next()` | 抛异常；含编号上限 |
| ZCZX-CXSGL-UT-004 | 参数校验 | 承销商名称 | 单元测试 | JUnit5 | 1～20 字 | 无 | 空、21 字、合法 trim | 空/超长失败；通过 |
| ZCZX-CXSGL-UT-005 | 参数校验 | 个体户身份证 | 单元测试 | JUnit5 | §3.4 | `type=1` | 非法、合法 18 位 | 非法失败；通过 |
| ZCZX-CXSGL-UT-006 | 参数校验 | 企业识别号 | 单元测试 | JUnit5 | §3.4 | `type=2` | 非 18 位、合法 USCC | 非法失败；通过 |
| ZCZX-CXSGL-UT-007 | 参数校验 | 手机号 | 单元测试 | JUnit5 | 全局 | 无 | 10 位、11 位合法 | 非法失败；通过 |
| ZCZX-CXSGL-UT-008 | 参数校验 | 销售去向 | 单元测试 | JUnit5 | §2.3 | 无 | 空、0、4、1/2/3 | 非法失败；1～3 通过 |
| ZCZX-CXSGL-UT-009 | 参数校验 | 经营地点长度 | 单元测试 | JUnit5 | ≤50 | 无 | 51 字、50 字 | 51 失败；50 通过 |
| ZCZX-CXSGL-UT-010 | 唯一性 | 名称重复 | 单元测试 | JUnit5+Mockito | §3.4 | 同名未删 | `validateUniqueName` | 失败 |
| ZCZX-CXSGL-UT-011 | 唯一性 | 身份号重复 | 单元测试 | JUnit5+Mockito | §3.4 | 同号未删 | `validateUniqueIdentity` | 失败 |
| ZCZX-CXSGL-UT-012 | Service | 新增落库 | 单元测试 | JUnit5+Mockito | 正常 | Mock Mapper | `insert` 合法行 | `del_flag=0`；`distributor_code` 非空 |
| ZCZX-CXSGL-UT-013 | Service | 修改禁改编号 | 单元测试 | JUnit5 | §3.3.1 | 记录 `01` | Body `distributorCode=99` | 库仍为 `01` |
| ZCZX-CXSGL-UT-014 | Service | 逻辑删除 | 单元测试 | JUnit5+Mockito | §3.5 | Mock | `remove(id)` | `del_flag=2` |
| ZCZX-CXSGL-UT-015 | Service | 删除有未支付订单 | 单元测试 | JUnit5+Mockito | §5.5 | `hasUnpaidOrder=true` | `remove` | 抛「存在未支付订单，无法删除」 |
| ZCZX-CXSGL-UT-016 | Mapper | 模糊筛选 SQL | 单元测试 | JUnit5 | §3.6 | 无 | 检查 XML | `LIKE CONCAT('%',…,'%')`；`del_flag=0` |
| ZCZX-CXSGL-UT-017 | Mapper | 排序 | 单元测试 | JUnit5 | §3.1.1 | 无 | 检查 XML | `distributor_code ASC, id ASC` |
| ZCZX-CXSGL-UT-018 | 登录名 | 拼音首字母+id | 单元测试 | JUnit5 | §2.5 | 无 | `generate("扎西承销商",3L)` | `zxcxs3` |
| ZCZX-CXSGL-UT-019 | 分配校验 | 已分配拒绝 | 单元测试 | JUnit5 | §3.4 | `account_assigned=1` | `validateForAssignAccount` | 失败 |
| ZCZX-CXSGL-UT-020 | Service | 分配成功 | 单元测试 | JUnit5+Mockito | §3.6 | DU | `assignAccount` | `account_assigned=1`；角色 **104** |
| ZCZX-CXSGL-UT-021 | Service | 重复分配 | 单元测试 | JUnit5+Mockito | §3.6 | DA | `assignAccount` | 失败 |
| ZCZX-CXSGL-UT-022 | Service | 删除联动 | 单元测试 | JUnit5+Mockito | §3.5 | 已分配 | `deleteByIds` | 联动删用户 |

---

## 二、接口测试用例

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXSGL-API-001 | 列表 | 默认分页排序 | 接口测试 | Postman | §3.1.1 | 有 D1～D3 | `GET .../list` | `rows`≤20；含 `salesDestinationName`；编号升序 |
| ZCZX-CXSGL-API-002 | 列表 | 编号模糊 | 接口测试 | Postman | §2.8 | 有 D1 `01` | `distributorCode=1` | 含 D1；全名 `01` 仍命中 |
| ZCZX-CXSGL-API-003 | 列表 | 名称模糊 | 接口测试 | Postman | §2.8 | 有 D2 | `distributorName=雪域` | 含 D2；与全名不等亦可 |
| ZCZX-CXSGL-API-004 | 列表 | 模糊无匹配 | 接口测试 | Postman | §2.8 | 已登录 | `distributorName=不存在xyz` | 空列表 |
| ZCZX-CXSGL-API-005 | 列表 | 精确不匹配反例 | 接口测试 | Postman | 对比供应商 | 有 D2 全名 | 名称少一字片段错误 | 仍可模糊命中或按输入为空不过滤 |
| ZCZX-CXSGL-API-006 | 列表 | 组合筛选 | 接口测试 | Postman | 多条件 | 已登录 | `distributorCode=0`+`distributorName=公司` | 同时满足行 |
| ZCZX-CXSGL-API-007 | 列表 | 不含已删除 | 接口测试 | Postman | 逻辑删除 | id 已删 | `GET list` | 无该 id |
| ZCZX-CXSGL-API-008 | 新增 | 个体户本市 | 接口测试 | Postman | §5.1 | 已登录 | `POST` 合法 Body `salesDestination=1` | `code=200`；`distributorCode` 2 位 |
| ZCZX-CXSGL-API-009 | 新增 | 企业本省 | 接口测试 | Postman | §2.3 | 已登录 | `type=2`+USCC+`salesDestination=2` | 成功 |
| ZCZX-CXSGL-API-010 | 新增 | 外省 | 接口测试 | Postman | §2.3 | 已登录 | `salesDestination=3` | 成功；详情销售去向为外省 |
| ZCZX-CXSGL-API-011 | 新增 | 缺销售去向 | 接口测试 | Postman | §3.4 | 已登录 | 无 `salesDestination` | 失败 |
| ZCZX-CXSGL-API-012 | 新增 | 销售去向非法 | 接口测试 | Postman | §3.4 | 已登录 | `salesDestination=9` | 失败 |
| ZCZX-CXSGL-API-013 | 新增 | 名称重复 | 接口测试 | Postman | §5.1.4 | 已有 D1 名 | `POST` 同名 | 失败 |
| ZCZX-CXSGL-API-014 | 新增 | 身份号重复 | 接口测试 | Postman | §5.1.4 | 已有 D1 证号 | 同 `identityNo` | 失败 |
| ZCZX-CXSGL-API-015 | 新增 | 手机号非法 | 接口测试 | Postman | §2.5 | 已登录 | `contactPhone=123` | 失败 |
| ZCZX-CXSGL-API-016 | 新增 | 企业错用身份证 | 接口测试 | Postman | §2.5 | 已登录 | `type=2`+身份证 | 失败 |
| ZCZX-CXSGL-API-017 | 详情 | 有效 id | 接口测试 | Postman | §3.2.1 | 已登录 | `GET /{id}` | 含销售去向、审计 |
| ZCZX-CXSGL-API-018 | 详情 | 无效/已删 id | 接口测试 | Postman | 异常 | 已登录 | 不存在/已删 | 失败或空 `data` |
| ZCZX-CXSGL-API-019 | 修改 | 改经营地点 | 接口测试 | Postman | §5.3 | 有 D1 | `PUT` 改 `businessLocation` | 成功；编号不变 |
| ZCZX-CXSGL-API-020 | 修改 | 改销售去向 | 接口测试 | Postman | §5.3 | D1 本市 | `PUT` `salesDestination=3` | 成功；详情为外省 |
| ZCZX-CXSGL-API-021 | 修改 | 传编号无效 | 接口测试 | Postman | §3.3.1 | 有 D1 | `PUT` `distributorCode=99` | 仍为 `01` |
| ZCZX-CXSGL-API-022 | 修改 | 不存在 id | 接口测试 | Postman | 异常 | 已登录 | 伪造 id `PUT` | 失败 |
| ZCZX-CXSGL-API-023 | 删除 | 单条逻辑删 | 接口测试 | Postman | §5.5 | 无关联新行 | `DELETE /{id}` | 成功；列表无 |
| ZCZX-CXSGL-API-024 | 删除 | 有未支付订单拒绝 | 接口测试 | Postman | §5.5 | 预置待支付订单 | `DELETE` | 失败；提示未支付 |
| ZCZX-CXSGL-API-025 | 删除 | 重复删除 | 接口测试 | Postman | 幂等 | 已删 id | 再次 `DELETE` | 失败或不存在 |
| ZCZX-CXSGL-API-026 | 端到端 | CRUD 串联 | 接口测试 | Postman | §4 | 已登录 | `POST`→`list`→`GET`→`PUT`→`DELETE` | 每步成功 |
| ZCZX-CXSGL-API-027 | 鉴权 | 未登录 | 接口测试 | curl | 安全 | 无 Token | `GET list` | 401 或统一未登录 |
| ZCZX-CXSGL-API-028 | 权限 | 无新增权限 | 接口测试 | Postman | §6 | 仅 list | `POST` | 无权限失败 |
| ZCZX-CXSGL-API-029 | 权限 | 无删除权限 | 接口测试 | Postman | §6 | 无 remove | `DELETE` | 无权限失败 |
| ZCZX-CXSGL-API-030 | 响应 | 失败可读 | 接口测试 | Postman | 草稿 §8 | 已登录 | 触发缺去向、重复名、手机号错 | `msg` 可区分 |
| ZCZX-CXSGL-API-031 | 分配账号 | 成功 | 接口测试 | Postman | §3.6 | DU | `POST .../assignAccount/{id}` | `accountAssigned=1`；角色 **104** |
| ZCZX-CXSGL-API-032 | 分配账号 | 重复 | 接口测试 | Postman | §3.6 | DA | 再次调用 | 失败 |
| ZCZX-CXSGL-API-033 | 删除 | 已分配联动 | 接口测试 | Postman | §3.5 | 已分配无关联行 | `DELETE` | 用户已删 |
| ZCZX-CXSGL-API-034 | 权限 | 无分配权限 | 接口测试 | Postman | §4 | 无 assignAccount | `POST assignAccount` | 无权限失败 |

---

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

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

| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ZCZX-CXSGL-UI-001 | 列表 | 默认展示 | UI 测试 | Playwright+Chrome | §5.2.3 | 已登录；有数据 | 进入「承销商管理」 | 含编号、名称、类型、识别号、电话、地点、销售去向、操作 |
| ZCZX-CXSGL-UI-002 | 列表 | 编号模糊筛选 | UI 测试 | Playwright+Chrome | §2.8 | 有 D1 `01` | 编号输入 `1`→搜索 | 含 D1 |
| ZCZX-CXSGL-UI-003 | 列表 | 名称模糊筛选 | UI 测试 | Playwright+Chrome | §2.8 | 有 D2 | 名称输入「雪域」→搜索 | 含 D2 |
| ZCZX-CXSGL-UI-004 | 列表 | 无结果 | UI 测试 | Playwright+Chrome | §2.8 | 已登录 | 输入不存在关键字→搜索 | 空列表或空状态 |
| ZCZX-CXSGL-UI-005 | 列表 | 重置 | UI 测试 | Playwright+Chrome | §5.2 | 已筛选 | 搜索→重置 | 条件清空 |
| ZCZX-CXSGL-UI-006 | 新增 | 个体户本市 | UI 测试 | Playwright+Chrome | §5.1 | 已登录 | 新增→个体户→本市→填必填→确定 | 成功；列表新行 |
| ZCZX-CXSGL-UI-007 | 新增 | 企业本省 | UI 测试 | Playwright+Chrome | §5.1 | 已登录 | 企业+主体识别号+本省→确定 | 成功 |
| ZCZX-CXSGL-UI-008 | 新增 | 销售去向必选 | UI 测试 | Playwright+Chrome | §5.1.4 | 新增 | 不选销售去向→确定 | 校验失败 |
| ZCZX-CXSGL-UI-009 | 新增 | 类型切换标签 | UI 测试 | Playwright+Chrome | §5.1.2 | 新增 | 个体户↔企业 | 标签在身份证/主体识别号间切换 |
| ZCZX-CXSGL-UI-010 | 新增 | 编号只读 | UI 测试 | Playwright+Chrome | §2.4 | 打开新增 | 查看编号控件 | 只读或保存后自动生成 |
| ZCZX-CXSGL-UI-011 | 新增 | 缺必填 | UI 测试 | Playwright+Chrome | §5.1.4 | 新增 | 留空名称或手机→确定 | 校验失败 |
| ZCZX-CXSGL-UI-012 | 新增 | 名称 20 字 | UI 测试 | Playwright+Chrome | §5.1.1 | 新增 | 超 20 字 | 无法输入或保存失败 |
| ZCZX-CXSGL-UI-013 | 新增 | 取消 | UI 测试 | Playwright+Chrome | §5.1.3 | 新增 | 填一半→取消 | 无新行 |
| ZCZX-CXSGL-UI-014 | 详情 | 只读含去向 | UI 测试 | Playwright+Chrome | §5.4 | 有 D3 | 查看 | 只读；销售去向为外省；含审计 |
| ZCZX-CXSGL-UI-015 | 编辑 | 修改地点 | UI 测试 | Playwright+Chrome | §5.3 | 有 D1 | 编辑→改经营地点→确定 | 列表已更新；编号不变 |
| ZCZX-CXSGL-UI-016 | 编辑 | 编号不可改 | UI 测试 | Playwright+Chrome | §5.3 | 编辑 D1 | 查看编号 | 只读 |
| ZCZX-CXSGL-UI-017 | 编辑 | 改销售去向 | UI 测试 | Playwright+Chrome | §5.3 | D1 本市 | 改外省→保存 | 列表/详情为外省 |
| ZCZX-CXSGL-UI-018 | 删除 | 确认删除 | UI 测试 | Playwright+Chrome | §5.5 | 无关联行 | 删除→确认 | 行消失 |
| ZCZX-CXSGL-UI-019 | 删除 | 取消删除 | UI 测试 | Playwright+Chrome | §5.5 | 任意行 | 删除→取消 | 行仍在 |
| ZCZX-CXSGL-UI-020 | 端到端 | 全流程 | UI 集成 | Playwright+Chrome | §4 | 权限齐备 | 新增→模糊查→看→改→删 | 无报错 |
| ZCZX-CXSGL-UI-021 | 权限 | 只读角色 | UI 测试 | Playwright+Chrome | §6 | 无写权限 | 进入模块 | 无新增/编辑/删除 |
| ZCZX-CXSGL-UI-022 | 详情 | 从详情编辑 | UI 测试 | Playwright+Chrome | §5.4 | 查看 D1 | 点「编辑」 | 进入编辑弹窗 |
| ZCZX-CXSGL-UI-023 | 列表 | 账号分配列 | UI 测试 | Playwright+Chrome | §5.2.3 | DU、DA | 查看列表 | 未分配/已分配展示正确 |
| ZCZX-CXSGL-UI-024 | 分配账号 | 成功 | UI 测试 | Playwright+Chrome | §5.6 | DU | 分配账号→确认 | 成功；无二次入口 |
| ZCZX-CXSGL-UI-025 | 分配账号 | 已分配无按钮 | UI 测试 | Playwright+Chrome | §5.6 | DA | 操作列 | 无分配账号 |
| ZCZX-CXSGL-UI-026 | 权限 | 无分配权限 | 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/distributor')`（以菜单 `component` 为准）。  
- 模糊搜索：`page.getByLabel('承销商编号').fill('1')` 后点击「搜索」。  
- 销售去向：`page.getByLabel('销售去向').click()` 后选「本市」等选项。

---

## 覆盖对照

| 类别 | 单元 UT | 接口 API | 界面 UI |
| --- | --- | --- | --- |
| 正常流程 | UT-012 | API-008～010、017、019～020、026 | UI-006～007、014～017、020 |
| 异常流程 | UT-003 | API-011～016、022、024～025 | UI-008、011、018～019 |
| 业务约束 | UT-001～011 | API-002～004、013～016、021 | UI-002～004、009～010、016 |
| 模糊筛选 | UT-016 | API-002～006 | UI-002～004 |
| 销售去向 | UT-008 | API-011～012、020 | UI-006～008、017 |
| 逻辑删除 | UT-014 | API-007、023～025 | UI-018 |
| 权限/鉴权 | — | API-027～029、034 | UI-021、026 |
| 分配账号 | UT-018～022 | API-031～033 | UI-023～025 |

---

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

| 需求章节 | 要点 | 主要对应用例 |
| --- | --- | --- |
| §5.1 新增 | 字段、销售去向 | UT-004～009、012；API-008～016；UI-006～013 |
| §5.2 列表 | **模糊**筛选 | UT-016；API-002～006；UI-002～005 |
| §5.3 修改 | 编号不可改 | UT-013；API-019～021；UI-015～017 |
| §5.4 详情 | 只读 | API-017；UI-014、022 |
| §5.5 删除 | 逻辑删、未支付拦截 | UT-014～015；API-023～025；UI-018～019 |
| §2.3 销售去向 | 三档 | UT-008；API-008～012、021；UI-006～008、018 |
| §2.4 编号 | 01～99 | UT-001～003；API-008；UI-010 |
| §6 权限 | 按钮级 | API-028～029、034；UI-021、026 |
| §5.6 分配账号 | 角色 104、一次 | UT-018～022；API-031～033；UI-023～025 |

---

## 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：单元 18、接口 31、UI 23；覆盖 CRUD、模糊筛选、销售去向、编号；Playwright+Chrome；前缀 **ZCZX-CXSGL** |
| 1.1 | 移除车辆号牌相关用例；章节引用 §2.8；用例编号重排（单元 17、接口 30、UI 22） |
| 1.2 | 增补分配账号：UT-018～022、API-031～034、UI-023～026；样本 DU/DA |
| 1.3 | 删除拦截：UT-015、API-024 对齐未支付订单 |
