# 管理员列表 — 测试用例

> **依据：** 《管理员列表功能需求.md》v1.1、《管理员列表技术方案.md》v1.1  
> **关联：** 《会员管理测试用例.md》v1.1（member 列表互斥）、《商户管理测试用例.md》v1.2（merchant 绑定/经营账号）  
> **范围：** 平台端 `/agri/platformAdmin` 列表/详情/新增/编辑/删除/角色选项；`PlatformAdminSupport` 安全校验；列表 **admin/merchant** 角色过滤  
> **排除：** 导入导出、重置密码专接口、账号管理（经营账号）模块、子管理员 CRUD、部门岗位表单  
> **环境：** RuoYi v3.9.2-springboot2；MySQL 5.7.39；平台 Token；UI 基路径 `{PLATFORM_URL}`

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| PAD-UT-xxx | 单元测试 | JUnit 5 + Mockito |
| PAD-API-xxx | 接口测试 | Apifox / REST Assured |
| PAD-UI-xxx | 界面测试 | Playwright（**Google Chrome**，`channel: chrome`） |

---

## 一、单元测试

### PAD-UT-001 列表仅含列表范围角色用户

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-001 |
| **测试模块** | 管理员列表 |
| **测试项** | selectAdminList 角色过滤 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 A1：仅 `admin`/`merchant` 出现在列表 |
| **前置条件** | Mock Mapper 返回：用户 A 具 admin；用户 B 仅 member；用户 C 仅 merchant；用户 D 具其他角色（如 common） |
| **测试步骤** | 调用 `PlatformAdminServiceImpl.selectAdminList(query)` |
| **预期结果** | 结果含 A、C；**不含** B、D |

### PAD-UT-002 keyword 匹配昵称

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-002 |
| **测试模块** | 管理员列表 |
| **测试项** | 列表检索 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A5：管理员名称模糊匹配 nick_name |
| **前置条件** | 用户 nick_name=「运营甲」，user_name 不含关键字 |
| **测试步骤** | query.keyword=「运营」 |
| **预期结果** | 命中该用户 |

### PAD-UT-003 keyword 匹配登录名

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-003 |
| **测试模块** | 管理员列表 |
| **测试项** | 列表检索 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A5：无昵称时匹配 user_name |
| **前置条件** | nick_name 空，user_name=pad_user01 |
| **测试步骤** | keyword=pad_user |
| **预期结果** | 命中 |

### PAD-UT-004 列表 adminName 优先昵称

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-004 |
| **测试模块** | 管理员列表 |
| **测试项** | ListVO 组装 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证展示名规则 |
| **前置条件** | nick_name=「张三」，user_name=zhangsan |
| **测试步骤** | 转 `PlatformAdminListVO` |
| **预期结果** | adminName=「张三」 |

### PAD-UT-005 角色名仅聚合列表范围角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-005 |
| **测试模块** | 管理员列表 |
| **测试项** | roleNames 聚合 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证列表 roleNames 不含 merchant/member |
| **前置条件** | 用户同时具 admin、merchant 角色 |
| **测试步骤** | 组装 ListVO |
| **预期结果** | roleNames 含「超级管理员」；**不含** merchant 角色名 |

### PAD-UT-006 新增拒绝 member 角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-006 |
| **测试模块** | 管理员列表 |
| **测试项** | createAdmin 角色校验 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A9、与会员边界 |
| **前置条件** | roleIds 含 member 角色 id |
| **测试步骤** | `createAdmin(dto)` |
| **预期结果** | 抛 `ServiceException`；msg 含「所选角色无效」或等价；**不** 调 insertUser |

### PAD-UT-007 新增 roleIds 为空失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-007 |
| **测试模块** | 管理员列表 |
| **测试项** | createAdmin |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A2：至少一个列表范围角色 |
| **前置条件** | 合法 userName/phone/password；roleIds=[] |
| **测试步骤** | createAdmin |
| **预期结果** | 失败；msg 含「请选择角色」 |

### PAD-UT-008 新增登录名重复失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-008 |
| **测试模块** | 管理员列表 |
| **测试项** | createAdmin 唯一性 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 A3 |
| **前置条件** | `checkUserNameUnique` 返回 false |
| **测试步骤** | createAdmin |
| **预期结果** | 失败；msg 登录名已存在 |

### PAD-UT-009 新增手机号重复失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-009 |
| **测试模块** | 管理员列表 |
| **测试项** | createAdmin 唯一性 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 A3 |
| **前置条件** | `checkPhoneUnique` 返回 false |
| **测试步骤** | createAdmin |
| **预期结果** | 失败；msg 手机号已存在 |

### PAD-UT-010 新增密码 BCrypt 入库

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-010 |
| **测试模块** | 管理员列表 |
| **测试项** | createAdmin |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + ArgumentCaptor |
| **测试目的** | 验证密码加密 |
| **前置条件** | Mock insertUser 成功 |
| **测试步骤** | password=Admin@123；createAdmin |
| **预期结果** | 传入 SysUser.password 为 BCrypt 哈希；**不等于** 明文 |

### PAD-UT-011 编辑不更新 user_name

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-011 |
| **测试模块** | 管理员列表 |
| **测试项** | updateAdmin |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证登录名不可改 |
| **前置条件** | 原 user_name=old_login；DTO 试图改登录名 |
| **测试步骤** | updateAdmin |
| **预期结果** | updateUser 入参 user_name 仍为 old_login |

### PAD-UT-012 编辑自身不可移除全部平台角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-012 |
| **测试模块** | 管理员列表 |
| **测试项** | assertEditableRoles |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §6.2 防锁死 |
| **前置条件** | currentUserId=目标 userId；roleIds 为空或非平台类 |
| **测试步骤** | `PlatformAdminSupport.assertEditableRoles(...)` |
| **预期结果** | 抛异常；msg 含不可移除全部平台角色 |

### PAD-UT-013 唯一 admin 不可降权

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-013 |
| **测试模块** | 管理员列表 |
| **测试项** | assertEditableRoles |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 §6.2 最后一个超级管理员 |
| **前置条件** | 全库仅 1 人具 admin；编辑其 roleIds 仅 merchant |
| **测试步骤** | updateAdmin / assertEditableRoles |
| **预期结果** | 失败；msg 至少保留一名超级管理员 |

### PAD-UT-014 删除自身失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-014 |
| **测试模块** | 管理员列表 |
| **测试项** | assertDeletable |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A6 |
| **前置条件** | userIds 含 currentUserId |
| **测试步骤** | assertDeletable |
| **预期结果** | 失败；msg 不能删除当前用户 |

### PAD-UT-015 删除 user_id=1 失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-015 |
| **测试模块** | 管理员列表 |
| **测试项** | assertDeletable |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 RuoYi checkUserAllowed |
| **前置条件** | userIds 含 1L |
| **测试步骤** | assertDeletable |
| **预期结果** | 失败；不允许操作超级管理员用户 |

### PAD-UT-016 删除最后一个 admin 失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-016 |
| **测试模块** | 管理员列表 |
| **测试项** | assertDeletable |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证 A6 |
| **前置条件** | 全库仅目标用户具 admin；无其他 admin |
| **测试步骤** | deleteAdmin |
| **预期结果** | 失败；msg 至少保留一名超级管理员 |

### PAD-UT-017 删除已绑定经营账号失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-017 |
| **测试模块** | 管理员列表 |
| **测试项** | assertDeletable |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证 §7.2 与商户协作 |
| **前置条件** | `biz_merchant_account.account_id=user.user_id` 且 del_flag=0 |
| **测试步骤** | deleteAdmin |
| **预期结果** | 失败；msg 已绑定商户经营账号 |

### PAD-UT-018 批量删除任一条失败则整批失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-018 |
| **测试模块** | 管理员列表 |
| **测试项** | deleteAdmin 批量 |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit + Mockito |
| **测试目的** | 验证技术方案 §3.6 整批失败策略 |
| **前置条件** | userIds=[可删A, 不可删B(绑定经营账号)] |
| **测试步骤** | deleteAdmin |
| **预期结果** | 整批失败；A、B 均 **未** 逻辑删除 |

### PAD-UT-019 详情不在列表范围抛不存在

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-019 |
| **测试模块** | 管理员列表 |
| **测试项** | getAdminDetail |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 验证详情范围校验 |
| **前置条件** | userId 对应用户仅 member 角色 |
| **测试步骤** | getAdminDetail(userId) |
| **预期结果** | 抛异常；msg 管理员不存在 |

### PAD-UT-020 countUsersWithRoleKey 统计 admin

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UT-020 |
| **测试模块** | 管理员列表 |
| **测试项** | PlatformAdminSupport |
| **测试类型** | 单元测试 |
| **测试工具** | JUnit |
| **测试目的** | 支撑删除/降权校验 |
| **前置条件** | DB 有 2 个 admin、1 个 merchant |
| **测试步骤** | countUsersWithRoleKey('admin') |
| **预期结果** | 返回 2 |

---

## 二、接口测试

### PAD-API-001 列表分页与默认排序

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-001 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /agri/platformAdmin/list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A4、§4.2 分页排序 |
| **前置条件** | ≥3 条管理员；Token 含 `agri:platformAdmin:list` |
| **测试步骤** | GET `/list?pageNum=1&pageSize=10` |
| **预期结果** | `code=200`；`rows` 按 createTime **降序**；含 adminName、phonenumber、email、roleNames、createTime |

### PAD-API-002 keyword 检索管理员名称

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-002 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A5 |
| **前置条件** | 存在 nick_name 含「测试管理员」记录 |
| **测试步骤** | GET `/list?keyword=测试管理员` |
| **预期结果** | 仅返回匹配行；total≥1 |

### PAD-API-003 列表不含纯 member 用户

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-003 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A1、与会员边界 |
| **前置条件** | 存在仅 member 角色用户（会员管理可见） |
| **测试步骤** | GET `/list` |
| **预期结果** | `rows` 中 **无** 该 userId |

### PAD-API-004 列表不含 common 等非范围角色用户

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-004 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A1：非 admin/merchant 不出现 |
| **前置条件** | 存在仅 RuoYi **common** 角色用户 |
| **测试步骤** | GET `/list` |
| **预期结果** | `rows` 不含该用户 |

### PAD-API-005 列表含 merchant 用户

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-005 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 merchant 在列表范围 |
| **前置条件** | 用户仅 merchant 角色 |
| **测试步骤** | GET `/list` |
| **预期结果** | 含该用户；roleNames 含「商户经营」 |

### PAD-API-006 详情正常返回

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-006 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /{userId} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §3.3 详情字段 |
| **前置条件** | 目标为 merchant 用户；`agri:platformAdmin:query` |
| **测试步骤** | GET `/{userId}` |
| **预期结果** | `code=200`；data 含 userId、adminName、userName、phonenumber、email、avatar、roleIds、roleNames、createTime |

### PAD-API-007 详情-非列表范围用户

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-007 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /{userId} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证详情边界 |
| **前置条件** | userId 为纯 member 用户 |
| **测试步骤** | GET `/{userId}` |
| **预期结果** | `code=500`（或非 200）；msg 管理员不存在 |

### PAD-API-008 新增管理员成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-008 |
| **测试模块** | 管理员列表 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A2 正向流程 |
| **前置条件** | 新 userName、新手机号；roleIds=[merchant]；`agri:platformAdmin:add` |
| **测试步骤** | POST Body：adminName、userName、phonenumber、password、roleIds |
| **预期结果** | `code=200`；`data=userId`；列表可查到；sys_user_role 已写入 |

### PAD-API-009 新增-登录名重复

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-009 |
| **测试模块** | 管理员列表 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A3 |
| **前置条件** | userName 已被占用 |
| **测试步骤** | POST 重复 userName |
| **预期结果** | 失败；msg 登录名已存在 |

### PAD-API-010 新增-手机号重复

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-010 |
| **测试模块** | 管理员列表 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A3 |
| **前置条件** | phonenumber 已被 del_flag=0 用户占用 |
| **测试步骤** | POST 重复手机号 |
| **预期结果** | 失败；msg 手机号已存在 |

### PAD-API-011 新增-未选角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-011 |
| **测试模块** | 管理员列表 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A2 |
| **前置条件** | roleIds 缺省或 [] |
| **测试步骤** | POST 其它字段合法 |
| **预期结果** | 失败；msg 请选择角色 |

### PAD-API-012 新增-传入 member 角色 id

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-012 |
| **测试模块** | 管理员列表 |
| **测试项** | POST / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证与会员边界 |
| **前置条件** | 取得 member 角色 roleId |
| **测试步骤** | POST roleIds=[memberRoleId] |
| **预期结果** | 失败；msg 所选角色无效 |

### PAD-API-013 编辑资料成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-013 |
| **测试模块** | 管理员列表 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.1 正向 |
| **前置条件** | 目标 merchant 用户；`agri:platformAdmin:edit` |
| **测试步骤** | PUT 修改 adminName、phonenumber、email、roleIds |
| **预期结果** | `code=200`；GET 详情字段已更新；userName **不变** |

### PAD-API-014 编辑自身-保留平台角色成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-014 |
| **测试模块** | 管理员列表 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.2 编辑自身 |
| **前置条件** | Token 对应 userId=当前编辑对象 |
| **测试步骤** | PUT 改 nick_name；roleIds 仍含 ≥1 列表范围角色 |
| **预期结果** | 成功 |

### PAD-API-015 编辑自身-移除全部平台角色失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-015 |
| **测试模块** | 管理员列表 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.2 防锁死 |
| **前置条件** | 当前用户编辑自身 |
| **测试步骤** | PUT roleIds=[] 或仅 merchant |
| **预期结果** | 失败；不可移除全部列表范围角色 |

### PAD-API-016 编辑唯一 admin-降权失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-016 |
| **测试模块** | 管理员列表 |
| **测试项** | PUT / |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §6.2 |
| **前置条件** | 全库仅 1 个 admin 账号 |
| **测试步骤** | PUT 将其 roleIds 改为仅 merchant |
| **预期结果** | 失败；至少保留一名超级管理员 |

### PAD-API-017 单独删除成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-017 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7 正向 |
| **前置条件** | 目标为 merchant、无经营账号绑定、非当前用户；`agri:platformAdmin:remove` |
| **测试步骤** | DELETE `/{userId}` |
| **预期结果** | `code=200`；GET list 不再出现；sys_user.del_flag=2 |

### PAD-API-018 删除当前登录用户失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-018 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A6 |
| **前置条件** | userIds=Token 对应 userId |
| **测试步骤** | DELETE 自身 id |
| **预期结果** | 失败；msg 不能删除当前用户 |

### PAD-API-019 删除最后一个 admin 失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-019 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 A6 |
| **前置条件** | 仅 1 个 admin 账号 |
| **测试步骤** | DELETE 该 admin |
| **预期结果** | 失败；至少保留一名超级管理员 |

### PAD-API-020 删除已绑定经营账号失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-020 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7.2、与商户协作 |
| **前置条件** | 用户 `user_id` 存在于 `biz_merchant_account.account_id` |
| **测试步骤** | DELETE 该 userId |
| **预期结果** | 失败；msg 已绑定商户经营账号 |

### PAD-API-021 批量删除成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-021 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §7.1 批量 |
| **前置条件** | 2 个可删 merchant 用户 |
| **测试步骤** | DELETE `/id1,id2` |
| **预期结果** | 成功；两条均 del_flag=2 |

### PAD-API-022 批量删除含不可删项整批失败

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-022 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE /{userIds} |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证整批失败策略 |
| **前置条件** | idA 可删；idB 绑定经营账号 |
| **测试步骤** | DELETE `idA,idB` |
| **预期结果** | 失败；A、B **均未** 删除 |

### PAD-API-023 角色选项仅列表范围角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-023 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /roleOptions |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证 §3.7 |
| **前置条件** | 系统存在 admin、merchant、member、merchant 角色 |
| **测试步骤** | GET `/roleOptions` |
| **预期结果** | 仅含 admin、merchant；每项含 roleId、roleName、roleKey |

### PAD-API-024 无 list 权限拒绝访问

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-024 |
| **测试模块** | 管理员列表 |
| **测试项** | GET /list |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证权限控制 |
| **前置条件** | Token 无 `agri:platformAdmin:list` |
| **测试步骤** | GET `/list` |
| **预期结果** | HTTP 403 或 `code=403`；无数据泄露 |

### PAD-API-025 统一响应结构

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-025 |
| **测试模块** | 管理员列表 |
| **测试项** | 响应格式 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox |
| **测试目的** | 验证草稿 §6 code/msg/data |
| **前置条件** | 任意成功/失败请求各 1 次 |
| **测试步骤** | 检查 JSON 根字段 |
| **预期结果** | 成功含 code、msg、data/rows/total；失败含 code、msg |

### PAD-API-026 删除后不级联删商户店铺

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-API-026 |
| **测试模块** | 管理员列表 |
| **测试项** | DELETE 副作用 |
| **测试类型** | 接口测试 |
| **测试工具** | Apifox + SQL 查询 |
| **测试目的** | 验证 §7.3 |
| **前置条件** | 删除无经营账号绑定的 admin 用户 |
| **测试步骤** | DELETE 成功后查 biz_merchant/biz_shop |
| **预期结果** | 商户、店铺数据 **不变** |

---

## 三、界面测试（Playwright · Google Chrome）

> **通用前置：** 平台超管或具 `agri:platformAdmin:*` 角色已登录；Playwright 配置 `channel: 'chrome'`；baseURL=`{PLATFORM_URL}`；菜单路径「农资管理 → 权限管理 → 管理员列表」（路由 `agri/platformAdmin/index`）。

### PAD-UI-001 进入管理员列表页

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-001 |
| **测试模块** | 管理员列表 |
| **测试项** | 列表页加载 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §10 列表字段与工具栏 |
| **前置条件** | 有 list 权限；存在 ≥1 条管理员 |
| **测试步骤** | 1. 登录平台 2. 点击「管理员列表」菜单 |
| **预期结果** | 表格列含：管理员名称、手机号、邮箱、角色名称、添加时间、操作；工具栏有「添加管理员」「批量删除」；有检索区与分页 |

### PAD-UI-002 按管理员名称检索

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-002 |
| **测试模块** | 管理员列表 |
| **测试项** | 高级检索 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A5 检索交互 |
| **前置条件** | 存在 nick_name 含「运营测试」的管理员 |
| **测试步骤** | 1. 检索框输入「运营测试」 2. 点击「搜索/查询」 |
| **预期结果** | 列表仅显示匹配行；分页重置为第 1 页 |

### PAD-UI-003 列表默认按添加时间倒序

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-003 |
| **测试模块** | 管理员列表 |
| **测试项** | 列表排序 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A4 |
| **前置条件** | 已知两条记录 createTime 先后 |
| **测试步骤** | 打开列表不排序 |
| **预期结果** | 最新添加时间记录排在最前 |

### PAD-UI-004 空数据友好提示

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-004 |
| **测试模块** | 管理员列表 |
| **测试项** | 空态 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §4.2 空态 |
| **前置条件** | keyword 检索无结果 |
| **测试步骤** | 输入不存在名称→查询 |
| **预期结果** | 表格空态文案友好（如「暂无数据」） |

### PAD-UI-005 添加管理员成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-005 |
| **测试模块** | 管理员列表 |
| **测试项** | 添加管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §5 正向流程 |
| **前置条件** | 有 add 权限；新登录名、新手机号 |
| **测试步骤** | 1. 点「添加管理员」 2. 填管理员名称、登录名、手机号、密码 3. 选「商户经营」角色 4. 确定 |
| **预期结果** | Toast 成功；弹窗关闭；列表首行出现新记录；角色列含「商户经营」 |

### PAD-UI-006 添加必填项为空校验

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-006 |
| **测试模块** | 管理员列表 |
| **测试项** | 添加管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §5.2 校验失败 |
| **前置条件** | 打开新增弹窗 |
| **测试步骤** | 不填任何项直接点「确定」 |
| **预期结果** | 表单项标红或提示；弹窗不关闭；无新记录 |

### PAD-UI-007 添加登录名重复提示

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-007 |
| **测试模块** | 管理员列表 |
| **测试项** | 添加管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A3 UI 反馈 |
| **前置条件** | 登录名 admin 已存在 |
| **测试步骤** | 填写重复登录名及其他合法项→提交 |
| **预期结果** | Toast/表单提示「登录名已存在」 |

### PAD-UI-008 添加未选角色校验

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-008 |
| **测试模块** | 管理员列表 |
| **测试项** | 添加管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A2 角色必选 |
| **前置条件** | 打开新增弹窗 |
| **测试步骤** | 填齐其它必填项但不选角色→提交 |
| **预期结果** | 提示请选择角色；提交失败 |

### PAD-UI-009 角色下拉不含 member/merchant

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-009 |
| **测试模块** | 管理员列表 |
| **测试项** | 角色选项 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A9 表单角色范围 |
| **前置条件** | 打开新增/编辑弹窗 |
| **测试步骤** | 展开角色多选下拉 |
| **预期结果** | 可选项仅 **超级管理员、商户经营**；**无** member |

### PAD-UI-010 编辑弹窗登录名只读

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-010 |
| **测试模块** | 管理员列表 |
| **测试项** | 编辑管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §6.1 登录名不可改 |
| **前置条件** | 选中一条记录 |
| **测试步骤** | 点「编辑」→查看登录名字段 |
| **预期结果** | 登录名 **disabled/只读**；不可编辑 |

### PAD-UI-011 编辑资料成功

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-011 |
| **测试模块** | 管理员列表 |
| **测试项** | 编辑管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §6 正向 |
| **前置条件** | 目标 merchant 用户 |
| **测试步骤** | 修改管理员名称、邮箱→保存 |
| **预期结果** | 成功提示；列表对应行已更新 |

### PAD-UI-012 编辑自身不可清空全部角色

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-012 |
| **测试模块** | 管理员列表 |
| **测试项** | 编辑管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §6.2 |
| **前置条件** | 当前登录用户编辑自身 |
| **测试步骤** | 取消勾选全部列表范围角色→保存 |
| **预期结果** | 失败提示；角色仍保留至少一项 |

### PAD-UI-013 单独删除二次确认

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-013 |
| **测试模块** | 管理员列表 |
| **测试项** | 删除管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §7.2 二次确认 |
| **前置条件** | 可删 merchant 用户 |
| **测试步骤** | 1. 点行「删除」 2. 在确认框点「取消」 3. 再次删除点「确定」 |
| **预期结果** | 取消后仍在列表；确定后成功且该行消失 |

### PAD-UI-014 删除当前用户失败提示

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-014 |
| **测试模块** | 管理员列表 |
| **测试项** | 删除管理员 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 A6 |
| **前置条件** | 列表含当前登录用户行 |
| **测试步骤** | 对当前用户点「删除」→确认 |
| **预期结果** | 提示不能删除当前用户；记录仍在 |

### PAD-UI-015 批量删除二次确认

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-015 |
| **测试模块** | 管理员列表 |
| **测试项** | 批量删除 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §7.1 批量交互 |
| **前置条件** | 勾选 2 条可删记录 |
| **测试步骤** | 点「批量删除」→确认 |
| **预期结果** | 确认框提示条数或「删除后不可恢复」；确认后两条均消失 |

### PAD-UI-016 角色名称过长省略与 tooltip

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-016 |
| **测试模块** | 管理员列表 |
| **测试项** | 角色展示 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §10 角色展示 |
| **前置条件** | 用户具多个列表范围角色导致 roleNames 较长 |
| **测试步骤** | 查看列表角色列；hover 省略文本 |
| **预期结果** | 过长显示省略号；tooltip 展示完整角色名 |

### PAD-UI-017 无权限菜单不可见

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-017 |
| **测试模块** | 管理员列表 |
| **测试项** | 菜单权限 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §10 权限 |
| **前置条件** | 使用无 `agri:platformAdmin:list` 的角色登录 |
| **测试步骤** | 查看侧栏「权限管理」 |
| **预期结果** | **无**「管理员列表」菜单入口 |

### PAD-UI-018 无 add 权限隐藏添加按钮

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-018 |
| **测试模块** | 管理员列表 |
| **测试项** | 按钮权限 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证按钮级权限 |
| **前置条件** | 仅有 list+query 权限 |
| **测试步骤** | 进入列表页 |
| **预期结果** | 无「添加管理员」按钮；行内无「编辑/删除」或按权限隐藏 |

### PAD-UI-019 邮箱为空显示占位

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-019 |
| **测试模块** | 管理员列表 |
| **测试项** | 列表展示 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §4.1 邮箱空值 |
| **前置条件** | 某管理员 email 为空 |
| **测试步骤** | 查看列表邮箱列 |
| **预期结果** | 显示「—」或等价占位 |

### PAD-UI-020 分页切换

| 要素 | 内容 |
|------|------|
| **用例编号** | PAD-UI-020 |
| **测试模块** | 管理员列表 |
| **测试项** | 分页 |
| **测试类型** | 界面测试 |
| **测试工具** | Playwright (Google Chrome) |
| **测试目的** | 验证 §4.2 分页 |
| **前置条件** | 管理员数量 > pageSize（默认 10） |
| **测试步骤** | 点击第 2 页 |
| **预期结果** | 表格刷新为第 2 页数据；页码高亮正确 |

---

## 四、测试数据准备

| 数据项 | 说明 |
|--------|------|
| **超管 A** | user_id=1 或具 admin；**不可删** |
| **商户经营 B** | 仅 merchant；可增删改测 |
| **双角色 C** | admin + merchant；roleNames 聚合 |
| **纯会员 D** | 仅 member；本模块不可见 |
| **common 用户 E** | 仅 common 角色；本模块不可见 |
| **绑定经营账号 F** | admin/merchant + `biz_merchant_account.account_id=user_id` |
| **Platform Token** | 含 `agri:platformAdmin:*` |
| **受限 Token** | 无 platformAdmin 权限 |
| **Playwright 配置** | `{ "use": { "channel": "chrome", "baseURL": "{PLATFORM_URL}" } }` |

---

## 五、与关联模块协作用例

| 场景 | 本模块用例 | 关联模块 |
|------|------------|----------|
| member 不出现在管理员列表 | PAD-API-003、PAD-UT-001 | MEM-API-021 |
| merchant 绑定后删除阻断 | PAD-API-020、PAD-UT-017 | MER-API-047 |
| 先建管理员再商户绑定 | PAD-API-008 | MER-API-044 |
| 删除不删商户数据 | PAD-API-026 | MER-API 删商户独立 |

---

## 六、用例统计

| 类型 | 数量 |
|------|------|
| 单元测试 PAD-UT | 20 |
| 接口测试 PAD-API | 26 |
| 界面测试 PAD-UI | 20 |
| **合计** | **66** |

---

## 七、规则覆盖矩阵

| 规则 | 单元 | 接口 | UI |
|------|:----:|:----:|:--:|
| A1 列表范围 admin/merchant | UT-001 | API-003/004/005 | — |
| A2 新增必填 | UT-007 | API-008/011 | UI-005/006/008 |
| A3 登录名/手机唯一 | UT-008/009 | API-009/010 | UI-007 |
| A4 添加时间倒序 | — | API-001 | UI-003 |
| A5 名称检索 | UT-002/003 | API-002 | UI-002 |
| A6 删自己/最后 admin | UT-014/016 | API-018/019 | UI-014 |
| A7 角色变更生效 | — | API-013 | UI-011 |
| A8 不维护经营账号/会员 | UT-006/019 | API-012/026 | UI-009 |
| A9 角色选项范围 | UT-005/006 | API-023 | UI-009 |
| 经营账号删除阻断 | UT-017/018 | API-020/022 | — |
| 编辑自身/唯一 admin | UT-012/013 | API-014/015/016 | UI-012 |
| 批量删除 | UT-018 | API-021/022 | UI-015 |
| 权限控制 | — | API-024 | UI-017/018 |

---

*文档版本：v1.1 · 关联《管理员列表功能需求.md》v1.1、《管理员列表技术方案.md》v1.1*
