Files
junhong_cmp_fiber/docs/shop-management/API文档.md
huang 18f35f3ef4 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模式)
2026-01-15 18:15:17 +08:00

818 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 商户管理模块 - API 文档
## 目录
- [商户管理 API](#商户管理-api)
- [查询商户列表](#1-查询商户列表)
- [创建商户](#2-创建商户)
- [更新商户](#3-更新商户)
- [删除商户](#4-删除商户)
- [商户账号管理 API](#商户账号管理-api)
- [查询商户账号列表](#1-查询商户账号列表)
- [创建商户账号](#2-创建商户账号)
- [更新商户账号](#3-更新商户账号)
- [重置账号密码](#4-重置账号密码)
- [启用/禁用账号](#5-启用禁用账号)
- [数据模型](#数据模型)
- [错误码](#错误码)
---
## 商户管理 API
### 1. 查询商户列表
获取商户列表,支持分页、筛选和搜索。
**请求**
```http
GET /api/admin/shops
```
**查询参数**
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | integer | 否 | 1 | 页码,从 1 开始 |
| size | integer | 否 | 20 | 每页数量,最大 100 |
| name | string | 否 | - | 商户名称(模糊搜索) |
| shop_code | string | 否 | - | 商户编码(精确匹配) |
| status | integer | 否 | - | 状态筛选1=正常2=禁用) |
| level | integer | 否 | - | 等级筛选1-7 |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"items": [
{
"id": 1,
"name": "测试商户",
"shop_code": "SHOP001",
"contact": "张三",
"phone": "13800138000",
"province": "广东省",
"city": "深圳市",
"district": "南山区",
"address": "科技园",
"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
}
```
**状态码**
| HTTP 状态码 | 说明 |
|-------------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 500 | 服务器错误 |
---
### 2. 创建商户
创建新商户,同时创建初始坐席账号。
**请求**
```http
POST /api/admin/shops
Content-Type: application/json
```
**请求体**
```json
{
"name": "测试商户",
"shop_code": "SHOP001",
"contact": "张三",
"phone": "13800138000",
"province": "广东省",
"city": "深圳市",
"district": "南山区",
"address": "科技园",
"level": 1,
"status": 1,
"init_username": "admin",
"init_phone": "13800138000",
"init_password": "password123"
}
```
**字段说明**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | 是 | 商户名称 |
| shop_code | string | 是 | 商户编码,全局唯一 |
| contact | string | 否 | 联系人 |
| phone | string | 否 | 联系电话 |
| province | string | 否 | 省份 |
| city | string | 否 | 城市 |
| district | string | 否 | 区域 |
| address | string | 否 | 详细地址 |
| level | integer | 是 | 商户等级1-7 |
| status | integer | 是 | 状态1=正常2=禁用) |
| init_username | string | 是 | 初始账号用户名 |
| init_phone | string | 是 | 初始账号手机号 |
| init_password | string | 是 | 初始账号密码 |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"name": "测试商户",
"shop_code": "SHOP001",
"contact": "张三",
"phone": "13800138000",
"province": "广东省",
"city": "深圳市",
"district": "南山区",
"address": "科技园",
"level": 1,
"status": 1,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
},
"timestamp": 1704096000
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 40002 | 商户编码已存在 |
| 400 | 40004 | 商户等级无效 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. 商户编码shop_code必须全局唯一
2. 等级level必须在 1-7 范围内
3. 创建商户的同时会自动创建一个初始坐席账号UserType=3
4. 初始账号的密码会使用 bcrypt 加密存储
5. 初始账号的 shop_id 会自动关联到新创建的商户
---
### 3. 更新商户
更新商户基本信息。
**请求**
```http
PUT /api/admin/shops/:id
Content-Type: application/json
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | integer | 是 | 商户ID |
**请求体**
```json
{
"name": "更新后的商户名称",
"shop_code": "SHOP001",
"contact": "李四",
"phone": "13900139000",
"province": "广东省",
"city": "深圳市",
"district": "福田区",
"address": "中心区",
"level": 2,
"status": 1
}
```
**字段说明**
所有字段均为可选,但至少需要提供一个字段进行更新。
| 字段 | 类型 | 说明 |
|------|------|------|
| name | string | 商户名称 |
| shop_code | string | 商户编码 |
| contact | string | 联系人 |
| phone | string | 联系电话 |
| province | string | 省份 |
| city | string | 城市 |
| district | string | 区域 |
| address | string | 详细地址 |
| level | integer | 商户等级1-7 |
| status | integer | 状态1=正常2=禁用) |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"name": "更新后的商户名称",
"shop_code": "SHOP001",
"contact": "李四",
"phone": "13900139000",
"province": "广东省",
"city": "深圳市",
"district": "福田区",
"address": "中心区",
"level": 2,
"status": 1,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T11:00:00Z"
},
"timestamp": 1704099600
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 40001 | 商户不存在 |
| 400 | 40002 | 商户编码已存在(修改编码时) |
| 400 | 40004 | 商户等级无效 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
---
### 4. 删除商户
软删除商户,同时批量禁用所有关联的商户账号。
**请求**
```http
DELETE /api/admin/shops/:id
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | integer | 是 | 商户ID |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096000
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | 40001 | 商户不存在 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. 删除商户时会进行软删除(设置 deleted_at
2. 所有关联的商户账号会被批量设置为禁用状态status=2
3. 账号不会被物理删除,只是被禁用
4. 删除操作不可逆(除非手动修改数据库)
---
## 商户账号管理 API
### 1. 查询商户账号列表
获取商户账号列表,支持分页、筛选和搜索。
**请求**
```http
GET /api/admin/shop-accounts
```
**查询参数**
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| page | integer | 否 | 1 | 页码,从 1 开始 |
| size | integer | 否 | 20 | 每页数量,最大 100 |
| shop_id | integer | 否 | - | 商户ID筛选 |
| status | integer | 否 | - | 状态筛选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
}
```
**状态码**
| HTTP 状态码 | 说明 |
|-------------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 500 | 服务器错误 |
---
### 2. 创建商户账号
为指定商户创建新的坐席账号。
**请求**
```http
POST /api/admin/shop-accounts
Content-Type: application/json
```
**请求体**
```json
{
"shop_id": 1,
"username": "agent01",
"phone": "13800138001",
"password": "password123"
}
```
**字段说明**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| shop_id | integer | 是 | 商户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
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 40001 | 商户不存在 |
| 400 | 50002 | 账号已存在(手机号重复) |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. shop_id 必须对应一个存在的商户
2. 创建的账号 UserType 固定为 3坐席/Agent
3. 密码会使用 bcrypt 加密存储
4. 手机号必须全局唯一
5. 账号默认状态为正常status=1
---
### 3. 更新商户账号
更新商户账号的基本信息(仅限用户名)。
**请求**
```http
PUT /api/admin/shop-accounts/:id
Content-Type: application/json
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | integer | 是 | 账号ID |
**请求体**
```json
{
"username": "new_username"
}
```
**字段说明**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| username | string | 是 | 新的用户名 |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 2,
"username": "new_username",
"phone": "13800138001",
"user_type": 3,
"status": 1,
"shop_id": 1,
"shop_name": "测试商户",
"created_at": "2024-01-01T10:05:00Z",
"updated_at": "2024-01-01T11:05:00Z"
},
"timestamp": 1704099900
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 50001 | 账号不存在 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. 此接口只能更新用户名
2. 手机号和密码不可通过此接口修改
3. 密码修改请使用"重置账号密码"接口
---
### 4. 重置账号密码
管理员为账号重置密码(无需提供原密码)。
**请求**
```http
PUT /api/admin/shop-accounts/:id/password
Content-Type: application/json
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | integer | 是 | 账号ID |
**请求体**
```json
{
"new_password": "newpassword123"
}
```
**字段说明**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| new_password | string | 是 | 新密码 |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096600
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 50001 | 账号不存在 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. 管理员操作,无需提供原密码
2. 新密码会使用 bcrypt 加密存储
3. 建议密码长度至少 8 位,包含字母和数字
---
### 5. 启用/禁用账号
更新账号的启用状态。
**请求**
```http
PUT /api/admin/shop-accounts/:id/status
Content-Type: application/json
```
**路径参数**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | integer | 是 | 账号ID |
**请求体**
```json
{
"status": 2
}
```
**字段说明**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| status | integer | 是 | 状态1=正常2=禁用) |
**响应**
```json
{
"code": 0,
"msg": "success",
"data": null,
"timestamp": 1704096900
}
```
**状态码**
| HTTP 状态码 | 业务错误码 | 说明 |
|-------------|-----------|------|
| 200 | 0 | 成功 |
| 400 | - | 请求参数错误 |
| 400 | 50001 | 账号不存在 |
| 400 | 50003 | 账号状态无效 |
| 401 | - | 未授权 |
| 500 | - | 服务器错误 |
**业务规则**
1. 状态值只能是 1正常或 2禁用
2. 禁用账号后,该账号无法登录
3. 启用账号后,账号恢复正常使用
---
## 数据模型
### ShopResponse
商户响应对象
```json
{
"id": 1,
"name": "测试商户",
"shop_code": "SHOP001",
"contact": "张三",
"phone": "13800138000",
"province": "广东省",
"city": "深圳市",
"district": "南山区",
"address": "科技园",
"level": 1,
"status": 1,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z"
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| id | integer | 商户ID |
| name | string | 商户名称 |
| shop_code | string | 商户编码 |
| contact | string | 联系人 |
| phone | string | 联系电话 |
| province | string | 省份 |
| city | string | 城市 |
| district | string | 区域 |
| address | string | 详细地址 |
| level | integer | 商户等级1-7 |
| status | integer | 状态1=正常2=禁用) |
| created_at | string | 创建时间ISO 8601 |
| updated_at | string | 更新时间ISO 8601 |
### ShopAccountResponse
商户账号响应对象
```json
{
"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"
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| id | integer | 账号ID |
| username | string | 用户名 |
| phone | string | 手机号 |
| user_type | integer | 用户类型(固定为 3表示坐席 |
| status | integer | 状态1=正常2=禁用) |
| shop_id | integer | 所属商户ID |
| shop_name | string | 所属商户名称 |
| created_at | string | 创建时间ISO 8601 |
| updated_at | string | 更新时间ISO 8601 |
### 分页响应
所有列表接口的响应都包含分页信息
```json
{
"items": [...],
"total": 100,
"page": 1,
"size": 20
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| items | array | 数据列表 |
| total | integer | 总记录数 |
| page | integer | 当前页码 |
| size | integer | 每页数量 |
---
## 错误码
### 通用错误码
| 错误码 | HTTP 状态码 | 说明 |
|--------|-------------|------|
| 0 | 200 | 成功 |
| 10001 | 400 | 请求参数错误 |
| 10002 | 401 | 未授权 |
| 10003 | 403 | 无权限 |
| 10004 | 404 | 资源不存在 |
| 10005 | 500 | 服务器内部错误 |
### 商户相关错误码
| 错误码 | HTTP 状态码 | 说明 |
|--------|-------------|------|
| 40001 | 400 | 商户不存在 |
| 40002 | 400 | 商户编码已存在 |
| 40003 | 400 | 商户状态无效 |
| 40004 | 400 | 商户等级无效 |
### 账号相关错误码
| 错误码 | HTTP 状态码 | 说明 |
|--------|-------------|------|
| 50001 | 400 | 账号不存在 |
| 50002 | 400 | 账号已存在 |
| 50003 | 400 | 账号状态无效 |
### 错误响应格式
```json
{
"code": 40001,
"msg": "商户不存在",
"data": null,
"timestamp": 1704096000
}
```
---
## 认证
所有 API 接口都需要在请求头中携带有效的认证 Token
```http
Authorization: Bearer YOUR_ACCESS_TOKEN
```
如果 Token 无效或过期,将返回 401 错误:
```json
{
"code": 10002,
"msg": "未授权",
"data": null,
"timestamp": 1704096000
}
```
---
## 速率限制
暂无速率限制。
---
## 版本历史
### v1.0.0 (2024-01-01)
- 初始版本
- 实现商户管理 CRUD 功能
- 实现商户账号管理功能
- 实现关联删除逻辑(删除商户自动禁用账号)
---
## 相关文档
- [使用指南](./使用指南.md) - 功能说明和使用场景
- [项目开发规范](../../AGENTS.md) - 项目整体开发规范