first commit
This commit is contained in:
21
Makefile
Normal file
21
Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
build_amd:
|
||||
@echo '┌ start build amd64'
|
||||
@bash ./script/build/multi-service.sh
|
||||
@echo '└ end build amd64'
|
||||
|
||||
build_arm:
|
||||
@echo '┌ start build arm64'
|
||||
@bash ./script/build/multi-service.sh arm64
|
||||
@echo '└ end build arm64'
|
||||
|
||||
# 编译二进制 amd64
|
||||
quick_build_amd:
|
||||
@echo '┌ start quick build amd64'
|
||||
@bash ./script/build/quick_build.sh
|
||||
@echo '└ end quick build amd64'
|
||||
|
||||
# 编译二进制 amr64
|
||||
quick_build_arm:
|
||||
@echo '┌ start quick build arm64'
|
||||
@bash ./script/build/quick_build.sh arm64
|
||||
@echo '└ end quick build arm64'
|
||||
22
README.md
Normal file
22
README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## 配置文件
|
||||
|
||||
```toml
|
||||
# Env 三种模式
|
||||
Env = "debug" # 测试环境
|
||||
Env = "release" # 线上环境
|
||||
Env = "benchmark" # 压测环境
|
||||
```
|
||||
|
||||
## 部署环境
|
||||
|
||||
环境需要增加以下环境变量
|
||||
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
|
||||
|
||||
## 快速部署
|
||||
|
||||
`make build_xxx` xxx 可选为 amd 或者 arm
|
||||
如果要选择平台则自行修改`dtalk/script/build/util.sh`中的`initOS()`编译设置
|
||||
|
||||
`make build` 包括编译二进制, 配置文件并打包
|
||||
|
||||
`make quick_build` 仅编译二进制
|
||||
57
doc/auth.md
Normal file
57
doc/auth.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 鉴权服务
|
||||
|
||||
#### 应用注册
|
||||
|
||||
URL: /auth/sign-in
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **约束** | **说明** |
|
||||
| -------------- | ------------ | -------- | -------- | -------- |
|
||||
| Content-Type | body中的数据类型 | string | true | 值为multipart/form-data |
|
||||
| configFile | 配置文件 | file | true | 包含第三方应用鉴权服务接口的相关信息 |
|
||||
| appId | 应用ID | text | true | 应用ID,位于请求头 |
|
||||
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **说明** |
|
||||
| ----------- | ------------ | -------- | ---------- |
|
||||
| appId | appId | string | appId |
|
||||
| key | key | string | 授权第三方应用使用本鉴权服务 |
|
||||
| createTime | 创建时间 | int | app注册时间 |
|
||||
| updateTime | 更新时间 | int | 信息更新时间 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"appId": "dtalk",
|
||||
"key": "key",
|
||||
"createTime": 1625552582748,
|
||||
"updateTime": 1625552582748
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 鉴权
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **约束** | **说明** |
|
||||
| ---------- | -------------- | -------- | -------- | ------------------------------------------------------------ |
|
||||
| appId | 应用的唯一标识 | string | true | 应用的唯一标识 |
|
||||
| token | token | string | true | 第三方鉴权所要的token |
|
||||
| digest | 消息摘要 | string | true | digest = SHA256 ( appId + token + createTime + key )(key为注册时所返回的key) |
|
||||
| createTime | 请求创建时间 | int | true | 请求创建时的时间戳 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **说明** |
|
||||
| -------- | -------- | -------- | -------- |
|
||||
| uid | 用户ID | string | 用户ID |
|
||||
406
doc/backend.md
Normal file
406
doc/backend.md
Normal file
@@ -0,0 +1,406 @@
|
||||
# 后台服务
|
||||
|
||||
#### 检查更新
|
||||
URL: /app/version/check
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **约束** | **说明** |
|
||||
| -------------- | ------------ | -------- | -------- | -------- |
|
||||
| versionCode | 当前版本 | int | true | 版本code |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **说明** |
|
||||
| ----------- | ------------ | -------- | ---------- |
|
||||
| id | 最新的版本 | int | 版本编号 |
|
||||
| platform | 平台 | string | chat33pro |
|
||||
| status | 线上状态 | int | 0:历史;1:线上版本 |
|
||||
| deviceType | 终端类型 | string | Android/IOS |
|
||||
| versionName | 版本名 | string | 3.6.8.10 |
|
||||
| versionCode | 版本code | int | 36810 |
|
||||
| url | 下载地址 | string | |
|
||||
| force | 是否强制更新 | bool | false:非强制;true:强制 |
|
||||
| description | 描述信息 | string array | |
|
||||
| opeUser | 操作者 | string | |
|
||||
| updateTime | 更新时间 | int | |
|
||||
| createTime | 创建时间 | int | |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 8,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 1,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.4",
|
||||
"versionCode": 10400,
|
||||
"url": "https://xxx",
|
||||
"force": true,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621408163504,
|
||||
"createTime": 1621396088880
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 创建版本
|
||||
|
||||
URL: /backend/version/create
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 约束 | 说明 |
|
||||
| ----------- | ------------ | ------------ | ---- | ------------------------- |
|
||||
| platform | 平台 | string | true | chat33pro |
|
||||
| description | 描述信息 | string array | true | |
|
||||
| force | 是否强制更新 | bool | true | false:非强制;true:强制 |
|
||||
| url | 下载地址 | string | true | |
|
||||
| versionCode | 版本code | int | true | 36810 |
|
||||
| versionName | 版本名 | string | true | 3.6.8.10 |
|
||||
| deviceType | 终端类型 | string | true | Android/IOS |
|
||||
| Authorization | 授权 | string | true | 用于传递token |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 说明 |
|
||||
| ----------- | ------------ | ------------ | ------------------------- |
|
||||
| version | 版本信息 | object | 创建的版本的全部信息 |
|
||||
| id | 版本编号 | int | |
|
||||
| platform | 平台 | string | chat33pro |
|
||||
| status | 线上状态 | int | 0:历史;1:线上版本 |
|
||||
| deviceType | 终端类型 | string | Android/IOS |
|
||||
| versionName | 版本名 | string | 3.6.8.10 |
|
||||
| versionCode | 版本code | int | 36810 |
|
||||
| url | 下载地址 | string | |
|
||||
| force | 是否强制更新 | bool | false:非强制;true:强制 |
|
||||
| description | 描述信息 | string array | |
|
||||
| opeUser | 操作者 | string | |
|
||||
| updateTime | 更新时间 | int | |
|
||||
| createTime | 创建时间 | int | |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"version": {
|
||||
"id": 3,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "Android",
|
||||
"versionName": "1.0.1",
|
||||
"versionCode": 10000,
|
||||
"url": "https://xxx",
|
||||
"force": true,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621394358387,
|
||||
"createTime": 1621394358387
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 更新版本
|
||||
|
||||
URL: /backend/version/update
|
||||
|
||||
`put`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 约束 | 说明 |
|
||||
| ----------- | ------------ | ------------ | ---- | ------------------------- |
|
||||
| description | 描述信息 | string array | true | |
|
||||
| force | 是否强制更新 | bool | true | false:非强制;true:强制 |
|
||||
| url | 下载地址 | string | true | |
|
||||
| versionCode | 版本code | int | true | 36810 |
|
||||
| versionName | 版本名 | string | true | 3.6.8.10 |
|
||||
| id | 版本编号 | int | true | |
|
||||
| Authorization | 授权 | string | true | 用于传递token |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 说明 |
|
||||
| ----------- | ------------ | ------------ | ------------------------- |
|
||||
| version | 版本信息 | object | 修改后的版本的全部信息 |
|
||||
| id | 版本编号 | int | |
|
||||
| platform | 平台 | string | chat33pro |
|
||||
| status | 线上状态 | int | 0:历史;1:线上版本 |
|
||||
| deviceType | 终端类型 | string | Android/IOS |
|
||||
| versionName | 版本名 | string | 3.6.8.10 |
|
||||
| versionCode | 版本code | int | 36810 |
|
||||
| url | 下载地址 | string | |
|
||||
| force | 是否强制更新 | bool | false:非强制;true:强制 |
|
||||
| description | 描述信息 | string array | |
|
||||
| opeUser | 操作者 | string | |
|
||||
| updateTime | 更新时间 | int | |
|
||||
| createTime | 创建时间 | int | |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"version": {
|
||||
"id": 3,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "Android",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 10000,
|
||||
"url": "https://xxx",
|
||||
"force": false,
|
||||
"description": [
|
||||
"xx",
|
||||
"yy"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "234567",
|
||||
"size": 2345,
|
||||
"updateTime": 1621395843469,
|
||||
"createTime": 1621394358387
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 修改版本线上状态
|
||||
|
||||
URL: /backend/version/change-status
|
||||
|
||||
`put`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 约束 | 说明 |
|
||||
| ------ | -------- | ------ | ---- | -------------------- |
|
||||
| id | 版本编号 | int | true | 要修改的版本编号 |
|
||||
| Authorization | 授权 | string | true | 用于传递token |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
无
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取全部版本信息
|
||||
|
||||
URL: /backend/version/list
|
||||
|
||||
`get`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 约束 | 说明 |
|
||||
| ---------- | -------- | ------ | ----- | ------------ |
|
||||
| page | 页码 | int | false | 从0开始,不填默认是0 |
|
||||
| platform | 平台 | string | false | 要筛选的平台 |
|
||||
| deviceType | 终端类型 | string | false | 要筛选的终端 |
|
||||
| Authorization | 授权 | string | true | 用于传递token |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 说明 |
|
||||
| ------------- | -------------- | ------------ | -------------------------- |
|
||||
| totalElements | 所有的记录条数 | int | |
|
||||
| totalPages | 总页数 | int | |
|
||||
| versionList | 版本列表 | object array | 所查询的全部版本的全部信息 |
|
||||
| id | 版本编号 | int | |
|
||||
| platform | 平台 | string | chat33pro |
|
||||
| status | 线上状态 | int | 0:历史;1:线上版本 |
|
||||
| deviceType | 终端类型 | string | Android/IOS |
|
||||
| versionName | 版本名 | string | 3.6.8.10 |
|
||||
| versionCode | 版本code | int | 36810 |
|
||||
| url | 下载地址 | string | |
|
||||
| force | 是否强制更新 | bool | false:非强制;true:强制 |
|
||||
| description | 描述信息 | string array | |
|
||||
| opeUser | 操作者 | string | |
|
||||
| updateTime | 更新时间 | int | |
|
||||
| createTime | 创建时间 | int | |
|
||||
| size | 包大小 | int | 单位:byte |
|
||||
| md5 | 包的md5 | string | |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"totalElements": 5,
|
||||
"totalPages": 1,
|
||||
"versionList": [
|
||||
{
|
||||
"id": 12,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 10000,
|
||||
"url": "https://xxx",
|
||||
"force": false,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621396134321,
|
||||
"createTime": 1621396134321
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 1,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.1",
|
||||
"versionCode": 10100,
|
||||
"url": "https://xxx",
|
||||
"force": true,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621396320416,
|
||||
"createTime": 1621396123534
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.2",
|
||||
"versionCode": 10200,
|
||||
"url": "https://xxx",
|
||||
"force": true,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621396117028,
|
||||
"createTime": 1621396117028
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.3",
|
||||
"versionCode": 10300,
|
||||
"url": "https://xxx",
|
||||
"force": false,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621396108579,
|
||||
"createTime": 1621396108579
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"platform": "Chat33Pro",
|
||||
"status": 0,
|
||||
"deviceType": "IOS",
|
||||
"versionName": "1.0.4",
|
||||
"versionCode": 10400,
|
||||
"url": "https://xxx",
|
||||
"force": true,
|
||||
"description": [
|
||||
"qqq",
|
||||
"ww"
|
||||
],
|
||||
"opeUser": "root",
|
||||
"md5": "12345",
|
||||
"size": 123,
|
||||
"updateTime": 1621396320416,
|
||||
"createTime": 1621396088880
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取token
|
||||
|
||||
URL: /backend/user/login
|
||||
|
||||
`get`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 约束 | 说明 |
|
||||
| -------- | ------ | ------ | ---- | ------------ |
|
||||
| userName | 用户名 | string | true | 暂时为“root” |
|
||||
| password | 口令 | string | true | 暂时为“root” |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数 | 名字 | 类型 | 说明 |
|
||||
| ----- | ----- | ------ | ---- |
|
||||
| userInfo | 用户信息 | object |包含用户名和token |
|
||||
| userName | 用户名 | string | |
|
||||
| token | token | string | |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"userInfo": {
|
||||
"userName": "root",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvb3QiLCJleHAiOjE2MjA5ODcyMDEsImlzcyI6IkJvYiJ9.w_NoSezjjJLRJMjiU4jiMYozdYvL6NPwv2xuCMepws4"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
516
doc/backupApi.md
Normal file
516
doc/backupApi.md
Normal file
@@ -0,0 +1,516 @@
|
||||
# 找回服务
|
||||
### 手机绑定查询
|
||||
URL: /backup/phone-query
|
||||
|
||||
`get`|`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"exists":false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 邮箱绑定查询
|
||||
URL: /backup/email-query
|
||||
|
||||
`get`|`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ---- |
|
||||
| email | true | string | 邮箱 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"exists":false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 发送手机验证码
|
||||
URL: /backup/v2/phone-send
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ----- | ------ | ------ |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| codeType | true | string | 验证码类型:quick->快速登录;bind->绑定;export->导出通讯录 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 发送邮箱验证码
|
||||
|
||||
URL: /backup/v2/email-send
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ---- |
|
||||
| email | true | string | 邮箱 |
|
||||
| codeType | true | string | 验证码类型:quick->快速登录;bind->绑定;export->导出通讯录 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 绑定手机
|
||||
|
||||
URL: /backup/v2/phone-binding
|
||||
|
||||
`post`|`auth`
|
||||
|
||||
type: bind
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ----- | ------ | ---------- |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 绑定邮箱
|
||||
|
||||
URL: /backup/v2/email-binding
|
||||
|
||||
`post`|`auth`
|
||||
|
||||
type: bind
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ---- | ------ | ---------- |
|
||||
| email | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 手机找回私钥
|
||||
|
||||
URL: /backup/v2/phone-retrieve
|
||||
|
||||
`post`
|
||||
|
||||
type: quick
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ----------- | ---- | ------ | ---------- |
|
||||
| address | true | string | 用户地址 |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| email | true | string | 邮箱 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
| update_time | true | string | 更新时间 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"address": "0xffffffff",
|
||||
"area":"",
|
||||
"phone":"",
|
||||
"email":"",
|
||||
"mnemonic":"",
|
||||
"update_time":""
|
||||
}
|
||||
}
|
||||
```
|
||||
### 邮箱找回私钥
|
||||
|
||||
URL: /backup/v2/email-retrieve
|
||||
|
||||
`post`
|
||||
|
||||
type: quick
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| email | true | string | 邮箱 |
|
||||
| code | true | string | 验证码 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ----------- | ---- | ------ | ---------- |
|
||||
| address | true | string | 用户地址 |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| email | true | string | 邮箱 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
| update_time | true | string | 更新时间 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"address": "0xffffffff",
|
||||
"area":"",
|
||||
"phone":"",
|
||||
"email":"",
|
||||
"mnemonic":"",
|
||||
"update_time":""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 手机导出通讯录验证
|
||||
|
||||
URL: /backup/v2/phone-export
|
||||
|
||||
`post`
|
||||
|
||||
type: export
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
| address | true | string | 地址 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
ERR:-4010 账号与绑定手机不一致
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 邮箱导出通讯录验证
|
||||
|
||||
URL: /backup/v2/email-export
|
||||
|
||||
`post`
|
||||
|
||||
type: export
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| email | true | string | 邮箱 |
|
||||
| code | true | string | 验证码 |
|
||||
| address | true | string | 地址 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
ERR:-4011 账号与绑定邮箱不一致
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 修改助记词(修改密聊密码)
|
||||
|
||||
URL: /backup/edit-mnemonic
|
||||
|
||||
`post`|`auth`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ---- | ------ | ---------- |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 发送手机验证码
|
||||
URL: /backup/phone-send(弃用)
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ----- | ------ | ------ |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 发送邮箱验证码
|
||||
|
||||
URL: /backup/email-send(弃用)
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ---- |
|
||||
| email | true | string | 邮箱 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 绑定手机
|
||||
|
||||
URL: /backup/phone-binding(弃用)
|
||||
|
||||
`post`|`auth`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ----- | ------ | ---------- |
|
||||
| area | false | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 绑定邮箱
|
||||
|
||||
URL: /backup/email-binding(弃用)
|
||||
|
||||
`post`|`auth`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ---- | ------ | ---------- |
|
||||
| email | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 手机找回私钥
|
||||
|
||||
URL: /backup/phone-retrieve(弃用)
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| code | true | string | 验证码 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ----------- | ---- | ------ | ---------- |
|
||||
| address | true | string | 用户地址 |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| email | true | string | 邮箱 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
| update_time | true | string | 更新时间 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"address": "0xffffffff",
|
||||
"area":"",
|
||||
"phone":"",
|
||||
"email":"",
|
||||
"mnemonic":"",
|
||||
"update_time":""
|
||||
}
|
||||
}
|
||||
```
|
||||
### 邮箱找回私钥
|
||||
|
||||
URL: /backup/email-retrieve(弃用)
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| email | true | string | 邮箱 |
|
||||
| code | true | string | 验证码 |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ----------- | ---- | ------ | ---------- |
|
||||
| address | true | string | 用户地址 |
|
||||
| area | true | string | 区号 |
|
||||
| phone | true | string | 手机号 |
|
||||
| email | true | string | 邮箱 |
|
||||
| mnemonic | true | string | 加密助记词 |
|
||||
| update_time | true | string | 更新时间 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"address": "0xffffffff",
|
||||
"area":"",
|
||||
"phone":"",
|
||||
"email":"",
|
||||
"mnemonic":"",
|
||||
"update_time":""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### bty和btc地址映射(第一阶段)
|
||||
|
||||
URL: /backup/transform/addressEnrolment
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| btcAddress | true | string | |
|
||||
| ethAddress | true | string | |
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ----------- | ---- | ------ | ---------- |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
42
doc/discoveryApi.md
Normal file
42
doc/discoveryApi.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# 发现服务
|
||||
#### 获取聊天服务列表
|
||||
URL: /disc/nodes
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**无
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| 参数名 | 必填 | 类型 | 说明 |
|
||||
| ------- | ---- | -------- | -------------- |
|
||||
| servers | true | []object | 聊天服务器列表 |
|
||||
| name | true | string | 名称 |
|
||||
| address | true | string | 地址 |
|
||||
| nodes | true | []object | 合约节点列表 |
|
||||
| name | true | string | 名称 |
|
||||
| address | true | string | 地址 |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"servers": [
|
||||
{
|
||||
"name": "默认服务器",
|
||||
"address":"127.0.0.1:8080"
|
||||
},{
|
||||
"name": "默认服务器2",
|
||||
"address":"chat.33.cn"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"name": "合约节点1",
|
||||
"address":"127.0.0.1:8080"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
95
doc/gateway.md
Normal file
95
doc/gateway.md
Normal file
@@ -0,0 +1,95 @@
|
||||
#### 获取模块启用状态
|
||||
URL: /app/modules/all
|
||||
|
||||
`post`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
无
|
||||
|
||||
**返回参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **说明** |
|
||||
| ----------- | ------------ | -------- | ---------- |
|
||||
| name | 模块名称 | string | 钱包模块:wallet,企业模块:oa,红包模块:redpacket |
|
||||
| isEnabled | 是否启用 | bool | |
|
||||
| endPoints | 模块访问地址 | string | |
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": [
|
||||
{
|
||||
"name": "wallet",
|
||||
"isEnabled": true,
|
||||
"endPoints": [
|
||||
"https://172.16.101.126:8083"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "oa",
|
||||
"isEnabled": true,
|
||||
"endPoints": [
|
||||
"http://127.0.0.1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 消息撤回
|
||||
URL: /app/record/revoke
|
||||
|
||||
`post`
|
||||
**请求参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **约束** | **说明** |
|
||||
| ----------- | ------------ | -------- | ---------- |---------- |
|
||||
| type | 类型 | int | 必填 | 0->撤回私聊消息;1->撤回群聊消息 |
|
||||
| logId | 消息id | int64 | 必填| |
|
||||
|
||||
```json
|
||||
{
|
||||
"type": 0,
|
||||
"logId": 0
|
||||
}
|
||||
```
|
||||
|
||||
**返回参数:**
|
||||
无
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
#### 关注消息
|
||||
URL: /app/record/focus
|
||||
|
||||
`post` `auth`
|
||||
**请求参数:**
|
||||
|
||||
| **参数** | **名字** | **类型** | **约束** | **说明** |
|
||||
| ----------- | ------------ | -------- | ---------- |---------- |
|
||||
| type | 类型 | int | 必填 | 0->关注私聊消息;1->关注群聊消息 |
|
||||
| logId | 消息id | int64 | 必填| |
|
||||
|
||||
```json
|
||||
{
|
||||
"type": 0,
|
||||
"logId": 0
|
||||
}
|
||||
```
|
||||
|
||||
**返回参数:**
|
||||
无
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
758
doc/group.md
Normal file
758
doc/group.md
Normal file
@@ -0,0 +1,758 @@
|
||||
# 以最新swagger为准
|
||||
[http://172.16.101.107:8888/group/swagger/index.html](http://172.16.101.107:8888/group/swagger/index.html)
|
||||
|
||||
## 群服务
|
||||
|
||||
|
||||
测试地址 172.16.101.107:8888/group/app
|
||||
|
||||
|
||||
|
||||
## 已完成接口
|
||||
|
||||
| 路由 | 说明 |
|
||||
| ------------------------------------- | ---------- |
|
||||
| `POST` URL: /app/create-group | 创建群 |
|
||||
| `POST` URL:/app /invite-group-members | 邀请新群友 |
|
||||
| `POST` URL: /app/group-info | 群信息 |
|
||||
| `POST` URL: /app/group-list | 群列表 |
|
||||
| `POST` URL: /app/group-member-list | 群成员列表 |
|
||||
| `POST`URL:/app/group-member-info | 群成员信息 |
|
||||
| `POST` URL:/app/group-remove | 踢群成员 |
|
||||
| `POST` URL:/app/group-exit | 退出群 |
|
||||
| `POST` URL:/app/group-disband | 解散群 |
|
||||
|
||||
|
||||
|
||||
|
||||
### 创建群+
|
||||
|
||||
`POST` URL: /app/create-group
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| --------- | ----- | -------- | ---------- |
|
||||
| name | false | string | 群名称 |
|
||||
| avatar | false | string | 群头像 url |
|
||||
| introduce | false | string | 群简介 |
|
||||
| memberIds | false | []string | 新群员 id |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"memberIds": [
|
||||
"member-1", "member-2"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------------ | ------------------------------------------------------------ |
|
||||
| id | int | 群id |
|
||||
| markId | string | 群短 id(暂时没用, 后面可以供搜索加群使用) |
|
||||
| name | string | 群名称 |
|
||||
| avatar | string | 群头像 url |
|
||||
| introduce | string | 群简介 |
|
||||
| owner | MemberInfo | 群主信息 |
|
||||
| members | []MemberInfo | 群成员信息list |
|
||||
| memberNum | int | 群总人数 |
|
||||
| maximum | int | 群成员人数上限 |
|
||||
| status | int | 群状态,0=正常 1=封禁 2=解散 |
|
||||
| createTime | int | 群创建时间 |
|
||||
| joinType | int | 加群方式,0=允许任何方式加群,1=群成员邀请加群,2=群主和管理员邀请加群 |
|
||||
| muteType | int | 禁言, 0=所有人可以发言, 1=群主和管理员可以发言 |
|
||||
|
||||
|
||||
|
||||
**MemberInfo 参数类型**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------ |
|
||||
| memberId | string | 用户id |
|
||||
| memberName | string | 用户群昵称 |
|
||||
| memberType | int | 用户角色,2=群主,1=管理员,0=群员,3=退群 |
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 127043701116506112,
|
||||
"markId": "00351854",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
"memberId": "member-1",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-2",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
}
|
||||
],
|
||||
"memberNum": 3,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621230378707,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 邀请新群友+
|
||||
|
||||
`POST` URL: /app/invite-group-members
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------------ | ---- | -------- | ---------- |
|
||||
| id | true | int64 | 群ID |
|
||||
| newMemberIds | true | []string | 被邀请人ID |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 127043701116506112,
|
||||
"newMemberIds": [
|
||||
"member-5",
|
||||
"member-6"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------------ | ----------------- |
|
||||
| id | int | 群id |
|
||||
| memberNum | int | 群总人数 |
|
||||
| inviter | MemberInfo | 邀请人信息 |
|
||||
| newMembers | []MemberInfo | 被邀请人信息 list |
|
||||
|
||||
|
||||
|
||||
**MemberInfo 参数类型**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------ |
|
||||
| memberId | string | 用户id |
|
||||
| memberName | string | 用户群昵称 |
|
||||
| memberType | int | 用户角色,2=群主,1=管理员,0=群员,3=退群 |
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 125290793882619904,
|
||||
"memberNum": 5,
|
||||
"inviter": {
|
||||
"memberId": "chenhongyu",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
"newMembers": [
|
||||
{
|
||||
"memberId": "member-4",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 群信息+
|
||||
|
||||
`POST` URL: /app/group-info
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ---- | ---- |
|
||||
| id | true | int | 群ID |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
{
|
||||
"id":127082931377147904
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------------ | ------------------------------------------------------------ |
|
||||
| id | int | 群id |
|
||||
| markId | string | 群短 id(暂时没用, 后面可以供搜索加群使用) |
|
||||
| name | string | 群名称 |
|
||||
| avatar | string | 群头像 url |
|
||||
| introduce | string | 群简介 |
|
||||
| owner | MemberInfo | 群主信息 |
|
||||
| person | MemberInfo | 本人信息 |
|
||||
| members | []MemberInfo | 所有群成员信息list |
|
||||
| memberNum | int | 群总人数 |
|
||||
| maximum | int | 群成员人数上限 |
|
||||
| status | int | 群状态,0=正常 1=封禁 2=解散 |
|
||||
| createTime | int | 群创建时间 |
|
||||
| joinType | int | 加群方式,0=允许任何方式加群,1=群成员邀请加群,2=群主和管理员邀请加群 |
|
||||
| muteType | int | 禁言, 0=所有人可以发言, 1=群主和管理员可以发言 |
|
||||
|
||||
|
||||
|
||||
**MemberInfo 参数类型**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------ |
|
||||
| memberId | string | 用户id |
|
||||
| memberName | string | 用户群昵称 |
|
||||
| memberType | int | 用户角色,0=群主,1=管理员,2=群员,3=退群 |
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 127043701116506112,
|
||||
"markId": "",
|
||||
"name": "",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"members": [
|
||||
{
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
{
|
||||
"memberId": "member-1",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-2",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-5",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-6",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
}
|
||||
],
|
||||
"memberNum": 5,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621230378707,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 群列表+
|
||||
|
||||
`GET` | `POST` URL: /app/group-list
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ---- | ---- |
|
||||
| | | | |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ------ | ----------- | ----------- |
|
||||
| groups | []GroupInfo | 群信息 list |
|
||||
|
||||
|
||||
|
||||
**GroupInfo:**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ---------- | ------------------------------------------------------------ |
|
||||
| id | int | 群id |
|
||||
| markId | string | 群短 id(暂时没用, 后面可以供搜索加群使用) |
|
||||
| name | string | 群名称 |
|
||||
| avatar | string | 群头像 url |
|
||||
| introduce | string | 群简介 |
|
||||
| owner | MemberInfo | 群主信息 |
|
||||
| memberNum | int | 群总人数 |
|
||||
| maximum | int | 群成员人数上限 |
|
||||
| status | int | 群状态,0=正常 1=封禁 2=解散 |
|
||||
| createTime | int | 群创建时间 |
|
||||
| joinType | int | 加群方式,0=允许任何方式加群,1=群成员邀请加群,2=群主和管理员邀请加群 |
|
||||
| muteType | int | 禁言, 0=所有人可以发言, 1=群主和管理员可以发言 |
|
||||
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"groups": [
|
||||
{
|
||||
"id": 127043701116506112,
|
||||
"markId": "00351854",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"memberNum": 5,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621230378707,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
},
|
||||
{
|
||||
"id": 127067012814868480,
|
||||
"markId": "62025607",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"memberNum": 5,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621235936650,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
},
|
||||
{
|
||||
"id": 127082931377147904,
|
||||
"markId": "88951481",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"memberNum": 11,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621239731935,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
},
|
||||
{
|
||||
"id": 127100214044528640,
|
||||
"markId": "43833969",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"memberNum": 3,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621243852439,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
},
|
||||
{
|
||||
"id": 127485592593240064,
|
||||
"markId": "00865442",
|
||||
"name": "test-group-1",
|
||||
"avatar": "",
|
||||
"introduce": "",
|
||||
"owner": {
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
"memberNum": 9,
|
||||
"maximum": 200,
|
||||
"status": 0,
|
||||
"createTime": 1621335733857,
|
||||
"joinType": 0,
|
||||
"muteType": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 群成员列表+
|
||||
|
||||
`POST` URL: /app/group-member-list
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ----- | ---- |
|
||||
| id | true | int64 | 群ID |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 127082931377147904
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ------- | ------------ | --------------- |
|
||||
| id | int | 群id |
|
||||
| members | []MemberInfo | 全部群成员 list |
|
||||
|
||||
|
||||
|
||||
**MemberInfo 参数类型**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------ |
|
||||
| memberId | string | 用户id |
|
||||
| memberName | string | 用户群昵称 |
|
||||
| memberType | int | 用户角色,0=群主,1=管理员,2=群员,3=退群 |
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 127043701116506112,
|
||||
"members": [
|
||||
{
|
||||
"memberId": "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR",
|
||||
"memberName": "",
|
||||
"memberType": 2
|
||||
},
|
||||
{
|
||||
"memberId": "member-1",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-2",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-5",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
},
|
||||
{
|
||||
"memberId": "member-6",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 群成员信息+
|
||||
|
||||
URL: /app/group-member-info
|
||||
|
||||
`GET`
|
||||
|
||||
|
||||
|
||||
**Herder**
|
||||
|
||||
`FZM-SIGNATURE` = token
|
||||
|
||||
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| -------- | ---- | ------ | --------- |
|
||||
| id | true | int | 群ID |
|
||||
| memberId | true | string | 群成员 ID |
|
||||
|
||||
|
||||
|
||||
**请求参数示例**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 125290793882619904,
|
||||
"memberId": "123"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
**返回参数(data):**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ---------- | ------ |
|
||||
| id | int | 群id |
|
||||
| newMembers | MemberInfo | 群成员 |
|
||||
|
||||
|
||||
|
||||
**MemberInfo 参数类型**
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ---------- | ------ | ------------------------------------------ |
|
||||
| memberId | string | 用户id |
|
||||
| memberName | string | 用户群昵称 |
|
||||
| memberType | int | 用户角色,0=群主,1=管理员,2=群员,3=退群 |
|
||||
|
||||
|
||||
|
||||
**返回参数示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "",
|
||||
"data": {
|
||||
"memberId": "member-1",
|
||||
"memberName": "",
|
||||
"memberType": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### 踢人+
|
||||
|
||||
`POST` URL: /app/group-remove
|
||||
|
||||
|
||||
|
||||
### 退群+
|
||||
|
||||
`POST` URL:/app/group-exit
|
||||
|
||||
|
||||
|
||||
### 解散群
|
||||
|
||||
URL: /disband-group
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
|
||||
### 更新群头像
|
||||
|
||||
URL: /update-group-avatar
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 更新群名称
|
||||
|
||||
URL: /update-group-name
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 更新个人群昵称(自己改自己的, 群主和管理员改所有人)
|
||||
|
||||
URL: /update-group-member-name
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 更新群简介
|
||||
|
||||
URL: /update-group-introduce
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 更新加群权限设置
|
||||
|
||||
URL: /update-group-join-type
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 更新群成员类型
|
||||
|
||||
URL: /update-group-member-type
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 转移群给群成员
|
||||
|
||||
URL: /update-group-owner
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 更新群状态
|
||||
|
||||
URL: /update-group-status
|
||||
|
||||
`PUT`
|
||||
|
||||
|
||||
|
||||
### 更新群成员上限
|
||||
|
||||
URL: /update-group-maximum
|
||||
|
||||
`PUT`
|
||||
60
doc/ossApi.md
Normal file
60
doc/ossApi.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 对象存储服务
|
||||
### 获取token
|
||||
URL: /oss/get-token
|
||||
|
||||
`get`|`post`
|
||||
|
||||
**请求参数:**
|
||||
无
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"RequestId": "E7A855E3-0A3B-479A-BF22-416A2D5D27B1",
|
||||
"Credentials": {
|
||||
"AccessKeySecret": "BxbYXWGjKrVT4qSzi6ZoLtD1qjZLAfNaULreCMb7EsYm",
|
||||
"Expiration": "2021-02-24T07:48:21Z",
|
||||
"AccessKeyId": "STS.NUrf45xSfTX7EkJxoo3G7C9Cm",
|
||||
"SecurityToken": "CAIS8wF1q6Ft5B2yfSjIr5bHLY6BlYxH45rcR037nG86P8gbrPzojzz2IHhNfXlqBeket/g1n2hY5/oelqN1TIVATEiBZNNotm32E/M0Jdivgde8yJBZor/HcDHhJnyW9cvWZPqDP7G5U/yxalfCuzZuyL/hD1uLVECkNpv74vwOLK5gPG+CYCFBGc1dKyZ7tcYeLgGxD/u2NQPwiWeiZygB+CgE0DkhtfTvkp3Ht0OP1wOhk9V4/dqhfsKWCOB3J4p6XtuP2+h7S7HMyiY46WIRrP4v3PYYoG+e4ovGWwkAv0mcUezT6NhmKEpwfrAq7DDiSR5ZYpcagAEcYDFBCF3QY2aQ8Jcs9L4utLb7Z6JdPvyG/zF7l7P1Br0MX0ad6sgWEGWTvTuxemRtmKSWxMEivRzx+6aT515Y7OQdFyX1uLrR1YOq9R2tjysh2d54wu09qr7BhPavADSFHj8fCrZugoul6vHtoslRgL+KSpuI3buhZ08VDxh5rg=="
|
||||
},
|
||||
"AssumedRoleUser": {
|
||||
"AssumedRoleId": "301182410142308944:normal-app",
|
||||
"Arn": "acs:ram::1264888835193631:role/normal-app/normal-app"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取华为云token
|
||||
URL: /oss/get-huaweiyun-token
|
||||
|
||||
`get`|`post`
|
||||
|
||||
**请求参数:**
|
||||
无
|
||||
|
||||
**返回参数:**
|
||||
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
"RequestId": "",
|
||||
"Credentials": {
|
||||
"AccessKeySecret": "BxbYXWGjKrVT4qSzi6ZoLtD1qjZLAfNaULreCMb7EsYm",
|
||||
"Expiration": "2021-02-24T07:48:21Z",
|
||||
"AccessKeyId": "NUrf45xSfTX7EkJxoo3G7C9Cm",
|
||||
"SecurityToken": "CAIS8wF1q6Ft5B2yfSjIr5bHLY6BlYxH45rcR037nG86P8gbrPzojzz2IHhNfXlqBeket/g1n2hY5/oelqN1TIVATEiBZNNotm32E/M0Jdivgde8yJBZor/HcDHhJnyW9cvWZPqDP7G5U/yxalfCuzZuyL/hD1uLVECkNpv74vwOLK5gPG+CYCFBGc1dKyZ7tcYeLgGxD/u2NQPwiWeiZygB+CgE0DkhtfTvkp3Ht0OP1wOhk9V4/dqhfsKWCOB3J4p6XtuP2+h7S7HMyiY46WIRrP4v3PYYoG+e4ovGWwkAv0mcUezT6NhmKEpwfrAq7DDiSR5ZYpcagAEcYDFBCF3QY2aQ8Jcs9L4utLb7Z6JdPvyG/zF7l7P1Br0MX0ad6sgWEGWTvTuxemRtmKSWxMEivRzx+6aT515Y7OQdFyX1uLrR1YOq9R2tjysh2d54wu09qr7BhPavADSFHj8fCrZugoul6vHtoslRgL+KSpuI3buhZ08VDxh5rg=="
|
||||
},
|
||||
"AssumedRoleUser": {
|
||||
"AssumedRoleId": "",
|
||||
"Arn": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
248
doc/proto.md
Normal file
248
doc/proto.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# 应用方消息子协议
|
||||
|
||||
**协议格式:**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| :----- | :--- | :--- | :--- |
|
||||
|eventType | true | int32 | 事件类型 |
|
||||
|body | true | byte[] | 消息体 |
|
||||
|
||||
## 事件类型
|
||||
| 类型 | 说明 |
|
||||
| :----- | :--- |
|
||||
| 0 | 普通消息 |
|
||||
| 1 | 消息回复 |
|
||||
| 2 | 通知信令 |
|
||||
|
||||
|
||||
## 普通消息
|
||||
**body描述(encode:proto序列化)**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| :----- | :--- | :--- | :--- |
|
||||
|channelType | true | int32 | 消息通道 |
|
||||
|logId | true | int64 | 消息id |
|
||||
|msgId | true | string | 客户端序列 |
|
||||
|from | true | string | 发送者 |
|
||||
|target | true | string | 接收者 |
|
||||
|msgType | true | int32 | 消息类型 |
|
||||
|msg | true | binary | 消息体 |
|
||||
|datetime | true | uint64 | 事件戳,ms |
|
||||
|source | true | Source | 来源,详见如下 |
|
||||
|
||||
Source结构:
|
||||
```
|
||||
message Source {
|
||||
int32 channelType=1;
|
||||
SourceUser from=2;
|
||||
SourceUser target=3;
|
||||
}
|
||||
|
||||
message SourceUser {
|
||||
string id=1;
|
||||
string name=2;
|
||||
}
|
||||
```
|
||||
|
||||
### 消息通道
|
||||
| 类型 | 说明 |
|
||||
| :----- | :--- |
|
||||
| 0 | 单聊 |
|
||||
| 1 | 群聊 |
|
||||
|
||||
### 消息类型
|
||||
| 类型 | 说明 |
|
||||
| :----- | :--- |
|
||||
| 0 | 系统消息 |
|
||||
| 1 | 文本消息 |
|
||||
| 2 | 音频消息 |
|
||||
| 3 | 图片消息 |
|
||||
| 4 | 视频消息 |
|
||||
| 5 | 文件消息 |
|
||||
| 6 | 卡片消息 |
|
||||
| 7 | 通知消息 |
|
||||
| 8 | 合并转发 |
|
||||
|
||||
注意:msg 必须可以反序列化为msgType相对应的结构体
|
||||
具体协议参考 `pkg/proto/api.proto`
|
||||
|
||||
```
|
||||
message TextMsg {
|
||||
string content = 1;
|
||||
repeated string mentions = 2;
|
||||
}
|
||||
|
||||
message AudioMsg {
|
||||
string mediaUrl = 1;
|
||||
int32 time = 2;
|
||||
}
|
||||
|
||||
message ImageMsg {
|
||||
string mediaUrl = 1;
|
||||
int32 height = 2;
|
||||
int32 width = 3;
|
||||
}
|
||||
|
||||
message VideoMsg {
|
||||
string mediaUrl = 1;
|
||||
int32 time = 2;
|
||||
int32 height = 3;
|
||||
int32 width = 4;
|
||||
}
|
||||
|
||||
message FileMsg {
|
||||
string mediaUrl = 1;
|
||||
string name = 2;
|
||||
string md5 = 3;
|
||||
int64 size = 4;
|
||||
}
|
||||
|
||||
message CardMsg {
|
||||
string bank = 1;
|
||||
string name = 2;
|
||||
string account = 3;
|
||||
}
|
||||
|
||||
message NoticeMsg {
|
||||
AlertType type = 1;
|
||||
bytes body = 2;
|
||||
}
|
||||
|
||||
message ForwardMsg {
|
||||
repeated ForwardItem items = 1;
|
||||
}
|
||||
|
||||
message ForwardItem {
|
||||
string avatar=1;
|
||||
string name=2;
|
||||
int32 msgType=3;
|
||||
bytes msg=4;
|
||||
uint64 datetime=5;
|
||||
}
|
||||
```
|
||||
|
||||
#### 通知消息
|
||||
##### 通知类型
|
||||
| 类型 | 说明 |
|
||||
| :----- | :--- |
|
||||
| 0 | 修改群名 |
|
||||
| 1 | 加群 |
|
||||
| 2 | 退群 |
|
||||
| 3 | 踢群 |
|
||||
| 4 | 删群 |
|
||||
| 5 | 群禁言模式更改 |
|
||||
| 6 | 更改禁言名单 |
|
||||
|
||||
注意:body必须可以反序列化为AlertType相对应的结构体
|
||||
具体协议参考 `pkg/proto/api.proto`
|
||||
|
||||
```
|
||||
message AlertUpdateGroupName {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
string name = 3;
|
||||
}
|
||||
|
||||
message AlertSignInGroup {
|
||||
int64 group = 1;
|
||||
string inviter = 2;
|
||||
repeated string members = 3;
|
||||
}
|
||||
|
||||
message AlertSignOutGroup {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
}
|
||||
|
||||
message AlertKickOutGroup {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
repeated string members = 3;
|
||||
}
|
||||
|
||||
message AlertDeleteGroup {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
}
|
||||
|
||||
message AlertUpdateGroupMuted {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
MuteType type = 3;
|
||||
}
|
||||
|
||||
message AlertUpdateGroupMemberMutedTime {
|
||||
int64 group = 1;
|
||||
string operator = 2;
|
||||
repeated string members = 3;
|
||||
}
|
||||
```
|
||||
|
||||
### Receive_Reply协议格式
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| :----- | :--- | :--- | :--- |
|
||||
|eventType | true | int32 | 事件类型 |
|
||||
|body | true | byte[] | 消息体 |
|
||||
|
||||
当eventType为0时,body必须可以被反序列化为CommonMsgAck
|
||||
```
|
||||
message CommonMsgAck {
|
||||
int64 logId = 2;
|
||||
uint64 datetime = 8;
|
||||
}
|
||||
```
|
||||
|
||||
## 通知信令
|
||||
**body描述(encode:proto序列化)**
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| :----- | :--- | :--- | :--- |
|
||||
|action | true | ActionType | 信令类型 |
|
||||
|body | true | binary | 消息体 |
|
||||
```
|
||||
//alert msg define
|
||||
message NotifyMsg {
|
||||
ActionType action = 1;
|
||||
bytes body = 2;
|
||||
}
|
||||
```
|
||||
### 信令类型
|
||||
| 类型 | 说明 |
|
||||
| :----- | :--- |
|
||||
| 0 | 送达 |
|
||||
| 1 | 加群 |
|
||||
| 2 | 退群 |
|
||||
| 3 | 删群 |
|
||||
| 20 | 更新加群权限 |
|
||||
| 21 | 更新群加好友权限 |
|
||||
| 22 | 更新群禁言类型 |
|
||||
| 23 | 更新群成员 |
|
||||
| 24 | 更新禁言列表 |
|
||||
| 25 | 更新群名 |
|
||||
| 26 | 更新群头像 |
|
||||
|
||||
注意:body必须可反序列化为ActionType对应的结构体。
|
||||
具体参考 `pkg/proto/api.proto`
|
||||
|
||||
```
|
||||
message ActionReceived {
|
||||
repeated uint64 logs = 1;
|
||||
}
|
||||
|
||||
message ActionSignInGroup {
|
||||
repeated string uid = 1;
|
||||
int64 group = 2;
|
||||
uint64 time = 3;
|
||||
}
|
||||
|
||||
message ActionSignOutGroup {
|
||||
repeated string uid = 1;
|
||||
int64 group = 2;
|
||||
uint64 time = 3;
|
||||
}
|
||||
|
||||
message ActionDeleteGroup {
|
||||
int64 group = 1;
|
||||
uint64 time = 2;
|
||||
}
|
||||
```
|
||||
33
doc/recordApi.md
Normal file
33
doc/recordApi.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 找回服务
|
||||
### 发送消息
|
||||
URL: /record/push2
|
||||
|
||||
`post`
|
||||
**Request Headers**
|
||||
- Content-Type: multipart/form-data
|
||||
|
||||
**Body:**`form-data`
|
||||
|
||||
| 参数名 | 必选 | 类型 | 说明 |
|
||||
| ------ | ---- | ------ | ------ |
|
||||
| name | true | string | 区号 |
|
||||
| filename | true | string | 手机号 |
|
||||
|
||||
**请求示例**
|
||||
```
|
||||
请求头:
|
||||
Content-Type=multipart/form-data
|
||||
请求参数:
|
||||
name="message"
|
||||
filename="message"
|
||||
```
|
||||
|
||||
**返回参数:**
|
||||
```json
|
||||
{
|
||||
"result": 0,
|
||||
"message": "操作成功",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
```
|
||||
11
doc/root.md
Normal file
11
doc/root.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# 总览
|
||||
## 约定
|
||||
- 数据类型`datetime`:时间戳,毫秒(ms)
|
||||
- 所有 `http` 接口请求都是 `POST` 方法, 数据请求和返回结果 都是 `JSON` 格式
|
||||
- Header: 接口里需要的
|
||||
- `FZM-SIGNATURE`(地址):格式[<signature>#<message>#<publicKey>]; signature格式:[<datetime>*<random string>]
|
||||
- `FZM-DEVICE`(设备类型):枚举 iOS、Android、PC
|
||||
- `FZM-UUID`(设备mac)
|
||||
- `FZM-DEVICE-NAME`(设备名称)
|
||||
- `FZM-VERSION` (应用版本号)
|
||||
- 返回结果的 `result` 为 `0` 代表成功,`data` 里面是具体数据,`result` 不为 `0` 代表失败,`message` 为失败信息
|
||||
32
gateway/api/READMD.md
Normal file
32
gateway/api/READMD.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Gateway
|
||||
|
||||
业务网关层往往又被称作业务聚合层,该层由若干个业务服务构成,负责接收通用网关转发过来的流量。核心作用如下:
|
||||
|
||||
### 1. 路由管理
|
||||
|
||||
业务网关层的服务负责自己服务的路由表维护。
|
||||
|
||||
### 2. 参数校验
|
||||
|
||||
业务网关层的服务负责执行与客户端约定的参数校验,验证通过之后再组装成后端微服务需要的数据结构请求到后端。
|
||||
|
||||
### 3. 权限校验
|
||||
|
||||
各个业务网关层的服务通过底层的用户服务调用来实现权限校验,对于哪些路由需要权限校验,哪些路由不需要,完全由业务网关层的服务自行维护。
|
||||
|
||||
### 4. 接口聚合
|
||||
|
||||
业务网关层的服务可能需要调用多个后端的微服务来组合实现一个接口,根据自身需求来对下层返回的数据进行聚合和处理。
|
||||
|
||||
### 5. 协议转换
|
||||
|
||||
业务网关层的服务接收转发过来的HTTP请求,并转换为内部的一个或者多个GRPC微服务调用来实现接口逻辑。
|
||||
|
||||
### 6. 数据转换
|
||||
|
||||
业务网关层的服务的输入和输出数据结构必须是表示层需要的,因此它所负责的数据结构和后端GRPC微服务的数据结构会不一样。业务网关层的服务需要负责数据结构的转换和封装处理。
|
||||
|
||||
> gateway 里不应该有复杂业务逻辑
|
||||
>
|
||||
|
||||
文档路径 : http://172.16.101.107:8888/swagger/index.html
|
||||
45
gateway/api/v1/CHANGELOG.md
Normal file
45
gateway/api/v1/CHANGELOG.md
Normal file
@@ -0,0 +1,45 @@
|
||||
版本号`major.minor.patch`具体规则如下:
|
||||
|
||||
- major:主版本号,如有重大版本重构则该字段递增,通常各主版本间接口不兼容。
|
||||
- minor:次版本号,各次版本号间接口保持兼容,如有接口新增或优化则该字段递增。
|
||||
- patch:补丁号,如有功能改善或缺陷修复则该字段递增。
|
||||
|
||||
## version 0.1.0 2022_01_20
|
||||
|
||||
**Feature**
|
||||
|
||||
- 增加 `group` 相关 api 接口
|
||||
|
||||
## version 0.0.8
|
||||
|
||||
**Feature**
|
||||
|
||||
- 更新gateway下服务修改signal和noticemsg名称 2021_12_07_17_52_18
|
||||
|
||||
## version 0.0.7
|
||||
|
||||
**配置文件新增**
|
||||
|
||||
所有 `[xxxRPCClient]` 增加 `RegAddrs = "127.0.0.1:2379"` 字段
|
||||
|
||||
**Feature**
|
||||
- 更新 etcdv3.5.0 v0.0.7 2021.11.03
|
||||
|
||||
## version 0.0
|
||||
|
||||
**Feature**
|
||||
- 模块开启接口 @v0.0.2
|
||||
- 撤回消息 @v0.0.4
|
||||
- 改用 imparse 中的 proto @v0.0.5 2021.10.14
|
||||
- 新增撤回消息时限配置文件 v0.0.6 2021.10.22
|
||||
|
||||
|
||||
## example x.x.x @yy.mm.dd
|
||||
|
||||
**Feature**
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
**Improvement**
|
||||
|
||||
**Breaking Change**
|
||||
48
gateway/api/v1/Makefile
Normal file
48
gateway/api/v1/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
# golang1.9 or latest
|
||||
# 1. make help
|
||||
# 2. make dep
|
||||
# 3. make build
|
||||
# ...
|
||||
|
||||
VERSION := $(shell echo $(shell cat gateway.go | grep "projectVersion =" | cut -d '=' -f2))
|
||||
APP_NAME := gateway
|
||||
BUILD_DIR := build
|
||||
APP := ${BUILD_DIR}/${APP_NAME}_v${VERSION}
|
||||
PKG_NAME := ${APP_NAME}_v${VERSION}
|
||||
PKG := ${PKG_NAME}.tar.gz
|
||||
|
||||
main_path = "main"
|
||||
go_version = $(shell go version | awk '{ print $3 }')
|
||||
build_time = $(shell date "+%Y-%m-%d %H:%M:%S %Z")
|
||||
git_commit = $(shell git rev-parse --short=10 HEAD)
|
||||
flags := -ldflags "-X '${main_path}.goVersion=${go_version}' \
|
||||
-X '${main_path}.buildTime=${build_time}' \
|
||||
-X '${main_path}.gitCommit=${git_commit}' \
|
||||
-X 'google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'"
|
||||
|
||||
.PHONY: clean build pkg
|
||||
|
||||
swag:
|
||||
@echo '┌ start gen swag'
|
||||
@swag init -g internal/handler/routes.go
|
||||
@echo '└ end gen swag'
|
||||
|
||||
clean: ## Remove previous build
|
||||
@rm -rf ${BUILD_DIR}
|
||||
@go clean
|
||||
|
||||
build: swag #checkgofmt ## Build the binary file
|
||||
GOOS=linux GOARCH=amd64 GO111MODULE=on GOPROXY=https://goproxy.cn,direct GOSUMDB="sum.golang.google.cn" go build -v $(flags) -o $(APP)
|
||||
|
||||
pkg: build ## Package
|
||||
mkdir -p ${PKG_NAME}/bin
|
||||
mkdir -p ${PKG_NAME}/etc
|
||||
cp ${APP} ${PKG_NAME}/bin/
|
||||
cp etc/* ${PKG_NAME}/etc/
|
||||
tar zvcf ${PKG} ${PKG_NAME}
|
||||
rm -rf ${PKG_NAME}
|
||||
|
||||
REMOTE_BIN_PATH := /opt/dtalk/srv/app/bin
|
||||
upload: build
|
||||
rsync -r $(APP) 107:$(REMOTE_BIN_PATH)
|
||||
ssh 107 "cd $(REMOTE_BIN_PATH) && chmod 777 $(PKG_NAME) && ln -sf $(PKG_NAME) $(APP_NAME) && supervisorctl restart $(APP_NAME)"
|
||||
2330
gateway/api/v1/docs/docs.go
Normal file
2330
gateway/api/v1/docs/docs.go
Normal file
File diff suppressed because it is too large
Load Diff
2270
gateway/api/v1/docs/swagger.json
Normal file
2270
gateway/api/v1/docs/swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
1447
gateway/api/v1/docs/swagger.yaml
Normal file
1447
gateway/api/v1/docs/swagger.yaml
Normal file
File diff suppressed because it is too large
Load Diff
63
gateway/api/v1/etc/gateway.toml
Normal file
63
gateway/api/v1/etc/gateway.toml
Normal file
@@ -0,0 +1,63 @@
|
||||
env = "debug"
|
||||
|
||||
[server]
|
||||
addr = "0.0.0.0:19000"
|
||||
|
||||
[Trace]
|
||||
ServiceName = "gateway"
|
||||
Gen128Bit = true
|
||||
[Trace.Sampler]
|
||||
Type = "const"
|
||||
Param = 1.0
|
||||
[Trace.Reporter]
|
||||
LogSpans = true
|
||||
LocalAgentHostPort = "127.0.0.1:6831"
|
||||
|
||||
[AnswerRPCClient]
|
||||
RegAddrs = "127.0.0.1:2379"
|
||||
Schema = "dtalk"
|
||||
SrvName = "answer"
|
||||
Dial = "1s"
|
||||
Timeout = "1s"
|
||||
|
||||
[StoreRPCClient]
|
||||
RegAddrs = "127.0.0.1:2379"
|
||||
Schema = "dtalk"
|
||||
SrvName = "store"
|
||||
Dial = "1s"
|
||||
Timeout = "1s"
|
||||
|
||||
[GroupRPCClient]
|
||||
RegAddrs = "127.0.0.1:2379"
|
||||
Schema = "dtalk"
|
||||
SrvName = "group"
|
||||
Dial = "1s"
|
||||
Timeout = "1s"
|
||||
|
||||
[[modules]]
|
||||
Name = "wallet"
|
||||
IsEnabled = true
|
||||
EndPoints = ["http://172.16.101.87:8901","http://172.16.101.107:8083"] # changeme (1. 红包服务 http 服务地址, 2. 钱包服务 http 服务地址)
|
||||
|
||||
[[modules]]
|
||||
Name = "redPacket"
|
||||
IsEnabled = true
|
||||
EndPoints = ["http://172.16.101.87:8901","http://172.16.101.107:8083"] # changeme (1. 红包服务 http 服务地址, 2. 钱包服务 http 服务地址)
|
||||
|
||||
[[modules]]
|
||||
Name = "oa"
|
||||
IsEnabled = true
|
||||
EndPoints = ["http://127.0.0.1:20000"] # changeme (oa 服务地址)
|
||||
|
||||
[[modules]]
|
||||
Name = "shop"
|
||||
IsEnabled = true
|
||||
EndPoints = ["http://146.56.218.121:12009"] # changeme (链上购服务地址)
|
||||
|
||||
[[modules]]
|
||||
Name="live"
|
||||
IsEnabled=true
|
||||
EndPoints=[""]
|
||||
|
||||
[Revoke]
|
||||
Expire = "86400h" #ten years (撤回消息有效时间)
|
||||
106
gateway/api/v1/gateway.go
Normal file
106
gateway/api/v1/gateway.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/config"
|
||||
http "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/im-pkg/trace"
|
||||
)
|
||||
|
||||
const srvName = "gateway"
|
||||
|
||||
var (
|
||||
// projectVersion 项目版本
|
||||
projectVersion = "0.1.2"
|
||||
// goVersion go版本
|
||||
goVersion = ""
|
||||
// gitCommit git提交commit id
|
||||
gitCommit = ""
|
||||
// buildTime 编译时间
|
||||
buildTime = ""
|
||||
|
||||
isShowVersion = flag.Bool("v", false, "show project version")
|
||||
)
|
||||
|
||||
// showVersion 显示项目版本信息
|
||||
func showVersion(isShow bool) {
|
||||
if isShow {
|
||||
fmt.Printf("Project: %s\n", srvName)
|
||||
fmt.Printf(" Version: %s\n", projectVersion)
|
||||
fmt.Printf(" Go Version: %s\n", goVersion)
|
||||
fmt.Printf(" Git Commit: %s\n", gitCommit)
|
||||
fmt.Printf(" Build Time: %s\n", buildTime)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// @Title 聊天网关
|
||||
// @Version 0.1
|
||||
// @Description
|
||||
// @SecurityDefinitions.ApiKey ApiKeyAuth
|
||||
// @In header
|
||||
// @Name Authorization
|
||||
// @BasePath /
|
||||
func main() {
|
||||
flag.Parse()
|
||||
showVersion(*isShowVersion)
|
||||
|
||||
if err := config.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//log init
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout}).With().Str("service", srvName).Logger()
|
||||
zerolog.SetGlobalLevel(zerolog.InfoLevel)
|
||||
|
||||
log.Info().
|
||||
Interface("Modules", config.Conf.Modules).
|
||||
Interface("Server", config.Conf.Server).
|
||||
Msg("config info")
|
||||
|
||||
//trace init
|
||||
tracer, tracerCloser := trace.Init(srvName, config.Conf.Trace)
|
||||
//不然后续不会有Jaeger实例
|
||||
opentracing.SetGlobalTracer(tracer)
|
||||
|
||||
// service init
|
||||
ctx := svc.NewServiceContext(*config.Conf)
|
||||
httpSrv := http.Init(ctx)
|
||||
|
||||
// init signal
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||
for {
|
||||
s := <-c
|
||||
log.Info().Str("signal", s.String()).Msg("service get a signal")
|
||||
switch s {
|
||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err := httpSrv.Shutdown(ctx); err != nil {
|
||||
log.Error().Err(err).Msg("server shutdown")
|
||||
}
|
||||
if err := tracerCloser.Close(); err != nil {
|
||||
log.Error().Err(err).Msg("tracer close failed")
|
||||
}
|
||||
time.Sleep(time.Second * 2)
|
||||
log.Info().Str("name", srvName).Msg("server exit")
|
||||
return
|
||||
case syscall.SIGHUP:
|
||||
// TODO reload
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
106
gateway/api/v1/internal/config/config.go
Normal file
106
gateway/api/v1/internal/config/config.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/uber/jaeger-client-go"
|
||||
traceConfig "github.com/uber/jaeger-client-go/config"
|
||||
xtime "gitlab.33.cn/chat/dtalk/pkg/time"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
confPath string
|
||||
|
||||
Conf *Config
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&confPath, "conf", "gateway.toml", "default config path.")
|
||||
}
|
||||
|
||||
// Init init config.
|
||||
func Init() (err error) {
|
||||
Conf = Default()
|
||||
_, err = toml.DecodeFile(confPath, &Conf)
|
||||
return
|
||||
}
|
||||
|
||||
func Default() *Config {
|
||||
return &Config{
|
||||
Env: "debug",
|
||||
Server: &HttpServer{
|
||||
Addr: "0.0.0.0:18002",
|
||||
},
|
||||
Trace: traceConfig.Configuration{
|
||||
ServiceName: "gateway",
|
||||
Gen128Bit: true,
|
||||
Sampler: &traceConfig.SamplerConfig{
|
||||
Type: jaeger.SamplerTypeConst,
|
||||
Param: 1,
|
||||
},
|
||||
Reporter: &traceConfig.ReporterConfig{
|
||||
LogSpans: true,
|
||||
LocalAgentHostPort: "127.0.0.1:6831",
|
||||
},
|
||||
},
|
||||
Revoke: &Revoke{
|
||||
Expire: xtime.Duration(time.Hour * 24),
|
||||
},
|
||||
AnswerRPCClient: &RPCClient{
|
||||
RegAddrs: "127.0.0.1:2379",
|
||||
Schema: "dtalk",
|
||||
SrvName: "answer",
|
||||
Dial: xtime.Duration(time.Second),
|
||||
Timeout: xtime.Duration(time.Second),
|
||||
},
|
||||
StoreRPCClient: &RPCClient{
|
||||
RegAddrs: "127.0.0.1:2379",
|
||||
Schema: "dtalk",
|
||||
SrvName: "store",
|
||||
Dial: xtime.Duration(time.Second),
|
||||
Timeout: xtime.Duration(time.Second),
|
||||
},
|
||||
GroupRPCClient: &RPCClient{
|
||||
RegAddrs: "127.0.0.1:2379",
|
||||
Schema: "dtalk",
|
||||
SrvName: "group",
|
||||
Dial: xtime.Duration(time.Second),
|
||||
Timeout: xtime.Duration(time.Second),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Env string
|
||||
Server *HttpServer
|
||||
Trace traceConfig.Configuration
|
||||
Modules []Module
|
||||
Revoke *Revoke
|
||||
AnswerRPCClient *RPCClient
|
||||
StoreRPCClient *RPCClient
|
||||
GroupRPCClient *RPCClient
|
||||
}
|
||||
|
||||
type HttpServer struct {
|
||||
Addr string
|
||||
}
|
||||
|
||||
// RPCClient is RPC client config.
|
||||
type RPCClient struct {
|
||||
RegAddrs string // etcd addrs, seperate by ','
|
||||
Schema string
|
||||
SrvName string // call
|
||||
Dial xtime.Duration
|
||||
Timeout xtime.Duration
|
||||
}
|
||||
|
||||
type Module struct {
|
||||
Name string `json:"name"` // enums: wallet、oa、redpacket
|
||||
IsEnabled bool `json:"isEnabled"`
|
||||
EndPoints []string `json:"endPoints"`
|
||||
}
|
||||
|
||||
type Revoke struct {
|
||||
Expire xtime.Duration
|
||||
}
|
||||
27
gateway/api/v1/internal/handler/account/userloginhandler.go
Normal file
27
gateway/api/v1/internal/handler/account/userloginhandler.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
)
|
||||
|
||||
// AddressLogin
|
||||
// @Summary 用户登录
|
||||
// @Description 内部接口,comet层使用
|
||||
// @Author dld@33.cn
|
||||
// @Tags account 账户模块
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Success 200 {object} model.GeneralResponse{data=model.AddressLoginResp}
|
||||
// @Router /user/login [post]
|
||||
func AddressLogin(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set(api.ReqResult, &model.AddressLoginResp{
|
||||
Address: c.MustGet(api.Address).(string),
|
||||
})
|
||||
c.Set(api.ReqError, nil)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/change_owner.go
Normal file
45
gateway/api/v1/internal/handler/group/change_owner.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// ChangeOwnerHandler
|
||||
// @Summary 转让群
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.ChangeOwnerReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.ChangeOwnerResp}
|
||||
// @Router /group/app/change-owner [post]
|
||||
func ChangeOwnerHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.ChangeOwnerReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.ChangeOwner(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
35
gateway/api/v1/internal/handler/group/create_group.go
Normal file
35
gateway/api/v1/internal/handler/group/create_group.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
)
|
||||
|
||||
// CreateGroupHandler
|
||||
// @Summary 创建群
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.CreateGroupReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.CreateGroupResp}
|
||||
// @Router /group/app/create-group [post]
|
||||
func CreateGroupHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.CreateGroupReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.CreateGroup(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/get_group_info.go
Normal file
45
gateway/api/v1/internal/handler/group/get_group_info.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GetGroupInfoHandler
|
||||
// @Summary 查询群信息
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetGroupInfoReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetGroupInfoResp}
|
||||
// @Router /group/app/group-info [post]
|
||||
func GetGroupInfoHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetGroupInfoReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetPriGroupInfo(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
29
gateway/api/v1/internal/handler/group/get_group_list.go
Normal file
29
gateway/api/v1/internal/handler/group/get_group_list.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
)
|
||||
|
||||
// GetGroupListHandler
|
||||
// @Summary 查询群列表
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetGroupListReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetGroupListResp}
|
||||
// @Router /app/group-list [post]
|
||||
func GetGroupListHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetGroupListReq{}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetGroupList(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GetGroupMemberInfoHandler
|
||||
// @Summary 查询群成员信息
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群成员信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetGroupMemberInfoReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetGroupMemberInfoResp}
|
||||
// @Router /group/app/group-member-info [post]
|
||||
func GetGroupMemberInfoHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetGroupMemberInfoReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetGroupMemberInfo(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GetGroupMemberListHandler
|
||||
// @Summary 查询群成员列表
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群成员信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetGroupMemberListReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetGroupMemberListResp}
|
||||
// @Router /group/app/group-member-list [post]
|
||||
func GetGroupMemberListHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetGroupMemberListReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetGroupMemberList(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/get_mute_list.go
Normal file
45
gateway/api/v1/internal/handler/group/get_mute_list.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GetMuteListHandler
|
||||
// @Summary 查询群内被禁言成员名单
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 禁言
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetMuteListReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetMuteListResp}
|
||||
// @Router /app/mute-list [post]
|
||||
func GetMuteListHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetMuteListReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetMuteList(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/get_pub_group_info.go
Normal file
45
gateway/api/v1/internal/handler/group/get_pub_group_info.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GetGroupPubInfoHandler
|
||||
// @Summary 查询群公开信息
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GetGroupPubInfoReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GetGroupPubInfoResp}
|
||||
// @Router /group/app/group-pub-info [post]
|
||||
func GetGroupPubInfoHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GetGroupPubInfoReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GetPubGroupInfo(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/group_disband.go
Normal file
45
gateway/api/v1/internal/handler/group/group_disband.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GroupDisbandHandler
|
||||
// @Summary 解散群
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GroupDisbandReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GroupDisbandResp}
|
||||
// @Router /group/app/group-disband [post]
|
||||
func GroupDisbandHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GroupDisbandReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GroupDisband(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/group_exit.go
Normal file
45
gateway/api/v1/internal/handler/group/group_exit.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GroupExitHandler
|
||||
// @Summary 退群
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GroupExitReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GroupExitResp}
|
||||
// @Router /group/app/group-exit [post]
|
||||
func GroupExitHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GroupExitReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GroupExit(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/group_remove.go
Normal file
45
gateway/api/v1/internal/handler/group/group_remove.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// GroupRemoveHandler
|
||||
// @Summary 踢人
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.GroupRemoveReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.GroupRemoveResp}
|
||||
// @Router /group/app/group-remove [post]
|
||||
func GroupRemoveHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.GroupRemoveReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.GroupRemove(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// InviteGroupMembersHandler
|
||||
// @Summary 邀请新群员
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.InviteGroupMembersReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.InviteGroupMembersResp}
|
||||
// @Router /group/app/invite-group-members [post]
|
||||
func InviteGroupMembersHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.InviteGroupMembersReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.InviteGroupMembers(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/join_group.go
Normal file
45
gateway/api/v1/internal/handler/group/join_group.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// JoinGroupHandler
|
||||
// @Summary 直接进群
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群动作
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.JoinGroupReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.JoinGroupResp}
|
||||
// @Router /group/app/join-group [post]
|
||||
func JoinGroupHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.JoinGroupReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.JoinGroup(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/set_admin.go
Normal file
45
gateway/api/v1/internal/handler/group/set_admin.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// SetAdminHandler
|
||||
// @Summary 设置管理员
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群成员信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.SetAdminReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.SetAdminResp}
|
||||
// @Router /group/app/member/type [post]
|
||||
func SetAdminHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.SetAdminReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.SetAdmin(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/update_group_avatar.go
Normal file
45
gateway/api/v1/internal/handler/group/update_group_avatar.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupAvatarHandler
|
||||
// @Summary 更新群头像
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupAvatarReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupAvatarResp}
|
||||
// @Router /group/app/avatar [post]
|
||||
func UpdateGroupAvatarHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupAvatarReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupAvatar(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupFriendTypeHandler
|
||||
// @Summary 更新群内加好友设置
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupFriendTypeReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupFriendTypeResp}
|
||||
// @Router /group/app/friendType [post]
|
||||
func UpdateGroupFriendTypeHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupFriendTypeReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupFriendType(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupJoinTypeHandler
|
||||
// @Summary 更新群内加好友设置
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupJoinTypeReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupJoinTypeResp}
|
||||
// @Router /group/app/joinType [post]
|
||||
func UpdateGroupJoinTypeHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupJoinTypeReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupJoinType(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupMemberMuteTimeHandler
|
||||
// @Summary 更新群成员禁言时间
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 禁言
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupMemberMuteTimeReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupMemberMuteTimeResp}
|
||||
// @Router /group/app/member/muteTime [post]
|
||||
func UpdateGroupMemberMuteTimeHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupMemberMuteTimeReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupMemberMuteTime(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupMemberNameHandler
|
||||
// @Summary 更新群成员昵称
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群成员信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupMemberNameReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupMemberNameResp}
|
||||
// @Router /group/app/member/name [post]
|
||||
func UpdateGroupMemberNameHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupMemberNameReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupMemberName(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupMuteTypeHandler
|
||||
// @Summary 更新群内加好友设置
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupMuteTypeReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupMuteTypeResp}
|
||||
// @Router /group/app/muteType [post]
|
||||
func UpdateGroupMuteTypeHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupMuteTypeReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupMuteType(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
45
gateway/api/v1/internal/handler/group/update_group_name.go
Normal file
45
gateway/api/v1/internal/handler/group/update_group_name.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/group"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
// UpdateGroupNameHandler
|
||||
// @Summary 更新群名称
|
||||
// @Author chy@33.cn
|
||||
// @Tags group 群信息
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body types.UpdateGroupNameReq false "body"
|
||||
// @Success 200 {object} types.GeneralResp{data=types.UpdateGroupNameResp}
|
||||
// @Router /group/app/name [post]
|
||||
func UpdateGroupNameHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &types.UpdateGroupNameReq{}
|
||||
err := c.ShouldBind(req)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if req.Id == 0 && req.IdStr == "" {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError))
|
||||
return
|
||||
}
|
||||
|
||||
if req.IdStr != "" {
|
||||
req.Id = convert.ToInt64(req.IdStr)
|
||||
}
|
||||
|
||||
l := logic.NewGroupLogic(c, ctx)
|
||||
res, err := l.UpdateGroupName(req)
|
||||
|
||||
c.Set(api.ReqResult, res)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
34
gateway/api/v1/internal/handler/modules/getmoduleshandler.go
Normal file
34
gateway/api/v1/internal/handler/modules/getmoduleshandler.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
)
|
||||
|
||||
// GetModulesHandler
|
||||
// @Summary 获取模块启用状态
|
||||
// @Description
|
||||
// @Author dld@33.cn
|
||||
// @Tags startup 初始化模块
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.GeneralResponse{data=[]model.GetModuleResp}
|
||||
// @Router /app/modules/all [post]
|
||||
func GetModulesHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
modules := ctx.Config().Modules
|
||||
var ret = make([]model.GetModuleResp, len(modules))
|
||||
for i, v := range modules {
|
||||
ret[i] = model.GetModuleResp{
|
||||
Name: v.Name,
|
||||
IsEnabled: v.IsEnabled,
|
||||
EndPoints: v.EndPoints,
|
||||
}
|
||||
}
|
||||
c.Set(api.ReqResult, ret)
|
||||
c.Set(api.ReqError, nil)
|
||||
}
|
||||
}
|
||||
48
gateway/api/v1/internal/handler/record/focushandler.go
Normal file
48
gateway/api/v1/internal/handler/record/focushandler.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/record"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
)
|
||||
|
||||
//@Summary 关注消息
|
||||
//@Description
|
||||
//@Author dld@33.cn
|
||||
//@Tags record 消息模块
|
||||
//@Accept json
|
||||
//@Produce json
|
||||
//@Param FZM-SIGNATURE header string true "MOCK"
|
||||
//@Param data body model.FocusMsgReq true "body"
|
||||
//@Success 200 {object} model.GeneralResponse{}
|
||||
//@Router /app/record/focus [post]
|
||||
func FocusHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &model.FocusMsgReq{}
|
||||
if err := c.ShouldBind(req); err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
var err error
|
||||
operator := c.MustGet(api.Address).(string)
|
||||
l := record.NewLogic(c.Request.Context(), ctx)
|
||||
switch req.Type {
|
||||
case model.Private:
|
||||
err = l.FocusPersonal(operator, req.LogId)
|
||||
case model.Group:
|
||||
err = l.FocusGroup(operator, req.LogId)
|
||||
default:
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("undefined type"))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.CodeInnerError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
c.Set(api.ReqResult, nil)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
142
gateway/api/v1/internal/handler/record/pushhandler.go
Normal file
142
gateway/api/v1/internal/handler/record/pushhandler.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/record"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
comet "gitlab.33.cn/chat/im/api/comet/grpc"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// PushToUid
|
||||
// @Summary 推送消息
|
||||
// @Description comet.Proto由接口组装,客户端只需传入comet.Proto的body部分
|
||||
// @Author dld@33.cn
|
||||
// @Tags record 消息模块
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param message body string true "消息协议序列化"
|
||||
// @Success 200 {object} model.GeneralResponse{}
|
||||
// @Router /record/push [post]
|
||||
func PushToUid(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("MultipartForm"+err.Error()))
|
||||
return
|
||||
}
|
||||
files := form.File["message"]
|
||||
|
||||
if len(files) < 1 {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("file len less than 1"))
|
||||
return
|
||||
}
|
||||
|
||||
//file, err := c.FormFile("")
|
||||
file := files[0]
|
||||
f, err := file.Open()
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("Open File"+err.Error()))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ReadAll"+err.Error()))
|
||||
return
|
||||
}
|
||||
if len(body) == 0 {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("error message length 0"))
|
||||
return
|
||||
}
|
||||
p := comet.Proto{
|
||||
Ver: 1,
|
||||
Op: int32(comet.Op_SendMsg),
|
||||
Seq: 0,
|
||||
Ack: 0,
|
||||
Body: body,
|
||||
}
|
||||
data, err := proto.Marshal(&p)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.SendMsgFailed).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
uid := c.MustGet(api.Address).(string)
|
||||
l := record.NewLogic(c.Request.Context(), ctx)
|
||||
mid, createTime, err := l.Push("", uid, data)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.SendMsgFailed).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
ret := map[string]interface{}{
|
||||
"logId": mid,
|
||||
"datetime": createTime,
|
||||
}
|
||||
c.Set(api.ReqResult, ret)
|
||||
c.Set(api.ReqError, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// PushToUid2
|
||||
// @Summary 推送消息2
|
||||
// @Description comet.Proto由客户端传入
|
||||
// @Author dld@33.cn
|
||||
// @Tags record 消息模块
|
||||
// @Accept mpfd
|
||||
// @Produce json
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param message body string true "消息协议序列化"
|
||||
// @Success 200 {object} model.GeneralResponse{}
|
||||
// @Router /record/push2 [post]
|
||||
func PushToUid2(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("MultipartForm"+err.Error()))
|
||||
return
|
||||
}
|
||||
files := form.File["message"]
|
||||
|
||||
if len(files) < 1 {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("file len less than 1"))
|
||||
return
|
||||
}
|
||||
|
||||
//file, err := c.FormFile("")
|
||||
file := files[0]
|
||||
f, err := file.Open()
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("Open File"+err.Error()))
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("ReadAll"+err.Error()))
|
||||
return
|
||||
}
|
||||
if len(body) == 0 {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("error message length 0"))
|
||||
return
|
||||
}
|
||||
uid := c.MustGet(api.Address).(string)
|
||||
l := record.NewLogic(c.Request.Context(), ctx)
|
||||
mid, createTime, err := l.Push("", uid, body)
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.SendMsgFailed).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
ret := map[string]interface{}{
|
||||
"logId": mid,
|
||||
"datetime": createTime,
|
||||
}
|
||||
c.Set(api.ReqResult, ret)
|
||||
c.Set(api.ReqError, nil)
|
||||
}
|
||||
}
|
||||
46
gateway/api/v1/internal/handler/record/recordhandler.go
Normal file
46
gateway/api/v1/internal/handler/record/recordhandler.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/record"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
)
|
||||
|
||||
// GetPriRecords
|
||||
// @Summary 获得聊天记录
|
||||
// @Author chy@33.cn
|
||||
// @Tags record 消息模块
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body model.GetPriRecordsReq false "body"
|
||||
// @Success 200 {object} model.GeneralResponse{data=model.GetPriRecordsResp}
|
||||
// @Router /app/pri-chat-record [post]
|
||||
func GetPriRecords(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &model.GetPriRecordsReq{}
|
||||
if err := c.ShouldBind(req); err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
userId, ok := c.Get(api.Address)
|
||||
if !ok {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.SignatureInvalid))
|
||||
return
|
||||
}
|
||||
req.FromId = userId.(string)
|
||||
|
||||
if req.Mid == "" {
|
||||
req.Mid = "999999999999999999"
|
||||
}
|
||||
|
||||
l := record.NewLogic(c.Request.Context(), ctx)
|
||||
data, err := l.GetPriRecord(req)
|
||||
c.Set(api.ReqResult, data)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
49
gateway/api/v1/internal/handler/record/revokehandler.go
Normal file
49
gateway/api/v1/internal/handler/record/revokehandler.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/record"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
)
|
||||
|
||||
// RevokeHandler
|
||||
// @Summary 撤回消息
|
||||
// @Description
|
||||
// @Author dld@33.cn
|
||||
// @Tags record 消息模块
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param FZM-SIGNATURE header string true "MOCK"
|
||||
// @Param data body model.RevokeMsgReq true "body"
|
||||
// @Success 200 {object} model.GeneralResponse{}
|
||||
// @Router /app/record/revoke [post]
|
||||
func RevokeHandler(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
req := &model.RevokeMsgReq{}
|
||||
if err := c.ShouldBind(req); err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
var err error
|
||||
operator := c.MustGet(api.Address).(string)
|
||||
l := record.NewLogic(c.Request.Context(), ctx)
|
||||
switch req.Type {
|
||||
case model.Private:
|
||||
err = l.RevokePersonal(operator, req.Mid)
|
||||
case model.Group:
|
||||
err = l.RevokeGroup(operator, req.Mid)
|
||||
default:
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.ParamsError).SetExtMessage("undefined type"))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
c.Set(api.ReqError, xerror.NewError(xerror.CodeInnerError).SetExtMessage(err.Error()))
|
||||
return
|
||||
}
|
||||
c.Set(api.ReqResult, nil)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
152
gateway/api/v1/internal/handler/routes.go
Normal file
152
gateway/api/v1/internal/handler/routes.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
zlog "github.com/rs/zerolog/log"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"github.com/swaggo/gin-swagger/swaggerFiles"
|
||||
_ "gitlab.33.cn/chat/dtalk/gateway/api/v1/docs"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler/account"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler/group"
|
||||
modules "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler/modules"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler/record"
|
||||
test "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/handler/test"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api/logger"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api/trace"
|
||||
xlog "gitlab.33.cn/chat/dtalk/pkg/logger"
|
||||
otrace "gitlab.33.cn/chat/im-pkg/trace"
|
||||
)
|
||||
|
||||
var (
|
||||
serverCtx *svc.ServiceContext
|
||||
log = zlog.Logger
|
||||
)
|
||||
|
||||
func Init(ctx *svc.ServiceContext) *http.Server {
|
||||
serverCtx = ctx
|
||||
addr := serverCtx.Config().Server.Addr
|
||||
engine := Default()
|
||||
SetupEngine(engine)
|
||||
SetupGroupRoutes(engine)
|
||||
SetupResourceRoutes(engine)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: engine,
|
||||
}
|
||||
go func() {
|
||||
// service connections
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Error().Err(err).Msg("engineInner.Start() err")
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
return srv
|
||||
}
|
||||
|
||||
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
|
||||
func Default() *gin.Engine {
|
||||
router := gin.New()
|
||||
// LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
|
||||
// By default gin.DefaultWriter = os.Stdout
|
||||
router.Use(gin.LoggerWithFormatter(api.Chat33GinLogFormatter))
|
||||
router.Use(gin.Recovery())
|
||||
return router
|
||||
}
|
||||
|
||||
// @title 即时通讯系统后端接口
|
||||
// @version 1.0
|
||||
// @description
|
||||
// @termsOfService
|
||||
// @contact.name
|
||||
// @contact.url
|
||||
// @contact.email
|
||||
// @schemes https
|
||||
// @host localhost:8080
|
||||
// @BasePath /api/v1
|
||||
func SetupEngine(e *gin.Engine) *gin.Engine {
|
||||
root := e.Group("/", otrace.OpenTracingServerMiddleWare(), api.RespMiddleWare())
|
||||
root.POST("/test", test.GetHelloWord(serverCtx))
|
||||
|
||||
userRoute := root.Group("/user")
|
||||
//获取服务器列表
|
||||
userRoute.Use(api.AuthMiddleWare())
|
||||
{
|
||||
userRoute.POST("/login", account.AddressLogin(serverCtx))
|
||||
}
|
||||
|
||||
app := root.Group("/app")
|
||||
{
|
||||
modulesRoute := app.Group("/modules")
|
||||
//获取模块启用状态
|
||||
modulesRoute.POST("/all", modules.GetModulesHandler(serverCtx))
|
||||
|
||||
recordRoute := app.Group("/record")
|
||||
{
|
||||
recordRoute.POST("/revoke", api.AuthMiddleWare(), record.RevokeHandler(serverCtx))
|
||||
recordRoute.POST("/focus", api.AuthMiddleWare(), record.FocusHandler(serverCtx))
|
||||
}
|
||||
}
|
||||
|
||||
recordRoute := root.Group("/record")
|
||||
recordRoute.Use(api.AuthMiddleWare())
|
||||
{
|
||||
recordRoute.POST("/push", record.PushToUid(serverCtx))
|
||||
recordRoute.POST("/push2", record.PushToUid2(serverCtx))
|
||||
}
|
||||
|
||||
store := root.Group("/store/app", api.RespMiddleWare())
|
||||
store.Use(api.AuthMiddleWare())
|
||||
{
|
||||
store.POST("/pri-chat-record", record.GetPriRecords(serverCtx))
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func SetupGroupRoutes(e *gin.Engine) *gin.Engine {
|
||||
logMiddleware := logger.NewMiddleware(xlog.New(serverCtx.Config().Env, "group"))
|
||||
|
||||
root := e.Group("/group/app", api.RespMiddleWare())
|
||||
root.Use(api.AuthMiddleWare(), trace.TraceMiddleware(), logMiddleware.Handle())
|
||||
{
|
||||
root.POST("/create-group", group.CreateGroupHandler(serverCtx))
|
||||
root.POST("/invite-group-members", group.InviteGroupMembersHandler(serverCtx))
|
||||
root.POST("/group-exit", group.GroupExitHandler(serverCtx))
|
||||
root.POST("/group-disband", group.GroupDisbandHandler(serverCtx))
|
||||
root.POST("/group-remove", group.GroupRemoveHandler(serverCtx))
|
||||
root.POST("/change-owner", group.ChangeOwnerHandler(serverCtx))
|
||||
root.POST("/join-group", group.JoinGroupHandler(serverCtx))
|
||||
|
||||
root.POST("/name", group.UpdateGroupNameHandler(serverCtx))
|
||||
root.POST("/avatar", group.UpdateGroupAvatarHandler(serverCtx))
|
||||
root.POST("/joinType", group.UpdateGroupJoinTypeHandler(serverCtx))
|
||||
root.POST("/friendType", group.UpdateGroupFriendTypeHandler(serverCtx))
|
||||
root.POST("/muteType", group.UpdateGroupMuteTypeHandler(serverCtx))
|
||||
root.POST("/member/name", group.UpdateGroupMemberNameHandler(serverCtx))
|
||||
root.POST("/member/type", group.SetAdminHandler(serverCtx))
|
||||
root.POST("/member/muteTime", group.UpdateGroupMemberMuteTimeHandler(serverCtx))
|
||||
|
||||
root.POST("/group-info", group.GetGroupInfoHandler(serverCtx))
|
||||
root.POST("/group-pub-info", group.GetGroupPubInfoHandler(serverCtx))
|
||||
root.POST("/group-list", group.GetGroupListHandler(serverCtx))
|
||||
root.POST("/group-member-list", group.GetGroupMemberListHandler(serverCtx))
|
||||
root.POST("/group-member-info", group.GetGroupMemberInfoHandler(serverCtx))
|
||||
root.POST("/mute-list", group.GetMuteListHandler(serverCtx))
|
||||
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func SetupResourceRoutes(e *gin.Engine) *gin.Engine {
|
||||
// swagger 文档接口
|
||||
if serverCtx.Config().Env == "debug" {
|
||||
// todo : 单独开一个 swagger 服务
|
||||
e.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
||||
return e
|
||||
}
|
||||
17
gateway/api/v1/internal/handler/test/test.go
Normal file
17
gateway/api/v1/internal/handler/test/test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
logic "gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/logic/test"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
)
|
||||
|
||||
func GetHelloWord(ctx *svc.ServiceContext) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
l := logic.NewTestLogic(c.Request.Context(), ctx)
|
||||
resp, err := l.GetHelloWorld()
|
||||
c.Set(api.ReqResult, resp)
|
||||
c.Set(api.ReqError, err)
|
||||
}
|
||||
}
|
||||
24
gateway/api/v1/internal/logic/group/change_owner.go
Normal file
24
gateway/api/v1/internal/logic/group/change_owner.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) ChangeOwner(req *types.ChangeOwnerReq) (*types.ChangeOwnerResp, error) {
|
||||
groupId := convert.ToInt64(req.Id)
|
||||
personId := l.getOpe()
|
||||
memberId := req.MemberId
|
||||
|
||||
_, err := l.svcCtx.GroupClient.ChangeOwner(l.ctx, &pb.ChangeOwnerReq{
|
||||
GroupId: groupId,
|
||||
PersonId: personId,
|
||||
MemberId: memberId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.ChangeOwnerResp{}, nil
|
||||
}
|
||||
51
gateway/api/v1/internal/logic/group/create_group.go
Normal file
51
gateway/api/v1/internal/logic/group/create_group.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) CreateGroup(req *types.CreateGroupReq) (*types.CreateGroupResp, error) {
|
||||
name := req.Name
|
||||
addr := l.getOpe()
|
||||
owner := &pb.GroupMemberInfo{
|
||||
Id: addr,
|
||||
Name: "",
|
||||
}
|
||||
members := make([]*pb.GroupMemberInfo, 0, len(req.MemberIds))
|
||||
for _, memberId := range req.MemberIds {
|
||||
members = append(members, &pb.GroupMemberInfo{
|
||||
Id: memberId,
|
||||
Name: "",
|
||||
})
|
||||
}
|
||||
|
||||
resp1, err := l.svcCtx.GroupClient.CreateGroup(l.ctx, &pb.CreateGroupReq{
|
||||
Name: name,
|
||||
GroupType: pb.GroupType_GROUP_TYPE_NORMAL,
|
||||
Owner: owner,
|
||||
Members: members,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupId := resp1.GroupId
|
||||
|
||||
resp2, err := l.svcCtx.GroupClient.GetPriGroupInfo(l.ctx, &pb.GetPriGroupInfoReq{
|
||||
GroupId: groupId,
|
||||
PersonId: addr,
|
||||
DisplayNum: int32(1 + len(members)),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Group := NewTypesGroupInfo(resp2.Group)
|
||||
Members := NewTypesGroupMemberInfos(resp2.Group.Members)
|
||||
|
||||
return &types.CreateGroupResp{
|
||||
GroupInfo: Group,
|
||||
Members: Members,
|
||||
}, nil
|
||||
}
|
||||
29
gateway/api/v1/internal/logic/group/get_group_info.go
Normal file
29
gateway/api/v1/internal/logic/group/get_group_info.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetPriGroupInfo(req *types.GetGroupInfoReq) (*types.GetGroupInfoResp, error) {
|
||||
if req.DisPlayNum == 0 {
|
||||
req.DisPlayNum = 10
|
||||
}
|
||||
|
||||
resp, err := l.svcCtx.GroupClient.GetPriGroupInfo(l.ctx, &pb.GetPriGroupInfoReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
DisplayNum: int32(req.DisPlayNum),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Group := NewTypesGroupInfo(resp.Group)
|
||||
Members := NewTypesGroupMemberInfos(resp.Group.Members)
|
||||
|
||||
return &types.GetGroupInfoResp{
|
||||
GroupInfo: Group,
|
||||
Members: Members,
|
||||
}, nil
|
||||
}
|
||||
23
gateway/api/v1/internal/logic/group/get_group_list.go
Normal file
23
gateway/api/v1/internal/logic/group/get_group_list.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetGroupList(req *types.GetGroupListReq) (*types.GetGroupListResp, error) {
|
||||
personId := l.getOpe()
|
||||
|
||||
resp, err := l.svcCtx.GroupClient.GetGroupList(l.ctx, &pb.GetGroupListReq{
|
||||
PersonId: personId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Groups := NewTypesGroupInfos(resp.Groups)
|
||||
|
||||
return &types.GetGroupListResp{
|
||||
Groups: Groups,
|
||||
}, nil
|
||||
}
|
||||
26
gateway/api/v1/internal/logic/group/get_group_member_info.go
Normal file
26
gateway/api/v1/internal/logic/group/get_group_member_info.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetGroupMemberInfo(req *types.GetGroupMemberInfoReq) (*types.GetGroupMemberInfoResp, error) {
|
||||
groupId := req.Id
|
||||
memberId := req.MemberId
|
||||
|
||||
resp, err := l.svcCtx.GroupClient.GetGroupMemberInfo(l.ctx, &pb.GetGroupMemberInfoReq{
|
||||
GroupId: groupId,
|
||||
PersonId: l.getOpe(),
|
||||
MemberId: memberId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Member := NewTypesGroupMemberInfo(resp.Member)
|
||||
res := &types.GetGroupMemberInfoResp{}
|
||||
res.GroupMember = Member
|
||||
|
||||
return res, nil
|
||||
}
|
||||
27
gateway/api/v1/internal/logic/group/get_group_member_list.go
Normal file
27
gateway/api/v1/internal/logic/group/get_group_member_list.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetGroupMemberList(req *types.GetGroupMemberListReq) (*types.GetGroupMemberListResp, error) {
|
||||
groupId := req.Id
|
||||
|
||||
resp, err := l.svcCtx.GroupClient.GetGroupMemberList(l.ctx, &pb.GetGroupMemberListReq{
|
||||
GroupId: groupId,
|
||||
PersonId: l.getOpe(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Members := NewTypesGroupMemberInfos(resp.Members)
|
||||
|
||||
return &types.GetGroupMemberListResp{
|
||||
Id: groupId,
|
||||
IdStr: convert.ToString(groupId),
|
||||
Members: Members,
|
||||
}, nil
|
||||
}
|
||||
19
gateway/api/v1/internal/logic/group/get_mute_list.go
Normal file
19
gateway/api/v1/internal/logic/group/get_mute_list.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetMuteList(req *types.GetMuteListReq) (*types.GetMuteListResp, error) {
|
||||
resp, err := l.svcCtx.GroupClient.GetMuteList(l.ctx, &pb.GetMuteListReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Members := NewTypesGroupMemberInfos(resp.Members)
|
||||
return &types.GetMuteListResp{Members: Members}, nil
|
||||
}
|
||||
21
gateway/api/v1/internal/logic/group/get_pub_group_info.go
Normal file
21
gateway/api/v1/internal/logic/group/get_pub_group_info.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GetPubGroupInfo(req *types.GetGroupPubInfoReq) (*types.GetGroupPubInfoResp, error) {
|
||||
resp, err := l.svcCtx.GroupClient.GetPubGroupInfo(l.ctx, &pb.GetPubGroupInfoReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &types.GetGroupPubInfoResp{}
|
||||
Group := NewTypesGroupInfo(resp.Group)
|
||||
res.GroupInfo = Group
|
||||
return res, nil
|
||||
}
|
||||
18
gateway/api/v1/internal/logic/group/group_disband.go
Normal file
18
gateway/api/v1/internal/logic/group/group_disband.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GroupDisband(req *types.GroupDisbandReq) (*types.GroupDisbandResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.GroupDisband(l.ctx, &pb.GroupDisbandReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.GroupDisbandResp{}, nil
|
||||
}
|
||||
18
gateway/api/v1/internal/logic/group/group_exit.go
Normal file
18
gateway/api/v1/internal/logic/group/group_exit.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GroupExit(req *types.GroupExitReq) (*types.GroupExitResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.GroupExit(l.ctx, &pb.GroupExitReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.GroupExitResp{}, nil
|
||||
}
|
||||
22
gateway/api/v1/internal/logic/group/group_remove.go
Normal file
22
gateway/api/v1/internal/logic/group/group_remove.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) GroupRemove(req *types.GroupRemoveReq) (*types.GroupRemoveResp, error) {
|
||||
resp, err := l.svcCtx.GroupClient.GroupRemove(l.ctx, &pb.GroupRemoveReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
MemberIds: req.MemberIds,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.GroupRemoveResp{
|
||||
MemberNum: resp.MemberNum,
|
||||
MemberIds: resp.MemberIds,
|
||||
}, nil
|
||||
}
|
||||
25
gateway/api/v1/internal/logic/group/invite_group_members.go
Normal file
25
gateway/api/v1/internal/logic/group/invite_group_members.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) InviteGroupMembers(req *types.InviteGroupMembersReq) (*types.InviteGroupMembersResp, error) {
|
||||
groupId := req.Id
|
||||
|
||||
_, err := l.svcCtx.GroupClient.InviteGroupMembers(l.ctx, &pb.InviteGroupMembersReq{
|
||||
GroupId: groupId,
|
||||
InviterId: l.getOpe(),
|
||||
MemberIds: req.NewMemberIds,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.InviteGroupMembersResp{
|
||||
Id: groupId,
|
||||
IdStr: convert.ToString(groupId),
|
||||
}, nil
|
||||
}
|
||||
25
gateway/api/v1/internal/logic/group/join_group.go
Normal file
25
gateway/api/v1/internal/logic/group/join_group.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) JoinGroup(req *types.JoinGroupReq) (*types.JoinGroupResp, error) {
|
||||
groupId := req.Id
|
||||
|
||||
_, err := l.svcCtx.GroupClient.InviteGroupMembers(l.ctx, &pb.InviteGroupMembersReq{
|
||||
GroupId: groupId,
|
||||
InviterId: req.InviterId,
|
||||
MemberIds: []string{l.getOpe()},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.JoinGroupResp{
|
||||
Id: groupId,
|
||||
IdStr: convert.ToString(groupId),
|
||||
}, nil
|
||||
}
|
||||
96
gateway/api/v1/internal/logic/group/newlogic.go
Normal file
96
gateway/api/v1/internal/logic/group/newlogic.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
"gitlab.33.cn/utils/go-kit/convert"
|
||||
)
|
||||
|
||||
type GroupLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) GroupLogic {
|
||||
return GroupLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GroupLogic) getOpe() string {
|
||||
return api.NewAddrWithContext(l.ctx)
|
||||
}
|
||||
|
||||
func NewTypesGroupInfo(do *pb.GroupBizInfo) *types.GroupInfo {
|
||||
if do == nil {
|
||||
return &types.GroupInfo{}
|
||||
}
|
||||
|
||||
res := &types.GroupInfo{
|
||||
Id: do.Id,
|
||||
IdStr: convert.ToString(do.Id),
|
||||
MarkId: do.MarkId,
|
||||
Name: do.Name,
|
||||
PublicName: do.PubName,
|
||||
Avatar: do.Avatar,
|
||||
Introduce: do.Introduce,
|
||||
Owner: nil,
|
||||
Person: nil,
|
||||
MemberNum: do.MemberNum,
|
||||
Maximum: do.MemberMaximum,
|
||||
Status: int32(do.Status),
|
||||
CreateTime: do.CreateTime,
|
||||
JoinType: int32(do.JoinType),
|
||||
MuteType: int32(do.MuteType),
|
||||
FriendType: int32(do.FriendType),
|
||||
MuteNum: do.MuteNum,
|
||||
AdminNum: do.AdminNum,
|
||||
AESKey: do.AESKey,
|
||||
GroupType: int32(do.GetType()),
|
||||
}
|
||||
|
||||
if do.Owner != nil {
|
||||
res.Owner = NewTypesGroupMemberInfo(do.Owner)
|
||||
}
|
||||
|
||||
if do.Person != nil {
|
||||
res.Person = NewTypesGroupMemberInfo(do.Person)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func NewTypesGroupInfos(dos []*pb.GroupBizInfo) []*types.GroupInfo {
|
||||
dtos := make([]*types.GroupInfo, 0, len(dos))
|
||||
for _, do := range dos {
|
||||
dtos = append(dtos, NewTypesGroupInfo(do))
|
||||
}
|
||||
|
||||
return dtos
|
||||
}
|
||||
|
||||
func NewTypesGroupMemberInfo(do *pb.GroupMemberBizInfo) *types.GroupMember {
|
||||
if do == nil {
|
||||
return &types.GroupMember{}
|
||||
}
|
||||
|
||||
return &types.GroupMember{
|
||||
MemberId: do.Id,
|
||||
MemberName: do.Name,
|
||||
MemberType: int32(do.Type),
|
||||
MemberMuteTime: do.MuteTime,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTypesGroupMemberInfos(dos []*pb.GroupMemberBizInfo) []*types.GroupMember {
|
||||
dtos := make([]*types.GroupMember, 0, len(dos))
|
||||
for _, do := range dos {
|
||||
dtos = append(dtos, NewTypesGroupMemberInfo(do))
|
||||
}
|
||||
|
||||
return dtos
|
||||
}
|
||||
25
gateway/api/v1/internal/logic/group/set_admin.go
Normal file
25
gateway/api/v1/internal/logic/group/set_admin.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) SetAdmin(req *types.SetAdminReq) (*types.SetAdminResp, error) {
|
||||
if _, ok := pb.GroupMemberType_name[req.MemberType]; !ok {
|
||||
return nil, xerror.NewError(xerror.ParamsError)
|
||||
}
|
||||
|
||||
_, err := l.svcCtx.GroupClient.SetAdmin(l.ctx, &pb.SetAdminReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
MemberId: req.MemberId,
|
||||
GroupMemberType: pb.GroupMemberType(req.MemberType),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.SetAdminResp{}, nil
|
||||
}
|
||||
19
gateway/api/v1/internal/logic/group/update_group_avatar.go
Normal file
19
gateway/api/v1/internal/logic/group/update_group_avatar.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupAvatar(req *types.UpdateGroupAvatarReq) (*types.UpdateGroupAvatarResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupAvatar(l.ctx, &pb.UpdateGroupAvatarReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
Avatar: req.Avatar,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupAvatarResp{}, nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupFriendType(req *types.UpdateGroupFriendTypeReq) (*types.UpdateGroupFriendTypeResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupFriendType(l.ctx, &pb.UpdateGroupFriendTypeReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
GroupFriendType: pb.GroupFriendType(req.FriendType),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupFriendTypeResp{}, nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupJoinType(req *types.UpdateGroupJoinTypeReq) (*types.UpdateGroupJoinTypeResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupJoinType(l.ctx, &pb.UpdateGroupJoinTypeReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
GroupJoinType: pb.GroupJoinType(req.JoinType),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupJoinTypeResp{}, nil
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupMemberMuteTime(req *types.UpdateGroupMemberMuteTimeReq) (*types.UpdateGroupMemberMuteTimeResp, error) {
|
||||
resp, err := l.svcCtx.GroupClient.UpdateGroupMemberMuteTime(l.ctx, &pb.UpdateGroupMemberMuteTimeReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
MemberIds: req.MemberIds,
|
||||
MuteTime: req.MuteTime,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Members := NewTypesGroupMemberInfos(resp.Members)
|
||||
|
||||
return &types.UpdateGroupMemberMuteTimeResp{Members: Members}, nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupMemberName(req *types.UpdateGroupMemberNameReq) (*types.UpdateGroupMemberNameResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupMemberName(l.ctx, &pb.UpdateGroupMemberNameReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
MemberName: req.MemberName,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupMemberNameResp{}, nil
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupMuteType(req *types.UpdateGroupMuteTypeReq) (*types.UpdateGroupMuteTypeResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupMuteType(l.ctx, &pb.UpdateGroupMuteTypeReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
GroupMuteType: pb.GroupMuteType(req.MuteType),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupMuteTypeResp{}, nil
|
||||
}
|
||||
20
gateway/api/v1/internal/logic/group/update_group_name.go
Normal file
20
gateway/api/v1/internal/logic/group/update_group_name.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
pb "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
)
|
||||
|
||||
func (l *GroupLogic) UpdateGroupName(req *types.UpdateGroupNameReq) (*types.UpdateGroupNameResp, error) {
|
||||
_, err := l.svcCtx.GroupClient.UpdateGroupName(l.ctx, &pb.UpdateGroupNameReq{
|
||||
GroupId: req.Id,
|
||||
PersonId: l.getOpe(),
|
||||
Name: req.Name,
|
||||
PublicName: req.PublicName,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.UpdateGroupNameResp{}, nil
|
||||
}
|
||||
87
gateway/api/v1/internal/logic/record/focus.go
Normal file
87
gateway/api/v1/internal/logic/record/focus.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
xproto "github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/util"
|
||||
"gitlab.33.cn/chat/dtalk/service/group/model/biz"
|
||||
"gitlab.33.cn/chat/imparse/proto"
|
||||
)
|
||||
|
||||
func (l *Logic) FocusPersonal(Operator string, logId int64) error {
|
||||
//查找消息
|
||||
rd, err := l.svcCtx.StoreClient.GetRecord(l.ctx, proto.Channel_ToUser, logId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := rd.ReceiverId
|
||||
sender := rd.SenderId
|
||||
if Operator == sender || Operator != target {
|
||||
return model.ErrPermission
|
||||
}
|
||||
now := uint64(util.TimeNowUnixNano() / int64(time.Millisecond))
|
||||
num, err := l.svcCtx.StoreClient.AddRecordFocus(l.ctx, Operator, logId, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
action := &proto.SignalFocusMessage{
|
||||
Mid: logId,
|
||||
Uid: Operator,
|
||||
CurrentNum: num,
|
||||
Time: now,
|
||||
}
|
||||
body, err := xproto.Marshal(action)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "proto.Marshal, action=%+v", action)
|
||||
}
|
||||
err = l.svcCtx.AnswerClient.UniCastSignal(l.ctx, proto.SignalType_FocusMessage, sender, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return l.svcCtx.AnswerClient.UniCastSignal(l.ctx, proto.SignalType_FocusMessage, target, body)
|
||||
}
|
||||
|
||||
func (l *Logic) FocusGroup(Operator string, logId int64) error {
|
||||
//查找消息
|
||||
rd, err := l.svcCtx.StoreClient.GetRecord(l.ctx, proto.Channel_ToGroup, logId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := rd.ReceiverId
|
||||
sender := rd.SenderId
|
||||
if Operator == sender {
|
||||
return model.ErrPermission
|
||||
}
|
||||
//群成员判断
|
||||
memOpt, err := l.svcCtx.GroupClient.GetMember(l.ctx, util.ToInt64(target), Operator)
|
||||
if err != nil || memOpt == nil {
|
||||
return err
|
||||
}
|
||||
switch memOpt.GroupMemberType {
|
||||
case biz.GroupMemberTypeOwner:
|
||||
case biz.GroupMemberTypeAdmin:
|
||||
case biz.GroupMemberTypeNormal:
|
||||
default:
|
||||
return model.ErrPermission
|
||||
}
|
||||
|
||||
now := uint64(util.TimeNowUnixNano() / int64(time.Millisecond))
|
||||
num, err := l.svcCtx.StoreClient.AddRecordFocus(l.ctx, Operator, logId, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
action := &proto.SignalFocusMessage{
|
||||
Mid: logId,
|
||||
Uid: Operator,
|
||||
CurrentNum: num,
|
||||
Time: now,
|
||||
}
|
||||
body, err := xproto.Marshal(action)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "proto.Marshal, action=%+v", action)
|
||||
}
|
||||
return l.svcCtx.AnswerClient.GroupCastSignal(l.ctx, proto.SignalType_FocusMessage, target, body)
|
||||
}
|
||||
5
gateway/api/v1/internal/logic/record/push.go
Normal file
5
gateway/api/v1/internal/logic/record/push.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package record
|
||||
|
||||
func (l *Logic) Push(key, from string, body []byte) (int64, uint64, error) {
|
||||
return l.svcCtx.AnswerClient.PushCommonMsg(l.ctx, key, from, body)
|
||||
}
|
||||
47
gateway/api/v1/internal/logic/record/record.go
Normal file
47
gateway/api/v1/internal/logic/record/record.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/util"
|
||||
store "gitlab.33.cn/chat/dtalk/service/record/store/api"
|
||||
storeModel "gitlab.33.cn/chat/dtalk/service/record/store/model"
|
||||
"gitlab.33.cn/chat/imparse/proto"
|
||||
)
|
||||
|
||||
func (l *Logic) GetPriRecord(req *model.GetPriRecordsReq) (*model.GetPriRecordsResp, error) {
|
||||
resp, err := l.svcCtx.StoreClient.GetRecordsAfterMid(l.ctx, &store.GetRecordsAfterMidReq{
|
||||
Tp: proto.Channel_ToUser,
|
||||
Mid: util.ToInt64(req.Mid),
|
||||
From: req.FromId,
|
||||
Target: req.TargetId,
|
||||
Count: req.RecordCount,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerror.NewError(xerror.QueryFailed).SetExtMessage(err.Error())
|
||||
}
|
||||
|
||||
res := &model.GetPriRecordsResp{
|
||||
RecordCount: len(resp.Records),
|
||||
Records: toChatRecord(resp.Records),
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// toChatRecord []MsgContent -> []Record , content json -> proto
|
||||
func toChatRecord(msgs []*store.GetRecordReply) []*model.Record {
|
||||
Result := make([]*model.Record, len(msgs))
|
||||
for i, msg := range msgs {
|
||||
Result[i] = &model.Record{
|
||||
Mid: msg.Mid,
|
||||
Seq: msg.Seq,
|
||||
FromId: msg.SenderId,
|
||||
TargetId: msg.ReceiverId,
|
||||
MsgType: int32(msg.MsgType),
|
||||
Content: storeModel.JsonUnmarshal(msg.MsgType, []byte(msg.Content)),
|
||||
CreateTime: msg.CreateTime,
|
||||
}
|
||||
}
|
||||
return Result
|
||||
}
|
||||
101
gateway/api/v1/internal/logic/record/revoke.go
Normal file
101
gateway/api/v1/internal/logic/record/revoke.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package record
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gitlab.33.cn/chat/dtalk/service/group/model/biz"
|
||||
"time"
|
||||
|
||||
xproto "github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/model"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/util"
|
||||
"gitlab.33.cn/chat/imparse/proto"
|
||||
)
|
||||
|
||||
type Logic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLogic(ctx context.Context, svcCtx *svc.ServiceContext) Logic {
|
||||
return Logic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logic) RevokePersonal(Operator string, mid int64) error {
|
||||
//查找消息
|
||||
rd, err := l.svcCtx.StoreClient.GetRecord(l.ctx, proto.Channel_ToUser, mid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := rd.ReceiverId
|
||||
if rd.SenderId != Operator || time.Since(util.UnixToTime(int64(rd.CreateTime))) > time.Duration(l.svcCtx.Config().Revoke.Expire) {
|
||||
return model.ErrPermission
|
||||
}
|
||||
action := &proto.SignalRevoke{
|
||||
Mid: mid,
|
||||
Operator: Operator,
|
||||
Self: rd.SenderId == Operator,
|
||||
}
|
||||
body, err := xproto.Marshal(action)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "proto.Marshal, action=%+v", action)
|
||||
}
|
||||
err = l.svcCtx.AnswerClient.UniCastSignal(l.ctx, proto.SignalType_Revoke, target, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := l.svcCtx.StoreClient.DelRecord(l.ctx, proto.Channel_ToUser, mid); err != nil {
|
||||
return err
|
||||
}
|
||||
return l.svcCtx.AnswerClient.UniCastSignal(l.ctx, proto.SignalType_Revoke, Operator, body)
|
||||
}
|
||||
|
||||
func (l *Logic) RevokeGroup(Operator string, mid int64) error {
|
||||
//查找消息
|
||||
rd, err := l.svcCtx.StoreClient.GetRecord(l.ctx, proto.Channel_ToGroup, mid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
target := rd.ReceiverId
|
||||
if rd.SenderId == Operator && time.Since(util.UnixToTime(int64(rd.CreateTime))) > time.Duration(l.svcCtx.Config().Revoke.Expire) {
|
||||
return model.ErrPermission
|
||||
}
|
||||
if rd.SenderId != Operator {
|
||||
//执行者
|
||||
memOpt, err := l.svcCtx.GroupClient.GetMember(l.ctx, util.ToInt64(target), Operator)
|
||||
if err != nil || memOpt == nil {
|
||||
return err
|
||||
}
|
||||
//消息所有者
|
||||
memOwn, err := l.svcCtx.GroupClient.GetMember(l.ctx, util.ToInt64(target), rd.SenderId)
|
||||
if err != nil || memOwn == nil {
|
||||
return err
|
||||
}
|
||||
switch memOpt.GroupMemberType {
|
||||
case biz.GroupMemberTypeOwner:
|
||||
case biz.GroupMemberTypeAdmin:
|
||||
if memOwn.GroupMemberType == biz.GroupMemberTypeOwner {
|
||||
return model.ErrPermission
|
||||
}
|
||||
default:
|
||||
return model.ErrPermission
|
||||
}
|
||||
}
|
||||
action := &proto.SignalRevoke{
|
||||
Mid: mid,
|
||||
Operator: Operator,
|
||||
Self: rd.SenderId == Operator,
|
||||
}
|
||||
body, err := xproto.Marshal(action)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "proto.Marshal, action=%+v", action)
|
||||
}
|
||||
if err := l.svcCtx.StoreClient.DelRecord(l.ctx, proto.Channel_ToGroup, mid); err != nil {
|
||||
return err
|
||||
}
|
||||
return l.svcCtx.AnswerClient.GroupCastSignal(l.ctx, proto.SignalType_Revoke, target, body)
|
||||
}
|
||||
24
gateway/api/v1/internal/logic/test/testlogic.go
Normal file
24
gateway/api/v1/internal/logic/test/testlogic.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/svc"
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/types"
|
||||
)
|
||||
|
||||
type TestLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewTestLogic(ctx context.Context, svcCtx *svc.ServiceContext) TestLogic {
|
||||
return TestLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *TestLogic) GetHelloWorld() (*types.Hello, error) {
|
||||
return &types.Hello{Content: "hello world"}, nil
|
||||
}
|
||||
7
gateway/api/v1/internal/model/account.go
Normal file
7
gateway/api/v1/internal/model/account.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
// 用户地址登录请求结果
|
||||
type AddressLoginResp struct {
|
||||
// 用户地址
|
||||
Address string `json:"address" example:"123"`
|
||||
}
|
||||
6
gateway/api/v1/internal/model/const.go
Normal file
6
gateway/api/v1/internal/model/const.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
const (
|
||||
Private = 0
|
||||
Group = 1
|
||||
)
|
||||
7
gateway/api/v1/internal/model/error.go
Normal file
7
gateway/api/v1/internal/model/error.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrPermission = errors.New("权限不足")
|
||||
)
|
||||
7
gateway/api/v1/internal/model/general.go
Normal file
7
gateway/api/v1/internal/model/general.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type GeneralResponse struct {
|
||||
Result int `json:"result"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
7
gateway/api/v1/internal/model/modules.go
Normal file
7
gateway/api/v1/internal/model/modules.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type GetModuleResp struct {
|
||||
Name string `json:"name" enums:"wallet,oa,redpacket"`
|
||||
IsEnabled bool `json:"isEnabled"`
|
||||
EndPoints []string `json:"endPoints"`
|
||||
}
|
||||
50
gateway/api/v1/internal/model/record.go
Normal file
50
gateway/api/v1/internal/model/record.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package model
|
||||
|
||||
type RevokeMsgReq struct {
|
||||
Type int `json:"type" enums:"0,1"`
|
||||
Mid int64 `json:"logId" binding:"required"`
|
||||
}
|
||||
|
||||
type FocusMsgReq struct {
|
||||
Type int `json:"type" enums:"0,1"`
|
||||
LogId int64 `json:"logId" binding:"required"`
|
||||
}
|
||||
|
||||
type Record struct {
|
||||
// log id
|
||||
Mid string `json:"logId"`
|
||||
// msg id (uuid)
|
||||
Seq string `json:"msgId"`
|
||||
// 发送者 id
|
||||
FromId string `json:"fromId"`
|
||||
// 接收者 id
|
||||
TargetId string `json:"targetId"`
|
||||
// 消息类型
|
||||
MsgType int32 `json:"msgType"`
|
||||
// 消息内容
|
||||
Content interface{} `json:"content"`
|
||||
// 消息发送时间
|
||||
CreateTime uint64 `json:"createTime"`
|
||||
}
|
||||
|
||||
type GetPriRecordsReq struct {
|
||||
// 发送者 ID
|
||||
FromId string `json:"-"`
|
||||
|
||||
// 发送者 ID
|
||||
//FromId string `json:"fromId" binding:"required"`
|
||||
|
||||
// 接受者 ID
|
||||
TargetId string `json:"targetId" binding:"required"`
|
||||
// 消息数量
|
||||
RecordCount int64 `json:"count" binding:"required,min=1,max=100"`
|
||||
// 消息 ID
|
||||
Mid string `json:"logId"`
|
||||
}
|
||||
|
||||
type GetPriRecordsResp struct {
|
||||
// 聊天记录数量
|
||||
RecordCount int `json:"record_count"`
|
||||
// 聊天记录
|
||||
Records []*Record `json:"records"`
|
||||
}
|
||||
48
gateway/api/v1/internal/svc/servicecontext.go
Normal file
48
gateway/api/v1/internal/svc/servicecontext.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/interceptor/trace"
|
||||
group "gitlab.33.cn/chat/dtalk/service/group/api"
|
||||
store "gitlab.33.cn/chat/dtalk/service/record/store/api"
|
||||
"google.golang.org/grpc"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/gateway/api/v1/internal/config"
|
||||
answer "gitlab.33.cn/chat/dtalk/service/record/answer/api"
|
||||
)
|
||||
|
||||
// ServiceContext 服务上下文
|
||||
type ServiceContext struct {
|
||||
m sync.RWMutex
|
||||
c config.Config
|
||||
|
||||
AnswerClient *answer.Client
|
||||
StoreClient *store.Client
|
||||
GroupClient *group.Client
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
sc := &ServiceContext{
|
||||
c: c,
|
||||
AnswerClient: answer.New(c.AnswerRPCClient.RegAddrs, c.AnswerRPCClient.Schema, c.AnswerRPCClient.SrvName, time.Duration(c.AnswerRPCClient.Dial)),
|
||||
StoreClient: store.New(c.StoreRPCClient.RegAddrs, c.StoreRPCClient.Schema, c.StoreRPCClient.SrvName, time.Duration(c.StoreRPCClient.Dial)),
|
||||
GroupClient: group.New(c.GroupRPCClient.RegAddrs,
|
||||
c.GroupRPCClient.Schema,
|
||||
c.GroupRPCClient.SrvName,
|
||||
time.Duration(c.GroupRPCClient.Dial),
|
||||
grpc.WithChainUnaryInterceptor(xerror.ErrClientInterceptor, trace.UnaryClientInterceptor),
|
||||
),
|
||||
}
|
||||
|
||||
return sc
|
||||
}
|
||||
|
||||
// Config 获取全局配置
|
||||
func (sc *ServiceContext) Config() config.Config {
|
||||
sc.m.RLock()
|
||||
defer sc.m.RUnlock()
|
||||
|
||||
return sc.c
|
||||
}
|
||||
431
gateway/api/v1/internal/types/group.go
Normal file
431
gateway/api/v1/internal/types/group.go
Normal file
@@ -0,0 +1,431 @@
|
||||
package types
|
||||
|
||||
type GeneralResp struct {
|
||||
Result int `json:"result"`
|
||||
Message int `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type GroupMember struct {
|
||||
// 用户 ID
|
||||
MemberId string `json:"memberId" form:"memberId"`
|
||||
// 用户群昵称
|
||||
MemberName string `json:"memberName" form:"memberName"`
|
||||
// 用户角色,2=群主,1=管理员,0=群员,10=退群
|
||||
MemberType int32 `json:"memberType" form:"memberType"`
|
||||
// 该用户被禁言结束的时间 9223372036854775807=永久禁言
|
||||
MemberMuteTime int64 `json:"memberMuteTime"`
|
||||
}
|
||||
|
||||
type GroupInfo struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id" form:"id"`
|
||||
IdStr string `json:"idStr"`
|
||||
// 群显示的 ID
|
||||
MarkId string `json:"markId" form:"markId"`
|
||||
// 群名称 加密的
|
||||
Name string `json:"name" form:"name"`
|
||||
// 公开的群名称 不加密的
|
||||
PublicName string `json:"publicName"`
|
||||
// 头像 url
|
||||
Avatar string `json:"avatar" form:"avatar"`
|
||||
Introduce string `json:"introduce" form:"introduce"`
|
||||
// 群主 信息
|
||||
Owner *GroupMember `json:"owner" form:"owner"`
|
||||
// 本人在群内的信息
|
||||
Person *GroupMember `json:"person" form:"person"`
|
||||
// 群人数
|
||||
MemberNum int32 `json:"memberNum" form:"memberNum"`
|
||||
// 群人数上限
|
||||
Maximum int32 `json:"maximum" form:"maximum"`
|
||||
// 群状态,0=正常 1=封禁 2=解散
|
||||
Status int32 `json:"status" form:"status"`
|
||||
// 群创建时间
|
||||
CreateTime int64 `json:"createTime" form:"createTime"`
|
||||
// 加群方式,0=无需审批(默认),1=禁止加群,群主和管理员邀请加群, 2=普通人邀请需要审批,群主和管理员直接加群
|
||||
JoinType int32 `json:"joinType" form:"joinType"`
|
||||
// 禁言, 0=全员可发言, 1=全员禁言(除群主和管理员)
|
||||
MuteType int32 `json:"muteType" form:"muteType"`
|
||||
// 加好友限制, 0=群内可加好友,1=群内禁止加好友
|
||||
FriendType int32 `json:"friendType"`
|
||||
// 群内当前被禁言的人数
|
||||
MuteNum int32 `json:"muteNum"`
|
||||
// 群内管理员数量
|
||||
AdminNum int32 `json:"adminNum"`
|
||||
//
|
||||
AESKey string `json:"key"`
|
||||
// 群类型 (0: 普通群, 1: 全员群, 2: 部门群)
|
||||
GroupType int32 `json:"groupType"`
|
||||
}
|
||||
|
||||
type CreateGroupReq struct {
|
||||
Name string `json:"name" form:"name"`
|
||||
Avatar string `json:"avatar" form:"avatar"`
|
||||
Introduce string `json:"introduce" form:"introduce"`
|
||||
MemberIds []string `json:"memberIds" form:"memberIds"`
|
||||
}
|
||||
|
||||
type CreateGroupResp struct {
|
||||
*GroupInfo
|
||||
// 群成员
|
||||
Members []*GroupMember `json:"members" form:"members"`
|
||||
}
|
||||
|
||||
type InviteGroupMembersReq struct {
|
||||
Id int64 `json:"id" form:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
Inviter GroupMember `json:"-"`
|
||||
NewMembers []GroupMember `json:"-"`
|
||||
NewMemberIds []string `json:"newMemberIds" form:"newMemberIds" binding:"required"`
|
||||
}
|
||||
|
||||
type InviteGroupMembersResp struct {
|
||||
Id int64 `json:"id" form:"id" example:"123821199217135616"`
|
||||
IdStr string `json:"idStr"`
|
||||
MemberNum int32 `json:"memberNum" form:"memberNum" example:"5"`
|
||||
//Inviter GroupMember `json:"inviter" form:"inviter"`
|
||||
//NewMembers []GroupMember `json:"newMembers" form:"newMembers"`
|
||||
}
|
||||
|
||||
type GetGroupInfoReq struct {
|
||||
Id int64 `json:"id" uri:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
DisPlayNum int64 `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupInfoResp struct {
|
||||
*GroupInfo
|
||||
Members []*GroupMember `json:"members" form:"members"`
|
||||
}
|
||||
|
||||
type GetGroupListReq struct {
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupListResp struct {
|
||||
Groups []*GroupInfo `json:"groups"`
|
||||
}
|
||||
|
||||
type GetGroupMemberListReq struct {
|
||||
Id int64 `json:"id" uri:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupMemberListResp struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
Members []*GroupMember `json:"members"`
|
||||
}
|
||||
|
||||
type GetGroupMemberInfoReq struct {
|
||||
Id int64 `json:"id" uri:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
MemberId string `json:"memberId" uri:"memberId" binding:"required"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupMemberInfoResp struct {
|
||||
*GroupMember
|
||||
}
|
||||
|
||||
type GroupExitReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GroupExitResp struct {
|
||||
}
|
||||
|
||||
type GroupRemoveReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
MemberIds []string `json:"memberIds" binding:"required"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GroupRemoveResp struct {
|
||||
// 群人数
|
||||
MemberNum int32 `json:"memberNum" form:"memberNum"`
|
||||
// 成功被踢的成员列表
|
||||
MemberIds []string `json:"memberIds"`
|
||||
}
|
||||
|
||||
type GroupDisbandReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GroupDisbandResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupNameReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
Name string `json:"name"`
|
||||
PublicName string `json:"publicName"`
|
||||
}
|
||||
|
||||
type UpdateGroupNameResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupAvatarReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
type UpdateGroupAvatarResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupMemberNameReq struct {
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
MemberName string `json:"memberName"`
|
||||
}
|
||||
|
||||
type UpdateGroupMemberNameResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupJoinTypeReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
// 加群方式,0=无需审批(默认),1=禁止加群,群主和管理员邀请加群, 2=普通人邀请需要审批,群主和管理员直接加群
|
||||
JoinType int32 `json:"joinType" binding:"oneof=0 1 2"`
|
||||
}
|
||||
|
||||
type UpdateGroupJoinTypeResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupFriendTypeReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
// 加好友限制, 0=群内可加好友,1=群内禁止加好友
|
||||
FriendType int32 `json:"friendType" binding:"oneof=0 1"`
|
||||
}
|
||||
|
||||
type UpdateGroupFriendTypeResp struct {
|
||||
}
|
||||
|
||||
type ChangeOwnerReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
// 被转让为群主的群成员 ID
|
||||
MemberId string `json:"memberId" binding:"required"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type ChangeOwnerResp struct {
|
||||
}
|
||||
|
||||
// JoinGroupReq 扫二维码加群
|
||||
type JoinGroupReq struct {
|
||||
Id int64 `json:"id"`
|
||||
IdStr string `json:"idStr"`
|
||||
InviterId string `json:"inviterId"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type JoinGroupResp struct {
|
||||
Id int64 `json:"id"`
|
||||
IdStr string `json:"idStr"`
|
||||
}
|
||||
|
||||
type SetAdminReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
// 被设置的群成员 ID
|
||||
MemberId string `json:"memberId" binding:"required"`
|
||||
PersonId string `json:"-"`
|
||||
// 用户角色 0=群员, 1=管理员
|
||||
MemberType int32 `json:"memberType" binding:"oneof=0 1"`
|
||||
}
|
||||
|
||||
type SetAdminResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupMuteTypeReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
// 禁言, 0=全员可发言, 1=全员禁言(除群主和管理员)
|
||||
MuteType int32 `json:"muteType" binding:"oneof=0 1"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type UpdateGroupMuteTypeResp struct {
|
||||
}
|
||||
|
||||
type UpdateGroupMemberMuteTimeReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
// 被禁言的群员 ID
|
||||
MemberIds []string `json:"memberIds" binding:"required"`
|
||||
// 禁言持续时间, 传9223372036854775807=永久禁言, 0=解除禁言
|
||||
MuteTime int64 `json:"muteTime"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type UpdateGroupMemberMuteTimeResp struct {
|
||||
Members []*GroupMember `json:"members"`
|
||||
}
|
||||
|
||||
type GetMuteListReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetMuteListResp struct {
|
||||
Members []*GroupMember `json:"members"`
|
||||
}
|
||||
|
||||
type GetGroupPubInfoReq struct {
|
||||
// 群 ID
|
||||
Id int64 `json:"id"`
|
||||
// 如果同时填了 idStr, 则优先选择 idStr
|
||||
IdStr string `json:"idStr"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupPubInfoResp struct {
|
||||
*GroupInfo
|
||||
}
|
||||
|
||||
type GetGroupInfoByConditionReq struct {
|
||||
// 查询方法 0:groupMarkId, 1:groupId
|
||||
Tp int32 `json:"tp" binding:"oneof=0 1"`
|
||||
Query string `json:"query" binding:"required"`
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type GetGroupInfoByConditionResp struct {
|
||||
Groups []*GroupInfo `json:"groups"`
|
||||
}
|
||||
|
||||
// ---群审批------------------
|
||||
|
||||
// GroupApplyInfo 群审批信息
|
||||
type GroupApplyInfo struct {
|
||||
// 审批 ID
|
||||
ApplyId string `json:"applyId,omitempty"`
|
||||
// 群 ID
|
||||
GroupId string `json:"id,omitempty"`
|
||||
// 邀请人 ID, 空表示是自己主动申请的
|
||||
InviterId string `json:"inviterId,omitempty"`
|
||||
// 申请加入人 ID
|
||||
MemberId string `json:"memberId,omitempty"`
|
||||
// 申请备注
|
||||
ApplyNote string `json:"applyNote,omitempty"`
|
||||
// 审批人 ID
|
||||
OperatorId string `json:"operatorId,omitempty"`
|
||||
// 审批情况 0=待审批, 1=审批通过, 2=审批不通过, 10=审批忽略
|
||||
ApplyStatus int32 `json:"applyStatus,omitempty"`
|
||||
// 拒绝原因
|
||||
RejectReason string `json:"rejectReason,omitempty"`
|
||||
// 创建时间 ms
|
||||
CreateTime int64 `json:"createTime,omitempty"`
|
||||
// 修改时间 ms
|
||||
UpdateTime int64 `json:"updateTime,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroupApplyReq 创建群审批请求
|
||||
type CreateGroupApplyReq struct {
|
||||
// 群 ID
|
||||
Id string `json:"id,omitempty" binding:"required"`
|
||||
// 申请备注
|
||||
ApplyNote string `json:"applyNote,omitempty"`
|
||||
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
// CreateGroupApplyResp 创建群审批响应
|
||||
type CreateGroupApplyResp struct {
|
||||
}
|
||||
|
||||
// GetGroupApplyByIdReq 查询群审批请求
|
||||
type GetGroupApplyByIdReq struct {
|
||||
// 审批 ID
|
||||
ApplyId string `json:"applyId" binding:"required"`
|
||||
// 群 ID
|
||||
Id string `json:"id" binding:"required"`
|
||||
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
// GetGroupApplysReq 查询群审批列表请求
|
||||
type GetGroupApplysReq struct {
|
||||
// 群 ID
|
||||
Id string `json:"id" binding:"required"`
|
||||
// 每页记录数
|
||||
Count int32 `json:"count" binding:"required"`
|
||||
// 当前审批记录数量
|
||||
Offset int32 `json:"offset"`
|
||||
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
// GetGroupApplysResp 查询群审批响应
|
||||
type GetGroupApplysResp struct {
|
||||
GroupApplys []*GroupApplyInfo `json:"applys"`
|
||||
}
|
||||
|
||||
// AcceptGroupApplyReq 接受加群审批请求
|
||||
type AcceptGroupApplyReq struct {
|
||||
// 审批 ID
|
||||
ApplyId string `json:"applyId" binding:"required"`
|
||||
// 群 ID
|
||||
Id string `json:"id" binding:"required"`
|
||||
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type AcceptGroupApplyResp struct {
|
||||
}
|
||||
|
||||
// RejectGroupApplyReq 拒绝加群审批请求
|
||||
type RejectGroupApplyReq struct {
|
||||
// 审批 ID
|
||||
ApplyId string `json:"applyId" binding:"required"`
|
||||
// 群 ID
|
||||
Id string `json:"id" binding:"required"`
|
||||
// 拒绝原因
|
||||
RejectReason string `json:"rejectReason"`
|
||||
|
||||
PersonId string `json:"-"`
|
||||
}
|
||||
|
||||
type RejectGroupApplyResp struct {
|
||||
}
|
||||
6
gateway/api/v1/internal/types/types.go
Normal file
6
gateway/api/v1/internal/types/types.go
Normal file
@@ -0,0 +1,6 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
package types
|
||||
|
||||
type Hello struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
16
gateway/api/v1/version.go
Normal file
16
gateway/api/v1/version.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
//var (
|
||||
// // The full version string
|
||||
// Version = "0.0.7"
|
||||
//
|
||||
// // GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse --short=8 HEAD)"
|
||||
// GitCommit string
|
||||
//)
|
||||
//
|
||||
//func GetVersion() string {
|
||||
// if GitCommit != "" {
|
||||
// return Version + "-" + GitCommit
|
||||
// }
|
||||
// return Version
|
||||
//}
|
||||
64
go.mod
Normal file
64
go.mod
Normal file
@@ -0,0 +1,64 @@
|
||||
module gitlab.33.cn/chat/dtalk
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/33cn/chain33 v1.65.3
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/Shopify/sarama v1.19.0
|
||||
github.com/Terry-Mao/goim v0.0.0-20210523140626-e742c99ad76e
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.948
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||
github.com/bsm/sarama-cluster v2.1.15+incompatible
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/gammazero/workerpool v1.1.2
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/haltingstate/secp256k1-go v0.0.0-20151224084235-572209b26df6
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.1+incompatible
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.0.35-rc
|
||||
github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac
|
||||
github.com/jinzhu/gorm v1.9.16
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.12
|
||||
github.com/oofpgDLD/u-push v0.0.2
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/rs/xid v1.3.0
|
||||
github.com/rs/zerolog v1.21.0
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
||||
github.com/swaggo/gin-swagger v1.1.0
|
||||
github.com/swaggo/swag v1.7.8
|
||||
github.com/tencentyun/tls-sig-api-v2-golang v1.2.0
|
||||
github.com/uber/jaeger-client-go v2.28.0+incompatible
|
||||
github.com/ugorji/go v1.1.13 // indirect
|
||||
gitlab.33.cn/chat/im v1.0.10
|
||||
//gitlab.33.cn/chat/imparse v0.0.0-00010101000000-000000000000
|
||||
//gitlab.33.cn/chat/im-pkg v0.0.0-00010101000000-000000000000
|
||||
gitlab.33.cn/chat/im-pkg v0.0.1
|
||||
gitlab.33.cn/chat/imparse v1.0.6
|
||||
gitlab.33.cn/utils/go-kit v1.0.7
|
||||
go.etcd.io/etcd/api/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect
|
||||
google.golang.org/grpc v1.40.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/Shopify/sarama.v1 v1.19.0
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
//replace gitlab.33.cn/chat/imparse => ../imparse
|
||||
//replace gitlab.33.cn/chat/im-pkg => ../im-pkg
|
||||
85
pkg/address/address.go
Normal file
85
pkg/address/address.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package address
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/pkg/address/base58"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/address/crypto"
|
||||
)
|
||||
|
||||
//Address 地址
|
||||
type Address struct {
|
||||
Version byte
|
||||
Hash160 [20]byte // For a stealth address: it's HASH160
|
||||
Checksum []byte // Unused for a stealth address
|
||||
Pubkey []byte // Unused for a stealth address
|
||||
Enc58str string
|
||||
}
|
||||
|
||||
//SetBytes 设置地址的bytes
|
||||
func (a *Address) SetBytes(b []byte) {
|
||||
copy(a.Hash160[:], b)
|
||||
}
|
||||
|
||||
func (a *Address) String() string {
|
||||
if a.Enc58str == "" {
|
||||
var ad [25]byte
|
||||
ad[0] = a.Version
|
||||
copy(ad[1:21], a.Hash160[:])
|
||||
if a.Checksum == nil {
|
||||
sh := crypto.Sha2Sum(ad[0:21])
|
||||
a.Checksum = make([]byte, 4)
|
||||
copy(a.Checksum, sh[:4])
|
||||
}
|
||||
copy(ad[21:25], a.Checksum[:])
|
||||
a.Enc58str = base58.Encode(ad[:])
|
||||
}
|
||||
return a.Enc58str
|
||||
}
|
||||
|
||||
//NormalVer 普通地址的版本号
|
||||
const NormalVer byte = 0
|
||||
|
||||
func PublicKeyToAddress(version byte, in []byte) string {
|
||||
a := new(Address)
|
||||
a.Pubkey = make([]byte, len(in))
|
||||
copy(a.Pubkey[:], in[:])
|
||||
a.Version = version
|
||||
a.SetBytes(crypto.Rimp160(in))
|
||||
return a.String()
|
||||
}
|
||||
|
||||
//CheckAddress 检查地址
|
||||
func CheckAddress(ver byte, addr string) (e error) {
|
||||
dec := base58.Decode(addr)
|
||||
if dec == nil {
|
||||
e = errors.New("Cannot decode b58 string '" + addr + "'")
|
||||
return
|
||||
}
|
||||
if len(dec) < 25 {
|
||||
e = errors.New("Address too short " + hex.EncodeToString(dec))
|
||||
return
|
||||
}
|
||||
//version 的错误优先
|
||||
if dec[0] != ver {
|
||||
e = ErrCheckVersion
|
||||
return
|
||||
}
|
||||
//需要兼容以前的错误(以前的错误,是一种特殊的情况)
|
||||
if len(dec) == 25 {
|
||||
sh := crypto.Sha2Sum(dec[0:21])
|
||||
if !bytes.Equal(sh[:4], dec[21:25]) {
|
||||
e = ErrCheckChecksum
|
||||
return
|
||||
}
|
||||
}
|
||||
var cksum [4]byte
|
||||
copy(cksum[:], dec[len(dec)-4:])
|
||||
//新的错误: 这个错误用一种新的错误标记
|
||||
if crypto.Checksum(dec[:len(dec)-4]) != cksum {
|
||||
e = ErrAddressChecksum
|
||||
}
|
||||
return e
|
||||
}
|
||||
30
pkg/address/address_test.go
Normal file
30
pkg/address/address_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package address
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Encoding(t *testing.T) {
|
||||
in, err := hex.DecodeString("02cec0b297406fc5298e9fe829c9f6f96fa176a1bd1a7c55fa0d345a6f49b09d25")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
addr := PublicKeyToAddress(NormalVer, in)
|
||||
t.Log(addr)
|
||||
if err := CheckAddress(NormalVer, addr); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
t.Log("check success")
|
||||
}
|
||||
|
||||
func Test_CheckAddress(t *testing.T) {
|
||||
addr := "1JoFzozbxvst22c2K7MBYwQGjCaMZbC5Qm"
|
||||
if err := CheckAddress(NormalVer, addr); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
t.Log("check success")
|
||||
}
|
||||
50
pkg/address/base58/alphabet.go
Normal file
50
pkg/address/base58/alphabet.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Copyright (c) 2015 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// AUTOGENERATED by genalphabet.go; do not edit.
|
||||
|
||||
package base58
|
||||
|
||||
const (
|
||||
// alphabet is the modified base58 alphabet used by Bitcoin.
|
||||
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
alphabetIdx0 = '1'
|
||||
)
|
||||
|
||||
var b58 = [256]byte{
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 255, 255, 255, 255, 255, 255,
|
||||
255, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 255, 17, 18, 19, 20, 21, 255,
|
||||
22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 255, 255, 255, 255, 255,
|
||||
255, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 255, 44, 45, 46,
|
||||
47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 56, 57, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255,
|
||||
}
|
||||
118
pkg/address/base58/base58.go
Normal file
118
pkg/address/base58/base58.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2013-2015 The btcsuite developers
|
||||
// Copyright (c) 2015-2019 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package base58
|
||||
|
||||
//go:generate go run genalphabet.go
|
||||
|
||||
// Decode decodes a modified base58 string to a byte slice.
|
||||
func Decode(input string) []byte {
|
||||
if len(input) == 0 {
|
||||
return []byte("")
|
||||
}
|
||||
|
||||
// The max possible output size is when a base58 encoding consists of
|
||||
// nothing but the alphabet character at index 0 which would result in the
|
||||
// same number of bytes as the number of input chars.
|
||||
output := make([]byte, len(input))
|
||||
|
||||
// Encode to base256 in reverse order to avoid extra calculations to
|
||||
// determine the final output size in favor of just keeping track while
|
||||
// iterating.
|
||||
var index int
|
||||
for _, r := range input {
|
||||
// Invalid base58 character.
|
||||
val := uint32(b58[r])
|
||||
if val == 255 {
|
||||
return []byte("")
|
||||
}
|
||||
|
||||
// Multiply each byte in the output by 58 and encode to base256 while
|
||||
// propagating the carry.
|
||||
for i, b := range output[:index] {
|
||||
val += uint32(b) * 58
|
||||
output[i] = byte(val)
|
||||
val >>= 8
|
||||
}
|
||||
for ; val > 0; val >>= 8 {
|
||||
output[index] = byte(val)
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
// Account for the leading zeros in the input. They are appended since the
|
||||
// encoding is happening in reverse order.
|
||||
for _, r := range input {
|
||||
if r != alphabetIdx0 {
|
||||
break
|
||||
}
|
||||
|
||||
output[index] = 0
|
||||
index++
|
||||
}
|
||||
|
||||
// Truncate the output buffer to the actual number of decoded bytes and
|
||||
// reverse it since it was calculated in reverse order.
|
||||
output = output[:index:index]
|
||||
for i := 0; i < index/2; i++ {
|
||||
output[i], output[index-1-i] = output[index-1-i], output[i]
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
// Encode encodes a byte slice to a modified base58 string.
|
||||
func Encode(input []byte) string {
|
||||
// Since the conversion is from base256 to base58, the max possible number
|
||||
// of bytes of output per input byte is log_58(256) ~= 1.37. Thus, the max
|
||||
// total output size is ceil(len(input) * 137/100). Rather than worrying
|
||||
// about the ceiling, just add one even if it isn't needed since the final
|
||||
// output is truncated to the right size at the end.
|
||||
output := make([]byte, (len(input)*137/100)+1)
|
||||
|
||||
// Encode to base58 in reverse order to avoid extra calculations to
|
||||
// determine the final output size in favor of just keeping track while
|
||||
// iterating.
|
||||
var index int
|
||||
for _, r := range input {
|
||||
// Multiply each byte in the output by 256 and encode to base58 while
|
||||
// propagating the carry.
|
||||
val := uint32(r)
|
||||
for i, b := range output[:index] {
|
||||
val += uint32(b) << 8
|
||||
output[i] = byte(val % 58)
|
||||
val /= 58
|
||||
}
|
||||
for ; val > 0; val /= 58 {
|
||||
output[index] = byte(val % 58)
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the calculated remainders with their corresponding base58 digit.
|
||||
for i, b := range output[:index] {
|
||||
output[i] = alphabet[b]
|
||||
}
|
||||
|
||||
// Account for the leading zeros in the input. They are appended since the
|
||||
// encoding is happening in reverse order.
|
||||
for _, r := range input {
|
||||
if r != 0 {
|
||||
break
|
||||
}
|
||||
|
||||
output[index] = alphabetIdx0
|
||||
index++
|
||||
}
|
||||
|
||||
// Truncate the output buffer to the actual number of encoded bytes and
|
||||
// reverse it since it was calculated in reverse order.
|
||||
output = output[:index:index]
|
||||
for i := 0; i < index/2; i++ {
|
||||
output[i], output[index-1-i] = output[index-1-i], output[i]
|
||||
}
|
||||
|
||||
return string(output)
|
||||
}
|
||||
44
pkg/address/crypto/hash.go
Normal file
44
pkg/address/crypto/hash.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
func Checksum(input []byte) (cksum [4]byte) {
|
||||
h := sha256.Sum256(input)
|
||||
h2 := sha256.Sum256(h[:])
|
||||
copy(cksum[:], h2[:4])
|
||||
return
|
||||
}
|
||||
|
||||
// Sha2Sum Returns hash: SHA256( SHA256( data ) )
|
||||
// Where possible, using ShaHash() should be a bit faster
|
||||
func Sha2Sum(b []byte) []byte {
|
||||
tmp := sha256.Sum256(b)
|
||||
tmp = sha256.Sum256(tmp[:])
|
||||
return tmp[:]
|
||||
}
|
||||
|
||||
// Rimp160 Returns hash: RIMP160( SHA256( data ) )
|
||||
// Where possible, using RimpHash() should be a bit faster
|
||||
func Rimp160(b []byte) []byte {
|
||||
out := make([]byte, 20)
|
||||
rimpHash(b, out[:])
|
||||
return out[:]
|
||||
}
|
||||
|
||||
func rimpHash(in []byte, out []byte) {
|
||||
sha := sha256.New()
|
||||
_, err := sha.Write(in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rim := ripemd160.New()
|
||||
_, err = rim.Write(sha.Sum(nil)[:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
copy(out, rim.Sum(nil))
|
||||
}
|
||||
12
pkg/address/error.go
Normal file
12
pkg/address/error.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package address
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrCheckVersion :
|
||||
var ErrCheckVersion = errors.New("check version error")
|
||||
|
||||
//ErrCheckChecksum :
|
||||
var ErrCheckChecksum = errors.New("Address Checksum error")
|
||||
|
||||
//ErrAddressChecksum :
|
||||
var ErrAddressChecksum = errors.New("address checksum error")
|
||||
83
pkg/api/api.go
Normal file
83
pkg/api/api.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gopkg.in/go-playground/validator.v8"
|
||||
)
|
||||
|
||||
// 处理跨域请求,支持options访问
|
||||
func Cors() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
method := c.Request.Method
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
c.Header("Access-Control-Allow-Headers", "*") //Content-Type,AccessToken,X-CSRF-Token,Authorization,Token,FZM-APP-ID
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
// 放行所有OPTIONS方法,因为有的模板是要请求两次的
|
||||
if method == "OPTIONS" {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// defaultLogFormatter is the default log format function Logger middleware uses.
|
||||
var Chat33GinLogFormatter = func(param gin.LogFormatterParams) string {
|
||||
var statusColor, methodColor, resetColor string
|
||||
if param.IsOutputColor() {
|
||||
statusColor = param.StatusCodeColor()
|
||||
methodColor = param.MethodColor()
|
||||
resetColor = param.ResetColor()
|
||||
}
|
||||
|
||||
if param.Latency > time.Minute {
|
||||
// Truncate in a golang < 1.8 safe way
|
||||
param.Latency = param.Latency - param.Latency%time.Second
|
||||
}
|
||||
return fmt.Sprintf("[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
|
||||
param.TimeStamp.Format("2006/01/02 - 15:04:05"),
|
||||
statusColor, param.StatusCode, resetColor,
|
||||
param.Latency,
|
||||
param.ClientIP,
|
||||
methodColor, param.Method, resetColor,
|
||||
param.Path,
|
||||
//param.Keys[DeviceType], param.Keys[Version], param.Keys[AppId], param.Keys[UserId], param.Keys[Uuid],
|
||||
param.ErrorMessage,
|
||||
)
|
||||
}
|
||||
|
||||
func CheckNumber(
|
||||
v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
|
||||
field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
|
||||
) bool {
|
||||
val := field.Interface()
|
||||
|
||||
switch val.(type) {
|
||||
case int:
|
||||
return true
|
||||
case string:
|
||||
if val.(string) == "" {
|
||||
return true
|
||||
}
|
||||
_, err := strconv.ParseInt(val.(string), 10, 64)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
case int64:
|
||||
return true
|
||||
default:
|
||||
//utility_log.Error("func ToInt error unknow type")
|
||||
return false
|
||||
}
|
||||
}
|
||||
33
pkg/api/const.go
Normal file
33
pkg/api/const.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
RespMiddleWareDisabled = "RespMiddleWareDisabled"
|
||||
|
||||
ReqError = "error"
|
||||
ReqResult = "result"
|
||||
)
|
||||
|
||||
const (
|
||||
Address = "address"
|
||||
Signature = "signature"
|
||||
DeviceName = "deviceName"
|
||||
DeviceType = "deviceType"
|
||||
Uuid = "uuid"
|
||||
Version = "version"
|
||||
)
|
||||
|
||||
const HeaderTimeOut = 120 * time.Second
|
||||
|
||||
func NewAddrWithContext(ctx context.Context) string {
|
||||
addr, ok := ctx.Value(Address).(string)
|
||||
if !ok {
|
||||
addr = ""
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
142
pkg/api/logger/logmiddleware.go
Normal file
142
pkg/api/logger/logmiddleware.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"time"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/pkg/logger"
|
||||
|
||||
"gitlab.33.cn/chat/dtalk/pkg/api"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
)
|
||||
|
||||
type Middleware struct {
|
||||
log zerolog.Logger
|
||||
}
|
||||
|
||||
func NewMiddleware(log zerolog.Logger) *Middleware {
|
||||
return &Middleware{
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Middleware) Handle() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
body := dumpRequest(ctx.Request)
|
||||
|
||||
start := time.Now()
|
||||
|
||||
ctx.Next()
|
||||
|
||||
tlog := logger.NewLogWithCtx(ctx, m.log)
|
||||
|
||||
latency := time.Since(start)
|
||||
if latency > time.Minute {
|
||||
latency = latency - latency%time.Second
|
||||
}
|
||||
reqURI := ctx.Request.RequestURI
|
||||
if reqURI == "" {
|
||||
reqURI = ctx.Request.URL.RequestURI()
|
||||
}
|
||||
|
||||
tlog.Info().
|
||||
Str("clientIP", ctx.ClientIP()).
|
||||
Str("method", ctx.Request.Method).
|
||||
Str("Path", reqURI).
|
||||
Dur("span", latency).
|
||||
Str("|body", body).
|
||||
Int("status", ctx.Writer.Status()).
|
||||
Msg("http req")
|
||||
|
||||
err, ok := ctx.Get(api.ReqError)
|
||||
if ok {
|
||||
code, msg := parseErr(err)
|
||||
if code != 0 {
|
||||
tlog.Error().
|
||||
Int("code", code).
|
||||
Str("msg", msg).
|
||||
Msg("http err")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ParseErr(err interface{}) (code int, msg string) {
|
||||
return parseErr(err)
|
||||
}
|
||||
|
||||
func parseErr(err interface{}) (code int, msg string) {
|
||||
if err != nil {
|
||||
switch ty := err.(type) {
|
||||
case *xerror.Error:
|
||||
code = ty.Code()
|
||||
msg = ty.Error()
|
||||
case error:
|
||||
code = xerror.CodeInnerError
|
||||
msg = err.(error).Error()
|
||||
default:
|
||||
e := xerror.NewError(xerror.CodeInnerError)
|
||||
code = e.Code()
|
||||
msg = e.Error()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
code = xerror.CodeOK
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func DupReadCloser(reader io.ReadCloser) (io.ReadCloser, io.ReadCloser) {
|
||||
var buf bytes.Buffer
|
||||
tee := io.TeeReader(reader, &buf)
|
||||
return ioutil.NopCloser(tee), ioutil.NopCloser(&buf)
|
||||
}
|
||||
|
||||
// dumpRequest 格式化请求样式
|
||||
func dumpRequest(req *http.Request) string {
|
||||
var dup io.ReadCloser
|
||||
var err error
|
||||
//req.Body, dup = iox.DupReadCloser(req.Body)
|
||||
req.Body, dup = DupReadCloser(req.Body)
|
||||
|
||||
var b bytes.Buffer
|
||||
|
||||
//reqURI := req.RequestURI
|
||||
//if reqURI == "" {
|
||||
// reqURI = req.URL.RequestURI()
|
||||
//}
|
||||
|
||||
//fmt.Fprintf(&b, "%s - %s - HTTP/%d.%d - OperaotrId:%s - ReqBody:", req.Method,
|
||||
// reqURI, req.ProtoMajor, req.ProtoMinor, operatorId)
|
||||
|
||||
chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"
|
||||
if req.Body != nil {
|
||||
var n int64
|
||||
var dest io.Writer = &b
|
||||
if chunked {
|
||||
dest = httputil.NewChunkedWriter(dest)
|
||||
}
|
||||
n, err = io.Copy(dest, req.Body)
|
||||
if chunked {
|
||||
dest.(io.Closer).Close()
|
||||
}
|
||||
if n > 0 {
|
||||
//io.WriteString(&b, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
req.Body = dup
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
192
pkg/api/midware.go
Normal file
192
pkg/api/midware.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
zlog "github.com/rs/zerolog/log"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/address"
|
||||
xerror "gitlab.33.cn/chat/dtalk/pkg/error"
|
||||
"gitlab.33.cn/chat/dtalk/pkg/util"
|
||||
)
|
||||
|
||||
var log = zlog.Logger
|
||||
|
||||
func composeHttpResp(code int, msg string, data interface{}) interface{} {
|
||||
type HttpAck struct {
|
||||
Result int `json:"result"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
var ret HttpAck
|
||||
ret.Result = code
|
||||
ret.Message = msg
|
||||
ret.Data = data
|
||||
return &ret
|
||||
}
|
||||
|
||||
func parseRlt(result interface{}, err interface{}) (code int, msg string, data interface{}) {
|
||||
if err != nil {
|
||||
switch ty := err.(type) {
|
||||
case *xerror.Error:
|
||||
code = ty.Code()
|
||||
msg = ty.Error()
|
||||
data = ty.Data()
|
||||
default:
|
||||
log.Warn().Interface("err", err).Msg("inner error type")
|
||||
e := xerror.NewError(xerror.CodeInnerError)
|
||||
code = e.Code()
|
||||
msg = e.Error()
|
||||
data = err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
code = xerror.CodeOK
|
||||
if isNil(result) {
|
||||
data = gin.H{}
|
||||
} else {
|
||||
data = result
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isNil(i interface{}) bool {
|
||||
vi := reflect.ValueOf(i)
|
||||
if vi.Kind() == reflect.Ptr {
|
||||
return vi.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func RespMiddleWare() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
if v, ok := c.Get(RespMiddleWareDisabled); ok && v == true {
|
||||
return
|
||||
}
|
||||
err := c.MustGet(ReqError)
|
||||
result, _ := c.Get(ReqResult)
|
||||
ret := composeHttpResp(parseRlt(result, err))
|
||||
c.PureJSON(http.StatusOK, ret)
|
||||
//c.PureJSON()
|
||||
}
|
||||
}
|
||||
|
||||
func AuthMiddleWare() gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
sig := context.GetHeader("FZM-SIGNATURE")
|
||||
uuid := context.GetHeader("FZM-UUID")
|
||||
device := context.GetHeader("FZM-DEVICE")
|
||||
deviceName := context.GetHeader("FZM-DEVICE-NAME")
|
||||
version := context.GetHeader("FZM-VERSION")
|
||||
|
||||
//
|
||||
if sig == "MOCK" || sig == "MOCK2" {
|
||||
mockAddr := ""
|
||||
switch sig {
|
||||
case "MOCK":
|
||||
mockAddr = "1FKxgaEh5fuSm7a35BfUnKYAmradowpiTR"
|
||||
case "MOCK2":
|
||||
mockAddr = "1AsPsahP7FvpR7F2de1LhSB4SU5ShqZ7eu"
|
||||
}
|
||||
//set val
|
||||
context.Set(Signature, sig)
|
||||
context.Set(Address, mockAddr)
|
||||
context.Set(Uuid, uuid)
|
||||
context.Set(DeviceType, device)
|
||||
context.Set(DeviceName, deviceName)
|
||||
context.Set(Version, version)
|
||||
} else {
|
||||
pubKey, err := VerifyAddress(sig)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Msg("VerifyAddress failed")
|
||||
context.Set(ReqError, err)
|
||||
context.Abort()
|
||||
return
|
||||
}
|
||||
addr := address.PublicKeyToAddress(address.NormalVer, pubKey)
|
||||
if addr == "" {
|
||||
log.Debug().Msg("PublicKeyToAddress addr is empty")
|
||||
context.Set(ReqError, err)
|
||||
context.Abort()
|
||||
return
|
||||
}
|
||||
//set val
|
||||
context.Set(Signature, sig)
|
||||
context.Set(Address, addr)
|
||||
context.Set(Uuid, uuid)
|
||||
context.Set(DeviceType, device)
|
||||
context.Set(DeviceName, deviceName)
|
||||
context.Set(Version, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func HeaderMiddleWare() gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
uuid := context.GetHeader("FZM-UUID")
|
||||
device := context.GetHeader("FZM-DEVICE")
|
||||
deviceName := context.GetHeader("FZM-DEVICE-NAME")
|
||||
version := context.GetHeader("FZM-VERSION")
|
||||
|
||||
//set val
|
||||
context.Set(Uuid, uuid)
|
||||
context.Set(DeviceType, device)
|
||||
context.Set(DeviceName, deviceName)
|
||||
context.Set(Version, version)
|
||||
}
|
||||
}
|
||||
|
||||
//get pubKey
|
||||
func VerifyAddress(str string) ([]byte, error) {
|
||||
//<signature>#<msg>#<address>; <>
|
||||
ss := strings.SplitN(str, "#", -1)
|
||||
if len(ss) < 3 {
|
||||
log.Debug().Err(fmt.Errorf("need length:%v,got:%v", 3, len(ss))).Str("sig", str).Msg("split signature failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
sigData := ss[0]
|
||||
msgData := ss[1]
|
||||
pubKeyData := ss[2]
|
||||
|
||||
msg := strings.SplitN(msgData, "*", -1)
|
||||
if len(msg) < 2 {
|
||||
log.Debug().Err(fmt.Errorf("need msg length:%v,got:%v", 2, len(ss))).Str("msgData", msgData).Msg("split msg data failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
time, err := strconv.ParseInt(msg[0], 10, 64)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Str("datetime", msg[0]).Msg("ParseInt datetime failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
//secp256
|
||||
sig, err := base64.StdEncoding.DecodeString(sigData)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Str("sigData", sigData).Msg("base64 decode sig data failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
pubKey, err := util.HexDecode(pubKeyData)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Str("pubKeyData", pubKeyData).Msg("hex decode pubKey failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
msg256 := sha256.Sum256([]byte(msgData))
|
||||
if !util.Secp256k1Verify(msg256[:], sig, pubKey) {
|
||||
log.Debug().Err(err).Str("msgData", msgData).Bytes("sig", sig).Bytes("pubKey", pubKey).
|
||||
Msg("Secp256k1Verify failed")
|
||||
return nil, xerror.NewError(xerror.SignatureInvalid)
|
||||
}
|
||||
//检查时间是否过期
|
||||
if util.CheckTimeOut(time, HeaderTimeOut) {
|
||||
log.Debug().Err(err).Int64("time", time).Msg("verify timeout")
|
||||
return nil, xerror.NewError(xerror.SignatureExpired)
|
||||
}
|
||||
return pubKey, nil
|
||||
}
|
||||
15
pkg/api/midware_test.go
Normal file
15
pkg/api/midware_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package api
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_VerifyAddress(t *testing.T) {
|
||||
//sig := "5a3tPpKtUwVzOXAmEFuMRNdHJqJnkjbWUPKVYJDLJRV9+AksajpvT9UUSeNFVVL1W1F8EUDQt01bp11jtV8gbwA=#1610336258730*6XofpoSc#0375610055c57e011a0a51457e0ce451849a4ca588b0ff0beb0ba5d929ca2dd82b"
|
||||
sig := "sjL53g5zbfwREjuBDfTpyaQRfULgip2Ax0Es3tVEIuBCxvWryXm7EVRv/jEmmi6ZlMZZbEXeKlBxrFt41OCPWAE=#1626170987818458*2syd7kfaiw#036801a786cba366d5f62283173681dd5801740d3ef6fe1d4383680f3c0f8e7d4f"
|
||||
|
||||
b, err := VerifyAddress(sig)
|
||||
if err != nil {
|
||||
t.Errorf("verify failed: %v", err)
|
||||
return
|
||||
}
|
||||
t.Logf("verify:%v", b)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user