Commit db1f4347 by luoqi

feat:接口标准

parent d91e197b
Pipeline #3222 passed with stage
in 9 seconds
...@@ -248,6 +248,58 @@ python migrate.py --rollback 001 ...@@ -248,6 +248,58 @@ python migrate.py --rollback 001
## 📚 API文档 ## 📚 API文档
### 🔗 前后端接口标准约定
#### 📋 统一响应格式
**标准响应格式(所有接口):**
```json
{
"success": true,
"message": "操作成功",
"data": [实际数据内容]
}
```
**特殊响应格式(认证相关接口):**
```json
{
"success": true,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"expires_in": 86400,
"user": {...},
"message": "登录成功"
}
```
#### 🔧 前端自动解包机制
前端API客户端自动处理响应格式:
- **自动检测**:识别 `BaseResponse` 格式(包含 `success` 字段)
- **自动解包**:提取 `data` 字段内容,透明返回给业务代码
- **错误处理**:检查 `success` 字段,失败时自动抛出异常
- **兼容性**:对特殊格式接口(如login)保持原样返回
#### 📊 状态码约定
| 状态码 | 含义 | 使用场景 |
|--------|------|----------|
| 200 | 成功 | 正常请求成功 |
| 400 | 请求错误 | 参数验证失败、业务逻辑错误 |
| 401 | 未授权 | Token无效、未登录 |
| 403 | 禁止访问 | 权限不足 |
| 404 | 资源不存在 | 数据不存在 |
| 500 | 服务器错误 | 系统内部错误 |
#### 🔐 认证机制
- **认证方式**:JWT Bearer Token
- **Token类型**:Access Token(短期)+ Refresh Token(长期)
- **自动刷新**:前端自动检测401错误并尝试刷新Token
- **安全登出**:服务端Token黑名单机制
### 接口概览 ### 接口概览
系统提供完整的RESTful API,支持前后端分离架构。 系统提供完整的RESTful API,支持前后端分离架构。
...@@ -260,30 +312,110 @@ python migrate.py --rollback 001 ...@@ -260,30 +312,110 @@ python migrate.py --rollback 001
### 主要接口 ### 主要接口
| 模块 | 方法 | 路径 | 描述 | | 模块 | 方法 | 路径 | 描述 | 响应格式 |
|------|------|------|------| |------|------|------|------|----------|
| 认证 | POST | `/users/login` | 用户登录 | | 认证 | POST | `/users/login` | 用户登录 | 特殊格式 |
| 认证 | POST | `/users/refresh` | 刷新Token | | 认证 | POST | `/users/logout` | 用户登出 | 标准格式 |
| 用户 | GET | `/users` | 获取用户列表 | | 认证 | POST | `/users/refresh` | 刷新Token | 特殊格式 |
| 用户 | POST | `/users` | 创建用户 | | 用户 | GET | `/users` | 获取用户列表 | 标准格式 |
| 用户 | PUT | `/users/{id}` | 更新用户 | | 用户 | GET | `/users/{id}` | 获取用户信息 | 标准格式 |
| 用户 | DELETE | `/users/{id}` | 删除用户 | | 用户 | POST | `/users` | 创建用户 | 标准格式 |
| 机构 | GET | `/institutions` | 获取机构列表 | | 用户 | PUT | `/users/{id}` | 更新用户 | 标准格式 |
| 机构 | POST | `/institutions` | 创建机构 | | 用户 | DELETE | `/users/{id}` | 删除用户 | 标准格式 |
| 历史 | GET | `/history` | 获取历史数据 | | 机构 | GET | `/institutions` | 获取机构列表 | 标准格式 |
| 配置 | GET | `/config` | 获取系统配置 | | 机构 | GET | `/institutions/{id}` | 获取机构信息 | 标准格式 |
| 机构 | POST | `/institutions` | 创建机构 | 标准格式 |
### 认证示例 | 机构 | PUT | `/institutions/{id}` | 更新机构 | 标准格式 |
| 机构 | DELETE | `/institutions/{id}` | 删除机构 | 标准格式 |
| 历史 | GET | `/history` | 获取历史数据列表 | 标准格式 |
| 历史 | GET | `/history/{month}` | 获取指定月份历史 | 标准格式 |
| 历史 | POST | `/history` | 保存月度历史 | 标准格式 |
| 历史 | DELETE | `/history` | 清空历史数据 | 标准格式 |
| 配置 | GET | `/config` | 获取系统配置 | 标准格式 |
| 配置 | GET | `/config/{key}` | 获取指定配置项 | 标准格式 |
### 🔧 API使用示例
#### 认证流程
```bash ```bash
# 登录获取Token # 1. 用户登录(特殊格式响应)
curl -X POST "http://localhost:8000/api/users/login" \ curl -X POST "http://localhost:8000/api/users/login" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"phone":"admin","password":"admin123"}' -d '{"phone":"admin","password":"admin123"}'
# 使用Token访问API # 响应示例:
{
"success": true,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"expires_in": 86400,
"user": {
"id": "admin",
"phone": "admin",
"name": "系统管理员",
"role": "admin"
},
"message": "登录成功"
}
# 2. 使用Token访问API(标准格式响应)
curl -X GET "http://localhost:8000/api/users" \ curl -X GET "http://localhost:8000/api/users" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 响应示例:
{
"success": true,
"message": "获取用户列表成功",
"data": [
{
"id": "admin",
"phone": "admin",
"name": "系统管理员",
"role": "admin",
"institutions": [],
"created_at": "2025-08-30T10:00:00",
"updated_at": "2025-08-30T10:00:00"
}
]
}
# 3. 刷新Token
curl -X POST "http://localhost:8000/api/users/refresh" \
-H "Content-Type: application/json" \
-d '{"refresh_token":"YOUR_REFRESH_TOKEN"}'
# 4. 用户登出
curl -X POST "http://localhost:8000/api/users/logout" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
#### 业务接口示例
```bash
# 获取机构列表
curl -X GET "http://localhost:8000/api/institutions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 创建机构
curl -X POST "http://localhost:8000/api/institutions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "inst_001",
"name": "测试机构",
"institution_id": "TEST001",
"owner_id": "user_001"
}'
# 获取历史数据
curl -X GET "http://localhost:8000/api/history" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
# 获取系统配置
curl -X GET "http://localhost:8000/api/config" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
``` ```
## 🔧 环境配置 ## 🔧 环境配置
......
...@@ -16,7 +16,7 @@ from dependencies import get_current_active_user, require_admin ...@@ -16,7 +16,7 @@ from dependencies import get_current_active_user, require_admin
router = APIRouter() router = APIRouter()
@router.get("", response_model=List[MonthlyHistoryResponse], summary="获取所有历史记录") @router.get("", response_model=BaseResponse, summary="获取所有历史记录")
async def get_all_history( async def get_all_history(
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
current_user: UserResponse = Depends(get_current_active_user) current_user: UserResponse = Depends(get_current_active_user)
...@@ -54,18 +54,26 @@ async def get_all_history( ...@@ -54,18 +54,26 @@ async def get_all_history(
# 跳过有问题的记录,继续处理其他记录 # 跳过有问题的记录,继续处理其他记录
continue continue
return result return BaseResponse(
success=True,
message="获取历史记录成功",
data=result
)
except Exception as e: except Exception as e:
logger.error(f"获取历史记录失败: {e}") logger.error(f"获取历史记录失败: {e}")
# 如果是表不存在或字段不存在的错误,返回空列表而不是抛出异常 # 如果是表不存在或字段不存在的错误,返回空列表而不是抛出异常
if "does not exist" in str(e).lower(): if "does not exist" in str(e).lower():
logger.info("历史记录表或字段不存在,返回空列表") logger.info("历史记录表或字段不存在,返回空列表")
return [] return BaseResponse(
success=True,
message="获取历史记录成功",
data=[]
)
raise HTTPException(status_code=500, detail="获取历史记录失败") raise HTTPException(status_code=500, detail="获取历史记录失败")
@router.get("/{month}", response_model=MonthlyHistoryResponse, summary="获取指定月份历史记录") @router.get("/{month}", response_model=BaseResponse, summary="获取指定月份历史记录")
async def get_history_by_month( async def get_history_by_month(
month: str, month: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -88,7 +96,7 @@ async def get_history_by_month( ...@@ -88,7 +96,7 @@ async def get_history_by_month(
if institutions_data is None: if institutions_data is None:
institutions_data = [] institutions_data = []
return MonthlyHistoryResponse( history_data = MonthlyHistoryResponse(
id=history["id"], id=history["id"],
month=history["month"], month=history["month"],
save_time=history["save_time"], save_time=history["save_time"],
...@@ -100,6 +108,12 @@ async def get_history_by_month( ...@@ -100,6 +108,12 @@ async def get_history_by_month(
created_at=history["created_at"] created_at=history["created_at"]
) )
return BaseResponse(
success=True,
message="获取历史记录成功",
data=history_data
)
except HTTPException: except HTTPException:
raise raise
except Exception as e: except Exception as e:
......
...@@ -59,7 +59,7 @@ async def get_institution_with_images(institution_id: str, db: DatabaseManager): ...@@ -59,7 +59,7 @@ async def get_institution_with_images(institution_id: str, db: DatabaseManager):
) )
@router.get("", response_model=List[InstitutionResponse], summary="获取机构列表") @router.get("", response_model=BaseResponse, summary="获取机构列表")
async def get_all_institutions( async def get_all_institutions(
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
current_user: UserResponse = Depends(get_current_active_user) current_user: UserResponse = Depends(get_current_active_user)
...@@ -85,14 +85,19 @@ async def get_all_institutions( ...@@ -85,14 +85,19 @@ async def get_all_institutions(
result.append(inst_with_images) result.append(inst_with_images)
logger.info(f"用户 {current_user.name}({current_user.role}) 获取到 {len(result)} 个机构") logger.info(f"用户 {current_user.name}({current_user.role}) 获取到 {len(result)} 个机构")
return result
return BaseResponse(
success=True,
message="获取机构列表成功",
data=result
)
except Exception as e: except Exception as e:
logger.error(f"获取机构列表失败: {e}") logger.error(f"获取机构列表失败: {e}")
raise HTTPException(status_code=500, detail="获取机构列表失败") raise HTTPException(status_code=500, detail="获取机构列表失败")
@router.get("/{institution_id}", response_model=InstitutionResponse, summary="根据ID获取机构") @router.get("/{institution_id}", response_model=BaseResponse, summary="根据ID获取机构")
async def get_institution_by_id( async def get_institution_by_id(
institution_id: str, institution_id: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -105,7 +110,11 @@ async def get_institution_by_id( ...@@ -105,7 +110,11 @@ async def get_institution_by_id(
if not institution: if not institution:
raise HTTPException(status_code=404, detail="机构不存在") raise HTTPException(status_code=404, detail="机构不存在")
return institution return BaseResponse(
success=True,
message="获取机构信息成功",
data=institution
)
except HTTPException: except HTTPException:
raise raise
...@@ -114,7 +123,7 @@ async def get_institution_by_id( ...@@ -114,7 +123,7 @@ async def get_institution_by_id(
raise HTTPException(status_code=500, detail="获取机构失败") raise HTTPException(status_code=500, detail="获取机构失败")
@router.get("/owner/{owner_id}", response_model=List[InstitutionResponse], summary="根据负责人ID获取机构") @router.get("/owner/{owner_id}", response_model=BaseResponse, summary="根据负责人ID获取机构")
async def get_institutions_by_owner( async def get_institutions_by_owner(
owner_id: str, owner_id: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -134,14 +143,18 @@ async def get_institutions_by_owner( ...@@ -134,14 +143,18 @@ async def get_institutions_by_owner(
if inst_with_images: if inst_with_images:
result.append(inst_with_images) result.append(inst_with_images)
return result return BaseResponse(
success=True,
message="获取机构列表成功",
data=result
)
except Exception as e: except Exception as e:
logger.error(f"根据负责人获取机构失败: {e}") logger.error(f"根据负责人获取机构失败: {e}")
raise HTTPException(status_code=500, detail="获取机构失败") raise HTTPException(status_code=500, detail="获取机构失败")
@router.post("", response_model=InstitutionResponse, summary="创建机构") @router.post("", response_model=BaseResponse, summary="创建机构")
async def create_institution( async def create_institution(
institution_data: InstitutionCreate, institution_data: InstitutionCreate,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -176,8 +189,14 @@ async def create_institution( ...@@ -176,8 +189,14 @@ async def create_institution(
await db.execute(query) await db.execute(query)
# 返回创建的机构信息 # 获取创建的机构信息
return await get_institution_by_id(institution_data.id, db) created_institution = await get_institution_with_images(institution_data.id, db)
return BaseResponse(
success=True,
message="创建机构成功",
data=created_institution
)
except HTTPException: except HTTPException:
raise raise
...@@ -186,7 +205,7 @@ async def create_institution( ...@@ -186,7 +205,7 @@ async def create_institution(
raise HTTPException(status_code=500, detail="创建机构失败") raise HTTPException(status_code=500, detail="创建机构失败")
@router.put("/{institution_id}", response_model=InstitutionResponse, summary="更新机构") @router.put("/{institution_id}", response_model=BaseResponse, summary="更新机构")
async def update_institution( async def update_institution(
institution_id: str, institution_id: str,
institution_data: InstitutionUpdate, institution_data: InstitutionUpdate,
...@@ -229,8 +248,14 @@ async def update_institution( ...@@ -229,8 +248,14 @@ async def update_institution(
).values(**update_data) ).values(**update_data)
await db.execute(query) await db.execute(query)
# 返回更新后的机构信息 # 获取更新后的机构信息
return await get_institution_by_id(institution_id, db) updated_institution = await get_institution_with_images(institution_id, db)
return BaseResponse(
success=True,
message="更新机构成功",
data=updated_institution
)
except HTTPException: except HTTPException:
raise raise
...@@ -359,7 +384,7 @@ async def delete_institution_image( ...@@ -359,7 +384,7 @@ async def delete_institution_image(
raise HTTPException(status_code=500, detail="删除图片失败") raise HTTPException(status_code=500, detail="删除图片失败")
@router.get("/institution-id/{inst_id}", response_model=InstitutionResponse, summary="根据机构编号获取机构") @router.get("/institution-id/{inst_id}", response_model=BaseResponse, summary="根据机构编号获取机构")
async def get_institution_by_institution_id( async def get_institution_by_institution_id(
inst_id: str, inst_id: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -373,7 +398,13 @@ async def get_institution_by_institution_id( ...@@ -373,7 +398,13 @@ async def get_institution_by_institution_id(
if not institution: if not institution:
raise HTTPException(status_code=404, detail="机构不存在") raise HTTPException(status_code=404, detail="机构不存在")
return await get_institution_with_images(institution["id"], db) institution_data = await get_institution_with_images(institution["id"], db)
return BaseResponse(
success=True,
message="获取机构信息成功",
data=institution_data
)
except HTTPException: except HTTPException:
raise raise
......
...@@ -14,7 +14,7 @@ from dependencies import get_current_active_user, require_admin ...@@ -14,7 +14,7 @@ from dependencies import get_current_active_user, require_admin
router = APIRouter() router = APIRouter()
@router.get("", response_model=Dict[str, Any], summary="获取所有系统配置") @router.get("", response_model=BaseResponse, summary="获取所有系统配置")
async def get_all_config( async def get_all_config(
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
current_user: UserResponse = Depends(get_current_active_user) current_user: UserResponse = Depends(get_current_active_user)
...@@ -29,21 +29,25 @@ async def get_all_config( ...@@ -29,21 +29,25 @@ async def get_all_config(
for config in configs: for config in configs:
result[config["config_key"]] = config["config_value"] result[config["config_key"]] = config["config_value"]
return result return BaseResponse(
success=True,
message="获取系统配置成功",
data=result
)
except Exception as e: except Exception as e:
logger.error(f"获取系统配置失败: {e}") logger.error(f"获取系统配置失败: {e}")
raise HTTPException(status_code=500, detail="获取系统配置失败") raise HTTPException(status_code=500, detail="获取系统配置失败")
@router.get("/list", response_model=List[SystemConfigResponse], summary="获取系统配置列表") @router.get("/list", response_model=BaseResponse, summary="获取系统配置列表")
async def get_config_list(db: DatabaseManager = Depends(get_database)): async def get_config_list(db: DatabaseManager = Depends(get_database)):
"""获取系统配置列表(详细格式)""" """获取系统配置列表(详细格式)"""
try: try:
query = system_config_table.select().order_by(system_config_table.c.config_key) query = system_config_table.select().order_by(system_config_table.c.config_key)
configs = await db.fetch_all(query) configs = await db.fetch_all(query)
return [ config_list = [
SystemConfigResponse( SystemConfigResponse(
id=config["id"], id=config["id"],
config_key=config["config_key"], config_key=config["config_key"],
...@@ -55,12 +59,18 @@ async def get_config_list(db: DatabaseManager = Depends(get_database)): ...@@ -55,12 +59,18 @@ async def get_config_list(db: DatabaseManager = Depends(get_database)):
for config in configs for config in configs
] ]
return BaseResponse(
success=True,
message="获取系统配置列表成功",
data=config_list
)
except Exception as e: except Exception as e:
logger.error(f"获取系统配置列表失败: {e}") logger.error(f"获取系统配置列表失败: {e}")
raise HTTPException(status_code=500, detail="获取系统配置列表失败") raise HTTPException(status_code=500, detail="获取系统配置列表失败")
@router.get("/{config_key}", response_model=Any, summary="获取指定配置项") @router.get("/{config_key}", response_model=BaseResponse, summary="获取指定配置项")
async def get_config_by_key(config_key: str, db: DatabaseManager = Depends(get_database)): async def get_config_by_key(config_key: str, db: DatabaseManager = Depends(get_database)):
"""根据配置键名获取配置值""" """根据配置键名获取配置值"""
try: try:
...@@ -70,7 +80,11 @@ async def get_config_by_key(config_key: str, db: DatabaseManager = Depends(get_d ...@@ -70,7 +80,11 @@ async def get_config_by_key(config_key: str, db: DatabaseManager = Depends(get_d
if not config: if not config:
raise HTTPException(status_code=404, detail="配置项不存在") raise HTTPException(status_code=404, detail="配置项不存在")
return config["config_value"] return BaseResponse(
success=True,
message="获取配置项成功",
data=config["config_value"]
)
except HTTPException: except HTTPException:
raise raise
......
...@@ -22,7 +22,7 @@ from config import settings ...@@ -22,7 +22,7 @@ from config import settings
router = APIRouter() router = APIRouter()
@router.get("", response_model=List[UserResponse], summary="获取所有用户") @router.get("", response_model=BaseResponse, summary="获取所有用户")
async def get_all_users( async def get_all_users(
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
current_user: UserResponse = Depends(require_admin) current_user: UserResponse = Depends(require_admin)
...@@ -32,7 +32,7 @@ async def get_all_users( ...@@ -32,7 +32,7 @@ async def get_all_users(
query = users_table.select() query = users_table.select()
users = await db.fetch_all(query) users = await db.fetch_all(query)
return [ user_list = [
UserResponse( UserResponse(
id=user["id"], id=user["id"],
phone=user["phone"], phone=user["phone"],
...@@ -44,6 +44,12 @@ async def get_all_users( ...@@ -44,6 +44,12 @@ async def get_all_users(
) )
for user in users for user in users
] ]
return BaseResponse(
success=True,
message="获取用户列表成功",
data=user_list
)
except Exception as e: except Exception as e:
logger.error(f"获取用户列表失败: {e}") logger.error(f"获取用户列表失败: {e}")
raise HTTPException(status_code=500, detail="获取用户列表失败") raise HTTPException(status_code=500, detail="获取用户列表失败")
...@@ -55,7 +61,7 @@ async def get_current_user_info(current_user: UserResponse = Depends(get_current ...@@ -55,7 +61,7 @@ async def get_current_user_info(current_user: UserResponse = Depends(get_current
return current_user return current_user
@router.get("/{user_id}", response_model=UserResponse, summary="根据ID获取用户") @router.get("/{user_id}", response_model=BaseResponse, summary="根据ID获取用户")
async def get_user_by_id( async def get_user_by_id(
user_id: str, user_id: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -69,7 +75,7 @@ async def get_user_by_id( ...@@ -69,7 +75,7 @@ async def get_user_by_id(
if not user: if not user:
raise HTTPException(status_code=404, detail="用户不存在") raise HTTPException(status_code=404, detail="用户不存在")
return UserResponse( user_data = UserResponse(
id=user["id"], id=user["id"],
phone=user["phone"], phone=user["phone"],
name=user["name"], name=user["name"],
...@@ -78,6 +84,12 @@ async def get_user_by_id( ...@@ -78,6 +84,12 @@ async def get_user_by_id(
created_at=user["created_at"], created_at=user["created_at"],
updated_at=user["updated_at"] updated_at=user["updated_at"]
) )
return BaseResponse(
success=True,
message="获取用户信息成功",
data=user_data
)
except HTTPException: except HTTPException:
raise raise
except Exception as e: except Exception as e:
...@@ -85,7 +97,7 @@ async def get_user_by_id( ...@@ -85,7 +97,7 @@ async def get_user_by_id(
raise HTTPException(status_code=500, detail="获取用户失败") raise HTTPException(status_code=500, detail="获取用户失败")
@router.post("", response_model=UserResponse, summary="创建用户") @router.post("", response_model=BaseResponse, summary="创建用户")
async def create_user( async def create_user(
user_data: UserCreate, user_data: UserCreate,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -122,8 +134,14 @@ async def create_user( ...@@ -122,8 +134,14 @@ async def create_user(
await db.execute(query) await db.execute(query)
# 返回创建的用户信息 # 获取创建的用户信息
return await get_user_by_id(user_data.id, db) created_user_response = await get_user_by_id(user_data.id, db, current_user)
return BaseResponse(
success=True,
message="创建用户成功",
data=created_user_response.data
)
except HTTPException: except HTTPException:
raise raise
...@@ -132,7 +150,7 @@ async def create_user( ...@@ -132,7 +150,7 @@ async def create_user(
raise HTTPException(status_code=500, detail="创建用户失败") raise HTTPException(status_code=500, detail="创建用户失败")
@router.put("/{user_id}", response_model=UserResponse, summary="更新用户") @router.put("/{user_id}", response_model=BaseResponse, summary="更新用户")
async def update_user( async def update_user(
user_id: str, user_id: str,
user_data: UserUpdate, user_data: UserUpdate,
...@@ -179,8 +197,14 @@ async def update_user( ...@@ -179,8 +197,14 @@ async def update_user(
query = users_table.update().where(users_table.c.id == user_id).values(**update_data) query = users_table.update().where(users_table.c.id == user_id).values(**update_data)
await db.execute(query) await db.execute(query)
# 返回更新后的用户信息 # 获取更新后的用户信息
return await get_user_by_id(user_id, db) updated_user_response = await get_user_by_id(user_id, db, current_user)
return BaseResponse(
success=True,
message="更新用户成功",
data=updated_user_response.data
)
except HTTPException: except HTTPException:
raise raise
...@@ -344,7 +368,7 @@ async def logout( ...@@ -344,7 +368,7 @@ async def logout(
@router.get("/phone/{phone}", response_model=UserResponse, summary="根据手机号获取用户") @router.get("/phone/{phone}", response_model=BaseResponse, summary="根据手机号获取用户")
async def get_user_by_phone( async def get_user_by_phone(
phone: str, phone: str,
db: DatabaseManager = Depends(get_database), db: DatabaseManager = Depends(get_database),
...@@ -358,7 +382,7 @@ async def get_user_by_phone( ...@@ -358,7 +382,7 @@ async def get_user_by_phone(
if not user: if not user:
raise HTTPException(status_code=404, detail="用户不存在") raise HTTPException(status_code=404, detail="用户不存在")
return UserResponse( user_data = UserResponse(
id=user["id"], id=user["id"],
phone=user["phone"], phone=user["phone"],
name=user["name"], name=user["name"],
...@@ -367,6 +391,12 @@ async def get_user_by_phone( ...@@ -367,6 +391,12 @@ async def get_user_by_phone(
created_at=user["created_at"], created_at=user["created_at"],
updated_at=user["updated_at"] updated_at=user["updated_at"]
) )
return BaseResponse(
success=True,
message="获取用户信息成功",
data=user_data
)
except HTTPException: except HTTPException:
raise raise
except Exception as e: except Exception as e:
......
...@@ -131,7 +131,8 @@ class ApiClient { ...@@ -131,7 +131,8 @@ class ApiClient {
}) })
if (retryResponse.ok) { if (retryResponse.ok) {
return await retryResponse.json() const retryData = await retryResponse.json()
return this.unwrapResponse(retryData)
} }
} }
...@@ -146,7 +147,9 @@ class ApiClient { ...@@ -146,7 +147,9 @@ class ApiClient {
throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`) throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`)
} }
return await response.json() const responseData = await response.json()
// 自动解包BaseResponse格式的响应
return this.unwrapResponse(responseData)
} catch (error) { } catch (error) {
if (error.name === 'AbortError') { if (error.name === 'AbortError') {
throw new Error('请求超时,请检查网络连接') throw new Error('请求超时,请检查网络连接')
...@@ -157,6 +160,23 @@ class ApiClient { ...@@ -157,6 +160,23 @@ class ApiClient {
} }
/** /**
* 自动解包BaseResponse格式的响应
*/
unwrapResponse(responseData) {
// 如果响应包含success字段,说明是BaseResponse格式
if (responseData && typeof responseData === 'object' && 'success' in responseData) {
// 检查请求是否成功
if (!responseData.success) {
throw new Error(responseData.message || '请求失败')
}
// 返回data字段的内容,如果没有data字段则返回整个响应
return responseData.data !== undefined ? responseData.data : responseData
}
// 如果不是BaseResponse格式,直接返回原始数据(如login/logout等特殊接口)
return responseData
}
/**
* 刷新访问token * 刷新访问token
*/ */
async refreshAccessToken() { async refreshAccessToken() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment