本文档详细描述了 NavDesk 后端 API 的所有接口。
- Base URL:
http://localhost:4100 - API 前缀:
/api - 认证方式: JWT (JSON Web Token)
- Content-Type:
application/json
大部分 API 需要在请求头中携带 JWT token:
Authorization: Bearer <your-jwt-token>登录成功后,服务器会返回 token,客户端需要保存并在后续请求中携带。
POST /api/auth/register请求体:
{
"username": "string",
"password": "string",
"email": "string (optional)"
}响应:
{
"success": true,
"message": "User registered successfully",
"data": {
"id": 1,
"username": "string",
"token": "jwt-token"
}
}POST /api/auth/login请求体:
{
"username": "string",
"password": "string"
}响应:
{
"success": true,
"token": "jwt-token",
"user": {
"id": 1,
"username": "string"
}
}POST /api/auth/refresh请求头:需要携带有效的 JWT token
响应:
{
"success": true,
"token": "new-jwt-token"
}POST /api/auth/logout请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Logged out successfully"
}GET /api/workspaces请求头:需要携带 JWT token
响应:
{
"success": true,
"data": [
{
"id": 1,
"name": "工作",
"description": "工作相关的导航",
"isActive": true,
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}POST /api/workspaces请求头:需要携带 JWT token
请求体:
{
"name": "string",
"description": "string (optional)"
}响应:
{
"success": true,
"data": {
"id": 2,
"name": "string",
"description": "string",
"isActive": false
}
}PUT /api/workspaces/:id请求头:需要携带 JWT token
请求体:
{
"name": "string (optional)",
"description": "string (optional)"
}响应:
{
"success": true,
"data": {
"id": 1,
"name": "string",
"description": "string"
}
}DELETE /api/workspaces/:id请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Workspace deleted successfully"
}POST /api/workspaces/:id/activate请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Workspace activated"
}GET /api/navigation?workspaceId=:id&sortBy=order|clicks|createdAt请求头:需要携带 JWT token
查询参数:
workspaceId: 工作台 ID(可选,默认当前激活的工作台)sortBy: 排序方式(可选,默认order)
响应:
{
"success": true,
"data": [
{
"id": 1,
"title": "Google",
"url": "https://www.google.com",
"icon": "globe",
"description": "搜索引擎",
"clicks": 10,
"isPinned": false,
"order": 0,
"workspaceId": 1
}
]
}POST /api/navigation请求头:需要携带 JWT token
请求体:
{
"title": "string",
"url": "string",
"icon": "string (optional)",
"description": "string (optional)",
"workspaceId": "number"
}响应:
{
"success": true,
"data": {
"id": 2,
"title": "string",
"url": "string",
"icon": "string",
"description": "string",
"clicks": 0,
"isPinned": false,
"order": 1
}
}PUT /api/navigation/:id请求头:需要携带 JWT token
请求体:
{
"title": "string (optional)",
"url": "string (optional)",
"icon": "string (optional)",
"description": "string (optional)"
}响应:
{
"success": true,
"data": {
"id": 1,
"title": "string",
"url": "string"
}
}DELETE /api/navigation/:id请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Navigation item deleted"
}POST /api/navigation/:id/click请求头:需要携带 JWT token
响应:
{
"success": true,
"clicks": 11
}POST /api/navigation/:id/pin请求头:需要携带 JWT token
请求体:
{
"isPinned": true
}响应:
{
"success": true,
"data": {
"id": 1,
"isPinned": true
}
}POST /api/navigation/reorder请求头:需要携带 JWT token
请求体:
{
"items": [
{ "id": 1, "order": 0 },
{ "id": 2, "order": 1 },
{ "id": 3, "order": 2 }
]
}响应:
{
"success": true,
"message": "Items reordered successfully"
}POST /api/navigation/import
Content-Type: multipart/form-data请求头:需要携带 JWT token
请求体:
file: HTML 书签文件workspaceId: 目标工作台 ID
响应:
{
"success": true,
"message": "Imported 50 bookmarks",
"data": {
"imported": 50,
"skipped": 5
}
}POST /api/navigation/check-links请求头:需要携带 JWT token
请求体:
{
"workspaceId": 1
}响应:
{
"success": true,
"data": {
"total": 50,
"valid": 45,
"invalid": 5,
"invalidItems": [
{
"id": 10,
"title": "Broken Link",
"url": "https://example.com/404",
"status": 404
}
]
}
}POST /api/login-strategies请求头:需要携带 JWT token
请求体(表单登录):
{
"navigationItemId": 1,
"type": "form",
"config": {
"usernameSelector": "#username",
"passwordSelector": "#password",
"submitSelector": "#login-button",
"targetUrl": "https://example.com/dashboard"
},
"credentials": {
"username": "user",
"password": "pass"
}
}请求体(API 登录):
{
"navigationItemId": 1,
"type": "api",
"config": {
"endpoint": "https://api.example.com/auth/login",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"bodyTemplate": "{\"username\":\"{{username}}\",\"password\":\"{{password}}\"}",
"tokenPath": "data.token",
"targetUrl": "https://example.com/dashboard"
},
"credentials": {
"username": "user",
"password": "pass"
}
}响应:
{
"success": true,
"data": {
"id": 1,
"navigationItemId": 1,
"type": "form"
}
}GET /api/login-strategies/:itemId请求头:需要携带 JWT token
响应:
{
"success": true,
"data": {
"id": 1,
"type": "form",
"config": {
"usernameSelector": "#username",
"passwordSelector": "#password",
"submitSelector": "#login-button",
"targetUrl": "https://example.com/dashboard"
},
"credentials": {
"username": "user"
}
}
}PUT /api/login-strategies/:id请求头:需要携带 JWT token
请求体:同创建登录策略
响应:
{
"success": true,
"message": "Login strategy updated"
}DELETE /api/login-strategies/:id请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Login strategy deleted"
}GET /api/preferences请求头:需要携带 JWT token
响应:
{
"success": true,
"data": {
"searchEngine": "google",
"backgroundRotation": true,
"rotationInterval": 30,
"currentBackground": "bg-1.jpg",
"customSearchEngines": []
}
}PUT /api/preferences请求头:需要携带 JWT token
请求体:
{
"searchEngine": "string (optional)",
"backgroundRotation": "boolean (optional)",
"rotationInterval": "number (optional)",
"currentBackground": "string (optional)"
}响应:
{
"success": true,
"data": {
"searchEngine": "google",
"backgroundRotation": true
}
}GET /api/wallpaper/list?page=1&limit=20响应:
{
"success": true,
"data": {
"wallpapers": [
{
"name": "bg-1.jpg",
"path": "/assets/backgrounds/bg-1.jpg"
}
],
"total": 40,
"page": 1,
"limit": 20
}
}POST /api/wallpaper/upload
Content-Type: multipart/form-data请求头:需要携带 JWT token
请求体:
file: 图片文件(JPG/PNG,最大 10MB)
响应:
{
"success": true,
"data": {
"filename": "custom-bg-1.jpg",
"path": "/assets/backgrounds/custom-bg-1.jpg"
}
}GET /api/music/playlist请求头:需要携带 JWT token
响应:
{
"success": true,
"data": [
{
"id": 1,
"title": "Song Title",
"artist": "Artist Name",
"url": "https://example.com/music.mp3",
"duration": 180
}
]
}POST /api/music/add请求头:需要携带 JWT token
请求体:
{
"title": "string",
"artist": "string (optional)",
"url": "string"
}响应:
{
"success": true,
"data": {
"id": 2,
"title": "string",
"url": "string"
}
}DELETE /api/music/:id请求头:需要携带 JWT token
响应:
{
"success": true,
"message": "Music deleted"
}GET /api/system/info响应:
{
"success": true,
"data": {
"version": "1.0.0",
"nodeVersion": "v16.0.0",
"platform": "win32",
"uptime": 3600
}
}GET /api/favicon?url=https://www.google.com查询参数:
url: 目标网站 URL
响应:
{
"success": true,
"data": {
"favicon": "https://www.google.com/favicon.ico"
}
}所有 API 在发生错误时返回统一格式:
{
"success": false,
"error": "Error message",
"statusCode": 400
}| 状态码 | 说明 |
|---|---|
| 400 | 请求参数错误 |
| 401 | 未授权(token 无效或过期) |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
import axios from 'axios';
const api = axios.create({
baseURL: 'http://localhost:4100/api',
headers: {
'Content-Type': 'application/json'
}
});
// 设置 token
api.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// 登录
const login = async (username, password) => {
const response = await api.post('/auth/login', { username, password });
localStorage.setItem('token', response.data.token);
return response.data;
};
// 获取导航项
const getNavigationItems = async (workspaceId) => {
const response = await api.get('/navigation', {
params: { workspaceId }
});
return response.data.data;
};# 登录
curl -X POST http://localhost:4100/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}'
# 获取导航项
curl -X GET http://localhost:4100/api/navigation \
-H "Authorization: Bearer <your-token>"
# 创建导航项
curl -X POST http://localhost:4100/api/navigation \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" \
-d '{
"title": "Google",
"url": "https://www.google.com",
"workspaceId": 1
}'- 初始版本发布
- 完整的认证系统
- 工作台管理
- 导航项 CRUD
- 登录策略
- 用户偏好
- 壁纸管理
- 音乐播放器
如有问题或建议,请提交 Issue。