Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de89b44b21 | ||
|
|
44b18a66c0 | ||
|
|
42281c3ad3 | ||
|
|
776c9e26c6 | ||
|
|
c7f7ce949e | ||
|
|
07b1de4ae3 | ||
|
|
7e87f9d6ab | ||
|
|
da781180a7 | ||
|
|
f1b62ad64a | ||
|
|
576fcf3e77 | ||
|
|
33f2124352 | ||
|
|
15701e9943 | ||
|
|
dc5687319a | ||
|
|
3eef24bdb9 | ||
|
|
be5a24a6fd | ||
|
|
6537b7e009 | ||
|
|
92471db413 | ||
|
|
6626237c80 | ||
|
|
c98507d9a0 | ||
|
|
d8adaf7e88 | ||
|
|
45d40e2389 | ||
|
|
33de0f3e43 | ||
|
|
a9300e8ecc | ||
|
|
368388e7bd | ||
|
|
969de83e1f | ||
|
|
8f74e54c88 | ||
|
|
efd9d5519f | ||
|
|
97b6ccb910 | ||
|
|
c51f523d6e | ||
|
|
298ce69db7 | ||
|
|
15c2d8f59e | ||
|
|
8322134e18 | ||
|
|
52b624f25e | ||
|
|
d90bab53ad | ||
|
|
4d60231c8c | ||
|
|
d08d6f0c49 | ||
|
|
effa30b546 | ||
|
|
0f688ff1df | ||
|
|
daa4767ed8 | ||
|
|
44a916892b | ||
|
|
51dd94d3a7 | ||
|
|
2609a4251c | ||
|
|
7d36775c27 | ||
|
|
6c9df5c071 | ||
|
|
2f9c4e028c | ||
|
|
a9b83a14ed |
@@ -30,28 +30,29 @@
|
||||
## 野火开源项目
|
||||
主要包括以下项目:
|
||||
|
||||
| [GitHub仓库](https://github.com/wildfirechat) | [码云仓库](https://gitee.com/wfchat) | 说明
|
||||
| ------------------------------------------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------
|
||||
| [im-server](https://github.com/wildfirechat/im-server) | [im-server](https://gitee.com/wfchat/im-server) | 野火社区版IM服务,野火IM的核心服务,处理所有IM相关业务。 |
|
||||
| [app-server](https://github.com/wildfirechat/app-server) | [app-server](https://gitee.com/wfchat/app-server) | Demo应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
|
||||
| [robot_server](https://github.com/wildfirechat/robot_server) | [robot_server](https://gitee.com/wfchat/robot_server) | 机器人服务,演示野火机器人对接其它系统的方法。 |
|
||||
| [push_server](https://github.com/wildfirechat/push_server) | [push_server](https://gitee.com/wfchat/push_server) | 推送服务器,可以对接所有的系统厂商推送服务或者第三方推送服务。 |
|
||||
| [wf-minio](https://github.com/wildfirechat/WF-minio) | [wf-minio](https://gitee.com/wfchat/WF-minio) | 私有对象存储服务,用来支持野火IM专业版的文件存储。 |
|
||||
| [wf-janus](https://github.com/wildfirechat/wf-janus ) | [wf-janus](https://gitee.com/wfchat/wf-janus ) | 高级音视频媒体服务。 |
|
||||
| [open-platform](https://github.com/wildfirechat/open-platform) | [open-platform](https://gitee.com/wfchat/open-platform) | 野火开放平台服务。 |
|
||||
| [daily-report](https://github.com/wildfirechat/daily-report) | [daily-report](https://github.com/wildfirechat/daily-report) | 野火开放平台日报 demo服务。 |
|
||||
| [channel-platform](https://github.com/wildfirechat/channel-platform) | [channel-platform](https://gitee.com/wfchat/channel-platform) | 野火频道(公众号)平台服务。 |
|
||||
| [organization-platform](https://github.com/wildfirechat/organization-platform) | [organization-platform](https://gitee.com/wfchat/organization-platform) | 野火组织通讯录服务。 |
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | [android-chat](https://gitee.com/wfchat/android-chat) | 野火IM Android SDK源码和App源码。 |
|
||||
| [ios-chat](https://github.com/wildfirechat/ios-chat) | [ios-chat](https://gitee.com/wfchat/ios-chat) | 野火IM iOS SDK源码和App源码。|
|
||||
| [pc-chat(electron)](https://github.com/wildfirechat/vue-pc-chat) | [pc-chat(electron)](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC 端 | |
|
||||
| [pc-chat(Qt)](https://github.com/wildfirechat/qt-pc-chat) | [pc-chat(Qt)](https://gitee.com/wfchat/qt-pc-chat) | 基于Qt开发的PC 端 | |
|
||||
| [web-chat](https://github.com/wildfirechat/vue-chat) | [web-chat](https://gitee.com/wfchat/vue-chat) | 野火IM Web 端, [体验地址](https://web.wildfirechat.cn)。 |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 小程序平台的Demo(支持微信、百度、阿里、字节、QQ 等小程序平台)。 |
|
||||
| [uni-chat](https://github.com/wildfirechat/uni-chat) | [uni-chat](https://gitee.com/wfchat/uni-chat) | UniApp平台移动端应用(使用原生插件)。 |
|
||||
| [uni-wfc-client](https://github.com/wildfirechat/uni-wfc-client) | [uni-wfc-client](https://gitee.com/wfchat/uni-wfc-client) | UniApp平台原生插件。已[商店](https://ext.dcloud.net.cn/plugin?id=7895)上架 |
|
||||
| [wfc_flutter_plugins](https://github.com/wildfirechat/wfc_flutter_plugins) | [flutter_imclient](https://gitee.com/wfchat/wfc_flutter_plugins) | Flutter平台原生插件,支持IM和音视频通话。 |
|
||||
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/)。 |
|
||||
| [GitHub仓库](https://github.com/wildfirechat) | [码云仓库](https://gitee.com/wfchat) | 说明
|
||||
|--------------------------------------------------------------------------------|-------------------------------------------------------------------------| --------------------------------------------------------------------------
|
||||
| [im-server](https://github.com/wildfirechat/im-server) | [im-server](https://gitee.com/wfchat/im-server) | 野火社区版IM服务,野火IM的核心服务,处理所有IM相关业务。 |
|
||||
| [app-server](https://github.com/wildfirechat/app-server) | [app-server](https://gitee.com/wfchat/app-server) | Demo应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
|
||||
| [robot_server](https://github.com/wildfirechat/robot_server) | [robot_server](https://gitee.com/wfchat/robot_server) | 机器人服务,演示野火机器人对接其它系统的方法。 |
|
||||
| [push_server](https://github.com/wildfirechat/push_server) | [push_server](https://gitee.com/wfchat/push_server) | 推送服务器,可以对接所有的系统厂商推送服务或者第三方推送服务。 |
|
||||
| [wf-minio](https://github.com/wildfirechat/WF-minio) | [wf-minio](https://gitee.com/wfchat/WF-minio) | 私有对象存储服务,用来支持野火IM专业版的文件存储。 |
|
||||
| [wf-janus](https://github.com/wildfirechat/wf-janus ) | [wf-janus](https://gitee.com/wfchat/wf-janus ) | 高级音视频媒体服务。 |
|
||||
| [open-platform](https://github.com/wildfirechat/open-platform) | [open-platform](https://gitee.com/wfchat/open-platform) | 野火开放平台服务。 |
|
||||
| [daily-report](https://github.com/wildfirechat/daily-report) | [daily-report](https://github.com/wildfirechat/daily-report) | 野火开放平台日报 demo服务。 |
|
||||
| [channel-platform](https://github.com/wildfirechat/channel-platform) | [channel-platform](https://gitee.com/wfchat/channel-platform) | 野火频道(公众号)平台服务。 |
|
||||
| [organization-platform](https://github.com/wildfirechat/organization-platform) | [organization-platform](https://gitee.com/wfchat/organization-platform) | 野火组织通讯录服务。 |
|
||||
| [archive-server](https://github.com/wildfirechat/archive-server) | [archive-server](https://gitee.com/wfchat/archive-server) | 野火组织通讯录服务。 |
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | [android-chat](https://gitee.com/wfchat/android-chat) | 野火IM Android SDK源码和App源码。 |
|
||||
| [ios-chat](https://github.com/wildfirechat/ios-chat) | [ios-chat](https://gitee.com/wfchat/ios-chat) | 野火IM iOS SDK源码和App源码。|
|
||||
| [pc-chat(electron)](https://github.com/wildfirechat/vue-pc-chat) | [pc-chat(electron)](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC 端 | |
|
||||
| [pc-chat(Qt)](https://github.com/wildfirechat/qt-pc-chat) | [pc-chat(Qt)](https://gitee.com/wfchat/qt-pc-chat) | 基于Qt开发的PC 端 | |
|
||||
| [web-chat](https://github.com/wildfirechat/vue-chat) | [web-chat](https://gitee.com/wfchat/vue-chat) | 野火IM Web 端, [体验地址](https://web.wildfirechat.cn)。 |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 小程序平台的Demo(支持微信、百度、阿里、字节、QQ 等小程序平台)。 |
|
||||
| [uni-chat](https://github.com/wildfirechat/uni-chat) | [uni-chat](https://gitee.com/wfchat/uni-chat) | UniApp平台移动端应用(使用原生插件)。 |
|
||||
| [uni-wfc-client](https://github.com/wildfirechat/uni-wfc-client) | [uni-wfc-client](https://gitee.com/wfchat/uni-wfc-client) | UniApp平台原生插件。已[商店](https://ext.dcloud.net.cn/plugin?id=7895)上架 |
|
||||
| [flutter-chat](https://github.com/wildfirechat/flutter-chat) | [flutter-chat](https://gitee.com/wfchat/flutter-chat) | Flutter平台原生插件,支持IM和音视频通话。 |
|
||||
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/)。 |
|
||||
|
||||
## 野火开发文档
|
||||
[在线文档](https://docs.wildfirechat.cn/)
|
||||
@@ -163,6 +164,9 @@ mvn clean package
|
||||
|
||||
如果是专业版IM服务,普通群性能会有些加强,但也不会提高太多,所以我们就开发了超级群,可以支持上万群成员。关于超级群,请参考[野火超级群组](https://mp.weixin.qq.com/s/ov5ZiaEIUZuvgFBXOrcjbg)。现有客户有接近10W的群组成员能够流畅稳定地运行。
|
||||
|
||||
## 网络问题
|
||||
如果是自建机房或者私有网络,可能会有跨运营商瓶颈,详情请参考[《从野火 IM 的网络踩坑经历,聊聊跨运营商访问的那些坑》](https://mp.weixin.qq.com/s/Pa8b93oMk58fjMgwtwmePQ)。
|
||||
|
||||
## 常见问题
|
||||
请参考文档[常见问题](https://docs.wildfirechat.cn/faq/server.html)
|
||||
|
||||
|
||||
@@ -174,6 +174,12 @@ robot.callback_with_target_info false
|
||||
## 如果为false,不能@不在会话中的机器人。机器人不在会话中时,也不能回复消息。
|
||||
robot.mention_external_robot true
|
||||
|
||||
## 机器人获取信息允许的字段,可以获取userId/displayName/portrait,其他需要这里配置允许。
|
||||
## 第一位(1)是name, 第二位(2)是mobile,第三(4)位是email,第四位(8)是address,第五位(16)是company,第六位(32)是extra,
|
||||
## 第七位(64)是updateDt,第八位(128)是gender,第九位(256)是social,第十位(512)是type。
|
||||
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
||||
#robot.get_user_info_mask 1023
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
@@ -334,6 +340,15 @@ qiniu.bucket_portrait_name storage
|
||||
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
|
||||
qiniu.bucket_favorite_name storage
|
||||
qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
|
||||
## custom的桶是给客户预留的,客户可以上传自己的文件到这3个桶中,野火不会用到这几个桶。如果不需要,可以忽略这几个配置
|
||||
qiniu.bucket_custom1_name temp1
|
||||
qiniu.bucket_custom1_domain http://temp1.wildfirechat.cn
|
||||
qiniu.bucket_custom2_name temp2
|
||||
qiniu.bucket_custom2_domain http://temp2.wildfirechat.cn
|
||||
qiniu.bucket_custom3_name temp3
|
||||
qiniu.bucket_custom3_domain http://temp3.wildfirechat.cn
|
||||
qiniu.bucket_pan_name pan
|
||||
qiniu.bucket_pan_domain http://pan.wildfirechat.cn
|
||||
|
||||
##媒体类型分类
|
||||
#Media_Type_GENERAL = 0,
|
||||
@@ -366,6 +381,12 @@ server.multi_pc_endpoint false
|
||||
## 是否支持PAD多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PAD端多端登录。
|
||||
server.multi_pad_endpoint false
|
||||
|
||||
## 是否支持可穿戴设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开可穿戴设备多端登录。
|
||||
server.multi_wearable_endpoint false
|
||||
|
||||
## 是否支持TV设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开TV多端登录。
|
||||
server.multi_tv_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或pad或web端登录的通知。
|
||||
server.multi_platform_notification true
|
||||
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_conference`;
|
||||
CREATE TABLE `t_conference` (
|
||||
`_id` varchar(64) NOT NULL PRIMARY KEY,
|
||||
`_des` varchar(64) NOT NULL,
|
||||
`_pin` varchar(16) NOT NULL,
|
||||
`_max_publishers` int(11) NOT NULL DEFAULT 0,
|
||||
`_bitrate` int(11) NOT NULL DEFAULT 0,
|
||||
`_advance` tinyint NOT NULL DEFAULT 0,
|
||||
`_recording` tinyint NOT NULL DEFAULT 0,
|
||||
`_create_dt` bigint(20) NOT NULL
|
||||
);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
DROP TABLE IF EXISTS `t_join_group_request`;
|
||||
CREATE TABLE `t_join_group_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) NOT NULL,
|
||||
`_request_uid` varchar(64) NOT NULL,
|
||||
`_accept_uid` varchar(64) DEFAULT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `join_group_request_key_index` (`_uid` DESC, `_gid` DESC, `_mid` DESC, `_request_uid` DESC),
|
||||
INDEX `join_group_request_gm_index` (`_gid` DESC, `_mid` DESC),
|
||||
INDEX `join_group_request_sync_index` (`_uid` DESC, `_dt` DESC)
|
||||
);
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend add index `friend_uid_index` (`_friend_uid`);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_by` varchar(64) DEFAULT '';
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_deleted` tinyint DEFAULT 0;
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_dt` bigint(20) DEFAULT 0;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_conference`;
|
||||
CREATE TABLE `t_conference` (
|
||||
`_id` varchar(64) NOT NULL PRIMARY KEY,
|
||||
`_des` varchar(64) NOT NULL,
|
||||
`_pin` varchar(16) NOT NULL,
|
||||
`_max_publishers` int(11) NOT NULL DEFAULT 0,
|
||||
`_bitrate` int(11) NOT NULL DEFAULT 0,
|
||||
`_advance` tinyint NOT NULL DEFAULT 0,
|
||||
`_recording` tinyint NOT NULL DEFAULT 0,
|
||||
`_create_dt` bigint(20) NOT NULL
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_join_group_request`;
|
||||
CREATE TABLE `t_join_group_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) NOT NULL,
|
||||
`_request_uid` varchar(64) NOT NULL,
|
||||
`_accept_uid` varchar(64) DEFAULT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `join_group_request_key_index` (`_uid` DESC, `_gid` DESC, `_mid` DESC, `_request_uid` DESC),
|
||||
INDEX `join_group_request_gm_index` (`_gid` DESC, `_mid` DESC),
|
||||
INDEX `join_group_request_sync_index` (`_uid` DESC, `_dt` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend add index `friend_uid_index` (`_friend_uid`);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_by` varchar(64) DEFAULT '';
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_deleted` tinyint DEFAULT 0;
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_dt` bigint(20) DEFAULT 0;
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -96,13 +96,18 @@ public class PushServer {
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_Android ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_APad ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_Harmony ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AppleTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AndroidTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AndroidWearable
|
||||
) {
|
||||
String url = androidPushServerUrl;
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad) {
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad || session.getPlatform() == ProtoConstants.Platform.Platform_AppleTV) {
|
||||
url = iOSPushServerUrl;
|
||||
pushMessage.voipDeviceToken = session.getVoipDeviceToken();
|
||||
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad) {
|
||||
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
url = harmonyPushServerUrl;
|
||||
}
|
||||
HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
|
||||
|
||||
@@ -35,6 +35,9 @@ public class ThreadPoolExecutorWrapper {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LOG.info("execute error = {}", e.toString());
|
||||
} finally {
|
||||
int endCount = runCounter.decrementAndGet();
|
||||
LOG.debug("Finish task and current task count {} use time {}", endCount, System.currentTimeMillis()-startTime);
|
||||
|
||||
@@ -144,7 +144,7 @@ abstract public class Action {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), RestResult.resultOf(errorCode));
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), null);
|
||||
response.setContent(gson.toJson(result));
|
||||
response.send();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
@@ -213,7 +215,7 @@ public class UploadFileAction extends Action {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
remoteFileName = getSafeFileName(remoteFileName);
|
||||
|
||||
String remoteFileExt = "";
|
||||
if (remoteFileName.lastIndexOf(".") == -1) {
|
||||
@@ -339,6 +341,15 @@ public class UploadFileAction extends Action {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String getSafeFileName(String originalFilename) {
|
||||
// Paths.get() 会解析路径,getFileName() 只取最后一部分(纯文件名)
|
||||
Path filenamePath = Paths.get(originalFilename.trim());
|
||||
String safeFilename = filenamePath.getFileName().toString();
|
||||
// 额外过滤特殊字符(可选,根据业务需要)
|
||||
safeFilename = safeFilename.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
return safeFilename.isEmpty() ? "default_file_" + System.currentTimeMillis() : safeFilename;
|
||||
}
|
||||
|
||||
public static void put(File file, long pos, byte[] data) throws Exception {
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputSubscribeChannelBatch;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
|
||||
@Route(APIPath.Batch_Subscribe_Channel)
|
||||
@HttpMethod("POST")
|
||||
public class ChannelSubscriberBatchAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputSubscribeChannelBatch input = getRequestBody(request.getNettyRequest(), InputSubscribeChannelBatch.class);
|
||||
if (input != null && !StringUtil.isNullOrEmpty(input.getChannelId()) && input.getUserIds() != null && !input.getUserIds().isEmpty() ) {
|
||||
ErrorCode errorCode = messagesStore.batchListenChannel(input.getChannelId(), input.getUserIds(), input.getSubscribe()>0);
|
||||
sendResponse(response, errorCode, null);
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class CreateUserAction extends AdminAction {
|
||||
if (inputCreateUser.getName() != null)
|
||||
newUserBuilder.setName(inputCreateUser.getName());
|
||||
if (inputCreateUser.getDisplayName() != null)
|
||||
newUserBuilder.setDisplayName(StringUtil.isNullOrEmpty(inputCreateUser.getDisplayName()) ? inputCreateUser.getName() : inputCreateUser.getDisplayName());
|
||||
newUserBuilder.setDisplayName(inputCreateUser.getDisplayName());
|
||||
if (inputCreateUser.getPortrait() != null)
|
||||
newUserBuilder.setPortrait(inputCreateUser.getPortrait());
|
||||
if (inputCreateUser.getEmail() != null)
|
||||
@@ -65,11 +65,8 @@ public class CreateUserAction extends AdminAction {
|
||||
newUserBuilder.setAddress(inputCreateUser.getAddress());
|
||||
if (inputCreateUser.getCompany() != null)
|
||||
newUserBuilder.setCompany(inputCreateUser.getCompany());
|
||||
|
||||
if (inputCreateUser.getSocial() != null)
|
||||
newUserBuilder.setSocial(inputCreateUser.getSocial());
|
||||
|
||||
|
||||
if (inputCreateUser.getMobile() != null)
|
||||
newUserBuilder.setMobile(inputCreateUser.getMobile());
|
||||
newUserBuilder.setGender(inputCreateUser.getGender());
|
||||
|
||||
@@ -11,12 +11,17 @@ package com.xiaoleilu.loServer.action.admin;
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputUpdateFriendExtra;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
@Route(APIPath.Friend_Set_Extra)
|
||||
@HttpMethod("POST")
|
||||
@@ -31,8 +36,17 @@ public class FriendExtraPutAction extends AdminAction {
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputUpdateFriendExtra input = getRequestBody(request.getNettyRequest(), InputUpdateFriendExtra.class);
|
||||
ErrorCode errorCode = messagesStore.setFriendExtraRequest(input.getOperator(), input.getTargetId(), input.getExtra(), new long[1]);
|
||||
setResponseContent(RestResult.resultOf(errorCode), response);
|
||||
if (input != null && !StringUtil.isNullOrEmpty(input.getOperator()) && !StringUtil.isNullOrEmpty(input.getTargetId())) {
|
||||
sendApiMessage(response, input.getOperator(), IMTopic.SetFriendExtraTopic, WFCMessage.StringPair.newBuilder().setKey(input.getTargetId()).setValue(input.getExtra()==null?"":input.getExtra()).build().toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Route(APIPath.User_Get_All_Robots)
|
||||
@HttpMethod("POST")
|
||||
public class GetAllRobotAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserList input = getRequestBody(request.getNettyRequest(), InputGetUserList.class);
|
||||
if (input != null && input.count > 0 && input.offset >= 0) {
|
||||
List<WFCMessage.Robot> robots = messagesStore.getRobotInfoList(input.count, input.offset);
|
||||
|
||||
OutputGetRobotList outputGetUserList = new OutputGetRobotList();
|
||||
outputGetUserList.robotInfoList = new ArrayList<>();
|
||||
robots.forEach(robotData -> {
|
||||
WFCMessage.User userInfoData = messagesStore.getUserInfo(robotData.getUid());
|
||||
if (userInfoData != null && !StringUtil.isNullOrEmpty(userInfoData.getName()) && userInfoData.getDeleted() ==0) {
|
||||
OutputRobot outputRobot = new OutputRobot();
|
||||
outputRobot.fromUser(userInfoData);
|
||||
outputRobot.fromRobot(robotData, true);
|
||||
outputGetUserList.robotInfoList.add(outputRobot);
|
||||
}
|
||||
});
|
||||
|
||||
RestResult result = RestResult.ok(outputGetUserList);
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfo;
|
||||
import cn.wildfirechat.pojos.PojoGroupInfoList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Group_Batch_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetBatchGroupInfoAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
List<String> inputGetGroup = getRequestBody(request.getNettyRequest(), ArrayList.class);
|
||||
if (inputGetGroup != null && !inputGetGroup.isEmpty()) {
|
||||
List<WFCMessage.UserRequest> requests = new ArrayList<>();
|
||||
for (String s : inputGetGroup) {
|
||||
requests.add(WFCMessage.UserRequest.newBuilder().setUid(s).build());
|
||||
}
|
||||
List<WFCMessage.GroupInfo> groupInfoDataList = messagesStore.getGroupInfos(requests);
|
||||
PojoGroupInfoList pojoGroupInfoList = new PojoGroupInfoList();
|
||||
pojoGroupInfoList.groupInfoList = new ArrayList<>();
|
||||
|
||||
for (WFCMessage.GroupInfo groupInfo : groupInfoDataList) {
|
||||
pojoGroupInfoList.groupInfoList.add(PojoGroupInfo.fromProto(groupInfo));
|
||||
}
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.ok(pojoGroupInfoList);
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputCountOffset;
|
||||
import cn.wildfirechat.pojos.OutputChannelInfoList;
|
||||
import cn.wildfirechat.pojos.OutputGetChannelInfo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.List_Channel_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetChannelListAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputCountOffset inputCreateChannel = getRequestBody(request.getNettyRequest(), InputCountOffset.class);
|
||||
if (inputCreateChannel != null
|
||||
&& inputCreateChannel.count > 0 && inputCreateChannel.offset >= 0) {
|
||||
int count = messagesStore.getChannelTotalCount(false);
|
||||
List<WFCMessage.ChannelInfo> list = messagesStore.getChannelInfoList(inputCreateChannel.count, inputCreateChannel.offset, false);
|
||||
OutputChannelInfoList outputChannelInfoList = new OutputChannelInfoList();
|
||||
outputChannelInfoList.total = count;
|
||||
outputChannelInfoList.list = new ArrayList<>();
|
||||
for (WFCMessage.ChannelInfo channelData : list) {
|
||||
outputChannelInfoList.list.add(OutputGetChannelInfo.fromPbInfo(channelData));
|
||||
}
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, outputChannelInfoList);
|
||||
} else {
|
||||
sendResponse(response, ErrorCode.INVALID_PARAMETER, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -46,25 +46,7 @@ public class GetGroupInfoAction extends AdminAction {
|
||||
if (groupInfo == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setMute(groupInfo.getMute());
|
||||
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
|
||||
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
|
||||
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
|
||||
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
|
||||
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
result = RestResult.ok(pojoGroupInfo);
|
||||
result = RestResult.ok(PojoGroupInfo.fromProto(groupInfo));
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetPresignedUploadUrl;
|
||||
import cn.wildfirechat.pojos.OutputPresignedUploadUrl;
|
||||
import com.qiniu.util.Auth;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.robot.RobotAction;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.server.config.MediaServerConfig;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Route(APIPath.Get_Presigned_Upload_Url)
|
||||
@HttpMethod("POST")
|
||||
public class GetUploadUrlAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
if(!MediaServerConfig.USER_QINIU) {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
return true;
|
||||
}
|
||||
|
||||
InputGetPresignedUploadUrl inputUserId = getRequestBody(request.getNettyRequest(), InputGetPresignedUploadUrl.class);
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputUserId.contentType)) {
|
||||
inputUserId.contentType = "application/octet-stream";
|
||||
}
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
inputUserId.fileName = uuid + inputUserId.fileName;
|
||||
|
||||
int type = inputUserId.mediaType;
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
case 0:
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
break;
|
||||
case 1:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_IMAGE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_IMAGE_DOMAIN;
|
||||
break;
|
||||
case 2:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VOICE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VOICE_DOMAIN;
|
||||
break;
|
||||
case 3:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VIDEO_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VIDEO_DOMAIN;
|
||||
break;
|
||||
case 4:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FILE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FILE_DOMAIN;
|
||||
break;
|
||||
case 5:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PORTRAIT_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
break;
|
||||
case 6:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
break;
|
||||
case 7:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
|
||||
break;
|
||||
case 8:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(bucketName)) {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
}
|
||||
|
||||
String key = inputUserId.fileName;
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
String token = auth.uploadToken(bucketName, key);
|
||||
String downloadUrl = bucketDomain + "/" + key;
|
||||
String uploadUrl = "https://" + MediaServerConfig.QINIU_SERVER_URL + "?" + token + "?" + key;
|
||||
|
||||
OutputPresignedUploadUrl outputPresignedUploadUrl = new OutputPresignedUploadUrl();
|
||||
outputPresignedUploadUrl.uploadUrl = uploadUrl;
|
||||
outputPresignedUploadUrl.downloadUrl = downloadUrl;
|
||||
outputPresignedUploadUrl.type = 1;
|
||||
setResponseContent(RestResult.ok(outputPresignedUploadUrl), response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public class GetUserAction extends AdminAction {
|
||||
}
|
||||
|
||||
RestResult result;
|
||||
if (user == null || user.getDeleted() > 0) {
|
||||
if (user == null || (user.getDeleted() > 0 && !inputUserId.isIncludeDeleted())) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(InputOutputUserInfo.fromPbUser(user));
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputRobotId;
|
||||
import cn.wildfirechat.pojos.InputUserId;
|
||||
import cn.wildfirechat.pojos.OutputRobot;
|
||||
import cn.wildfirechat.pojos.OutputStringList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.User_Get_User_Robots)
|
||||
@HttpMethod("POST")
|
||||
public class GetUserRobotsAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputUserId inputUserId = getRequestBody(request.getNettyRequest(), InputUserId.class);
|
||||
if (inputUserId != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputUserId.getUserId()))) {
|
||||
RestResult result = RestResult.ok(new OutputStringList(messagesStore.getUserRobotIds(inputUserId.getUserId())));
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputUserInfoList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.User_Get_By_Mobile)
|
||||
@HttpMethod("POST")
|
||||
public class GetUsersByMobileAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserInfo email = getRequestBody(request.getNettyRequest(), InputGetUserInfo.class);
|
||||
if (!StringUtil.isNullOrEmpty(email.getMobile())) {
|
||||
List<WFCMessage.User> users = messagesStore.getUserInfosByMobile(email.getMobile(), email.isIncludeDeleted());
|
||||
List<InputOutputUserInfo> list = new ArrayList<>();
|
||||
for (WFCMessage.User user : users) {
|
||||
list.add(InputOutputUserInfo.fromPbUser(user));
|
||||
}
|
||||
|
||||
RestResult result;
|
||||
if (list.isEmpty()) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
OutputUserInfoList outputUserInfoList = new OutputUserInfoList();
|
||||
outputUserInfoList.userInfos = list;
|
||||
result = RestResult.ok(outputUserInfoList);
|
||||
}
|
||||
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputStringCountOffset;
|
||||
import cn.wildfirechat.pojos.InputSubscribeChannel;
|
||||
import cn.wildfirechat.pojos.OutputBooleanValue;
|
||||
import cn.wildfirechat.pojos.PojoTotalList;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.List_Channel_Subscriber)
|
||||
@HttpMethod("POST")
|
||||
public class ListChannelSubscriberAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputStringCountOffset inputSubscribeChannel = getRequestBody(request.getNettyRequest(), InputStringCountOffset.class);
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (inputSubscribeChannel != null
|
||||
&& !StringUtil.isNullOrEmpty(inputSubscribeChannel.target)
|
||||
&& inputSubscribeChannel.count > 0) {
|
||||
int count = messagesStore.getChannelListenerCount(inputSubscribeChannel.target);
|
||||
List<String> list = messagesStore.getChannelListenerList(inputSubscribeChannel.target, inputSubscribeChannel.count, inputSubscribeChannel.offset);
|
||||
RestResult result = RestResult.ok(new PojoTotalList(count, list));
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputChatroomMute;
|
||||
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.Chatroom_MuteAll)
|
||||
@HttpMethod("POST")
|
||||
public class SetChatroomMuteAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputChatroomMute input = getRequestBody(request.getNettyRequest(), InputChatroomMute.class);
|
||||
if (input != null
|
||||
&& !StringUtil.isNullOrEmpty(input.getChatroomId())) {
|
||||
|
||||
ErrorCode code = messagesStore.setChatroomState(input.getChatroomId(), input.getStatus());
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
response.setContent(gson.toJson(RestResult.resultOf(code)));
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_SUCCESS, null);
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.UserSettingPojo;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
@Route(APIPath.User_Get_Setting)
|
||||
@HttpMethod("POST")
|
||||
public class UserSettingGetAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
UserSettingPojo input = getRequestBody(request.getNettyRequest(), UserSettingPojo.class);
|
||||
if (input != null && (!StringUtil.isNullOrEmpty(input.getUserId()))) {
|
||||
WFCMessage.UserSettingEntry entry = messagesStore.getUserSetting(input.getUserId(), input.getScope(), input.getKey());
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result;
|
||||
if (entry == null) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
input.setValue(entry.getValue());
|
||||
result = RestResult.ok(input);
|
||||
}
|
||||
response.setContent(gson.toJson(result));
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.UserSettingPojo;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
|
||||
|
||||
@Route(APIPath.User_Put_Setting)
|
||||
@HttpMethod("POST")
|
||||
public class UserSettingPutAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
UserSettingPojo userSettingPojo = getRequestBody(request.getNettyRequest(), UserSettingPojo.class);
|
||||
if (userSettingPojo != null && !StringUtil.isNullOrEmpty(userSettingPojo.getUserId())) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(userSettingPojo.getScope()).setKey(userSettingPojo.getKey()).setValue(userSettingPojo.getValue()).build();
|
||||
sendApiMessage(response, userSettingPojo.getUserId(), PutUserSettingTopic, modifyUserSettingReq.toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
|
||||
response.setContent(gson.toJson(result));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.InputStringList;
|
||||
import cn.wildfirechat.pojos.OutputUserInfoList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Robot_User_Batch_Get_Infos)
|
||||
@HttpMethod("POST")
|
||||
public class GetBatchUserAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputStringList inputUserId = getRequestBody(request.getNettyRequest(), InputStringList.class);
|
||||
if (inputUserId != null && inputUserId.getList() != null && !inputUserId.getList().isEmpty()) {
|
||||
|
||||
OutputUserInfoList res = new OutputUserInfoList();
|
||||
res.userInfos = new ArrayList<>();
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
for (String userId : inputUserId.getList()) {
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user == null || StringUtil.isNullOrEmpty(user.getName())) {
|
||||
continue;
|
||||
}
|
||||
InputOutputUserInfo inputOutputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
if((mask & 1) == 0) {
|
||||
inputOutputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
inputOutputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
inputOutputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
inputOutputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
inputOutputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
inputOutputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
inputOutputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
inputOutputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
inputOutputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
inputOutputUserInfo.setType(0);
|
||||
}
|
||||
res.userInfos.add(inputOutputUserInfo);
|
||||
}
|
||||
RestResult result = RestResult.ok(res);
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetPresignedUploadUrl;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputPresignedUploadUrl;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.qiniu.util.Auth;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.moquette.persistence.MemorySessionStore;
|
||||
import io.moquette.server.config.MediaServerConfig;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@Route(APIPath.Robot_Get_Presigned_Upload_Url)
|
||||
@HttpMethod("POST")
|
||||
public class GetUploadUrlAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
if(!MediaServerConfig.USER_QINIU) {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
return true;
|
||||
}
|
||||
|
||||
InputGetPresignedUploadUrl inputUserId = getRequestBody(request.getNettyRequest(), InputGetPresignedUploadUrl.class);
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputUserId.contentType)) {
|
||||
inputUserId.contentType = "application/octet-stream";
|
||||
}
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
inputUserId.fileName = uuid + inputUserId.fileName;
|
||||
|
||||
int type = inputUserId.mediaType;
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
case 0:
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
break;
|
||||
case 1:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_IMAGE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_IMAGE_DOMAIN;
|
||||
break;
|
||||
case 2:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VOICE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VOICE_DOMAIN;
|
||||
break;
|
||||
case 3:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VIDEO_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VIDEO_DOMAIN;
|
||||
break;
|
||||
case 4:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FILE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FILE_DOMAIN;
|
||||
break;
|
||||
case 5:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PORTRAIT_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
break;
|
||||
case 6:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
break;
|
||||
case 7:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
|
||||
break;
|
||||
case 8:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(bucketName)) {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
}
|
||||
|
||||
String key = inputUserId.fileName;
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
String token = auth.uploadToken(bucketName, key);
|
||||
String downloadUrl = bucketDomain + "/" + key;
|
||||
String uploadUrl = "https://" + MediaServerConfig.QINIU_SERVER_URL + "?" + token + "?" + key;
|
||||
|
||||
OutputPresignedUploadUrl outputPresignedUploadUrl = new OutputPresignedUploadUrl();
|
||||
outputPresignedUploadUrl.uploadUrl = uploadUrl;
|
||||
outputPresignedUploadUrl.downloadUrl = downloadUrl;
|
||||
outputPresignedUploadUrl.type = 1;
|
||||
setResponseContent(RestResult.ok(outputPresignedUploadUrl), response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,39 @@ public class GetUserAction extends RobotAction {
|
||||
if (user == null || user.getDeleted() > 0) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(InputOutputUserInfo.fromPbUser(user));
|
||||
InputOutputUserInfo outputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
if((mask & 1) == 0) {
|
||||
outputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
outputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
outputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
outputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
outputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
outputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
outputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
outputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
outputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
outputUserInfo.setType(0);
|
||||
}
|
||||
result = RestResult.ok(outputUserInfo);
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputUserInfoList;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Route(APIPath.Robot_User_Get_Email_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetUsersByEmailAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
String email = getRequestBody(request.getNettyRequest(), String.class);
|
||||
if (!StringUtil.isNullOrEmpty(email)) {
|
||||
|
||||
List<WFCMessage.User> users = messagesStore.getUserInfosByEmail(email);
|
||||
List<InputOutputUserInfo> list = new ArrayList<>();
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
for (WFCMessage.User user : users) {
|
||||
InputOutputUserInfo outputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
if((mask & 1) == 0) {
|
||||
outputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
outputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
outputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
outputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
outputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
outputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
outputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
outputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
outputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
outputUserInfo.setType(0);
|
||||
}
|
||||
list.add(outputUserInfo);
|
||||
}
|
||||
|
||||
RestResult result;
|
||||
if (list.isEmpty()) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
OutputUserInfoList outputUserInfoList = new OutputUserInfoList();
|
||||
outputUserInfoList.userInfos = list;
|
||||
result = RestResult.ok(outputUserInfoList);
|
||||
}
|
||||
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,15 @@ public final class BrokerConstants {
|
||||
public static final String QINIU_BUCKET_PORTRAIT_DOMAIN = "qiniu.bucket_portrait_domain";
|
||||
public static final String QINIU_BUCKET_FAVORITE_NAME= "qiniu.bucket_favorite_name";
|
||||
public static final String QINIU_BUCKET_FAVORITE_DOMAIN = "qiniu.bucket_favorite_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM1_NAME= "qiniu.bucket_custom1_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM1_DOMAIN = "qiniu.bucket_custom1_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM2_NAME= "qiniu.bucket_custom2_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM2_DOMAIN = "qiniu.bucket_custom2_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM3_NAME= "qiniu.bucket_custom3_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM3_DOMAIN = "qiniu.bucket_custom3_domain";
|
||||
public static final String QINIU_BUCKET_PAN_NAME= "qiniu.bucket_pan_name";
|
||||
public static final String QINIU_BUCKET_PAN_DOMAIN = "qiniu.bucket_pan_domain";
|
||||
|
||||
|
||||
public static final String FILE_STORAGE_ROOT = "local.media.storage.root";
|
||||
public static final String FILE_STORAGE_REMOTE_SERVER_URL = "local.media.storage.remote_server_url";
|
||||
@@ -139,6 +148,8 @@ public final class BrokerConstants {
|
||||
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
|
||||
public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_endpoint";
|
||||
public static final String SERVER_MULTI_PAD_ENDPOINT = "server.multi_pad_endpoint";
|
||||
public static final String SERVER_MULTI_WEARABLE_ENDPOINT = "server.multi_wearable_endpoint";
|
||||
public static final String SERVER_MULTI_TV_ENDPOINT = "server.multi_tv_endpoint";
|
||||
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
|
||||
public static final String SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE = "server.mobile_default_silent_when_pc_online";
|
||||
public static final String SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
|
||||
@@ -174,7 +185,7 @@ public final class BrokerConstants {
|
||||
public static final String ROBOT_Callback_With_Sender_Info = "robot.callback_with_sender_info";
|
||||
public static final String ROBOT_Callback_With_Target_Info = "robot.callback_with_target_info";
|
||||
public static final String ROBOT_Mention_External_Robot = "robot.mention_external_robot";
|
||||
|
||||
public static final String ROBOT_Get_User_Info_Mask = "robot.get_user_info_mask";
|
||||
|
||||
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
|
||||
public static final String CHANNEL_Callback_With_Sender_Info = "channel.callback_with_sender_info";
|
||||
|
||||
@@ -32,7 +32,6 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
||||
if (MediaServerConfig.USER_QINIU) {
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
|
||||
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
@@ -72,6 +71,22 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
|
||||
@@ -77,6 +77,22 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.moquette.spi.impl.security.TokenAuthenticator;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.UserSettingScope;
|
||||
|
||||
@Handler(IMTopic.GetTokenTopic)
|
||||
public class GetTokenHandler extends IMHandler<WFCMessage.GetTokenRequest> {
|
||||
@@ -26,6 +27,11 @@ public class GetTokenHandler extends IMHandler<WFCMessage.GetTokenRequest> {
|
||||
if(userInfo != null && userInfo.getType() == 1) {
|
||||
return ErrorCode.ERROR_CODE_ROBOT_NO_TOKEN;
|
||||
}
|
||||
if(session.isPcClient() || session.isPadClient() || session.isTVClient()) {
|
||||
if(m_messagesStore.isLocked(session.getUsername(), session.getClientID())) {
|
||||
m_messagesStore.updateUserSettings(session.getUsername(), WFCMessage.ModifyUserSettingReq.newBuilder().setScope(UserSettingScope.UserSettingScopeLockPC).setKey(session.getClientID()).setValue("0").build(), null);
|
||||
}
|
||||
}
|
||||
|
||||
TokenAuthenticator authenticator = new TokenAuthenticator();
|
||||
String strToken = authenticator.generateToken(fromUser);
|
||||
|
||||
@@ -45,20 +45,20 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
|
||||
contentBuilder.setType(92);
|
||||
|
||||
builder = WFCMessage.Message.newBuilder();
|
||||
builder.setFromUser(request.getTargetUid());
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setFromUser(fromUser);
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(request.getTargetUid()).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setContent(contentBuilder);
|
||||
builder.setServerTimestamp(++timestamp);
|
||||
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), requestSourceType);
|
||||
saveAndPublish(fromUser, null, builder.build(), requestSourceType);
|
||||
contentBuilder.setType(93);
|
||||
builder.setContent(contentBuilder);
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
builder.setServerTimestamp(++timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), requestSourceType);
|
||||
saveAndPublish(fromUser, null, builder.build(), requestSourceType);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.SetFriendExtraTopic)
|
||||
public class SetFriendExtraHandler extends IMHandler<WFCMessage.StringPair> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.StringPair request, Qos1PublishHandler.IMCallback callback) {
|
||||
long[] heads = new long[1];
|
||||
ErrorCode errorCode = m_messagesStore.setFriendExtraRequest(fromUser, request.getKey(), request.getValue(), heads);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[0], clientID);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
@@ -1870,6 +1870,10 @@ public class DatabaseStore {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
|
||||
} else if(platform == ProtoConstants.Platform.Platform_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad) {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
|
||||
} else {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and `_platform` = ? and `_cid` <> ? and `_deleted` = 0";
|
||||
}
|
||||
@@ -1897,6 +1901,13 @@ public class DatabaseStore {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_iPad);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_APad);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyPad);
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AndroidWearable);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyWearable);
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AndroidTV);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AppleTV);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyTV);
|
||||
} else {
|
||||
statement.setInt(index++, platform);
|
||||
}
|
||||
@@ -3080,6 +3091,102 @@ public class DatabaseStore {
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
List<WFCMessage.User> outList = new ArrayList<>();
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select `_uid`, `_name`" +
|
||||
", `_display_name`" +
|
||||
", `_portrait`" +
|
||||
", `_mobile`" +
|
||||
", `_gender`" +
|
||||
", `_email`" +
|
||||
", `_address`" +
|
||||
", `_company`" +
|
||||
", `_social`" +
|
||||
", `_extra`" +
|
||||
", `_type`" +
|
||||
", `_deleted`" +
|
||||
", `_dt` from t_user where `_mobile` = ?";
|
||||
if(!includeDeleted) {
|
||||
sql += " and `_deleted` = 0";
|
||||
}
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, mobile);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
WFCMessage.User.Builder builder = WFCMessage.User.newBuilder();
|
||||
int index = 1;
|
||||
String value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setUid(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setName(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setDisplayName(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setPortrait(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setMobile(value);
|
||||
|
||||
int gender = rs.getInt(index++);
|
||||
builder.setGender(gender);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setEmail(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setAddress(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setCompany(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setSocial(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setExtra(value);
|
||||
|
||||
int type = rs.getInt(index++);
|
||||
builder.setType(type);
|
||||
|
||||
int deleted = rs.getInt(index++);
|
||||
builder.setDeleted(deleted);
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
if(longValue <= 0)
|
||||
longValue = 1;
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
outList.add(builder.build());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> getAllUsers(int count, int offset) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -3177,6 +3284,97 @@ public class DatabaseStore {
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<WFCMessage.Robot> getAllRobots(int count, int offset) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
List<WFCMessage.Robot> outList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select `_uid`, `_owner`" +
|
||||
", `_secret`" +
|
||||
", `_callback`" +
|
||||
", `_state`" +
|
||||
", `_extra`" +
|
||||
", `_dt` from t_robot limit ? offset ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setInt(1, count);
|
||||
statement.setInt(2, offset);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
WFCMessage.Robot.Builder builder = WFCMessage.Robot.newBuilder();
|
||||
index = 1;
|
||||
String value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setUid(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setOwner(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setSecret(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setCallback(value);
|
||||
|
||||
|
||||
int state = rs.getInt(index++);
|
||||
builder.setState(state);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setExtra(value);
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
|
||||
outList.add(builder.build());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<String> getUserRobotIds(String userId) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
List<String> outList = new ArrayList<>();
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _uid from t_robot where _owner = ? and _state = 0";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(1, userId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
outList.add(rs.getString(1));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return outList;
|
||||
}
|
||||
|
||||
|
||||
Set<String> getAllEnds(boolean fromUserTable) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -3719,7 +3917,6 @@ public class DatabaseStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
void persistChannelListener(final String groupId, final List<String> memberList) {
|
||||
mScheduler.execute(()->{
|
||||
Connection connection = null;
|
||||
@@ -3984,6 +4181,279 @@ public class DatabaseStore {
|
||||
}
|
||||
}
|
||||
|
||||
void batchInsertChannelListener(String channelId, List<String> listeners, boolean listen) throws SQLException {
|
||||
LOG.info("updateChannelListener {}", channelId);
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
int size = 0;
|
||||
String sql = listen
|
||||
? "insert into t_channel_listener (_cid, _mid, _dt) values(?, ?, ?)"
|
||||
: "delete from t_channel_listener where _cid=? and _mid=?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
for (String listener : listeners) {
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
statement.setString(index++, listener);
|
||||
if (listen) {
|
||||
statement.setLong(index++, System.currentTimeMillis());
|
||||
}
|
||||
statement.addBatch();
|
||||
if(++size%100 == 0) {
|
||||
statement.executeBatch();
|
||||
statement.clearBatch();
|
||||
}
|
||||
}
|
||||
if(size%100 != 0) {
|
||||
statement.executeBatch();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
throw e;
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> findMissingMids(String cid, List<String> midList, boolean contain) {
|
||||
if (midList == null || midList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
String tempTable = "temp_check_mids_" + System.currentTimeMillis();
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = DBUtil.getConnection();
|
||||
|
||||
// Step 1: 创建临时表
|
||||
try (Statement st = conn.createStatement()) {
|
||||
st.execute("CREATE TEMPORARY TABLE " + tempTable +
|
||||
" (_mid VARCHAR(64) NOT NULL PRIMARY KEY)");
|
||||
}
|
||||
|
||||
// Step 2: 批量插入
|
||||
String insertSql = "INSERT IGNORE INTO " + tempTable + " (_mid) VALUES (?)";
|
||||
try (PreparedStatement ps = conn.prepareStatement(insertSql)) {
|
||||
int count = 0;
|
||||
for (String mid : midList) {
|
||||
ps.setString(1, mid);
|
||||
ps.addBatch();
|
||||
if (++count % 1000 == 0) {
|
||||
ps.executeBatch();
|
||||
ps.clearBatch();
|
||||
}
|
||||
}
|
||||
if (count % 1000 != 0) {
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: 查询
|
||||
String querySql = "SELECT t._mid FROM " + tempTable + " t " +
|
||||
"WHERE " + (contain ? "" : " NOT ") + " EXISTS (" +
|
||||
" SELECT 1 FROM t_channel_listener c " +
|
||||
" WHERE c._cid = ? AND c._mid = t._mid" +
|
||||
")";
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
try (PreparedStatement ps = conn.prepareStatement(querySql)) {
|
||||
ps.setString(1, cid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
result.add(rs.getString(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("查询缺失mid失败", e);
|
||||
} finally {
|
||||
// 显式清理临时表
|
||||
if (conn != null) {
|
||||
try (Statement st = conn.createStatement()) {
|
||||
st.execute("DROP TEMPORARY TABLE IF EXISTS " + tempTable);
|
||||
} catch (SQLException ignored) {
|
||||
// 清理失败不影响主流程
|
||||
} finally {
|
||||
try { conn.close(); } catch (SQLException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted) {
|
||||
List<WFCMessage.ChannelInfo> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _cid, _name" +
|
||||
", _portrait" +
|
||||
", _owner" +
|
||||
", _status" +
|
||||
", _desc" +
|
||||
", _extra" +
|
||||
", _dt from t_channel";
|
||||
if(!withDeleted) {
|
||||
sql += " where _status <> 64 ";
|
||||
}
|
||||
sql += " order by _dt desc ";
|
||||
|
||||
sql += " limit " + count;
|
||||
|
||||
if (offset > 0) {
|
||||
sql += " offset " + offset;
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
WFCMessage.ChannelInfo.Builder builder = WFCMessage.ChannelInfo.newBuilder();
|
||||
int index = 1;
|
||||
|
||||
String value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setTargetId(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setName(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setPortrait(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setOwner(value);
|
||||
|
||||
int status = rs.getInt(index++);
|
||||
builder.setStatus(status);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setDesc(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setExtra(value);
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
builder.setUpdateDt(longValue);
|
||||
|
||||
out.add(builder.build());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int getChannelTotalCount(boolean withDeleted) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select count(*) from t_channel";
|
||||
if(!withDeleted) {
|
||||
sql += " where _status <> 64";
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getChannelListenerCount(String channelId) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select count(*) from t_channel_listener where _cid = ?";
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public List<String> getChannelListenerList(String channelId, int count, int offset) {
|
||||
List<String> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _mid from t_channel_listener where _cid = ?";
|
||||
|
||||
if(count > 0) {
|
||||
sql += " limit " + count;
|
||||
}
|
||||
|
||||
if(offset > 0) {
|
||||
sql += " offset " + offset;
|
||||
}
|
||||
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(index++, channelId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
String value = rs.getString(1);
|
||||
if (!StringUtil.isNullOrEmpty(value)) {
|
||||
out.add(value);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getSensitiveWord() {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -48,6 +48,7 @@ import win.liyufan.im.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -78,8 +79,8 @@ import static io.moquette.BrokerConstants.*;
|
||||
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.pojos.MyInfoType.*;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingAddFriendStrategy;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.*;
|
||||
|
||||
public class MemoryMessagesStore implements IMessagesStore {
|
||||
private static final String MESSAGES_MAP = "messages_map";
|
||||
@@ -222,6 +223,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private boolean mRobotCallbackWithSenderInfo = false;
|
||||
private boolean mRobotCallbackWithTargetInfo = false;
|
||||
private boolean mRobotMentionExternalRobot = false;
|
||||
private int mRobotGetUserInfoMask = 0;
|
||||
|
||||
private boolean mChannelCallbackWithClientInfo = false;
|
||||
private boolean mChannelCallbackWithSenderInfo = false;
|
||||
@@ -684,6 +686,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
try {
|
||||
mRobotMentionExternalRobot = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Mention_External_Robot, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotGetUserInfoMask = Integer.parseInt(server.getConfig().getProperty(BrokerConstants.ROBOT_Get_User_Info_Mask, "0"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||
@@ -1338,6 +1343,20 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode setChatroomState(String chatroomId, int status) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.ChatroomInfo> chatroomInfoMap = hzInstance.getMap(CHATROOMS);
|
||||
WFCMessage.ChatroomInfo info = chatroomInfoMap.get(chatroomId);
|
||||
|
||||
if (info == null) {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
info = info.toBuilder().setState(status).build();
|
||||
chatroomInfoMap.set(chatroomId, info);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long insertChatroomMessages(String target, int line, long messageId) {
|
||||
// messageId是全局的,messageSeq是跟个人相关的,理论上messageId的增长数度远远大于seq。
|
||||
@@ -2322,6 +2341,19 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
ArrayList<WFCMessage.GroupInfo> out = new ArrayList<>();
|
||||
for (WFCMessage.UserRequest request : requests) {
|
||||
WFCMessage.GroupInfo groupInfo = mIMap.get(request.getUid());
|
||||
out.add(groupInfo);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WFCMessage.GroupInfo getGroupInfo(String groupId) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
@@ -2434,6 +2466,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if(newOwner.equals(groupInfo.getOwner())) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
//check the new owner is in member list? is that necessary?
|
||||
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
|
||||
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
|
||||
@@ -3023,6 +3059,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
String pcValue = null;
|
||||
String padValue = null;
|
||||
String wearableValue = null;
|
||||
String tvValue = null;
|
||||
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
|
||||
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
|
||||
continue;
|
||||
@@ -3040,6 +3078,15 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
case Platform_HarmonyPad:
|
||||
padValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
case Platform_AndroidWearable:
|
||||
case Platform_HarmonyWearable:
|
||||
wearableValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
case Platform_AndroidTV:
|
||||
case Platform_AppleTV:
|
||||
case Platform_HarmonyTV:
|
||||
tvValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3054,6 +3101,16 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (!isOnlineValueEqual(padentry, padValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Pad").setValue(padValue==null?"":padValue).build(), session.clientID);
|
||||
}
|
||||
|
||||
WFCMessage.UserSettingEntry wearableEntry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "Wearable");
|
||||
if (!isOnlineValueEqual(wearableEntry, wearableValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Wearable").setValue(wearableValue==null?"":wearableValue).build(), session.clientID);
|
||||
}
|
||||
|
||||
WFCMessage.UserSettingEntry tvEntry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "TV");
|
||||
if (!isOnlineValueEqual(tvEntry, tvValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("TV").setValue(tvValue==null?"":tvValue).build(), session.clientID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3172,7 +3229,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
|
||||
WFCMessage.User us = mUserMap.get(userId);
|
||||
if (us != null) {
|
||||
WFCMessage.User.Builder builder = WFCMessage.User.newBuilder().setUpdateDt(System.currentTimeMillis()).setDeleted(1);
|
||||
WFCMessage.User.Builder builder = us.toBuilder().setUpdateDt(System.currentTimeMillis()).setDeleted(1);
|
||||
|
||||
if(keepFullInfoWhenDestroyUser) {
|
||||
if(!keepMobileWhenDestroyUser) {
|
||||
@@ -3244,11 +3301,26 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return databaseStore.getUserInfosByEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted) {
|
||||
return databaseStore.getUserInfosByMobile(mobile, includeDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> getUserInfoList(int count, int offset) {
|
||||
return databaseStore.getAllUsers(count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.Robot> getRobotInfoList(int count, int offset) {
|
||||
return databaseStore.getAllRobots(count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUserRobotIds(String userId) {
|
||||
return databaseStore.getUserRobotIds(userId);
|
||||
}
|
||||
|
||||
// 电话号码校验正则表达式(支持中国大陆手机号和固话)
|
||||
private static final String PHONE_REGEX = "^\\s*" + // 允许开头空白
|
||||
"(?:" +
|
||||
@@ -4537,6 +4609,15 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked(String userId, String clientId) {
|
||||
WFCMessage.UserSettingEntry lockSetting = getUserSetting(userId, UserSettingScopeLockPC, clientId);
|
||||
if(lockSetting != null && "1".equals(lockSetting.getValue())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUserGlobalSilent(String userId) {
|
||||
Boolean slient = userGlobalSlientMap.get(userId);
|
||||
@@ -4873,6 +4954,56 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return getChannelListener(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted) {
|
||||
return databaseStore.getChannelInfoList(count, offset, withDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelTotalCount(boolean withDeleted) {
|
||||
return databaseStore.getChannelTotalCount(withDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode batchListenChannel(String channelId, List<String> userIds, boolean listen) {
|
||||
IMap<String, WFCMessage.ChannelInfo> mIMap = m_Server.getHazelcastInstance().getMap(CHANNELS);
|
||||
WFCMessage.ChannelInfo channelData = mIMap.get(channelId);
|
||||
if(channelData == null || (channelData.getStatus() & Channel_State_Mask_Deleted) > 0) {
|
||||
return ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
}
|
||||
List<String> missedIds = databaseStore.findMissingMids(channelId, userIds, !listen);
|
||||
|
||||
try {
|
||||
databaseStore.batchInsertChannelListener(channelId, missedIds, listen);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
new Thread(() -> {
|
||||
for (String missedId : missedIds) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingListenedChannels).setKey(channelId).setValue(listen? "1" : "0").build();
|
||||
m_Server.onApiMessage(missedId, null, modifyUserSettingReq.toByteArray(), 0, missedId, PutUserSettingTopic, ProtoConstants.RequestSourceType.Request_From_User);
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChannelListenerCount(String channelId) {
|
||||
return databaseStore.getChannelListenerCount(channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getChannelListenerList(String channelId, int count, int offset) {
|
||||
return databaseStore.getChannelListenerList(channelId, count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOnlineUserCount() {
|
||||
return m_Server.getProcessor().getConnectionDescriptors().getActiveConnectionsNo();
|
||||
@@ -5009,6 +5140,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mRobotMentionExternalRobot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRobotGetUserInfoMask() {
|
||||
return mRobotGetUserInfoMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithClientInfo() {
|
||||
return mChannelCallbackWithClientInfo;
|
||||
|
||||
@@ -41,6 +41,8 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
private boolean supportMultiEndpoint = false;
|
||||
private boolean supportMultiPCEndpoint = false;
|
||||
private boolean supportMultiPadEndpoint = false;
|
||||
private boolean supportMultiWearableEndpoint = false;
|
||||
private boolean supportMultiTVEndpoint = false;
|
||||
private boolean clientSupportKickoff = false;
|
||||
|
||||
public static class Session implements Comparable<Session>{
|
||||
@@ -93,6 +95,18 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return unReceivedMsgs;
|
||||
}
|
||||
|
||||
public boolean isPcClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_LINUX;
|
||||
}
|
||||
|
||||
public boolean isPadClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad;
|
||||
}
|
||||
|
||||
public boolean isTVClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_HarmonyTV;
|
||||
}
|
||||
|
||||
public int getPushType() {
|
||||
return pushType;
|
||||
}
|
||||
@@ -303,6 +317,16 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
supportMultiWearableEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_WEARABLE_ENDPOINT, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
supportMultiTVEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_TV_ENDPOINT, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
|
||||
} catch (Exception e) {
|
||||
@@ -410,6 +434,11 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
&& !(platform == ProtoConstants.Platform.Platform_iPad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_APad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyPad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AndroidWearable && supportMultiWearableEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyWearable && supportMultiWearableEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AndroidTV && supportMultiTVEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AppleTV && supportMultiTVEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyTV && supportMultiTVEndpoint)
|
||||
) {
|
||||
databaseStore.clearMultiEndpoint(username, clientID, platform);
|
||||
if (userSessions.get(username) != null) {
|
||||
@@ -436,6 +465,14 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
if (s.getPlatform() == ProtoConstants.Platform.Platform_OSX || s.getPlatform() == ProtoConstants.Platform.Platform_Windows || s.getPlatform() == ProtoConstants.Platform.Platform_LINUX || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPC) {
|
||||
remove = true;
|
||||
}
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
if (s.getPlatform() == ProtoConstants.Platform.Platform_AndroidWearable || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
remove = true;
|
||||
}
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
if (s.getPlatform() == ProtoConstants.Platform.Platform_AndroidTV || s.getPlatform() == ProtoConstants.Platform.Platform_AppleTV || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
remove = true;
|
||||
}
|
||||
} else { //web, microapp
|
||||
if (s.getPlatform() ==platform) {
|
||||
remove = true;
|
||||
|
||||
@@ -331,6 +331,17 @@ public class Server {
|
||||
MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_FAVORITE_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_FAVORITE_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM1_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM1_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM2_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM2_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM3_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM3_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_PAN_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_PAN_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_PAN_DOMAIN);
|
||||
|
||||
MediaServerConfig.SERVER_IP = getServerIp(config);
|
||||
|
||||
|
||||
@@ -23,7 +23,16 @@ public class MediaServerConfig {
|
||||
public static String QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
public static String QINIU_BUCKET_FAVORITE_NAME;
|
||||
public static String QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
|
||||
public static String QINIU_BUCKET_CUSTOM1_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
public static String QINIU_BUCKET_CUSTOM2_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
public static String QINIU_BUCKET_CUSTOM3_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
public static String QINIU_BUCKET_PAN_NAME;
|
||||
public static String QINIU_BUCKET_PAN_DOMAIN;
|
||||
|
||||
|
||||
public static String SERVER_IP = "localhost";
|
||||
public static int HTTP_SERVER_PORT = 8080;
|
||||
public static String FILE_STROAGE_ROOT = "fs";
|
||||
|
||||
@@ -113,6 +113,7 @@ public interface IMessagesStore {
|
||||
ErrorCode modifyGroupMemberAlias(String operator, String groupId, String alias, String memberId, boolean isAdmin);
|
||||
ErrorCode modifyGroupMemberExtra(String operator, String groupId, String extra, String memberId, boolean isAdmin);
|
||||
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests, String fromUser, boolean isAdmin);
|
||||
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests);
|
||||
WFCMessage.GroupInfo getGroupInfo(String groupId);
|
||||
Set<String> getUserGroupIds(String userId);
|
||||
Set<String> getUserGroupIds(String userId, List<Integer> types);
|
||||
@@ -154,9 +155,12 @@ public interface IMessagesStore {
|
||||
WFCMessage.User getUserInfoByName(String name);
|
||||
WFCMessage.User getUserInfoByMobile(String mobile);
|
||||
List<WFCMessage.User> getUserInfosByEmail(String email);
|
||||
List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted);
|
||||
ErrorCode searchUser(String userId, String keyword, int searchType, int userType, int page, List<WFCMessage.User> users);
|
||||
|
||||
List<WFCMessage.User> getUserInfoList(int count, int offset);
|
||||
List<WFCMessage.Robot> getRobotInfoList(int count, int offset);
|
||||
List<String> getUserRobotIds(String userId);
|
||||
|
||||
boolean updateSystemSetting(int id, String value, String desc);
|
||||
SystemSettingPojo getSystemSetting(int id);
|
||||
@@ -167,6 +171,7 @@ public interface IMessagesStore {
|
||||
int getChatroomMemberCount(String chatroomId);
|
||||
Collection<String> getChatroomMemberClient(String userId);
|
||||
boolean checkUserClientInChatroom(String user, String clientId, String chatroomId);
|
||||
ErrorCode setChatroomState(String chatroomId, int status);
|
||||
|
||||
long insertChatroomMessages(String target, int line, long messageId);
|
||||
Collection<UserClientEntry> getChatroomMembers(String chatroomId);
|
||||
@@ -207,6 +212,9 @@ public interface IMessagesStore {
|
||||
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
|
||||
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request, String clientId);
|
||||
void clearUserSettings(String userId);
|
||||
|
||||
boolean isLocked(String userId, String clientId);
|
||||
|
||||
boolean getUserGlobalSilent(String userId);
|
||||
boolean getUserVoipSilent(String userId);
|
||||
|
||||
@@ -226,6 +234,12 @@ public interface IMessagesStore {
|
||||
boolean canSendMessageInChannel(String user, String channelId);
|
||||
boolean checkUserInChannel(String user, String channelId);
|
||||
Collection<String> getChannelSubscriber(String channelId);
|
||||
List<WFCMessage.ChannelInfo> getChannelInfoList(int count, int offset, boolean withDeleted);
|
||||
int getChannelTotalCount(boolean withDeleted);
|
||||
ErrorCode batchListenChannel(String channelId, List<String> userIds, boolean listen);
|
||||
int getChannelListenerCount(String channelId);
|
||||
List<String> getChannelListenerList(String channelId, int count, int offset);
|
||||
|
||||
|
||||
int getOnlineUserCount();
|
||||
GetOnlineUserResult getOnlineUsers(int offset, int count);
|
||||
@@ -255,6 +269,7 @@ public interface IMessagesStore {
|
||||
boolean isRobotCallbackWithSenderInfo();
|
||||
boolean isRobotCallbackWithTargetInfo();
|
||||
boolean isRobotMentionExternalRobot();
|
||||
int getRobotGetUserInfoMask();
|
||||
|
||||
boolean isChannelCallbackWithClientInfo();
|
||||
boolean isChannelCallbackWithSenderInfo();
|
||||
|
||||
@@ -179,6 +179,7 @@ public class MessagesPublisher {
|
||||
message = m_messagesStore.getMessage(messageId);
|
||||
}
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isRobotCallbackWithClientInfo() , m_messagesStore.isRobotCallbackWithSenderInfo(), m_messagesStore.isRobotCallbackWithTargetInfo());
|
||||
outputMessageData.setToRobotId(robot.getUid());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
|
||||
-6
@@ -3,18 +3,12 @@ package io.moquette.spi.impl.security;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
@@ -52,6 +52,7 @@ public interface IMTopic {
|
||||
String FriendRequestPullTopic = "FRP";
|
||||
String NotifyFriendRequestTopic = "FRN";
|
||||
String RriendRequestUnreadSyncTopic = "FRUS";
|
||||
String SetFriendExtraTopic = "FES";
|
||||
|
||||
String DeleteFriendTopic = "FDL";
|
||||
String FriendPullTopic = "FP";
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package win.liyufan.im;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SensitiveFilter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SensitiveFilter.class);
|
||||
public enum MatchType {
|
||||
MIN_MATCH("最小匹配规则"),MAX_MATCH("最大匹配规则");
|
||||
|
||||
@@ -71,6 +75,9 @@ public class SensitiveFilter {
|
||||
i=i+sensitiveWordLength-1;
|
||||
}
|
||||
}
|
||||
if(!sensitiveWords.isEmpty()) {
|
||||
LOG.info("Text {} matched sensitive word {}", originalText, sensitiveWords);
|
||||
}
|
||||
return sensitiveWords;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,4 +22,5 @@ public interface UserSettingScope {
|
||||
int kUserSettingPrivacySearchable = 27;
|
||||
int kUserSettingAddFriendStrategy = 28;
|
||||
int kUserSettingScopeSyncBadge = 29;
|
||||
int UserSettingScopeLockPC = 30;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* API路径接口
|
||||
* <p>
|
||||
* 定义了野火IM服务器所有管理接口的API路径。
|
||||
* 包括聊天室、敏感词、域、用户、好友、黑名单、消息、群组、会议、频道等模块的接口路径。
|
||||
* </p>
|
||||
*/
|
||||
public interface APIPath {
|
||||
String Create_Chatroom = "/admin/chatroom/create";
|
||||
String Chatroom_Destroy = "/admin/chatroom/del";
|
||||
@@ -36,8 +43,11 @@ public interface APIPath {
|
||||
String User_Get_Info = "/admin/user/get_info";
|
||||
String User_Batch_Get_Infos = "/admin/user/batch_get_infos";
|
||||
String User_Get_Email_Info = "/admin/user/get_info_by_email";
|
||||
String User_Get_By_Mobile = "/admin/user/get_info_by_mobile";
|
||||
String User_Get_All = "/admin/user/all";
|
||||
String User_Get_Robot_Info = "/admin/user/get_robot_info";
|
||||
String User_Get_All_Robots = "/admin/user/get_all_robots";
|
||||
String User_Get_User_Robots = "/admin/user/get_user_robots";
|
||||
String User_Get_Blocked_List = "/admin/user/get_blocked_list";
|
||||
String User_Check_Block_Status = "/admin/user/check_block_status";
|
||||
String User_Get_Online_Status = "/admin/user/onlinestatus";
|
||||
@@ -80,6 +90,7 @@ public interface APIPath {
|
||||
String Msg_Delivery = "/admin/message/delivery";
|
||||
String Conversation_Delete = "/admin/conversation/delete";
|
||||
String Msg_Clear_By_User = "/admin/message/clear_by_user";
|
||||
String Msg_Import = "/admin/message/import";
|
||||
|
||||
String Create_Group = "/admin/group/create";
|
||||
String Group_Dismiss = "/admin/group/del";
|
||||
@@ -95,6 +106,7 @@ public interface APIPath {
|
||||
String Group_Set_Manager = "/admin/group/manager/set";
|
||||
String Group_Mute_Member = "/admin/group/manager/mute";
|
||||
String Group_Allow_Member = "/admin/group/manager/allow";
|
||||
String Group_Join_Request_Add = "/admin/group/join_request/add";
|
||||
String Get_User_Groups = "/admin/group/of_user";
|
||||
String Get_User_Groups_By_Type = "/admin/group/of_user_by_type";
|
||||
String Group_Set_Member_Alias = "/admin/group/member/set_alias";
|
||||
@@ -108,12 +120,20 @@ public interface APIPath {
|
||||
String Create_Channel = "/admin/channel/create";
|
||||
String Destroy_Channel = "/admin/channel/destroy";
|
||||
String Get_Channel_Info = "/admin/channel/get";
|
||||
String List_Channel_Info = "/admin/channel/list";
|
||||
String Subscribe_Channel = "/admin/channel/subscribe";
|
||||
String Batch_Subscribe_Channel = "/admin/channel/batch_subscribe";
|
||||
String Check_User_Subscribe_Channel = "/admin/channel/is_subscribed";
|
||||
String List_Channel_Subscriber = "/admin/channel/list_subscriber";
|
||||
String Get_System_Setting = "/admin/system/get_setting";
|
||||
String Put_System_Setting = "/admin/system/put_setting";
|
||||
String GET_CUSTOMER = "/admin/customer";
|
||||
String Health = "/admin/health";
|
||||
String Get_Conversation_Files = "/admin/file/conversation_files";
|
||||
String Get_User_Files = "/admin/file/user_files";
|
||||
String Get_Message_File = "/admin/file/message_file";
|
||||
|
||||
String Get_Presigned_Upload_Url = "/admin/oss/get_upload_url";
|
||||
|
||||
String Conference_List = "/admin/conference/list";
|
||||
String Conference_Exist = "/admin/conference/exist";
|
||||
@@ -137,6 +157,8 @@ public interface APIPath {
|
||||
String Channel_Application_Get_UserInfo = "/channel/application/get_user_info";
|
||||
|
||||
String Robot_User_Info = "/robot/user_info";
|
||||
String Robot_User_Get_Email_Info = "/robot/user/get_info_by_email";
|
||||
String Robot_User_Batch_Get_Infos = "/robot/user/batch_get_infos";
|
||||
String Robot_Get_Profile = "/robot/profile";
|
||||
String Robot_Message_Send = "/robot/message/send";
|
||||
String Robot_Message_Reply = "/robot/message/reply";
|
||||
@@ -176,4 +198,6 @@ public interface APIPath {
|
||||
String Robot_Moments_Update_Profiles_Value = "/robot/moments/profiles/value/push";
|
||||
|
||||
String Robot_Conference_Request = "/robot/conference/request";
|
||||
|
||||
String Robot_Get_Presigned_Upload_Url = "/robot/oss/get_upload_url";
|
||||
}
|
||||
|
||||
@@ -8,6 +8,25 @@
|
||||
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* 错误码枚举
|
||||
* <p>
|
||||
* 定义了野火IM系统中所有可能的错误码,包括:
|
||||
* <ul>
|
||||
* <li>通用错误(0-5)</li>
|
||||
* <li>认证错误(6-8)</li>
|
||||
* <li>消息错误(9-10)</li>
|
||||
* <li>群组错误(11-12)</li>
|
||||
* <li>用户错误(16-19)</li>
|
||||
* <li>聊天室错误(20)</li>
|
||||
* <li>频道错误(21-25)</li>
|
||||
* <li>会议错误(60-61)</li>
|
||||
* <li>应用错误(70)</li>
|
||||
* <li>密聊错误(81-87)</li>
|
||||
* <li>其他错误(90-255)</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public enum ErrorCode {
|
||||
//General error
|
||||
ERROR_CODE_SUCCESS(0, "success"),
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* IM异常事件类
|
||||
* <p>
|
||||
* 用于记录和传递IM系统中的异常事件信息。
|
||||
* </p>
|
||||
*/
|
||||
public class IMExceptionEvent {
|
||||
/**
|
||||
* 事件类型接口
|
||||
* <p>
|
||||
* 定义了各种异常事件的类型常量。
|
||||
* </p>
|
||||
*/
|
||||
public interface EventType {
|
||||
int RDBS_Exception = 1;
|
||||
int MONGO_Exception = 2;
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
/**
|
||||
* 会话类
|
||||
* <p>
|
||||
* 表示一个会话对象,包含会话类型、目标ID和线路信息。
|
||||
* 用于标识消息发送或接收的目标会话。
|
||||
* </p>
|
||||
*/
|
||||
public class Conversation {
|
||||
private int type;
|
||||
private String target;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FilesPojo {
|
||||
public int total;
|
||||
public List<FilePojo> files;
|
||||
public static class FilePojo {
|
||||
public long messageId;
|
||||
public String sender;
|
||||
public int conversationType;
|
||||
public String target;
|
||||
public int line;
|
||||
public String name;
|
||||
public String url;
|
||||
public int size;
|
||||
public int downloadCount;
|
||||
public long timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class GetConversationFilesPojo {
|
||||
public int conversationType;
|
||||
public String target;
|
||||
public int line;
|
||||
public String userId;
|
||||
public int offset;
|
||||
public boolean desc;
|
||||
public int count;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ public class GetOnlineUserResult {
|
||||
public String userId;
|
||||
public String clientId;
|
||||
public int platform;
|
||||
public String ip;
|
||||
}
|
||||
|
||||
public ArrayList<GetOnlineUserResult.UserClient> userClients;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class GetUserFilesPojo {
|
||||
public String userId;
|
||||
public int offset;
|
||||
public boolean desc;
|
||||
public int count;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ImportMessagesData {
|
||||
public static class ImportMessage {
|
||||
public String sender;
|
||||
public Conversation conversation;
|
||||
public MessagePayload payload;
|
||||
public List<String> receivers;
|
||||
public long timestamp;
|
||||
}
|
||||
public List<ImportMessage> messages;
|
||||
}
|
||||
@@ -14,6 +14,12 @@ import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 添加群组成员输入参数类
|
||||
* <p>
|
||||
* 封装添加群组成员的输入参数,包括群组ID、成员列表、成员额外信息等。
|
||||
* </p>
|
||||
*/
|
||||
public class InputAddGroupMember extends InputGroupBase {
|
||||
private String group_id;
|
||||
private List<PojoGroupMember> members;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputCountOffset {
|
||||
public int count;
|
||||
public int offset;
|
||||
}
|
||||
@@ -14,6 +14,12 @@ import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建群组输入参数类
|
||||
* <p>
|
||||
* 封装创建群组的输入参数,包括群组信息、成员列表、成员额外信息等。
|
||||
* </p>
|
||||
*/
|
||||
public class InputCreateGroup extends InputGroupBase {
|
||||
private PojoGroup group;
|
||||
private String member_extra;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
|
||||
/**
|
||||
* 请求预签名上传地址
|
||||
* <p>
|
||||
* 请求封装预签名上传地址,包括:
|
||||
* <ul>
|
||||
* <li>文件名</li>
|
||||
* <li>文件类型</li>
|
||||
* <li>媒体类型</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class InputGetPresignedUploadUrl {
|
||||
public String fileName;
|
||||
public String contentType;
|
||||
public int mediaType;
|
||||
}
|
||||
@@ -12,6 +12,7 @@ public class InputGetUserInfo {
|
||||
private String userId;
|
||||
private String name;
|
||||
private String mobile;
|
||||
private boolean includeDeleted;
|
||||
|
||||
public InputGetUserInfo() {
|
||||
}
|
||||
@@ -22,6 +23,13 @@ public class InputGetUserInfo {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public InputGetUserInfo(String userId, String name, String mobile, boolean includeDeleted) {
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
this.mobile = mobile;
|
||||
this.includeDeleted = includeDeleted;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
@@ -45,4 +53,12 @@ public class InputGetUserInfo {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isIncludeDeleted() {
|
||||
return includeDeleted;
|
||||
}
|
||||
|
||||
public void setIncludeDeleted(boolean includeDeleted) {
|
||||
this.includeDeleted = includeDeleted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,21 @@ package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
/**
|
||||
* 用户信息类
|
||||
* <p>
|
||||
* 封装用户的所有信息,包括:
|
||||
* <ul>
|
||||
* <li>用户ID、用户名、显示名称</li>
|
||||
* <li>头像、性别</li>
|
||||
* <li>手机号、邮箱、地址</li>
|
||||
* <li>公司、社交信息</li>
|
||||
* <li>用户类型、删除状态</li>
|
||||
* <li>更新时间</li>
|
||||
* <li>额外扩展信息</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class InputOutputUserInfo {
|
||||
private String userId;
|
||||
private String name;
|
||||
@@ -196,4 +211,16 @@ public class InputOutputUserInfo {
|
||||
public void setDeleted(int deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"userId='" + userId + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", displayName='" + displayName + '\'' +
|
||||
", portrait='" + portrait + '\'' +
|
||||
", mobile='" + mobile + '\'' +
|
||||
", updateDt=" + updateDt +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputStringCountOffset {
|
||||
public String target;
|
||||
public int count;
|
||||
public int offset;
|
||||
|
||||
public InputStringCountOffset() {
|
||||
}
|
||||
|
||||
public InputStringCountOffset(String target, int count, int offset) {
|
||||
this.target = target;
|
||||
this.count = count;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InputSubscribeChannelBatch {
|
||||
private String channelId;
|
||||
private List<String> userIds;
|
||||
private int subscribe; //1,订阅;0,取消订阅
|
||||
|
||||
public InputSubscribeChannelBatch() {
|
||||
}
|
||||
|
||||
public InputSubscribeChannelBatch(String channelId, List<String> userIds, int subscribe) {
|
||||
this.channelId = channelId;
|
||||
this.userIds = userIds;
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(String channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public List<String> getUserIds() {
|
||||
return userIds;
|
||||
}
|
||||
|
||||
public void setUserIds(List<String> userIds) {
|
||||
this.userIds = userIds;
|
||||
}
|
||||
|
||||
public int getSubscribe() {
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
public void setSubscribe(int subscribe) {
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class LongPojo {
|
||||
public long value;
|
||||
}
|
||||
@@ -16,6 +16,22 @@ import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息内容负载类
|
||||
* <p>
|
||||
* 封装消息的所有内容信息,包括:
|
||||
* <ul>
|
||||
* <li>消息类型</li>
|
||||
* <li>可搜索内容(文本消息的文本)</li>
|
||||
* <li>推送内容和推送数据</li>
|
||||
* <li>消息内容(二进制数据)</li>
|
||||
* <li>媒体类型和远程URL</li>
|
||||
* <li>持久化标志和过期时间</li>
|
||||
* <li>@提及信息</li>
|
||||
* <li>额外数据</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class MessagePayload {
|
||||
private int type;
|
||||
private String searchableContent;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OutputChannelInfoList {
|
||||
public List<OutputGetChannelInfo> list;
|
||||
public int total;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OutputGetRobotList {
|
||||
public List<OutputRobot> robotInfoList;
|
||||
}
|
||||
@@ -27,6 +27,8 @@ public class OutputMessageData {
|
||||
private PojoGroupInfo targetGroupInfo;
|
||||
private OutputGetChannelInfo targetChannelInfo;
|
||||
|
||||
private String toRobotId;
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
@@ -119,6 +121,14 @@ public class OutputMessageData {
|
||||
return fromProtoMessage(protoMessage, null);
|
||||
}
|
||||
|
||||
public String getToRobotId() {
|
||||
return toRobotId;
|
||||
}
|
||||
|
||||
public void setToRobotId(String toRobotId) {
|
||||
this.toRobotId = toRobotId;
|
||||
}
|
||||
|
||||
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage, OutputClient fromClient) {
|
||||
OutputMessageData data = new OutputMessageData();
|
||||
data.messageId = protoMessage.getMessageId();
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
|
||||
/**
|
||||
* 预签名上传地址
|
||||
* <p>
|
||||
* 封装预签名上传地址,包括:
|
||||
* <ul>
|
||||
* <li>上传地址</li>
|
||||
* <li>备选上传地址</li>
|
||||
* <li>下载地址</li>
|
||||
* <li>类型</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class OutputPresignedUploadUrl {
|
||||
public String uploadUrl;
|
||||
public String backupUploadUrl;
|
||||
public String downloadUrl;
|
||||
public int type;
|
||||
}
|
||||
@@ -2,11 +2,8 @@ package cn.wildfirechat.pojos;
|
||||
|
||||
public class PojoConferenceInfo {
|
||||
public String roomId;
|
||||
public String serverId;
|
||||
public String description;
|
||||
public int max_publishers;
|
||||
public int num_publishers;
|
||||
public int bitrate;
|
||||
public boolean advance;
|
||||
public boolean recording;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@ package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 群组对象类
|
||||
* <p>
|
||||
* 封装创建群组时使用的参数,包含群组信息和成员列表。
|
||||
* </p>
|
||||
*/
|
||||
public class PojoGroup {
|
||||
private PojoGroupInfo group_info;
|
||||
private List<PojoGroupMember> members;
|
||||
|
||||
@@ -8,6 +8,21 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
/**
|
||||
* 群组信息类
|
||||
* <p>
|
||||
* 封装群组的信息,包括:
|
||||
* <ul>
|
||||
* <li>群组ID、名称、头像、所有者</li>
|
||||
* <li>群组类型、成员数量、最大成员数</li>
|
||||
* <li>群组设置(禁言、加群方式、私聊、可搜索、历史消息)</li>
|
||||
* <li>是否超级群、是否已删除</li>
|
||||
* <li>更新时间</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class PojoGroupInfo {
|
||||
String target_id;
|
||||
String name;
|
||||
@@ -162,4 +177,26 @@ public class PojoGroupInfo {
|
||||
public void setMember_update_dt(long member_update_dt) {
|
||||
this.member_update_dt = member_update_dt;
|
||||
}
|
||||
|
||||
static public PojoGroupInfo fromProto(WFCMessage.GroupInfo groupInfo) {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
pojoGroupInfo.setExtra(groupInfo.getExtra());
|
||||
pojoGroupInfo.setName(groupInfo.getName());
|
||||
pojoGroupInfo.setOwner(groupInfo.getOwner());
|
||||
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
|
||||
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
|
||||
pojoGroupInfo.setType(groupInfo.getType());
|
||||
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setMute(groupInfo.getMute());
|
||||
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
|
||||
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
|
||||
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
|
||||
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
|
||||
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
|
||||
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
return pojoGroupInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,19 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
/**
|
||||
* 群组成员类
|
||||
* <p>
|
||||
* 封装群组成员的信息,包括:
|
||||
* <ul>
|
||||
* <li>成员ID</li>
|
||||
* <li>群组内别名</li>
|
||||
* <li>成员类型</li>
|
||||
* <li>扩展信息</li>
|
||||
* <li>更新时间和创建时间</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class PojoGroupMember {
|
||||
String member_id;
|
||||
String alias;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PojoTotalList {
|
||||
public int total;
|
||||
public List<String> list;
|
||||
|
||||
public PojoTotalList() {
|
||||
}
|
||||
|
||||
public PojoTotalList(int total, List<String> list) {
|
||||
this.total = total;
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,12 @@ package cn.wildfirechat.pojos;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
/**
|
||||
* 发送消息结果类
|
||||
* <p>
|
||||
* 封装发送消息后的返回结果,包含消息UID和时间戳。
|
||||
* </p>
|
||||
*/
|
||||
public class SendMessageResult {
|
||||
private long messageUid;
|
||||
private long timestamp;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.wildfirechat.pojos.mesh;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PojoAddJoinGroupRequest {
|
||||
public String domainId;
|
||||
public String operator;
|
||||
public String group_id;
|
||||
public List<String> userIds;
|
||||
public String reason;
|
||||
public String extra;
|
||||
}
|
||||
@@ -56,7 +56,14 @@ public class ProtoConstants {
|
||||
int Platform_Harmony = 10;
|
||||
int Platform_HarmonyPad = 11;
|
||||
int Platform_HarmonyPC = 12;
|
||||
int Platform_MAX = Platform_HarmonyPC;
|
||||
// 穿戴端 (Wearable)
|
||||
int Platform_AndroidWearable = 13;
|
||||
int Platform_HarmonyWearable = 14;
|
||||
// TV端
|
||||
int Platform_AndroidTV = 15;
|
||||
int Platform_AppleTV = 16;
|
||||
int Platform_HarmonyTV = 17;
|
||||
int Platform_MAX = Platform_HarmonyTV;
|
||||
}
|
||||
|
||||
//message NotifyMessage & PullMessageRequest -> type
|
||||
|
||||
@@ -67311,6 +67311,641 @@ public final class WFCMessage {
|
||||
// @@protoc_insertion_point(class_scope:ApplicationConfigRequest)
|
||||
}
|
||||
|
||||
public interface StringPairOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// required string key = 1;
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
boolean hasKey();
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
java.lang.String getKey();
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getKeyBytes();
|
||||
|
||||
// optional string value = 2;
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
boolean hasValue();
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
java.lang.String getValue();
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getValueBytes();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code StringPair}
|
||||
*/
|
||||
public static final class StringPair extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
implements StringPairOrBuilder {
|
||||
// Use StringPair.newBuilder() to construct.
|
||||
private StringPair(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
private StringPair(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
|
||||
private static final StringPair defaultInstance;
|
||||
public static StringPair getDefaultInstance() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public StringPair getDefaultInstanceForType() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||
@java.lang.Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private StringPair(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
initFields();
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
default: {
|
||||
if (!parseUnknownField(input, unknownFields,
|
||||
extensionRegistry, tag)) {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10: {
|
||||
bitField0_ |= 0x00000001;
|
||||
key_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
bitField0_ |= 0x00000002;
|
||||
value_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
e.getMessage()).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
this.unknownFields = unknownFields.build();
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return cn.wildfirechat.proto.WFCMessage.internal_static_StringPair_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return cn.wildfirechat.proto.WFCMessage.internal_static_StringPair_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
cn.wildfirechat.proto.WFCMessage.StringPair.class, cn.wildfirechat.proto.WFCMessage.StringPair.Builder.class);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Parser<StringPair> PARSER =
|
||||
new com.google.protobuf.AbstractParser<StringPair>() {
|
||||
public StringPair parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return new StringPair(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
@java.lang.Override
|
||||
public com.google.protobuf.Parser<StringPair> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
private int bitField0_;
|
||||
// required string key = 1;
|
||||
public static final int KEY_FIELD_NUMBER = 1;
|
||||
private java.lang.Object key_;
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public boolean hasKey() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public java.lang.String getKey() {
|
||||
java.lang.Object ref = key_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
return (java.lang.String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
java.lang.String s = bs.toStringUtf8();
|
||||
if (bs.isValidUtf8()) {
|
||||
key_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getKeyBytes() {
|
||||
java.lang.Object ref = key_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
key_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// optional string value = 2;
|
||||
public static final int VALUE_FIELD_NUMBER = 2;
|
||||
private java.lang.Object value_;
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public boolean hasValue() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public java.lang.String getValue() {
|
||||
java.lang.Object ref = value_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
return (java.lang.String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
java.lang.String s = bs.toStringUtf8();
|
||||
if (bs.isValidUtf8()) {
|
||||
value_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getValueBytes() {
|
||||
java.lang.Object ref = value_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
value_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
key_ = "";
|
||||
value_ = "";
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized != -1) return isInitialized == 1;
|
||||
|
||||
if (!hasKey()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
output.writeBytes(1, getKeyBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeBytes(2, getValueBytes());
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
private int memoizedSerializedSize = -1;
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSerializedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, getKeyBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(2, getValueBytes());
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
@java.lang.Override
|
||||
protected java.lang.Object writeReplace()
|
||||
throws java.io.ObjectStreamException {
|
||||
return super.writeReplace();
|
||||
}
|
||||
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static cn.wildfirechat.proto.WFCMessage.StringPair parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
|
||||
public static Builder newBuilder() { return Builder.create(); }
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder(cn.wildfirechat.proto.WFCMessage.StringPair prototype) {
|
||||
return newBuilder().mergeFrom(prototype);
|
||||
}
|
||||
public Builder toBuilder() { return newBuilder(this); }
|
||||
|
||||
@java.lang.Override
|
||||
protected Builder newBuilderForType(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code StringPair}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements cn.wildfirechat.proto.WFCMessage.StringPairOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return cn.wildfirechat.proto.WFCMessage.internal_static_StringPair_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return cn.wildfirechat.proto.WFCMessage.internal_static_StringPair_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
cn.wildfirechat.proto.WFCMessage.StringPair.class, cn.wildfirechat.proto.WFCMessage.StringPair.Builder.class);
|
||||
}
|
||||
|
||||
// Construct using cn.wildfirechat.proto.WFCMessage.StringPair.newBuilder()
|
||||
private Builder() {
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
|
||||
private Builder(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
}
|
||||
}
|
||||
private static Builder create() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
key_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
value_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder clone() {
|
||||
return create().mergeFrom(buildPartial());
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return cn.wildfirechat.proto.WFCMessage.internal_static_StringPair_descriptor;
|
||||
}
|
||||
|
||||
public cn.wildfirechat.proto.WFCMessage.StringPair getDefaultInstanceForType() {
|
||||
return cn.wildfirechat.proto.WFCMessage.StringPair.getDefaultInstance();
|
||||
}
|
||||
|
||||
public cn.wildfirechat.proto.WFCMessage.StringPair build() {
|
||||
cn.wildfirechat.proto.WFCMessage.StringPair result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public cn.wildfirechat.proto.WFCMessage.StringPair buildPartial() {
|
||||
cn.wildfirechat.proto.WFCMessage.StringPair result = new cn.wildfirechat.proto.WFCMessage.StringPair(this);
|
||||
int from_bitField0_ = bitField0_;
|
||||
int to_bitField0_ = 0;
|
||||
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
to_bitField0_ |= 0x00000001;
|
||||
}
|
||||
result.key_ = key_;
|
||||
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.value_ = value_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof cn.wildfirechat.proto.WFCMessage.StringPair) {
|
||||
return mergeFrom((cn.wildfirechat.proto.WFCMessage.StringPair)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(cn.wildfirechat.proto.WFCMessage.StringPair other) {
|
||||
if (other == cn.wildfirechat.proto.WFCMessage.StringPair.getDefaultInstance()) return this;
|
||||
if (other.hasKey()) {
|
||||
bitField0_ |= 0x00000001;
|
||||
key_ = other.key_;
|
||||
onChanged();
|
||||
}
|
||||
if (other.hasValue()) {
|
||||
bitField0_ |= 0x00000002;
|
||||
value_ = other.value_;
|
||||
onChanged();
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isInitialized() {
|
||||
if (!hasKey()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
cn.wildfirechat.proto.WFCMessage.StringPair parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (cn.wildfirechat.proto.WFCMessage.StringPair) e.getUnfinishedMessage();
|
||||
throw e;
|
||||
} finally {
|
||||
if (parsedMessage != null) {
|
||||
mergeFrom(parsedMessage);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
private int bitField0_;
|
||||
|
||||
// required string key = 1;
|
||||
private java.lang.Object key_ = "";
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public boolean hasKey() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public java.lang.String getKey() {
|
||||
java.lang.Object ref = key_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
key_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (java.lang.String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getKeyBytes() {
|
||||
java.lang.Object ref = key_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
key_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public Builder setKey(
|
||||
java.lang.String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
key_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public Builder clearKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
key_ = getDefaultInstance().getKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>required string key = 1;</code>
|
||||
*/
|
||||
public Builder setKeyBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
key_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional string value = 2;
|
||||
private java.lang.Object value_ = "";
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public boolean hasValue() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public java.lang.String getValue() {
|
||||
java.lang.Object ref = value_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
value_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (java.lang.String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getValueBytes() {
|
||||
java.lang.Object ref = value_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
value_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public Builder setValue(
|
||||
java.lang.String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
value_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public Builder clearValue() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
value_ = getDefaultInstance().getValue();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string value = 2;</code>
|
||||
*/
|
||||
public Builder setValueBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
value_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:StringPair)
|
||||
}
|
||||
|
||||
static {
|
||||
defaultInstance = new StringPair(true);
|
||||
defaultInstance.initFields();
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:StringPair)
|
||||
}
|
||||
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_AddFriendRequest_descriptor;
|
||||
private static
|
||||
@@ -67691,6 +68326,11 @@ public final class WFCMessage {
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_ApplicationConfigRequest_fieldAccessorTable;
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_StringPair_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_StringPair_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
@@ -67877,9 +68517,10 @@ public final class WFCMessage {
|
||||
"rget_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022\014\n\004host\030\003 \002(" +
|
||||
"\t\"o\n\030ApplicationConfigRequest\022\r\n\005appId\030\001" +
|
||||
" \002(\t\022\017\n\007appType\030\002 \002(\005\022\021\n\ttimestamp\030\003 \002(\003" +
|
||||
"\022\r\n\005nonce\030\004 \002(\t\022\021\n\tsignature\030\005 \002(\tB/\n\025cn" +
|
||||
".wildfirechat.protoB\nWFCMessageZ\n./go;pr" +
|
||||
"oto"
|
||||
"\022\r\n\005nonce\030\004 \002(\t\022\021\n\tsignature\030\005 \002(\t\"(\n\nSt" +
|
||||
"ringPair\022\013\n\003key\030\001 \002(\t\022\r\n\005value\030\002 \001(\tB/\n\025" +
|
||||
"cn.wildfirechat.protoB\nWFCMessageZ\n./go;",
|
||||
"proto"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@@ -68342,6 +68983,12 @@ public final class WFCMessage {
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_ApplicationConfigRequest_descriptor,
|
||||
new java.lang.String[] { "AppId", "AppType", "Timestamp", "Nonce", "Signature", });
|
||||
internal_static_StringPair_descriptor =
|
||||
getDescriptor().getMessageTypes().get(76);
|
||||
internal_static_StringPair_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_StringPair_descriptor,
|
||||
new java.lang.String[] { "Key", "Value", });
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.xiaoleilu.loServer.pojos;
|
||||
|
||||
|
||||
public class InputRoute {
|
||||
private String userId;
|
||||
private String token;
|
||||
private String clientId;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
|
||||
@@ -171,6 +171,12 @@ robot.callback_with_target_info false
|
||||
## 如果为false,不能@不在会话中的机器人。机器人不在会话中时,也不能回复消息。
|
||||
robot.mention_external_robot true
|
||||
|
||||
## 机器人获取信息允许的字段,可以获取userId/displayName/portrait,其他需要这里配置允许。
|
||||
## 第一位(1)是name, 第二位(2)是mobile,第三(4)位是email,第四位(8)是address,第五位(16)是company,第六位(32)是extra,
|
||||
## 第七位(64)是updateDt,第八位(128)是gender,第九位(256)是social,第十位(512)是type。
|
||||
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
||||
#robot.get_user_info_mask 1023
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
@@ -334,6 +340,16 @@ qiniu.bucket_portrait_name storage
|
||||
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
|
||||
qiniu.bucket_favorite_name storage
|
||||
qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
|
||||
## custom的桶是给客户预留的,客户可以上传自己的文件到这3个桶中,野火不会用到这几个桶。如果不需要,可以忽略这几个配置
|
||||
qiniu.bucket_custom1_name temp1
|
||||
qiniu.bucket_custom1_domain http://temp1.wildfirechat.cn
|
||||
qiniu.bucket_custom2_name temp2
|
||||
qiniu.bucket_custom2_domain http://temp2.wildfirechat.cn
|
||||
qiniu.bucket_custom3_name temp3
|
||||
qiniu.bucket_custom3_domain http://temp3.wildfirechat.cn
|
||||
## 如果配置网盘服务,需要配置这个
|
||||
qiniu.bucket_pan_name pan
|
||||
qiniu.bucket_pan_domain http://pan.wildfirechat.cn
|
||||
|
||||
##媒体类型分类
|
||||
#Media_Type_GENERAL = 0,
|
||||
@@ -366,6 +382,12 @@ server.multi_pc_endpoint false
|
||||
## 是否支持PAD多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PAD端多端登录。
|
||||
server.multi_pad_endpoint false
|
||||
|
||||
## 是否支持可穿戴设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开可穿戴设备多端登录。
|
||||
server.multi_wearable_endpoint false
|
||||
|
||||
## 是否支持TV设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开TV多端登录。
|
||||
server.multi_tv_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或pad或web端登录的通知。
|
||||
server.multi_platform_notification true
|
||||
|
||||
|
||||
@@ -97,4 +97,4 @@ echo ""
|
||||
#JAVA_OPTS="$JAVA_OPTS -Xms2G"
|
||||
|
||||
|
||||
$JAVA -server $JAVA_OPTS $JAVA_OPTS_SCRIPT -Dlog4j.configurationFile="file:$LOG_FILE" -Dlog4j2.formatMsgNoLookups=true -Dcom.mchange.v2.c3p0.cfg.xml="$C3P0_CONF_FILE" -Dhazelcast.configuration=$HZ_CONF_FILE -Dwildfirechat.path="$WILDFIRECHAT_CONFIG_PATH" -cp "$WILDFIRECHAT_HOME/lib/*" cn.wildfirechat.server.Server
|
||||
$JAVA -server $JAVA_OPTS $JAVA_OPTS_SCRIPT -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Dlog4j.configurationFile="file:$LOG_FILE" -Dlog4j2.formatMsgNoLookups=true -Dcom.mchange.v2.c3p0.cfg.xml="$C3P0_CONF_FILE" -Dhazelcast.configuration=$HZ_CONF_FILE -Dwildfirechat.path="$WILDFIRECHAT_CONFIG_PATH" -cp "$WILDFIRECHAT_HOME/lib/*" cn.wildfirechat.server.Server
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
@@ -12,6 +12,46 @@
|
||||
11. *** 1.3.8版本添加了server api发送消息的限制,限制消息体最大内容不能超过64KB,如果升级请注意业务系统发送消息大小。***
|
||||
|
||||
# 更新记录
|
||||
--------------
|
||||
Release note 1.4.7:
|
||||
1. 添加获取所有机器人的Server API接口。
|
||||
2. 添加获取某个电话号码的用户列表的Server API接口。
|
||||
3. 机器人发送消息distribute为false时不重新分发。
|
||||
4. 解决机器人和频道API请求错误时result不为空的问题。
|
||||
5. 机器人添加根据邮箱获取用户信息和批量获取用户信息的接口。
|
||||
6. 添加批量订阅/取消订阅的频道接口,添加批量获取订阅用户的接口。
|
||||
|
||||
--------------
|
||||
Release note 1.4.6:
|
||||
1. 添加网盘存储类型。
|
||||
2. 添加可穿戴设备和TV设备类型。
|
||||
3. Server SDK添加上传接口。
|
||||
4. 解决转移群主给现有群主错误问题。
|
||||
|
||||
--------------
|
||||
Release note 1.4.5:
|
||||
1. 解决删除用户时保留信息错误问题。
|
||||
2. Server API获取用户信息时,可以指定是否获取已删除用户。
|
||||
3. 好友关系表添加一个索引。
|
||||
4. 支持PC端锁定功能。
|
||||
|
||||
--------------
|
||||
Release note 1.4.4:
|
||||
1. Server SDK添加mesh相关修改
|
||||
2. 添加设置好友Extra的接口。
|
||||
3. 解决创建账户时,没有传昵称使用了账户的问题。
|
||||
4. 添加获取用户机器人列表的Server API。
|
||||
5. 机器人回调消息中加上目标机器人ID。
|
||||
6. 机器人获取用户信息添加配置确定能获取哪些字段。
|
||||
|
||||
--------------
|
||||
Release note 1.4.3:
|
||||
1. 添加内置存储上传文件文件名有效性检查。
|
||||
2. 接受好友请求通知的发送者改成接受者发送。
|
||||
3. 对象存储添加预留类型供扩展使用。
|
||||
4. 同步专业版数据库表格式。
|
||||
5. 解决server sdk有轻微内存泄漏的问题。
|
||||
|
||||
--------------
|
||||
Release note 1.4.2:
|
||||
1. 解决部分情况下Server SDK没有解析出文本消息的问题。
|
||||
|
||||
+359
@@ -0,0 +1,359 @@
|
||||
# 野火IM Server Java SDK
|
||||
|
||||
野火IM Server Java SDK 是野火IM服务器的官方 Java 语言 SDK,提供了完整的 Admin API、Robot API 和 Channel API 接口封装。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **用户管理**:创建用户、获取用户信息、更新用户信息、封禁/解封用户等
|
||||
- **群组管理**:创建群组、添加/移除成员、转让群主、设置管理员等
|
||||
- **消息管理**:发送消息、广播消息、撤回消息、删除消息等
|
||||
- **好友关系**:添加好友、删除好友、获取好友列表、设置黑名单等
|
||||
- **聊天室管理**:创建聊天室、获取聊天室信息、销毁聊天室等
|
||||
- **频道管理**:创建频道、订阅/取消订阅、发送频道消息等
|
||||
- **机器人服务**:机器人消息收发、用户信息查询、群组管理等
|
||||
- **会议管理**:创建会议、查询会议信息、管理参会者等(高级音视频功能)
|
||||
- **朋友圈功能**:发布动态、评论、点赞等(需启用朋友圈功能)
|
||||
- **敏感词管理**:添加/删除敏感词、检查敏感词等
|
||||
|
||||
## 安装
|
||||
|
||||
### Maven 依赖
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<!-- 必需依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>2.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SDK JAR (本地路径根据实际情况修改) -->
|
||||
<dependency>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<artifactId>sdk</artifactId>
|
||||
<version>1.2.2</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/lib/sdk.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>1.2.2</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/lib/common.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- Spring Boot 项目需要添加 includeSystemScope -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
### SDK 获取
|
||||
|
||||
1. 从源码编译:本项目位于 `server/sdk` 目录
|
||||
2. 从发布包获取:在 release 包的 `server_sdk` 目录中
|
||||
|
||||
## 快速开始
|
||||
|
||||
### Admin 管理 API
|
||||
|
||||
```java
|
||||
import cn.wildfirechat.sdk.AdminConfig;
|
||||
import cn.wildfirechat.sdk.UserAdmin;
|
||||
import cn.wildfirechat.sdk.MessageAdmin;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.Conversation;
|
||||
import cn.wildfirechat.sdk.messagecontent.TextMessageContent;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
|
||||
public class QuickStart {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 初始化配置
|
||||
AdminConfig.initAdmin("http://localhost:18080", "123456");
|
||||
|
||||
// 创建用户
|
||||
InputOutputUserInfo user = new InputOutputUserInfo();
|
||||
user.setUserId("user1");
|
||||
user.setName("user1");
|
||||
user.setDisplayName("Test User");
|
||||
user.setMobile("13900000000");
|
||||
|
||||
IMResult<OutputCreateUser> result = UserAdmin.createUser(user);
|
||||
if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("创建用户成功: " + result.getResult().getUserId());
|
||||
}
|
||||
|
||||
// 获取用户 Token
|
||||
IMResult<OutputGetIMTokenData> tokenResult = UserAdmin.getUserToken(
|
||||
"user1",
|
||||
"client1",
|
||||
ProtoConstants.Platform.Platform_Android
|
||||
);
|
||||
if (tokenResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("Token: " + tokenResult.getResult().getToken());
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
Conversation conversation = new Conversation();
|
||||
conversation.setType(ProtoConstants.ConversationType.ConversationType_Private);
|
||||
conversation.setTarget("user2");
|
||||
conversation.setLine(0);
|
||||
|
||||
TextMessageContent content = new TextMessageContent("Hello, World!");
|
||||
MessagePayload payload = content.encode();
|
||||
|
||||
IMResult<SendMessageResult> msgResult = MessageAdmin.sendMessage("user1", conversation, payload);
|
||||
if (msgResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("消息发送成功,ID: " + msgResult.getResult().getMessageUid());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Robot 机器人服务
|
||||
|
||||
```java
|
||||
import cn.wildfirechat.sdk.RobotService;
|
||||
import cn.wildfirechat.sdk.messagecontent.TextMessageContent;
|
||||
|
||||
public class RobotExample {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 初始化机器人服务
|
||||
RobotService robot = new RobotService("http://localhost", "robot1", "123456");
|
||||
|
||||
// 获取机器人信息
|
||||
IMResult<OutputRobot> profile = robot.getProfile();
|
||||
if (profile.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("机器人名称: " + profile.getResult().getDisplayName());
|
||||
}
|
||||
|
||||
// 发送消息给用户
|
||||
TextMessageContent content = new TextMessageContent("Hello from robot!");
|
||||
IMResult<SendMessageResult> result = robot.sendMessage("user1", content);
|
||||
if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("机器人消息发送成功");
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
IMResult<OutputUserInfo> userInfo = robot.getUserInfo("user1");
|
||||
if (userInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("用户显示名: " + userInfo.getResult().getDisplayName());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Channel 频道服务
|
||||
|
||||
```java
|
||||
import cn.wildfirechat.sdk.ChannelServiceApi;
|
||||
import cn.wildfirechat.sdk.messagecontent.TextMessageContent;
|
||||
|
||||
public class ChannelExample {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 初始化频道服务
|
||||
ChannelServiceApi channel = new ChannelServiceApi("http://localhost", "channel1", "secret");
|
||||
|
||||
// 发送广播消息给订阅者
|
||||
TextMessageContent content = new TextMessageContent("Channel broadcast message");
|
||||
IMResult<SendMessageResult> result = channel.broadcastMessage(content);
|
||||
if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("频道广播消息发送成功");
|
||||
}
|
||||
|
||||
// 用户订阅频道
|
||||
IMResult<Void> subscribeResult = channel.subscribe("user1");
|
||||
if (subscribeResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("订阅成功");
|
||||
}
|
||||
|
||||
// 获取频道订阅者(商业版功能)
|
||||
IMResult<OutputStringList> subscribers = channel.getSubscriberList();
|
||||
if (subscribers.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
System.out.println("订阅者数量: " + subscribers.getResult().getList().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 运行测试
|
||||
|
||||
SDK 提供了完整的测试示例 `Main.java`:
|
||||
|
||||
```bash
|
||||
# 编译
|
||||
mvn compile
|
||||
|
||||
# 运行测试(使用默认配置)
|
||||
mvn exec:java -Dexec.mainClass="cn.wildfirechat.sdk.Main"
|
||||
|
||||
# 运行测试(自定义配置)
|
||||
mvn exec:java -Dexec.mainClass="cn.wildfirechat.sdk.Main" \
|
||||
-Dexec.args="http://your-server:18080 your-secret http://your-server false false"
|
||||
```
|
||||
|
||||
### 命令行参数
|
||||
|
||||
```
|
||||
Usage: java -jar sdk.jar adminUrl adminSecret imUrl commercialServer advanceVoip
|
||||
|
||||
参数说明:
|
||||
adminUrl - 管理API地址,如 http://localhost:18080
|
||||
adminSecret - 管理员密钥
|
||||
imUrl - IM服务地址(机器人/频道使用),如 http://localhost
|
||||
commercialServer - 是否为商业版服务器 (true/false)
|
||||
advanceVoip - 是否启用高级音视频功能 (true/false)
|
||||
```
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
sdk/
|
||||
├── src/main/java/cn/wildfirechat/
|
||||
│ ├── sdk/
|
||||
│ │ ├── AdminConfig.java # 配置类
|
||||
│ │ ├── UserAdmin.java # 用户管理
|
||||
│ │ ├── GroupAdmin.java # 群组管理
|
||||
│ │ ├── MessageAdmin.java # 消息管理
|
||||
│ │ ├── RelationAdmin.java # 好友关系管理
|
||||
│ │ ├── ChatroomAdmin.java # 聊天室管理
|
||||
│ │ ├── ChannelAdmin.java # 频道管理
|
||||
│ │ ├── GeneralAdmin.java # 通用管理
|
||||
│ │ ├── SensitiveAdmin.java # 敏感词管理
|
||||
│ │ ├── ConferenceAdmin.java # 会议管理
|
||||
│ │ ├── MomentsAdmin.java # 朋友圈管理
|
||||
│ │ ├── RobotService.java # 机器人服务
|
||||
│ │ ├── ChannelServiceApi.java # 频道服务API
|
||||
│ │ ├── MeshAdmin.java # Mesh分布式管理
|
||||
│ │ └── Main.java # 测试主程序
|
||||
│ │ └── messagecontent/ # 消息内容类
|
||||
│ │ ├── MessageContent.java
|
||||
│ │ ├── TextMessageContent.java
|
||||
│ │ ├── ImageMessageContent.java
|
||||
│ │ ├── SoundMessageContent.java
|
||||
│ │ ├── VideoMessageContent.java
|
||||
│ │ ├── FileMessageContent.java
|
||||
│ │ └── ...
|
||||
│ ├── common/ # 公共模块(依赖)
|
||||
│ └── proto/ # 协议常量
|
||||
└── pom.xml # Maven配置
|
||||
```
|
||||
|
||||
## 主要 API 说明
|
||||
|
||||
### 用户管理 (UserAdmin)
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `createUser()` | 创建用户 |
|
||||
| `getUserByName()` | 按用户名获取用户 |
|
||||
| `getUserByMobile()` | 按手机号获取用户 |
|
||||
| `getUserByUserId()` | 按用户ID获取用户 |
|
||||
| `updateUserInfo()` | 更新用户信息 |
|
||||
| `getUserToken()` | 获取用户IM Token |
|
||||
| `updateUserBlockStatus()` | 封禁/解封用户 |
|
||||
| `checkUserOnlineStatus()` | 检查用户在线状态 |
|
||||
|
||||
### 群组管理 (GroupAdmin)
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `createGroup()` | 创建群组 |
|
||||
| `getGroupInfo()` | 获取群组信息 |
|
||||
| `addGroupMembers()` | 添加群成员 |
|
||||
| `kickoffGroupMembers()` | 踢出群成员 |
|
||||
| `transferGroup()` | 转让群主 |
|
||||
| `dismissGroup()` | 解散群组 |
|
||||
|
||||
### 消息管理 (MessageAdmin)
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `sendMessage()` | 发送消息 |
|
||||
| `broadcastMessage()` | 广播消息 |
|
||||
| `multicastMessage()` | 群发消息 |
|
||||
| `recallMessage()` | 撤回消息 |
|
||||
| `deleteMessage()` | 删除消息 |
|
||||
|
||||
### 好友关系 (RelationAdmin)
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `setUserFriend()` | 设置好友关系 |
|
||||
| `getFriendList()` | 获取好友列表 |
|
||||
| `setUserBlacklist()` | 设置黑名单 |
|
||||
| `getUserBlacklist()` | 获取黑名单列表 |
|
||||
|
||||
## 接口文档
|
||||
|
||||
- [Admin API 文档](https://docs.wildfirechat.cn/server/admin_api/) - 服务端管理接口,包括用户、群组、消息、频道等管理功能
|
||||
- [Robot API 文档](https://docs.wildfirechat.cn/server/robot_api/) - 机器人服务接口,用于开发机器人应用
|
||||
- [Channel API 文档](https://docs.wildfirechat.cn/server/channel_api/) - 频道服务接口,用于开发公众号/频道应用
|
||||
- [IM 开发文档](https://docs.wildfirechat.cn/) - 野火IM完整开发文档
|
||||
|
||||
## 其他语言 SDK
|
||||
|
||||
| 语言 | GitHub | Gitee(码云) |
|
||||
|------|------------------------------------------------------------------|-------------|
|
||||
| Java SDK | [GitHub](https://github.com/wildfirechat/server/tree/master/sdk) | [Gitee](https://gitee.com/wfchat/im-server/tree/wildfirechat/sdk) |
|
||||
| Python SDK | [GitHub](https://github.com/wildfirechat/server-sdk-python) | [Gitee](https://gitee.com/wfchat/im-server/server-sdk-python) |
|
||||
| Go SDK | [GitHub](https://github.com/wildfirechat/server-sdk-go) | [Gitee](https://gitee.com/wfchat/server-sdk-go) |
|
||||
| Node.js SDK | [GitHub](https://github.com/wildfirechat/server-sdk.js) | [Gitee](https://gitee.com/wfchat/server-sdk.js) |
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [野火IM 官网](https://wildfirechat.cn/)
|
||||
- [在线文档](https://docs.wildfirechat.cn/)
|
||||
- [服务端源码 - GitHub](https://github.com/wildfirechat/server) | [Gitee](https://gitee.com/wfchat/im-server)
|
||||
- [应用服务源码 - GitHub](https://github.com/wildfirechat/app-server) | [Gitee](https://gitee.com/wfchat/app-server)
|
||||
- [机器人服务源码 - GitHub](https://github.com/wildfirechat/robot-server) | [Gitee](https://gitee.com/wfchat/robot-server)
|
||||
- [推送服务源码 - GitHub](https://github.com/wildfirechat/push-server) | [Gitee](https://gitee.com/wfchat/push-server)
|
||||
- [论坛交流](https://bbs.wildfirechat.cn/)
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **Admin API** 使用 18080 端口,具有超级管理权限,理论上不应对外开放,也不应让非内部服务知悉密钥。
|
||||
2. **Robot API** 和 **Channel API** 使用 IM 服务的公开端口(默认 80),第三方可以使用机器人或频道与 IM 系统进行对接。
|
||||
3. 商业版服务器支持更多高级功能,如在线用户统计、设备管理等。
|
||||
4. 高级音视频功能需要单独启用,支持会议管理相关 API。
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目采用与野火IM相同的许可证。
|
||||
+7
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.4.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>4.5.13</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
|
||||
@@ -2,7 +2,22 @@ package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
/**
|
||||
* 管理员配置类
|
||||
* <p>
|
||||
* 用于初始化管理员SDK的配置,包括IM服务器URL和密钥。
|
||||
* 在使用任何Admin功能之前,必须先调用initAdmin方法进行初始化。
|
||||
* </p>
|
||||
*/
|
||||
public class AdminConfig {
|
||||
/**
|
||||
* 初始化管理员配置
|
||||
* <p>
|
||||
* 在使用任何Admin功能之前,必须先调用此方法进行初始化。
|
||||
* </p>
|
||||
* @param url IM服务器地址,例如: http://your-im-server.com
|
||||
* @param secret 管理员密钥,在服务器配置中设置
|
||||
*/
|
||||
public static void initAdmin(String url, String secret) {
|
||||
AdminHttpUtils.init(url, secret);
|
||||
}
|
||||
|
||||
@@ -2,42 +2,151 @@ package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.pojos.mesh.PojoStringList;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 频道管理类
|
||||
* <p>
|
||||
* 提供频道管理相关的功能,包括:
|
||||
* <ul>
|
||||
* <li>创建和销毁频道</li>
|
||||
* <li>获取频道信息</li>
|
||||
* <li>用户订阅/取消订阅频道</li>
|
||||
* <li>检查用户是否订阅频道</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class ChannelAdmin {
|
||||
/**
|
||||
* 创建频道
|
||||
* @param inputCreateChannel 频道创建信息
|
||||
* @return 创建结果,包含频道ID
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputCreateChannel> createChannel(InputCreateChannel inputCreateChannel) throws Exception {
|
||||
String path = APIPath.Create_Channel;
|
||||
return AdminHttpUtils.httpJsonPost(path, inputCreateChannel, OutputCreateChannel.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁频道
|
||||
* @param channelId 频道ID
|
||||
* @return 销毁结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> destroyChannel(String channelId) throws Exception {
|
||||
String path = APIPath.Destroy_Channel;
|
||||
InputChannelId inputChannelId = new InputChannelId(channelId);
|
||||
return AdminHttpUtils.httpJsonPost(path, inputChannelId, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道信息
|
||||
* @param channelId 频道ID
|
||||
* @return 频道信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGetChannelInfo> getChannelInfo(String channelId) throws Exception {
|
||||
String path = APIPath.Get_Channel_Info;
|
||||
InputChannelId inputChannelId = new InputChannelId(channelId);
|
||||
return AdminHttpUtils.httpJsonPost(path, inputChannelId, OutputGetChannelInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道信息列表
|
||||
* @param count 数量
|
||||
* @param offset offset
|
||||
* @return 频道信息列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputChannelInfoList> getChannelInfoList(int count, int offset) throws Exception {
|
||||
String path = APIPath.List_Channel_Info;
|
||||
InputCountOffset inputCountOffset = new InputCountOffset();
|
||||
inputCountOffset.count = count;
|
||||
inputCountOffset.offset = offset;
|
||||
return AdminHttpUtils.httpJsonPost(path, inputCountOffset, OutputChannelInfoList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userId 用户ID
|
||||
* @return 订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> subscribeChannel(String channelId, String userId) throws Exception {
|
||||
String path = APIPath.Subscribe_Channel;
|
||||
InputSubscribeChannel input = new InputSubscribeChannel(channelId, userId, 1);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量用户订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userIds 用户ID列表
|
||||
* @return 订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> batchSubscribeChannel(String channelId, List<String> userIds) throws Exception {
|
||||
String path = APIPath.Batch_Subscribe_Channel;
|
||||
InputSubscribeChannelBatch input = new InputSubscribeChannelBatch(channelId, userIds, 1);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userId 用户ID
|
||||
* @return 取消订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> unsubscribeChannel(String channelId, String userId) throws Exception {
|
||||
String path = APIPath.Subscribe_Channel;
|
||||
InputSubscribeChannel input = new InputSubscribeChannel(channelId, userId, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量用户取消订阅频道
|
||||
* @param channelId 频道ID
|
||||
* @param userIds 用户ID列表
|
||||
* @return 取消订阅结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> batchUnsubscribeChannel(String channelId, List<String> userIds) throws Exception {
|
||||
String path = APIPath.Batch_Subscribe_Channel;
|
||||
InputSubscribeChannelBatch input = new InputSubscribeChannelBatch(channelId, userIds, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否订阅了频道
|
||||
* @param userId 用户ID
|
||||
* @param channelId 频道ID
|
||||
* @return true-已订阅,false-未订阅
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputBooleanValue> isUserSubscribedChannel(String userId, String channelId) throws Exception {
|
||||
String path = APIPath.Check_User_Subscribe_Channel;
|
||||
InputSubscribeChannel input = new InputSubscribeChannel(channelId, userId, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputBooleanValue.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道订阅用户列表
|
||||
* @param channelId 频道ID
|
||||
* @param count
|
||||
* @param offset
|
||||
* @return 订阅用户id列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoTotalList> getChannelSubscribers(String channelId, int count, int offset) throws Exception {
|
||||
String path = APIPath.List_Channel_Subscriber;
|
||||
InputStringCountOffset input = new InputStringCountOffset(channelId, count, offset);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, PojoTotalList.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,32 +15,75 @@ import java.util.List;
|
||||
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ApplicationType.ApplicationType_Channel;
|
||||
|
||||
//仅专业版支持,社区版不支持
|
||||
/**
|
||||
* 频道服务类(仅专业版支持,社区版不支持)
|
||||
* <p>
|
||||
* 提供频道相关的功能,包括:
|
||||
* <ul>
|
||||
* <li>获取用户信息</li>
|
||||
* <li>修改频道信息</li>
|
||||
* <li>发送和撤回消息</li>
|
||||
* <li>用户订阅管理</li>
|
||||
* <li>订阅者列表查询</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class ChannelServiceApi implements Closeable {
|
||||
private final ChannelHttpUtils channelHttpUtils;
|
||||
|
||||
/**
|
||||
* 创建频道服务实例
|
||||
* @param imurl IM服务器地址
|
||||
* @param channelId 频道ID
|
||||
* @param secret 频道密钥
|
||||
*/
|
||||
public ChannelServiceApi(String imurl, String channelId, String secret) {
|
||||
channelHttpUtils = new ChannelHttpUtils(imurl, channelId, secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户信息
|
||||
* @param userId 用户ID
|
||||
* @return 用户信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<InputOutputUserInfo> getUserInfo(String userId) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(userId, null, null);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户名获取用户信息
|
||||
* @param userName 用户名
|
||||
* @return 用户信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<InputOutputUserInfo> getUserInfoByName(String userName) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, userName, null);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机号获取用户信息
|
||||
* @param mobile 手机号
|
||||
* @return 用户信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<InputOutputUserInfo> getUserInfoByMobile(String mobile) throws Exception {
|
||||
String path = APIPath.Channel_User_Info;
|
||||
InputGetUserInfo getUserInfo = new InputGetUserInfo(null, null, mobile);
|
||||
return channelHttpUtils.httpJsonPost(path, getUserInfo, InputOutputUserInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改频道信息
|
||||
* @param type 修改类型,参考{@link cn.wildfirechat.proto.ProtoConstants.ModifyChannelInfoType}
|
||||
* @param value 修改的值
|
||||
* @return 操作结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Void> modifyChannelInfo(/*ProtoConstants.ModifyChannelInfoType*/int type, String value) throws Exception {
|
||||
String path = APIPath.Channel_Update_Profile;
|
||||
InputModifyChannelInfo modifyChannelInfo = new InputModifyChannelInfo();
|
||||
@@ -49,16 +92,35 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, modifyChannelInfo, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道信息
|
||||
* @return 频道信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<OutputGetChannelInfo> getChannelInfo() throws Exception {
|
||||
String path = APIPath.Channel_Get_Profile;
|
||||
return channelHttpUtils.httpJsonPost(path, null, OutputGetChannelInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改频道菜单
|
||||
* @param menus 菜单列表
|
||||
* @return 操作结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Void> modifyChannelMenu(List<PojoChannelMenu> menus) throws Exception {
|
||||
String menuStr = new Gson().toJson(menus);
|
||||
return modifyChannelInfo(ProtoConstants.ModifyChannelInfoType.Modify_Channel_Menu, menuStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送频道消息
|
||||
* @param line 线路
|
||||
* @param targets 目标用户ID列表
|
||||
* @param payload 消息内容
|
||||
* @return 发送结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<SendMessageResult> sendMessage(int line, List<String> targets, MessagePayload payload) throws Exception {
|
||||
String path = APIPath.Channel_Message_Send;
|
||||
SendChannelMessageData messageData = new SendChannelMessageData();
|
||||
@@ -68,6 +130,12 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, messageData, SendMessageResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回频道消息
|
||||
* @param messageUid 消息UID
|
||||
* @return 操作结果,返回被撤回消息的UID
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<String> recallMessage(long messageUid) throws Exception {
|
||||
String path = APIPath.Channel_Msg_Recall;
|
||||
RecallMessageData messageData = new RecallMessageData();
|
||||
@@ -75,6 +143,13 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, messageData, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新发布频道消息
|
||||
* @param messageUid 消息UID
|
||||
* @param targets 目标用户ID列表
|
||||
* @return 操作结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Void> republishMessage(long messageUid, List<String> targets) throws Exception {
|
||||
String path = APIPath.Channel_Msg_Republish;
|
||||
RepublishChannelMessageData messageData = new RepublishChannelMessageData();
|
||||
@@ -83,6 +158,12 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, messageData, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅频道
|
||||
* @param userId 用户ID
|
||||
* @return 操作结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Void> subscribe(String userId) throws Exception {
|
||||
String path = APIPath.Channel_Subscribe;
|
||||
InputChannelSubscribe input = new InputChannelSubscribe();
|
||||
@@ -91,6 +172,12 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订阅频道
|
||||
* @param userId 用户ID
|
||||
* @return 操作结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Void> unsubscribe(String userId) throws Exception {
|
||||
String path = APIPath.Channel_Subscribe;
|
||||
InputChannelSubscribe input = new InputChannelSubscribe();
|
||||
@@ -99,17 +186,34 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道订阅者列表
|
||||
* @return 订阅者用户ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<OutputStringList> getSubscriberList() throws Exception {
|
||||
String path = APIPath.Channel_Subscriber_List;
|
||||
return channelHttpUtils.httpJsonPost(path, null, OutputStringList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否订阅了频道
|
||||
* @param userId 用户ID
|
||||
* @return 是否订阅
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<Boolean> isSubscriber(String userId) throws Exception {
|
||||
String path = APIPath.Channel_Is_Subscriber;
|
||||
InputUserId input = new InputUserId(userId);
|
||||
return channelHttpUtils.httpJsonPost(path, input, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过授权码获取应用用户信息
|
||||
* @param authCode 授权码
|
||||
* @return 应用用户信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public IMResult<OutputApplicationUserInfo> applicationGetUserInfo(String authCode) throws Exception {
|
||||
String path = APIPath.Channel_Application_Get_UserInfo;
|
||||
InputApplicationGetUserInfo input = new InputApplicationGetUserInfo();
|
||||
@@ -117,6 +221,11 @@ public class ChannelServiceApi implements Closeable {
|
||||
return channelHttpUtils.httpJsonPost(path, input, OutputApplicationUserInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用签名配置
|
||||
* <p>用于客户端接入时的签名验证</p>
|
||||
* @return 应用签名配置数据
|
||||
*/
|
||||
public OutputApplicationConfigData getApplicationSignature() {
|
||||
int nonce = (int)(Math.random() * 100000 + 3);
|
||||
long timestamp = System.currentTimeMillis()/1000;
|
||||
@@ -131,6 +240,10 @@ public class ChannelServiceApi implements Closeable {
|
||||
return configData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭服务,释放资源
|
||||
* @throws IOException 关闭时发生IO异常
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
channelHttpUtils.close();
|
||||
|
||||
@@ -5,7 +5,32 @@ import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
/**
|
||||
* 聊天室管理类
|
||||
* <p>
|
||||
* 提供聊天室管理相关的功能,包括:
|
||||
* <ul>
|
||||
* <li>创建和销毁聊天室</li>
|
||||
* <li>获取聊天室信息</li>
|
||||
* <li>聊天室成员管理</li>
|
||||
* <li>聊天室黑名单管理(仅专业版)</li>
|
||||
* <li>聊天室管理员设置</li>
|
||||
* <li>聊天室全员禁言</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class ChatroomAdmin {
|
||||
/**
|
||||
* 创建聊天室
|
||||
* @param chatroomId 聊天室ID(为空时自动生成)
|
||||
* @param title 聊天室标题
|
||||
* @param desc 聊天室描述
|
||||
* @param portrait 聊天室头像
|
||||
* @param extra 额外信息
|
||||
* @param state 聊天室状态
|
||||
* @return 创建结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputCreateChatroom> createChatroom(String chatroomId, String title, String desc ,String portrait, String extra, Integer state) throws Exception {
|
||||
String path = APIPath.Create_Chatroom;
|
||||
InputCreateChatroom input = new InputCreateChatroom();
|
||||
@@ -18,6 +43,12 @@ public class ChatroomAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputCreateChatroom.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁聊天室
|
||||
* @param chatroomId 聊天室ID
|
||||
* @return 销毁结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> destroyChatroom(String chatroomId) throws Exception {
|
||||
String path = APIPath.Chatroom_Destroy;
|
||||
InputDestoryChatroom input = new InputDestoryChatroom();
|
||||
@@ -25,51 +56,103 @@ public class ChatroomAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取聊天室信息
|
||||
* @param chatroomId 聊天室ID
|
||||
* @return 聊天室信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGetChatroomInfo> getChatroomInfo(String chatroomId) throws Exception {
|
||||
String path = APIPath.Chatroom_Info;
|
||||
InputGetChatroomInfo input = new InputGetChatroomInfo(chatroomId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputGetChatroomInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取聊天室成员列表
|
||||
* @param chatroomId 聊天室ID
|
||||
* @return 成员ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputStringList> getChatroomMembers(String chatroomId) throws Exception {
|
||||
String path = APIPath.Chatroom_GetMembers;
|
||||
InputGetChatroomInfo input = new InputGetChatroomInfo(chatroomId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputStringList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户所在的聊天室
|
||||
* @param userId 用户ID
|
||||
* @return 用户所在的聊天室信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputUserChatroom> getUserChatroom(String userId) throws Exception {
|
||||
String path = APIPath.Chatroom_GetUserChatroom;
|
||||
InputUserId input = new InputUserId(userId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputUserChatroom.class);
|
||||
}
|
||||
|
||||
//仅专业版支持
|
||||
//status:0,正常;1,禁言;2,禁止加入
|
||||
/**
|
||||
* 设置聊天室黑名单状态(仅专业版支持)
|
||||
* <p>status:0-正常;1-禁言;2-禁止加入</p>
|
||||
* @param chatroomId 聊天室ID
|
||||
* @param userId 用户ID
|
||||
* @param status 状态值
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setChatroomBlacklist(String chatroomId, String userId, int status) throws Exception {
|
||||
String path = APIPath.Chatroom_SetBlacklist;
|
||||
InputSetChatroomBlacklist input = new InputSetChatroomBlacklist(chatroomId, userId, status, 0);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取聊天室黑名单
|
||||
* @param chatroomId 聊天室ID
|
||||
* @return 黑名单信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputChatroomBlackInfos> getChatroomBlacklist(String chatroomId) throws Exception {
|
||||
String path = APIPath.Chatroom_GetBlacklist;
|
||||
InputChatroomId input = new InputChatroomId(chatroomId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputChatroomBlackInfos.class);
|
||||
}
|
||||
|
||||
//status: 1 set; 0 unset
|
||||
/**
|
||||
* 设置聊天室管理员
|
||||
* <p>status:1-设置为管理员;0-取消管理员</p>
|
||||
* @param chatroomId 聊天室ID
|
||||
* @param userId 用户ID
|
||||
* @param status 状态值
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setChatroomManager(String chatroomId, String userId, int status) throws Exception {
|
||||
String path = APIPath.Chatroom_SetManager;
|
||||
InputSetChatroomManager input = new InputSetChatroomManager(chatroomId, userId, status);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取聊天室管理员列表
|
||||
* @param chatroomId 聊天室ID
|
||||
* @return 管理员ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputStringList> getChatroomManagerList(String chatroomId) throws Exception {
|
||||
String path = APIPath.Chatroom_GetManagerList;
|
||||
InputChatroomId input = new InputChatroomId(chatroomId);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputStringList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置聊天室全员禁言
|
||||
* @param chatroomId 聊天室ID
|
||||
* @param mute true-全员禁言,false-取消全员禁言
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setChatroomMute(String chatroomId, boolean mute) throws Exception {
|
||||
String path = APIPath.Chatroom_MuteAll;
|
||||
InputChatroomMute input = new InputChatroomMute(chatroomId, mute ? 1 : 0);
|
||||
|
||||
@@ -5,24 +5,73 @@ import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
/**
|
||||
* 会议管理类
|
||||
* <p>
|
||||
* 提供音视频会议管理相关的功能,包括:
|
||||
* <ul>
|
||||
* <li>会议列表查询</li>
|
||||
* <li>会议创建和销毁</li>
|
||||
* <li>会议参与者管理</li>
|
||||
* <li>会议录制控制</li>
|
||||
* <li>RTP转发管理</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class ConferenceAdmin {
|
||||
public static IMResult<PojoConferenceInfoList> listConferences() throws Exception {
|
||||
/**
|
||||
* 获取会议列表(分页)
|
||||
* @param count 每页数量
|
||||
* @param offset 偏移量
|
||||
* @return 会议信息列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoConferenceInfoList> listConferences(int count, int offset) throws Exception {
|
||||
String path = APIPath.Conference_List;
|
||||
return AdminHttpUtils.httpJsonPost(path, null, PojoConferenceInfoList.class);
|
||||
InputCountOffset inputCountOffset = new InputCountOffset();
|
||||
inputCountOffset.count = count;
|
||||
inputCountOffset.offset = offset;
|
||||
return AdminHttpUtils.httpJsonPost(path, inputCountOffset, PojoConferenceInfoList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查会议是否存在
|
||||
* @param conferenceId 会议ID
|
||||
* @return true-存在,false-不存在
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Boolean> existsConferences(String conferenceId) throws Exception {
|
||||
String path = APIPath.Conference_Exist;
|
||||
PojoConferenceRoomId data = new PojoConferenceRoomId(conferenceId, false);
|
||||
return AdminHttpUtils.httpJsonPost(path, data, Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会议参与者列表
|
||||
* @param roomId 房间ID
|
||||
* @param advance 是否使用高级模式
|
||||
* @return 参与者列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoConferenceParticipantList> listParticipants(String roomId, boolean advance) throws Exception {
|
||||
String path = APIPath.Conference_List_Participant;
|
||||
PojoConferenceRoomId data = new PojoConferenceRoomId(roomId, advance);
|
||||
return AdminHttpUtils.httpJsonPost(path, data, PojoConferenceParticipantList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建会议房间
|
||||
* @param roomId 房间ID
|
||||
* @param description 描述
|
||||
* @param pin 房间密码
|
||||
* @param maxPublisher 最大推流数
|
||||
* @param advance 是否使用高级模式
|
||||
* @param bitrate 比特率
|
||||
* @param recording 是否录制
|
||||
* @param permanent 是否永久房间
|
||||
* @return 创建结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> createRoom(String roomId, String description, String pin, int maxPublisher, boolean advance, int bitrate, boolean recording, boolean permanent) throws Exception {
|
||||
String path = APIPath.Conference_Create;
|
||||
PojoConferenceCreate create = new PojoConferenceCreate();
|
||||
@@ -37,6 +86,14 @@ public class ConferenceAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, create, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用或禁用会议录制
|
||||
* @param roomId 房间ID
|
||||
* @param advance 是否使用高级模式
|
||||
* @param recording true-启用录制,false-禁用录制
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> enableRecording(String roomId, boolean advance, boolean recording) throws Exception {
|
||||
String path = APIPath.Conference_Recording;
|
||||
PojoConferenceRecording create = new PojoConferenceRecording();
|
||||
@@ -46,24 +103,59 @@ public class ConferenceAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, create, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁会议房间
|
||||
* @param roomId 房间ID
|
||||
* @param advance 是否使用高级模式
|
||||
* @return 销毁结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> destroy(String roomId, boolean advance) throws Exception {
|
||||
String path = APIPath.Conference_Destroy;
|
||||
PojoConferenceRoomId conferenceRoomId = new PojoConferenceRoomId(roomId, advance);
|
||||
return AdminHttpUtils.httpJsonPost(path, conferenceRoomId, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* RTP转发
|
||||
* @param roomId 房间ID
|
||||
* @param userId 用户ID
|
||||
* @param rtpHost RTP主机地址
|
||||
* @param audioPort 音频端口
|
||||
* @param audioPt 音频Payload类型
|
||||
* @param audioSSRC 音频SSRC
|
||||
* @param videoPort 视频端口
|
||||
* @param videoPt 视频Payload类型
|
||||
* @param videoSSRC 视频SSRC
|
||||
* @return 转发结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> rtpForward(String roomId, String userId, String rtpHost, int audioPort, int audioPt, long audioSSRC, int videoPort, int videoPt, long videoSSRC) throws Exception {
|
||||
String path = APIPath.Conference_Rtp_Forward;
|
||||
PojoConferenceRtpForwardReq req = new PojoConferenceRtpForwardReq(roomId, userId, rtpHost, audioPort, audioPt, audioSSRC, videoPort, videoPt, videoSSRC);
|
||||
return AdminHttpUtils.httpJsonPost(path, req, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止RTP转发
|
||||
* @param roomId 房间ID
|
||||
* @param userId 用户ID
|
||||
* @param streamId 流ID
|
||||
* @return 停止结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> stopRtpForward(String roomId, String userId, long streamId) throws Exception {
|
||||
String path = APIPath.Conference_Stop_Rtp_Forward;
|
||||
PojoConferenceStopRtpForwardReq req = new PojoConferenceStopRtpForwardReq(roomId, userId, streamId);
|
||||
return AdminHttpUtils.httpJsonPost(path, req, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取RTP转发列表
|
||||
* @param roomId 房间ID
|
||||
* @return RTP转发列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoConferenceRtpForwarders> listRtpForwarders(String roomId) throws Exception {
|
||||
String path = APIPath.Conference_List_Rtp_Forward;
|
||||
PojoConferenceRoomId req = new PojoConferenceRoomId();
|
||||
|
||||
@@ -1,11 +1,47 @@
|
||||
package cn.wildfirechat.sdk;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.sdk.model.IMResult;
|
||||
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.FileEntity;
|
||||
import org.apache.http.entity.InputStreamEntity;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.entity.mime.content.FileBody;
|
||||
import org.apache.http.entity.mime.content.InputStreamBody;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* 通用管理类
|
||||
* <p>
|
||||
* 提供通用的系统管理功能,包括:
|
||||
* <ul>
|
||||
* <li>系统设置管理</li>
|
||||
* <li>文件管理(会话文件、用户文件)</li>
|
||||
* <li>用户设置管理(会话置顶等)</li>
|
||||
* <li>健康检查</li>
|
||||
* <li>频道管理(已废弃,请使用ChannelAdmin)</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class GeneralAdmin {
|
||||
/**
|
||||
* 获取系统设置
|
||||
* @param id 设置项ID
|
||||
* @return 系统设置信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<SystemSettingPojo> getSystemSetting(int id) throws Exception {
|
||||
String path = APIPath.Get_System_Setting;
|
||||
SystemSettingPojo input = new SystemSettingPojo();
|
||||
@@ -13,6 +49,14 @@ public class GeneralAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, SystemSettingPojo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置系统设置
|
||||
* @param id 设置项ID
|
||||
* @param value 设置值
|
||||
* @param desc 设置描述
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setSystemSetting(int id, String value, String desc) throws Exception {
|
||||
String path = APIPath.Put_System_Setting;
|
||||
SystemSettingPojo input = new SystemSettingPojo();
|
||||
@@ -81,13 +125,91 @@ public class GeneralAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputBooleanValue.class);
|
||||
}
|
||||
|
||||
//以下仅专业版支持
|
||||
/**
|
||||
* 获取会话文件列表(仅专业版支持)
|
||||
* <p>
|
||||
* 如果是单聊会话,target和userId代表会话的2个用户;如果是其他会话userId无意义。
|
||||
* </p>
|
||||
* @param conversationType 会话类型
|
||||
* @param target 会话目标ID
|
||||
* @param line 线路
|
||||
* @param userId 用户ID
|
||||
* @param offset 偏移量
|
||||
* @param desc 是否降序
|
||||
* @param count 每页数量
|
||||
* @return 文件列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<FilesPojo> getConversationFiles(int conversationType, String target, int line, String userId, int offset, boolean desc, int count) throws Exception {
|
||||
String path = APIPath.Get_Conversation_Files;
|
||||
GetConversationFilesPojo input = new GetConversationFilesPojo();
|
||||
input.conversationType = conversationType;
|
||||
input.target = target;
|
||||
input.line = line;
|
||||
input.userId = userId;
|
||||
input.offset = offset;
|
||||
input.desc = desc;
|
||||
input.count = count;
|
||||
return AdminHttpUtils.httpJsonPost(path, input, FilesPojo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户文件列表
|
||||
* @param userId 用户ID
|
||||
* @param offset 偏移量
|
||||
* @param desc 是否降序
|
||||
* @param count 每页数量
|
||||
* @return 文件列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<FilesPojo> getUserFiles(String userId, int offset, boolean desc, int count) throws Exception {
|
||||
String path = APIPath.Get_User_Files;
|
||||
GetUserFilesPojo input = new GetUserFilesPojo();
|
||||
input.userId = userId;
|
||||
input.offset = offset;
|
||||
input.desc = desc;
|
||||
input.count = count;
|
||||
return AdminHttpUtils.httpJsonPost(path, input, FilesPojo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据消息ID获取文件信息
|
||||
* @param messageId 消息ID
|
||||
* @return 文件信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<FilesPojo.FilePojo> getFile(long messageId) throws Exception {
|
||||
String path = APIPath.Get_Message_File;
|
||||
LongPojo input = new LongPojo();
|
||||
input.value = messageId;
|
||||
return AdminHttpUtils.httpJsonPost(path, input, FilesPojo.FilePojo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置会话置顶
|
||||
* @param userId 用户ID
|
||||
* @param conversationType 会话类型
|
||||
* @param target 会话目标ID
|
||||
* @param line 线路
|
||||
* @param isTop true-置顶,false-取消置顶
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setConversationTop(String userId, int conversationType, String target, int line, boolean isTop) throws Exception {
|
||||
String key = conversationType + "-" + line + "-" + target;
|
||||
String value = isTop?"1":"0";
|
||||
return setUserSetting(userId, 3, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话置顶状态
|
||||
* @param userId 用户ID
|
||||
* @param conversationType 会话类型
|
||||
* @param target 会话目标ID
|
||||
* @param line 线路
|
||||
* @return true-已置顶,false-未置顶
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Boolean> getConversationTop(String userId, int conversationType, String target, int line) throws Exception {
|
||||
String key = conversationType + "-" + line + "-" + target;
|
||||
IMResult<UserSettingPojo> result = getUserSetting(userId, 3, key);
|
||||
@@ -98,7 +220,14 @@ public class GeneralAdmin {
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户设置
|
||||
* @param userId 用户ID
|
||||
* @param scope 设置范围
|
||||
* @param key 设置键
|
||||
* @return 用户设置信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<UserSettingPojo> getUserSetting(String userId, int scope, String key) throws Exception {
|
||||
String path = APIPath.User_Get_Setting;
|
||||
UserSettingPojo pojo = new UserSettingPojo();
|
||||
@@ -108,6 +237,15 @@ public class GeneralAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, pojo, UserSettingPojo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户设置
|
||||
* @param userId 用户ID
|
||||
* @param scope 设置范围
|
||||
* @param key 设置键
|
||||
* @param value 设置值
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setUserSetting(String userId, int scope, String key, String value) throws Exception {
|
||||
String path = APIPath.User_Put_Setting;
|
||||
UserSettingPojo pojo = new UserSettingPojo();
|
||||
@@ -118,11 +256,348 @@ public class GeneralAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, pojo, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 健康检查
|
||||
* @return 健康检查结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<HealthCheckResult> healthCheck() throws Exception {
|
||||
return AdminHttpUtils.httpGet(APIPath.Health, HealthCheckResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户信息
|
||||
* @return 客户信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> getCustomer() throws Exception {
|
||||
return AdminHttpUtils.httpJsonPost(APIPath.GET_CUSTOMER, null, String.class);
|
||||
}
|
||||
|
||||
public static IMResult<OutputPresignedUploadUrl> getPresignedUploadUrl(String fileName, int/*ProtoConstants.MessageMediaType*/ mediaType, String contentType) throws Exception {
|
||||
String path = APIPath.Get_Presigned_Upload_Url;
|
||||
|
||||
InputGetPresignedUploadUrl requestPojo = new InputGetPresignedUploadUrl();
|
||||
requestPojo.fileName = fileName;
|
||||
requestPojo.mediaType = mediaType;
|
||||
requestPojo.contentType = contentType;
|
||||
return AdminHttpUtils.httpJsonPost(path, requestPojo, OutputPresignedUploadUrl.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件名获取Content-Type
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return Content-Type,如果无法识别则返回 "application/octet-stream"
|
||||
*/
|
||||
private static String getContentTypeByFileName(String fileName) {
|
||||
if (fileName == null || fileName.isEmpty()) {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
// 首先尝试使用 URLConnection 猜测
|
||||
String contentType = URLConnection.guessContentTypeFromName(fileName);
|
||||
|
||||
// 如果无法识别,使用常见扩展名映射
|
||||
if (contentType == null) {
|
||||
String lowerName = fileName.toLowerCase();
|
||||
if (lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg")) {
|
||||
contentType = "image/jpeg";
|
||||
} else if (lowerName.endsWith(".png")) {
|
||||
contentType = "image/png";
|
||||
} else if (lowerName.endsWith(".gif")) {
|
||||
contentType = "image/gif";
|
||||
} else if (lowerName.endsWith(".bmp")) {
|
||||
contentType = "image/bmp";
|
||||
} else if (lowerName.endsWith(".webp")) {
|
||||
contentType = "image/webp";
|
||||
} else if (lowerName.endsWith(".mp4")) {
|
||||
contentType = "video/mp4";
|
||||
} else if (lowerName.endsWith(".mov")) {
|
||||
contentType = "video/quicktime";
|
||||
} else if (lowerName.endsWith(".avi")) {
|
||||
contentType = "video/x-msvideo";
|
||||
} else if (lowerName.endsWith(".mp3")) {
|
||||
contentType = "audio/mpeg";
|
||||
} else if (lowerName.endsWith(".wav")) {
|
||||
contentType = "audio/wav";
|
||||
} else if (lowerName.endsWith(".pdf")) {
|
||||
contentType = "application/pdf";
|
||||
} else if (lowerName.endsWith(".doc")) {
|
||||
contentType = "application/msword";
|
||||
} else if (lowerName.endsWith(".docx")) {
|
||||
contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||
} else if (lowerName.endsWith(".xls")) {
|
||||
contentType = "application/vnd.ms-excel";
|
||||
} else if (lowerName.endsWith(".xlsx")) {
|
||||
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
} else if (lowerName.endsWith(".ppt")) {
|
||||
contentType = "application/vnd.ms-powerpoint";
|
||||
} else if (lowerName.endsWith(".pptx")) {
|
||||
contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||||
} else if (lowerName.endsWith(".txt")) {
|
||||
contentType = "text/plain";
|
||||
} else if (lowerName.endsWith(".html") || lowerName.endsWith(".htm")) {
|
||||
contentType = "text/html";
|
||||
} else if (lowerName.endsWith(".json")) {
|
||||
contentType = "application/json";
|
||||
} else if (lowerName.endsWith(".xml")) {
|
||||
contentType = "application/xml";
|
||||
} else if (lowerName.endsWith(".zip")) {
|
||||
contentType = "application/zip";
|
||||
} else if (lowerName.endsWith(".rar")) {
|
||||
contentType = "application/x-rar-compressed";
|
||||
} else if (lowerName.endsWith(".7z")) {
|
||||
contentType = "application/x-7z-compressed";
|
||||
} else if (lowerName.endsWith(".tar")) {
|
||||
contentType = "application/x-tar";
|
||||
} else if (lowerName.endsWith(".gz")) {
|
||||
contentType = "application/gzip";
|
||||
} else {
|
||||
contentType = "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* <p>
|
||||
* 流程:先调用getPresignedUploadUrl获取预签名上传地址,然后直接上传文件。
|
||||
* 上传成功后返回文件的下载地址等信息。
|
||||
* </p>
|
||||
*
|
||||
* @param file 要上传的文件
|
||||
* @return 上传结果,包含下载地址
|
||||
* @throws Exception 上传失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> uploadFile(File file) throws Exception {
|
||||
return uploadFile(file, ProtoConstants.MessageMediaType.FILE, null);
|
||||
}
|
||||
/**
|
||||
* 上传文件
|
||||
* <p>
|
||||
* 流程:先调用getPresignedUploadUrl获取预签名上传地址,然后直接上传文件。
|
||||
* 上传成功后返回文件的下载地址等信息。
|
||||
* </p>
|
||||
*
|
||||
* @param file 要上传的文件
|
||||
* @param mediaType 媒体类型,参考{@link cn.wildfirechat.proto.ProtoConstants.MessageMediaType}
|
||||
* @param contentType 文件Content-Type,例如 "image/jpeg", "application/octet-stream" 等;
|
||||
* 如果为null或空,则根据文件名自动识别
|
||||
* @return 上传结果,包含下载地址
|
||||
* @throws Exception 上传失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> uploadFile(File file, int mediaType, String contentType) throws Exception {
|
||||
if (file == null || !file.exists()) {
|
||||
throw new IllegalArgumentException("文件不能为空或不存在");
|
||||
}
|
||||
|
||||
// 如果未指定Content-Type,根据文件名自动获取
|
||||
if (contentType == null || contentType.isEmpty()) {
|
||||
contentType = getContentTypeByFileName(file.getName());
|
||||
}
|
||||
|
||||
return doUploadFile(file.getName(), mediaType, contentType, file, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行文件上传的公共方法
|
||||
* <p>
|
||||
* 根据服务器类型选择不同的上传方式:
|
||||
* <ul>
|
||||
* <li>type = 1(七牛云):使用 POST + multipart/form-data 表单上传</li>
|
||||
* <li>type = 其他(阿里云、Minio等):使用 PUT + 二进制流上传</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @param mediaType 媒体类型
|
||||
* @param contentType Content-Type
|
||||
* @param file 文件对象(用于七牛云上传)
|
||||
* @param inputStream 输入流(用于其他类型上传,可为null)
|
||||
* @return 上传结果
|
||||
* @throws Exception 上传失败时抛出异常
|
||||
*/
|
||||
private static IMResult<String> doUploadFile(String fileName, int mediaType,
|
||||
String contentType,
|
||||
File file,
|
||||
InputStream inputStream) throws Exception {
|
||||
// 1. 获取预签名上传地址
|
||||
IMResult<OutputPresignedUploadUrl> presignedResult = getPresignedUploadUrl(
|
||||
fileName, mediaType, contentType);
|
||||
|
||||
if (presignedResult.getErrorCode() != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
IMResult<String> imResult = new IMResult<>();
|
||||
imResult.setCode(presignedResult.code);
|
||||
imResult.setMsg(presignedResult.msg);
|
||||
return imResult;
|
||||
}
|
||||
|
||||
OutputPresignedUploadUrl presignedUrl = presignedResult.getResult();
|
||||
if (presignedUrl == null || presignedUrl.uploadUrl == null) {
|
||||
throw new Exception("预签名上传地址为空");
|
||||
}
|
||||
|
||||
// 2. 根据服务器类型选择上传方式
|
||||
if (presignedUrl.type == 1) {
|
||||
// 七牛云:使用 POST + multipart/form-data 表单上传
|
||||
return uploadToQiniu(presignedUrl, file, inputStream, fileName, contentType);
|
||||
} else {
|
||||
// 其他(阿里云、Minio、腾讯云、华为云、AWS S3等):使用 PUT 上传
|
||||
return uploadToOther(presignedUrl, file, inputStream, contentType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传到七牛云(type = 1)
|
||||
* 使用 POST + multipart/form-data 表单格式
|
||||
*/
|
||||
private static IMResult<String> uploadToQiniu(OutputPresignedUploadUrl presignedUrl, File file,
|
||||
InputStream inputStream, String fileName,
|
||||
String contentType) throws Exception {
|
||||
// 解析七牛云上传地址:格式为 "https://host?token?key"
|
||||
String uploadUrl = presignedUrl.uploadUrl;
|
||||
String token;
|
||||
String key;
|
||||
|
||||
int tokenStart = uploadUrl.indexOf('?');
|
||||
int keyStart = uploadUrl.indexOf('?', tokenStart + 1);
|
||||
|
||||
if (tokenStart == -1 || keyStart == -1) {
|
||||
throw new Exception("七牛云上传地址格式错误");
|
||||
}
|
||||
|
||||
String baseUrl = uploadUrl.substring(0, tokenStart);
|
||||
token = uploadUrl.substring(tokenStart + 1, keyStart);
|
||||
key = uploadUrl.substring(keyStart + 1);
|
||||
|
||||
HttpPost httpPost = new HttpPost(baseUrl);
|
||||
try {
|
||||
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
|
||||
|
||||
// 添加 token 和 key 字段
|
||||
builder.addTextBody("token", token);
|
||||
builder.addTextBody("key", key);
|
||||
|
||||
// 添加文件字段
|
||||
if (file != null) {
|
||||
builder.addPart("file", new FileBody(file, ContentType.create(contentType), fileName));
|
||||
} else if (inputStream != null) {
|
||||
builder.addPart("file", new InputStreamBody(inputStream, ContentType.create(contentType), fileName));
|
||||
}
|
||||
|
||||
httpPost.setEntity(builder.build());
|
||||
|
||||
HttpResponse response = AdminHttpUtils.getHttpClient().execute(httpPost);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
// 消耗响应体
|
||||
if (response.getEntity() != null) {
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
}
|
||||
|
||||
// 七牛云返回 200 表示成功
|
||||
if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED) {
|
||||
throw new Exception("文件上传到七牛云失败,HTTP状态码:" + statusCode);
|
||||
}
|
||||
|
||||
IMResult<String> imResult = new IMResult<>();
|
||||
imResult.setCode(0);
|
||||
imResult.setResult(presignedUrl.downloadUrl);
|
||||
return imResult;
|
||||
} finally {
|
||||
httpPost.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传到其他对象存储(type != 1)
|
||||
* 使用 PUT + 二进制流
|
||||
*/
|
||||
private static IMResult<String> uploadToOther(OutputPresignedUploadUrl presignedUrl, File file,
|
||||
InputStream inputStream, String contentType) throws Exception {
|
||||
HttpPut httpPut = new HttpPut(presignedUrl.uploadUrl);
|
||||
try {
|
||||
// 设置请求实体
|
||||
if (file != null) {
|
||||
FileEntity fileEntity = new FileEntity(file);
|
||||
fileEntity.setContentType(contentType);
|
||||
httpPut.setEntity(fileEntity);
|
||||
} else if (inputStream != null) {
|
||||
InputStreamEntity streamEntity = new InputStreamEntity(inputStream);
|
||||
streamEntity.setContentType(contentType);
|
||||
httpPut.setEntity(streamEntity);
|
||||
}
|
||||
|
||||
HttpResponse response = AdminHttpUtils.getHttpClient().execute(httpPut);
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
||||
// 消耗响应体,确保连接可以被复用
|
||||
if (response.getEntity() != null) {
|
||||
EntityUtils.consumeQuietly(response.getEntity());
|
||||
}
|
||||
|
||||
if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED) {
|
||||
throw new Exception("文件上传失败,HTTP状态码:" + statusCode);
|
||||
}
|
||||
|
||||
IMResult<String> imResult = new IMResult<>();
|
||||
imResult.setCode(0);
|
||||
imResult.setResult(presignedUrl.downloadUrl);
|
||||
return imResult;
|
||||
} finally {
|
||||
httpPut.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件(通过输入流)
|
||||
* <p>
|
||||
* 流程:先调用getPresignedUploadUrl获取预签名上传地址,然后直接上传文件。
|
||||
* 上传成功后返回文件的下载地址等信息。
|
||||
* </p>
|
||||
*
|
||||
* @param inputStream 文件输入流
|
||||
* @param fileName 文件名
|
||||
* @return 上传结果,包含下载地址
|
||||
* @throws Exception 上传失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> uploadFile(InputStream inputStream, String fileName) throws Exception {
|
||||
return uploadFile(inputStream, fileName, ProtoConstants.MessageMediaType.FILE, null);
|
||||
}
|
||||
/**
|
||||
* 上传文件(通过输入流)
|
||||
* <p>
|
||||
* 流程:先调用getPresignedUploadUrl获取预签名上传地址,然后直接上传文件。
|
||||
* 上传成功后返回文件的下载地址等信息。
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>注意:</b>无论上传成功还是失败,此方法都会关闭输入流。
|
||||
* </p>
|
||||
*
|
||||
* @param inputStream 文件输入流(此方法会关闭该流)
|
||||
* @param fileName 文件名
|
||||
* @param mediaType 媒体类型,参考{@link cn.wildfirechat.proto.ProtoConstants.MessageMediaType}
|
||||
* @param contentType 文件Content-Type,例如 "image/jpeg", "application/octet-stream" 等;
|
||||
* 如果为null或空,则根据文件名自动识别
|
||||
* @return 上传结果,包含下载地址
|
||||
* @throws Exception 上传失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> uploadFile(InputStream inputStream, String fileName,
|
||||
int mediaType, String contentType) throws Exception {
|
||||
if (inputStream == null) {
|
||||
throw new IllegalArgumentException("输入流不能为空");
|
||||
}
|
||||
|
||||
// 如果未指定Content-Type,根据文件名自动获取
|
||||
if (contentType == null || contentType.isEmpty()) {
|
||||
contentType = getContentTypeByFileName(fileName);
|
||||
}
|
||||
|
||||
return doUploadFile(fileName, mediaType, contentType, null, inputStream);
|
||||
// 注意:正常流程下的流关闭在 uploadToQiniu 或 uploadToOther 的 finally 块中处理
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,32 @@ import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 群组管理类
|
||||
* <p>
|
||||
* 提供群组管理相关的功能,包括:
|
||||
* <ul>
|
||||
* <li>群组的创建、解散、转移</li>
|
||||
* <li>群组信息修改</li>
|
||||
* <li>群组成员管理(添加、移除、踢出)</li>
|
||||
* <li>群组管理员设置</li>
|
||||
* <li>群组成员禁言</li>
|
||||
* <li>用户群组查询</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class GroupAdmin {
|
||||
/**
|
||||
* 创建群组
|
||||
* @param operator 操作者用户ID
|
||||
* @param group_info 群组信息
|
||||
* @param members 群组成员列表
|
||||
* @param member_extra 成员额外信息
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 创建结果,包含群组ID
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputCreateGroupResult> createGroup(String operator, PojoGroupInfo group_info, List<PojoGroupMember> members, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Create_Group;
|
||||
PojoGroup pojoGroup = new PojoGroup();
|
||||
@@ -24,6 +49,12 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, createGroup, OutputCreateGroupResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群组信息
|
||||
* @param groupId 群组ID
|
||||
* @return 群组信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoGroupInfo> getGroupInfo(String groupId) throws Exception {
|
||||
String path = APIPath.Group_Get_Info;
|
||||
InputGetGroup input = new InputGetGroup();
|
||||
@@ -32,11 +63,26 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, PojoGroupInfo.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量获取群组信息
|
||||
* @param groupIds 群组ID列表
|
||||
* @return 群组信息列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoGroupInfoList> batchGroupInfos(List<String> groupIds) throws Exception {
|
||||
String path = APIPath.Group_Batch_Info;
|
||||
return AdminHttpUtils.httpJsonPost(path, groupIds, PojoGroupInfoList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解散群组
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 解散结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> dismissGroup(String operator, String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Dismiss;
|
||||
InputDismissGroup dismissGroup = new InputDismissGroup();
|
||||
@@ -47,6 +93,16 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, dismissGroup, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转让群组
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param newOwner 新群主用户ID
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 转让结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> transferGroup(String operator, String groupId, String newOwner, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Transfer;
|
||||
InputTransferGroup transferGroup = new InputTransferGroup();
|
||||
@@ -58,6 +114,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, transferGroup, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改群组信息
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param type 修改信息类型(ModifyGroupInfoType)
|
||||
* @param value 新值
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 修改结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> modifyGroupInfo(String operator, String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Modify_Info;
|
||||
InputModifyGroupInfo modifyGroupInfo = new InputModifyGroupInfo();
|
||||
@@ -70,7 +137,12 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, modifyGroupInfo, Void.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取群组成员列表
|
||||
* @param groupId 群组ID
|
||||
* @return 群组成员列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGroupMemberList> getGroupMembers(String groupId) throws Exception {
|
||||
String path = APIPath.Group_Member_List;
|
||||
InputGetGroup input = new InputGetGroup();
|
||||
@@ -78,6 +150,13 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputGroupMemberList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群组成员信息
|
||||
* @param groupId 群组ID
|
||||
* @param memberId 成员用户ID
|
||||
* @return 群组成员信息
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<PojoGroupMember> getGroupMember(String groupId, String memberId) throws Exception {
|
||||
String path = APIPath.Group_Member_Get;
|
||||
InputGetGroupMember input = new InputGetGroupMember();
|
||||
@@ -86,6 +165,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, PojoGroupMember.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加群组成员
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param groupMembers 要添加的成员列表
|
||||
* @param member_extra 成员额外信息
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 添加结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> addGroupMembers(String operator, String groupId, List<PojoGroupMember> groupMembers, String member_extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Member_Add;
|
||||
InputAddGroupMember addGroupMember = new InputAddGroupMember();
|
||||
@@ -98,6 +188,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置或取消群组管理员
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param groupMemberIds 成员用户ID列表
|
||||
* @param isManager true-设置为管理员,false-取消管理员
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setGroupManager(String operator, String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Set_Manager;
|
||||
InputSetGroupManager addGroupMember = new InputSetGroupManager();
|
||||
@@ -110,6 +211,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁言或解禁群组成员
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param groupMemberIds 成员用户ID列表
|
||||
* @param isMute true-禁言,false-解禁
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 禁言结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> muteGroupMemeber(String operator, String groupId, List<String> groupMemberIds, boolean isMute, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Mute_Member;
|
||||
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
|
||||
@@ -122,6 +234,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 允许或禁止群组成员发言
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param groupMemberIds 成员用户ID列表
|
||||
* @param isAllow true-允许,false-禁止
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> allowGroupMemeber(String operator, String groupId, List<String> groupMemberIds, boolean isAllow, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Allow_Member;
|
||||
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
|
||||
@@ -134,6 +257,16 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 踢出群组成员
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param groupMemberIds 要踢出的成员用户ID列表
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 踢出结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> kickoffGroupMembers(String operator, String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Member_Kickoff;
|
||||
InputKickoffGroupMember kickoffGroupMember = new InputKickoffGroupMember();
|
||||
@@ -145,6 +278,15 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, kickoffGroupMember, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出群组
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 退出结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> quitGroup(String operator, String groupId, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Member_Quit;
|
||||
InputQuitGroup quitGroup = new InputQuitGroup();
|
||||
@@ -155,6 +297,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, quitGroup, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置群组成员别名
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param memberId 成员用户ID
|
||||
* @param alias 别名
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setGroupMemberAlias(String operator, String groupId, String memberId, String alias, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Set_Member_Alias;
|
||||
InputSetGroupMemberAlias input = new InputSetGroupMemberAlias();
|
||||
@@ -167,6 +320,17 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置群组成员额外信息
|
||||
* @param operator 操作者用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param memberId 成员用户ID
|
||||
* @param extra 额外信息
|
||||
* @param to_lines 消息同步到的线路列表
|
||||
* @param notify_message 通知消息
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setGroupMemberExtra(String operator, String groupId, String memberId, String extra, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
|
||||
String path = APIPath.Group_Set_Member_Extra;
|
||||
InputSetGroupMemberExtra input = new InputSetGroupMemberExtra();
|
||||
@@ -179,10 +343,25 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置群组备注(用户个性化设置)
|
||||
* @param userId 用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param remark 备注内容
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setGroupRemark(String userId, String groupId, String remark) throws Exception {
|
||||
return GeneralAdmin.setUserSetting(userId, 26, groupId, remark);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群组备注(用户个性化设置)
|
||||
* @param userId 用户ID
|
||||
* @param groupId 群组ID
|
||||
* @return 备注内容
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<String> getGroupRemark(String userId, String groupId) throws Exception {
|
||||
IMResult<UserSettingPojo> imResult = GeneralAdmin.getUserSetting(userId, 26, groupId);
|
||||
IMResult<String> result = new IMResult<>();
|
||||
@@ -194,10 +373,25 @@ public class GroupAdmin {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置群组是否收藏(用户个性化设置)
|
||||
* @param userId 用户ID
|
||||
* @param groupId 群组ID
|
||||
* @param fav true-收藏,false-取消收藏
|
||||
* @return 设置结果
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Void> setFavGroup(String userId, String groupId, boolean fav) throws Exception {
|
||||
return GeneralAdmin.setUserSetting(userId, 6, groupId, fav?"1":"0");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查群组是否收藏(用户个性化设置)
|
||||
* @param userId 用户ID
|
||||
* @param groupId 群组ID
|
||||
* @return true-已收藏,false-未收藏
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<Boolean> isFavGroup(String userId, String groupId) throws Exception {
|
||||
IMResult<UserSettingPojo> imResult = GeneralAdmin.getUserSetting(userId, 6, groupId);
|
||||
IMResult<Boolean> result = new IMResult<>();
|
||||
@@ -209,6 +403,12 @@ public class GroupAdmin {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的群组列表
|
||||
* @param user 用户ID
|
||||
* @return 用户所属的群组ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGroupIds> getUserGroups(String user) throws Exception {
|
||||
String path = APIPath.Get_User_Groups;
|
||||
InputUserId inputUserId = new InputUserId();
|
||||
@@ -216,12 +416,26 @@ public class GroupAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, inputUserId, OutputGroupIds.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据成员类型获取用户的群组列表
|
||||
* @param user 用户ID
|
||||
* @param groupMemberType 群组成员类型列表(GroupMemberType)
|
||||
* @return 用户所属的群组ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGroupIds> getUserGroupsByType(String user, List</*ProtoConstants.GroupMemberType*/Integer> groupMemberType) throws Exception {
|
||||
String path = APIPath.Get_User_Groups_By_Type;
|
||||
InputGetUserGroupByType input = new InputGetUserGroupByType(user, groupMemberType);
|
||||
return AdminHttpUtils.httpJsonPost(path, input, OutputGroupIds.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取两个用户的共同群组
|
||||
* @param user1 用户1的ID
|
||||
* @param user2 用户2的ID
|
||||
* @return 共同群组ID列表
|
||||
* @throws Exception 请求失败时抛出异常
|
||||
*/
|
||||
public static IMResult<OutputGroupIds> getCommonGroups(String user1, String user2) throws Exception {
|
||||
String path = APIPath.Get_Common_Groups;
|
||||
StringPairPojo intput = new StringPairPojo(user1, user2);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user