# 会员管理 — 测试用例

> **依据：** 《会员管理功能需求.md》v1.1、《会员管理技术方案.md》v1.3、《消费者APP/会员注册登录/会员注册登录技术方案.md》v1.2  
> **关联：** 《订单管理测试用例.md》v1.0（会员订单只读、O11 消费统计）、《订单管理技术方案.md》v1.0  
> **范围：** 平台端 `/agri/member` 列表/详情/添加/启用禁用/会员订单只读；`IMemberFacade`；C 端 `/api/member` 注册登录；账号 **sys_user** + 角色 **member**  
> **排除：** 余额积分、标签、导入、商家端查会员、会员等级自动升级  
> **环境：** RuoYi v3.9.2；平台 Token + 会员 C 端 Token

---

## 用例编号说明

| 前缀 | 类型 | 工具 |
|------|------|------|
| MEM-UT-xxx | 单元测试 | JUnit 5 + Mockito |
| MEM-API-xxx | 接口测试 | Apifox / REST Assured |
| MEM-UI-xxx | 界面测试 | Playwright |

---

## 一、单元测试

### MEM-UT-001 手机号未删唯一-注册重复失败

| 要素 | 内容 |
|------|------|
| **测试项** | register |
| **测试目的** | 验证 M2 |
| **前置条件** | 已有 mobile=17700001111 |
| **测试步骤** | 同号注册 |
| **预期结果** | 失败；手机号已注册 |

### MEM-UT-002 逻辑删除后同号可再注册

| 要素 | 内容 |
|------|------|
| **测试项** | register |
| **测试目的** | 唯一仅 del_flag=0 |
| **前置条件** | 原会员 del_flag=2 |
| **测试步骤** | 同号注册 |
| **预期结果** | 成功；新 member_id |

### MEM-UT-003 isMemberEnabled 启用 true

| 要素 | 内容 |
|------|------|
| **测试项** | IMemberFacade |
| **测试目的** | 验证 M4 |
| **前置条件** | status=0，del_flag=0 |
| **测试步骤** | `isMemberEnabled(id)` |
| **预期结果** | true |

### MEM-UT-004 isMemberEnabled 禁用 false

| 要素 | 内容 |
|------|------|
| **测试项** | IMemberFacade |
| **测试目的** | 验证 M4 |
| **前置条件** | status=1 |
| **测试步骤** | `isMemberEnabled` |
| **预期结果** | false |

### MEM-UT-005 refreshConsumption 按已完成重算

| 要素 | 内容 |
|------|------|
| **测试项** | refreshConsumption |
| **测试目的** | 验证 M5、O11 |
| **前置条件** | 会员 3 笔已完成 pay_amount=10/20/30；1 笔已关闭 |
| **测试步骤** | `refreshConsumption(memberId)` |
| **预期结果** | order_count=3；total_amount=60.00 |

### MEM-UT-006 禁用会员不关闭订单

| 要素 | 内容 |
|------|------|
| **测试项** | updateStatus |
| **测试目的** | 验证 M15 |
| **前置条件** | 会员有 status=1 待发货订单 |
| **测试步骤** | `updateStatus(1)` 禁用 |
| **预期结果** | 订单 status 仍为 1；**不** 调 OrderFacade.close |

### MEM-UT-007 列表 keyword 匹配会员名称

| 要素 | 内容 |
|------|------|
| **测试项** | listMembers |
| **测试目的** | 验证 M11 |
| **前置条件** | `sys_user.user_name` 含「张三」 |
| **测试步骤** | keyword=张三 |
| **预期结果** | 命中 |

### MEM-UT-007a 列表 keyword 匹配昵称

| 要素 | 内容 |
|------|------|
| **测试项** | listMembers |
| **测试目的** | 验证 M11 |
| **前置条件** | `sys_user.nick_name` 含「李四」且 `user_name` 不含 |
| **测试步骤** | keyword=李四 |
| **预期结果** | 命中 |

### MEM-UT-008 列表 keyword 匹配手机号

| 要素 | 内容 |
|------|------|
| **测试项** | listMembers |
| **测试目的** | 验证 M11 |
| **前置条件** | mobile=17712345678 |
| **测试步骤** | keyword=5678 |
| **预期结果** | 命中 |

### MEM-UT-009 设默认地址取消其它默认

| 要素 | 内容 |
|------|------|
| **测试项** | setDefaultAddress |
| **测试目的** | 地址默认唯一 |
| **前置条件** | 地址 A、B 同属会员；A 默认 |
| **测试步骤** | 设 B 为默认 |
| **预期结果** | B is_default=1；A is_default=0 |

### MEM-UT-010 详情组装 addressList

| 要素 | 内容 |
|------|------|
| **测试项** | getMemberDetail |
| **测试目的** | 验证 M14 |
| **前置条件** | 2 条有效地址 |
| **测试步骤** | `getMemberDetail` |
| **预期结果** | addressList.size=2；fullAddress 拼接正确 |

### MEM-UT-011 pageOrdersByMember 委托 OrderFacade

| 要素 | 内容 |
|------|------|
| **测试项** | MemberOrderService |
| **测试目的** | 验证 M6 数据源 |
| **前置条件** | Mock IOrderFacade |
| **测试步骤** | `listMemberOrders(memberId, q)` |
| **预期结果** | 调用 `pageOrdersByMember` 一次 |

### MEM-UT-012 注册不校验经营账号存在

| 要素 | 内容 |
|------|------|
| **测试项** | register |
| **测试目的** | 验证 M7 |
| **前置条件** | 某 `sys_user.user_name` 已与商户经营账号绑定（`biz_merchant_account.account_id`） |
| **测试步骤** | C 端注册同手机号会员 |
| **预期结果** | 会员注册成功（两库独立） |

---

## 二、接口测试

### MEM-API-001 会员列表分页与默认排序

| 要素 | 内容 |
|------|------|
| **测试项** | GET /agri/member/list |
| **测试目的** | 验证 §4.2 |
| **前置条件** | 多条会员 |
| **测试步骤** | pageNum=1 |
| **预期结果** | registerTime 降序；含 orderCount、totalAmount |

### MEM-API-002 列表手机号脱敏

| 要素 | 内容 |
|------|------|
| **测试项** | GET /list |
| **测试目的** | 验证 §10 |
| **前置条件** | — |
| **测试步骤** | GET list |
| **预期结果** | mobile 形如 177****9136 |

### MEM-API-003 keyword 检索昵称

| 要素 | 内容 |
|------|------|
| **测试项** | GET /list |
| **测试目的** | 验证 M11 |
| **前置条件** | — |
| **测试步骤** | keyword=测试会员名 |
| **预期结果** | 按 user_name / nick_name 命中 |

### MEM-API-004 status 筛选禁用会员

| 要素 | 内容 |
|------|------|
| **测试项** | GET /list?status=1 |
| **测试目的** | 筛选 |
| **前置条件** | 启用/禁用均有 |
| **测试步骤** | status=1 |
| **预期结果** | 仅禁用 |

### MEM-API-005 详情含基本信息与地址列表

| 要素 | 内容 |
|------|------|
| **测试项** | GET /{memberId} |
| **测试目的** | 验证 §5 |
| **前置条件** | 有地址 |
| **测试步骤** | GET 详情 |
| **预期结果** | memberCode、nickName、mobile 完整号、addressList、isDefault 标记 |

### MEM-API-006 会员不存在

| 要素 | 内容 |
|------|------|
| **测试项** | GET /999999 |
| **测试目的** | 负向 |
| **测试步骤** | GET |
| **预期结果** | 失败；会员不存在 |

### MEM-API-007 禁用会员

| 要素 | 内容 |
|------|------|
| **测试项** | PUT /{id}/status |
| **测试目的** | 验证 M4 |
| **前置条件** | status=0 |
| **测试步骤** | `{"status":"1"}` |
| **预期结果** | 成功；再 GET status=1 |

### MEM-API-008 启用会员

| 要素 | 内容 |
|------|------|
| **测试项** | PUT /status |
| **测试目的** | 验证 §7 |
| **前置条件** | status=1 |
| **测试步骤** | status=0 |
| **预期结果** | 成功 |

### MEM-API-009 非法 status 拒绝

| 要素 | 内容 |
|------|------|
| **测试项** | PUT /status |
| **测试目的** | 校验 |
| **测试步骤** | status=9 |
| **预期结果** | 失败 |

### MEM-API-010 会员订单列表只读

| 要素 | 内容 |
|------|------|
| **测试项** | GET /{id}/orders |
| **测试目的** | 验证 §6、M6 |
| **前置条件** | 会员有 2 笔订单 |
| **测试步骤** | GET orders |
| **预期结果** | rows 仅该会员；响应含 operateType=readonly 或等价字段 |

### MEM-API-011 会员订单按订单号检索

| 要素 | 内容 |
|------|------|
| **测试项** | GET /orders |
| **测试目的** | 验证 M12 |
| **前置条件** | — |
| **测试步骤** | orderNo=已知 |
| **预期结果** | 命中 1 条 |

### MEM-API-012 会员订单详情成功

| 要素 | 内容 |
|------|------|
| **测试项** | GET /orders/{orderId} |
| **测试目的** | 验证 §6.4 |
| **前置条件** | 订单属该会员 |
| **测试步骤** | GET |
| **预期结果** | items、traceList；**无** ship/close 写接口字段 |

### MEM-API-013 会员订单详情归属校验失败

| 要素 | 内容 |
|------|------|
| **测试项** | GET /orders/{orderId} |
| **测试目的** | 验证 M9 |
| **前置条件** | 订单属其他会员 |
| **测试步骤** | 会员 A 查会员 B 的 orderId |
| **预期结果** | 失败；无权查看该订单 |

### MEM-API-014 会员模块无发货接口

| 要素 | 内容 |
|------|------|
| **测试项** | POST /agri/member/{id}/orders/{oid}/ship |
| **测试目的** | 验证 M6 |
| **测试步骤** | 任意 POST ship |
| **预期结果** | 404 或 405 |

### MEM-API-015 无 list 权限 403

| 要素 | 内容 |
|------|------|
| **测试项** | GET /list |
| **测试目的** | 权限 |
| **前置条件** | 无 agri:member:list |
| **测试步骤** | GET |
| **预期结果** | 403 |

### MEM-API-016 C 端注册成功

| 要素 | 内容 |
|------|------|
| **测试项** | POST /api/member/register |
| **测试目的** | C 端 |
| **前置条件** | 新手机号；password 与 confirmPassword 一致 |
| **测试步骤** | POST Body：mobile、password、confirmPassword、agreementAccepted |
| **预期结果** | `sys_user` + `sys_user_role`(member) + `biz_member` 新增；`user_name` 有值；`member_id=user_id`；`register_time` 有值 |

### MEM-API-017 C 端登录启用会员（手机号）

| 要素 | 内容 |
|------|------|
| **测试项** | POST /api/member/login |
| **测试目的** | C 端 · 手机号登录 |
| **前置条件** | status=0 |
| **测试步骤** | Body：`account`=手机号、`password` |
| **预期结果** | 返回 token、memberId |

### MEM-API-017b C 端登录启用会员（会员名称）

| 要素 | 内容 |
|------|------|
| **测试项** | POST /api/member/login |
| **测试目的** | C 端 · **会员名称**（产品所称会员 ID = `user_name`）登录 |
| **前置条件** | status=0；已知 `sys_user.user_name` |
| **测试步骤** | Body：`account`=会员名称、`password` |
| **预期结果** | 返回 token、memberId；**非** 数字 member_id 登录 |

### MEM-API-018 C 端禁用会员登录失败

| 要素 | 内容 |
|------|------|
| **测试项** | POST /login |
| **测试目的** | 验证 M4 |
| **前置条件** | status=1 |
| **测试步骤** | login |
| **预期结果** | 失败；账号已禁用 |

### MEM-API-019 完成后消费统计与列表一致

| 要素 | 内容 |
|------|------|
| **测试项** | 跨模块 O11 |
| **测试目的** | 验证 §6.5 |
| **前置条件** | 会员完成 1 笔 pay_amount=100 |
| **测试步骤** | confirmReceive → GET /agri/member/list |
| **预期结果** | orderCount、totalAmount 与订单一致 |

### MEM-API-020 禁用后 C 端下单失败

| 要素 | 内容 |
|------|------|
| **测试项** | POST /api/order/create |
| **测试目的** | M4 与下单 |
| **前置条件** | 会员已禁用 |
| **测试步骤** | create order |
| **预期结果** | 失败 |

### MEM-API-021 列表仅含 member 角色用户

| 要素 | 内容 |
|------|------|
| **测试项** | GET /agri/member/list |
| **测试目的** | 列表过滤 member 角色 |
| **前置条件** | 存在仅有 `merchant` 角色、无 `member` 的 `sys_user`；另有正常会员 |
| **测试步骤** | GET list |
| **预期结果** | `rows` 不含无 member 角色账号 |

### MEM-API-022 平台添加会员

| 要素 | 内容 |
|------|------|
| **测试项** | POST /agri/member |
| **测试目的** | 平台添加 |
| **前置条件** | 新手机号；`agri:member:add` |
| **测试步骤** | Body：mobile、password、可选 memberCode/nickName |
| **预期结果** | `code=200`；`data=memberId`；`sys_user_role` 含 member；`biz_member` 有记录 |

### MEM-UT-013 平台添加委托 RegistrationSupport

| 要素 | 内容 |
|------|------|
| **测试项** | MemberServiceImpl.createMember |
| **测试目的** | 委托共用逻辑 |
| **前置条件** | Mock `MemberRegistrationSupport` |
| **测试步骤** | createMember(dto, operator) |
| **预期结果** | 调用 `memberRegistrationSupport.createMember` |

---

## 三、界面测试

### MEM-UI-001 会员列表字段展示

| 要素 | 内容 |
|------|------|
| **测试工具** | Playwright |
| **测试步骤** | 进入会员管理列表 |
| **预期结果** | 列含会员名称（memberCode）、等级、启用、消费次数/金额、注册日期、操作 |

### MEM-UI-002 列表禁用二次确认

| 要素 | 内容 |
|------|------|
| **测试项** | 启用开关 |
| **测试目的** | 验证 §4.2 |
| **测试步骤** | 关闭启用开关 |
| **预期结果** | 确认文案含无法登录/下单 |

### MEM-UI-003 查看详情分区与查看订单入口

| 要素 | 内容 |
|------|------|
| **测试项** | 详情 |
| **测试步骤** | 点击「查看详情」 |
| **预期结果** | 基本/收货分区；有「查看订单」按钮 |

### MEM-UI-004 查看订单仅详情操作

| 要素 | 内容 |
|------|------|
| **测试项** | 会员订单 |
| **测试目的** | 验证 M6 |
| **测试步骤** | 会员列表 → 查看订单 |
| **预期结果** | 操作列仅「查看详情」；无发货/关闭 |

### MEM-UI-005 会员订单详情无写操作按钮

| 要素 | 内容 |
|------|------|
| **测试项** | 订单详情 |
| **测试步骤** | 打开会员订单详情 |
| **预期结果** | 无去发货、关闭、删除按钮 |

### MEM-UI-006 空数据友好提示

| 要素 | 内容 |
|------|------|
| **测试项** | 空态 |
| **前置条件** | 新会员无订单 |
| **测试步骤** | 查看订单 |
| **预期结果** | 无订单提示 |

### MEM-UI-007 无权限菜单不可见

| 要素 | 内容 |
|------|------|
| **测试项** | 权限 |
| **前置条件** | 角色无会员菜单 |
| **测试步骤** | 登录查看菜单 |
| **预期结果** | 无会员管理入口 |

---

## 四、测试数据准备

| 数据 | 说明 |
|------|------|
| 会员 A | 启用；有地址 2 条；有各状态订单 |
| 会员 B | 禁用 |
| 会员 C | 无订单 |
| 已完成订单 | 用于 O11 校验 |
| 平台角色 | 含/不含 agri:member:* |

---

## 五、用例统计

| 类型 | 数量 |
|------|------|
| 单元测试 MEM-UT | 13 |
| 接口测试 MEM-API | 22 |
| 界面测试 MEM-UI | 7 |
| **合计** | **42** |

---

## 六、与订单用例协作

| 场景 | 订单用例 | 会员用例 |
|------|----------|----------|
| 确认收货更新消费 | ORD-API-018、ORD-UT-009 | MEM-API-019 |
| 删店未完成阻断 | ORD-API-020 | — |
| 订单只读 | ORD-UT-017/018 | MEM-API-010～014 |

---

*文档版本：v1.2 · 关联《会员管理功能需求.md》v1.1、《会员管理技术方案.md》v1.3、《会员注册登录技术方案.md》v1.2、《订单管理测试用例.md》v1.0*
