# 使用说明
* 喝酒了么 - 后端接口 API
* 小程序:喝酒了么(uni-app 微信小程序)
* 基础URL: /api/v1
*
* 主要功能模块:
* 1. 用户模块 - 微信登录、用户信息管理
* 2. 打卡记录模块 - 饮酒记录创建、查询、日历数据
* 3. 照片上传模块 - 单张/批量照片上传
* 4. 统计模块 - 用户统计、月度统计、酒类分布
* 5. 成就模块 - 成就列表和进度
* 6. 社交模块 - 朋友圈动态、点赞
**版本:** v1.0.4
## 安装
```
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
POST `/api/have_a_drink/v1/auth/wechat/login`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|code|`string`|required| 登录时获取的 code, 可通过 wx.login 获取|
|nickName|`string`|| 用户昵称|
|avatarUrl|`string`|| 头像URL|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|token|`string`| JWT Token
|
|user|`User`| 用户信息
|
|isNew|`boolean`| 是否新用户
|
|session_key|`string`| 会话密钥
|
|open_id|`string`| 用户唯一标识
|
|union_id|`string`| 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见 UnionID 机制说明。
|
|errcode|`number`| 错误码
|
|errmsg|`string`| 错误信息
|
|refresh_token|`string`| 刷新token
|
**User**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 用户ID|
|nickname|`string`| 用户昵称|
|avatar|`string`| 头像URL|
|joinedAt|`string`| 加入时间|
|preferences|`UserPreferences`| 用户偏好|
**UserPreferences**
|名称|类型|说明|
|:-|:-|:-|
|favoriteCategories|`Array`| 偏好酒类ID列表|
|frequency|`Frequency`| 饮酒频率|
```javascript
const req = new WechatLoginReq()
client.WechatLogin(req).then(...).catch(...)
```
### 获取微信手机号
POST `/api/have_a_drink/v1/auth/wechat/get_phone_number`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|code|`string`|required| 手机号获取凭证|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|errcode|`number`| 错误码
|
|errmsg|`string`| 错误信息
|
|token|`string`| token:api使用
|
|expires_in|`number`| token 超时时间,单位(秒)
|
|refresh_token|`string`| refresh_token:刷新token
|
```javascript
const req = new WechatGetPhoneNumberReq()
client.WechatGetPhoneNumber(req).then(...).catch(...)
```
### 刷新 token 接口
POST `/api/have_a_drink/v1/auth/refresh_token`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|refresh_token|`string`|required| 签发 token 时生成的 refresh_token|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|token|`string`| 生成的新token
|
|expire_in|`number`| token 超时时间,单位(秒)
|
|refresh_token|`string`| refresh_token:刷新token
|
```javascript
const req = new RefreshTokenReq()
client.RefreshToken(req).then(...).catch(...)
```
### 获取成就列表
GET `/api/have_a_drink/v1/achievements/list`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`AchievementsData`| 成就列表数据
|
**AchievementsData**
|名称|类型|说明|
|:-|:-|:-|
|achievements|`Array`| 成就列表|
**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(...)
```
### 获取朋友圈动态
GET `/api/have_a_drink/v1/communication/feed`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|lastId|`string\|number`|| 游标分页,上一页最后一条ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`FeedPageData`| 朋友圈动态分页数据
|
**FeedPageData**
|名称|类型|说明|
|:-|:-|:-|
|list|`Array`| 动态列表|
**FeedItem**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|user|`FeedUser`| 用户信息|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array`| 照片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`| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`| 自定义饮酒数量|
|customUnit|`Unit`| 自定义饮酒单位|
**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|
**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(...)
```
### 点赞
POST `/api/have_a_drink/v1/communication/records/like`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new LikeRecordReq()
client.LikeRecord(req).then(...).catch(...)
```
### 取消点赞
POST `/api/have_a_drink/v1/communication/records/unlike`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new LikeRecordReq()
client.UnlikeRecord(req).then(...).catch(...)
```
### 上传照片
POST `/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(...)
```
### 批量上传照片
POST `/api/have_a_drink/v1/photo/upload/photos`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|urls|`Array`|required,max=9| 图片URL数组(最多9张)|
|recordId|`string\|number`|required| 关联记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new UploadPhotosReq()
client.UploadPhotos(req).then(...).catch(...)
```
### 创建打卡记录
POST `/api/have_a_drink/v1/record/records`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|date|`string`|required| 日期 YYYY-MM-DD|
|mode|`Mode`|今日喝了: Mode.Drank = "drank"
今日未喝: Mode.Abstain = "abstain"| 打卡模式|
|drinks|`Array`|| 酒水列表(mode=abstain时为空数组)|
|food|`FoodInfo`|| 配餐信息|
|feeling|`Feeling`|微醺: Feeling.Tipsy = "tipsy"
到位: Feeling.Buzzed = "buzzed"
醉了: Feeling.Drunk = "drunk"
断片: Feeling.Blackout = "blackout"| 感受ID|
|photos|`Array`|max=9| 照片URL数组(最多9张)|
|visibility|`Visibility`|公开: Visibility.Public = "public"
仅好友: Visibility.Friends = "friends"
仅自己: 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`|| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`|| 自定义饮酒数量|
|customUnit|`Unit`|| 自定义饮酒单位|
**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|
**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`| 创建的记录详情
|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array`| 照片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`| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`| 自定义饮酒数量|
|customUnit|`Unit`| 自定义饮酒单位|
**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(...)
```
### 获取记录列表
GET `/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"
今日未喝: Mode.Abstain = "abstain"| 打卡模式筛选|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array`| 分页数据
|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array`| 照片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`| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`| 自定义饮酒数量|
|customUnit|`Unit`| 自定义饮酒单位|
**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(...)
```
### 获取单条记录详情
GET `/api/have_a_drink/v1/record/records/detail`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`Record`| 记录详情
|
**Record**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 记录ID|
|date|`string`| 日期|
|mode|`Mode`| 打卡模式|
|drinks|`Array`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array`| 照片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`| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`| 自定义饮酒数量|
|customUnit|`Unit`| 自定义饮酒单位|
**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(...)
```
### 删除记录
DELETE `/api/have_a_drink/v1/record/records`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 记录ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new DeleteRecordReq()
client.DeleteRecord(req).then(...).catch(...)
```
### 获取日历打卡数据
GET `/api/have_a_drink/v1/record/records/calendar`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|year|`number`|required| 年份|
|month|`number`|required,gte=1,lte=12| 月份(1-12)|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|year|`number`| 年份
|
|month|`number`| 月份
|
|days|`Array`| 每天的打卡数据,null表示当天无记录
|
**CalendarDayData**
|名称|类型|说明|
|:-|:-|:-|
|date|`string`| 日期YYYY-MM-DD|
|hasRecord|`boolean`| 是否有记录|
|mode|`Mode`| 打卡模式|
|standardCupsTotal|`number`| 标准杯总数|
|id|`string\|number`| 记录ID|
|drinks|`Array`| 酒水列表|
|food|`FoodInfo`| 配餐信息|
|feeling|`Feeling`| 感受|
|photos|`Array`| 照片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`| 标准杯数(前端计算,后端应校验)|
|customAmount|`number`| 自定义饮酒数量|
|customUnit|`Unit`| 自定义饮酒单位|
**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(...)
```
### 获取用户统计概览
GET `/api/have_a_drink/v1/statistics/overview`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`StatsOverview`| 统计概览数据
|
**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(...)
```
### 获取月度统计
GET `/api/have_a_drink/v1/statistics/monthly`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|year|`number`|| 年份,默认当前年|
|month|`number`|| 月份,默认当前月|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`MonthlyStats`| 月度统计数据
|
**MonthlyStats**
|名称|类型|说明|
|:-|:-|:-|
|year|`number`| 年份|
|month|`number`| 月份|
|drinkDays|`number`| 饮酒天数|
|abstainDays|`number`| 戒酒天数|
|totalCups|`number`| 总标准杯数|
|avgCupsPerDay|`number`| 日均标准杯数|
|categoryBreakdown|`Array`| 酒类分布|
|feelingBreakdown|`Array`| 感受分布|
|foodBreakdown|`Array`| 配餐分布|
**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(...)
```
### 获取酒类分布统计
GET `/api/have_a_drink/v1/statistics/categories`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|data|`CategoryStatsData`| 酒类分布统计数据
|
**CategoryStatsData**
|名称|类型|说明|
|:-|:-|:-|
|categories|`Array`| 酒类分布列表|
**CategoryStats**
|名称|类型|说明|
|:-|:-|:-|
|id|`Category`| 酒类分类ID|
|name|`string`| 酒类名称|
|recordCount|`number`| 记录次数|
|totalCups|`number`| 总标准杯数|
|percentage|`number`| 占比(百分比)|
```javascript
const req = new GetCategoryStatsReq()
client.GetCategoryStats(req).then(...).catch(...)
```
### 获取用户信息
GET `/api/have_a_drink/v1/user/user/profile`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 用户ID
|
|nickname|`string`| 用户昵称
|
|avatar|`string`| 头像URL
|
|joinedAt|`string`| 加入时间
|
|preferences|`UserPreferences`| 用户偏好
|
**UserPreferences**
|名称|类型|说明|
|:-|:-|:-|
|favoriteCategories|`Array`| 偏好酒类ID列表|
|frequency|`Frequency`| 饮酒频率|
**Frequency**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Rarely|"rarely"|`Frequency`|很少|
|Sometimes|"sometimes"|`Frequency`|有时|
|Often|"often"|`Frequency`|经常|
```javascript
const req = new GetUserProfileReq()
client.GetUserProfile(req).then(...).catch(...)
```
### 更新用户偏好
PUT `/api/have_a_drink/v1/user/user/preferences`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|favoriteCategories|`Array`|| 偏好酒类ID列表|
|frequency|`Frequency`|很少: Frequency.Rarely = "rarely"
有时: Frequency.Sometimes = "sometimes"
经常: Frequency.Often = "often"| 饮酒频率|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|favoriteCategories|`Array`| 偏好酒类ID列表
|
|frequency|`Frequency`| 饮酒频率
很少: Frequency.Rarely = "rarely"
有时: Frequency.Sometimes = "sometimes"
经常: Frequency.Often = "often"|
```javascript
const req = new UpdatePreferencesReq()
client.UpdatePreferences(req).then(...).catch(...)
```
### 上传文件
POST `/api/have_a_drink/v1/upload/image`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|image|`any`|required| 图片|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 图片 id
|
|url|`string`| 图片 url
|
```javascript
const req = new UploadImageReq()
client.UploadImage(req).then(...).catch(...)
```