feat: 完成B端认证系统和商户管理模块测试补全
主要变更: - 新增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模式)
This commit is contained in:
422
docs/shop-management/使用指南.md
Normal file
422
docs/shop-management/使用指南.md
Normal file
@@ -0,0 +1,422 @@
|
||||
# 商户管理模块 - 使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
商户管理模块提供了完整的商户(Shop)和商户账号(ShopAccount)管理功能,支持商户的创建、更新、删除、查询,以及商户账号的全生命周期管理。
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 商户管理
|
||||
- **创建商户**:创建新商户的同时自动创建一个初始坐席账号
|
||||
- **查询商户**:支持分页查询、模糊搜索、状态筛选
|
||||
- **更新商户**:更新商户基本信息(名称、编码、等级、状态等)
|
||||
- **删除商户**:软删除商户,同时批量禁用所有关联的商户账号
|
||||
|
||||
### 2. 商户账号管理
|
||||
- **创建账号**:为商户创建新的坐席账号
|
||||
- **查询账号**:支持分页查询、按商户筛选、状态筛选
|
||||
- **更新账号**:更新账号用户名(手机号和密码不可通过此接口修改)
|
||||
- **重置密码**:管理员为账号重置密码(无需原密码)
|
||||
- **启用/禁用账号**:控制账号的启用状态
|
||||
|
||||
## 业务规则
|
||||
|
||||
### 商户规则
|
||||
1. **商户编码唯一性**:商户编码(ShopCode)必须全局唯一
|
||||
2. **商户等级**:等级范围为 1-7,表示商户层级结构
|
||||
3. **商户状态**:
|
||||
- `1` - 正常
|
||||
- `2` - 禁用
|
||||
4. **关联删除**:删除商户时,所有关联的商户账号将被批量禁用(不删除)
|
||||
|
||||
### 商户账号规则
|
||||
1. **账号类型**:所有商户账号的用户类型固定为 `3`(坐席/Agent)
|
||||
2. **初始账号**:创建商户时必须提供初始账号的用户名、手机号和密码
|
||||
3. **密码安全**:密码采用 bcrypt 加密存储
|
||||
4. **账号状态**:
|
||||
- `1` - 正常
|
||||
- `2` - 禁用
|
||||
5. **字段限制**:
|
||||
- 更新账号时,手机号和密码不可修改(需通过专用接口)
|
||||
- 密码重置由管理员操作,无需提供原密码
|
||||
|
||||
### 数据权限
|
||||
- 所有查询操作会根据当前登录用户的数据权限自动过滤结果
|
||||
- 使用 GORM 回调机制自动处理数据权限逻辑
|
||||
|
||||
## API 端点
|
||||
|
||||
### 商户管理 API
|
||||
|
||||
#### 1. 查询商户列表
|
||||
```http
|
||||
GET /api/admin/shops
|
||||
```
|
||||
|
||||
**查询参数**:
|
||||
- `page` (int, 可选): 页码,默认 1
|
||||
- `size` (int, 可选): 每页数量,默认 20,最大 100
|
||||
- `name` (string, 可选): 商户名称模糊搜索
|
||||
- `shop_code` (string, 可选): 商户编码精确搜索
|
||||
- `status` (int, 可选): 状态筛选(1=正常,2=禁用)
|
||||
- `level` (int, 可选): 等级筛选
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"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. 创建商户
|
||||
```http
|
||||
POST /api/admin/shops
|
||||
```
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"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-7
|
||||
- `status` (int, 必填): 状态(1=正常,2=禁用)
|
||||
- `init_username` (string, 必填): 初始账号用户名
|
||||
- `init_phone` (string, 必填): 初始账号手机号
|
||||
- `init_password` (string, 必填): 初始账号密码
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"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. 更新商户
|
||||
```http
|
||||
PUT /api/admin/shops/:id
|
||||
```
|
||||
|
||||
**路径参数**:
|
||||
- `id` (uint): 商户ID
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"name": "更新后的商户名称",
|
||||
"shop_code": "SHOP001",
|
||||
"level": 2,
|
||||
"status": 1
|
||||
}
|
||||
```
|
||||
|
||||
**响应示例**:同创建商户
|
||||
|
||||
#### 4. 删除商户
|
||||
```http
|
||||
DELETE /api/admin/shops/:id
|
||||
```
|
||||
|
||||
**路径参数**:
|
||||
- `id` (uint): 商户ID
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"data": null,
|
||||
"timestamp": 1704096000
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:删除商户时,所有关联的商户账号将被自动禁用。
|
||||
|
||||
---
|
||||
|
||||
### 商户账号管理 API
|
||||
|
||||
#### 1. 查询商户账号列表
|
||||
```http
|
||||
GET /api/admin/shop-accounts
|
||||
```
|
||||
|
||||
**查询参数**:
|
||||
- `page` (int, 可选): 页码,默认 1
|
||||
- `size` (int, 可选): 每页数量,默认 20,最大 100
|
||||
- `shop_id` (uint, 可选): 商户ID筛选
|
||||
- `status` (int, 可选): 状态筛选(1=正常,2=禁用)
|
||||
- `username` (string, 可选): 用户名模糊搜索
|
||||
- `phone` (string, 可选): 手机号模糊搜索
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"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. 创建商户账号
|
||||
```http
|
||||
POST /api/admin/shop-accounts
|
||||
```
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"shop_id": 1,
|
||||
"username": "agent01",
|
||||
"phone": "13800138001",
|
||||
"password": "password123"
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `shop_id` (uint, 必填): 商户ID
|
||||
- `username` (string, 必填): 用户名
|
||||
- `phone` (string, 必填): 手机号
|
||||
- `password` (string, 必填): 密码
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"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. 更新商户账号
|
||||
```http
|
||||
PUT /api/admin/shop-accounts/:id
|
||||
```
|
||||
|
||||
**路径参数**:
|
||||
- `id` (uint): 账号ID
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"username": "new_username"
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:此接口只能更新用户名,手机号和密码不可通过此接口修改。
|
||||
|
||||
**响应示例**:同创建商户账号
|
||||
|
||||
#### 4. 重置账号密码
|
||||
```http
|
||||
PUT /api/admin/shop-accounts/:id/password
|
||||
```
|
||||
|
||||
**路径参数**:
|
||||
- `id` (uint): 账号ID
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"new_password": "newpassword123"
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `new_password` (string, 必填): 新密码
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"data": null,
|
||||
"timestamp": 1704096600
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:此操作为管理员重置密码,无需提供原密码。
|
||||
|
||||
#### 5. 启用/禁用账号
|
||||
```http
|
||||
PUT /api/admin/shop-accounts/:id/status
|
||||
```
|
||||
|
||||
**路径参数**:
|
||||
- `id` (uint): 账号ID
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"status": 2
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `status` (int, 必填): 状态(1=正常,2=禁用)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"data": null,
|
||||
"timestamp": 1704096900
|
||||
}
|
||||
```
|
||||
|
||||
## 错误码
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| `40001` | 商户不存在 |
|
||||
| `40002` | 商户编码已存在 |
|
||||
| `40003` | 商户状态无效 |
|
||||
| `40004` | 商户等级无效 |
|
||||
| `50001` | 账号不存在 |
|
||||
| `50002` | 账号已存在 |
|
||||
| `50003` | 账号状态无效 |
|
||||
|
||||
## 使用场景示例
|
||||
|
||||
### 场景1:创建新商户并设置初始账号
|
||||
```bash
|
||||
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:为商户添加新的坐席账号
|
||||
```bash
|
||||
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:管理员重置账号密码
|
||||
```bash
|
||||
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:删除商户(自动禁用关联账号)
|
||||
```bash
|
||||
curl -X DELETE http://localhost:3000/api/admin/shops/1 \
|
||||
-H "Authorization: Bearer YOUR_TOKEN"
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **认证要求**:所有接口需要在请求头中携带有效的认证 Token
|
||||
2. **数据权限**:查询结果会根据当前用户的数据权限自动过滤
|
||||
3. **密码安全**:
|
||||
- 密码在存储前会自动使用 bcrypt 加密
|
||||
- 建议密码长度至少 8 位,包含字母和数字
|
||||
4. **关联关系**:
|
||||
- 删除商户不会删除关联账号,只会禁用
|
||||
- 禁用商户不会影响已存在账号的状态
|
||||
5. **并发控制**:更新操作会检查记录是否存在,避免并发冲突
|
||||
6. **日志记录**:所有操作会记录到访问日志(access.log)
|
||||
|
||||
## 技术实现细节
|
||||
|
||||
- **框架**:Fiber v2.x (HTTP)
|
||||
- **ORM**:GORM v1.25.x
|
||||
- **密码加密**:bcrypt
|
||||
- **数据权限**:GORM 回调自动处理
|
||||
- **错误处理**:统一错误码系统(pkg/errors)
|
||||
- **响应格式**:统一响应格式(pkg/response)
|
||||
- **分层架构**:Handler → Service → Store → Model
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [API 文档](./API文档.md) - 详细的 API 接口文档
|
||||
- [项目开发规范](../../AGENTS.md) - 项目整体开发规范
|
||||
- [错误码定义](../../pkg/errors/codes.go) - 完整错误码列表
|
||||
Reference in New Issue
Block a user