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

1257 lines
32 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: 哈尔滨美食地图 API
version: 0.2.0
description: |
统一约定:
- 除 `/healthz` 外,所有 `/api/**` 接口都必须携带 `X-API-Key`
- 管理端 `/api/admin/**`(除登录外)还必须携带 `Authorization: Bearer <admin_token>`
- 用户端 `/api/user/**`(需要登录的接口)必须携带 `Authorization: Bearer <user_token>`
servers:
- url: http://localhost:8080
tags:
- name: Health
description: 健康检查
- name: Captcha
description: 验证码
- name: AdminAuth
description: 管理员登录与身份
- name: Settings
description: 系统设置CORS
- name: APIKeys
description: APIKey 管理
- name: Merchant
description: 商家入驻与审核
- name: Categories
description: 分类管理
- name: Stores
description: 店铺管理与搜索/热榜
- name: Reviews
description: 评论管理与用户发评
- name: Users
description: 用户注册/登录/信息
- name: Rankings
description: 排行(管理端)
- name: Upload
description: 上传(管理端)
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
BearerAuth:
type: http
scheme: bearer
schemas:
RespBase:
type: object
properties:
code:
type: integer
description: 0 表示成功;非 0 通常等于 HTTP 状态码
message:
type: string
data: {}
meta: {}
required: [code, message]
PaginationMeta:
type: object
properties:
page: { type: integer, example: 1 }
page_size: { type: integer, example: 20 }
total: { type: integer, example: 123 }
total_page: { type: integer, example: 7 }
AdminUser:
type: object
properties:
id: { type: integer, example: 1 }
username: { type: string, example: admin }
role: { type: string, example: admin }
enabled: { type: boolean, example: true }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
User:
type: object
properties:
id: { type: integer, example: 7 }
username: { type: string, example: tiedanzi888 }
status: { type: string, example: active }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
Category:
type: object
properties:
id: { type: integer, example: 1 }
name: { type: string, example: 烧烤 }
icon_url: { type: string, example: "http://localhost:8080/static/upload/2025/12/xx.png" }
sort_order: { type: integer, example: 10 }
enabled: { type: boolean, example: true }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
StoreImage:
type: object
properties:
id: { type: integer }
url: { type: string, example: "http://localhost:8080/static/upload/2025/12/xx.jpg" }
sort_order: { type: integer, example: 0 }
SignatureDish:
type: object
properties:
id: { type: integer }
name: { type: string, example: 锅包肉 }
description: { type: string, example: 必点 }
image_url: { type: string, example: "http://localhost:8080/static/upload/2025/12/dish.jpg" }
sort_order: { type: integer, example: 0 }
Store:
type: object
properties:
id: { type: integer, example: 1 }
name: { type: string, example: 示例店铺 }
category_id: { type: integer, example: 1 }
category:
$ref: "#/components/schemas/Category"
address: { type: string, example: 哈尔滨市道里区xxx路 }
open_hours: { type: string, example: "10:00-22:00" }
phone: { type: string, example: "13000000000" }
cover_url: { type: string, example: "http://localhost:8080/static/upload/2025/12/cover.jpg" }
description: { type: string, example: 店铺描述 }
status: { type: string, example: active }
images:
type: array
items: { $ref: "#/components/schemas/StoreImage" }
dishes:
type: array
items: { $ref: "#/components/schemas/SignatureDish" }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
Review:
type: object
properties:
id: { type: integer, example: 1 }
store_id: { type: integer, example: 1 }
store:
$ref: "#/components/schemas/Store"
user_id: { type: integer, nullable: true }
user_name: { type: string, example: tiedanzi888 }
rating: { type: integer, example: 5 }
content: { type: string, example: 太好吃了 }
image_urls:
type: array
items: { type: string }
recommend_dishes:
type: array
items:
type: object
additionalProperties: true
status: { type: string, example: pending }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
MerchantApplication:
type: object
properties:
id: { type: integer }
store_name: { type: string }
category_id: { type: integer }
address: { type: string }
open_hours: { type: string }
phone: { type: string }
cover_url: { type: string }
image_urls:
type: array
items: { type: string }
description: { type: string }
contact_name: { type: string }
contact_phone: { type: string }
status: { type: string, example: pending }
reject_reason: { type: string }
reviewed_at: { type: string, format: date-time, nullable: true }
reviewer_id: { type: integer, nullable: true }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
APIKeyItem:
type: object
properties:
id: { type: integer }
name: { type: string }
prefix: { type: string }
status: { type: string, example: active }
last_used_at: { type: string, format: date-time, nullable: true }
revoked_at: { type: string, format: date-time, nullable: true }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
# ---- Requests ----
CaptchaNewData:
type: object
properties:
captcha_id: { type: string, example: c180df303849ea6dc75c670c4f1062b0 }
svg: { type: string, description: SVG 字符串(可直接渲染) }
required: [captcha_id, svg]
AdminLoginReq:
type: object
required: [username, password, captcha_id, captcha_code]
properties:
username: { type: string, example: admin }
password: { type: string, example: admin123456 }
captcha_id: { type: string }
captcha_code: { type: string, example: XHSXY }
UserRegisterReq:
type: object
required: [username, password, captcha_id, captcha_code]
properties:
username: { type: string, example: tiedanzi888 }
password: { type: string, example: malegebi }
captcha_id: { type: string }
captcha_code: { type: string, example: XHSXY }
UserLoginReq:
type: object
required: [username, password, captcha_id, captcha_code]
properties:
username: { type: string }
password: { type: string }
captcha_id: { type: string }
captcha_code: { type: string }
CORSUpdateReq:
type: object
required: [origins]
properties:
origins:
type: array
items: { type: string }
example: ["http://localhost:5173", "https://admin.example.com"]
APIKeyCreateReq:
type: object
required: [name]
properties:
name: { type: string, example: 前端管理后台 }
CategoryUpsertReq:
type: object
required: [name]
properties:
name: { type: string, example: 烧烤 }
icon_url: { type: string }
sort_order: { type: integer, example: 10 }
enabled: { type: boolean, example: true }
StoreUpsertReq:
type: object
required: [name, category_id, address]
properties:
name: { type: string }
category_id: { type: integer }
address: { type: string }
open_hours: { type: string }
phone: { type: string }
cover_url: { type: string }
description: { type: string }
status: { type: string, description: active|inactive }
images:
type: array
items:
type: object
required: [url]
properties:
url: { type: string }
sort_order: { type: integer }
dishes:
type: array
items:
type: object
required: [name]
properties:
name: { type: string }
description: { type: string }
image_url: { type: string }
sort_order: { type: integer }
StatusReq:
type: object
required: [status]
properties:
status: { type: string }
MerchantApplyReq:
type: object
required: [store_name, category_id, address, contact_name, contact_phone]
properties:
store_name: { type: string }
category_id: { type: integer }
address: { type: string }
open_hours: { type: string }
phone: { type: string }
cover_url: { type: string }
image_urls:
type: array
items: { type: string }
description: { type: string }
contact_name: { type: string }
contact_phone: { type: string }
MerchantReviewReq:
type: object
required: [action]
properties:
action: { type: string, enum: [approve, reject] }
reject_reason: { type: string }
ReviewCreateReq:
type: object
required: [rating]
properties:
rating: { type: integer, minimum: 1, maximum: 5, example: 5 }
content: { type: string, example: 太好吃了 }
image_urls:
type: array
items: { type: string }
recommend_dishes:
type: array
items:
type: object
additionalProperties: true
AdminCreateReq:
type: object
required: [username, password]
properties:
username: { type: string }
password: { type: string }
enabled: { type: boolean, default: true }
AdminUpdatePasswordReq:
type: object
required: [password]
properties:
password: { type: string }
AdminUpdateEnabledReq:
type: object
required: [enabled]
properties:
enabled: { type: boolean }
parameters:
Page:
in: query
name: page
schema: { type: integer, default: 1 }
PageSize:
in: query
name: page_size
schema: { type: integer, default: 20 }
paths:
/healthz:
get:
tags: [Health]
summary: 健康检查
responses:
"200":
description: ok
/api/captcha/new:
get:
tags: [Captcha]
summary: 获取验证码SVG
description: |
- `captcha_id` 有效期 5 分钟
- 校验成功后删除(一次性使用)
security:
- ApiKeyAuth: []
responses:
"200":
description: ok
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/RespBase"
- type: object
properties:
data: { $ref: "#/components/schemas/CaptchaNewData" }
examples:
ok:
value:
code: 0
message: ok
data:
captcha_id: c180df303849ea6dc75c670c4f1062b0
svg: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><svg ...>XHSXY</svg>"
/api/user/register:
post:
tags: [Users]
summary: 用户注册(需要验证码)
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UserRegisterReq" }
responses:
"200":
description: ok
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/RespBase"
- type: object
properties:
data:
type: object
properties:
token: { type: string }
user: { $ref: "#/components/schemas/User" }
"409":
description: username already exists
/api/user/login:
post:
tags: [Users]
summary: 用户登录(需要验证码)
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/UserLoginReq" }
responses:
"200":
description: ok
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/RespBase"
- type: object
properties:
data:
type: object
properties:
token: { type: string }
user:
type: object
properties:
id: { type: integer }
username: { type: string }
/api/user/me:
get:
tags: [Users]
summary: 当前用户信息
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
"200":
description: ok
/api/user/reviews:
get:
tags: [Reviews]
summary: 我的评论列表(用户端)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/user/upload:
post:
tags: [Upload]
summary: 用户上传图片(用于评论等)
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [file]
properties:
file:
type: string
format: binary
responses:
"200":
description: ok
/api/user/douyin/login:
post:
tags: [Users]
summary: 抖音登录(预留)
security:
- ApiKeyAuth: []
responses:
"501":
description: not implemented
/api/user/stores/{id}/reviews:
post:
tags: [Reviews]
summary: 用户提交评论(进入待审核)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/ReviewCreateReq" }
responses:
"200":
description: ok
/api/user/stores/{id}/like:
post:
tags: [Stores]
summary: 用户点赞/取消点赞toggle
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/merchant/apply:
post:
tags: [Merchant]
summary: 商家入驻提交
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/MerchantApplyReq" }
responses:
"200":
description: ok
/api/categories:
get:
tags: [Categories]
summary: 分类列表(公开,只返回 enabled=true
security:
- ApiKeyAuth: []
responses:
"200":
description: ok
/api/stores:
get:
tags: [Stores]
summary: 店铺列表(公开,只返回 active
security:
- ApiKeyAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- in: query
name: category_id
schema: { type: integer }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/stores/{id}:
get:
tags: [Stores]
summary: 店铺详情(公开,只返回 active
security:
- ApiKeyAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/stores/{id}/reviews:
get:
tags: [Reviews]
summary: 店铺评论列表(公开,只返回 approved
security:
- ApiKeyAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/rankings/stores:
get:
tags: [Rankings]
summary: 店铺排行(公开,只返回 active
security:
- ApiKeyAuth: []
parameters:
- in: query
name: by
schema:
type: string
enum: [hotness, likes, search, reviews]
default: hotness
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/stores/search:
get:
tags: [Stores]
summary: 店铺搜索(会累积热度)
security:
- ApiKeyAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/stores/hot:
get:
tags: [Stores]
summary: 店铺热榜
security:
- ApiKeyAuth: []
parameters:
- in: query
name: by
schema:
type: string
enum: [hotness, likes, search, reviews]
default: hotness
- in: query
name: limit
schema: { type: integer, default: 20 }
responses:
"200":
description: ok
/api/admin/login:
post:
tags: [AdminAuth]
summary: 管理员登录
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/AdminLoginReq" }
responses:
"200":
description: ok
/api/admin/me:
get:
tags: [AdminAuth]
summary: 当前管理员信息
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
"200":
description: ok
/api/admin/dashboard/overview:
get:
tags: [AdminAuth]
summary: 后台概览(统计)
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
"200":
description: ok
/api/admin/settings/cors:
get:
tags: [Settings]
summary: 获取 CORS origins
security:
- ApiKeyAuth: []
- BearerAuth: []
responses:
"200":
description: ok
put:
tags: [Settings]
summary: 更新 CORS origins
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CORSUpdateReq" }
responses:
"200":
description: ok
/api/admin/apikeys:
get:
tags: [APIKeys]
summary: APIKey 列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
post:
tags: [APIKeys]
summary: 创建 APIKey只会返回一次明文 key
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/APIKeyCreateReq" }
responses:
"200":
description: ok
/api/admin/apikeys/{id}/revoke:
patch:
tags: [APIKeys]
summary: 撤销 APIKey
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/admin/merchant/applications:
get:
tags: [Merchant]
summary: 商家入驻申请列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: status
schema: { type: string, enum: [pending, approved, rejected] }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/admin/merchant/applications/{id}/review:
patch:
tags: [Merchant]
summary: 审核商家入驻approve/reject
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/MerchantReviewReq" }
responses:
"200":
description: ok
/api/admin/categories:
get:
tags: [Categories]
summary: 分类列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
post:
tags: [Categories]
summary: 新增分类
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CategoryUpsertReq" }
responses:
"200":
description: ok
/api/admin/categories/{id}:
put:
tags: [Categories]
summary: 编辑分类
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/CategoryUpsertReq" }
responses:
"200":
description: ok
delete:
tags: [Categories]
summary: 删除分类(软删)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/admin/stores:
get:
tags: [Stores]
summary: 店铺列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- in: query
name: status
schema: { type: string, enum: [active, inactive] }
- in: query
name: category_id
schema: { type: integer }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
post:
tags: [Stores]
summary: 新增店铺
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/StoreUpsertReq" }
responses:
"200":
description: ok
/api/admin/stores/{id}:
get:
tags: [Stores]
summary: 店铺详情(含图片/招牌菜)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
put:
tags: [Stores]
summary: 编辑店铺
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/StoreUpsertReq" }
responses:
"200":
description: ok
delete:
tags: [Stores]
summary: 删除店铺(软删)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/admin/stores/{id}/status:
patch:
tags: [Stores]
summary: 上下架店铺
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/StatusReq" }
examples:
active: { value: { status: active } }
inactive: { value: { status: inactive } }
responses:
"200":
description: ok
/api/admin/reviews:
get:
tags: [Reviews]
summary: 评论列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: status
schema: { type: string, enum: [pending, approved, blocked] }
- in: query
name: store_id
schema: { type: integer }
- in: query
name: user_id
schema: { type: integer }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/admin/reviews/{id}/status:
patch:
tags: [Reviews]
summary: 修改评论状态(审核)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/StatusReq" }
examples:
approve: { value: { status: approved } }
block: { value: { status: blocked } }
responses:
"200":
description: ok
/api/admin/reviews/{id}:
delete:
tags: [Reviews]
summary: 删除评论(软删)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/admin/users:
get:
tags: [Users]
summary: 用户列表(管理端)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- in: query
name: status
schema: { type: string, enum: [active, disabled] }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/admin/users/{id}:
get:
tags: [Users]
summary: 用户详情(管理端)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
responses:
"200":
description: ok
/api/admin/users/{id}/status:
patch:
tags: [Users]
summary: 修改用户状态(启用/禁用)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/StatusReq" }
examples:
disable: { value: { status: disabled } }
active: { value: { status: active } }
responses:
"200":
description: ok
/api/admin/admins:
get:
tags: [AdminAuth]
summary: 管理员列表
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: keyword
schema: { type: string }
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
post:
tags: [AdminAuth]
summary: 创建管理员
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/AdminCreateReq" }
responses:
"200":
description: ok
/api/admin/admins/{id}/password:
patch:
tags: [AdminAuth]
summary: 重置管理员密码
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/AdminUpdatePasswordReq" }
responses:
"200":
description: ok
/api/admin/admins/{id}/enabled:
patch:
tags: [AdminAuth]
summary: 启用/禁用管理员
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: path
name: id
required: true
schema: { type: integer }
requestBody:
required: true
content:
application/json:
schema: { $ref: "#/components/schemas/AdminUpdateEnabledReq" }
responses:
"200":
description: ok
/api/admin/rankings/stores:
get:
tags: [Rankings]
summary: 店铺排行(管理端)
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: by
schema:
type: string
enum: [hotness, likes, search, reviews]
default: hotness
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/PageSize"
responses:
"200":
description: ok
/api/admin/rankings/stores/recalc:
post:
tags: [Rankings]
summary: 重算综合分score
security:
- ApiKeyAuth: []
- BearerAuth: []
parameters:
- in: query
name: limit
schema: { type: integer, default: 5000 }
responses:
"200":
description: ok
/api/admin/upload:
post:
tags: [Upload]
summary: 上传图片multipart/form-data
security:
- ApiKeyAuth: []
- BearerAuth: []
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [file]
properties:
file:
type: string
format: binary
responses:
"200":
description: ok