Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88d764fb6d | ||
|
|
08b3886238 | ||
|
|
7e73c2880b | ||
|
|
1359ce5250 | ||
|
|
56eaf938a8 | ||
|
|
6ef6ed2906 | ||
|
|
63f37e8984 | ||
|
|
337302c551 | ||
|
|
721f27a58a |
@@ -44,7 +44,8 @@
|
||||
| [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](https://github.com/wildfirechat/vue-pc-chat) | [pc-chat](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)的PC 端,支持Windows、Mac、Linux(包括国产化linux系统和CPU)。 |
|
||||
| [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平台移动端应用(使用原生插件)。 |
|
||||
|
||||
@@ -248,6 +248,10 @@ group.visible_quit_or_kickoff_notification 0
|
||||
## 是否禁止陌生人拉人入群,默认为false
|
||||
group.disable_stranger_invite false
|
||||
|
||||
## 创建群组或者加人时。可能会有成员加入失败(黑名单,或者不允许陌生人拉入群)。当出现有成员失败时,如果此开关为关,操作会失败。
|
||||
## 如果此开关打开,操作会返回成功,另外在群里发送一条通知消息 XXX 拒绝加入群组。默认为开。
|
||||
group.add_member_allow_part_success true
|
||||
|
||||
## 群组信息是否标记删除
|
||||
group.enable_mark_deletion true
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
|
||||
@@ -37,6 +37,7 @@ public class PushMessage {
|
||||
public boolean republish;
|
||||
public long messageId;
|
||||
public long callStartUid;
|
||||
public int existBadgeNumber;
|
||||
|
||||
public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) {
|
||||
this.sender = sender;
|
||||
|
||||
@@ -81,10 +81,6 @@ public class PushServer {
|
||||
}
|
||||
|
||||
MemorySessionStore.Session session = sessionsStore.getSession(deviceId);
|
||||
int badge = session.getUnReceivedMsgs();
|
||||
if (badge <= 0) {
|
||||
badge = 1;
|
||||
}
|
||||
if (StringUtil.isNullOrEmpty(session.getDeviceToken())) {
|
||||
LOG.warn("Device token is empty for device {}", deviceId);
|
||||
return;
|
||||
@@ -94,7 +90,6 @@ public class PushServer {
|
||||
pushMessage.pushType = session.getPushType();
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.deviceToken = session.getDeviceToken();
|
||||
pushMessage.unReceivedMsg = badge;
|
||||
pushMessage.userId = session.getUsername();
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_iPad ||
|
||||
|
||||
@@ -284,9 +284,10 @@ public class UploadFileAction extends Action {
|
||||
|
||||
savedThunkSize += readableBytesSize;
|
||||
offset += readableBytesSize;
|
||||
byteBuf.release();
|
||||
byteBuf = null;
|
||||
|
||||
if (savedThunkSize >= remoteFileSize) {
|
||||
byteBuf.release();
|
||||
fileUpload.release();
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
|
||||
@@ -205,6 +205,7 @@ public final class BrokerConstants {
|
||||
public static final String GROUP_Forbidden_Client_Operation = "group.forbidden_client_operation";
|
||||
|
||||
public static final String GROUP_Disable_Stranger_Invite = "group.disable_stranger_invite";
|
||||
public static final String GROUP_ADD_MEMBER_ALLOW_PART_SUCCESS = "group.add_member_allow_part_success";
|
||||
|
||||
public static final String GROUP_INFO_MARK_DELETION = "group.enable_mark_deletion";
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(value = IMTopic.AddGroupMemberTopic)
|
||||
@@ -38,16 +42,34 @@ public class AddGroupMember extends GroupHandler<WFCMessage.AddGroupMemberReques
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.addGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getAddedMemberList(), request.getExtra());
|
||||
Map<String, Integer> failedMembers = new HashMap<>();
|
||||
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) {
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getAddedMemberList(), failedMembers);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.addGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getAddedMemberList(), request.getExtra(), failedMembers);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).setExtra(request.getExtra()).getAddGroupNotifyContent();
|
||||
List<String> added = getMemberIdList(request.getAddedMemberList());
|
||||
added.removeAll(failedMembers.keySet());
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, added).setExtra(request.getExtra()).getAddGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCode == ERROR_CODE_SUCCESS && !failedMembers.isEmpty()) {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").setMi(failedMembers).getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_REJECT_JOIN_GROUP);
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if(errorCode == ERROR_CODE_SUCCESS && !failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_PARTLY_SUCCESS;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Handler(value = IMTopic.CreateGroupTopic)
|
||||
public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupRequest> {
|
||||
@Override
|
||||
@@ -51,14 +54,21 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> failedMembers = new HashMap<>();
|
||||
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) {
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getGroup().getMembersList());
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getGroup().getMembersList(), failedMembers);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin);
|
||||
if (request.getGroup().getGroupInfo().getTargetId().length() > 64
|
||||
|| request.getGroup().getGroupInfo().getName().length() > 64
|
||||
|| request.getGroup().getGroupInfo().getPortrait().length() > 1024) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin, failedMembers);
|
||||
if (groupInfo != null && groupInfo.getDeleted() == 0) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
@@ -66,9 +76,19 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").setExtra(request.getMemberExtra()).getCreateGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if(!failedMembers.isEmpty()) {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, null, "").setMi(failedMembers).getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_REJECT_JOIN_GROUP);
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] data = groupInfo.getTargetId().getBytes();
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
if(failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_PARTLY_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
public class UserSearchHandler extends IMHandler<WFCMessage.SearchUserRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.SearchUserRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
List<WFCMessage.User> users = m_messagesStore.searchUser(request.getKeyword(), request.getFuzzy(), request.getPage());
|
||||
List<WFCMessage.User> users = m_messagesStore.searchUser(request.getKeyword(), request.getFuzzy(), request.getType(), request.getPage());
|
||||
WFCMessage.SearchUserResult.Builder builder = WFCMessage.SearchUserResult.newBuilder();
|
||||
builder.addAllEntry(users);
|
||||
byte[] data = builder.build().toByteArray();
|
||||
|
||||
@@ -36,6 +36,8 @@ import java.util.function.Function;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.UserSearchUserType.UserSearchUserType_ONLY_ROBOT;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.UserSearchUserType.UserSearchUserType_ONLY_USER;
|
||||
import static io.moquette.BrokerConstants.GROUP_INFO_MARK_DELETION;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
|
||||
@@ -169,7 +171,7 @@ public class DatabaseStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserByNameMobileUserId(String keyword, int searchType) {
|
||||
List<WFCMessage.User> searchUserByNameMobileUserId(String keyword, int searchType, int userType) {
|
||||
ArrayList<WFCMessage.User> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -203,7 +205,15 @@ public class DatabaseStore {
|
||||
sql += " where (`_name` = ? or `_mobile` = ? or `_uid` = ?) ";
|
||||
}
|
||||
|
||||
sql += " and `_type` <> 2 and `_deleted` = 0"; //can search normal user(0) and robot(1) and admin(100), can not search things
|
||||
if(userType == UserSearchUserType_ONLY_USER) {
|
||||
sql += " and _type <> 2 "; //can not search device
|
||||
sql += " and _type <> 1 ";
|
||||
} else if(userType == UserSearchUserType_ONLY_ROBOT) {
|
||||
sql += " and _type = 1 ";
|
||||
} else {
|
||||
sql += " and _type <> 2 "; //can not search device
|
||||
}
|
||||
sql += " and _deleted = 0 ";
|
||||
|
||||
if(searchType == SearchUserType_Name || searchType == SearchUserType_Mobile || searchType == SearchUserType_UserId) {
|
||||
sql += " limit 1";
|
||||
@@ -408,7 +418,7 @@ public class DatabaseStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserByDisplayName(String keyword, int page, List<WFCMessage.User> nameOrIdMatched) {
|
||||
List<WFCMessage.User> searchUserByDisplayName(String keyword, int userType, int page, List<WFCMessage.User> nameOrIdMatched) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
@@ -419,7 +429,18 @@ public class DatabaseStore {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select u._uid, u._name, u._display_name, u._portrait, u._mobile, u._gender, u._email, u._address, u._company, u._social, u._extra, u._dt, u._type " +
|
||||
" from t_user u left join (select _uid, _value from t_user_setting where _scope = 27) s on u._uid = s._uid " +
|
||||
" where u._display_name like ? ESCAPE '!' and u._type <> 2 and u._deleted = 0 ";
|
||||
" where u._display_name like ? ESCAPE '!' ";
|
||||
|
||||
if(userType == UserSearchUserType_ONLY_USER) {
|
||||
sql += " and u._type <> 2 ";
|
||||
sql += " and u._type <> 1 ";
|
||||
} else if(userType == UserSearchUserType_ONLY_ROBOT) {
|
||||
sql += " and u._type = 1 ";
|
||||
} else {
|
||||
sql += " and u._type <> 2 ";
|
||||
}
|
||||
sql += " and u._deleted = 0 ";
|
||||
|
||||
if(nameOrIdMatched.size() == 1) {
|
||||
sql += " and u._uid <> ? and u._name <> ?";
|
||||
} else if(nameOrIdMatched.size() == 2) {
|
||||
@@ -523,15 +544,15 @@ public class DatabaseStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) {
|
||||
List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobileUserId(keyword, searchType);
|
||||
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int userType, int page) {
|
||||
List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobileUserId(keyword, searchType, userType);
|
||||
List<WFCMessage.User> out = new ArrayList<>();
|
||||
if(page == 0) {
|
||||
out.addAll(nameOrIdMatched);
|
||||
}
|
||||
|
||||
if(searchType == SearchUserType_General || searchType == SearchUserType_Name_Mobile_DisplayName) {
|
||||
List<WFCMessage.User> general = searchUserByDisplayName(keyword, page, nameOrIdMatched);
|
||||
List<WFCMessage.User> general = searchUserByDisplayName(keyword, userType, page, nameOrIdMatched);
|
||||
general.removeAll(nameOrIdMatched);
|
||||
out.addAll(general);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
@@ -167,6 +168,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private Set<String> mAllowStrangerChatSet = new HashSet<>();
|
||||
private Set<Integer> mAllowStrangerLineSet = new HashSet<>();
|
||||
private boolean mDisableStrangerAddGroup = false;
|
||||
private boolean mGroupAllowPartSuccess = false;
|
||||
|
||||
private boolean mIDUseUUID = true;
|
||||
|
||||
@@ -630,6 +632,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
mGroupAllowPartSuccess = "true".equals(server.getConfig().getProperty(BrokerConstants.GROUP_ADD_MEMBER_ALLOW_PART_SUCCESS, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
@@ -838,6 +845,18 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return pullType;
|
||||
}
|
||||
|
||||
private final Map<String, Integer> unreceivedMsgCount = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void increaseUnreceivedMsgCount(String user) {
|
||||
unreceivedMsgCount.compute(user, (s, integer) -> integer == null ? 1 : integer+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnreceivedMsgCount(String user) {
|
||||
return unreceivedMsgCount.getOrDefault(user, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllEnds() {
|
||||
return databaseStore.getAllEnds(mBroadcastTargetFromUserTable);
|
||||
@@ -852,7 +871,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
MemorySessionStore.Session session = m_Server.getStore().sessionsStore().getSession(exceptClientId);
|
||||
session.refreshLastActiveTime();
|
||||
if (pullType != ProtoConstants.PullType.Pull_ChatRoom) {
|
||||
session.setUnReceivedMsgs(0);
|
||||
unreceivedMsgCount.put(user, 0);
|
||||
} else {
|
||||
session.refreshLastChatroomActiveTime();
|
||||
}
|
||||
@@ -1282,7 +1301,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode canAddGroupMembers(String fromUser, List<WFCMessage.GroupMember> memberList) {
|
||||
public ErrorCode canAddGroupMembers(String fromUser, List<WFCMessage.GroupMember> memberList, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
|
||||
@@ -1308,7 +1327,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
for (FriendData friendData : friendDatas) {
|
||||
if (friendData.getFriendUid().equals(fromUser)) {
|
||||
if (friendData.getBlacked() == 1) {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
LOG.error("Add group member failure, because inviter {} is blocked by invitee {}", fromUser, targetUser);
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 1); //black
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
}
|
||||
} else {
|
||||
if (friendData.getState() == 0) {
|
||||
allow = true;
|
||||
@@ -1332,7 +1356,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
continue;
|
||||
}
|
||||
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 2);//stranger
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (WFCMessage.GroupMember groupMember : memberList) {
|
||||
@@ -1349,7 +1377,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
for (FriendData friendData : friendDatas) {
|
||||
if (friendData.getFriendUid().equals(fromUser)) {
|
||||
if (friendData.getBlacked() == 1) {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
LOG.error("Add group member failure, because inviter {} is blocked by invitee {}", fromUser, targetUser);
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 1); //black
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -1361,7 +1394,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WFCMessage.GroupInfo createGroup(String fromUser, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin) {
|
||||
public WFCMessage.GroupInfo createGroup(String fromUser, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
|
||||
@@ -1383,6 +1416,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
List<WFCMessage.GroupMember> updatedMemberList = new ArrayList<>();
|
||||
boolean hasOwnerMember = false;
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
WFCMessage.GroupMember.Builder builder = member.toBuilder();
|
||||
builder.setUpdateDt(dt).setCreateDt(dt);
|
||||
if (member.getMemberId().equals(owner)) {
|
||||
@@ -1577,7 +1613,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra) {
|
||||
public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
|
||||
@@ -1650,6 +1686,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
List<WFCMessage.GroupMember> tmp = new ArrayList<>();
|
||||
int newMemberCount = 0;
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existMemberIds.contains(member.getMemberId()) && member.getType() != GroupMemberType_Removed) {
|
||||
if(!isAdmin)
|
||||
continue;
|
||||
@@ -1682,7 +1722,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
if (memberList.size() == 0) {
|
||||
if (!isAdmin) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
|
||||
if(failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
@@ -1701,6 +1745,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
List<String> memberIds = new ArrayList<>();
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member.getType() != GroupMemberType_Removed) {
|
||||
memberIds.add(member.getMemberId());
|
||||
}
|
||||
@@ -3109,7 +3157,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> searchUser(String keyword, int searchType, int page) {
|
||||
public List<WFCMessage.User> searchUser(String keyword, int searchType, int userType, int page) {
|
||||
if (mDisableSearch) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
@@ -3130,7 +3178,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return databaseStore.searchUserFromDB(keyword, searchType, page);
|
||||
return databaseStore.searchUserFromDB(keyword, searchType, userType, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4748,6 +4796,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mGroupVisibleQuitKickoffNotification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupAllowPartSuccess() {
|
||||
return mGroupAllowPartSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupForbiddenClientOperation() {
|
||||
return mGroupForbiddenClientOperation;
|
||||
|
||||
@@ -92,10 +92,6 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return unReceivedMsgs;
|
||||
}
|
||||
|
||||
public void setUnReceivedMsgs(int unReceivedMsgs) {
|
||||
this.unReceivedMsgs = unReceivedMsgs;
|
||||
}
|
||||
|
||||
public int getPushType() {
|
||||
return pushType;
|
||||
}
|
||||
|
||||
@@ -102,9 +102,9 @@ public interface IMessagesStore {
|
||||
WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType);
|
||||
WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count, Collection<Integer> contentTypes);
|
||||
long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId, boolean directing);
|
||||
ErrorCode canAddGroupMembers(String operator, List<WFCMessage.GroupMember> memberList);
|
||||
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin);
|
||||
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra);
|
||||
ErrorCode canAddGroupMembers(String operator, List<WFCMessage.GroupMember> memberList, Map<String, Integer> failedMembers);
|
||||
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin, Map<String, Integer> failedMembers);
|
||||
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra, Map<String, Integer> failedMembers);
|
||||
ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList);
|
||||
ErrorCode quitGroup(String operator, String groupId, boolean admin);
|
||||
void clearUserGroups(String userId);
|
||||
@@ -154,7 +154,7 @@ public interface IMessagesStore {
|
||||
WFCMessage.User getUserInfoByName(String name);
|
||||
WFCMessage.User getUserInfoByMobile(String mobile);
|
||||
List<WFCMessage.User> getUserInfosByEmail(String email);
|
||||
List<WFCMessage.User> searchUser(String keyword, int searchType, int page);
|
||||
List<WFCMessage.User> searchUser(String keyword, int searchType, int userType, int page);
|
||||
|
||||
List<WFCMessage.User> getUserInfoList(int count, int offset);
|
||||
|
||||
@@ -235,6 +235,9 @@ public interface IMessagesStore {
|
||||
|
||||
WFCMessage.Message getMessage(long messageId);
|
||||
|
||||
void increaseUnreceivedMsgCount(String user);
|
||||
int getUnreceivedMsgCount(String user);
|
||||
|
||||
boolean isAllowClientCustomGroupNotification();
|
||||
boolean isAllowRobotCustomGroupNotification();
|
||||
int getVisibleQuitKickoffNotification();
|
||||
@@ -253,7 +256,7 @@ public interface IMessagesStore {
|
||||
boolean isChannelCallbackWithSenderInfo();
|
||||
boolean isChannelCallbackWithTargetInfo();
|
||||
boolean isChannelNewCallbackFeature();
|
||||
|
||||
boolean isGroupAllowPartSuccess();
|
||||
boolean isRobotAutoAcceptFriendRequest();
|
||||
|
||||
long getPushExpiredTimes();
|
||||
|
||||
@@ -178,19 +178,10 @@ public class MessagesPublisher {
|
||||
if (message == null) {
|
||||
message = m_messagesStore.getMessage(messageId);
|
||||
}
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isRobotCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(sender)) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isRobotCallbackWithClientInfo() , m_messagesStore.isRobotCallbackWithSenderInfo(), m_messagesStore.isRobotCallbackWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(finalMsg, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -324,7 +315,7 @@ public class MessagesPublisher {
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
|
||||
if (!isConvSilent && (persistFlag & 0x02) > 0) {
|
||||
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
|
||||
m_messagesStore.increaseUnreceivedMsgCount(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -423,13 +414,25 @@ public class MessagesPublisher {
|
||||
name = fd.getAlias();
|
||||
}
|
||||
}
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, callStartUid, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, callStartUid, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, m_messagesStore.getUnreceivedMsgCount(user), curMentionType, isHiddenDetail, targetSession.getLanguage(), getExistBadgeNumber(user));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int getExistBadgeNumber(String user) {
|
||||
int existBadgeNumber = 0;
|
||||
WFCMessage.UserSettingEntry userSettingData = m_messagesStore.getUserSetting(user, UserSettingScope.kUserSettingScopeSyncBadge, "");
|
||||
if(userSettingData != null && !StringUtil.isNullOrEmpty(userSettingData.getValue())) {
|
||||
try {
|
||||
existBadgeNumber = Integer.parseInt(userSettingData.getValue());
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
return existBadgeNumber;
|
||||
}
|
||||
|
||||
public boolean sendOfflineNotify(String clientId) {
|
||||
boolean targetIsActive = this.connectionDescriptors.isConnected(clientId);
|
||||
if (targetIsActive) {
|
||||
@@ -595,7 +598,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
if (IMTopic.NotifyFriendRequestTopic.equals(topic)) {
|
||||
messageSender.sendPush(fromUser, receiver, targetSession.getClientID(), pushContent, PushServer.PushMessageType.PUSH_MESSAGE_TYPE_FRIEND_REQUEST, System.currentTimeMillis(), fromUserName, targetSession.getUnReceivedMsgs() + 1, targetSession.getLanguage());
|
||||
messageSender.sendPush(fromUser, receiver, targetSession.getClientID(), pushContent, PushServer.PushMessageType.PUSH_MESSAGE_TYPE_FRIEND_REQUEST, System.currentTimeMillis(), fromUserName, m_messagesStore.getUnreceivedMsgCount(receiver) + 1, targetSession.getLanguage(), getExistBadgeNumber(receiver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,17 +37,18 @@ class PersistentQueueMessageSender {
|
||||
this.connectionDescriptorStore = connectionDescriptorStore;
|
||||
}
|
||||
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, long callStartUid, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, long callStartUid, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language, int existBadgeNumber) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, senderPortrait, targetName, targetPortrait, unReceivedMsg, mentionType, isHiddenDetail, language);
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.pushData = pushData;
|
||||
pushMessage.messageId = messageId;
|
||||
pushMessage.callStartUid = callStartUid;
|
||||
pushMessage.existBadgeNumber = existBadgeNumber;
|
||||
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
|
||||
}
|
||||
|
||||
void sendPush(String sender, String target, String deviceId, String pushContent, int pushContentType, long serverTime, String senderName, int unReceivedMsg, String language) {
|
||||
void sendPush(String sender, String target, String deviceId, String pushContent, int pushContentType, long serverTime, String senderName, int unReceivedMsg, String language, int existBadgeNumber) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, target, serverTime, senderName, unReceivedMsg, language, pushContentType);
|
||||
pushMessage.pushContent = pushContent;
|
||||
|
||||
@@ -21,4 +21,5 @@ public interface UserSettingScope {
|
||||
int kUserSettingGroupRemark = 26;
|
||||
int kUserSettingPrivacySearchable = 27;
|
||||
int kUserSettingAddFriendStrategy = 28;
|
||||
int kUserSettingScopeSyncBadge = 29;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ public enum ErrorCode {
|
||||
ERROR_CODE_CONFERENCE_ERROR(90, "Conference server response error"),
|
||||
|
||||
ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"),
|
||||
ERROR_CODE_SERVER_BUSY(221, "Server busy"),
|
||||
ERROR_CODE_PARTLY_SUCCESS(222, "Partly success"),
|
||||
|
||||
ERROR_CODE_OTHER_CLIENT_ALREADY_IN_CHATROOM(225, "other client already in chatroom"),
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.protobuf.ByteString;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GroupNotificationBinaryContent {
|
||||
//groupId
|
||||
@@ -33,6 +34,8 @@ public class GroupNotificationBinaryContent {
|
||||
//value2(member or something)
|
||||
private String m;
|
||||
|
||||
private Map<String, Integer> mi;
|
||||
|
||||
private String extra;
|
||||
|
||||
public GroupNotificationBinaryContent() {
|
||||
@@ -92,6 +95,11 @@ public class GroupNotificationBinaryContent {
|
||||
this.ms = ms;
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent setMi(Map<String, Integer> mi) {
|
||||
this.mi = mi;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
return this;
|
||||
|
||||
@@ -3,6 +3,7 @@ package cn.wildfirechat.pojos.mesh;
|
||||
public class PojoSearchUserReq {
|
||||
public String keyword;
|
||||
public int searchType;
|
||||
public int userType;
|
||||
public int page;
|
||||
public String domainId;
|
||||
|
||||
@@ -22,6 +23,14 @@ public class PojoSearchUserReq {
|
||||
this.searchType = searchType;
|
||||
}
|
||||
|
||||
public int getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
public void setUserType(int userType) {
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
@@ -238,6 +238,12 @@ public class ProtoConstants {
|
||||
int SearchUserType_Name_Mobile_DisplayName = 100;
|
||||
}
|
||||
|
||||
public interface UserSearchUserType {
|
||||
int UserSearchUserType_ALL = 0;
|
||||
int UserSearchUserType_ONLY_USER = 1;
|
||||
int UserSearchUserType_ONLY_ROBOT = 2;
|
||||
}
|
||||
|
||||
public interface DisableSearchMask {
|
||||
int DisableSearchDisplayNameMask = 1;
|
||||
int DisableSearchNameMask = 2;
|
||||
@@ -390,5 +396,7 @@ public class ProtoConstants {
|
||||
|
||||
public static final int MESSAGE_CONTENT_TYPE_MODIFY_GROUP_EXTRA = 122;
|
||||
public static final int MESSAGE_CONTENT_TYPE_MODIFY_GROUP_MEMBER_EXTRA = 123;
|
||||
public static final int MESSAGE_CONTENT_TYPE_MODIFY_GROUP_SETTINGS = 124;
|
||||
public static final int MESSAGE_CONTENT_TYPE_REJECT_JOIN_GROUP = 125;
|
||||
}
|
||||
|
||||
|
||||
@@ -54041,6 +54041,31 @@ public final class WFCMessage {
|
||||
* <code>optional int32 page = 3;</code>
|
||||
*/
|
||||
int getPage();
|
||||
|
||||
// optional string domain_id = 4;
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
boolean hasDomainId();
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
java.lang.String getDomainId();
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getDomainIdBytes();
|
||||
|
||||
// optional int32 type = 5;
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
boolean hasType();
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
int getType();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code SearchUserRequest}
|
||||
@@ -54108,6 +54133,16 @@ public final class WFCMessage {
|
||||
page_ = input.readInt32();
|
||||
break;
|
||||
}
|
||||
case 34: {
|
||||
bitField0_ |= 0x00000008;
|
||||
domainId_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
bitField0_ |= 0x00000010;
|
||||
type_ = input.readInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
@@ -54223,10 +54258,71 @@ public final class WFCMessage {
|
||||
return page_;
|
||||
}
|
||||
|
||||
// optional string domain_id = 4;
|
||||
public static final int DOMAIN_ID_FIELD_NUMBER = 4;
|
||||
private java.lang.Object domainId_;
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public boolean hasDomainId() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public java.lang.String getDomainId() {
|
||||
java.lang.Object ref = domainId_;
|
||||
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()) {
|
||||
domainId_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getDomainIdBytes() {
|
||||
java.lang.Object ref = domainId_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
domainId_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// optional int32 type = 5;
|
||||
public static final int TYPE_FIELD_NUMBER = 5;
|
||||
private int type_;
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public boolean hasType() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public int getType() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
keyword_ = "";
|
||||
fuzzy_ = 0;
|
||||
page_ = 0;
|
||||
domainId_ = "";
|
||||
type_ = 0;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@@ -54253,6 +54349,12 @@ public final class WFCMessage {
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeInt32(3, page_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeBytes(4, getDomainIdBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeInt32(5, type_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@@ -54274,6 +54376,14 @@ public final class WFCMessage {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(3, page_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(4, getDomainIdBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(5, type_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
@@ -54396,6 +54506,10 @@ public final class WFCMessage {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
page_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
domainId_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
type_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -54436,6 +54550,14 @@ public final class WFCMessage {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.page_ = page_;
|
||||
if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.domainId_ = domainId_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.type_ = type_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
@@ -54463,6 +54585,14 @@ public final class WFCMessage {
|
||||
if (other.hasPage()) {
|
||||
setPage(other.getPage());
|
||||
}
|
||||
if (other.hasDomainId()) {
|
||||
bitField0_ |= 0x00000008;
|
||||
domainId_ = other.domainId_;
|
||||
onChanged();
|
||||
}
|
||||
if (other.hasType()) {
|
||||
setType(other.getType());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
@@ -54634,6 +54764,113 @@ public final class WFCMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional string domain_id = 4;
|
||||
private java.lang.Object domainId_ = "";
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public boolean hasDomainId() {
|
||||
return ((bitField0_ & 0x00000008) == 0x00000008);
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public java.lang.String getDomainId() {
|
||||
java.lang.Object ref = domainId_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
domainId_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (java.lang.String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getDomainIdBytes() {
|
||||
java.lang.Object ref = domainId_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
domainId_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public Builder setDomainId(
|
||||
java.lang.String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000008;
|
||||
domainId_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public Builder clearDomainId() {
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
domainId_ = getDefaultInstance().getDomainId();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional string domain_id = 4;</code>
|
||||
*/
|
||||
public Builder setDomainIdBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000008;
|
||||
domainId_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional int32 type = 5;
|
||||
private int type_ ;
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public boolean hasType() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public int getType() {
|
||||
return type_;
|
||||
}
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public Builder setType(int value) {
|
||||
bitField0_ |= 0x00000010;
|
||||
type_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional int32 type = 5;</code>
|
||||
*/
|
||||
public Builder clearType() {
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
type_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:SearchUserRequest)
|
||||
}
|
||||
|
||||
@@ -67604,44 +67841,45 @@ public final class WFCMessage {
|
||||
"ead\030\004 \001(\003\022\021\n\tnode_addr\030\005 \001(\t\022\021\n\tnode_por" +
|
||||
"t\030\006 \001(\005\022\023\n\013server_time\030\007 \001(\003\"P\n\rIMHttpWr",
|
||||
"apper\022\r\n\005token\030\001 \002(\t\022\021\n\tclient_id\030\002 \002(\t\022" +
|
||||
"\017\n\007request\030\003 \002(\t\022\014\n\004data\030\004 \001(\014\"A\n\021Search" +
|
||||
"\017\n\007request\030\003 \002(\t\022\014\n\004data\030\004 \001(\014\"b\n\021Search" +
|
||||
"UserRequest\022\017\n\007keyword\030\001 \002(\t\022\r\n\005fuzzy\030\002 " +
|
||||
"\001(\005\022\014\n\004page\030\003 \001(\005\"(\n\020SearchUserResult\022\024\n" +
|
||||
"\005entry\030\001 \003(\0132\005.User\"@\n\026GetChatroomInfoRe" +
|
||||
"quest\022\023\n\013chatroom_id\030\001 \002(\t\022\021\n\tupdate_dt\030" +
|
||||
"\002 \001(\003\"\227\001\n\014ChatroomInfo\022\r\n\005title\030\001 \002(\t\022\014\n" +
|
||||
"\004desc\030\002 \001(\t\022\020\n\010portrait\030\003 \001(\t\022\024\n\014member_" +
|
||||
"count\030\004 \001(\005\022\021\n\tcreate_dt\030\005 \001(\003\022\021\n\tupdate" +
|
||||
"_dt\030\006 \001(\003\022\r\n\005extra\030\007 \001(\t\022\r\n\005state\030\010 \001(\005\"",
|
||||
"F\n\034GetChatroomMemberInfoRequest\022\023\n\013chatr" +
|
||||
"oom_id\030\001 \002(\t\022\021\n\tmax_count\030\002 \001(\005\";\n\022Chatr" +
|
||||
"oomMemberInfo\022\024\n\014member_count\030\001 \001(\005\022\017\n\007m" +
|
||||
"embers\030\002 \003(\t\"\026\n\010INT64Buf\022\n\n\002id\030\001 \002(\003\"4\n\023" +
|
||||
"NotifyRecallMessage\022\n\n\002id\030\001 \002(\003\022\021\n\tfrom_" +
|
||||
"user\030\002 \002(\t\"/\n\020BlackUserRequest\022\013\n\003uid\030\001 " +
|
||||
"\002(\t\022\016\n\006status\030\002 \002(\005\"\323\001\n\014RouteRequest\022\013\n\003" +
|
||||
"app\030\001 \001(\t\022\020\n\010platform\030\002 \001(\005\022\021\n\tpush_type" +
|
||||
"\030\003 \001(\005\022\023\n\013device_name\030\004 \001(\t\022\026\n\016device_ve" +
|
||||
"rsion\030\005 \001(\t\022\022\n\nphone_name\030\006 \001(\t\022\020\n\010langu",
|
||||
"age\030\007 \001(\t\022\024\n\014carrier_name\030\010 \001(\t\022\023\n\013app_v" +
|
||||
"ersion\030\t \001(\t\022\023\n\013sdk_version\030\n \001(\t\"D\n\rRou" +
|
||||
"teResponse\022\014\n\004host\030\001 \002(\t\022\021\n\tlong_port\030\002 " +
|
||||
"\002(\005\022\022\n\nshort_port\030\003 \002(\005\"G\n\017GetTokenReque" +
|
||||
"st\022\017\n\007user_id\030\001 \002(\t\022\021\n\tclient_id\030\002 \002(\t\022\020" +
|
||||
"\n\010platform\030\003 \001(\005\"r\n\022LoadRemoteMessages\022#" +
|
||||
"\n\014conversation\030\001 \002(\0132\r.Conversation\022\022\n\nb" +
|
||||
"efore_uid\030\002 \002(\003\022\r\n\005count\030\003 \002(\005\022\024\n\014conten" +
|
||||
"t_type\030\004 \003(\005\"a\n\020MultiCastMessage\022\021\n\tfrom" +
|
||||
"_user\030\001 \002(\t\022 \n\007content\030\002 \002(\0132\017.MessageCo",
|
||||
"ntent\022\n\n\002to\030\003 \003(\t\022\014\n\004line\030\004 \002(\005\"E\n\035Recal" +
|
||||
"lMultiCastMessageRequest\022\022\n\nmessage_id\030\001" +
|
||||
" \002(\003\022\020\n\010receiver\030\002 \003(\t\"@\n\017AuthCodeReques" +
|
||||
"t\022\021\n\ttarget_id\030\001 \002(\t\022\014\n\004type\030\002 \002(\005\022\014\n\004ho" +
|
||||
"st\030\003 \002(\t\"o\n\030ApplicationConfigRequest\022\r\n\005" +
|
||||
"appId\030\001 \002(\t\022\017\n\007appType\030\002 \002(\005\022\021\n\ttimestam" +
|
||||
"p\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;proto"
|
||||
"\001(\005\022\014\n\004page\030\003 \001(\005\022\021\n\tdomain_id\030\004 \001(\t\022\014\n\004" +
|
||||
"type\030\005 \001(\005\"(\n\020SearchUserResult\022\024\n\005entry\030" +
|
||||
"\001 \003(\0132\005.User\"@\n\026GetChatroomInfoRequest\022\023" +
|
||||
"\n\013chatroom_id\030\001 \002(\t\022\021\n\tupdate_dt\030\002 \001(\003\"\227" +
|
||||
"\001\n\014ChatroomInfo\022\r\n\005title\030\001 \002(\t\022\014\n\004desc\030\002" +
|
||||
" \001(\t\022\020\n\010portrait\030\003 \001(\t\022\024\n\014member_count\030\004" +
|
||||
" \001(\005\022\021\n\tcreate_dt\030\005 \001(\003\022\021\n\tupdate_dt\030\006 \001",
|
||||
"(\003\022\r\n\005extra\030\007 \001(\t\022\r\n\005state\030\010 \001(\005\"F\n\034GetC" +
|
||||
"hatroomMemberInfoRequest\022\023\n\013chatroom_id\030" +
|
||||
"\001 \002(\t\022\021\n\tmax_count\030\002 \001(\005\";\n\022ChatroomMemb" +
|
||||
"erInfo\022\024\n\014member_count\030\001 \001(\005\022\017\n\007members\030" +
|
||||
"\002 \003(\t\"\026\n\010INT64Buf\022\n\n\002id\030\001 \002(\003\"4\n\023NotifyR" +
|
||||
"ecallMessage\022\n\n\002id\030\001 \002(\003\022\021\n\tfrom_user\030\002 " +
|
||||
"\002(\t\"/\n\020BlackUserRequest\022\013\n\003uid\030\001 \002(\t\022\016\n\006" +
|
||||
"status\030\002 \002(\005\"\323\001\n\014RouteRequest\022\013\n\003app\030\001 \001" +
|
||||
"(\t\022\020\n\010platform\030\002 \001(\005\022\021\n\tpush_type\030\003 \001(\005\022" +
|
||||
"\023\n\013device_name\030\004 \001(\t\022\026\n\016device_version\030\005",
|
||||
" \001(\t\022\022\n\nphone_name\030\006 \001(\t\022\020\n\010language\030\007 \001" +
|
||||
"(\t\022\024\n\014carrier_name\030\010 \001(\t\022\023\n\013app_version\030" +
|
||||
"\t \001(\t\022\023\n\013sdk_version\030\n \001(\t\"D\n\rRouteRespo" +
|
||||
"nse\022\014\n\004host\030\001 \002(\t\022\021\n\tlong_port\030\002 \002(\005\022\022\n\n" +
|
||||
"short_port\030\003 \002(\005\"G\n\017GetTokenRequest\022\017\n\007u" +
|
||||
"ser_id\030\001 \002(\t\022\021\n\tclient_id\030\002 \002(\t\022\020\n\010platf" +
|
||||
"orm\030\003 \001(\005\"r\n\022LoadRemoteMessages\022#\n\014conve" +
|
||||
"rsation\030\001 \002(\0132\r.Conversation\022\022\n\nbefore_u" +
|
||||
"id\030\002 \002(\003\022\r\n\005count\030\003 \002(\005\022\024\n\014content_type\030" +
|
||||
"\004 \003(\005\"a\n\020MultiCastMessage\022\021\n\tfrom_user\030\001",
|
||||
" \002(\t\022 \n\007content\030\002 \002(\0132\017.MessageContent\022\n" +
|
||||
"\n\002to\030\003 \003(\t\022\014\n\004line\030\004 \002(\005\"E\n\035RecallMultiC" +
|
||||
"astMessageRequest\022\022\n\nmessage_id\030\001 \002(\003\022\020\n" +
|
||||
"\010receiver\030\002 \003(\t\"@\n\017AuthCodeRequest\022\021\n\tta" +
|
||||
"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"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@@ -68007,7 +68245,7 @@ public final class WFCMessage {
|
||||
internal_static_SearchUserRequest_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_SearchUserRequest_descriptor,
|
||||
new java.lang.String[] { "Keyword", "Fuzzy", "Page", });
|
||||
new java.lang.String[] { "Keyword", "Fuzzy", "Page", "DomainId", "Type", });
|
||||
internal_static_SearchUserResult_descriptor =
|
||||
getDescriptor().getMessageTypes().get(60);
|
||||
internal_static_SearchUserResult_fieldAccessorTable = new
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<!--<relativePath>../pom.xml</relativePath>-->
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>distribution</artifactId>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
部署IM服务后,可以使用Server SDK通过API来检查服务的部署情况,可以执行:
|
||||
```shell
|
||||
java -jar checker.jar http://127.0.0.1:18080 123456 http://127.0.0.1 true false
|
||||
java -jar checker.jar http://127.0.0.1:18080 123456 http://127.0.0.1 false false
|
||||
```
|
||||
来检查。检查之后会产生垃圾数据,请在检查之后停掉IM服务后,再删除掉IM服务数据库。此检查仅检查API,检查通过并不代表部署肯定成功,还需要客户端来验证。
|
||||
|
||||
@@ -246,6 +246,10 @@ group.visible_quit_or_kickoff_notification 0
|
||||
## 是否禁止陌生人拉人入群,默认为false
|
||||
group.disable_stranger_invite false
|
||||
|
||||
## 创建群组或者加人时。可能会有成员加入失败(黑名单,或者不允许陌生人拉入群)。当出现有成员失败时,如果此开关为关,操作会失败。
|
||||
## 如果此开关打开,操作会返回成功,另外在群里发送一条通知消息 XXX 拒绝加入群组。默认为开。
|
||||
group.add_member_allow_part_success true
|
||||
|
||||
## 群组信息是否标记删除
|
||||
group.enable_mark_deletion true
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
<name>Wildfire Chat</name>
|
||||
<description>Wildfire Chat Server</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
|
||||
+8
-1
@@ -8,9 +8,16 @@
|
||||
7. *** 从0.68 版本起添加了pc在线是否默认手机接收推送的开关,默认为开,与以前版本作用相反,请注意兼容(可以关掉与之前保持一致或者升级客户端) ***
|
||||
8. *** 从0.78 版本起把MySQL数据库中关键字都改为大小写敏感,另外生成id的方法也做了改变,只生成小写的id,避免出现id重复的问题,建议所有客户都升级 ***
|
||||
9. *** 从0.79 版本起把log4j升级到log4j2,因为log4j已经不再维护而且还有已知的漏洞,建议所有客户都升级,升级时注意更新log4j2的配置文件 ***
|
||||
10. *** 5. 0.97版本更改了启动脚本```wildfirechat.sh```,如果是升级服务,请注意更新启动脚本。***
|
||||
10. *** 0.97版本更改了启动脚本```wildfirechat.sh```,如果是升级服务,请注意更新启动脚本。***
|
||||
|
||||
# 更新记录
|
||||
--------------
|
||||
Release note 1.3.7:
|
||||
1. 搜索用户可以指定搜索机器人、普通用户或者所有。
|
||||
2. 添加群组成员时,允许部分失败。
|
||||
3. 解决内置存储上传文件时可能内存泄漏。
|
||||
4. 支持客户端上传本地角标,用于推送得到较为精确的角标数字。
|
||||
5. 解决机器人回调配置携带发送者用户信息无效的问题。
|
||||
|
||||
--------------
|
||||
Release note 1.3.6:
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.6</version>
|
||||
<version>1.3.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1004,6 +1004,12 @@ public class Main {
|
||||
}
|
||||
|
||||
static void testReadMessageContentFromDB() throws Exception {
|
||||
//需要注意几点:
|
||||
// 1 WFCMessage类不能混淆,如果混淆 WFCMessage.MessageContent.parseFrom(data) 就会失败。
|
||||
// 2 MessageContentFactory方法会自动查找所有的消息类,包括文本/图片/语音等。也有可能在某些环境下找不到这些类。可以检查MessageContentFactory
|
||||
// 类的源码,修改registerAllMessageContent方法,确保能找到所有的内容类。也可以显式调用注册的方法把所有已知消息都注册一遍,比如:
|
||||
// MessageContentFactory.registerCustomMessageContent(TextMessageContent.class); //这里示例只写了文本的,其他所有已知消息都需要注册一遍。
|
||||
|
||||
//从数据库t_messages_x表中读取到消息内容字段_data的二进制数据为
|
||||
byte[] data = {8,1,18,5,72,101,108,108,111,64,3};
|
||||
//1. 先把二进制数据转化为协议栈消息内容。
|
||||
|
||||
@@ -39,12 +39,13 @@ public class MeshAdmin {
|
||||
return AdminHttpUtils.httpJsonPost(path, getUserInfo, OutputUserInfoList.class);
|
||||
}
|
||||
|
||||
public static IMResult<PojoSearchUserRes> searchUser(String keyword, int searchType, int page) throws Exception {
|
||||
public static IMResult<PojoSearchUserRes> searchUser(String keyword, int searchType, int userType, int page) throws Exception {
|
||||
String path = APIPath.Search_User;
|
||||
PojoSearchUserReq req = new PojoSearchUserReq();
|
||||
req.keyword = keyword;
|
||||
req.searchType = searchType;
|
||||
req.page = page;
|
||||
req.userType = userType;
|
||||
return AdminHttpUtils.httpJsonPost(path, req, PojoSearchUserRes.class);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user