用户管理
用户管理模块提供用户资料的查看、修改、密码管理等功能。
接口概览
| 方法 | 路径 | 描述 | 权限要求 |
|---|---|---|---|
| GET | /api/v1/users/profile | 获取当前用户资料 | 登录用户 |
| PUT | /api/v1/users/profile | 更新当前用户资料 | 登录用户 |
| PUT | /api/v1/users/password | 修改当前用户密码 | 登录用户 |
| GET | /api/v1/admin/users | 获取用户列表(管理员) | 管理员 |
| PUT | /api/v1/admin/users/{id}/status | 更新用户状态(管理员) | 管理员 |
获取当前用户资料
获取当前登录用户的详细资料信息。
接口信息
- URL:
/api/v1/users/profile - 方法:
GET - 认证: 需要 JWT token
请求头
Authorization: Bearer <your-jwt-token>响应示例
成功响应 (200)
json
{
"code": 200,
"message": "获取成功",
"data": {
"id": 1,
"username": "johndoe",
"email": "john@example.com",
"phone": "13800138000",
"avatar": "https://example.com/avatar.jpg",
"status": 1,
"created_at": "2024-01-01T12:00:00Z",
"updated_at": "2024-01-01T12:00:00Z"
},
"timestamp": "2024-01-01T12:00:00Z"
}错误响应 (401)
json
{
"code": 401,
"message": "未认证",
"error": "Invalid or expired token",
"timestamp": "2024-01-01T12:00:00Z"
}更新当前用户资料
更新当前登录用户的基本信息。
接口信息
- URL:
/api/v1/users/profile - 方法:
PUT - 内容类型:
application/json - 认证: 需要 JWT token
请求参数
| 字段 | 类型 | 必填 | 描述 | 示例 |
|---|---|---|---|---|
| username | string | 否 | 用户名 | "johndoe" |
| string | 否 | 邮箱地址 | "john@example.com" | |
| phone | string | 否 | 手机号码 | "13800138000" |
| avatar | string | 否 | 头像URL | "https://example.com/avatar.jpg" |
请求示例
json
{
"username": "johnsmith",
"phone": "13900139000",
"avatar": "https://example.com/new-avatar.jpg"
}响应示例
成功响应 (200)
json
{
"code": 200,
"message": "更新成功",
"data": null,
"timestamp": "2024-01-01T12:00:00Z"
}修改密码
修改当前登录用户的密码。
接口信息
- URL:
/api/v1/users/password - 方法:
PUT - 内容类型:
application/json - 认证: 需要 JWT token
请求参数
| 字段 | 类型 | 必填 | 描述 | 示例 |
|---|---|---|---|---|
| old_password | string | 是 | 旧密码 | "oldpassword123" |
| new_password | string | 是 | 新密码(至少6位) | "newpassword123" |
| confirm_password | string | 是 | 确认新密码 | "newpassword123" |
请求示例
json
{
"old_password": "oldpassword123",
"new_password": "newpassword123",
"confirm_password": "newpassword123"
}响应示例
成功响应 (200)
json
{
"code": 200,
"message": "密码修改成功",
"data": null,
"timestamp": "2024-01-01T12:00:00Z"
}错误响应 (401)
json
{
"code": 401,
"message": "认证失败",
"error": "旧密码错误",
"timestamp": "2024-01-01T12:00:00Z"
}获取用户列表(管理员)
管理员获取系统中的用户列表,支持分页。
接口信息
- URL:
/api/v1/admin/users - 方法:
GET - 认证: 需要管理员 JWT token
查询参数
| 参数 | 类型 | 必填 | 描述 | 默认值 |
|---|---|---|---|---|
| page | int | 否 | 页码 | 1 |
| page_size | int | 否 | 每页数量 | 10 |
| search | string | 否 | 搜索关键词 | - |
| status | int | 否 | 用户状态(0:禁用, 1:启用) | - |
请求示例
bash
GET /api/v1/admin/users?page=1&page_size=20&search=john响应示例
成功响应 (200)
json
{
"code": 200,
"message": "获取成功",
"data": {
"users": [
{
"id": 1,
"username": "johndoe",
"email": "john@example.com",
"phone": "13800138000",
"avatar": "https://example.com/avatar.jpg",
"status": 1,
"created_at": "2024-01-01T12:00:00Z"
}
],
"pagination": {
"page": 1,
"page_size": 20,
"total": 1,
"pages": 1
}
},
"timestamp": "2024-01-01T12:00:00Z"
}更新用户状态(管理员)
管理员更新指定用户的状态(启用/禁用)。
接口信息
- URL:
/api/v1/admin/users/{id}/status - 方法:
PUT - 内容类型:
application/json - 认证: 需要管理员 JWT token
路径参数
| 参数 | 类型 | 必填 | 描述 | 示例 |
|---|---|---|---|---|
| id | int | 是 | 用户ID | 1 |
请求参数
| 字段 | 类型 | 必填 | 描述 | 示例 |
|---|---|---|---|---|
| status | int | 是 | 用户状态(0:禁用, 1:启用) | 1 |
请求示例
json
{
"status": 1
}响应示例
成功响应 (200)
json
{
"code": 200,
"message": "更新成功",
"data": null,
"timestamp": "2024-01-01T12:00:00Z"
}数据模型
UserResponse
typescript
interface UserResponse {
id: number; // 用户ID
username: string; // 用户名
email: string; // 邮箱地址
phone: string; // 手机号码
avatar?: string; // 头像URL
status: number; // 用户状态(0:禁用, 1:启用)
created_at: string; // 创建时间
updated_at: string; // 更新时间
}UserListResponse
typescript
interface UserListResponse {
users: UserResponse[]; // 用户列表
pagination: { // 分页信息
page: number; // 当前页码
page_size: number; // 每页数量
total: number; // 总记录数
pages: number; // 总页数
};
}错误代码
| 错误代码 | 描述 | 解决方案 |
|---|---|---|
| 400 | 请求参数错误 | 检查请求参数格式和必填字段 |
| 401 | 未认证 | 检查 JWT token 是否有效 |
| 403 | 无权限 | 确认用户具有相应权限 |
| 404 | 用户不存在 | 检查用户ID是否正确 |
| 409 | 邮箱已被注册 | 使用其他邮箱地址 |
| 500 | 服务器内部错误 | 联系系统管理员 |
集成示例
React Hook
javascript
import { useState, useEffect } from 'react';
import axios from 'axios';
const useUser = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// 获取用户资料
const fetchProfile = async () => {
setLoading(true);
try {
const token = localStorage.getItem('token');
const response = await axios.get('/api/v1/users/profile', {
headers: {
'Authorization': `Bearer ${token}`
}
});
setUser(response.data.data);
} catch (err) {
setError(err.response?.data?.message || '获取用户资料失败');
} finally {
setLoading(false);
}
};
// 更新用户资料
const updateProfile = async (userData) => {
setLoading(true);
try {
const token = localStorage.getItem('token');
const response = await axios.put('/api/v1/users/profile', userData, {
headers: {
'Authorization': `Bearer ${token}`
}
});
setUser(response.data.data);
return response.data;
} catch (err) {
setError(err.response?.data?.message || '更新用户资料失败');
throw err;
} finally {
setLoading(false);
}
};
// 修改密码
const changePassword = async (passwordData) => {
setLoading(true);
try {
const token = localStorage.getItem('token');
const response = await axios.put('/api/v1/users/password', passwordData, {
headers: {
'Authorization': `Bearer ${token}`
}
});
return response.data;
} catch (err) {
setError(err.response?.data?.message || '修改密码失败');
throw err;
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchProfile();
}, []);
return {
user,
loading,
error,
fetchProfile,
updateProfile,
changePassword
};
};
// 使用示例
function UserProfile() {
const { user, loading, error, updateProfile } = useUser();
const handleUpdate = async (formData) => {
try {
await updateProfile(formData);
alert('更新成功');
} catch (err) {
alert('更新失败: ' + err.message);
}
};
if (loading) return <div>加载中...</div>;
if (error) return <div>错误: {error}</div>;
return (
<div>
<h1>用户资料</h1>
<p>用户名: {user?.username}</p>
<p>邮箱: {user?.email}</p>
{/* 更新表单 */}
</div>
);
}Go Client
go
package user
import (
"bytes"
"encoding/json"
"net/http"
"strconv"
)
type Client struct {
BaseURL string
Token string
Client *http.Client
}
type UpdateProfileRequest struct {
Username *string `json:"username,omitempty"`
Email *string `json:"email,omitempty"`
Phone *string `json:"phone,omitempty"`
Avatar *string `json:"avatar,omitempty"`
}
type ChangePasswordRequest struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
ConfirmPassword string `json:"confirm_password"`
}
func NewClient(baseURL, token string) *Client {
return &Client{
BaseURL: baseURL,
Token: token,
Client: &http.Client{},
}
}
func (c *Client) GetProfile() (*UserResponse, error) {
req, err := http.NewRequest("GET", c.BaseURL+"/api/v1/users/profile", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+c.Token)
resp, err := c.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result struct {
Code int `json:"code"`
Data UserResponse `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
return &result.Data, nil
}
func (c *Client) UpdateProfile(req *UpdateProfileRequest) error {
jsonData, err := json.Marshal(req)
if err != nil {
return err
}
request, err := http.NewRequest("PUT", c.BaseURL+"/api/v1/users/profile", bytes.NewBuffer(jsonData))
if err != nil {
return err
}
request.Header.Set("Authorization", "Bearer "+c.Token)
request.Header.Set("Content-Type", "application/json")
resp, err := c.Client.Do(request)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
var errorResp struct {
Message string `json:"message"`
}
json.NewDecoder(resp.Body).Decode(&errorResp)
return fmt.Errorf("更新失败: %s", errorResp.Message)
}
return nil
}
func (c *Client) ChangePassword(req *ChangePasswordRequest) error {
jsonData, err := json.Marshal(req)
if err != nil {
return err
}
request, err := http.NewRequest("PUT", c.BaseURL+"/api/v1/users/password", bytes.NewBuffer(jsonData))
if err != nil {
return err
}
request.Header.Set("Authorization", "Bearer "+c.Token)
request.Header.Set("Content-Type", "application/json")
resp, err := c.Client.Do(request)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
var errorResp struct {
Message string `json:"message"`
}
json.NewDecoder(resp.Body).Decode(&errorResp)
return fmt.Errorf("修改密码失败: %s", errorResp.Message)
}
return nil
}