- 添加完整的后端接口文档,包含用户、打卡记录、统计等模块 - 修复应用名称从"喝酒了么"统一更正为"喝了么" - 重构App.vue中的启动逻辑,增加数据迁移和路由守卫功能 - 调整DrinkCalendar组件的UI间距和尺寸参数 - 优化DrinkCard组件的品牌展示文案 - 修改manifest.json中的应用描述和微信小程序配置 - 调整pages.json中的页面路径顺序和tabBar配置 - 更新全局样式文件中的应用名称标识 - 修改mock数据中的用户头像默认值 - 优化卡片导出功能的绘制逻辑和视觉效果
15 KiB
15 KiB
喝了么 - 后端接口文档
版本: v1.0
日期: 2026-07-13
小程序: 喝了么(uni-app 微信小程序)
基础URL:https://your-domain.com/api/v1
1. 通用说明
1.1 请求格式
- Content-Type:
application/json - 鉴权方式: 请求头
Authorization: Bearer {token}(微信登录获取) - 所有时间字段使用 ISO 8601 格式
1.2 统一响应格式
{
"code": 0,
"message": "success",
"data": {}
}
| code | 含义 |
|---|---|
| 0 | 成功 |
| 400 | 参数错误 |
| 401 | 未登录/token过期 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
1.3 分页参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码,默认1 |
| pageSize | int | 否 | 每页数量,默认20 |
1.4 分页响应
{
"code": 0,
"data": {
"list": [],
"total": 100,
"page": 1,
"pageSize": 20
}
}
2. 用户模块
2.1 微信登录
POST /auth/wechat-login
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 是 | 微信登录code(wx.login获取) |
| nickName | string | 否 | 用户昵称 |
| avatarUrl | string | 否 | 头像URL |
响应 data:
{
"token": "jwt_token_xxx",
"user": {
"id": "user_001",
"nickname": "酒友小王",
"avatar": "https://xxx/avatar.jpg",
"joinedAt": "2026-01-15T00:00:00.000Z",
"preferences": {
"favoriteCategories": ["baijiu", "beer"],
"frequency": "often"
}
},
"isNew": false
}
2.2 获取用户信息
GET /user/profile
响应 data:
{
"id": "user_001",
"nickname": "酒友小王",
"avatar": "https://xxx/avatar.jpg",
"joinedAt": "2026-01-15T00:00:00.000Z",
"preferences": {
"favoriteCategories": ["baijiu", "beer"],
"frequency": "often"
}
}
2.3 更新用户偏好
PUT /user/preferences
请求参数:
{
"favoriteCategories": ["baijiu", "beer"],
"frequency": "often"
}
| 字段 | 类型 | 说明 |
|---|---|---|
| favoriteCategories | string[] | 偏好酒类ID列表 |
| frequency | string | 饮酒频率:rarely / sometimes / often |
3. 打卡记录模块(核心)
3.1 创建打卡记录
POST /records
请求参数:
{
"date": "2026-07-13",
"mode": "drank",
"drinks": [
{
"category": "baijiu",
"brand": "茅台",
"product": "飞天茅台53度",
"amount": 100,
"unit": "ml",
"degree": 53,
"standardCups": 2.12
}
],
"food": {
"category": "hotpot",
"name": "重庆老火锅"
},
"feeling": "tipsy",
"photos": [],
"visibility": "friends",
"quote": "人生得意须尽欢,莫使金樽空对月"
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| date | string | 是 | 日期 YYYY-MM-DD |
| mode | string | 是 | 打卡模式:drank(喝了) / abstain(未喝) |
| drinks | DrinkItem[] | 否 | 酒水列表(mode=abstain时为空数组) |
| food | FoodInfo / null | 否 | 配餐信息 |
| feeling | string / null | 否 | 感受ID |
| photos | string[] | 否 | 照片URL数组(最多9张) |
| visibility | string | 否 | 可见范围:public / friends / private,默认 friends |
| quote | string | 否 | 酒言酒语(用户选择或自定义) |
DrinkItem 结构:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| category | string | 是 | 酒类分类ID |
| brand | string | 是 | 品牌名称 |
| product | string | 否 | 产品名 |
| amount | number | 是 | 饮用量数值 |
| unit | string | 是 | 单位:ml / liang(两) / bottle(瓶) / cup(杯) / can(听) / shot |
| degree | number | 是 | 酒精度数(%) |
| standardCups | number | 否 | 标准杯数(前端计算,后端应校验) |
FoodInfo 结构:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| category | string | 是 | 配餐分类ID |
| name | string | 否 | 具体菜名 |
响应 data:
{
"id": "record_1689234567890",
"date": "2026-07-13",
"mode": "drank",
"drinks": [...],
"food": {...},
"feeling": "tipsy",
"photos": [],
"visibility": "friends",
"quote": "...",
"standardCupsTotal": 2.12,
"createdAt": "2026-07-13T22:30:00.000Z"
}
标准杯计算公式:
标准杯 = (饮用量ml × 酒精度数% × 0.8) / 10
1标准杯 = 10g纯酒精
单位换算为ml:
单位 换算 ml ×1 liang(两) ×50 bottle(瓶) ×500 cup(杯) ×150 can(听) ×330 shot ×30
3.2 获取记录列表
GET /records
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码 |
| pageSize | int | 否 | 每页数量 |
| month | string | 否 | 月份筛选 YYYY-MM |
| mode | string | 否 | 打卡模式筛选 drank/abstain |
响应 data:
{
"list": [
{
"id": "record_xxx",
"date": "2026-07-13",
"mode": "drank",
"drinks": [...],
"food": {...},
"feeling": "tipsy",
"photos": [],
"visibility": "friends",
"standardCupsTotal": 2.12,
"createdAt": "2026-07-13T22:30:00.000Z"
}
],
"total": 30,
"page": 1,
"pageSize": 20
}
3.3 获取单条记录详情
GET /records/:id
响应 data: 同 3.1 创建记录的返回结构
3.4 删除记录
DELETE /records/:id
3.5 获取日历打卡数据
GET /records/calendar
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| year | int | 是 | 年份 |
| month | int | 是 | 月份(1-12) |
响应 data:
{
"year": 2026,
"month": 7,
"days": {
"2026-07-01": { "mode": "drank", "standardCupsTotal": 2.5 },
"2026-07-02": { "mode": "abstain", "standardCupsTotal": 0 },
"2026-07-03": null
}
}
前端根据此数据渲染日历打卡状态。null表示当天无记录。
4. 照片上传
4.1 上传照片
POST /upload/photo
Content-Type: multipart/form-data
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 图片文件(jpg/png,最大10MB) |
| recordId | string | 否 | 关联记录ID(可选,用于后续关联) |
响应 data:
{
"url": "https://cdn.xxx.com/photos/2026/07/abc123.jpg",
"width": 1080,
"height": 1920,
"size": 256000
}
4.2 批量上传
POST /upload/photos
Content-Type: multipart/form-data
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| files | File[] | 是 | 图片文件数组(最多9张) |
响应 data:
{
"photos": [
{ "url": "https://...", "width": 1080, "height": 1920, "size": 256000 },
...
]
}
5. 统计模块
5.1 获取用户统计概览
GET /stats/overview
响应 data:
{
"weekDrinkCount": 3,
"weekCups": 6.5,
"monthDrinkCount": 12,
"monthCups": 28.3,
"streak": 5,
"streakType": "drank",
"totalDays": 45,
"totalRecords": 48,
"totalCups": 134.4,
"favCategory": "baijiu",
"categoryVariety": 5
}
| 字段 | 类型 | 说明 |
|---|---|---|
| weekDrinkCount | int | 本周饮酒天数 |
| weekCups | float | 本周标准杯总数 |
| monthDrinkCount | int | 本月饮酒天数 |
| monthCups | float | 本月标准杯总数 |
| streak | int | 当前连续打卡天数 |
| streakType | string | 连续类型:drank/abstain |
| totalDays | int | 总饮酒天数(去重) |
| totalRecords | int | 总记录数 |
| totalCups | float | 历史累计标准杯 |
| favCategory | string/null | 最爱酒类ID |
| categoryVariety | int | 尝试过的酒类品种数 |
5.2 获取月度统计
GET /stats/monthly
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| year | int | 否 | 年份,默认当前年 |
| month | int | 否 | 月份,默认当前月 |
响应 data:
{
"year": 2026,
"month": 7,
"drinkDays": 18,
"abstainDays": 12,
"totalCups": 45.6,
"avgCupsPerDay": 2.53,
"categoryBreakdown": [
{ "category": "baijiu", "count": 8, "cups": 22.4 },
{ "category": "beer", "count": 6, "cups": 15.2 },
{ "category": "wine", "count": 4, "cups": 8.0 }
],
"feelingBreakdown": [
{ "feeling": "tipsy", "count": 10 },
{ "feeling": "buzzed", "count": 5 },
{ "feeling": "drunk", "count": 2 },
{ "feeling": "blackout", "count": 1 }
],
"foodBreakdown": [
{ "category": "hotpot", "count": 5 },
{ "category": "bbq", "count": 4 }
]
}
5.3 获取酒类分布统计
GET /stats/categories
响应 data:
{
"categories": [
{
"id": "baijiu",
"name": "白酒",
"recordCount": 20,
"totalCups": 56.8,
"percentage": 42.3
},
{
"id": "beer",
"name": "啤酒",
"recordCount": 15,
"totalCups": 38.2,
"percentage": 28.5
}
]
}
6. 成就模块
6.1 获取成就列表
GET /achievements
响应 data:
{
"achievements": [
{
"id": "first_checkin",
"name": "初来乍到",
"desc": "完成第一次打卡,开启你的饮酒记录之旅",
"icon": "🏅",
"unlocked": true,
"unlockedAt": "2026-01-15T20:00:00.000Z",
"condition": {
"type": "total_records",
"value": 1
},
"progress": 1.0
},
{
"id": "hundred_cups",
"name": "百杯不醉",
"desc": "累计饮用100标准杯",
"icon": "🏆",
"unlocked": false,
"unlockedAt": null,
"condition": {
"type": "total_standard_cups",
"value": 100
},
"progress": 0.75
}
]
}
成就条件类型:
| type | 说明 | value含义 |
|---|---|---|
| total_records | 总记录数 | 次数 |
| total_standard_cups | 累计标准杯 | 杯数 |
| streak_days | 连续打卡天数 | 天数 |
| category_records | 某酒类打卡次数 | 次数(需配合category字段) |
| category_variety | 尝试酒类品种数 | 品种数 |
7. 社交模块(朋友圈/卡片分享)
7.1 获取朋友圈动态
GET /feed
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | int | 否 | 页码 |
| pageSize | int | 否 | 每页数量 |
| lastId | string | 否 | 游标分页,上一页最后一条ID |
响应 data:
{
"list": [
{
"id": "record_xxx",
"user": {
"id": "user_002",
"nickname": "酒友小李",
"avatar": "https://xxx/avatar2.jpg"
},
"date": "2026-07-13",
"mode": "drank",
"drinks": [...],
"food": {...},
"feeling": "tipsy",
"photos": ["https://..."],
"standardCupsTotal": 3.5,
"quote": "酒逢知己千杯少",
"likeCount": 5,
"commentCount": 2,
"liked": false,
"createdAt": "2026-07-13T22:30:00.000Z"
}
],
"total": 100,
"page": 1,
"pageSize": 20
}
7.2 点赞/取消点赞
POST /records/:id/like
POST /records/:id/unlike
8. 数据字典
8.1 酒类分类 (category)
| ID | 名称 | 默认度数 |
|---|---|---|
| baijiu | 白酒 | 52 |
| beer | 啤酒 | 5 |
| wine | 红酒 | 13 |
| whisky | 洋酒 | 40 |
| huangjiu | 黄酒 | 15 |
| sake | 清酒 | 15 |
| fruit | 果酒 | 8 |
| cocktail | 调酒 | 15 |
| other | 其他 | 10 |
8.2 饮用量单位 (unit)
| ID | 名称 | 换算(ml) |
|---|---|---|
| ml | ml | 1 |
| liang | 两 | 50 |
| bottle | 瓶 | 500 |
| cup | 杯 | 150 |
| can | 听 | 330 |
| shot | shot | 30 |
8.3 配餐分类 (food category)
| ID | 名称 |
|---|---|
| hotpot | 火锅 |
| bbq | 烧烤 |
| stirfry | 炒菜 |
| seafood | 海鲜 |
| japanese | 日料 |
| western | 西餐 |
| snack | 小吃卤味 |
| junk | 零食 |
| none | 无配餐 |
8.4 饮用感受 (feeling)
| ID | 名称 | 描述 |
|---|---|---|
| tipsy | 微醺 | 刚刚好的快乐 |
| buzzed | 到位 | 今夜刚刚好 |
| drunk | 醉了 | 有点上头了 |
| blackout | 断片 | 什么都不记得了 |
8.5 可见范围 (visibility)
| ID | 名称 | 说明 |
|---|---|---|
| public | 公开 | 所有人可见 |
| friends | 仅好友 | 好友可见 |
| private | 仅自己 | 仅自己可见 |
8.6 打卡模式 (mode)
| ID | 名称 | 说明 |
|---|---|---|
| drank | 今日喝了 | 有饮酒记录 |
| abstain | 今日未喝 | 戒酒打卡 |
9. 数据库表设计参考
9.1 用户表 (users)
CREATE TABLE users (
id VARCHAR(32) PRIMARY KEY,
openid VARCHAR(64) UNIQUE NOT NULL,
union_id VARCHAR(64),
nickname VARCHAR(64),
avatar VARCHAR(512),
preferences JSON,
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
9.2 打卡记录表 (records)
CREATE TABLE records (
id VARCHAR(32) PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
date DATE NOT NULL,
mode ENUM('drank', 'abstain') NOT NULL,
drinks JSON,
food JSON,
feeling VARCHAR(16),
photos JSON,
visibility ENUM('public', 'friends', 'private') DEFAULT 'friends',
quote VARCHAR(256),
standard_cups_total DECIMAL(8,2) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_date (user_id, date),
INDEX idx_user_mode (user_id, mode, date)
);
9.3 照片表 (photos)
CREATE TABLE photos (
id VARCHAR(32) PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
record_id VARCHAR(32),
url VARCHAR(512) NOT NULL,
width INT,
height INT,
size INT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_record (record_id),
INDEX idx_user (user_id)
);
9.4 点赞表 (likes)
CREATE TABLE likes (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
record_id VARCHAR(32) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX idx_user_record (user_id, record_id)
);
9.5 成就记录表 (user_achievements)
CREATE TABLE user_achievements (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(32) NOT NULL,
achievement_id VARCHAR(32) NOT NULL,
unlocked_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE INDEX idx_user_achievement (user_id, achievement_id)
);
10. 备注
- 标准杯计算建议由后端完成,前端传入的
standardCups仅作参考,后端应以amount、unit、degree为准重新计算 - 照片上传建议走对象存储(OSS/COS),返回CDN链接
- 日历接口建议缓存,避免每次查全月记录
- 成就检测可在创建记录后异步触发,避免影响主流程
- 可见范围控制需在 feed 接口和记录详情接口中做权限过滤
- 前端目前使用 Mock 数据(
mock-data.js),切换到真实接口时只需替换common/mock-data.js中的方法为 HTTP 调用即可