Files
hejiu/node_modules/HaveADrink/README.md
T
cg 57eef74eb1 feat(sdk): 升级HaveADrink SDK并集成邀请系统
- 将HaveADrink依赖从1.0.8升级至1.0.12版本
- 集成邀请码功能,新增common/invite.js处理邀请链路
- 实现发送好友请求返回邀请码的新流程
- 添加删除动态功能,新增DeleteFeed接口
- 集成UniAppWebSocket适配器,重构WebSocket连接管理
- 优化好友请求支持关键词搜索功能
- 在FeedCard组件中添加删除按钮和分享按钮
- 更新SDK类型定义文件以匹配新接口规范
2026-08-04 23:32:45 +08:00

2047 lines
41 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.12
## 安装
```
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`| 标准杯数(前端计算,后端应校验)|
|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(...)
```
### 上传照片
<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`|| 酒类分类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`|| 配餐分类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`| 标准杯数(前端计算,后端应校验)|
|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(...)
```
### 获取记录列表
<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`| 标准杯数(前端计算,后端应校验)|
|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(...)
```
### 获取单条记录详情
<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`| 标准杯数(前端计算,后端应校验)|
|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(...)
```
### 删除记录
<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`| 标准杯数(前端计算,后端应校验)|
|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(...)
```
### 获取用户统计概览
<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(...)
```
### 动态信息流
<font color="green">GET</font> `/api/have_a_drink/v1/moments/feeds`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|lastId|`string\|number`|| 最后一条动态ID,用于分页|
|pageSize|`number`|| 每页数量|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Feed>`| 动态列表<br>|
|hasMore|`boolean`| 是否还有更多动态<br>|
**Feed**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 动态ID|
|userId|`string\|number`| 用户ID|
|nickname|`string`| 昵称|
|avatar|`string`| 头像|
|time|`string`| 发布时间|
|text|`string`| 动态文本|
|drinks|`Array<DrinkTag>`| 酒水标签|
|feeling|`Feeling`| 自我感觉|
|images|`Array<string>`| 图片列表|
|likes|`number`| 点赞数|
|liked|`boolean`| 是否点赞|
|comments|`number`| 评论数|
**DrinkTag**
|名称|类型|说明|
|:-|:-|:-|
|category|`Category`| 酒类分类|
|name|`string`| 酒类名称|
|amount|`number`| 酒类数量|
**Feeling**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Tipsy|"tipsy"|`Feeling`|微醺|
|Buzzed|"buzzed"|`Feeling`|到位|
|Drunk|"drunk"|`Feeling`|醉了|
|Blackout|"blackout"|`Feeling`|断片|
```javascript
const req = new GetFeedsReq()
client.GetFeeds(req).then(...).catch(...)
```
### 发布动态
<font color="green">POST</font> `/api/have_a_drink/v1/moments/feeds`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|text|`string`|| 动态文本|
|images|`Array<string>`|| 图片列表|
|recordId|`string\|number`|| 关联的记录ID|
|visibility|`Visibility`|公开: Visibility.Public = "public"<br>仅好友: Visibility.Friends = "friends"<br>仅自己: Visibility.Private = "private"| 可见性|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|success|`boolean`| 是否成功<br>|
|feedId|`string\|number`| 动态ID<br>|
```javascript
const req = new PublishFeedReq()
client.PublishFeed(req).then(...).catch(...)
```
### 删除动态
<font color="green">DELETE</font> `/api/have_a_drink/v1/moments/feeds`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 动态ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new DeleteFeedReq()
client.DeleteFeed(req).then(...).catch(...)
```
### 点赞
<font color="green">POST</font> `/api/have_a_drink/v1/moments/feeds/like`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 动态ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new LikeFeedReq()
client.LikeFeed(req).then(...).catch(...)
```
### 取消点赞
<font color="green">POST</font> `/api/have_a_drink/v1/moments/feeds/unlike`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 动态ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new UnlikeFeedReq()
client.UnlikeFeed(req).then(...).catch(...)
```
### 获取评论
<font color="green">GET</font> `/api/have_a_drink/v1/moments/feeds/comments`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 动态ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Comment>`| 评论列表<br>|
**Comment**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 评论ID|
|userId|`string\|number`| 用户ID|
|nickname|`string`| 昵称|
|avatar|`string`| 头像|
|content|`string`| 评论内容|
|time|`string`| 评论时间|
```javascript
const req = new GetFeedCommentsReq()
client.GetFeedComments(req).then(...).catch(...)
```
### 发表评论
<font color="green">POST</font> `/api/have_a_drink/v1/moments/feeds/comments`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 动态ID|
|content|`string`|| 评论内容|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 评论ID<br>|
|userId|`string\|number`| 用户ID<br>|
|nickname|`string`| 昵称<br>|
|avatar|`string`| 头像<br>|
|content|`string`| 评论内容<br>|
|time|`string`| 评论时间<br>|
```javascript
const req = new AddCommentFullReq()
client.AddComment(req).then(...).catch(...)
```
### 酒友管理
<font color="green">GET</font> `/api/have_a_drink/v1/friends/friends`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|keyword|`string`|| 搜索关键词|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Friend>`| 分页数据<br>|
**Friend**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 酒友ID|
|nickname|`string`| 昵称|
|avatar|`string`| 头像|
|lastDrink|`string\|number`| 最近一次喝的酒|
|lastDrinkTime|`string`| 最近一次喝的酒时间|
|online|`boolean`| 是否在线|
```javascript
const req = new GetFriendsReq()
client.GetFriends(req).then(...).catch(...)
```
### 好友请求管理
<font color="green">GET</font> `/api/have_a_drink/v1/friends/friend-requests`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|keyword|`string`|| 搜索关键词|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<FriendRequest>`| 分页数据<br>|
**FriendRequest**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 好友请求ID|
|userId|`string\|number`| 酒友ID|
|nickname|`string`| 昵称|
|avatar|`string`| 头像|
|message|`string`| 消息|
|time|`string`| 创建时间|
```javascript
const req = new GetFriendRequestsReq()
client.GetFriendRequests(req).then(...).catch(...)
```
### 发送好友请求
<font color="green">POST</font> `/api/have_a_drink/v1/friends/friend-requests`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|message|`string`|| 消息|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|inviteCode|`string\|number`| 好友请求ID<br>|
```javascript
const req = new SendFriendRequestReq()
client.SendFriendRequest(req).then(...).catch(...)
```
### 接受好友请求
<font color="green">POST</font> `/api/have_a_drink/v1/friends/friend-requests/accept`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 好友请求ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new AcceptFriendRequestReq()
client.AcceptFriendRequest(req).then(...).catch(...)
```
### 删除酒友
<font color="green">DELETE</font> `/api/have_a_drink/v1/friends/friends`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|userId|`string\|number`|| 酒友ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
```javascript
const req = new RemoveFriendReq()
client.RemoveFriend(req).then(...).catch(...)
```
### 约酒活动
<font color="green">GET</font> `/api/have_a_drink/v1/events/events`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|status|`EventStatus`|开放报名: EventStatus.Open = 1<br>待开始: EventStatus.Upcoming = 2<br>进行中: EventStatus.Ongoing = 3<br>已结束: EventStatus.Ended = 4| 状态筛选|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Event>`| 分页数据<br>|
**Event**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 酒局ID|
|title|`string`| 酒局标题|
|organizer|`User`| 酒局组织者|
|time|`string`| 酒局时间|
|location|`string`| 酒局地点|
|maxPeople|`number`| 最大人数|
|joined|`number`| 已报名人数|
|participants|`Array<User>`| 已报名用户|
|status|`EventStatus`| 酒局状态|
|note|`string`| 酒局备注|
|isJoined|`boolean`| 是否已报名|
|isOrganizer|`boolean`| 是否为组织者|
**User**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 用户ID|
|nickname|`string`| 用户昵称|
|avatar|`string`| 头像URL|
|joinedAt|`string`| 加入时间|
|preferences|`UserPreferences`| 用户偏好|
**UserPreferences**
|名称|类型|说明|
|:-|:-|:-|
|favoriteCategories|`Array<Category>`| 偏好酒类ID列表|
|frequency|`Frequency`| 饮酒频率|
**Frequency**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Rarely|"rarely"|`Frequency`|很少|
|Sometimes|"sometimes"|`Frequency`|有时|
|Often|"often"|`Frequency`|经常|
**EventStatus**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Open|1|`EventStatus`|开放报名|
|Upcoming|2|`EventStatus`|待开始|
|Ongoing|3|`EventStatus`|进行中|
|Ended|4|`EventStatus`|已结束|
```javascript
const req = new GetEventsReq()
client.GetEvents(req).then(...).catch(...)
```
### 获取酒局详情
<font color="green">GET</font> `/api/have_a_drink/v1/events/events/detail`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 酒局ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|id|`string\|number`| 酒局ID<br>|
|title|`string`| 酒局标题<br>|
|organizer|`User`| 酒局组织者<br>|
|time|`string`| 酒局时间<br>|
|location|`string`| 酒局地点<br>|
|maxPeople|`number`| 最大人数<br>|
|joined|`number`| 已报名人数<br>|
|participants|`Array<User>`| 已报名用户<br>|
|status|`EventStatus`| 酒局状态<br>开放报名: EventStatus.Open = 1<br>待开始: EventStatus.Upcoming = 2<br>进行中: EventStatus.Ongoing = 3<br>已结束: EventStatus.Ended = 4|
|note|`string`| 酒局备注<br>|
|isJoined|`boolean`| 是否已报名<br>|
|isOrganizer|`boolean`| 是否为组织者<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 GetEventDetailReq()
client.GetEventDetail(req).then(...).catch(...)
```
### 发起酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|title|`string`|| 酒局标题|
|time|`string`|| 酒局时间|
|location|`string`|| 酒局地点|
|maxPeople|`number`|| 最大人数|
|geo|`GeoPoint`|| 坐标信息|
|note|`string`|| 酒局备注|
**GeoPoint**
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|latitude|`number`|| 纬度|
|longitude|`number`|| 经度|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|eventId|`string\|number`| 酒局ID<br>|
```javascript
const req = new CreateEventReq()
client.CreateEvent(req).then(...).catch(...)
```
### 修改酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events/update`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 酒局ID|
|title|`string`|| 酒局标题|
|time|`string`|| 酒局时间|
|location|`string`|| 酒局地点|
|maxPeople|`number`|| 最大人数|
|geo|`GeoPoint`|| 坐标信息|
|note|`string`|| 酒局备注|
**GeoPoint**
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|latitude|`number`|| 纬度|
|longitude|`number`|| 经度|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new UpdateEventReq()
client.UpdateEvent(req).then(...).catch(...)
```
### 删除酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events/delete`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|required| 酒局ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new DeleteEventReq()
client.DeleteEvent(req).then(...).catch(...)
```
### 报名酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events/join`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 酒局ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new JoinEventReq()
client.JoinEvent(req).then(...).catch(...)
```
### 取消报名酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events/quit`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 酒局ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new QuitEventReq()
client.QuitEvent(req).then(...).catch(...)
```
### 签到酒局
<font color="green">POST</font> `/api/have_a_drink/v1/events/events/checkin`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string\|number`|| 酒局ID|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|ok|`boolean`| 是否成功<br>|
```javascript
const req = new CheckInEventReq()
client.CheckInEvent(req).then(...).catch(...)
```
### 获取会话列表
<font color="green">GET</font> `/api/have_a_drink/v1/chat/conversations`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Conversation>`| 会话列表<br>|
**Conversation**
|名称|类型|说明|
|:-|:-|:-|
|id|`string`| 会话ID|
|friendId|`string\|number`| 对方用户ID|
|nickname|`string`| 对方昵称|
|avatar|`string`| 对方头像URL(可为空)|
|lastMessage|`string`| 最后一条消息摘要|
|lastTime|`string`| 最后消息时间(ISO 8601|
|unread|`number`| 未读消息数|
|online|`boolean`| 对方是否在线|
```javascript
const req = new GetConversationsReq()
client.GetConversations(req).then(...).catch(...)
```
### 获取历史消息
<font color="green">GET</font> `/api/have_a_drink/v1/chat/messages`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|conversationId|`string`|required| 会话ID|
|lastID|`string\|number`|| 游标分页|
|pageSize|`number`|gt=0,lte=100| 每页数量,默认20|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|list|`Array<Message>`| 消息列表<br>|
|hasMore|`boolean`| 是否还有更多消息<br>|
**Message**
|名称|类型|说明|
|:-|:-|:-|
|id|`string\|number`| 消息ID|
|conversationId|`string`| 会话ID|
|senderId|`string\|number`| 发送者ID|
|receiverId|`string\|number`| 接收者ID|
|type|`MessageType`| 消息类型|
|content|`string`| 消息内容|
|timestamp|`number`| 发送时间(毫秒时间戳)|
|status|`MessageStatus`| 消息状态|
**MessageType**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Text|"text"|`MessageType`|文本消息|
|Image|"image"|`MessageType`|图片消息|
**MessageStatus**
|名称|值|类型|说明|
|:-|:-:|:-|:-|
|Sending|"sending"|`MessageStatus`|发送中|
|Sent|"sent"|`MessageStatus`|已发送|
|Delivered|"delivered"|`MessageStatus`|已送达|
|Read|"read"|`MessageStatus`|已读|
```javascript
const req = new GetMessagesReq()
client.GetMessages(req).then(...).catch(...)
```
### 标记会话已读
<font color="green">POST</font> `/api/have_a_drink/v1/chat/conversations/read`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|id|`string`|required| 会话ID(路径参数)|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|success|`boolean`| 是否成功<br>|
```javascript
const req = new MarkReadReq()
client.MarkRead(req).then(...).catch(...)
```
### 获取未读消息总数
<font color="green">GET</font> `/api/have_a_drink/v1/chat/unread-count`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|total|`number`| 未读总数<br>|
```javascript
const req = new GetUnreadCountReq()
client.GetUnreadCount(req).then(...).catch(...)
```
### 注意:连接建立后,服务端会先验证 token,然后推送 connected 事件
<font color="green">WS</font> `/api/have_a_drink/v1/chat/chat`
#### 请求参数
|名称|类型|校验规则|说明|
|:-|:-|:-|:-|
|mesgType|`ClientMesgType`|发送消息: ClientMesgType.Chat = "chat"<br>输入状态: ClientMesgType.Typing = "typing"<br>已读回执: ClientMesgType.Read = "read"<br>心跳: ClientMesgType.Ping = "ping"| 消息类型|
|data|`ClientMessage`|| 消息数据|
#### 返回值
|名称|类型|说明|
|:-|:-:|:-|
|mesgType|`ServerMesgType`| 消息类型<br>推送新消息: ServerMesgType.Chat = "chat"<br>对方输入状态: ServerMesgType.Typing = "typing"<br>对方已读回执: ServerMesgType.Read = "read"<br>消息送达确认: ServerMesgType.Ack = "ack"<br>心跳响应: ServerMesgType.Pong = "pong"<br>连接成功: ServerMesgType.Connected = "connected"<br>被踢下线: ServerMesgType.Kicked = "kicked"|
|data|`ServerMessage`| 消息数据<br>|
```javascript
const req = new ChatWebSocket()
client.ChatWebSocket(req).then(...).catch(...)
```