- 新增酒友圈、圈子详情、发布动态、好友列表、活动创建等页面配置 - 添加酒友圈相关API接口,包括动态、评论、好友、活动等功能 - 实现模拟数据用于前端开发和测试 - 创建评论项、空状态、活动卡片、动态卡片、好友项等组件 - 编写酒友圈模块详细的接口文档,定义数据结构和业务规则
16 KiB
干杯日记 - 酒友圈模块接口文档
版本: 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 8601:
2026-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 | 感受ID:sober/buzzed/tipsy/drunk |
| images | string[] | 配图URL数组(最多9张) |
| likes | int | 点赞数 |
| liked | boolean | 当前用户是否已点赞 |
| comments | int | 评论数 |
DrinkTag 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
| category | string | 酒类ID(baijiu/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 注意事项
- 字段名严格一致:前端已按本文档字段名渲染,请勿更改命名(如
likes不能改为likeCount) - 头像可为空:avatar 字段允许空字符串,前端有默认占位头像
- 时间格式:统一 ISO 8601,前端自行格式化
- 内容安全:text、content、title、note 等 UGC 字段需接入微信 msgSecCheck 审核
- 幂等性:点赞/取消、报名/取消等操作需幂等,避免前端重试导致计数错误