9.1 KiB
API 使用说明(中文)
Base URL
- 后端:
http://localhost:8080 - Swagger(推荐看这个,字段更全):
http://localhost:8081(加载docs/openapi.yaml)
统一响应结构
后端所有接口统一返回:
{ "code": 0, "message": "ok", "data": {}, "meta": {} }
code=0表示成功code!=0表示失败(通常等于 HTTP 状态码)
必须携带的请求头
本项目所有 /api/** 接口都需要 APIKey:
X-API-Key: <你的apikey>
管理端接口(/api/admin/**,除登录外)还需要管理员 JWT:
Authorization: Bearer <admin_token>
用户端需要登录的接口(/api/user/** 的部分接口)需要用户 JWT:
Authorization: Bearer <user_token>
默认开发环境(可在 backend/.env 修改):
API_KEY=dev-api-key-change-me
PowerShell / curl 提示(Windows)
- Windows PowerShell 里的
curl可能是Invoke-WebRequest的别名;建议用curl.exe或Invoke-RestMethod。
验证码(Captcha)
用户注册/登录 必须先获取验证码,再把 captcha_id + captcha_code 带到接口里。
获取验证码(SVG)
GET /api/captcha/new
curl.exe "http://localhost:8080/api/captcha/new" -H "X-API-Key: dev-api-key-change-me"
返回示例:
{
"code": 0,
"message": "ok",
"data": {
"captcha_id": "c180df303849ea6dc75c670c4f1062b0",
"svg": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg ...>XHSXY</svg>"
}
}
说明:
captcha_id有效期 5 分钟- 校验成功后删除(一次性使用)
svg是字符串:前端可用v-html渲染,或转成data:image/svg+xml显示在<img>
PowerShell 测试(从 SVG 中提取验证码文本,仅用于本地调试):
$apiKey='dev-api-key-change-me'
$cap = Invoke-RestMethod -Method Get -Uri http://localhost:8080/api/captcha/new -Headers @{"X-API-Key"=$apiKey}
$id = $cap.data.captcha_id
$svg = $cap.data.svg
$code = [regex]::Match($svg,'>([0-9A-Z]{5})<').Groups[1].Value
用户侧(Web/小程序)
用户注册
POST /api/user/register
请求示例:
curl.exe -X POST "http://localhost:8080/api/user/register" `
-H "X-API-Key: dev-api-key-change-me" `
-H "Content-Type: application/json" `
-d "{\"username\":\"u1\",\"password\":\"pass123456\",\"captcha_id\":\"$CAPTCHA_ID\",\"captcha_code\":\"$CAPTCHA_CODE\"}"
请求结构体(JSON):
{
"username": "u1",
"password": "pass123456",
"captcha_id": "xxxx",
"captcha_code": "ABCDE"
}
返回:
data.token:用户 JWTdata.user:用户信息
用户登录
POST /api/user/login
请求结构体(JSON):
{
"username": "u1",
"password": "pass123456",
"captcha_id": "xxxx",
"captcha_code": "ABCDE"
}
返回:
data.token:用户 JWTdata.user:用户信息(简化字段)
当前用户
GET /api/user/me(需要 Authorization: Bearer <user_token>)
我的评论记录
GET /api/user/reviews?page=1&page_size=20(需要 Authorization: Bearer <user_token>)
提交评论(进入待审核)
POST /api/user/stores/:id/reviews
图片上传说明:
- 评论的
image_urls需要先上传拿到图片 URL - 用户上传接口:
POST /api/user/upload(multipart/form-data,字段名file)
请求结构体(JSON):
{
"rating": 5,
"content": "太好吃了",
"image_urls": ["http://localhost:8080/static/upload/2025/12/xx.jpg"],
"recommend_dishes": [
{ "name": "锅包肉", "image_url": "http://...", "like": true }
]
}
返回示例:
{ "code": 0, "message": "ok", "data": { "id": 1, "status": "pending" } }
点赞店铺(toggle)
POST /api/user/stores/:id/like
返回示例:
{ "code": 0, "message": "ok", "data": { "liked": true } }
店铺搜索 / 热榜(公开)
- 搜索:
GET /api/stores/search?keyword=锅包肉&page=1&page_size=20(会累积热度) - 热榜:
GET /api/stores/hot?by=hotness&limit=20
公共读取接口(前端可直接调用)
- 分类列表:
GET /api/categories(只返回 enabled=true) - 店铺列表:
GET /api/stores?page=1&page_size=20&category_id=1&keyword=xx(只返回 active) - 店铺详情:
GET /api/stores/:id(只返回 active) - 店铺评论:
GET /api/stores/:id/reviews?page=1&page_size=20(只返回 approved) - 店铺排行:
GET /api/rankings/stores?by=hotness&page=1&page_size=20
商家入驻(公开提交)
POST /api/merchant/apply
请求结构体(JSON):
{
"store_name": "示例店铺",
"category_id": 1,
"address": "哈尔滨市xx路",
"open_hours": "10:00-22:00",
"phone": "13000000000",
"cover_url": "",
"image_urls": [],
"description": "商家描述",
"contact_name": "张三",
"contact_phone": "13000000000"
}
返回示例:
{ "code": 0, "message": "ok", "data": { "id": 1, "status": "pending" } }
管理后台(Admin)
管理员登录
POST /api/admin/login
说明:
- 管理员登录也需要验证码(防止暴力破解)
- 先调用
GET /api/captcha/new获取captcha_id+svg,再提交到登录接口
curl.exe -X POST "http://localhost:8080/api/admin/login" `
-H "X-API-Key: dev-api-key-change-me" `
-H "Content-Type: application/json" `
-d "{\"username\":\"admin\",\"password\":\"admin123456\",\"captcha_id\":\"$CAPTCHA_ID\",\"captcha_code\":\"$CAPTCHA_CODE\"}"
返回:
data.token:管理员 JWT
CORS 跨域设置(可视化配置)
- 获取:
GET /api/admin/settings/cors - 保存:
PUT /api/admin/settings/cors
保存 payload:
{ "origins": ["http://localhost:5173", "https://admin.example.com"] }
上传图片
POST /api/admin/upload(multipart/form-data,字段名 file)
curl.exe -X POST "http://localhost:8080/api/admin/upload" `
-H "X-API-Key: dev-api-key-change-me" `
-H "Authorization: Bearer <admin_token>" `
-F "file=@./test.jpg"
返回:
data.url:可访问 URL(例如http://localhost:8080/static/upload/2025/12/xx.jpg)
用户上传图片(用于评论)
POST /api/user/upload(multipart/form-data,字段名 file,需要用户 JWT)
curl.exe -X POST "http://localhost:8080/api/user/upload" `
-H "X-API-Key: dev-api-key-change-me" `
-H "Authorization: Bearer <user_token>" `
-F "file=@./test.jpg"
分类管理
- 列表:
GET /api/admin/categories?page=1&page_size=20&keyword=xxx - 新增:
POST /api/admin/categories - 编辑:
PUT /api/admin/categories/:id - 删除:
DELETE /api/admin/categories/:id
新增/编辑 payload:
{ "name": "烧烤", "icon_url": "", "sort_order": 10, "enabled": true }
店铺管理
- 列表:
GET /api/admin/stores?page=1&page_size=20&keyword=xx&status=active&category_id=1 - 详情:
GET /api/admin/stores/:id - 新增:
POST /api/admin/stores - 编辑:
PUT /api/admin/stores/:id - 上下架:
PATCH /api/admin/stores/:id/status({"status":"active|inactive"}) - 删除:
DELETE /api/admin/stores/:id
新增/编辑 payload:
{
"name": "示例店铺",
"category_id": 1,
"address": "哈尔滨市xx路",
"open_hours": "10:00-22:00",
"phone": "13000000000",
"cover_url": "http://localhost:8080/static/upload/2025/12/cover.jpg",
"description": "描述",
"status": "active",
"images": [{ "url": "http://...", "sort_order": 0 }],
"dishes": [{ "name": "锅包肉", "description": "必点", "image_url": "http://...", "sort_order": 0 }]
}
评论管理(审核/删除)
- 列表:
GET /api/admin/reviews?page=1&page_size=20&status=pending&store_id=1&user_id=2 - 审核:
PATCH /api/admin/reviews/:id/status({"status":"pending|approved|blocked"}) - 删除:
DELETE /api/admin/reviews/:id
商家入驻审核
- 列表:
GET /api/admin/merchant/applications?status=pending&page=1&page_size=20 - 审核:
PATCH /api/admin/merchant/applications/:id/review
审核 payload:
- 通过:
{ "action": "approve" } - 拒绝:
{ "action": "reject", "reject_reason": "资料不完整" }
排行管理
- 查看排行:
GET /api/admin/rankings/stores?by=hotness&page=1&page_size=20by=hotness|likes|search|reviews
- 重算综合分:
POST /api/admin/rankings/stores/recalc
APIKey 管理
- 列表:
GET /api/admin/apikeys?page=1&page_size=20 - 创建:
POST /api/admin/apikeys(创建成功会返回一次性明文data.key,请立即保存) - 撤销:
PATCH /api/admin/apikeys/:id/revoke
用户管理(管理端)
- 列表:
GET /api/admin/users?keyword=xx&status=active&page=1&page_size=20 - 详情:
GET /api/admin/users/:id - 启用/禁用:
PATCH /api/admin/users/:id/status({"status":"active|disabled"})
管理员管理
- 列表:
GET /api/admin/admins?keyword=xx&page=1&page_size=20 - 新增:
POST /api/admin/admins - 重置密码:
PATCH /api/admin/admins/:id/password - 启用/禁用:
PATCH /api/admin/admins/:id/enabled
新增 payload:
{ "username": "ops", "password": "StrongPass123", "enabled": true }
OpenAPI
- 文件:
docs/openapi.yaml - Swagger UI:
http://localhost:8081