蜜恋后端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

31 KiB

Dating App API 完整接口说明

API version: 0.6.12 面向前端与后端开发者的接口参考文档。 0.6.12 已完成正式数据库迁移并发布,通过公网接口验证。

1. 通用说明

1.1 Base URL

{{base_url}}

本地测试地址:

http://127.0.0.1:8001

生产地址由部署环境提供,客户端通过配置项设置 base_url,不要在代码中写死具体域名。

1.2 请求格式

  • JSON 接口请求头:Content-Type: application/json
  • 文件上传接口请求格式:multipart/form-data
  • 除注册、登录、OAuth、健康检查外,接口都需要登录。
  • 登录接口使用:Authorization: Bearer <access_token>
  • access_token 默认有效 15 分钟,refresh_token 默认有效 30 天。

1.3 通用错误

参数错误:422 Unprocessable Entity

{
  "detail": [
    {
      "loc": ["body", "field_name"],
      "msg": "说明文字",
      "type": "validation_error"
    }
  ]
}

未登录或 token 无效:401

{"detail": "需要登录"}

账号被停用或没有权限:403

资源不存在:404

2. 数据结构

2.1 注册请求 RegisterRequest

必填字段:

字段 类型 说明
email_or_phone string 邮箱或手机号,二选一但使用同一个字段,3-320 字符
password string 密码,8-128 字符
confirm_password string 确认密码,8-128 字符,必须和 password 完全一致
relationship_goal string 必填单选:serious_relationship、casual_dates、new_friends 或 marriage

可选字段:full_name(最多 120)、gender(最多 30)、birth_date(YYYY-MM-DD)、city(最多 120)、country(最多 120)、bio(去除首尾空格后 1-2000 字符)、interests(兴趣数组)。

用户的介绍内容在 bio 和介绍视频中二选一。选择文字简介时在注册 JSON 中提交非空 bio;选择视频时可以省略 bio,注册成功取得 access token 后调用 /api/v1/users/me/video。因为注册请求是 JSON,不能直接携带视频文件。

confirm_password 只用于注册时校验,不保存到数据库,也不会出现在任何响应中。

注册响应继续只返回 token。前端随后调用 GET /api/v1/auth/me:未上传头像或视频时,profile.profile_image_url 或 profile.video_url 为 null;上传后,生产环境返回可直接加载的一小时 OSS 签名 URL。两者互斥:上传视频会清空已有 bio,之后通过个人资料接口提交非空 bio 会删除介绍视频。前端应在 bio 或 video_url 其中一个非空时才完成注册引导。

2.2 用户 UserResponse

{
  "id": 1,
  "email_or_phone": "user@example.com",
  "status": "active",
  "profile": {
    "full_name": "Test User",
    "gender": "female",
    "birth_date": "2000-01-01",
    "city": "Shanghai",
    "county": "Huangpu",
    "country": "China",
    "relationship_goal": "serious_relationship",
    "bio": "I like traveling.",
    "profile_image_url": "https://<oss-host>/melove/users/1/avatar.jpg?<signature>",
    "video_url": null,
    "interests": ["Photography", "Movies"]
  },
  "posts": [],
  "liked_users": [],
  "liked_by_users": [],
  "matches": [],
  "liked_users_count": 0,
  "liked_by_users_count": 0,
  "matches_count": 0,
  "created_at": "2026-09-01T10:00:00"
}

GET /api/v1/auth/me 和 GET /api/v1/users/me 会在这四个数组中分别返回最近 20 条本人帖子、我喜欢的人、喜欢我的人和匹配对象。liked_users_count、liked_by_users_count、matches_count 是对应三类关系的总数,不受 20 条列表上限影响;喜欢包含 like 和 super_like,均只统计当前有效用户。完整或分页数据使用 4.9-4.14 的独立接口。注册、登录和资料更新响应不包含这些总数字段。

2.3 TokenResponse

{
  "access_token": "<access_token>",
  "refresh_token": "<refresh_token>",
  "token_type": "bearer",
  "user": { "...": "UserResponse" }
}

注册接口是例外,只返回 token,不返回 user:

{
  "access_token": "<access_token>",
  "refresh_token": "<refresh_token>",
  "token_type": "bearer"
}

2.4 公开用户 DiscoveryUserResponse

{
  "id": 2,
  "full_name": "Bob",
  "gender": "male",
  "birth_date": "1998-05-20",
  "city": "Shanghai",
  "county": "Huangpu",
  "country": "China",
  "relationship_goal": "serious_relationship",
  "bio": "Likes hiking",
  "profile_image_url": "https://<oss-host>/melove/users/2/avatar.jpg?<signature>",
  "video_url": "https://<oss-host>/melove/users/2/intro.mp4?<signature>",
  "distance_km": 1.24,
  "compatibility_percentage": 85,
  "media": [
    {"id": 10, "media_type": "profile_image", "url": "https://<oss-host>/melove/users/2/avatar.jpg?<signature>"}
  ]
}

公开用户响应中的 profile_image_url 是头像地址,video_url 是介绍视频地址;media[] 是同一用户公开资料媒体的明细列表,按 media_type 区分头像和介绍视频,不是用户发布的帖子。公开主页接口额外返回 interests 和最近 20 条公开 posts,方便前端用一次请求渲染主页。邮箱/手机号、账号状态、喜欢列表和匹配记录不会返回;超过 20 条帖子时调用 GET /api/v1/users/{user_id}/posts 分页获取。

2.5 兴趣、位置、帖子和聊天结构

兴趣响应:{"interests": ["Photography", "Dogs"]}

位置响应:{"latitude": 31.2304, "longitude": 121.4737, "city": "上海市", "county": "黄浦区", "updated_at": "2026-09-01T10:00:00"}

滑动响应:{"direction": "like", "matched": true, "match_id": 15}。未匹配时 match_id 为 null。

帖子响应字段:id、content、post_type、content_format、feeling、location、author、like_count、comment_count、liked_by_me、liked_by_users、media、created_at。location 是发帖时选定地点的快照,与作者当前资料城市和位置分开保存。

帖子和评论的 author 均包含 id、full_name、profile_image_url、city、country、compatibility_percentage。未上传头像时 profile_image_url 为 null;生产环境返回一小时有效的 OSS 签名 URL,可直接展示,过期后重新请求。所有 PostResponse(Explore、详情、个人资料内的帖子和用户帖子列表)均包含 liked_by_users: [{"id": 2, "full_name": "Reader"}];无点赞时为 [],按最近点赞在前排序,只包含 active 用户,like_count 等于名单长度。姓名可能为 null;名单不含联系方式或完整用户资料。

聊天消息字段:id、conversation_id、sender_id、content、message_type、is_deleted、created_at。撤回后 content 为 null,is_deleted 为 true。

3. Authentication 认证接口

3.1 健康检查

GET {{base_url}}/health
认证:不需要。
前端发送:无 body。
成功:200

{"status": "ok"}

3.2 注册

POST {{base_url}}/api/v1/auth/register
认证:不需要。
请求体:application/json

{
  "email_or_phone": "user@example.com",
  "password": "password123",
  "confirm_password": "password123",
  "relationship_goal": "serious_relationship",
  "full_name": "Test User",
  "gender": "female",
  "birth_date": "2000-01-01",
  "city": "Shanghai",
  "country": "China",
  "bio": "I like traveling.",
  "interests": ["Photography", "Movies"]
}

手机号注册只需把 email_or_phone 改为手机号。成功:201,返回 2.3 中的 token-only 结构。
错误:409 邮箱/手机号已注册;422 缺少必填字段、relationship_goal 值无效、两次密码不一致或兴趣少于 2 个。 MVP 不使用 OTP,注册后账号直接为 active。

3.3 登录

POST {{base_url}}/api/v1/auth/login
认证:不需要。
请求体:

{
  "email_or_phone": "user@example.com",
  "password": "password123"
}

成功:200,返回 TokenResponse。错误:401 账号或密码错误;403 账号已停用;422 参数错误。

3.4 OAuth 登录/注册占位接口

POST {{base_url}}/api/v1/auth/oauth
认证:不需要。
请求体:

{
  "provider": "google",
  "provider_user_id": "google-user-id-123",
  "email": "user@example.com",
  "full_name": "OAuth User"
}

provider 只能是 wechat 或 google;email、full_name 可选。成功:200,返回 TokenResponse。错误:422 参数错误。

3.5 刷新 token

POST {{base_url}}/api/v1/auth/refresh
认证:不需要 Bearer token,但必须提交有效 refresh token。
请求体:

{"refresh_token": "<refresh_token>"}

成功:200,返回新的 TokenResponse;旧 refresh token 会失效。错误:401 refresh token 无效、已过期或已撤销;422 参数错误。

3.6 退出登录

POST {{base_url}}/api/v1/auth/logout
认证:不需要 Bearer token。
请求体:

{"refresh_token": "<refresh_token>"}

成功:200

{"message": "已退出登录"}

3.7 获取当前用户

GET {{base_url}}/api/v1/auth/me
认证:需要 Bearer token。
前端发送:无 body。
成功:200,返回 UserResponse。启动 App 时可调用此接口判断 token 是否仍然有效。

3.8 获取当前用户(兼容地址)

GET {{base_url}}/api/v1/users/me
认证:需要 Bearer token。
功能和 3.7 完全相同,返回 UserResponse。

4. User Profile 用户资料和媒体

4.1 修改个人资料

PATCH {{base_url}}/api/v1/users/me
认证:需要 Bearer token。
请求体可只提交需要修改的字段:

{
  "full_name": "New Name",
  "gender": "female",
  "birth_date": "2000-01-01",
  "city": "Beijing",
  "country": "China",
  "relationship_goal": "marriage",
  "bio": "Updated bio",
  "occupation": "Creative Director at Studio Drift",
  "education": "NYU Gallatin School",
  "height_cm": 175,
  "beliefs": "spiritual_agnostic",
  "smoking": "non_smoker",
  "drinking": "socially",
  "pets": "golden_retriever",
  "exercise": "active_4x_week",
  "interests": ["Travel", "Music"]
}

新增可选资料字段:occupation、education(各最多 120 字符)、height_cm(整数,100-250)、beliefs(最多 120)、smoking、drinking(各最多 50)、pets(最多 120)、exercise(最多 50)。传 null 可清空对应字段。GET /api/v1/auth/me 会返回这些字段,并额外返回根据 birth_date 计算的 age。

成功:200,返回更新后的 UserResponse。兴趣如提交则至少 2 个;错误:422 字段格式或兴趣不符合要求。

4.2 获取我的兴趣

GET {{base_url}}/api/v1/users/me/interests
认证:需要 Bearer token。
成功:200

{"interests": ["Photography", "Dogs", "My custom interest"]}

4.3 替换我的兴趣

PUT {{base_url}}/api/v1/users/me/interests
认证:需要 Bearer token。
请求体:

{"interests": ["Photography", "Dogs", "My custom interest"]}

至少 2 项,不限制最多数量;Other 不需要特殊字段,直接把自定义文字作为数组项。成功:200,返回兴趣数组。错误:422 少于 2 项、空字符串或单项超过 120 字符。

4.4 更新位置

PUT {{base_url}}/api/v1/users/me/location
认证:需要 Bearer token。
请求体:

{"latitude": 31.2304, "longitude": 121.4737, "city": "上海市", "county": "黄浦区"}

纬度范围 -90 到 90,经度范围 -180 到 180;city 和 county 必填,去除首尾空格后须为 1-120 字符。城市写入用户资料并参与同城推荐;区县单独保存在 county,不等于国家字段 country。成功:200,返回四个位置字段及 updated_at;GET /api/v1/auth/me 和公开用户资料也返回 profile.county 或 county。错误:422 缺字段、空城市/区县或坐标超出范围。

4.5 上传自我介绍视频

POST {{base_url}}/api/v1/users/me/video
认证:需要 Bearer token。
请求格式:multipart/form-data,字段名 video,支持 video/mp4、video/quicktime、video/webm,最大 100 MB。
每名用户只保留最新一份介绍视频;再次上传成功后,旧视频记录和旧文件会被替换。若新文件存储失败,原视频保持不变。 成功:200

{"id": 11, "media_type": "intro_video", "review_status": "pending"}

错误:413 文件过大;415 文件类型不支持;422 未上传文件。

4.6 上传头像

POST {{base_url}}/api/v1/users/me/image
认证:需要 Bearer token。
请求格式:multipart/form-data,字段名 image,支持 JPG、PNG、WebP,最大 10 MB。
每名用户只保留最新一张头像;再次上传成功后,旧头像记录和旧文件会被替换。若新文件存储失败,原头像保持不变。 成功返回媒体 id、类型和审核状态;错误:413、415、422。

4.7 上传身份证/护照

POST {{base_url}}/api/v1/users/me/identity
认证:需要 Bearer token。
请求格式:multipart/form-data,字段名 document,支持 JPG、PNG、PDF,最大 10 MB。
成功返回媒体 id、类型和审核状态;该文件只有本人可访问。错误:413、415、422。

4.8 获取用户媒体文件

GET {{base_url}}/api/v1/media/{media_id}
认证:需要 Bearer token。
路径参数:media_id 为媒体 id。
成功:200,返回文件二进制内容;公开头像/视频可被其他 active 用户读取,身份证/护照只有本人可读取。错误:403 无权限;404 文件不存在。

Meet、Search、Match 和个人资料响应中的 profile_image_url、video_url、media[].url 在生产 OSS 环境为一小时有效的完整签名 URL,前端图片/视频组件可直接使用,不需要再次附加 Bearer Token。URL 过期后重新请求相应的资料列表即可取得新 URL。身份证/护照不会出现在这些公开 URL 字段中。

4.9 获取本人帖子

GET {{base_url}}/api/v1/users/me/posts?limit=20&offset=0 认证:需要 Bearer token。limit 为 1-50,offset 为 0-5000。成功返回 PostResponse 数组,新帖在前。

4.10 获取公开用户资料

GET {{base_url}}/api/v1/users/{user_id} 认证:需要 Bearer token。成功返回目标用户的 PublicUserProfileResponse,包括公开资料、interests 和最近 20 条 posts;不会返回邮箱/手机号、账号状态、喜欢列表或匹配记录。目标不存在或已停用返回 404。

4.11 获取公开用户帖子

GET {{base_url}}/api/v1/users/{user_id}/posts?limit=20&offset=0 认证:需要 Bearer token。成功返回目标用户的 PostResponse 数组,新帖在前;目标不存在或已停用返回 404。

4.12 获取我喜欢的人

GET {{base_url}}/api/v1/users/me/liked 认证:需要 Bearer token。成功返回当前用户主动右滑喜欢的完整 DiscoveryUserResponse 数组,最近操作在前;已经匹配成功的用户会被排除。该接口不分页;旧请求中的 limit、offset 参数会被忽略。

4.13 获取喜欢我的人

GET {{base_url}}/api/v1/users/me/likes 认证:需要 Bearer token。成功返回主动喜欢当前用户的完整 DiscoveryUserResponse 数组,最近操作在前;已经匹配成功的用户会被排除。该接口不分页;旧请求中的 limit、offset 参数会被忽略。

4.14 获取我的匹配对象

GET {{base_url}}/api/v1/users/me/matches 认证:需要 Bearer token。成功返回完整的 MatchResponse 数组,与 /api/v1/matches 数据一致,便于个人主页分区加载。该接口不分页,旧的 limit、offset 参数会被忽略。

5.1 获取推荐用户

GET {{base_url}}/api/v1/meet?limit=20
认证:需要 Bearer token。
查询参数:limit 可选,1-50,默认 20。
成功:200,返回 DiscoveryUserResponse 数组;只返回 active 用户,且不会重复返回已经滑过的用户。向当前用户发出有效 super_like 的用户最优先;其余按同城、同国家、其他国家排序,同组内按 compatibility_percentage 从高到低排序。

5.2 左滑、右滑或超级喜欢

POST {{base_url}}/api/v1/meet/swipes
认证:需要 Bearer token。
请求体:

{"target_user_id": 2, "direction": "like"}

direction 可为 pass(左滑)、like(右滑)或 super_like(超级喜欢)。super_like 会让发起者在目标用户的 Meet 列表中优先出现,直到发起者撤销或改为其他滑动;目标用户已经滑过发起者时不会再次显示。成功:200,返回 SwipeResponse;双方的操作均为 like 或 super_like 时,matched=true 并生成 match_id。错误:400 不能操作自己;404 目标用户不存在;422 参数错误。

5.3 取消喜欢

DELETE {{base_url}}/api/v1/meet/likes/{target_user_id}
认证:需要 Bearer token。
成功:200 {"message":"已取消喜欢"},并解除对应匹配。兼容旧客户端,可取消 like 或 super_like;取消键请统一使用 5.4 的撤销滑动接口。错误:404 没有可取消的喜欢记录。

5.4 取消键:撤销左滑、右滑或超级喜欢

DELETE {{base_url}}/api/v1/meet/swipes/{target_user_id} 认证:需要 Bearer token。删除本人对目标用户保存的 pass、like 或 super_like 记录,使目标用户可以再次出现在自己的 Meet 推荐列表;撤销 super_like 也会立即取消在目标用户列表中的优先展示。如果撤销的是已形成匹配的喜欢,同时解除对应匹配。成功:200,例如 {"message":"已撤销滑动","previous_direction":"super_like"}。错误:404 没有可撤销的滑动记录。

5.5 获取匹配列表

GET {{base_url}}/api/v1/matches 认证:需要 Bearer token。
该接口不分页,返回全部有效匹配,最近的在前;旧的 limit、offset 参数会被忽略。成功:200,返回 MatchResponse 数组,每项包含 id、matched_at 和对方公开资料 user。返回条数等于 GET /api/v1/auth/me 中的 matches_count。

5.6 搜索用户

GET {{base_url}}/api/v1/search
认证:需要 Bearer token。
查询参数:

参数 类型 说明
q string 可选,搜索姓名、简介、城市、国家,最多 200 字符
city string 可选,按城市筛选,可与 country 同时提供
country string 可选,按国家筛选,可与 city 同时提供
latitude number 可选,必须和 longitude 同时提供
longitude number 可选,必须和 latitude 同时提供
max_distance_km number 可选,最大 500;不传坐标时使用自己的位置
limit integer 可选,1-50,默认 20

成功:200,返回 DiscoveryUserResponse 数组,包含 country 和 compatibility_percentage。错误:422 坐标只提供一个,或距离筛选缺少坐标/自己的位置。

6. Explore 动态

6.1 创建帖子

POST {{base_url}}/api/v1/explore/posts
认证:需要 Bearer token。
请求体:

{
  "content": "Feeling **happy** and *relaxed* today",
  "post_type": "text",
  "content_format": "markdown",
  "feeling": "happy",
  "location": {"name": "Blue Bottle Coffee, Soho NYC", "latitude": 40.723, "longitude": -73.998}
}

post_type 可选 text、image、video,默认 text。content 最多 5000 字符;文字帖至少包含非空文字、心情或地点之一。feeling 可选,提交 1-50 字符的心情代码或标签,例如 happy。location 可选,name 必填且为 1-255 字符,经纬度可以都不传或同时传,范围分别为 -90..90 和 -180..180。地点是帖子内容,不会修改用户资料或当前位置;选定地点及提交的坐标会显示给能查看帖子的用户。

content_format 为 plain(默认)或 markdown。前端粗体按钮把选中文字写成 **bold**,斜体按钮写成 *italic*,并提交 content_format: "markdown";后端原样保存 Markdown 源文本,不返回 HTML。前端显示时按该字段渲染并对生成的 HTML 做安全处理。旧帖子按 plain 返回。音乐字段暂未开放。

图片或视频帖先用此接口创建,取得 id,再调用 6.5 的媒体上传接口;单帖最多 9 张图片加 1 个视频,可以混合使用;同时含图片和视频时 post_type 为 mixed。成功:201,返回包含新字段的 PostResponse。

6.2 获取 Explore 信息流

GET {{base_url}}/api/v1/explore/feed?limit=20&offset=0
认证:需要 Bearer token。
参数:limit 1-50,默认 20;新排序使用 offset 分页。旧参数 before_id 保留为按时间 ID 截断的兼容模式,不能与非零 offset 同时使用。成功:200,每条帖子包含 content_format、feeling 和 location;按作者同城、同国家、其他国家分组,同组按匹配度排序,最后以新帖优先打破并列。

6.3 获取帖子详情

GET {{base_url}}/api/v1/explore/posts/{post_id}
认证:需要 Bearer token。
成功:200,返回 PostResponse;错误:404 帖子不存在或作者不可用。

6.4 删除帖子

DELETE {{base_url}}/api/v1/explore/posts/{post_id}
认证:需要 Bearer token。只能删除自己的帖子。成功:200 {"message":"帖子已删除"};错误:403 无权限;404 不存在。

6.5 上传帖子媒体

POST {{base_url}}/api/v1/explore/posts/{post_id}/media?position=0
认证:需要 Bearer token,且必须是帖子作者。
请求格式:multipart/form-data,字段名 media;position 可选,0-8。支持 JPG、PNG、WebP、MP4、MOV、WebM。
每条帖子最多 9 张图片和 1 个视频,可同时存在于同一帖子;同时含图片和视频时 post_type 为 mixed。成功:201,返回 PostMediaResponse(id、media_type、mime_type、size_bytes、position、url)。生产 OSS 环境的 url 是一小时有效的完整签名 URL,可直接加载且不需要 Bearer Token。错误:403、404、409 类型/数量冲突、413、415。

6.6 获取帖子媒体

GET {{base_url}}/api/v1/explore/media/{media_id}
认证:需要 Bearer token。
成功:200,返回文件二进制内容;错误:404 帖子或媒体不存在。

6.7 点赞帖子

POST {{base_url}}/api/v1/explore/posts/{post_id}/like
认证:需要 Bearer token。
成功:200,返回精简的 PostLikeResponse,不再返回完整帖子正文、作者和媒体:

{
  "message": "like successful",
  "like_count": 1,
  "liked_by_me": true,
  "liked_by_users": [{"id": 2, "full_name": "Reader"}]
}

重复点赞不会增加数量;前端用返回的数量、状态和名单更新已有帖子。错误:401 未登录;404 帖子不存在。

单独查询点赞者

GET {{base_url}}/api/v1/explore/posts/{post_id}/like 认证:需要 Bearer token,无请求体或分页参数。成功:200,直接返回 [{"id": 2, "full_name": "Reader"}],无点赞时为 [];只含 active 用户,最近点赞在前。错误:401 未登录;404 帖子不存在。

6.8 取消帖子点赞

DELETE {{base_url}}/api/v1/explore/posts/{post_id}/like
认证:需要 Bearer token。
成功:200,返回精简的 PostUnlikeResponse —— {"message":"unlike successful","like_count":0,"liked_by_me":false,"liked_by_users":[...]},不再返回完整帖子。重复请求保持未点赞状态。

6.9 获取评论

GET {{base_url}}/api/v1/explore/posts/{post_id}/comments
认证:需要 Bearer token。
成功:200,返回 CommentResponse 数组;每条评论的 author.profile_image_url 为头像地址,无头像时为 null,并包含 parent_comment_id、reply_count、like_count、liked_by_me。评论以扁平列表返回,前端按 parent_comment_id 组织回复。错误:404 帖子不存在。

6.10 发表评论

POST {{base_url}}/api/v1/explore/posts/{post_id}/comments
认证:需要 Bearer token。
请求体:

{"content": "Looks great!"}

内容 1-2000 字符且不能全是空格。回复某条评论时额外传 parent_comment_id:

{"content": "我同意", "parent_comment_id": 12}

成功:201,返回 CommentResponse,包含 author.profile_image_url;错误:404 帖子或父评论不存在;422 内容无效。

6.11 删除评论

DELETE {{base_url}}/api/v1/explore/comments/{comment_id}
认证:需要 Bearer token,只能删除自己的评论。成功:200 {"message":"评论已删除"};错误:403、404。

6.12 编辑帖子

PATCH {{base_url}}/api/v1/explore/posts/{post_id} 认证:需要 Bearer token,且只能是帖子作者。 请求体(只提交需要修改的字段):

{"content": "更新后的文字", "content_format": "markdown", "feeling": "happy", "location": {"name": "新地点"}}

可编辑字段:content(最多 5000 字)、content_format(plain/markdown)、feeling(1-50 字符)、location。未提交的字段保持不变;提交 null 可清空 feeling 或 location。文字帖子必须保留文字、心情或地点至少一项。成功:200,返回更新后的完整 PostResponse。错误:403 非作者;404 帖子不存在;422 字段无效。

6.13 编辑评论

PATCH {{base_url}}/api/v1/explore/comments/{comment_id} 认证:需要 Bearer token,且只能是评论作者。 请求体:

{"content": "更新后的评论"}

content 必须为 1-2000 字符且不能全是空格。成功:200,返回更新后的 CommentResponse。错误:403 非作者;404 评论不存在;422 内容无效。

6.14 给评论点赞

POST {{base_url}}/api/v1/explore/comments/{comment_id}/like 认证:需要 Bearer token,无请求体。 成功:200

{"message": "like successful", "like_count": 1, "liked_by_me": true}

重复点赞不会增加数量。错误:401 未登录;404 评论不存在或帖子作者已停用。

6.15 取消评论点赞

DELETE {{base_url}}/api/v1/explore/comments/{comment_id}/like 认证:需要 Bearer token,无请求体。 成功:200

{"message": "unlike successful", "like_count": 0, "liked_by_me": false}

重复请求保持未点赞状态。错误:401 未登录;404 评论不存在或帖子作者已停用。

7. Feed 问答

7.1 获取 Feed 问题

GET {{base_url}}/api/v1/feed/questions?unanswered_only=false
认证:需要 Bearer token。
unanswered_only 可选,默认 false;设为 true 只返回当前用户尚未回答的问题。成功:200,返回问题数组,每项包含 id、code、中英文问题、answer_type(boolean 或 text)、当前答案和回答时间。

7.2 获取我的 Feed 回答

GET {{base_url}}/api/v1/feed/answers/me
认证:需要 Bearer token。
成功:200,返回当前用户已回答的问题数组。

7.3 新增或修改 Feed 回答

PUT {{base_url}}/api/v1/feed/questions/{question_id}/answer
认证:需要 Bearer token。
请求体示例(布尔题):

{"answer": true}

文字题:

{"answer": "Coffee and a walk"}

成功:200

{"question_id": 1, "answer": true, "answered_at": "2026-09-01T10:00:00"}

错误:404 问题不存在/已停用;422 答案类型和题目类型不匹配或内容为空。

7.4 删除 Feed 回答

DELETE {{base_url}}/api/v1/feed/questions/{question_id}/answer
认证:需要 Bearer token。
成功:200 {"message":"回答已删除"};错误:404 回答不存在。

8. Chat 聊天

聊天仅对已经匹配的双方开放。

8.1 获取会话列表

GET {{base_url}}/api/v1/chat/conversations
认证:需要 Bearer token。
成功:200,返回会话数组,每项包含 id、match_id、other_user、last_message、created_at、updated_at。

8.2 创建或获取会话

POST {{base_url}}/api/v1/chat/conversations/{match_id}
认证:需要 Bearer token,必须是该匹配的其中一方。
前端发送:无 body。
成功:201,返回 ConversationResponse;如果会话已存在,返回已有会话。错误:404 匹配不存在、不是匹配双方或对方不可用。

8.3 获取聊天消息

GET {{base_url}}/api/v1/chat/conversations/{conversation_id}/messages?limit=50&before_id=100
认证:需要 Bearer token,必须是会话双方之一。
参数:limit 1-100,默认 50;before_id 可选,用于分页。成功:200,返回 ChatMessageResponse 数组,按时间正序返回。

8.4 发送聊天消息

POST {{base_url}}/api/v1/chat/conversations/{conversation_id}/messages
认证:需要 Bearer token,必须是会话双方之一。
请求体:

{
  "content": "Hello, nice to meet you!",
  "message_type": "text"
}

content 1-5000 字符,message_type 目前只能是 text。成功:201,返回 ChatMessageResponse;错误:404 会话不存在或无权访问;422 内容为空或格式错误。

8.5 撤回聊天消息

DELETE {{base_url}}/api/v1/chat/messages/{message_id}
认证:需要 Bearer token,只能撤回自己发送的消息。成功:200,返回撤回后的 ChatMessageResponse(content=null、is_deleted=true);错误:403 不是自己的消息;404 消息不存在或无权访问。

9. 前端注册和登录流程

  1. 注册页面显示邮箱/手机号、密码、确认密码和可选资料。
  2. 前端先检查 password === confirm_password,然后将两个密码字段一起提交给注册接口。
  3. 注册成功后保存返回的 access_token 和 refresh_token。确认密码不保存。
  4. 不调用 OTP 接口;当前版本没有 /api/v1/auth/request-code 和 /api/v1/auth/verify。
  5. App 启动时调用 /api/v1/auth/me。返回 200 进入首页;返回 401 清除 token 并回到登录页。
  6. access token 过期时,用 refresh token 调 /api/v1/auth/refresh,保存新 token 对;刷新失败则重新登录。

10. Postman 导入和测试

  1. 打开 Postman,点击 Import -> Files。
  2. 导入 docs/openapi-0.6.12.json,选择导入为 Postman Collection。
  3. 在 Collection Variables 中设置:base_url = http://127.0.0.1:8001。
  4. 先发送 POST /api/v1/auth/register 或 POST /api/v1/auth/login。
  5. 复制响应中的 access_token,在需要登录的请求中选择 Authorization -> Bearer Token 粘贴。
  6. 测试文件上传时选择 Body -> form-data,文件字段名必须使用本文对应的字段名。

建议最小测试顺序:health -> register -> login -> auth/me -> update profile -> meet -> swipe -> matches -> explore -> feed questions -> chat。

11. 规范文件

完整机器可读接口定义:docs/openapi-0.6.12.json。如本文和 OpenAPI 出现不一致,以当前后端 /openapi.json 和最新版 OpenAPI 文件为准。