蜜恋后端
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.
 
 
 
lozonee 966206bb94 Merge repository initial commit 17 hours ago
app Upload milian backend source and documentation 18 hours ago
docs Upload milian backend source and documentation 18 hours ago
sql Upload milian backend source and documentation 18 hours ago
tests Upload milian backend source and documentation 18 hours ago
.dockerignore Upload milian backend source and documentation 18 hours ago
.env.example Upload milian backend source and documentation 18 hours ago
.gitignore Upload milian backend source and documentation 18 hours ago
Dockerfile Upload milian backend source and documentation 18 hours ago
README.md Upload milian backend source and documentation 18 hours ago
UPLOAD-MANIFEST.md Upload milian backend source and documentation 18 hours ago
docker-compose.yml Upload milian backend source and documentation 18 hours ago
requirements.txt Upload milian backend source and documentation 18 hours ago
start_cloud_api.ps1 Upload milian backend source and documentation 18 hours ago

README.md

Dating App 后端(FastAPI)

这是 Dating App Function 阶段的 FastAPI 后端实现,默认使用 MySQL。数据库连接通过 DATABASE_URL 配置。

项目文档:

API 0.6.12 为个人资料新增职业、学历、身高、信仰、吸烟、饮酒、宠物、运动习惯 8 个可选字段,编辑资料接口可写入,Get Me 会返回并新增根据生日计算的 age;匹配成功后双方从喜欢/被喜欢名单移除;评论支持回复(parent_comment_id)和点赞/取消点赞。数据库迁移已完成,正式环境已发布。

运行

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
$env:DATABASE_URL = "mysql+pymysql://用户名:密码@127.0.0.1:3306/dating_app?charset=utf8mb4"
uvicorn app.main:app --reload --port 8001

启动前先在 MySQL 中创建数据库(表会由应用自动创建):

CREATE DATABASE dating_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

已有数据库升级到 API 0.6.4 时,除既有迁移外还需执行非破坏性迁移 sql/migrate_relationship_goal.sql,为 user_profiles 增加 relationship_goal 字段。

升级到 API 0.6.5 前还需执行 sql/migrate_super_like.sql,将已有 swipes.direction 的约束扩展为允许 super_like。先迁移正式数据库,再发布新代码。

升级到 API 0.6.6 前还需执行 sql/migrate_location_county.sql,为 user_profiles 增加可空的 county 区县字段。位置接口现在要求经纬度、城市、区县一并提交。

升级到 API 0.6.7 前需执行 sql/migrate_post_composer.sql,为已有 posts 表增加文字格式、心情和地点字段。历史帖子默认为 plain 且没有心情、地点。API 0.6.8 的公开主页字段、0.6.9 的头像/点赞名单响应、0.6.10 的编辑接口与混合媒体、0.6.11 的匹配列表均不涉及数据库迁移。升级到 0.6.12 前需依次执行 sql/migrate_profile_details.sql(user_profiles 增加 8 个可空资料字段)和 sql/migrate_comment_interactions.sql(post_comments 增加 parent_comment_id,新增 comment_likes 表)。

如果暂时没有 MySQL,可临时设置 DATABASE_URL=sqlite:///./dating_app.db 做本地测试;正式环境按项目方案使用 MySQL。

Windows 本地启动云 MySQL + 阿里云 OSS 时,可运行 .\start_cloud_api.ps1。脚本会在启动时安全询问数据库密码、OSS 凭据和 JWT Secret;这些值只存在于当前 API 进程环境中,不会写入项目文件。正式服务器部署时,应使用服务器的环境变量或密钥管理服务提供同样的配置。

Docker 部署

项目根目录的 Dockerfile 用于生产容器,容器内 FastAPI 固定监听 8001。以下示例将宿主机端口 8011 映射到容器端口 8001:

docker build -t dating-app-api:0.6.12 .
docker rm -f dating-app-api 2>/dev/null || true
docker run -d \
  --name dating-app-api \
  --restart unless-stopped \
  -p 8011:8001 \
  --env-file "${HOME}/.secrets/dating-app.env" \
  dating-app-api:0.6.12

${HOME}/.secrets/dating-app.env 由服务器管理员维护,至少需要提供正式 DATABASE_URL、生产 JWT_SECRET、OSS_ENABLED=true 以及 OSS 配置。这个文件不应提交到 Git 或放入 Jenkins 工作区。当前 Jenkins 已通过只读 Deploy Key 拉取 Gitee 仓库。

日常改代码和发布

正式公网地址为 https://melove.youthome.com.cn,业务接口统一使用 /api/v1/...。当前 Jenkins Job 1 从 Gitee main 分支拉取代码,构建镜像并以 8011:8001 启动 dating-app-api 容器。Jenkins 运行账户读取的正式环境文件为 ${HOME}/.secrets/dating-app.env,其中包含数据库、JWT 和 OSS 配置;不要把这些值写入 Git、Jenkins Shell、提交信息或文档。

每次发布按以下顺序执行:

  1. 本地修改代码,运行 python -m pytest -q。
  2. 接口变化同步更新最新 OpenAPI 文件和对接文档。
  3. 数据库模型变化新增幂等 SQL 迁移,并先在正式 MySQL 执行迁移;Docker 重建不会自动修改已有表。
  4. 提交并推送 Gitee main,在 Jenkins Job 1 点击“立即构建”。
  5. 检查代码拉取、Docker 构建、数据库预检、容器健康检查和控制台日志。
  6. 使用 https://melove.youthome.com.cn/api/v1/... 做公网烟测,重点复测本次改动涉及的接口。

只修改 Python、schema 或业务逻辑时,推送代码并重新构建即可;修改 requirements.txt 或 Dockerfile 后还要检查镜像构建和容器启动日志。发布失败时先查看 Jenkins 控制台日志与容器日志,区分数据库网络、认证、表结构和应用错误,再决定是否回滚或补迁移。

本地 Windows Docker Desktop 也可以直接使用 Compose 启动一个隔离实例。默认使用 Docker 命名卷中的 SQLite 和本地文件存储,不会接触正式云数据库或 OSS:

$docker = "D:\Docker\DockerDesktop\resources\bin\docker.exe"
& $docker compose -p dating-app up -d --build

本地实例地址为 http://127.0.0.1:8011。需要连接正式云 MySQL/OSS 时,通过环境变量覆盖 docker-compose.yml 中的默认值,不要把真实凭据写进该文件。

打开 http://127.0.0.1:8001/docs 查看接口文档。

Postman 或 Apifox 可导入最新的 docs/openapi-0.6.12.json 同步接口定义。

数据库表、字段和表关系见:中文设计文档 或 English database design

已实现接口

  • POST /api/v1/auth/register:使用统一的 email_or_phone 字段、密码、确认密码和必填的四选一 relationship_goal 注册,可直接提交非空 bio,成功后返回 token,不需要验证码
  • POST /api/v1/auth/login:使用统一的 email_or_phone 字段和密码登录
  • POST /api/v1/auth/refresh:使用 refresh token 换取新的 access/refresh token
  • POST /api/v1/auth/logout:撤销 refresh session
  • GET /api/v1/auth/me:应用启动时验证 access token,并返回当前用户、本人帖子、我喜欢的人、喜欢我的人和匹配对象(各最近 20 条)
  • POST /api/v1/auth/oauth:微信/谷歌账号登录或注册占位接口
  • GET/PATCH /api/v1/users/me:读取和更新个人资料
  • GET /api/v1/users/me/interests:读取当前用户的全部兴趣
  • PUT /api/v1/users/me/interests:替换当前用户的兴趣列表,至少 2 个,不设上限
  • POST /api/v1/users/me/video:上传或替换自我介绍视频,最大 100MB;每名用户只保留最新一份
  • POST /api/v1/users/me/image:上传或替换个人头像;每名用户只保留最新一份
  • POST /api/v1/users/me/identity:上传身份证/护照,最大 10MB
  • PUT /api/v1/users/me/location:更新当前位置
  • 位置请求需同时提供 latitude、longitude、city、county;城市用于同城推荐,区县返回在个人和公开资料中
  • GET /api/v1/users/me/posts:分页查看本人帖子
  • GET /api/v1/users/{user_id}、GET /api/v1/users/{user_id}/posts:查看公开用户资料和帖子
  • GET /api/v1/users/me/liked、GET /api/v1/users/me/likes:查看完整的我喜欢的人和喜欢我的人名单,不再分页
  • GET /api/v1/users/me/matches:分页查看匹配对象
  • GET /api/v1/meet:获取尚未滑过的候选用户;向当前用户发出 Super Like 的用户最优先,其余按同城、同国家和匹配度排序
  • POST /api/v1/meet/swipes:pass 左滑、like 右滑、super_like 超级喜欢;双方互相喜欢(含 Super Like)时自动匹配
  • DELETE /api/v1/meet/swipes/{target_user_id}:取消键,撤销保存的左滑、右滑或 Super Like,让该用户重新进入推荐列表
  • DELETE /api/v1/meet/likes/{target_user_id}:取消喜欢并解除对应匹配
  • GET /api/v1/matches:查看完整匹配列表(不分页,旧 limit、offset 参数会被忽略)
  • GET /api/v1/search:按姓名、简介、城市、国家和距离搜索用户,支持城市/国家组合筛选
  • POST /api/v1/explore/posts:发布文字/图片/视频类型帖子,保存可选心情、地点和 plain/markdown 文字格式;图片/视频先创建帖子再上传媒体,音乐暂不支持
  • GET /api/v1/explore/feed:按同城、同国家和匹配度优先获取 Explore 信息流
  • GET/PATCH/DELETE /api/v1/explore/posts/{post_id}:查看、编辑或删除自己的帖子
  • GET/POST/DELETE /api/v1/explore/posts/{post_id}/like:查询点赞者名单、点赞或取消点赞
  • GET/POST /api/v1/explore/posts/{post_id}/comments:查看或发表评论,POST 传 parent_comment_id 可回复;PATCH /api/v1/explore/comments/{comment_id}:编辑自己的评论;POST/DELETE /api/v1/explore/comments/{comment_id}/like:点赞或取消点赞评论
  • DELETE /api/v1/explore/comments/{comment_id}:删除自己的评论
  • POST /api/v1/explore/posts/{post_id}/media:为帖子上传图片或短视频,同一条帖子最多 9 张图片加 1 个视频,可混合
  • GET/DELETE /api/v1/explore/media/{media_id}:读取或删除帖子媒体
  • GET /api/v1/chat/conversations:查看已匹配用户的会话列表
  • POST /api/v1/chat/conversations/{match_id}:为匹配关系创建或获取会话
  • GET/POST /api/v1/chat/conversations/{conversation_id}/messages:查看或发送聊天消息
  • DELETE /api/v1/chat/messages/{message_id}:撤回自己的消息
  • GET /api/v1/feed/questions:获取 AI Feed 问题,可筛选尚未回答的问题
  • PUT/DELETE /api/v1/feed/questions/{question_id}/answer:提交、修改或删除回答
  • GET /api/v1/feed/answers/me:查看当前用户的全部回答

接口测试

Swagger:启动服务后打开 http://127.0.0.1:8001/docs。

FastAPI 自带的 Swagger UI 和 Postman 都可以完成当前接口的手动调试。MVP 阶段不使用 OTP。

注册介绍内容采用两步流程:用户选择文字简介时,在注册 JSON 中提交非空 bio;用户选择视频时,注册后使用 access token 调用视频上传接口。GET /api/v1/auth/me 的 profile.profile_image_url 和 profile.video_url 在对应媒体未上传时为 null,生产环境上传后返回一小时有效的完整 OSS 签名 URL,前端可直接加载而无需再次携带 Token。文字简介与视频互斥:上传视频会清空 bio,之后提交非空 bio 会删除介绍视频。前端只有在 bio 或 video_url 其中一个非空时才应完成注册引导。

认证说明:access token 默认有效 15 分钟,refresh token 默认有效 30 天。客户端安全保存两个 token;应用启动时调用 /api/v1/auth/me,返回 200 就进入首页,否则回到登录页。refresh token 只以哈希形式保存到 user_sessions 表,logout 会撤销对应 session。

自动化测试:

python -m pytest -q

生产环境需要替换 JWT_SECRET,关闭 DEV_RETURN_CODES,并设置 OSS_ENABLED=true 及 .env.example 中的 OSS 环境变量。开启后上传文件会保存到对象存储,数据库只保存对象标识。