Skip to content

用户管理

用户管理模块提供用户资料的查看、修改、密码管理等功能。

接口概览

方法路径描述权限要求
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

请求参数

字段类型必填描述示例
usernamestring用户名"johndoe"
emailstring邮箱地址"john@example.com"
phonestring手机号码"13800138000"
avatarstring头像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_passwordstring旧密码"oldpassword123"
new_passwordstring新密码(至少6位)"newpassword123"
confirm_passwordstring确认新密码"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

查询参数

参数类型必填描述默认值
pageint页码1
page_sizeint每页数量10
searchstring搜索关键词-
statusint用户状态(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

路径参数

参数类型必填描述示例
idint用户ID1

请求参数

字段类型必填描述示例
statusint用户状态(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
}

相关链接

基于 MIT 许可发布