Skip to content

基础示例

本节提供 API 使用的基础示例,帮助您快速上手。

准备工作

1. 获取认证 Token

首先需要通过登录获取 JWT token:

bash
curl -X POST http://localhost:8080/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin@example.com",
    "password": "password123"
  }'

2. 设置请求头

在后续请求中携带 token:

bash
# 设置 token 变量
TOKEN="your-jwt-token-here"

# 设置通用请求头
HEADERS="-H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json'"

用户管理示例

获取当前用户信息

bash
curl -X GET http://localhost:8080/api/v1/users/profile \
  -H "Authorization: Bearer $TOKEN"

更新用户资料

bash
curl -X PUT http://localhost:8080/api/v1/users/profile \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "newusername",
    "phone": "13900139000"
  }'

修改密码

bash
curl -X PUT http://localhost:8080/api/v1/users/password \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "old_password": "oldpassword123",
    "new_password": "newpassword123",
    "confirm_password": "newpassword123"
  }'

员工管理示例

创建员工

bash
curl -X POST http://localhost:8080/api/v1/admin/employees \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 2,
    "employee_no": "EMP001",
    "first_name": "张",
    "last_name": "三",
    "email": "zhangsan@company.com",
    "phone": "13800138000",
    "department_id": 1,
    "position": "软件工程师",
    "hire_date": "2024-01-01",
    "status": 1
  }'

获取员工列表

bash
curl -X GET "http://localhost:8080/api/v1/admin/employees?page=1&page_size=10" \
  -H "Authorization: Bearer $TOKEN"

搜索员工

bash
curl -X GET "http://localhost:8080/api/v1/admin/employees?search=张三" \
  -H "Authorization: Bearer $TOKEN"

待办事项示例

创建待办事项

bash
curl -X POST http://localhost:8080/api/v1/todos \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "完成项目文档",
    "description": "编写API文档和用户手册",
    "priority": 3,
    "due_date": "2024-01-15T23:59:59Z",
    "assignee_id": 2,
    "tags": ["文档", "项目"]
  }'

获取我的待办事项

bash
curl -X GET http://localhost:8080/api/v1/todos/my \
  -H "Authorization: Bearer $TOKEN"

开始任务

bash
curl -X PATCH http://localhost:8080/api/v1/todos/1/start \
  -H "Authorization: Bearer $TOKEN"

完成任务

bash
curl -X PATCH http://localhost:8080/api/v1/todos/1/complete \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "completion_note": "文档已全部完成"
  }'

文件上传示例

上传单个文件

bash
curl -X POST http://localhost:8080/api/v1/oss/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@/path/to/document.pdf" \
  -F "folder=documents/2024/01" \
  -F "description=项目文档"

获取文件信息

bash
curl -X GET "http://localhost:8080/api/v1/oss/file-info?file_id=file-id-here" \
  -H "Authorization: Bearer $TOKEN"

获取文件列表

bash
curl -X GET "http://localhost:8080/api/v1/oss/files?page=1&page_size=20" \
  -H "Authorization: Bearer $TOKEN"

公司管理示例

创建公司

bash
curl -X POST http://localhost:8080/api/v1/admin/companies \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "源丰科技有限公司",
    "description": "专注于企业信息化服务",
    "industry": "软件开发",
    "address": "北京市朝阳区xxx街道xxx号",
    "phone": "010-12345678",
    "email": "contact@yuanfeng.com",
    "website": "https://www.yuanfeng.com",
    "status": 1
  }'

获取公司详情

bash
curl -X GET http://localhost:8080/api/v1/companies/1

获取公司员工列表

bash
curl -X GET "http://localhost:8080/api/v1/companies/1/employees?page=1&page_size=10" \
  -H "Authorization: Bearer $TOKEN"

JavaScript 示例

基础 API 客户端

javascript
class APIClient {
  constructor(baseURL, token) {
    this.baseURL = baseURL;
    this.token = token;
  }

  async request(method, path, data = null, params = null) {
    const url = new URL(path, this.baseURL);

    if (params) {
      Object.keys(params).forEach(key => {
        if (params[key] !== null && params[key] !== undefined) {
          url.searchParams.append(key, params[key]);
        }
      });
    }

    const options = {
      method,
      headers: {
        'Authorization': `Bearer ${this.token}`,
        'Content-Type': 'application/json'
      }
    };

    if (data) {
      options.body = JSON.stringify(data);
    }

    const response = await fetch(url.toString(), options);
    return response.json();
  }

  // 用户管理
  async getProfile() {
    return this.request('GET', '/api/v1/users/profile');
  }

  async updateProfile(data) {
    return this.request('PUT', '/api/v1/users/profile', data);
  }

  // 员工管理
  async getEmployees(params) {
    return this.request('GET', '/api/v1/admin/employees', null, params);
  }

  async createEmployee(data) {
    return this.request('POST', '/api/v1/admin/employees', data);
  }

  // 待办事项
  async getMyTodos(params) {
    return this.request('GET', '/api/v1/todos/my', null, params);
  }

  async createTodo(data) {
    return this.request('POST', '/api/v1/todos', data);
  }

  async startTodo(todoId) {
    return this.request('PATCH', `/api/v1/todos/${todoId}/start`);
  }

  async completeTodo(todoId, note) {
    return this.request('PATCH', `/api/v1/todos/${todoId}/complete`, {
      completion_note: note
    });
  }
}

// 使用示例
const client = new APIClient('http://localhost:8080', 'your-jwt-token');

// 获取用户资料
client.getProfile().then(response => {
  console.log('用户资料:', response.data);
});

// 创建待办事项
client.createTodo({
  title: '学习API',
  description: '学习如何使用系统API',
  priority: 2,
  due_date: '2024-01-20T23:59:59Z'
}).then(response => {
  console.log('创建成功:', response.data);
});

// 获取我的待办事项
client.getMyTodos({ status: 'pending' }).then(response => {
  console.log('待办事项:', response.data.todos);
});

React Hook 示例

javascript
import { useState, useEffect } from 'react';
import axios from 'axios';

const useAPI = (baseURL, token) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const api = axios.create({
    baseURL,
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  });

  const request = async (config) => {
    setLoading(true);
    setError(null);
    try {
      const response = await api(config);
      return response.data;
    } catch (err) {
      setError(err.response?.data?.message || err.message);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  return { request, loading, error };
};

// 待办事项 Hook
const useTodos = () => {
  const { request, loading, error } = useAPI('http://localhost:8080', 'your-token');
  const [todos, setTodos] = useState([]);

  const fetchTodos = async (params = {}) => {
    try {
      const response = await request({
        method: 'GET',
        url: '/api/v1/todos/my',
        params
      });
      setTodos(response.data.todos);
      return response;
    } catch (err) {
      console.error('获取待办事项失败:', err);
    }
  };

  const createTodo = async (todoData) => {
    try {
      const response = await request({
        method: 'POST',
        url: '/api/v1/todos',
        data: todoData
      });
      await fetchTodos(); // 刷新列表
      return response;
    } catch (err) {
      console.error('创建待办事项失败:', err);
    }
  };

  const completeTodo = async (todoId, note) => {
    try {
      const response = await request({
        method: 'PATCH',
        url: `/api/v1/todos/${todoId}/complete`,
        data: { completion_note: note }
      });
      await fetchTodos(); // 刷新列表
      return response;
    } catch (err) {
      console.error('完成待办事项失败:', err);
    }
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return {
    todos,
    loading,
    error,
    fetchTodos,
    createTodo,
    completeTodo
  };
};

// 使用示例
function TodoApp() {
  const { todos, loading, error, createTodo, completeTodo } = useTodos();

  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误: {error}</div>;

  const handleCreate = async () => {
    await createTodo({
      title: '新任务',
      description: '任务描述',
      priority: 2
    });
  };

  const handleComplete = async (todoId) => {
    await completeTodo(todoId, '任务已完成');
  };

  return (
    <div>
      <h1>我的待办事项</h1>
      <button onClick={handleCreate}>创建新任务</button>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            <span>{todo.title}</span>
            <button onClick={() => handleComplete(todo.id)}>
              完成
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Python 示例

python
import requests
import json
from typing import Optional, Dict, Any, List

class YuanfengAPI:
    def __init__(self, base_url: str, token: str):
        self.base_url = base_url
        self.token = token
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }

    def _request(self, method: str, endpoint: str,
                 data: Optional[Dict] = None,
                 params: Optional[Dict] = None) -> Dict[str, Any]:
        """发送 HTTP 请求"""
        url = f'{self.base_url}{endpoint}'

        response = requests.request(
            method=method,
            url=url,
            headers=self.headers,
            json=data,
            params=params
        )

        response.raise_for_status()
        return response.json()

    # 用户相关
    def get_profile(self) -> Dict[str, Any]:
        """获取用户资料"""
        return self._request('GET', '/api/v1/users/profile')

    def update_profile(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """更新用户资料"""
        return self._request('PUT', '/api/v1/users/profile', data)

    # 员工相关
    def get_employees(self, page: int = 1, page_size: int = 10,
                     search: Optional[str] = None) -> Dict[str, Any]:
        """获取员工列表"""
        params = {'page': page, 'page_size': page_size}
        if search:
            params['search'] = search
        return self._request('GET', '/api/v1/admin/employees', params=params)

    def create_employee(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """创建员工"""
        return self._request('POST', '/api/v1/admin/employees', data)

    # 待办事项相关
    def get_my_todos(self, status: Optional[str] = None) -> Dict[str, Any]:
        """获取我的待办事项"""
        params = {}
        if status:
            params['status'] = status
        return self._request('GET', '/api/v1/todos/my', params=params)

    def create_todo(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """创建待办事项"""
        return self._request('POST', '/api/v1/todos', data)

    def start_todo(self, todo_id: int) -> Dict[str, Any]:
        """开始待办事项"""
        return self._request('PATCH', f'/api/v1/todos/{todo_id}/start')

    def complete_todo(self, todo_id: int, note: str = '') -> Dict[str, Any]:
        """完成待办事项"""
        return self._request('PATCH', f'/api/v1/todos/{todo_id}/complete',
                           {'completion_note': note})

# 使用示例
def main():
    # 初始化 API 客户端
    api = YuanfengAPI('http://localhost:8080', 'your-jwt-token')

    try:
        # 获取用户资料
        profile = api.get_profile()
        print(f"用户信息: {profile['data']['username']}")

        # 创建待办事项
        todo = api.create_todo({
            'title': 'Python API 测试',
            'description': '测试 Python API 客户端',
            'priority': 2
        })
        print(f"创建待办事项成功: {todo['data']['id']}")

        # 开始任务
        api.start_todo(todo['data']['id'])
        print("任务已开始")

        # 完成任务
        api.complete_todo(todo['data']['id'], "测试完成")
        print("任务已完成")

        # 获取我的待办事项
        todos = api.get_my_todos()
        print(f"当前待办事项数量: {len(todos['data']['todos'])}")

    except requests.exceptions.RequestException as e:
        print(f"API 请求失败: {e}")

if __name__ == '__main__':
    main()

常见问题

1. 如何处理认证失败?

当收到 401 错误时,需要重新登录获取新的 token:

javascript
try {
  const response = await api.get('/api/v1/users/profile');
} catch (error) {
  if (error.response?.status === 401) {
    // token 过期,重新登录
    await login();
    // 重试请求
    const response = await api.get('/api/v1/users/profile');
  }
}

2. 如何处理分页?

大多数列表接口都支持分页,使用 pagepage_size 参数:

javascript
async function getAllEmployees() {
  let allEmployees = [];
  let page = 1;
  let hasMore = true;

  while (hasMore) {
    const response = await api.get('/api/v1/admin/employees', {
      params: { page, page_size: 100 }
    });

    allEmployees = allEmployees.concat(response.data.employees);
    hasMore = page < response.data.pagination.pages;
    page++;
  }

  return allEmployees;
}

3. 如何处理大文件上传?

对于大文件,建议使用分片上传:

javascript
async function uploadLargeFile(file, chunkSize = 1024 * 1024) {
  const totalChunks = Math.ceil(file.size / chunkSize);
  const uploadId = generateUploadId(); // 生成上传ID

  for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(start + chunkSize, file.size);
    const chunk = file.slice(start, end);

    await api.post('/api/v1/oss/upload-chunk', {
      upload_id: uploadId,
      chunk_number: i + 1,
      total_chunks: totalChunks,
      data: chunk
    });
  }

  // 完成上传
  return api.post('/api/v1/oss/complete-upload', {
    upload_id: uploadId,
    filename: file.name
  });
}

下一步

基于 MIT 许可发布