Files
hejiu/node_modules/HaveADrink/README.md
T
cg adf6b684b9 feat(calendar): 更新日历接口并优化记录流程
- 将GetRecords接口替换为GetCalendar接口获取日历数据
- 重构首页日历数据显示逻辑,支持年月维度的数据获取
- 优化打卡记录流程,合并选酒和记量步骤为单一添加酒水步骤
- 移除登录页面的游客模式选项,简化首次启动逻辑
- 调整引导页逻辑,移除登录跳转改为直接进入首页
- 优化记录页面UI布局,添加状态栏安全距离适配
- 新增酒水列表管理功能,支持添加和删除已选酒水
- 更新依赖包HaveADrink至v1.0.3版本,同步API变更
2026-07-17 23:51:43 +08:00

1161 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 使用说明
* 喝酒了么 - 后端接口 API
* 小程序:喝酒了么(uni-app 微信小程序)
* 基础URL: /api/v1
*
* 主要功能模块:
* 1. 用户模块 - 微信登录、用户信息管理
* 2. 打卡记录模块 - 饮酒记录创建、查询、日历数据
* 3. 照片上传模块 - 单张/批量照片上传
* 4. 统计模块 - 用户统计、月度统计、酒类分布
* 5. 成就模块 - 成就列表和进度
* 6. 社交模块 - 朋友圈动态、点赞
**版本:** v1.0.3
## 安装
```
npm install --registry="https://npm.wash-painting.cn" HaveADrink
```
## 用法
用户需实现普通 http 请求函数和文件上传函数,返回值均为 json 对象
**示例**
```javascript
// reslove 和 reject 必须返回 json 对象
const http_request_function = (url, method, headers, body) => {
return new Promise((reslove, reject)=>{});
}
const upload_function = (url, method, headers, data) => {
return new Promise((reslove, reject)=>{});
}
const client = new HaveADrink(host, http_request_function, upload_function);
```
## 接口文档
### 微信登录, 获取openid、unionid、token
<font color="green">POST</font> `/api/have_a_drink/v1/auth/wechat/login`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|code|`string`|required| 登录时获取的 code, 可通过 wx.login 获取|
|nickName|`string`|| 用户昵称|
|avatarUrl|`string`|| 头像URL|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|token|`string`| JWT Token<br>|
|user|`User`| 用户信息<br>|
|isNew|`boolean`| 是否新用户<br>|
|session_key|`string`| 会话密钥<br>|
|open_id|`string`| 用户唯一标识<br>|
|union_id|`string`| 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见 UnionID 机制说明。<br>|
|errcode|`number`| 错误码<br>|
|errmsg|`string`| 错误信息<br>|
|refresh_token|`string`| 刷新token<br>|
**User**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 用户ID|
|nickname|`string`| 用户昵称|
|avatar|`string`| 头像URL|
|joinedAt|`string`| 加入时间|
|preferences|`UserPreferences`| 用户偏好|
**UserPreferences**
|名称|类型|说明|
|:-|:-|:-|
|favoriteCategories|`Array<Category>`| 偏好酒类ID列表|
|frequency|`Frequency`| 饮酒频率|
```javascript
const req = new WechatLoginReq()
client.WechatLogin(req).then(...).catch(...)
```
### 获取微信手机号
<font color="green">POST</font> `/api/have_a_drink/v1/auth/wechat/get_phone_number`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|code|`string`|required| 手机号获取凭证|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|errcode|`number`| 错误码<br>|
|errmsg|`string`| 错误信息<br>|
|token|`string`| token:api使用<br>|
|expires_in|`number`| token 超时时间,单位(秒)<br>|
|refresh_token|`string`| refresh_token:刷新token<br>|
```javascript
const req = new WechatGetPhoneNumberReq()
client.WechatGetPhoneNumber(req).then(...).catch(...)
```
### 刷新 token 接口
<font color="green">POST</font> `/api/have_a_drink/v1/auth/refresh_token`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|refresh_token|`string`|required| 签发 token 时生成的 refresh_token|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|token|`string`| 生成的新token<br>|
|expire_in|`number`| token 超时时间,单位(秒)<br>|
|refresh_token|`string`| refresh_token:刷新token<br>|
```javascript
const req = new RefreshTokenReq()
client.RefreshToken(req).then(...).catch(...)
```
### 获取成就列表
<font color="green">GET</font> `/api/have_a_drink/v1/achievements/list`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`AchievementsData`| 成就列表数据<br>|
**AchievementsData**
|名称|类型|说明|
|:-|:-|:-|
|achievements|`Array<Achievement>`| 成就列表|
**Achievement**
|名称|类型|说明|
|:-|:-|:-|
|id|`string`| 成就ID|
|name|`string`| 成就名称|
|desc|`string`| 成就描述|
|icon|`string`| 成就图标|
|unlocked|`boolean`| 是否已解锁|
|unlockedAt|`string`| 解锁时间|
|condition|`AchievementCondition`| 成就条件|
|progress|`number`| 进度(0-1|
**AchievementCondition**
|名称|类型|说明|
|:-|:-|:-|
|type|`AchievementConditionType`| 条件类型|
|value|`number`| 目标值|
**AchievementConditionType**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|TotalRecords|"total_records"|`AchievementConditionType`|总记录数|
|TotalStandardCups|"total_standard_cups"|`AchievementConditionType`|累计标准杯|
|StreakDays|"streak_days"|`AchievementConditionType`|连续打卡天数|
|CategoryRecords|"category_records"|`AchievementConditionType`|某酒类打卡次数|
|CategoryVariety|"category_variety"|`AchievementConditionType`|尝试酒类品种数|
```javascript
const req = new GetAchievementsReq()
client.GetAchievements(req).then(...).catch(...)
```
### 获取朋友圈动态
<font color="green">GET</font> `/api/have_a_drink/v1/communication/feed`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|lastId|`string\|number`|| 游标分页,上一页最后一条ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`FeedPageData`| 朋友圈动态分页数据<br>|
**FeedPageData**
|名称|类型|说明|
|:-|:-|:-|
|list|`Array<FeedItem>`| 动态列表|
**FeedItem**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|user|`FeedUser`| 用户信息|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array<DrinkItem>`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array<string>`| 照片URL数组|
|standardCupsTotal|`number`| 标准杯总数|
|quote|`string`| 酒言酒语|
|likeCount|`number`| 点赞数|
|commentCount|`number`| 评论数|
|liked|`boolean`| 当前用户是否已点赞|
|createdAt|`string`| 创建时间|
**FeedUser**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 用户ID|
|nickname|`string`| 用户昵称|
|avatar|`string`| 头像URL|
**DrinkItem**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类ID|
|brand|`string`| 品牌名称|
|product|`string`| 产品名|
|amount|`number`| 饮用量数值|
|unit|`Unit`| 单位|
|degree|`number`| 酒精度数(%)|
|standardCups|`number`| 标准杯数(前端计算,后端应校验)|
**Category**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Baijiu|"baijiu"|`Category`|白酒|
|Beer|"beer"|`Category`|啤酒|
|Wine|"wine"|`Category`|红酒|
|Whisky|"whisky"|`Category`|洋酒|
|Huangjiu|"huangjiu"|`Category`|黄酒|
|Sake|"sake"|`Category`|清酒|
|Fruit|"fruit"|`Category`|果酒|
|Cocktail|"cocktail"|`Category`|调酒|
|Other|"other"|`Category`|其他|
**Unit**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Ml|"ml"|`Unit`|毫升|
|Liang|"liang"|`Unit`|两|
|Bottle|"bottle"|`Unit`|瓶|
|Cup|"cup"|`Unit`|杯|
|Can|"can"|`Unit`|听|
|Shot|"shot"|`Unit`|shot|
**FoodInfo**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类ID|
|name|`string`| 具体菜名|
**FoodCategory**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Hotpot|"hotpot"|`FoodCategory`|火锅|
|Bbq|"bbq"|`FoodCategory`|烧烤|
|Stirfry|"stirfry"|`FoodCategory`|炒菜|
|Seafood|"seafood"|`FoodCategory`|海鲜|
|Japanese|"japanese"|`FoodCategory`|日料|
|Western|"western"|`FoodCategory`|西餐|
|Snack|"snack"|`FoodCategory`|小吃卤味|
|Junk|"junk"|`FoodCategory`|零食|
|None|"none"|`FoodCategory`|无配餐|
```javascript
const req = new GetFeedReq()
client.GetFeed(req).then(...).catch(...)
```
### 点赞
<font color="green">POST</font> `/api/have_a_drink/v1/communication/records/like`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new LikeRecordReq()
client.LikeRecord(req).then(...).catch(...)
```
### 取消点赞
<font color="green">POST</font> `/api/have_a_drink/v1/communication/records/unlike`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new LikeRecordReq()
client.UnlikeRecord(req).then(...).catch(...)
```
### 上传照片
<font color="green">POST</font> `/api/have_a_drink/v1/photo/upload/photo`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|url|`string`|required| 图片Url|
|recordId|`string\|number`|required| 关联记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new UploadPhotoReq()
client.UploadPhoto(req).then(...).catch(...)
```
### 批量上传照片
<font color="green">POST</font> `/api/have_a_drink/v1/photo/upload/photos`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|urls|`Array<string>`|required,max=9| 图片URL数组(最多9张)|
|recordId|`string\|number`|required| 关联记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new UploadPhotosReq()
client.UploadPhotos(req).then(...).catch(...)
```
### 创建打卡记录
<font color="green">POST</font> `/api/have_a_drink/v1/record/records`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|date|`string`|required| 日期 YYYY-MM-DD|
|mode|`Mode`|今日喝了: Mode.Drank = "drank"<br>今日未喝: Mode.Abstain = "abstain"| 打卡模式|
|drinks|`Array<DrinkItem>`|| 酒水列表(mode=abstain时为空数组)|
|food|`FoodInfo`|| 配餐信息|
|feeling|`Feeling`|微醺: Feeling.Tipsy = "tipsy"<br>到位: Feeling.Buzzed = "buzzed"<br>醉了: Feeling.Drunk = "drunk"<br>断片: Feeling.Blackout = "blackout"| 感受ID|
|photos|`Array<string>`|max=9| 照片URL数组(最多9张)|
|visibility|`Visibility`|公开: Visibility.Public = "public"<br>仅好友: Visibility.Friends = "friends"<br>仅自己: Visibility.Private = "private"| 可见范围|
|quote|`string`|| 酒言酒语|
**DrinkItem**
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|category|`Category`|required| 酒类分类ID|
|brand|`string`|required| 品牌名称|
|product|`string`|| 产品名|
|amount|`number`|required,gt=0| 饮用量数值|
|unit|`Unit`|required| 单位|
|degree|`number`|required,gte=0,lte=100| 酒精度数(%)|
|standardCups|`number`|| 标准杯数(前端计算,后端应校验)|
**Category**
|名称|值|类型|说明|
|:-|:-|:-|:-|
|Baijiu|"baijiu"|`Category`|白酒|
|Beer|"beer"|`Category`|啤酒|
|Wine|"wine"|`Category`|红酒|
|Whisky|"whisky"|`Category`|洋酒|
|Huangjiu|"huangjiu"|`Category`|黄酒|
|Sake|"sake"|`Category`|清酒|
|Fruit|"fruit"|`Category`|果酒|
|Cocktail|"cocktail"|`Category`|调酒|
|Other|"other"|`Category`|其他|
**Unit**
|名称|值|类型|说明|
|:-|:-|:-|:-|
|Ml|"ml"|`Unit`|毫升|
|Liang|"liang"|`Unit`|两|
|Bottle|"bottle"|`Unit`|瓶|
|Cup|"cup"|`Unit`|杯|
|Can|"can"|`Unit`|听|
|Shot|"shot"|`Unit`|shot|
**FoodInfo**
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|category|`FoodCategory`|required| 配餐分类ID|
|name|`string`|| 具体菜名|
**FoodCategory**
|名称|值|类型|说明|
|:-|:-|:-|:-|
|Hotpot|"hotpot"|`FoodCategory`|火锅|
|Bbq|"bbq"|`FoodCategory`|烧烤|
|Stirfry|"stirfry"|`FoodCategory`|炒菜|
|Seafood|"seafood"|`FoodCategory`|海鲜|
|Japanese|"japanese"|`FoodCategory`|日料|
|Western|"western"|`FoodCategory`|西餐|
|Snack|"snack"|`FoodCategory`|小吃卤味|
|Junk|"junk"|`FoodCategory`|零食|
|None|"none"|`FoodCategory`|无配餐|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`Record`| 创建的记录详情<br>|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array<DrinkItem>`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array<string>`| 照片URL数组|
|visibility|`Visibility`| 可见范围|
|quote|`string`| 酒言酒语|
|standardCupsTotal|`number`| 标准杯总数|
|createdAt|`string`| 创建时间|
**Mode**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Drank|"drank"|`Mode`|今日喝了|
|Abstain|"abstain"|`Mode`|今日未喝|
**DrinkItem**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类ID|
|brand|`string`| 品牌名称|
|product|`string`| 产品名|
|amount|`number`| 饮用量数值|
|unit|`Unit`| 单位|
|degree|`number`| 酒精度数(%)|
|standardCups|`number`| 标准杯数(前端计算,后端应校验)|
**FoodInfo**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类ID|
|name|`string`| 具体菜名|
**Feeling**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Tipsy|"tipsy"|`Feeling`|微醺|
|Buzzed|"buzzed"|`Feeling`|到位|
|Drunk|"drunk"|`Feeling`|醉了|
|Blackout|"blackout"|`Feeling`|断片|
**Visibility**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Public|"public"|`Visibility`|公开|
|Friends|"friends"|`Visibility`|仅好友|
|Private|"private"|`Visibility`|仅自己|
```javascript
const req = new CreateRecordReq()
client.CreateRecord(req).then(...).catch(...)
```
### 获取记录列表
<font color="green">GET</font> `/api/have_a_drink/v1/record/records`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|page|`number`|required,min=1| 页码|
|pageSize|`number`|required,min=1,max=100| 每页数量,默认1-100|
|month|`string`|| 月份筛选 YYYY-MM|
|mode|`Mode`|今日喝了: Mode.Drank = "drank"<br>今日未喝: Mode.Abstain = "abstain"| 打卡模式筛选|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Record>`| 分页数据<br>|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array<DrinkItem>`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array<string>`| 照片URL数组|
|visibility|`Visibility`| 可见范围|
|quote|`string`| 酒言酒语|
|standardCupsTotal|`number`| 标准杯总数|
|createdAt|`string`| 创建时间|
**Mode**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Drank|"drank"|`Mode`|今日喝了|
|Abstain|"abstain"|`Mode`|今日未喝|
**DrinkItem**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类ID|
|brand|`string`| 品牌名称|
|product|`string`| 产品名|
|amount|`number`| 饮用量数值|
|unit|`Unit`| 单位|
|degree|`number`| 酒精度数(%)|
|standardCups|`number`| 标准杯数(前端计算,后端应校验)|
**FoodInfo**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类ID|
|name|`string`| 具体菜名|
**Feeling**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Tipsy|"tipsy"|`Feeling`|微醺|
|Buzzed|"buzzed"|`Feeling`|到位|
|Drunk|"drunk"|`Feeling`|醉了|
|Blackout|"blackout"|`Feeling`|断片|
**Visibility**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Public|"public"|`Visibility`|公开|
|Friends|"friends"|`Visibility`|仅好友|
|Private|"private"|`Visibility`|仅自己|
```javascript
const req = new GetRecordsReq()
client.GetRecords(req).then(...).catch(...)
```
### 获取单条记录详情
<font color="green">GET</font> `/api/have_a_drink/v1/record/records/detail`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`Record`| 记录详情<br>|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array<DrinkItem>`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array<string>`| 照片URL数组|
|visibility|`Visibility`| 可见范围|
|quote|`string`| 酒言酒语|
|standardCupsTotal|`number`| 标准杯总数|
|createdAt|`string`| 创建时间|
**Mode**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Drank|"drank"|`Mode`|今日喝了|
|Abstain|"abstain"|`Mode`|今日未喝|
**DrinkItem**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类ID|
|brand|`string`| 品牌名称|
|product|`string`| 产品名|
|amount|`number`| 饮用量数值|
|unit|`Unit`| 单位|
|degree|`number`| 酒精度数(%)|
|standardCups|`number`| 标准杯数(前端计算,后端应校验)|
**FoodInfo**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类ID|
|name|`string`| 具体菜名|
**Feeling**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Tipsy|"tipsy"|`Feeling`|微醺|
|Buzzed|"buzzed"|`Feeling`|到位|
|Drunk|"drunk"|`Feeling`|醉了|
|Blackout|"blackout"|`Feeling`|断片|
**Visibility**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Public|"public"|`Visibility`|公开|
|Friends|"friends"|`Visibility`|仅好友|
|Private|"private"|`Visibility`|仅自己|
```javascript
const req = new GetRecordDetailReq()
client.GetRecordDetail(req).then(...).catch(...)
```
### 删除记录
<font color="green">DELETE</font> `/api/have_a_drink/v1/record/records`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new DeleteRecordReq()
client.DeleteRecord(req).then(...).catch(...)
```
### 获取日历打卡数据
<font color="green">GET</font> `/api/have_a_drink/v1/record/records/calendar`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|year|`number`|required| 年份|
|month|`number`|required,gte=1,lte=12| 月份(1-12)|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|year|`number`| 年份<br>|
|month|`number`| 月份<br>|
|days|`Array<CalendarDayData>`| 每天的打卡数据,null表示当天无记录<br>|
**CalendarDayData**
|名称|类型|说明|
|:-|:-|:-|
|date|`string`| 日期YYYY-MM-DD|
|hasRecord|`boolean`| 是否有记录|
|mode|`Mode`| 打卡模式|
|standardCupsTotal|`number`| 标准杯总数|
|id|`string\|number`| 记录ID|
|drinks|`Array<DrinkItem>`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array<string>`| 照片URL数组|
|visibility|`Visibility`| 可见范围|
|quote|`string`| 酒言酒语|
|createdAt|`string`| 创建时间|
**Mode**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Drank|"drank"|`Mode`|今日喝了|
|Abstain|"abstain"|`Mode`|今日未喝|
**DrinkItem**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类ID|
|brand|`string`| 品牌名称|
|product|`string`| 产品名|
|amount|`number`| 饮用量数值|
|unit|`Unit`| 单位|
|degree|`number`| 酒精度数(%)|
|standardCups|`number`| 标准杯数(前端计算,后端应校验)|
**FoodInfo**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类ID|
|name|`string`| 具体菜名|
**Feeling**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Tipsy|"tipsy"|`Feeling`|微醺|
|Buzzed|"buzzed"|`Feeling`|到位|
|Drunk|"drunk"|`Feeling`|醉了|
|Blackout|"blackout"|`Feeling`|断片|
**Visibility**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Public|"public"|`Visibility`|公开|
|Friends|"friends"|`Visibility`|仅好友|
|Private|"private"|`Visibility`|仅自己|
```javascript
const req = new GetCalendarReq()
client.GetCalendar(req).then(...).catch(...)
```
### 获取用户统计概览
<font color="green">GET</font> `/api/have_a_drink/v1/statistics/overview`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`StatsOverview`| 统计概览数据<br>|
**StatsOverview**
|名称|类型|说明|
|:-|:-|:-|
|weekDrinkCount|`number`| 本周饮酒天数|
|weekCups|`number`| 本周标准杯总数|
|monthDrinkCount|`number`| 本月饮酒天数|
|monthCups|`number`| 本月标准杯总数|
|streak|`number`| 当前连续打卡天数|
|streakType|`Mode`| 连续类型|
|totalDays|`number`| 总饮酒天数(去重)|
|totalRecords|`number`| 总记录数|
|totalCups|`number`| 历史累计标准杯|
|favCategory|`Category`| 最爱酒类ID|
|categoryVariety|`number`| 尝试过的酒类品种数|
**Mode**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Drank|"drank"|`Mode`|今日喝了|
|Abstain|"abstain"|`Mode`|今日未喝|
**Category**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Baijiu|"baijiu"|`Category`|白酒|
|Beer|"beer"|`Category`|啤酒|
|Wine|"wine"|`Category`|红酒|
|Whisky|"whisky"|`Category`|洋酒|
|Huangjiu|"huangjiu"|`Category`|黄酒|
|Sake|"sake"|`Category`|清酒|
|Fruit|"fruit"|`Category`|果酒|
|Cocktail|"cocktail"|`Category`|调酒|
|Other|"other"|`Category`|其他|
```javascript
const req = new GetStatsOverviewReq()
client.GetStatsOverview(req).then(...).catch(...)
```
### 获取月度统计
<font color="green">GET</font> `/api/have_a_drink/v1/statistics/monthly`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|year|`number`|| 年份,默认当前年|
|month|`number`|| 月份,默认当前月|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`MonthlyStats`| 月度统计数据<br>|
**MonthlyStats**
|名称|类型|说明|
|:-|:-|:-|
|year|`number`| 年份|
|month|`number`| 月份|
|drinkDays|`number`| 饮酒天数|
|abstainDays|`number`| 戒酒天数|
|totalCups|`number`| 总标准杯数|
|avgCupsPerDay|`number`| 日均标准杯数|
|categoryBreakdown|`Array<CategoryBreakdown>`| 酒类分布|
|feelingBreakdown|`Array<FeelingBreakdown>`| 感受分布|
|foodBreakdown|`Array<FoodBreakdown>`| 配餐分布|
**CategoryBreakdown**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类|
|count|`number`| 次数|
|cups|`number`| 标准杯数|
**FeelingBreakdown**
|名称|类型|说明|
|:-|:-|:-|
|feeling|`Feeling`| 感受类型|
|count|`number`| 次数|
**FoodBreakdown**
|名称|类型|说明|
|:-|:-|:-|
|category|`FoodCategory`| 配餐分类|
|count|`number`| 次数|
```javascript
const req = new GetMonthlyStatsReq()
client.GetMonthlyStats(req).then(...).catch(...)
```
### 获取酒类分布统计
<font color="green">GET</font> `/api/have_a_drink/v1/statistics/categories`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`CategoryStatsData`| 酒类分布统计数据<br>|
**CategoryStatsData**
|名称|类型|说明|
|:-|:-|:-|
|categories|`Array<CategoryStats>`| 酒类分布列表|
**CategoryStats**
|名称|类型|说明|
|:-|:-|:-|
|id|`Category`| 酒类分类ID|
|name|`string`| 酒类名称|
|recordCount|`number`| 记录次数|
|totalCups|`number`| 总标准杯数|
|percentage|`number`| 占比(百分比)|
```javascript
const req = new GetCategoryStatsReq()
client.GetCategoryStats(req).then(...).catch(...)
```
### 获取用户信息
<font color="green">GET</font> `/api/have_a_drink/v1/user/user/profile`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 用户ID<br>|
|nickname|`string`| 用户昵称<br>|
|avatar|`string`| 头像URL<br>|
|joinedAt|`string`| 加入时间<br>|
|preferences|`UserPreferences`| 用户偏好<br>|
**UserPreferences**
|名称|类型|说明|
|:-|:-|:-|
|favoriteCategories|`Array<Category>`| 偏好酒类ID列表|
|frequency|`Frequency`| 饮酒频率|
**Frequency**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Rarely|"rarely"|`Frequency`|很少|
|Sometimes|"sometimes"|`Frequency`|有时|
|Often|"often"|`Frequency`|经常|
```javascript
const req = new GetUserProfileReq()
client.GetUserProfile(req).then(...).catch(...)
```
### 更新用户偏好
<font color="green">PUT</font> `/api/have_a_drink/v1/user/user/preferences`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|favoriteCategories|`Array<Category>`|| 偏好酒类ID列表|
|frequency|`Frequency`|很少: Frequency.Rarely = "rarely"<br>有时: Frequency.Sometimes = "sometimes"<br>经常: Frequency.Often = "often"| 饮酒频率|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|favoriteCategories|`Array<Category>`| 偏好酒类ID列表<br>|
|frequency|`Frequency`| 饮酒频率<br>很少: Frequency.Rarely = "rarely"<br>有时: Frequency.Sometimes = "sometimes"<br>经常: Frequency.Often = "often"|
```javascript
const req = new UpdatePreferencesReq()
client.UpdatePreferences(req).then(...).catch(...)
```
### 上传文件
<font color="green">POST</font> `/api/have_a_drink/v1/upload/image`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|image|`any`|required| 图片|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 图片 id<br>|
|url|`string`| 图片 url<br>|
```javascript
const req = new UploadImageReq()
client.UploadImage(req).then(...).catch(...)
```