Files
hejiu/docs/酒友圈接口文档.md
T
cg fabbb167cf feat(circle): 添加酒友圈社交模块
- 新增酒友圈、圈子详情、发布动态、好友列表、活动创建等页面配置
- 添加酒友圈相关API接口,包括动态、评论、好友、活动等功能
- 实现模拟数据用于前端开发和测试
- 创建评论项、空状态、活动卡片、动态卡片、好友项等组件
- 编写酒友圈模块详细的接口文档,定义数据结构和业务规则
2026-07-20 22:53:04 +08:00

16 KiB
Raw Blame History

干杯日记 - 酒友圈模块接口文档

版本: v1.0 日期: 2026-07-20 模块: 酒友圈(社交模块) 小程序: 干杯日记(uni-app 微信小程序) 基础URL: https://your-domain.com/api/v1


1. 模块概述

酒友圈是干杯日记的核心社交模块,包含三大子功能:

子功能 说明
动态信息流 酒友发布饮酒动态,支持点赞、评论
酒友管理 好友请求、酒友列表、搜索、删除
约酒活动 发起酒局、报名、取消、签到

前端当前状态: 所有接口已在前端 common/api.js 中预留调用方法,暂用 Mock 数据。后端实现后前端仅需切换调用方式,无需改动页面逻辑。请严格按照本文档的字段名和数据结构实现,确保前端零改动对接。


2. 通用约定

2.1 鉴权

  • 请求头:Authorization: Bearer {token}
  • 所有接口均需登录态

2.2 统一响应格式

{
  "code": 0,
  "message": "success",
  "data": {}
}

2.3 错误码

code 含义
0 成功
400 参数错误
401 未登录/token过期
403 无权限(如:非酒友关系、非发起人)
404 资源不存在
409 冲突(如:重复报名、已是酒友)
500 服务器错误

2.4 时间格式

  • 所有时间字段使用 ISO 86012026-07-20T22:30:00.000Z
  • 前端会自行转换为相对时间("2小时前"等)

3. 动态信息流

3.1 获取动态列表

GET /circle/feeds

查询参数:

参数 类型 必填 说明
page int 页码,默认1
pageSize int 每页数量,默认10

响应 data

{
  "list": [
    {
      "id": "feed001",
      "userId": "user_002",
      "nickname": "老张",
      "avatar": "https://xxx/avatar.jpg",
      "time": "2026-07-20T20:30:00.000Z",
      "text": "今晚和几个老兄弟整了瓶飞天,配重庆火锅,巴适得很!",
      "drinks": [
        { "category": "baijiu", "name": "飞天茅台53度", "amount": "100ml" }
      ],
      "feeling": "tipsy",
      "images": ["https://xxx/img1.jpg"],
      "likes": 12,
      "liked": false,
      "comments": 3
    }
  ],
  "total": 50,
  "hasMore": true
}

Feed 字段说明:

字段 类型 说明
id string 动态ID
userId string 发布者用户ID
nickname string 发布者昵称
avatar string 发布者头像URL(可为空字符串)
time string 发布时间 ISO 8601
text string 动态文字内容
drinks DrinkTag[] 关联酒水标签(见下方结构)
feeling string/null 感受IDsober/buzzed/tipsy/drunk
images string[] 配图URL数组(最多9张)
likes int 点赞数
liked boolean 当前用户是否已点赞
comments int 评论数

DrinkTag 结构:

字段 类型 说明
category string 酒类IDbaijiu/beer/wine/whisky/huangjiu/sake/fruit/cocktail
name string 酒名(如"飞天茅台53度"
amount string 用量展示文本(如"100ml"、"3瓶"

业务规则:

  • 仅返回当前用户酒友发布的动态(visibility=friends+ 公开动态(visibility=public
  • 按发布时间倒序
  • 自己的动态也包含在内

3.2 发布动态

POST /circle/feeds

请求参数:

{
  "text": "今晚小酌一杯",
  "images": ["https://xxx/img1.jpg"],
  "recordId": "record_1689234567890",
  "visibility": "friends"
}
字段 类型 必填 说明
text string 文字内容(最长500字),text和images至少一项非空
images string[] 图片URL数组(最多9张,先调上传接口获取URL)
recordId string/null 关联的饮酒记录ID,传入时自动提取酒水信息生成drinks标签
visibility string 可见范围:friends(默认)/private

响应 data

{
  "success": true,
  "feedId": "feed_1689234567890"
}

业务规则:

  • 传入 recordId 时,后端从记录中提取 drinks 信息填充到动态的 drinks 字段
  • UGC 内容(text)需接入微信内容安全审核(msgSecCheck

3.3 点赞动态

POST /circle/feeds/:id/like

响应 data

{ "success": true }

3.4 取消点赞

POST /circle/feeds/:id/unlike

响应 data

{ "success": true }

重复点赞/取消应幂等处理,不报错。


3.5 获取动态评论

GET /circle/feeds/:id/comments

响应 data

{
  "list": [
    {
      "id": "c001",
      "userId": "user_003",
      "nickname": "酒仙李白",
      "avatar": "https://xxx/avatar3.jpg",
      "content": "茅台配火锅,土豪啊老张!",
      "time": "2026-07-20T21:00:00.000Z"
    }
  ]
}

Comment 字段说明:

字段 类型 说明
id string 评论ID
userId string 评论者ID
nickname string 评论者昵称
avatar string 评论者头像
content string 评论内容
time string 评论时间 ISO 8601

按时间正序返回(最早在前)。


3.6 发表评论

POST /circle/feeds/:id/comments

请求参数:

{ "content": "看着就馋了,下次带上我" }
字段 类型 必填 说明
content string 评论内容(最长200字)

响应 data

{
  "success": true,
  "comment": {
    "id": "c_1689234567890",
    "content": "看着就馋了,下次带上我",
    "time": "2026-07-20T22:00:00.000Z"
  }
}

业务规则:

  • 评论需接入内容安全审核
  • 评论成功后,动态的 comments 计数 +1

4. 酒友管理

4.1 获取酒友列表

GET /circle/friends

查询参数:

参数 类型 必填 说明
keyword string 按昵称模糊搜索

响应 data

{
  "list": [
    {
      "id": "user_002",
      "nickname": "老张",
      "avatar": "https://xxx/avatar.jpg",
      "lastDrink": "昨晚喝了飞天茅台",
      "lastDrinkTime": "2026-07-20T20:30:00.000Z",
      "online": true
    }
  ]
}

Friend 字段说明:

字段 类型 说明
id string 酒友用户ID
nickname string 昵称
avatar string 头像URL
lastDrink string 最近一次饮酒摘要文本(如"昨晚喝了飞天茅台"),无记录则为空
lastDrinkTime string 最近饮酒时间 ISO 8601
online boolean 是否在线(24小时内活跃视为在线)

4.2 获取好友请求列表

GET /circle/friend-requests

响应 data

{
  "list": [
    {
      "id": "req001",
      "userId": "user_101",
      "nickname": "夜猫子",
      "avatar": "https://xxx/avatar101.jpg",
      "message": "一起喝过酒,加个好友",
      "time": "2026-07-20T21:00:00.000Z"
    }
  ]
}

仅返回待处理的请求(status=pending),按时间倒序。


4.3 发送好友请求

POST /circle/friend-requests

请求参数:

{
  "userId": "user_101",
  "message": "一起喝过酒,加个好友"
}
字段 类型 必填 说明
userId string 目标用户ID
message string 验证消息(最长50字)

响应 data

{ "success": true }

业务规则:

  • 已是酒友返回 409
  • 已有待处理请求则幂等返回成功

4.4 接受好友请求

POST /circle/friend-requests/:id/accept

响应 data

{ "success": true }

业务规则:

  • 接受后双方建立酒友关系
  • 请求状态更新为 accepted

4.5 删除酒友

DELETE /circle/friends/:userId

响应 data

{ "success": true }

业务规则:

  • 双向解除酒友关系
  • 删除后对方动态不再出现在自己的信息流中

5. 约酒活动(酒局)

5.1 获取酒局列表

GET /circle/events

查询参数:

参数 类型 必填 说明
status string 状态筛选:open/ongoing/ended,不传返回全部

响应 data

{
  "list": [
    {
      "id": "evt001",
      "title": "周五夜·老地方火锅局",
      "organizer": {
        "id": "user_002",
        "nickname": "老张",
        "avatar": "https://xxx/avatar.jpg"
      },
      "time": "2026-07-25T19:00:00.000Z",
      "location": "渝味晓宇火锅(解放碑店)",
      "maxPeople": 8,
      "joined": 5,
      "participants": [
        { "id": "user_002", "nickname": "老张", "avatar": "https://xxx/avatar.jpg" }
      ],
      "status": "open",
      "note": "自带酒水,AA制餐费",
      "isJoined": false,
      "isOrganizer": false
    }
  ]
}

Event 字段说明:

字段 类型 说明
id string 酒局ID
title string 酒局名称(最长30字)
organizer UserInfo 发起人信息
time string 开始时间 ISO 8601
location string 地点文本
maxPeople int 人数上限(2-50
joined int 已报名人数(含发起人)
participants UserInfo[] 参与者列表
status string 状态:open(报名中)/ongoing(进行中)/ended(已结束)
note string 备注
isJoined boolean 当前用户是否已报名
isOrganizer boolean 当前用户是否为发起人

状态流转规则(后端自动维护):

  • open:当前时间 < 开始时间
  • ongoing:开始时间 <= 当前时间 < 开始时间+6小时
  • ended:当前时间 >= 开始时间+6小时

可见范围: 仅酒友可见(同动态信息流规则)


5.2 获取酒局详情

GET /circle/events/:id

响应 data 同 5.1 中单个 Event 结构


5.3 发起酒局

POST /circle/events

请求参数:

{
  "title": "周五夜·老地方火锅局",
  "time": "2026-07-25T19:00:00.000Z",
  "location": "渝味晓宇火锅(解放碑店)",
  "maxPeople": 8,
  "note": "自带酒水,AA制餐费"
}
字段 类型 必填 说明
title string 酒局名称(最长30字)
time string 开始时间(必须为未来时间)
location string 地点(最长50字)
maxPeople int 人数上限(2-50
note string 备注(最长200字)

响应 data

{
  "success": true,
  "eventId": "evt_1689234567890"
}

业务规则:

  • 发起人自动算作已报名(joined 初始为1)
  • 发起人 isOrganizer = true

5.4 报名酒局

POST /circle/events/:id/join

响应 data

{ "success": true }

业务规则:

  • 人数已满返回 409
  • 酒局非 open 状态返回 403
  • 重复报名幂等处理

5.5 取消报名

POST /circle/events/:id/quit

响应 data

{ "success": true }

业务规则:

  • 发起人不可取消报名(返回 403
  • 未报名状态幂等处理

5.6 酒局签到

POST /circle/events/:id/checkin

响应 data

{ "success": true }

业务规则:

  • 仅 ongoing 状态可签到(返回 403
  • 仅已报名用户可签到
  • 签到后可在参与者信息中标记 checkedIn(可选扩展)

6. 数据库表设计参考

6.1 酒友关系表 (friendships)

CREATE TABLE friendships (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id VARCHAR(32) NOT NULL,
  friend_id VARCHAR(32) NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  UNIQUE INDEX idx_user_friend (user_id, friend_id),
  INDEX idx_friend (friend_id)
);

双向关系存两条记录(A->B 和 B->A),便于查询。

6.2 好友请求表 (friend_requests)

CREATE TABLE friend_requests (
  id VARCHAR(32) PRIMARY KEY,
  from_user_id VARCHAR(32) NOT NULL,
  to_user_id VARCHAR(32) NOT NULL,
  message VARCHAR(64),
  status ENUM('pending', 'accepted', 'rejected') DEFAULT 'pending',
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_to_status (to_user_id, status),
  INDEX idx_from_to (from_user_id, to_user_id)
);

6.3 动态表 (feeds)

CREATE TABLE feeds (
  id VARCHAR(32) PRIMARY KEY,
  user_id VARCHAR(32) NOT NULL,
  text VARCHAR(512),
  drinks JSON,
  feeling VARCHAR(16),
  images JSON,
  record_id VARCHAR(32),
  visibility ENUM('friends', 'private') DEFAULT 'friends',
  like_count INT DEFAULT 0,
  comment_count INT DEFAULT 0,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_user_time (user_id, created_at),
  INDEX idx_created (created_at)
);

6.4 评论表 (comments)

CREATE TABLE comments (
  id VARCHAR(32) PRIMARY KEY,
  feed_id VARCHAR(32) NOT NULL,
  user_id VARCHAR(32) NOT NULL,
  content VARCHAR(256) NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_feed (feed_id, created_at)
);

6.5 酒局表 (events)

CREATE TABLE events (
  id VARCHAR(32) PRIMARY KEY,
  organizer_id VARCHAR(32) NOT NULL,
  title VARCHAR(64) NOT NULL,
  start_time DATETIME NOT NULL,
  location VARCHAR(128) NOT NULL,
  max_people INT NOT NULL DEFAULT 6,
  joined_count INT NOT NULL DEFAULT 1,
  note VARCHAR(256),
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_organizer (organizer_id),
  INDEX idx_start_time (start_time)
);

6.6 酒局报名表 (event_participants)

CREATE TABLE event_participants (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  event_id VARCHAR(32) NOT NULL,
  user_id VARCHAR(32) NOT NULL,
  checked_in TINYINT(1) DEFAULT 0,
  joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  UNIQUE INDEX idx_event_user (event_id, user_id),
  INDEX idx_user (user_id)
);

7. 前端对接说明

7.1 前端调用位置

所有接口调用集中在 common/api.js,当前为 Mock 实现,方法签名如下:

// 动态
GetCircleFeeds({ page, pageSize })   // GET  /circle/feeds
PublishFeed({ text, images, recordId, visibility })  // POST /circle/feeds
LikeFeed({ feedId })                 // POST /circle/feeds/:id/like
UnlikeFeed({ feedId })               // POST /circle/feeds/:id/unlike
GetFeedComments({ feedId })          // GET  /circle/feeds/:id/comments
AddComment({ feedId, content })      // POST /circle/feeds/:id/comments

// 酒友
GetFriends({ keyword })              // GET  /circle/friends
GetFriendRequests()                  // GET  /circle/friend-requests
SendFriendRequest({ userId })        // POST /circle/friend-requests
AcceptFriendRequest({ requestId })   // POST /circle/friend-requests/:id/accept
RemoveFriend({ userId })             // DELETE /circle/friends/:userId

// 酒局
GetEvents({ status })                // GET  /circle/events
GetEventDetail({ eventId })          // GET  /circle/events/:id
CreateEvent({ title, time, location, maxPeople, note })  // POST /circle/events
JoinEvent({ eventId })               // POST /circle/events/:id/join
QuitEvent({ eventId })               // POST /circle/events/:id/quit
CheckInEvent({ eventId })            // POST /circle/events/:id/checkin

7.2 响应解包约定

前端 SDK 会自动解包 data.data,因此接口实际返回给前端的结构为:

{ "code": 0, "data": { ... } }

前端拿到的就是 data 内的对象。

7.3 注意事项

  1. 字段名严格一致:前端已按本文档字段名渲染,请勿更改命名(如 likes 不能改为 likeCount
  2. 头像可为空:avatar 字段允许空字符串,前端有默认占位头像
  3. 时间格式:统一 ISO 8601,前端自行格式化
  4. 内容安全text、content、title、note 等 UGC 字段需接入微信 msgSecCheck 审核
  5. 幂等性:点赞/取消、报名/取消等操作需幂等,避免前端重试导致计数错误