Files
huang 80f560df33
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m17s
refactor(account): 统一账号管理API、完善权限检查和操作审计
- 合并 customer_account 和 shop_account 路由到统一的 account 接口
- 新增统一认证接口 (auth handler)
- 实现越权防护中间件和权限检查工具函数
- 新增操作审计日志模型和服务
- 更新数据库迁移 (版本 39: account_operation_log 表)
- 补充集成测试覆盖权限检查和审计日志场景
2026-02-02 17:23:20 +08:00

589 lines
9.7 KiB
Markdown
Raw Permalink 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/auth/*`)
### 1. 登录
**路由**`POST /api/auth/login`
**请求体**
```json
{
"username": "admin", // 用户名或手机号(二选一)
"phone": "13800000001", //
"password": "Password123" // 必填
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 86400, // 24小时
"user": {
"id": 1,
"username": "admin",
"user_type": 1,
"menus": [...], // 菜单树
"buttons": [...] // 按钮权限
}
},
"timestamp": 1638345600
}
```
### 2. 登出
**路由**`POST /api/auth/logout`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
### 3. 刷新 Token
**路由**`POST /api/auth/refresh-token`
**请求体**
```json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 86400
},
"timestamp": 1638345600
}
```
### 4. 获取用户信息
**路由**`GET /api/auth/me`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"username": "admin",
"phone": "13800000001",
"user_type": 1,
"shop_id": null,
"enterprise_id": null,
"status": 1,
"menus": [...],
"buttons": [...]
},
"timestamp": 1638345600
}
```
### 5. 修改密码
**路由**`PUT /api/auth/password`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体**
```json
{
"old_password": "OldPassword123",
"new_password": "NewPassword123"
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
---
## 账号管理接口 (`/api/admin/accounts/*`)
### 路由结构说明
**所有账号类型共享同一套接口**,通过请求体的 `user_type` 字段区分:
- `user_type: 2` - 平台用户
- `user_type: 3` - 代理账号(需提供 `shop_id`
- `user_type: 4` - 企业账号(需提供 `enterprise_id`
---
### 1. 创建账号
**路由**`POST /api/admin/accounts`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体(平台账号)**
```json
{
"username": "platform_user",
"phone": "13800000001",
"password": "Password123",
"user_type": 2 // 2=平台用户
}
```
**请求体(代理账号)**
```json
{
"username": "agent_user",
"phone": "13800000002",
"password": "Password123",
"user_type": 3, // 3=代理账号
"shop_id": 10 // 必填
}
```
**请求体(企业账号)**
```json
{
"username": "enterprise_user",
"phone": "13800000003",
"password": "Password123",
"user_type": 4, // 4=企业账号
"enterprise_id": 5 // 必填
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 100,
"username": "platform_user",
"phone": "13800000001",
"user_type": 2,
"status": 1,
"created_at": "2025-02-02T10:00:00Z"
},
"timestamp": 1638345600
}
```
### 2. 查询账号列表
**路由**`GET /api/admin/accounts?page=1&page_size=20&user_type=3&username=test&status=1`
**请求头**
```
Authorization: Bearer {access_token}
```
**查询参数**
- `page`:页码(默认 1
- `page_size`:每页数量(默认 20最大 100
- `user_type`账号类型2=平台3=代理4=企业),不传则查询所有
- `username`:用户名(模糊搜索)
- `phone`:手机号(模糊搜索)
- `status`状态1=启用2=禁用)
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"list": [
{
"id": 100,
"username": "platform_user",
"phone": "13800000001",
"user_type": 2,
"status": 1,
"created_at": "2025-02-02T10:00:00Z"
}
],
"total": 50,
"page": 1,
"page_size": 20
},
"timestamp": 1638345600
}
```
### 3. 获取账号详情
**路由**`GET /api/admin/accounts/:id`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 100,
"username": "platform_user",
"phone": "13800000001",
"user_type": 2,
"shop_id": null,
"enterprise_id": null,
"status": 1,
"created_at": "2025-02-02T10:00:00Z",
"updated_at": "2025-02-02T11:00:00Z"
},
"timestamp": 1638345600
}
```
### 4. 更新账号
**路由**`PUT /api/admin/accounts/:id`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体**
```json
{
"username": "new_username", // 可选
"phone": "13900000001", // 可选
"status": 2 // 可选1=启用2=禁用)
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": {
"id": 100,
"username": "new_username",
"phone": "13900000001",
"status": 2,
"updated_at": "2025-02-02T12:00:00Z"
},
"timestamp": 1638345600
}
```
### 5. 删除账号
**路由**`DELETE /api/admin/accounts/:id`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
### 6. 修改账号密码
**路由**`PUT /api/admin/accounts/:id/password`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体**
```json
{
"password": "NewPassword123"
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
### 7. 修改账号状态
**路由**`PUT /api/admin/accounts/:id/status`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体**
```json
{
"status": 2 // 1=启用2=禁用
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
### 8. 分配角色
**路由**`POST /api/admin/accounts/:id/roles`
**请求头**
```
Authorization: Bearer {access_token}
```
**请求体**
```json
{
"role_ids": [1, 2, 3] // 角色 ID 数组,空数组表示清空所有角色
}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": [
{
"id": 1,
"account_id": 100,
"role_id": 1,
"created_at": "2025-02-02T12:00:00Z"
},
{
"id": 2,
"account_id": 100,
"role_id": 2,
"created_at": "2025-02-02T12:00:00Z"
}
],
"timestamp": 1638345600
}
```
### 9. 获取账号角色
**路由**`GET /api/admin/accounts/:id/roles`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"data": [
{
"id": 1,
"role_name": "系统管理员",
"role_code": "system_admin",
"role_type": 2
},
{
"id": 2,
"role_name": "运营人员",
"role_code": "operator",
"role_type": 2
}
],
"timestamp": 1638345600
}
```
### 10. 移除角色
**路由**`DELETE /api/admin/accounts/:account_id/roles/:role_id`
**请求头**
```
Authorization: Bearer {access_token}
```
**响应**
```json
{
"code": 0,
"msg": "success",
"timestamp": 1638345600
}
```
---
## 错误码说明
### 认证相关
| 错误码 | 说明 |
|-------|------|
| 1001 | 缺失认证令牌 |
| 1002 | 无效或过期的令牌 |
| 1003 | 权限不足 |
### 账号管理相关
| 错误码 | 说明 |
|-------|------|
| 2001 | 用户名已存在 |
| 2002 | 手机号已存在 |
| 2003 | 账号不存在 |
| 2004 | 无权限操作该资源或资源不存在 |
| 2005 | 超级管理员不允许分配角色 |
| 2006 | 角色类型与账号类型不匹配 |
### 通用错误
| 错误码 | 说明 |
|-------|------|
| 400 | 请求参数错误 |
| 500 | 服务器内部错误 |
---
## 权限说明
### 账号类型与权限
| 账号类型 | 值 | 可创建的账号类型 | 可访问的接口 |
|---------|---|---------------|------------|
| 超级管理员 | 1 | 所有 | 所有 |
| 平台用户 | 2 | 平台、代理、企业 | 所有账号管理 |
| 代理账号 | 3 | 自己店铺及下级店铺的代理、企业 | 自己店铺及下级的账号 |
| 企业账号 | 4 | 无 | **禁止访问账号管理** |
### 企业账号限制
企业账号访问账号管理接口会返回:
```json
{
"code": 1003,
"msg": "无权限访问账号管理功能",
"timestamp": 1638345600
}
```
---
## 使用示例
### 创建不同类型账号
```javascript
// 1. 创建平台账号
POST /api/admin/accounts
{
"username": "platform1",
"phone": "13800000001",
"password": "Pass123",
"user_type": 2 // 平台用户
}
// 2. 创建代理账号
POST /api/admin/accounts
{
"username": "agent1",
"phone": "13800000002",
"password": "Pass123",
"user_type": 3, // 代理账号
"shop_id": 10 // 必填:归属店铺
}
// 3. 创建企业账号
POST /api/admin/accounts
{
"username": "ent1",
"phone": "13800000003",
"password": "Pass123",
"user_type": 4, // 企业账号
"enterprise_id": 5 // 必填:归属企业
}
```
### 查询不同类型账号
```javascript
// 1. 查询所有账号
GET /api/admin/accounts
// 2. 查询平台账号
GET /api/admin/accounts?user_type=2
// 3. 查询代理账号
GET /api/admin/accounts?user_type=3
// 4. 查询企业账号
GET /api/admin/accounts?user_type=4
// 5. 组合筛选(代理账号 + 启用状态)
GET /api/admin/accounts?user_type=3&status=1
// 6. 分页查询
GET /api/admin/accounts?page=2&page_size=50
```
---
## 相关文档
- [迁移指南](./迁移指南.md) - 接口迁移步骤
- [功能总结](./功能总结.md) - 重构内容和安全提升
- [OpenAPI 规范](../../docs/admin-openapi.yaml) - 机器可读的完整接口文档