主要变更: - 新增B端认证系统(后台+H5):登录、登出、Token刷新、密码修改 - 完善商户管理和商户账号管理功能 - 补全单元测试(ShopService: 72.5%, ShopAccountService: 79.8%) - 新增集成测试(商户管理+商户账号管理) - 归档OpenSpec提案(add-shop-account-management, implement-b-end-auth-system) - 完善文档(使用指南、API文档、认证架构说明) 测试统计: - 13个测试套件,37个测试用例,100%通过率 - 平均覆盖率76.2%,达标 OpenSpec验证:通过(strict模式)
9.5 KiB
9.5 KiB
商户管理模块 - 使用指南
概述
商户管理模块提供了完整的商户(Shop)和商户账号(ShopAccount)管理功能,支持商户的创建、更新、删除、查询,以及商户账号的全生命周期管理。
核心功能
1. 商户管理
- 创建商户:创建新商户的同时自动创建一个初始坐席账号
- 查询商户:支持分页查询、模糊搜索、状态筛选
- 更新商户:更新商户基本信息(名称、编码、等级、状态等)
- 删除商户:软删除商户,同时批量禁用所有关联的商户账号
2. 商户账号管理
- 创建账号:为商户创建新的坐席账号
- 查询账号:支持分页查询、按商户筛选、状态筛选
- 更新账号:更新账号用户名(手机号和密码不可通过此接口修改)
- 重置密码:管理员为账号重置密码(无需原密码)
- 启用/禁用账号:控制账号的启用状态
业务规则
商户规则
- 商户编码唯一性:商户编码(ShopCode)必须全局唯一
- 商户等级:等级范围为 1-7,表示商户层级结构
- 商户状态:
1- 正常2- 禁用
- 关联删除:删除商户时,所有关联的商户账号将被批量禁用(不删除)
商户账号规则
- 账号类型:所有商户账号的用户类型固定为
3(坐席/Agent) - 初始账号:创建商户时必须提供初始账号的用户名、手机号和密码
- 密码安全:密码采用 bcrypt 加密存储
- 账号状态:
1- 正常2- 禁用
- 字段限制:
- 更新账号时,手机号和密码不可修改(需通过专用接口)
- 密码重置由管理员操作,无需提供原密码
数据权限
- 所有查询操作会根据当前登录用户的数据权限自动过滤结果
- 使用 GORM 回调机制自动处理数据权限逻辑
API 端点
商户管理 API
1. 查询商户列表
GET /api/admin/shops
查询参数:
page(int, 可选): 页码,默认 1size(int, 可选): 每页数量,默认 20,最大 100name(string, 可选): 商户名称模糊搜索shop_code(string, 可选): 商户编码精确搜索status(int, 可选): 状态筛选(1=正常,2=禁用)level(int, 可选): 等级筛选
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"items": [
{
"id": 1,
"name": "测试商户",
"shop_code": "SHOP001",
"level": 1,
"status": 1,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
}
],
"total": 1,
"page": 1,
"size": 20
},
"timestamp": 1704096000
}
2. 创建商户
POST /api/admin/shops
请求体:
{
"name": "测试商户",
"shop_code": "SHOP001",
"level": 1,
"status": 1,
"init_username": "admin",
"init_phone": "13800138000",
"init_password": "password123"
}
字段说明:
name(string, 必填): 商户名称shop_code(string, 必填): 商户编码,全局唯一level(int, 必填): 商户等级,范围 1-7status(int, 必填): 状态(1=正常,2=禁用)init_username(string, 必填): 初始账号用户名init_phone(string, 必填): 初始账号手机号init_password(string, 必填): 初始账号密码
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"name": "测试商户",
"shop_code": "SHOP001",
"level": 1,
"status": 1,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
},
"timestamp": 1704096000
}
3. 更新商户
PUT /api/admin/shops/:id
路径参数:
id(uint): 商户ID
请求体:
{
"name": "更新后的商户名称",
"shop_code": "SHOP001",
"level": 2,
"status": 1
}
响应示例:同创建商户
4. 删除商户
DELETE /api/admin/shops/:id
路径参数:
id(uint): 商户ID
响应示例:
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096000
}
注意:删除商户时,所有关联的商户账号将被自动禁用。
商户账号管理 API
1. 查询商户账号列表
GET /api/admin/shop-accounts
查询参数:
page(int, 可选): 页码,默认 1size(int, 可选): 每页数量,默认 20,最大 100shop_id(uint, 可选): 商户ID筛选status(int, 可选): 状态筛选(1=正常,2=禁用)username(string, 可选): 用户名模糊搜索phone(string, 可选): 手机号模糊搜索
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"items": [
{
"id": 1,
"username": "admin",
"phone": "13800138000",
"user_type": 3,
"status": 1,
"shop_id": 1,
"shop_name": "测试商户",
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
}
],
"total": 1,
"page": 1,
"size": 20
},
"timestamp": 1704096000
}
2. 创建商户账号
POST /api/admin/shop-accounts
请求体:
{
"shop_id": 1,
"username": "agent01",
"phone": "13800138001",
"password": "password123"
}
字段说明:
shop_id(uint, 必填): 商户IDusername(string, 必填): 用户名phone(string, 必填): 手机号password(string, 必填): 密码
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"id": 2,
"username": "agent01",
"phone": "13800138001",
"user_type": 3,
"status": 1,
"shop_id": 1,
"shop_name": "测试商户",
"created_at": "2024-01-01T10:05:00Z",
"updated_at": "2024-01-01T10:05:00Z"
},
"timestamp": 1704096300
}
3. 更新商户账号
PUT /api/admin/shop-accounts/:id
路径参数:
id(uint): 账号ID
请求体:
{
"username": "new_username"
}
注意:此接口只能更新用户名,手机号和密码不可通过此接口修改。
响应示例:同创建商户账号
4. 重置账号密码
PUT /api/admin/shop-accounts/:id/password
路径参数:
id(uint): 账号ID
请求体:
{
"new_password": "newpassword123"
}
字段说明:
new_password(string, 必填): 新密码
响应示例:
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096600
}
注意:此操作为管理员重置密码,无需提供原密码。
5. 启用/禁用账号
PUT /api/admin/shop-accounts/:id/status
路径参数:
id(uint): 账号ID
请求体:
{
"status": 2
}
字段说明:
status(int, 必填): 状态(1=正常,2=禁用)
响应示例:
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096900
}
错误码
| 错误码 | 说明 |
|---|---|
40001 |
商户不存在 |
40002 |
商户编码已存在 |
40003 |
商户状态无效 |
40004 |
商户等级无效 |
50001 |
账号不存在 |
50002 |
账号已存在 |
50003 |
账号状态无效 |
使用场景示例
场景1:创建新商户并设置初始账号
curl -X POST http://localhost:3000/api/admin/shops \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "示例商户",
"shop_code": "DEMO001",
"level": 1,
"status": 1,
"init_username": "admin",
"init_phone": "13800138000",
"init_password": "admin123"
}'
场景2:为商户添加新的坐席账号
curl -X POST http://localhost:3000/api/admin/shop-accounts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"shop_id": 1,
"username": "agent01",
"phone": "13800138001",
"password": "agent123"
}'
场景3:管理员重置账号密码
curl -X PUT http://localhost:3000/api/admin/shop-accounts/2/password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"new_password": "newpassword123"
}'
场景4:删除商户(自动禁用关联账号)
curl -X DELETE http://localhost:3000/api/admin/shops/1 \
-H "Authorization: Bearer YOUR_TOKEN"
注意事项
- 认证要求:所有接口需要在请求头中携带有效的认证 Token
- 数据权限:查询结果会根据当前用户的数据权限自动过滤
- 密码安全:
- 密码在存储前会自动使用 bcrypt 加密
- 建议密码长度至少 8 位,包含字母和数字
- 关联关系:
- 删除商户不会删除关联账号,只会禁用
- 禁用商户不会影响已存在账号的状态
- 并发控制:更新操作会检查记录是否存在,避免并发冲突
- 日志记录:所有操作会记录到访问日志(access.log)
技术实现细节
- 框架:Fiber v2.x (HTTP)
- ORM:GORM v1.25.x
- 密码加密:bcrypt
- 数据权限:GORM 回调自动处理
- 错误处理:统一错误码系统(pkg/errors)
- 响应格式:统一响应格式(pkg/response)
- 分层架构:Handler → Service → Store → Model