Procházet zdrojové kódy

ios通知消息可以打开对应的应用

fancy před 5 roky
rodič
revize
297f2dd08e

+ 63 - 2
o2ios/O2Platform/App/IM-聊天/IMChatViewController.swift

@@ -71,8 +71,9 @@ class IMChatViewController: UIViewController {
         self.tableView.register(UINib(nibName: "IMChatMessageViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageViewCell")
         self.tableView.register(UINib(nibName: "IMChatMessageSendViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageSendViewCell")
         self.tableView.separatorStyle = .none
-        self.tableView.rowHeight = UITableView.automaticDimension
-        self.tableView.estimatedRowHeight = 144
+//        self.tableView.rowHeight = UITableView.automaticDimension
+//        self.tableView.estimatedRowHeight = 144
+        self.tableView.backgroundColor = UIColor(hex: "#f3f3f3")
         self.messageInputView.delegate = self
 
         //底部安全距离 老机型没有
@@ -521,6 +522,38 @@ extension IMChatViewController: UIImagePickerControllerDelegate & UINavigationCo
 // MARK: - 图片消息点击 delegate
 extension IMChatViewController: IMChatMessageDelegate {
     
+    func openApplication(storyboard: String) {
+        if storyboard == "mind" {
+            let flutterViewController = O2FlutterViewController()
+            flutterViewController.setInitialRoute("mindMap")
+            self.present(flutterViewController, animated: false, completion: nil)
+        }else {
+            let storyBoard = UIStoryboard(name: storyboard, bundle: nil)
+            guard let destVC = storyBoard.instantiateInitialViewController() else {
+                return
+            }
+            destVC.modalPresentationStyle = .fullScreen
+            if destVC.isKind(of: ZLNavigationController.self) {
+                self.show(destVC, sender: nil)
+            }else{
+                self.navigationController?.pushViewController(destVC, animated: true)
+            }
+        }
+    }
+    
+    func openWork(workId: String) {
+        let storyBoard = UIStoryboard(name: "task", bundle: nil)
+        let destVC = storyBoard.instantiateViewController(withIdentifier: "todoTaskDetailVC") as! TodoTaskDetailViewController
+        let json = """
+        {"work":"\(workId)", "workCompleted":"", "title":""}
+        """
+        let todo = TodoTask(JSONString: json)
+        destVC.todoTask = todo
+        destVC.backFlag = 3 //隐藏就行
+        self.show(destVC, sender: nil)
+    }
+    
+    
     func openLocatinMap(info: IMMessageBodyInfo) {
         let map = IMShowLocationViewController()
         map.address = info.address
@@ -607,6 +640,34 @@ extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
         return UITableViewCell()
     }
 
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        let msg = self.chatMessageList[indexPath.row]
+        return cellHeight(item: msg)
+    }
+    
+    func cellHeight(item: IMMessageInfo) -> CGFloat {
+        if let jsonBody = item.body, let body = IMMessageBodyInfo.deserialize(from: jsonBody){
+            if body.type == o2_im_msg_type_emoji {
+                 // 上边距 69 + emoji高度 + 内边距 + 底部空白高度
+                 return 69 + 36 + 20 + 10
+            } else if body.type == o2_im_msg_type_image {
+                 // 上边距 69 + 图片高度 + 内边距 + 底部空白高度
+                 return 69 + 192 + 20 + 10
+            } else if o2_im_msg_type_audio == body.type {
+                 // 上边距 69 + audio高度 + 内边距 + 底部空白高度
+                 return 69 + IMAudioView.IMAudioView_height + 20 + 10
+            } else if o2_im_msg_type_location == body.type {
+                 // 上边距 69 + 位置图高度 + 内边距 + 底部空白高度
+                 return 69 + IMLocationView.IMLocationViewHeight + 20 + 10
+            } else {
+                let size = body.body!.getSizeWithMaxWidth(fontSize: 16, maxWidth: messageWidth)
+                // 上边距 69 + 文字高度 + 内边距 + 底部空白高度
+                return 69 + size.height + 28 + 10
+            }
+        }
+        return 132
+    }
+    
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         tableView.deselectRow(at: indexPath, animated: false)
     }

+ 62 - 5
o2ios/O2Platform/App/IM-聊天/IMInstantMessageViewController.swift

@@ -21,8 +21,8 @@ class IMInstantMessageViewController: UITableViewController {
         self.title = "通知消息"
         self.tableView.register(UINib(nibName: "IMChatMessageViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageViewCell")
         self.tableView.separatorStyle = .none
-        self.tableView.rowHeight = UITableView.automaticDimension
-        self.tableView.estimatedRowHeight = 144
+//        self.tableView.rowHeight = UITableView.automaticDimension
+//        self.tableView.estimatedRowHeight = 144
         self.tableView.backgroundColor = UIColor(hex: "#f3f3f3")
        
     }
@@ -49,16 +49,73 @@ class IMInstantMessageViewController: UITableViewController {
     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return self.instantMsgList.count
     }
-
-    
     
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         if let cell = tableView.dequeueReusableCell(withIdentifier: "IMChatMessageViewCell", for: indexPath) as? IMChatMessageViewCell {
             cell.setInstantContent(item: self.instantMsgList[indexPath.row])
+            cell.delegate = self
             return cell
         }
-
         return UITableViewCell()
     }
     
+    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return cellHeightForInstant(item: self.instantMsgList[indexPath.row])
+    }
+    
+    func cellHeightForInstant(item: InstantMessage) -> CGFloat {
+        if let msg = item.title {
+            let size = msg.getSizeWithMaxWidth(fontSize: 16, maxWidth: messageWidth)
+            // 上边距 69 + 文字高度 + 内边距 + 底部空白高度
+            return 69 + size.height + 28 + 10
+        }
+        return 132
+    }
+    
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        tableView.deselectRow(at: indexPath, animated: false)
+    }
+}
+
+extension IMInstantMessageViewController : IMChatMessageDelegate {
+    func clickImageMessage(info: IMMessageBodyInfo) {
+        //无需实现
+    }
+    
+    func openLocatinMap(info: IMMessageBodyInfo) {
+        //无需实现
+    }
+    
+    func openApplication(storyboard: String) {
+        if storyboard == "mind" {
+            let flutterViewController = O2FlutterViewController()
+            flutterViewController.setInitialRoute("mindMap")
+            self.present(flutterViewController, animated: false, completion: nil)
+        }else {
+            let storyBoard = UIStoryboard(name: storyboard, bundle: nil)
+            guard let destVC = storyBoard.instantiateInitialViewController() else {
+                return
+            }
+            destVC.modalPresentationStyle = .fullScreen
+            if destVC.isKind(of: ZLNavigationController.self) {
+                self.show(destVC, sender: nil)
+            }else{
+                self.navigationController?.pushViewController(destVC, animated: true)
+            }
+        }
+    }
+    
+    func openWork(workId: String) {
+        let storyBoard = UIStoryboard(name: "task", bundle: nil)
+        let destVC = storyBoard.instantiateViewController(withIdentifier: "todoTaskDetailVC") as! TodoTaskDetailViewController
+        let json = """
+        {"work":"\(workId)", "workCompleted":"", "title":""}
+        """
+        let todo = TodoTask(JSONString: json)
+        destVC.todoTask = todo
+        destVC.backFlag = 3 //隐藏就行
+        self.show(destVC, sender: nil)
+    }
+    
+    
 }

+ 2 - 0
o2ios/O2Platform/App/IM-聊天/O2IM.swift

@@ -30,6 +30,8 @@ let o2_im_msg_body_audio = "[语音]"
 let o2_im_msg_body_video = "[视频]"
 let o2_im_msg_body_location = "[位置]"
 
+let messageWidth: CGFloat = 176
+
 
 //表情的字符串转化为O2Emoji.bundle里面的图片路径 [01] -> im_emotion_01
 func o2ImEmojiPath(emojiBody: String) -> String {

+ 16 - 13
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageSendViewCell.swift

@@ -77,6 +77,8 @@ class IMChatMessageSendViewCell: UITableViewCell {
         }
     }
     
+    
+    
     //位置消息
     private func locationMsgRender(info: IMMessageBodyInfo) {
         self.messageBgWidth.constant = IMLocationView.IMLocationViewWidth + 20
@@ -199,11 +201,11 @@ class IMChatMessageSendViewCell: UITableViewCell {
     }
     
     private func textMsgRender(msg: String) {
-        let size = calTextSize(str: msg)
-        self.messageBgWidth.constant = size.width + 20
-        self.messageBgHeight.constant = size.height + 20
+        let size = msg.getSizeWithMaxWidth(fontSize: 16, maxWidth: messageWidth)
+        self.messageBgWidth.constant = size.width + 28
+        self.messageBgHeight.constant = size.height + 28
         //背景图片
-        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 20, height: size.height + 20))
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 28, height: size.height + 28))
         let insets = UIEdgeInsets(top: 28, left: 5, bottom: 5, right: 10); // 上、左、下、右
         var bubble = UIImage(named: "chat_bubble_outgoing")
         bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
@@ -213,14 +215,15 @@ class IMChatMessageSendViewCell: UITableViewCell {
         let label = generateMessagelabel(str: msg, size: size)
         label.translatesAutoresizingMaskIntoConstraints = false
         self.messageBackgroundView.addSubview(label)
-        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
-        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
-        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
-        NSLayoutConstraint.activate([top, left, right])
+        self.constraintWithContent(contentView: label)
+//        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
+//        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
+//        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
+//        NSLayoutConstraint.activate([top, left, right])
     }
     
     private func generateMessagelabel(str: String, size: CGSize) -> UILabel {
-        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
+        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width + 8, height: size.height + 8))
         label.text = str
         label.font = UIFont.systemFont(ofSize: 16)
         label.numberOfLines = 0
@@ -230,10 +233,10 @@ class IMChatMessageSendViewCell: UITableViewCell {
     }
     
     
-    private func calTextSize(str: String) -> CGSize {
-        let size = CGSize(width: 176, height: CGFloat(MAXFLOAT))
-        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
-    }
+//    private func calTextSize(str: String) -> CGSize {
+//        let size = CGSize(width: 176, height: CGFloat(MAXFLOAT))
+//        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
+//    }
     
     //解析json为消息对象
     private func parseJson(msg: String) -> IMMessageBodyInfo? {

+ 13 - 14
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageSendViewCell.xib

@@ -11,13 +11,13 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="129" id="KGk-i7-Jjw" customClass="IMChatMessageSendViewCell" customModule="O2Platform" customModuleProvider="target">
-            <rect key="frame" x="0.0" y="0.0" width="320" height="129"/>
+            <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
-                <rect key="frame" x="0.0" y="0.0" width="320" height="129"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="06-09 13:02" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k0L-ig-bhB">
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="06-09 13:02" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k0L-ig-bhB">
                         <rect key="frame" x="14" y="5" width="292" height="18"/>
                         <constraints>
                             <constraint firstAttribute="height" constant="18" id="MJ9-1n-RP4"/>
@@ -26,7 +26,7 @@
                         <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dRS-Ex-V2s">
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dRS-Ex-V2s">
                         <rect key="frame" x="258" y="31" width="48" height="48"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="48" id="ALp-AJ-k89"/>
@@ -38,8 +38,8 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </imageView>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="姓名" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O0d-aO-DEf">
-                        <rect key="frame" x="219" y="31" width="29" height="24"/>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="姓名" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O0d-aO-DEf">
+                        <rect key="frame" x="219" y="37" width="29" height="24"/>
                         <constraints>
                             <constraint firstAttribute="height" constant="24" id="hV4-hf-Q8a"/>
                         </constraints>
@@ -47,8 +47,8 @@
                         <nil key="textColor"/>
                         <nil key="highlightedColor"/>
                     </label>
-                    <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="73U-Yu-hhb">
-                        <rect key="frame" x="72" y="63" width="176" height="42"/>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="73U-Yu-hhb">
+                        <rect key="frame" x="72" y="69" width="176" height="42"/>
                         <constraints>
                             <constraint firstAttribute="height" constant="42" id="9m9-a5-elu"/>
                             <constraint firstAttribute="width" constant="176" id="B2b-ep-gRb"/>
@@ -58,14 +58,13 @@
                 <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
                 <constraints>
                     <constraint firstItem="k0L-ig-bhB" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="5" id="59J-ml-PYh"/>
-                    <constraint firstItem="73U-Yu-hhb" firstAttribute="top" secondItem="O0d-aO-DEf" secondAttribute="bottom" constant="8" id="6MU-oN-E2m"/>
+                    <constraint firstItem="O0d-aO-DEf" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="37" id="6NB-9d-uAN"/>
                     <constraint firstItem="k0L-ig-bhB" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="6QF-aq-QM6"/>
-                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="top" secondItem="k0L-ig-bhB" secondAttribute="bottom" constant="8" id="JfT-ce-huE"/>
-                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="leading" secondItem="73U-Yu-hhb" secondAttribute="trailing" constant="10" id="Njy-Bc-KtC"/>
-                    <constraint firstItem="O0d-aO-DEf" firstAttribute="top" secondItem="k0L-ig-bhB" secondAttribute="bottom" constant="8" id="VFs-xs-kta"/>
+                    <constraint firstItem="dRS-Ex-V2s" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="31" id="NCS-bP-NLG"/>
                     <constraint firstAttribute="trailing" secondItem="dRS-Ex-V2s" secondAttribute="trailing" constant="14" id="gmx-Y3-81p"/>
-                    <constraint firstAttribute="bottomMargin" secondItem="73U-Yu-hhb" secondAttribute="bottom" constant="10" id="j9W-5A-2om"/>
+                    <constraint firstAttribute="trailing" secondItem="73U-Yu-hhb" secondAttribute="trailing" constant="72" id="kmb-aR-DfK"/>
                     <constraint firstItem="dRS-Ex-V2s" firstAttribute="leading" secondItem="O0d-aO-DEf" secondAttribute="trailing" constant="10" id="ngR-6P-5QW"/>
+                    <constraint firstItem="73U-Yu-hhb" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="69" id="xdH-1U-slK"/>
                     <constraint firstAttribute="trailing" secondItem="k0L-ig-bhB" secondAttribute="trailing" constant="14" id="y21-uR-MhX"/>
                 </constraints>
             </tableViewCellContentView>

+ 151 - 17
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageViewCell.swift

@@ -12,6 +12,8 @@ import CocoaLumberjack
 protocol IMChatMessageDelegate {
     func clickImageMessage(info: IMMessageBodyInfo)
     func openLocatinMap(info: IMMessageBodyInfo)
+    func openApplication(storyboard: String)
+    func openWork(workId: String)
 }
 
 class IMChatMessageViewCell: UITableViewCell {
@@ -22,7 +24,7 @@ class IMChatMessageViewCell: UITableViewCell {
     @IBOutlet weak var messageBackgroundView: UIView!
     @IBOutlet weak var messageBackgroundWidth: NSLayoutConstraint!
     @IBOutlet weak var messageBackgroundHeight: NSLayoutConstraint!
-    private let messageWidth = 176
+    
 
     private lazy var audioView: IMAudioView = {
         let view = Bundle.main.loadNibNamed("IMAudioView", owner: self, options: nil)?.first as! IMAudioView
@@ -56,7 +58,8 @@ class IMChatMessageViewCell: UITableViewCell {
         }
         self.messageBackgroundView.removeSubviews()
         if let msg = item.title {
-            textMsgRender(msg: msg)
+            let msgLabel = textMsgRender(msg: msg)
+            setColorAndClickEvent(item: item, label: msgLabel)
         }
         if let type = item.type {
             if type.starts(with: "task_") {
@@ -98,6 +101,135 @@ class IMChatMessageViewCell: UITableViewCell {
             }
         }
     }
+    
+    private func setcc(label:UILabel, clickEvent: ((UITapGestureRecognizer)->Void)?) {
+        if let textString = label.text {
+            let attributedString = NSMutableAttributedString(string: textString)
+            attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: attributedString.length))
+            attributedString.addAttribute(.foregroundColor, value: base_blue_color, range: NSRange(location: 0, length: attributedString.length))
+            label.attributedText = attributedString
+            label.addTapGesture(action: clickEvent)
+        }
+    }
+    
+    private func setColorAndClickEvent(item: InstantMessage, label:UILabel) {
+        
+        func parseWorkId(body: String) -> String? {
+            if let jsonData = String(body).data(using: .utf8) {
+                let dicArr = try! JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as! [String:AnyObject]
+                if let work = dicArr["work"] as? String {
+                    return work
+                }
+                if let workCompleted = dicArr["workCompleted"] as? String {
+                    return workCompleted
+                }
+            }
+            return nil
+        }
+        
+        if let type = item.type {
+            if type.starts(with: "task_") {
+                if !type.contains("_delete") {
+                    guard let body = item.body else {
+                        return
+                    }
+                    guard let workId = parseWorkId(body: body) else {
+                        return
+                    }
+                    setcc(label: label) { tap in
+                        //打开工作 ?
+                        self.delegate?.openWork(workId: workId)
+                    }
+                }
+            } else if type.starts(with: "taskCompleted_") {
+                if !type.contains("_delete") {
+                    guard let body = item.body else {
+                        return
+                    }
+                    guard let workId = parseWorkId(body: body) else {
+                        return
+                    }
+                    setcc(label: label) { tap in
+                        //打开已办
+                        self.delegate?.openWork(workId: workId)
+                    }
+                }
+            } else if type.starts(with: "read_") {
+                if !type.contains("_delete") {
+                    guard let body = item.body else {
+                        return
+                    }
+                    guard let workId = parseWorkId(body: body) else {
+                        return
+                    }
+                    setcc(label: label) { tap in
+                        //打开待阅
+                        self.delegate?.openWork(workId: workId)
+                    }
+                }
+            } else if type.starts(with: "readCompleted_") {
+                if !type.contains("_delete") {
+                    guard let body = item.body else {
+                        return
+                    }
+                    guard let workId = parseWorkId(body: body) else {
+                        return
+                    }
+                    setcc(label: label) { tap in
+                        //打开已阅
+                        self.delegate?.openWork(workId: workId)
+                    }
+                }
+            } else if type.starts(with: "review_") || type.starts(with: "work_") || type.starts(with: "process_") {
+                if !type.contains("_delete") {
+                    guard let body = item.body else {
+                        return
+                    }
+                    guard let workId = parseWorkId(body: body) else {
+                        return
+                    }
+                    setcc(label: label) { tap in
+                        //打开 其他工作
+                        self.delegate?.openWork(workId: workId)
+                    }
+                }
+            } else if type.starts(with: "meeting_") {
+                setcc(label: label) { tap in
+                    //打开会议模块
+                    self.delegate?.openApplication(storyboard: "meeting")
+                }
+            } else if type.starts(with: "attachment_") {
+                setcc(label: label) { tap in
+                    //打开云盘
+                    self.delegate?.openApplication(storyboard: "CloudFile")
+                }
+            } else if type.starts(with: "calendar_") {
+                setcc(label: label) { tap in
+                    //打开日历
+                    self.delegate?.openApplication(storyboard: "calendar")
+                }
+            } else if type.starts(with: "cms_") {
+                setcc(label: label) { tap in
+                    //打开cms
+                    self.delegate?.openApplication(storyboard: "information")
+                }
+            } else if type.starts(with: "bbs_") {
+               setcc(label: label) { tap in
+                    //打开论坛
+                self.delegate?.openApplication(storyboard: "bbs")
+                }
+            } else if type.starts(with: "mind_") {
+                setcc(label: label) { tap in
+                    //打开脑图
+                    self.delegate?.openApplication(storyboard: "mind")
+                }
+            } else {
+                
+            }
+        }
+    }
+    
+    
 
     //聊天消息
     func setContent(item: IMMessageInfo) {
@@ -131,7 +263,7 @@ class IMChatMessageViewCell: UITableViewCell {
             } else if o2_im_msg_type_location == body.type {
                 locationMsgRender(info: body)
             } else {
-                textMsgRender(msg: body.body!)
+                _ = textMsgRender(msg: body.body!)
             }
         }
     }
@@ -258,12 +390,12 @@ class IMChatMessageViewCell: UITableViewCell {
         self.constraintWithContent(contentView: emojiImage)
     }
 
-    private func textMsgRender(msg: String) {
-        let size = calTextSize(str: msg)
-        self.messageBackgroundWidth.constant = size.width + 20
-        self.messageBackgroundHeight.constant = size.height + 20
+    private func textMsgRender(msg: String) -> UILabel {
+        let size = msg.getSizeWithMaxWidth(fontSize: 16, maxWidth: messageWidth)
+        self.messageBackgroundWidth.constant = size.width + 28
+        self.messageBackgroundHeight.constant = size.height + 28
         //背景图片
-        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 20, height: size.height + 20))
+        let bgImg = UIImageView(frame: CGRect(x: 0, y: 0, width: size.width + 28, height: size.height + 28))
         let insets = UIEdgeInsets(top: 28, left: 10, bottom: 5, right: 5); // 上、左、下、右
         var bubble = UIImage(named: "chat_bubble_incomming")
         bubble = bubble?.resizableImage(withCapInsets: insets, resizingMode: .stretch)
@@ -273,14 +405,16 @@ class IMChatMessageViewCell: UITableViewCell {
         let label = generateMessagelabel(str: msg, size: size)
         label.translatesAutoresizingMaskIntoConstraints = false
         self.messageBackgroundView.addSubview(label)
-        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
-        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
-        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
-        NSLayoutConstraint.activate([top, left, right])
+        self.constraintWithContent(contentView: label)
+        return label
+//        let top = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label.superview!, attribute: .top, multiplier: 1, constant: 10)
+//        let left = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: label.superview!, attribute: .leading, multiplier: 1, constant: 10)
+//        let right = NSLayoutConstraint(item: label.superview!, attribute: .trailing, relatedBy: .equal, toItem: label, attribute: .trailing, multiplier: 1, constant: 10)
+//        NSLayoutConstraint.activate([top, left, right])
     }
 
     private func generateMessagelabel(str: String, size: CGSize) -> UILabel {
-        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height))
+        let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width + 8, height: size.height + 8))
         label.text = str
         label.font = UIFont.systemFont(ofSize: 16)
         label.numberOfLines = 0
@@ -290,10 +424,10 @@ class IMChatMessageViewCell: UITableViewCell {
     }
 
 
-    private func calTextSize(str: String) -> CGSize {
-        let size = CGSize(width: messageWidth.toCGFloat, height: CGFloat(MAXFLOAT))
-        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
-    }
+//    private func calTextSize(str: String) -> CGSize {
+//        let size = CGSize(width: messageWidth.toCGFloat, height: CGFloat(MAXFLOAT))
+//        return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], context: nil).size
+//    }
 
     //解析json为消息对象
     private func parseJson(msg: String) -> IMMessageBodyInfo? {

+ 7 - 8
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageViewCell.xib

@@ -13,7 +13,7 @@
         <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="132" id="KGk-i7-Jjw" customClass="IMChatMessageViewCell" customModule="O2Platform" customModuleProvider="target">
             <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
                 <rect key="frame" x="0.0" y="0.0" width="320" height="132"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
@@ -39,7 +39,7 @@
                         <nil key="highlightedColor"/>
                     </label>
                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="姓名" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2r2-Sl-HFm">
-                        <rect key="frame" x="72" y="31" width="29" height="24"/>
+                        <rect key="frame" x="72" y="37" width="29" height="24"/>
                         <constraints>
                             <constraint firstAttribute="height" constant="24" id="4T7-qw-JEB"/>
                         </constraints>
@@ -48,7 +48,7 @@
                         <nil key="highlightedColor"/>
                     </label>
                     <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jxc-0S-MrS">
-                        <rect key="frame" x="72" y="63" width="176" height="42"/>
+                        <rect key="frame" x="72" y="69" width="176" height="42"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="176" id="0aZ-iT-9wn"/>
                             <constraint firstAttribute="height" constant="42" id="ah6-qa-1tp"/>
@@ -59,14 +59,13 @@
                 <constraints>
                     <constraint firstItem="Mov-YP-dlA" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="0dz-GG-NKV"/>
                     <constraint firstItem="fy3-Pu-FHB" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="33C-sl-5B1"/>
-                    <constraint firstItem="jxc-0S-MrS" firstAttribute="leading" secondItem="Mov-YP-dlA" secondAttribute="trailing" constant="10" id="3AB-04-3Ot"/>
                     <constraint firstAttribute="trailing" secondItem="fy3-Pu-FHB" secondAttribute="trailing" constant="14" id="AQO-Yx-K4D"/>
-                    <constraint firstItem="Mov-YP-dlA" firstAttribute="top" secondItem="fy3-Pu-FHB" secondAttribute="bottom" constant="8" id="Faw-qG-7Fy"/>
-                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="top" secondItem="fy3-Pu-FHB" secondAttribute="bottom" constant="8" id="GtC-yx-sjT"/>
+                    <constraint firstItem="jxc-0S-MrS" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="69" id="GLr-LT-32j"/>
                     <constraint firstItem="2r2-Sl-HFm" firstAttribute="leading" secondItem="Mov-YP-dlA" secondAttribute="trailing" constant="10" id="JYE-0i-s5S"/>
-                    <constraint firstAttribute="bottomMargin" secondItem="jxc-0S-MrS" secondAttribute="bottom" constant="10" id="Tpo-I1-lKY"/>
                     <constraint firstItem="fy3-Pu-FHB" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="5" id="VVF-dB-vnY"/>
-                    <constraint firstItem="jxc-0S-MrS" firstAttribute="top" secondItem="2r2-Sl-HFm" secondAttribute="bottom" constant="8" id="gYS-LW-7T4"/>
+                    <constraint firstItem="jxc-0S-MrS" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="72" id="iJn-Op-hcs"/>
+                    <constraint firstItem="Mov-YP-dlA" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="31" id="ltH-hE-V43"/>
+                    <constraint firstItem="2r2-Sl-HFm" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="37" id="vM3-Gj-y2a"/>
                 </constraints>
             </tableViewCellContentView>
             <viewLayoutGuide key="safeArea" id="njF-e1-oar"/>

+ 6 - 0
o2ios/O2Platform/Extension/String+Extenstion.swift

@@ -84,6 +84,12 @@ extension String {
         return str.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)], context: nil).size
     }
     
+    // MARK: - 根据固定宽度获取字符串在label中的size
+    func getSizeWithMaxWidth(fontSize:CGFloat, maxWidth: CGFloat) -> CGSize {
+        let size = CGSize(width: maxWidth, height: CGFloat(MAXFLOAT))
+        return self.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)], context: nil).size
+    }
+    
     // MARK:- 获取文本图片
     func getTextImage(_ size:CGSize,textColor tColor:UIColor,backColor bColor:UIColor,textFont tFont:UIFont) -> UIImage? {
         let label = UILabel(frame: CGRect(origin:CGPoint(x:0,y:0), size: size))