Files
junhong_cmp_fiber/docs/account-management-refactor/迁移指南.md
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

311 lines
10 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.
# 账号管理接口迁移指南
## 概述
本次重构统一了账号管理和认证接口架构,简化了路由结构,前端需要更新所有相关接口调用。
## Breaking Changes
### 1. 账号管理接口路由变更
所有账号管理接口统一为 `/api/admin/accounts/*` 结构,**不再按账号类型区分路由**
| 旧路由前缀 | 新路由前缀 | 说明 |
|-----------|-----------|------|
| `/api/admin/platform-accounts` | `/api/admin/accounts` | 平台账号 |
| `/api/admin/shop-accounts` | `/api/admin/accounts` | 代理账号 |
| `/api/admin/customer-accounts` | `/api/admin/accounts` | 企业账号(改名) |
**重要变更**
- ✅ 所有账号类型共享同一套路由
- ✅ 账号类型通过**请求体的 `user_type` 字段**区分2=平台3=代理4=企业)
-`customer-accounts` 改名为 `enterprise`(命名更准确)
#### 完整路由映射10个接口
| 功能 | HTTP 方法 | 旧路径示例(平台账号) | 新路径(统一) |
|------|-----------|---------------------|-------------|
| 创建账号 | POST | `/api/admin/platform-accounts` | `/api/admin/accounts` |
| 查询列表 | GET | `/api/admin/platform-accounts` | `/api/admin/accounts` |
| 获取详情 | GET | `/api/admin/platform-accounts/:id` | `/api/admin/accounts/:id` |
| 更新账号 | PUT | `/api/admin/platform-accounts/:id` | `/api/admin/accounts/:id` |
| 删除账号 | DELETE | `/api/admin/platform-accounts/:id` | `/api/admin/accounts/:id` |
| 修改密码 | PUT | `/api/admin/platform-accounts/:id/password` | `/api/admin/accounts/:id/password` |
| 修改状态 | PUT | `/api/admin/platform-accounts/:id/status` | `/api/admin/accounts/:id/status` |
| 分配角色 | POST | `/api/admin/platform-accounts/:id/roles` | `/api/admin/accounts/:id/roles` |
| 获取角色 | GET | `/api/admin/platform-accounts/:id/roles` | `/api/admin/accounts/:id/roles` |
| 移除角色 | DELETE | `/api/admin/platform-accounts/:id/roles/:role_id` | `/api/admin/accounts/:account_id/roles/:role_id` |
**⚠️ 特别注意**:移除角色接口的路径参数从 `:id` 改为 `:account_id`
### 2. 认证接口路由变更
后台和 H5 认证接口合并为统一的 `/api/auth/*`
| 功能 | 后台旧路由 | H5 旧路由 | 新路由(统一) |
|------|-----------|----------|-------------|
| 登录 | `/api/admin/login` | `/api/h5/login` | `/api/auth/login` |
| 登出 | `/api/admin/logout` | `/api/h5/logout` | `/api/auth/logout` |
| 刷新Token | `/api/admin/refresh-token` | `/api/h5/refresh-token` | `/api/auth/refresh-token` |
| 获取用户信息 | `/api/admin/me` | `/api/h5/me` | `/api/auth/me` |
| 修改密码 | `/api/admin/password` | `/api/h5/password` | `/api/auth/password` |
**个人客户认证不受影响**`/api/c/v1/*` 保持不变
## 数据结构变更
### 请求体变更:账号类型通过 user_type 字段区分
创建账号时,必须在请求体中指定 `user_type`
```json
{
"username": "test_user",
"phone": "13800000001",
"password": "Password123",
"user_type": 2, // 必填2=平台用户3=代理账号4=企业账号
"shop_id": 10, // 代理账号必填
"enterprise_id": 5 // 企业账号必填
}
```
查询账号列表时,可通过 `user_type` 参数筛选:
```
GET /api/admin/accounts?user_type=3 // 查询代理账号
GET /api/admin/accounts // 查询所有账号
```
### 响应体无变化
所有接口的响应体结构保持不变。
## 迁移步骤
### 第一步:批量替换路由
使用编辑器全局搜索替换:
```
# 账号管理路由(所有账号类型统一)
/api/admin/platform-accounts → /api/admin/accounts
/api/admin/shop-accounts → /api/admin/accounts
/api/admin/customer-accounts → /api/admin/accounts
# 认证路由(后台)
/api/admin/login → /api/auth/login
/api/admin/logout → /api/auth/logout
/api/admin/refresh-token → /api/auth/refresh-token
/api/admin/me → /api/auth/me
/api/admin/password → /api/auth/password
# 认证路由H5
/api/h5/login → /api/auth/login
/api/h5/logout → /api/auth/logout
/api/h5/refresh-token → /api/auth/refresh-token
/api/h5/me → /api/auth/me
/api/h5/password → /api/auth/password
```
### 第二步:更新账号创建逻辑
**旧代码**(根据路由区分账号类型):
```javascript
// ❌ 错误:通过不同路由创建不同类型账号
const createPlatformAccount = (data) => axios.post('/api/admin/platform-accounts', data);
const createShopAccount = (data) => axios.post('/api/admin/shop-accounts', data);
const createEnterpriseAccount = (data) => axios.post('/api/admin/customer-accounts', data);
```
**新代码**(通过 user_type 区分账号类型):
```javascript
// ✅ 正确:统一路由,通过 user_type 区分
const createAccount = (data) => axios.post('/api/admin/accounts', {
...data,
user_type: data.user_type, // 2=平台, 3=代理, 4=企业
});
// 使用示例
createAccount({ username: 'test', user_type: 2, ...otherData }); // 创建平台账号
createAccount({ username: 'agent1', user_type: 3, shop_id: 10, ...otherData }); // 创建代理账号
createAccount({ username: 'ent1', user_type: 4, enterprise_id: 5, ...otherData }); // 创建企业账号
```
### 第三步:更新账号查询逻辑
**旧代码**(分别查询不同类型账号):
```javascript
// ❌ 错误:三个不同的查询接口
const getPlatformAccounts = (params) => axios.get('/api/admin/platform-accounts', { params });
const getShopAccounts = (params) => axios.get('/api/admin/shop-accounts', { params });
const getEnterpriseAccounts = (params) => axios.get('/api/admin/customer-accounts', { params });
```
**新代码**(统一查询,可选筛选):
```javascript
// ✅ 正确:统一查询接口,通过 user_type 筛选
const getAccounts = (params) => axios.get('/api/admin/accounts', { params });
// 使用示例
getAccounts({ user_type: 2 }); // 查询平台账号
getAccounts({ user_type: 3 }); // 查询代理账号
getAccounts({ user_type: 4 }); // 查询企业账号
getAccounts({}); // 查询所有账号
```
### 第四步:更新类型定义(如果使用 TypeScript
```typescript
// 旧类型
type AccountType = 'platform' | 'shop' | 'customer';
// 新类型
type AccountType = 'platform' | 'shop' | 'enterprise'; // customer 改名为 enterprise
// 新增:账号类型值枚举
enum UserType {
Platform = 2, // 平台用户
Agent = 3, // 代理账号
Enterprise = 4, // 企业账号
}
```
### 第五步:测试验证
1. **后台系统**
- 登录/登出功能
- 平台账号 CRUD
- 代理账号 CRUD
- 企业账号 CRUD
- 角色管理功能
2. **H5 系统**
- 登录/登出功能
- 代理账号自助操作
- 企业账号自助操作
3. **个人客户端**
- 确认认证接口不受影响
## 快速迁移示例
### Vue/React 项目
```javascript
// 旧配置
const API = {
platformAccounts: '/api/admin/platform-accounts',
shopAccounts: '/api/admin/shop-accounts',
customerAccounts: '/api/admin/customer-accounts',
adminLogin: '/api/admin/login',
h5Login: '/api/h5/login',
}
// 新配置
const API = {
accounts: '/api/admin/accounts', // 统一账号管理接口
login: '/api/auth/login', // 统一认证接口
logout: '/api/auth/logout',
refreshToken: '/api/auth/refresh-token',
me: '/api/auth/me',
updatePassword: '/api/auth/password',
}
// 使用示例
const accountAPI = {
// 创建账号(根据 user_type 区分类型)
create: (data) => axios.post(API.accounts, data),
// 查询账号列表(可选筛选 user_type
list: (params) => axios.get(API.accounts, { params }),
// 获取详情
get: (id) => axios.get(`${API.accounts}/${id}`),
// 更新账号
update: (id, data) => axios.put(`${API.accounts}/${id}`, data),
// 删除账号
delete: (id) => axios.delete(`${API.accounts}/${id}`),
// 其他操作...
};
```
## 常见问题
### Q1为什么要做这次重构
**A**:解决以下问题:
1. 接口重复(三种账号类型有三套完全相同的接口)
2. 路由冗余Handler 逻辑完全一样,却有三套路由)
3. 维护成本高(新增功能需要改三处)
4. 命名混乱(`customer-accounts` 实际管理企业账号)
5. **安全漏洞**(缺少越权检查,代理可以为其他店铺创建账号)
### Q2是否支持向后兼容
**A****不支持**。这是 Breaking Change旧接口已完全删除前端必须同步更新。
### Q3迁移需要多长时间
**A**
- 简单项目2-4 小时(主要是查找替换 + 测试)
- 复杂项目1-2 天(需要重构业务逻辑 + 测试回归)
### Q4后台和 H5 登录接口合并后如何区分?
**A**:不需要区分。后端通过用户类型自动判断:
- 超级管理员、平台用户:只能后台登录
- 代理用户:可以后台和 H5 登录
- 企业用户:只能 H5 登录
### Q5企业账号有什么特殊限制
**A**:企业账号**禁止访问账号管理接口**(路由层直接拦截),尝试访问会返回 403 错误。
### Q6新增了哪些安全功能
**A**
1. **三层越权防护**:路由层拦截 + Service 层权限检查 + GORM 自动过滤
2. **操作审计日志**:所有账号操作(创建、更新、删除、角色分配)都被记录
3. **统一错误返回**:越权访问返回"无权限操作该资源或资源不存在",防止信息泄露
### Q7如何区分不同账号类型
**A**:通过 `user_type` 字段区分:
- `user_type: 2` - 平台用户
- `user_type: 3` - 代理账号(需提供 `shop_id`
- `user_type: 4` - 企业账号(需提供 `enterprise_id`
## 新增功能
### 1. 企业账号完整功能
企业账号现在支持所有操作(之前只有部分功能):
- ✅ CRUD 操作
- ✅ 角色管理
- ✅ 密码管理
- ✅ 状态管理
### 2. 代理账号完整功能
代理账号现在支持所有操作(之前缺少角色管理):
- ✅ CRUD 操作
-**角色管理**(新增)
- ✅ 密码管理
- ✅ 状态管理
### 3. 统一路由结构
所有账号类型共享同一套接口,简化了前端开发:
- ✅ 减少重复代码
- ✅ 统一接口调用方式
- ✅ 更容易扩展新功能
## 支持
如有问题请联系后端团队或查看以下文档:
- [功能总结](./功能总结.md)
- [API 文档](./API文档.md)
- [OpenAPI 规范](../../docs/admin-openapi.yaml)