Files
0451meishi/docs/API.md
2026-01-15 11:37:22 +08:00

9.1 KiB
Raw Blame History

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.exeInvoke-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:用户 JWT
  • data.user:用户信息

用户登录

POST /api/user/login

请求结构体JSON

{
  "username": "u1",
  "password": "pass123456",
  "captcha_id": "xxxx",
  "captcha_code": "ABCDE"
}

返回:

  • data.token:用户 JWT
  • data.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/uploadmultipart/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/uploadmultipart/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/uploadmultipart/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=20
    • by=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 UIhttp://localhost:8081