فهرست منبع

添加发送消息功能

fancy 5 سال پیش
والد
کامیت
f2c8f3b4e2

+ 16 - 0
o2ios/O2Platform.xcodeproj/project.pbxproj

@@ -126,6 +126,10 @@
 		B1489B52248E192D009EE9FD /* IMChatMessageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */; };
 		B1489B52248E192D009EE9FD /* IMChatMessageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */; };
 		B1489BFE2490BE51009EE9FD /* IMChatMessageSendViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */; };
 		B1489BFE2490BE51009EE9FD /* IMChatMessageSendViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */; };
 		B1489BFF2490BE51009EE9FD /* IMChatMessageSendViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */; };
 		B1489BFF2490BE51009EE9FD /* IMChatMessageSendViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */; };
+		B1489C7B2491FEFE009EE9FD /* IMChatEmojiBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489C7A2491FEFE009EE9FD /* IMChatEmojiBarView.swift */; };
+		B1489CAE2491FF13009EE9FD /* IMChatEmojiBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489CAD2491FF13009EE9FD /* IMChatEmojiBarView.xib */; };
+		B1489CB12492045D009EE9FD /* IMChatEmojiItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1489CAF2492045D009EE9FD /* IMChatEmojiItemCell.swift */; };
+		B1489CB22492045D009EE9FD /* IMChatEmojiItemCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1489CB02492045D009EE9FD /* IMChatEmojiItemCell.xib */; };
 		B14B339F2356EB1500442968 /* CloudFileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B339E2356EB1500442968 /* CloudFileViewModel.swift */; };
 		B14B339F2356EB1500442968 /* CloudFileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B339E2356EB1500442968 /* CloudFileViewModel.swift */; };
 		B14E07532301137F00AE85A0 /* ContactPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */; };
 		B14E07532301137F00AE85A0 /* ContactPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */; };
 		B14E07862301418400AE85A0 /* ContactUnitPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */; };
 		B14E07862301418400AE85A0 /* ContactUnitPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */; };
@@ -1447,6 +1451,10 @@
 		B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageViewCell.xib; sourceTree = "<group>"; };
 		B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageViewCell.xib; sourceTree = "<group>"; };
 		B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatMessageSendViewCell.swift; sourceTree = "<group>"; };
 		B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatMessageSendViewCell.swift; sourceTree = "<group>"; };
 		B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageSendViewCell.xib; sourceTree = "<group>"; };
 		B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatMessageSendViewCell.xib; sourceTree = "<group>"; };
+		B1489C7A2491FEFE009EE9FD /* IMChatEmojiBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatEmojiBarView.swift; sourceTree = "<group>"; };
+		B1489CAD2491FF13009EE9FD /* IMChatEmojiBarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatEmojiBarView.xib; sourceTree = "<group>"; };
+		B1489CAF2492045D009EE9FD /* IMChatEmojiItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IMChatEmojiItemCell.swift; sourceTree = "<group>"; };
+		B1489CB02492045D009EE9FD /* IMChatEmojiItemCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = IMChatEmojiItemCell.xib; sourceTree = "<group>"; };
 		B14B339E2356EB1500442968 /* CloudFileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileViewModel.swift; sourceTree = "<group>"; };
 		B14B339E2356EB1500442968 /* CloudFileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileViewModel.swift; sourceTree = "<group>"; };
 		B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07522301137F00AE85A0 /* ContactPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactUnitPickerViewController.swift; sourceTree = "<group>"; };
 		B14E07852301418400AE85A0 /* ContactUnitPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactUnitPickerViewController.swift; sourceTree = "<group>"; };
@@ -2603,6 +2611,10 @@
 				B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */,
 				B1489B50248E192D009EE9FD /* IMChatMessageViewCell.xib */,
 				B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */,
 				B1489BFC2490BE51009EE9FD /* IMChatMessageSendViewCell.swift */,
 				B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */,
 				B1489BFD2490BE51009EE9FD /* IMChatMessageSendViewCell.xib */,
+				B1489C7A2491FEFE009EE9FD /* IMChatEmojiBarView.swift */,
+				B1489CAD2491FF13009EE9FD /* IMChatEmojiBarView.xib */,
+				B1489CAF2492045D009EE9FD /* IMChatEmojiItemCell.swift */,
+				B1489CB02492045D009EE9FD /* IMChatEmojiItemCell.xib */,
 			);
 			);
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -5574,6 +5586,7 @@
 				E46E6CB51DD41F5D00AB7561 /* jQuery.js in Resources */,
 				E46E6CB51DD41F5D00AB7561 /* jQuery.js in Resources */,
 				E46E6C801DD41F5D00AB7561 /* ZSSh6@2x.png in Resources */,
 				E46E6C801DD41F5D00AB7561 /* ZSSh6@2x.png in Resources */,
 				E46E6C971DD41F5D00AB7561 /* ZSSparagraph.png in Resources */,
 				E46E6C971DD41F5D00AB7561 /* ZSSparagraph.png in Resources */,
+				B1489CAE2491FF13009EE9FD /* IMChatEmojiBarView.xib in Resources */,
 				E4B888E01D9D48F1002E1A46 /* apps.storyboard in Resources */,
 				E4B888E01D9D48F1002E1A46 /* apps.storyboard in Resources */,
 				E428AF6120AD4DCE00D964B9 /* OOAttanceCheckInController.xib in Resources */,
 				E428AF6120AD4DCE00D964B9 /* OOAttanceCheckInController.xib in Resources */,
 				B165CD5D2242093500373B66 /* SourceSansPro-Regular.ttf in Resources */,
 				B165CD5D2242093500373B66 /* SourceSansPro-Regular.ttf in Resources */,
@@ -5595,6 +5608,7 @@
 				B165CD682242093500373B66 /* Montserrat-Regular.ttf in Resources */,
 				B165CD682242093500373B66 /* Montserrat-Regular.ttf in Resources */,
 				E41441DB1DCAC5D700E3DDA3 /* bbs.storyboard in Resources */,
 				E41441DB1DCAC5D700E3DDA3 /* bbs.storyboard in Resources */,
 				E46E6C9B1DD41F5D00AB7561 /* ZSSquicklink.png in Resources */,
 				E46E6C9B1DD41F5D00AB7561 /* ZSSquicklink.png in Resources */,
+				B1489CB22492045D009EE9FD /* IMChatEmojiItemCell.xib in Resources */,
 				E45755A91E0BA72E00EC44F4 /* qrcode_Scan_weixin_Line@2x.png in Resources */,
 				E45755A91E0BA72E00EC44F4 /* qrcode_Scan_weixin_Line@2x.png in Resources */,
 				E4B697B920764A2D0062F6E8 /* buildlist.json in Resources */,
 				E4B697B920764A2D0062F6E8 /* buildlist.json in Resources */,
 				E4C24B4320844F3C00E426B0 /* defaultTheme.bundle in Resources */,
 				E4C24B4320844F3C00E426B0 /* defaultTheme.bundle in Resources */,
@@ -6066,6 +6080,7 @@
 				B1FBA01A230533FA00A90722 /* PersonPickerTableViewCell.swift in Sources */,
 				B1FBA01A230533FA00A90722 /* PersonPickerTableViewCell.swift in Sources */,
 				E4B6981A2079A8BB0062F6E8 /* OOBindNodeViewController.swift in Sources */,
 				E4B6981A2079A8BB0062F6E8 /* OOBindNodeViewController.swift in Sources */,
 				E4F4544F20902263002FBC32 /* OOConfigInfoModels.swift in Sources */,
 				E4F4544F20902263002FBC32 /* OOConfigInfoModels.swift in Sources */,
+				B1489CB12492045D009EE9FD /* IMChatEmojiItemCell.swift in Sources */,
 				E4B2321A20B3E9440082F30A /* OOAttanceCheckinPromptView.swift in Sources */,
 				E4B2321A20B3E9440082F30A /* OOAttanceCheckinPromptView.swift in Sources */,
 				E4B69810207652960062F6E8 /* OOTaskModels.swift in Sources */,
 				E4B69810207652960062F6E8 /* OOTaskModels.swift in Sources */,
 				E4B888761D9D48F1002E1A46 /* DepartmentDuty.swift in Sources */,
 				E4B888761D9D48F1002E1A46 /* DepartmentDuty.swift in Sources */,
@@ -6080,6 +6095,7 @@
 				E4C24BD120844F3C00E426B0 /* JCNoteNameViewController.swift in Sources */,
 				E4C24BD120844F3C00E426B0 /* JCNoteNameViewController.swift in Sources */,
 				B1B110E2223622C400775BEF /* O2BioLocalAuth.swift in Sources */,
 				B1B110E2223622C400775BEF /* O2BioLocalAuth.swift in Sources */,
 				E4184B231DB4B29B00FCC907 /* SPasswordChangeViewController.swift in Sources */,
 				E4184B231DB4B29B00FCC907 /* SPasswordChangeViewController.swift in Sources */,
+				B1489C7B2491FEFE009EE9FD /* IMChatEmojiBarView.swift in Sources */,
 				E4B7816C1DF8F2B2007B58A9 /* CMSData.swift in Sources */,
 				E4B7816C1DF8F2B2007B58A9 /* CMSData.swift in Sources */,
 				B165CD592242093500373B66 /* PresentrController.swift in Sources */,
 				B165CD592242093500373B66 /* PresentrController.swift in Sources */,
 				E4B7816D1DF8F2B2007B58A9 /* CMSWrapOutCategoryList.swift in Sources */,
 				E4B7816D1DF8F2B2007B58A9 /* CMSWrapOutCategoryList.swift in Sources */,

+ 78 - 18
o2ios/O2Platform/App/IM-聊天/IMChatViewController.swift

@@ -21,6 +21,14 @@ class IMChatViewController: UIViewController {
     @IBOutlet weak var bottomBarHeightConstraint: NSLayoutConstraint!
     @IBOutlet weak var bottomBarHeightConstraint: NSLayoutConstraint!
     //底部工具栏
     //底部工具栏
     @IBOutlet weak var bottomBar: UIView!
     @IBOutlet weak var bottomBar: UIView!
+    
+    private let emojiBarHeight = 256
+    //表情窗口
+    private lazy var emojiBar: IMChatEmojiBarView = {
+       let view = Bundle.main.loadNibNamed("IMChatEmojiBarView", owner: self, options: nil)?.first as! IMChatEmojiBarView
+        view.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: emojiBarHeight.toCGFloat)
+       return view
+    }()
 
 
     private lazy var viewModel: IMViewModel = {
     private lazy var viewModel: IMViewModel = {
         return IMViewModel()
         return IMViewModel()
@@ -73,17 +81,61 @@ class IMChatViewController: UIViewController {
         if let c = self.conversation, let id = c.id {
         if let c = self.conversation, let id = c.id {
             self.viewModel.myMsgPageList(page: page, conversationId: id).then { (list) in
             self.viewModel.myMsgPageList(page: page, conversationId: id).then { (list) in
                 self.chatMessageList = list
                 self.chatMessageList = list
-                DispatchQueue.main.async {
-                    self.tableView.reloadData()
-                    if self.chatMessageList.count > 0 {
-                        self.tableView.scrollToRow(at: IndexPath(row: self.chatMessageList.count-1, section: 0), at: .bottom, animated: true)
-                    }
-                }
+                self.scrollMessageToBottom()
             }
             }
         } else {
         } else {
             self.showError(title: "参数错误!!!")
             self.showError(title: "参数错误!!!")
         }
         }
     }
     }
+    //刷新tableview 滚动到底部
+    private func scrollMessageToBottom() {
+        DispatchQueue.main.async {
+            self.tableView.reloadData()
+            if self.chatMessageList.count > 0 {
+                self.tableView.scrollToRow(at: IndexPath(row: self.chatMessageList.count-1, section: 0), at: .bottom, animated: true)
+            }
+        }
+    }
+    
+    //发送文本消息
+    private func sendTextMessage() {
+        guard let msg = self.messageInputView.text else {
+            return
+        }
+        self.messageInputView.text = ""
+        let body = IMMessageBodyInfo()
+        body.type = o2_im_msg_type_text
+        body.body = msg
+        sendMessage(body: body)
+    }
+    //发送表情消息
+    private func sendEmojiMessage(emoji: String) {
+        let body = IMMessageBodyInfo()
+        body.type = o2_im_msg_type_emoji
+        body.body = emoji
+        sendMessage(body: body)
+    }
+    
+    //发送消息到服务器
+    private func sendMessage(body: IMMessageBodyInfo) {
+        let message = IMMessageInfo()
+        message.body = body.toJSONString()
+        message.id = UUID().uuidString
+        message.conversationId = self.conversation?.id
+        message.createPerson = O2AuthSDK.shared.myInfo()?.distinguishedName
+        message.createTime = Date().formatterDate(formatter: "yyyy-MM-dd HH:mm:ss")
+        //添加到界面
+        self.chatMessageList.append(message)
+        self.scrollMessageToBottom()
+        //发送消息到服务器
+        self.viewModel.sendMsg(msg: message)
+            .then { (result)  in
+                DDLogDebug("发送消息成功 \(result)")
+        }.catch { (error) in
+            DDLogError(error.localizedDescription)
+            self.showError(title: "发送消息失败!")
+        }
+    }
 
 
 
 
     // MARK: - IBAction
     // MARK: - IBAction
@@ -92,10 +144,17 @@ class IMChatViewController: UIViewController {
         self.isShowEmoji.toggle()
         self.isShowEmoji.toggle()
         self.view.endEditing(true)
         self.view.endEditing(true)
         if self.isShowEmoji {
         if self.isShowEmoji {
-            self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat + 128
+            self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat + self.emojiBarHeight.toCGFloat
+            self.emojiBar.delegate = self
+            self.emojiBar.translatesAutoresizingMaskIntoConstraints = false
+            self.bottomBar.addSubview(self.emojiBar)
+            let top = NSLayoutConstraint(item: self.emojiBar, attribute: .top, relatedBy: .equal, toItem: self.emojiBar.superview!, attribute: .top, multiplier: 1, constant: CGFloat(self.bottomBarHeight))
+            let width = NSLayoutConstraint(item: self.emojiBar, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: SCREEN_WIDTH)
+            let height = NSLayoutConstraint(item: self.emojiBar, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: self.emojiBarHeight.toCGFloat)
+            NSLayoutConstraint.activate([top, width, height])
         } else {
         } else {
             self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
             self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
-
+            self.emojiBar.removeFromSuperview()
         }
         }
         self.view.layoutIfNeeded()
         self.view.layoutIfNeeded()
     }
     }
@@ -103,6 +162,15 @@ class IMChatViewController: UIViewController {
 
 
 
 
 }
 }
+
+// MARK: - 表情点击 delegate
+extension IMChatViewController: IMChatEmojiBarClickDelegate {
+    func clickEmoji(emoji: String) {
+        DDLogDebug("发送表情消息 \(emoji)")
+        self.sendEmojiMessage(emoji: emoji)
+    }
+}
+
 // MARK: - tableview delegate
 // MARK: - tableview delegate
 extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
 extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
 
 
@@ -127,17 +195,8 @@ extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
     }
     }
     
     
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        
         tableView.deselectRow(at: indexPath, animated: false)
         tableView.deselectRow(at: indexPath, animated: false)
     }
     }
-//    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
-//        guard let c = cell as? IMChatMessageViewCell else {
-//            return
-//        }
-//        //todo
-//        c.setContent(item: self.chatMessageList[indexPath.row])
-//    }
-
 
 
 }
 }
 
 
@@ -151,12 +210,13 @@ extension IMChatViewController: UITextFieldDelegate {
 
 
     private func closeEmoji() {
     private func closeEmoji() {
         self.isShowEmoji = false
         self.isShowEmoji = false
-        self.bottomBarHeightConstraint.constant = 64
+        self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
         self.view.layoutIfNeeded()
         self.view.layoutIfNeeded()
     }
     }
 
 
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
     func textFieldShouldReturn(_ textField: UITextField) -> Bool {
         DDLogDebug("回车。。。。")
         DDLogDebug("回车。。。。")
+        self.sendTextMessage()
         return true
         return true
     }
     }
 }
 }

+ 38 - 19
o2ios/O2Platform/App/IM-聊天/IMViewModel.swift

@@ -13,12 +13,31 @@ class IMViewModel: NSObject {
     override init() {
     override init() {
         super.init()
         super.init()
     }
     }
-    
-    
+
+
     let communicateAPI = OOMoyaProvider<CommunicateAPI>()
     let communicateAPI = OOMoyaProvider<CommunicateAPI>()
 }
 }
 
 
 extension IMViewModel {
 extension IMViewModel {
+
+    //发送消息
+    func sendMsg(msg: IMMessageInfo) -> Promise<Bool> {
+        return Promise { fulfill, reject in
+            self.communicateAPI.request(.sendMsg(msg), completion: { result in
+                    let response = OOResult<BaseModelClass<OOCommonIdModel>>(result)
+                    if response.isResultSuccess() {
+                        if let _ = response.model?.data {
+                            fulfill(true)
+                        } else {
+                            reject(OOAppError.apiEmptyResultError)
+                        }
+                    } else {
+                        reject(response.error!)
+                    }
+                })
+        }
+    }
+
     //查询会话列表
     //查询会话列表
     func myConversationList() -> Promise<[IMConversationInfo]> {
     func myConversationList() -> Promise<[IMConversationInfo]> {
         return Promise { fulfill, reject in
         return Promise { fulfill, reject in
@@ -27,10 +46,10 @@ extension IMViewModel {
                 if response.isResultSuccess() {
                 if response.isResultSuccess() {
                     if let list = response.model?.data {
                     if let list = response.model?.data {
                         fulfill(list)
                         fulfill(list)
-                    }else {
+                    } else {
                         reject(OOAppError.apiEmptyResultError)
                         reject(OOAppError.apiEmptyResultError)
                     }
                     }
-                }else {
+                } else {
                     reject(response.error!)
                     reject(response.error!)
                 }
                 }
             })
             })
@@ -40,24 +59,24 @@ extension IMViewModel {
     func myMsgPageList(page: Int, conversationId: String) -> Promise<[IMMessageInfo]> {
     func myMsgPageList(page: Int, conversationId: String) -> Promise<[IMMessageInfo]> {
         return Promise { fulfill, reject in
         return Promise { fulfill, reject in
             self.communicateAPI.request(.msgListByPaging(page, 40, conversationId), completion: { result in
             self.communicateAPI.request(.msgListByPaging(page, 40, conversationId), completion: { result in
-                let response = OOResult<BaseModelClass<[IMMessageInfo]>>(result)
-                if response.isResultSuccess() {
-                    if let list = response.model?.data {
-                        //列表翻转
-                        let rList = list.sorted { (f, s) -> Bool in
-                            if let ft = f.createTime, let st = s.createTime {
-                                return ft.toDate(formatter: "yyyy-MM-dd HH:mm:ss") < st.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
+                    let response = OOResult<BaseModelClass<[IMMessageInfo]>>(result)
+                    if response.isResultSuccess() {
+                        if let list = response.model?.data {
+                            //列表翻转
+                            let rList = list.sorted { (f, s) -> Bool in
+                                if let ft = f.createTime, let st = s.createTime {
+                                    return ft.toDate(formatter: "yyyy-MM-dd HH:mm:ss") < st.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
+                                }
+                                return true
                             }
                             }
-                            return true
+                            fulfill(rList)
+                        } else {
+                            reject(OOAppError.apiEmptyResultError)
                         }
                         }
-                        fulfill(rList)
-                    }else {
-                        reject(OOAppError.apiEmptyResultError)
+                    } else {
+                        reject(response.error!)
                     }
                     }
-                }else {
-                    reject(response.error!)
-                }
-            })
+                })
         }
         }
     }
     }
 }
 }

+ 68 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatEmojiBarView.swift

@@ -0,0 +1,68 @@
+//
+//  IMChatEmojiBarView.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/11.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+import CocoaLumberjack
+
+protocol IMChatEmojiBarClickDelegate {
+    func clickEmoji(emoji: String)
+}
+
+class IMChatEmojiBarView: UIView {
+    
+    @IBOutlet weak var collectionView: UICollectionView!
+    
+    private let emojiList: [String] = {
+        var list: [String] = []
+        for i in 1...87 {
+            if i < 10 {
+                list.append("[0\(i)]")
+            }else {
+                list.append("[\(i)]")
+            }
+        }
+        return list
+    }()
+    
+    var delegate: IMChatEmojiBarClickDelegate? = nil
+    
+    override func awakeFromNib() {
+        collectionView.register(UINib(nibName: "IMChatEmojiItemCell", bundle: nil), forCellWithReuseIdentifier: "IMChatEmojiItemCell")
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        DDLogDebug("list size \(emojiList.count)")
+        
+    }
+}
+
+extension IMChatEmojiBarView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
+    
+    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return emojiList.count
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
+        return CGSize(width:SCREEN_WIDTH / 8, height: 52)
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        if let cell =  collectionView.dequeueReusableCell(withReuseIdentifier: "IMChatEmojiItemCell", for: indexPath) as? IMChatEmojiItemCell {
+            cell.setEmoji(emoji: self.emojiList[indexPath.row])
+            return cell
+        }
+        return UICollectionViewCell()
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if delegate != nil {
+            delegate?.clickEmoji(emoji: self.emojiList[indexPath.row])
+        }
+        collectionView.deselectItem(at: indexPath, animated: false)
+    }
+    
+}

+ 43 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatEmojiBarView.xib

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="IMChatEmojiBarView" customModule="O2Platform" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="256"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="Ard-Nz-Tlw">
+                    <rect key="frame" x="0.0" y="0.0" width="414" height="256"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                    <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="9JR-h1-hg9">
+                        <size key="itemSize" width="128" height="128"/>
+                        <size key="headerReferenceSize" width="0.0" height="0.0"/>
+                        <size key="footerReferenceSize" width="0.0" height="0.0"/>
+                        <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
+                    </collectionViewFlowLayout>
+                </collectionView>
+            </subviews>
+            <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+            <constraints>
+                <constraint firstItem="Ard-Nz-Tlw" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="CAd-rq-tVD"/>
+                <constraint firstItem="Ard-Nz-Tlw" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="CaO-m5-kmB"/>
+                <constraint firstItem="Ard-Nz-Tlw" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="sfG-sX-ZzB"/>
+                <constraint firstItem="Ard-Nz-Tlw" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="wmb-YF-ekq"/>
+            </constraints>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <connections>
+                <outlet property="collectionView" destination="Ard-Nz-Tlw" id="8ST-jl-atl"/>
+            </connections>
+            <point key="canvasLocation" x="100.00000000000001" y="-9.375"/>
+        </view>
+    </objects>
+</document>

+ 25 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatEmojiItemCell.swift

@@ -0,0 +1,25 @@
+//
+//  IMChatEmojiItemCell.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/11.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+
+class IMChatEmojiItemCell: UICollectionViewCell {
+    @IBOutlet weak var emojiImage: UIImageView!
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        // Initialization code
+    }
+    
+    func setEmoji(emoji: String) {
+        let bundle = Bundle().o2EmojiBundle(anyClass: IMChatEmojiItemCell.self)
+        let path = o2ImEmojiPath(emojiBody: emoji)
+        self.emojiImage.image = UIImage(named: path, in: bundle, compatibleWith: nil)
+    }
+
+}

+ 41 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatEmojiItemCell.xib

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="IMChatEmojiItemCell" customModule="O2Platform" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="52" height="52"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="52" height="52"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="JXV-Hl-6Xb">
+                        <rect key="frame" x="10" y="10" width="32" height="32"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="32" id="i41-s0-3eR"/>
+                            <constraint firstAttribute="width" constant="32" id="x6M-1W-tyM"/>
+                        </constraints>
+                    </imageView>
+                </subviews>
+            </view>
+            <constraints>
+                <constraint firstItem="JXV-Hl-6Xb" firstAttribute="centerX" secondItem="gTV-IL-0wX" secondAttribute="centerX" id="i60-Uy-DQL"/>
+                <constraint firstItem="JXV-Hl-6Xb" firstAttribute="centerY" secondItem="gTV-IL-0wX" secondAttribute="centerY" id="ssV-XP-TUi"/>
+            </constraints>
+            <viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
+            <size key="customSize" width="52" height="62"/>
+            <connections>
+                <outlet property="emojiImage" destination="JXV-Hl-6Xb" id="b2g-I1-yjf"/>
+            </connections>
+            <point key="canvasLocation" x="146.37681159420291" y="156.02678571428569"/>
+        </collectionViewCell>
+    </objects>
+</document>

+ 2 - 2
o2ios/O2Platform/App/O2MainController.swift

@@ -89,8 +89,8 @@ class O2MainController: UITabBarController, UITabBarControllerDelegate {
 
 
     private func _initControllers() {
     private func _initControllers() {
         //消息
         //消息
-        let conversationVC = JCConversationListViewController()
-//        let conversationVC = IMConversationListViewController()
+//        let conversationVC = JCConversationListViewController()
+        let conversationVC = IMConversationListViewController()
         conversationVC.title = "消息"
         conversationVC.title = "消息"
         let messages = ZLNavigationController(rootViewController: conversationVC)
         let messages = ZLNavigationController(rootViewController: conversationVC)
 
 

+ 6 - 1
o2ios/O2Platform/Framework/O2API/Communicate/CommunicateAPI.swift

@@ -14,6 +14,7 @@ import O2OA_Auth_SDK
 enum CommunicateAPI {
 enum CommunicateAPI {
     case myConversationList
     case myConversationList
     case msgListByPaging(Int, Int, String)
     case msgListByPaging(Int, Int, String)
+    case sendMsg(IMMessageInfo)
     
     
     
     
 }
 }
@@ -45,6 +46,8 @@ extension CommunicateAPI: TargetType {
             return "/jaxrs/im/conversation/list/my"
             return "/jaxrs/im/conversation/list/my"
         case .msgListByPaging(let page, let size, _):
         case .msgListByPaging(let page, let size, _):
             return "/jaxrs/im/msg/list/\(page)/size/\(size)"
             return "/jaxrs/im/msg/list/\(page)/size/\(size)"
+        case .sendMsg(_):
+            return "/jaxrs/im/msg"
         }
         }
     }
     }
     
     
@@ -52,7 +55,7 @@ extension CommunicateAPI: TargetType {
         switch self {
         switch self {
         case .myConversationList:
         case .myConversationList:
             return .get
             return .get
-        case .msgListByPaging(_, _, _):
+        case .msgListByPaging(_, _, _), .sendMsg(_):
             return .post
             return .post
         }
         }
     }
     }
@@ -69,6 +72,8 @@ extension CommunicateAPI: TargetType {
             let form = IMMessageRequestForm()
             let form = IMMessageRequestForm()
             form.conversationId = conversationId
             form.conversationId = conversationId
             return .requestParameters(parameters: form.toJSON()!, encoding: JSONEncoding.default)
             return .requestParameters(parameters: form.toJSON()!, encoding: JSONEncoding.default)
+        case .sendMsg(let msg):
+            return .requestParameters(parameters: msg.toJSON()!, encoding: JSONEncoding.default)
         }
         }
     }
     }