diff --git a/android/build.gradle b/android/build.gradle
index d21fe20..e790c1c 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -52,5 +52,5 @@ android {
 dependencies {
     // 本地依赖,现将aar复制到libs/io/openim/core-sdk/0.0.1/ 下,命名core-sdk-0.0.1.aar
 //    implementation 'io.openim:core-sdk:0.0.1@aar'
-    implementation 'io.openim:core-sdk:3.2.0@aar'
+    implementation 'io.openim:core-sdk:3.2.1@aar'
 }
\ No newline at end of file
diff --git a/android/src/main/java/io/openim/flutter_openim_sdk/manager/MessageManager.java b/android/src/main/java/io/openim/flutter_openim_sdk/manager/MessageManager.java
index c1e1770..ce5e4d7 100644
--- a/android/src/main/java/io/openim/flutter_openim_sdk/manager/MessageManager.java
+++ b/android/src/main/java/io/openim/flutter_openim_sdk/manager/MessageManager.java
@@ -382,7 +382,15 @@ public class MessageManager extends BaseManager {
         );
     }
 
-
+    public void setMessageLocalEx(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.setMessageLocalEx(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID"),
+                value(methodCall, "conversationID"),
+                value(methodCall, "clientMsgID"),
+                value(methodCall, "localEx")
+        );
+    }
     public void sendMessageNotOss(MethodCall methodCall, MethodChannel.Result result) {
         Open_im_sdk.sendMessageNotOss(
                 new OnMsgSendListener(result, methodCall),
diff --git a/android/src/main/java/io/openim/flutter_openim_sdk/manager/UserManager.java b/android/src/main/java/io/openim/flutter_openim_sdk/manager/UserManager.java
index 1cf4f26..4d8fe67 100644
--- a/android/src/main/java/io/openim/flutter_openim_sdk/manager/UserManager.java
+++ b/android/src/main/java/io/openim/flutter_openim_sdk/manager/UserManager.java
@@ -34,4 +34,39 @@ public class UserManager extends BaseManager {
                 value(methodCall, "operationID")
         );
     }
+    public void subscribeUsersStatus(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.subscribeUsersStatus(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID"),
+                jsonValue(methodCall, "userIDs"));
+    }
+
+    public void unsubscribeUsersStatus(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.unsubscribeUsersStatus(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID"),
+                jsonValue(methodCall, "userIDs"));
+    }
+
+    public void getSubscribeUsersStatus(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.getSubscribeUsersStatus(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID")
+        );
+    }
+
+    public void getUserStatus(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.getUserStatus(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID"),
+                jsonValue(methodCall, "userIDs"));
+    }
+
+    public void getUsersInfoStranger(MethodCall methodCall, MethodChannel.Result result) {
+        Open_im_sdk.getUsersInfoStranger(
+                new OnBaseListener(result, methodCall),
+                value(methodCall, "operationID"),
+                jsonValue(methodCall, "userIDs"),
+                value(methodCall, "groupID"));
+    }
 }
diff --git a/ios/Classes/Module/MessageManager.swift b/ios/Classes/Module/MessageManager.swift
index c281d15..6044a84 100644
--- a/ios/Classes/Module/MessageManager.swift
+++ b/ios/Classes/Module/MessageManager.swift
@@ -45,6 +45,7 @@ public class MessageManager: BaseServiceManager {
         self["getAdvancedHistoryMessageListReverse"] = getAdvancedHistoryMessageListReverse
 
         self["findMessageList"] = findMessageList
+        self["setMessageLocalEx"] = setMessageLocalEx
    
         self["sendMessageNotOss"] = sendMessageNotOss
         self["createImageMessageByURL"] = createImageMessageByURL
@@ -217,6 +218,10 @@ public class MessageManager: BaseServiceManager {
     func findMessageList(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
         Open_im_sdkFindMessageList(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "searchParams"])
     }
+
+    func setMessageLocalEx(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkSetMessageLocalEx(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "conversationID"], methodCall[string: "clientMsgID"], methodCall[string: "localEx"])
+    }
     
     func sendMessageNotOss(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
         let sendMsgProgressListener: SendMsgProgressListener = SendMsgProgressListener(channel: channel,result: result,methodCall: methodCall)
diff --git a/ios/Classes/Module/OrganizationManager.swift b/ios/Classes/Module/OrganizationManager.swift
deleted file mode 100644
index 3d96e51..0000000
--- a/ios/Classes/Module/OrganizationManager.swift
+++ /dev/null
@@ -1,59 +0,0 @@
-//import Foundation
-//import OpenIMCore
-//
-//public class OrganizationManager: BaseServiceManager {
-//
-//  public override func registerHandlers() {
-//        super.registerHandlers()
-//        self["setOrganizationListener"] = setOrganizationListener
-//        self["getSubDepartment"] = getSubDepartment
-//        self["getDepartmentMember"] = getDepartmentMember
-//        self["getUserInDepartment"] = getUserInDepartment
-//        self["getDepartmentMemberAndSubDepartment"] = getDepartmentMemberAndSubDepartment
-//        self["getDepartmentInfo"] = getDepartmentInfo
-//        self["searchOrganization"] = searchOrganization
-//    }
-//
-//    func setOrganizationListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSetOrganizationListener(OrganizationListener(channel: channel))
-//        callBack(result)
-//    }
-//
-//    func getSubDepartment(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetSubDepartment(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "departmentID"], methodCall[int: "offset"], methodCall[int: "count"])
-//    }
-//
-//    func getDepartmentMember(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetDepartmentMember(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "departmentID"], methodCall[int: "offset"], methodCall[int: "count"])
-//    }
-//
-//    func getUserInDepartment(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetUserInDepartment(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "userID"])
-//    }
-//
-//    func getDepartmentMemberAndSubDepartment(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetDepartmentMemberAndSubDepartment(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "departmentID"])
-//    }
-//
-//    func getDepartmentInfo(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetDepartmentInfo(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "departmentID"])
-//    }
-//
-//    func searchOrganization(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkSearchOrganization(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "searchParam"], methodCall[int: "offset"], methodCall[int: "count"])
-//    }
-//}
-//
-//public class OrganizationListener: NSObject, Open_im_sdk_callbackOnOrganizationListenerProtocol {
-//
-//    private let channel:FlutterMethodChannel
-//
-//    init(channel:FlutterMethodChannel) {
-//        self.channel = channel
-//    }
-//
-//    public func onOrganizationUpdated() {
-//        CommonUtil.emitEvent(channel: self.channel, method: "organizationListener", type: "onOrganizationUpdated", errCode: nil, errMsg: nil, data: nil)
-//    }
-//
-//}
diff --git a/ios/Classes/Module/SignalingManager.swift b/ios/Classes/Module/SignalingManager.swift
deleted file mode 100644
index abb403b..0000000
--- a/ios/Classes/Module/SignalingManager.swift
+++ /dev/null
@@ -1,148 +0,0 @@
-//import Foundation
-//import OpenIMCore
-//
-//public class SignalingManager: BaseServiceManager {
-//    
-//    public override func registerHandlers() {
-//        super.registerHandlers()
-//        self["setSignalingListener"] = setSignalingListener
-//        self["signalingInvite"] = signalingInvite
-//        self["signalingInviteInGroup"] = signalingInviteInGroup
-//        self["signalingAccept"] = signalingAccept
-//        self["signalingReject"] = signalingReject
-//        self["signalingCancel"] = signalingCancel
-//        self["signalingHungUp"] = signalingHungUp
-//        self["signalingGetRoomByGroupID"] = signalingGetRoomByGroupID
-//        self["signalingGetTokenByRoomID"] = signalingGetTokenByRoomID
-//        self["signalingUpdateMeetingInfo"] = signalingUpdateMeetingInfo
-//        self["signalingCreateMeeting"] = signalingCreateMeeting
-//        self["signalingJoinMeeting"] = signalingJoinMeeting
-//        self["signalingOperateStream"] = signalingOperateStream
-//        self["signalingGetMeetings"] = signalingGetMeetings
-//        self["signalingCloseRoom"] = signalingCloseRoom
-//        self["signalingSendCustomSignal"] = signalingSendCustomSignal
-//    }
-//
-//    func setSignalingListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSetSignalingListener(SignalingListener(channel: channel))
-//        callBack(result)
-//    }
-//
-//    func signalingInvite(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingInvite(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//    
-//    func signalingInviteInGroup(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingInviteInGroup(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//    
-//    func signalingAccept(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingAccept(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//    
-//    func signalingReject(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingReject(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//    
-//    func signalingCancel(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingCancel(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//
-//    func signalingHungUp(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingHungUp(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "signalingInfo"])
-//    }
-//    
-//    func signalingGetRoomByGroupID(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingGetRoomByGroupID(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "groupID"])
-//    }
-//    
-//    func signalingGetTokenByRoomID(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingGetTokenByRoomID(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "roomID"])
-//    }
-//    
-//    func signalingUpdateMeetingInfo(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingUpdateMeetingInfo(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "info"])
-//    }
-//    
-//    func signalingCreateMeeting(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingCreateMeeting(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "info"])
-//    }
-//    
-//    func signalingJoinMeeting(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingJoinMeeting(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "info"])
-//    }
-//    
-//    func signalingOperateStream(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingOperateStream(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "streamType"], methodCall[string: "roomID"], methodCall[string: "userID"], methodCall[bool: "mute"], methodCall[bool: "muteAll"])
-//    }
-//    
-//    func signalingGetMeetings(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingGetMeetings(BaseCallback(result: result), methodCall[string: "operationID"])
-//    }
-//    
-//    func signalingCloseRoom(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingCloseRoom(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "roomID"])
-//    }
-//    
-//    func signalingSendCustomSignal(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSignalingSendCustomSignal(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "customInfo"], methodCall[string: "roomID"])
-//    }
-//}
-//public class SignalingListener: NSObject, Open_im_sdk_callbackOnSignalingListenerProtocol {
-// 
-//  
-//    private let channel:FlutterMethodChannel
-//    
-//    init(channel:FlutterMethodChannel) {
-//        self.channel = channel
-//    }
-//    
-//    public func onInvitationCancelled(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInvitationCancelled", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onInvitationTimeout(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInvitationTimeout", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onInviteeAccepted(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInviteeAccepted", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onInviteeAccepted(byOtherDevice s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInviteeAcceptedByOtherDevice", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onInviteeRejected(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInviteeRejected", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onInviteeRejected(byOtherDevice s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onInviteeRejectedByOtherDevice", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onReceiveNewInvitation(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onReceiveNewInvitation", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onHangUp(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onHangUp", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onRoomParticipantConnected(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onRoomParticipantConnected", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onRoomParticipantDisconnected(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onRoomParticipantDisconnected", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onStreamChange(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onStreamChange", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//    public func onReceiveCustomSignal(_ s: String?) {
-//        CommonUtil.emitEvent(channel: channel, method: "signalingListener", type: "onReceiveCustomSignal", errCode: nil, errMsg: nil, data: s)
-//    }
-//    
-//}
diff --git a/ios/Classes/Module/UserManager.swift b/ios/Classes/Module/UserManager.swift
index 19873e5..269ace6 100644
--- a/ios/Classes/Module/UserManager.swift
+++ b/ios/Classes/Module/UserManager.swift
@@ -9,6 +9,11 @@ public class UserManager: BaseServiceManager {
         self["getUsersInfo"] = getUsersInfo
         self["setSelfInfo"] = setSelfInfo
         self["getSelfUserInfo"] = getSelfUserInfo
+        self["subscribeUsersStatus"] = subscribeUsersStatus
+        self["unsubscribeUsersStatus"] = unsubscribeUsersStatus
+        self["getSubscribeUsersStatus"] = getSubscribeUsersStatus
+        self["getUserStatus"] = getUserStatus
+        self["getUsersInfoStranger"] = getUsersInfoStranger
     }
 
     func setUserListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
@@ -27,6 +32,26 @@ public class UserManager: BaseServiceManager {
     func getSelfUserInfo(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
         Open_im_sdkGetSelfUserInfo(BaseCallback(result: result), methodCall[string: "operationID"])
     }
+
+    func subscribeUsersStatus(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkSubscribeUsersStatus(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "userIDs"])
+    }
+
+    func unsubscribeUsersStatus(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkUnsubscribeUsersStatus(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "userIDs"])
+    }
+
+    func getSubscribeUsersStatus(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkGetSubscribeUsersStatus(BaseCallback(result: result), methodCall[string: "operationID"])
+    }
+
+    func getUserStatus(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkGetUserStatus(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "userIDs"])
+    }
+    
+    func getUsersInfoStranger(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
+        Open_im_sdkGetUsersInfoStranger(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "userIDs"], methodCall[string: "groupID"])
+    }
 }
 
 public class UserListener: NSObject, Open_im_sdk_callbackOnUserListenerProtocol {
@@ -41,8 +66,8 @@ public class UserListener: NSObject, Open_im_sdk_callbackOnUserListenerProtocol
         CommonUtil.emitEvent(channel: self.channel, method: "userListener", type: "onSelfInfoUpdated", errCode: nil, errMsg: nil, data: userInfo)
     }
     
-    public func onUserStatusChanged(_ userInfo: String?) {
-        CommonUtil.emitEvent(channel: self.channel, method: "userListener", type: "onUserStatusChanged", errCode: nil, errMsg: nil, data: userInfo)
+    public func onUserStatusChanged(_ statusInfo: String?) {
+        CommonUtil.emitEvent(channel: self.channel, method: "userListener", type: "onUserStatusChanged", errCode: nil, errMsg: nil, data: statusInfo)
     }
 
 }
diff --git a/ios/Classes/Module/WorkMomentsManager.swift b/ios/Classes/Module/WorkMomentsManager.swift
deleted file mode 100644
index 25315d1..0000000
--- a/ios/Classes/Module/WorkMomentsManager.swift
+++ /dev/null
@@ -1,44 +0,0 @@
-//import Foundation
-//import OpenIMCore
-//
-//public class WorkMomentsManager: BaseServiceManager {
-//
-//  public override func registerHandlers() {
-//        super.registerHandlers()
-//        self["setWorkMomentsListener"] = setWorkMomentsListener
-//        self["getWorkMomentsUnReadCount"] = getWorkMomentsUnReadCount
-//        self["getWorkMomentsNotification"] = getWorkMomentsNotification
-//        self["clearWorkMomentsNotification"] = clearWorkMomentsNotification
-//    }
-//
-//    func setWorkMomentsListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
-//        Open_im_sdkSetWorkMomentsListener(WorkMomentsListener(channel: channel))
-//        callBack(result)
-//    }
-//
-//    func getWorkMomentsUnReadCount(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetWorkMomentsUnReadCount(BaseCallback(result: result), methodCall[string: "operationID"])
-//    }
-//
-//    func getWorkMomentsNotification(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkGetWorkMomentsNotification(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[int: "offset"], methodCall[int: "count"])
-//    }
-//
-//    func clearWorkMomentsNotification(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
-//        Open_im_sdkClearWorkMomentsNotification(BaseCallback(result: result), methodCall[string: "operationID"])
-//    }
-//}
-//
-//public class WorkMomentsListener: NSObject, Open_im_sdk_callbackOnWorkMomentsListenerProtocol {
-//
-//    private let channel:FlutterMethodChannel
-//
-//    init(channel:FlutterMethodChannel) {
-//        self.channel = channel
-//    }
-//
-//    public func onRecvNewNotification() {
-//        CommonUtil.emitEvent(channel: self.channel, method: "workMomentsListener", type: "OnRecvNewNotification", errCode: nil, errMsg: nil, data: nil)
-//    }
-//
-//}
diff --git a/ios/flutter_openim_sdk.podspec b/ios/flutter_openim_sdk.podspec
index 1dde1fb..1702525 100644
--- a/ios/flutter_openim_sdk.podspec
+++ b/ios/flutter_openim_sdk.podspec
@@ -17,7 +17,7 @@ A new Flutter project.
   s.dependency 'Flutter'
   s.platform = :ios, '11.0'
 
-  s.dependency 'OpenIMSDKCore','3.2.0'
+  s.dependency 'OpenIMSDKCore','3.2.1'
   s.static_framework = true
   # s.vendored_frameworks = 'Framework/*.framework'
   # Flutter.framework does not contain a i386 slice.
diff --git a/lib/src/listener/user_listener.dart b/lib/src/listener/user_listener.dart
index a2c4f34..a97255a 100644
--- a/lib/src/listener/user_listener.dart
+++ b/lib/src/listener/user_listener.dart
@@ -6,7 +6,7 @@ class OnUserListener {
   Function(UserInfo info)? onSelfInfoUpdated;
   Function(UserStatusInfo info)? onUserStatusChanged;
 
-  OnUserListener({this.onSelfInfoUpdated});
+  OnUserListener({this.onSelfInfoUpdated, this.onUserStatusChanged});
 
   /// 自身信息发送变化回调
   void selfInfoUpdated(UserInfo info) {
diff --git a/lib/src/manager/im_manager.dart b/lib/src/manager/im_manager.dart
index fbf0e12..6d6c10c 100644
--- a/lib/src/manager/im_manager.dart
+++ b/lib/src/manager/im_manager.dart
@@ -65,7 +65,7 @@ class IMManager {
               break;
             case 'onUserStatusChanged':
               final status = Utils.toObj(data, (map) => UserStatusInfo.fromJson(map));
-              userManager.listener.userStatusChanged(status);
+              userManager.listener.userStatusChanged(status); 
               break;
           }
         } else if (call.method == ListenerType.groupListener) {
diff --git a/lib/src/manager/im_message_manager.dart b/lib/src/manager/im_message_manager.dart
index 98a80bc..797eab6 100644
--- a/lib/src/manager/im_message_manager.dart
+++ b/lib/src/manager/im_message_manager.dart
@@ -531,8 +531,7 @@ class MessageManager {
                 },
                 'operationID': Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toObj(value, (map) => SearchResult.fromJson(map)));
+          .then((value) => Utils.toObj(value, (map) => SearchResult.fromJson(map)));
 
   /// 撤回消息
   /// [message] 被撤回的消息体
@@ -587,8 +586,7 @@ class MessageManager {
                 'lastMinSeq': lastMinSeq ?? 0,
                 'operationID': Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toObj(value, (map) => AdvancedMessage.fromJson(map)));
+          .then((value) => Utils.toObj(value, (map) => AdvancedMessage.fromJson(map)));
 
   /// 获取聊天记录(以startMsg为节点,新收到的聊天记录),用在全局搜索定位某一条消息,然后此条消息后新增的消息
   /// [conversationID] 会话id,查询通知时可用
@@ -611,8 +609,7 @@ class MessageManager {
                 'lastMinSeq': lastMinSeq ?? 0,
                 'operationID': Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toObj(value, (map) => AdvancedMessage.fromJson(map)));
+          .then((value) => Utils.toObj(value, (map) => AdvancedMessage.fromJson(map)));
 
   /// 查找消息详细
   /// [conversationID] 会话id
@@ -628,8 +625,7 @@ class MessageManager {
                 'searchParams': searchParams.map((e) => e.toJson()).toList(),
                 'operationID': Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toObj(value, (map) => SearchResult.fromJson(map)));
+          .then((value) => Utils.toObj(value, (map) => SearchResult.fromJson(map)));
 
   /// 富文本消息
   /// [text] 输入内容
@@ -763,6 +759,22 @@ class MessageManager {
     return _channel.invokeMethod('setCustomBusinessListener', _buildParam({}));
   }
 
+  Future setMessageLocalEx({
+    required String conversationID,
+    required String clientMsgID,
+    required String localEx,
+    String? operationID,
+  }) {
+    return _channel.invokeMethod(
+        'setMessageLocalEx',
+        _buildParam({
+          "conversationID": conversationID,
+          "clientMsgID": clientMsgID,
+          "localEx": localEx,
+          "operationID": Utils.checkOperationID(operationID),
+        }));
+  }
+
   ///
   Future setMessageKvInfoListener(OnMessageKvInfoListener listener) {
     this.messageKvInfoListener = listener;
@@ -782,8 +794,7 @@ class MessageManager {
                 'list': list.map((e) => e.toJson()).toList(),
                 "operationID": Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
+          .then((value) => Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
 
   Future<List<TypeKeySetResult>> deleteMessageReactionExtensions({
     required Message message,
@@ -798,8 +809,7 @@ class MessageManager {
                 'list': list,
                 "operationID": Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
+          .then((value) => Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
 
   Future<List<MessageTypeKeyMapping>> getMessageListReactionExtensions({
     List<Message> messageList = const [],
@@ -812,8 +822,7 @@ class MessageManager {
                 'messageList': messageList.map((e) => e.toJson()).toList(),
                 "operationID": Utils.checkOperationID(operationID),
               }))
-          .then((value) => Utils.toList(
-              value, (map) => MessageTypeKeyMapping.fromJson(map)));
+          .then((value) => Utils.toList(value, (map) => MessageTypeKeyMapping.fromJson(map)));
 
   Future<List<TypeKeySetResult>> addMessageReactionExtensions({
     required Message message,
@@ -828,8 +837,7 @@ class MessageManager {
                 'list': list.map((e) => e.toJson()).toList(),
                 "operationID": Utils.checkOperationID(operationID),
               }))
-          .then((value) =>
-              Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
+          .then((value) => Utils.toList(value, (map) => TypeKeySetResult.fromJson(map)));
 
   Future<List<MessageTypeKeyMapping>> getMessageListSomeReactionExtensions({
     List<Message> messageList = const [],
@@ -844,8 +852,7 @@ class MessageManager {
                 'list': kvList.map((e) => e.toJson()).toList(),
                 "operationID": Utils.checkOperationID(operationID),
               }))
-          .then((value) => Utils.toList(
-              value, (map) => MessageTypeKeyMapping.fromJson(map)));
+          .then((value) => Utils.toList(value, (map) => MessageTypeKeyMapping.fromJson(map)));
 
   static Map _buildParam(Map param) {
     param["ManagerName"] = "messageManager";
diff --git a/lib/src/manager/im_user_manager.dart b/lib/src/manager/im_user_manager.dart
index 3dc3dad..1761e13 100644
--- a/lib/src/manager/im_user_manager.dart
+++ b/lib/src/manager/im_user_manager.dart
@@ -75,6 +75,76 @@ class UserManager {
             'operationID': Utils.checkOperationID(operationID),
           }));
 
+  Future<List<UserStatusInfo>> subscribeUsersStatus(
+    List<String> userIDs, {
+    String? operationID,
+  }) {
+    return _channel
+        .invokeMethod(
+            'subscribeUsersStatus',
+            _buildParam({
+              'userIDs': userIDs,
+              'operationID': Utils.checkOperationID(operationID),
+            }))
+        .then((value) => Utils.toList(value, (map) => UserStatusInfo.fromJson(map)));
+  }
+
+  Future<List<UserStatusInfo>> unsubscribeUsersStatus(
+    List<String> userIDs, {
+    String? operationID,
+  }) {
+    return _channel
+        .invokeMethod(
+            'unsubscribeUsersStatus',
+            _buildParam({
+              'userIDs': userIDs,
+              'operationID': Utils.checkOperationID(operationID),
+            }))
+        .then((value) => Utils.toList(value, (map) => UserStatusInfo.fromJson(map)));
+  }
+
+  Future<List<UserStatusInfo>> getSubscribeUsersStatus({
+    String? operationID,
+  }) {
+    return _channel
+        .invokeMethod(
+            'getSubscribeUsersStatus',
+            _buildParam({
+              'operationID': Utils.checkOperationID(operationID),
+            }))
+        .then((value) => Utils.toList(value, (map) => UserStatusInfo.fromJson(map)));
+  }
+
+  Future<List<UserStatusInfo>> getUserStatus(
+    List<String> userIDs, {
+    String? operationID,
+  }) {
+    return _channel
+        .invokeMethod(
+            'getUserStatus',
+            _buildParam({
+              'userIDs': userIDs,
+              'operationID': Utils.checkOperationID(operationID),
+            }))
+        .then((value) => Utils.toList(value, (map) => UserStatusInfo.fromJson(map)));
+  }
+
+  Future<List<UserInfo>> getUsersInfoStranger(
+    List<String> userIDs,
+    String groupID, {
+    String? operationID,
+  }) {
+    return _channel
+        .invokeMethod(
+            'getUsersInfoStranger',
+            _buildParam({
+              'userIDs': userIDs,
+              'groupID': groupID,
+              'operationID': Utils.checkOperationID(operationID),
+            }))
+        .then((value) => Utils.toList(value, (map) => UserInfo.fromJson(map)));
+  }
+
   static Map _buildParam(Map param) {
     param["ManagerName"] = "userManager";
     return param;
diff --git a/lib/src/models/message.dart b/lib/src/models/message.dart
index b37b253..f92370e 100644
--- a/lib/src/models/message.dart
+++ b/lib/src/models/message.dart
@@ -31,7 +31,7 @@ class Message {
   int? contentType;
 
   /// 平台[Platform]
-  int? platformID;
+  int? senderPlatformID;
 
   /// 发送者昵称
   String? senderNickname;
@@ -131,7 +131,7 @@ class Message {
     this.recvID,
     this.msgFrom,
     this.contentType,
-    this.platformID,
+    this.senderPlatformID,
     this.senderNickname,
     this.senderFaceUrl,
     this.groupID,
@@ -173,7 +173,7 @@ class Message {
     recvID = json['recvID'];
     msgFrom = json['msgFrom'];
     contentType = json['contentType'];
-    platformID = json['platformID'];
+    senderPlatformID = json['senderPlatformID'];
     senderNickname = json['senderNickname'];
     senderFaceUrl = json['senderFaceUrl'];
     groupID = json['groupID'];
@@ -248,7 +248,7 @@ class Message {
     data['recvID'] = this.recvID;
     data['msgFrom'] = this.msgFrom;
     data['contentType'] = this.contentType;
-    data['platformID'] = this.platformID;
+    data['senderPlatformID'] = this.senderPlatformID;
     data['senderNickname'] = this.senderNickname;
     data['senderFaceUrl'] = this.senderFaceUrl;
     data['groupID'] = this.groupID;
@@ -302,7 +302,7 @@ class Message {
     recvID = message.recvID;
     msgFrom = message.msgFrom;
     contentType = message.contentType;
-    platformID = message.platformID;
+    senderPlatformID = message.senderPlatformID;
     senderNickname = message.senderNickname;
     senderFaceUrl = message.senderFaceUrl;
     groupID = message.groupID;
diff --git a/lib/src/models/user_info.dart b/lib/src/models/user_info.dart
index f141ec1..62330f4 100644
--- a/lib/src/models/user_info.dart
+++ b/lib/src/models/user_info.dart
@@ -102,15 +102,9 @@ class UserInfo {
   // }
 
   UserInfo.fromJson(Map<String, dynamic> json) {
-    publicInfo = json['publicInfo'] != null
-        ? PublicUserInfo.fromJson(json['publicInfo'])
-        : null;
-    friendInfo = json['friendInfo'] != null
-        ? FriendInfo.fromJson(json['friendInfo'])
-        : null;
-    blackInfo = json['blackInfo'] != null
-        ? BlacklistInfo.fromJson(json['blackInfo'])
-        : null;
+    publicInfo = json['publicInfo'] != null ? PublicUserInfo.fromJson(json['publicInfo']) : null;
+    friendInfo = json['friendInfo'] != null ? FriendInfo.fromJson(json['friendInfo']) : null;
+    blackInfo = json['blackInfo'] != null ? BlacklistInfo.fromJson(json['blackInfo']) : null;
     //
     isFriendship = friendInfo != null;
     isBlacklist = blackInfo != null;
@@ -164,25 +158,17 @@ class UserInfo {
 
   bool get isMale => gender == 1;
 
-  String get _userID => isFriendship!
-      ? friendInfo!.userID!
-      : (isBlacklist! ? blackInfo!.userID! : publicInfo!.userID!);
+  String get _userID => isFriendship! ? friendInfo!.userID! : (isBlacklist! ? blackInfo!.userID! : publicInfo!.userID!);
 
-  String? get _nickname => isFriendship!
-      ? friendInfo?.nickname
-      : (isBlacklist! ? blackInfo?.nickname : publicInfo?.nickname);
+  String? get _nickname =>
+      isFriendship! ? friendInfo?.nickname : (isBlacklist! ? blackInfo?.nickname : publicInfo?.nickname);
 
-  String? get _faceUrl => isFriendship!
-      ? friendInfo?.faceURL
-      : (isBlacklist! ? blackInfo?.faceURL : publicInfo?.faceURL);
+  String? get _faceUrl =>
+      isFriendship! ? friendInfo?.faceURL : (isBlacklist! ? blackInfo?.faceURL : publicInfo?.faceURL);
 
-  int? get _gender => isFriendship!
-      ? friendInfo?.gender
-      : (isBlacklist! ? blackInfo?.gender : publicInfo?.gender);
+  int? get _gender => isFriendship! ? friendInfo?.gender : (isBlacklist! ? blackInfo?.gender : publicInfo?.gender);
 
-  String? get _ex => isFriendship!
-      ? friendInfo?.ex
-      : (isBlacklist! ? blackInfo?.ex : publicInfo?.ex);
+  String? get _ex => isFriendship! ? friendInfo?.ex : (isBlacklist! ? blackInfo?.ex : publicInfo?.ex);
 
   String? get _phoneNumber => friendInfo?.phoneNumber;
 
@@ -201,10 +187,7 @@ class UserInfo {
 
   @override
   bool operator ==(Object other) =>
-      identical(this, other) ||
-      other is UserInfo &&
-          runtimeType == other.runtimeType &&
-          userID == other.userID;
+      identical(this, other) || other is UserInfo && runtimeType == other.runtimeType && userID == other.userID;
 
   @override
   int get hashCode => userID.hashCode;
@@ -571,14 +554,14 @@ class UserStatusInfo {
   UserStatusInfo.fromJson(Map<String, dynamic> json) {
     userID = json['userID'];
     status = json['status'];
-    platformIDs = json['platformIDs'];
+    platformIDs = json["platformIDs"] == null ? [] : List<int>.from(json["platformIDs"].map((x) => x));
   }
 
   Map<String, dynamic> toJson() {
     final data = Map<String, dynamic>();
     data['userID'] = this.userID;
     data['status'] = this.status;
-    data['platformIDs'] = this.platformIDs;
+    data['platformIDs'] = List<dynamic>.from(platformIDs!.map((x) => x));
     return data;
   }
 }
diff --git a/lib/src/openim.dart b/lib/src/openim.dart
index b18660a..17dfc97 100644
--- a/lib/src/openim.dart
+++ b/lib/src/openim.dart
@@ -2,7 +2,7 @@ import 'package:flutter/services.dart';
 import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
 
 class OpenIM {
-  static const version = '3.2.0';
+  static const version = '3.2.1';
 
   static const _channel = const MethodChannel('flutter_openim_sdk');
 
diff --git a/pubspec.yaml b/pubspec.yaml
index c86ff8a..858eb16 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: flutter_openim_sdk
 description: An instant messaging plug-in that supports Android and IOS. And the server is also all open source.
-version: 3.2.0
+version: 3.2.1
 homepage: https://www.rentsoft.cn
 repository: https://github.com/OpenIMSDK/Open-IM-SDK-Flutter