Sfoglia il codice sorgente

Merge branch 'feature/ios_bbs_attachment' into 'develop'

ios 打卡定位不出来的bug,论坛帖子附件查看功能

See merge request o2oa/o2oa!894
楼国栋 5 anni fa
parent
commit
bb00e6a91f

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

@@ -258,6 +258,9 @@
 		B1E95FA72375155F004876B7 /* CloudFileBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E95FA62375155F004876B7 /* CloudFileBaseVC.swift */; };
 		B1EE2CCE2281729400842F48 /* QDatePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EE2CCD2281729400842F48 /* QDatePicker.swift */; };
 		B1EE2CD02281771600842F48 /* O2JsApiUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EE2CCF2281771600842F48 /* O2JsApiUtil.swift */; };
+		B1F6CDBE24A88D26005CB1E0 /* BBSViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F6CDBD24A88D26005CB1E0 /* BBSViewModel.swift */; };
+		B1F6CDEE24A893B6005CB1E0 /* BBSSubjectAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F6CDED24A893B6005CB1E0 /* BBSSubjectAttachmentViewController.swift */; };
+		B1F6CDF024A89836005CB1E0 /* BBSSubjectAttachmentViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F6CDEF24A89836005CB1E0 /* BBSSubjectAttachmentViewCell.swift */; };
 		B1FAE9E12115F95800981A25 /* OOCalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FAE9E02115F95800981A25 /* OOCalendarViewController.swift */; };
 		B1FAFD442105C23B008A0CDF /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FAFD432105C23B008A0CDF /* Operators.swift */; };
 		B1FB9FAE2302891F00A90722 /* ContactPickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB9FAD2302891F00A90722 /* ContactPickerViewModel.swift */; };
@@ -1594,6 +1597,9 @@
 		B1E95FA62375155F004876B7 /* CloudFileBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileBaseVC.swift; sourceTree = "<group>"; };
 		B1EE2CCD2281729400842F48 /* QDatePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QDatePicker.swift; sourceTree = "<group>"; };
 		B1EE2CCF2281771600842F48 /* O2JsApiUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = O2JsApiUtil.swift; sourceTree = "<group>"; };
+		B1F6CDBD24A88D26005CB1E0 /* BBSViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBSViewModel.swift; sourceTree = "<group>"; };
+		B1F6CDED24A893B6005CB1E0 /* BBSSubjectAttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBSSubjectAttachmentViewController.swift; sourceTree = "<group>"; };
+		B1F6CDEF24A89836005CB1E0 /* BBSSubjectAttachmentViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBSSubjectAttachmentViewCell.swift; sourceTree = "<group>"; };
 		B1FAE9E02115F95800981A25 /* OOCalendarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OOCalendarViewController.swift; sourceTree = "<group>"; };
 		B1FAFD432105C23B008A0CDF /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
 		B1FB9FAD2302891F00A90722 /* ContactPickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactPickerViewModel.swift; sourceTree = "<group>"; };
@@ -3288,6 +3294,7 @@
 				E41441D71DCAC5C600E3DDA3 /* c */,
 				E41441D81DCAC5C600E3DDA3 /* m */,
 				E41441D91DCAC5C600E3DDA3 /* v */,
+				B1F6CDBD24A88D26005CB1E0 /* BBSViewModel.swift */,
 			);
 			path = "BBS-论坛";
 			sourceTree = "<group>";
@@ -3301,6 +3308,7 @@
 				E46E6BF61DD2C8B500AB7561 /* BBSReplySubjectViewController.swift */,
 				E4418C6C1DDD5D6A0066348D /* BBSSubjectCreateTableViewController.swift */,
 				E47EF77C1DDDC78300B5B8C2 /* BBSSubjectContentViewController.swift */,
+				B1F6CDED24A893B6005CB1E0 /* BBSSubjectAttachmentViewController.swift */,
 			);
 			path = c;
 			sourceTree = "<group>";
@@ -3320,6 +3328,7 @@
 				E41441E01DCB248C00E3DDA3 /* BBSForumCell.swift */,
 				E4740ABE1DCC267100686780 /* BBSHeaderCollectionReusableView.swift */,
 				E4740AC01DCC45A300686780 /* SubjectTableViewCell.swift */,
+				B1F6CDEF24A89836005CB1E0 /* BBSSubjectAttachmentViewCell.swift */,
 			);
 			path = v;
 			sourceTree = "<group>";
@@ -5949,6 +5958,7 @@
 				E4B8889E1D9D48F1002E1A46 /* MJRefreshFooter.m in Sources */,
 				E4F45446208EC359002FBC32 /* OOPersonsViewController.swift in Sources */,
 				09E02E841F16319600579887 /* CGSize+Swift.swift in Sources */,
+				B1F6CDBE24A88D26005CB1E0 /* BBSViewModel.swift in Sources */,
 				E4B888751D9D48F1002E1A46 /* Department.swift in Sources */,
 				E4C24B6D20844F3C00E426B0 /* JCAlertView.swift in Sources */,
 				B190923521071777009A7906 /* OOCalendarModels.swift in Sources */,
@@ -6096,6 +6106,8 @@
 				B167F7662362C60200F182B8 /* CloudFileMoveFolderCell.swift in Sources */,
 				B165CD5C2242093500373B66 /* CoverHorizontalAnimation.swift in Sources */,
 				B1908E1422685E8F00D75632 /* O2WebViewModels.swift in Sources */,
+				B1F6CDF024A89836005CB1E0 /* BBSSubjectAttachmentViewCell.swift in Sources */,
+				B1F6CDEE24A893B6005CB1E0 /* BBSSubjectAttachmentViewController.swift in Sources */,
 				E4B69738207602A40062F6E8 /* OOAccessTokenAuthorizable.swift in Sources */,
 				E4C24BB120844F3C00E426B0 /* JCMessageOptions.swift in Sources */,
 				E4B8889C1D9D48F1002E1A46 /* MJRefreshBackFooter.m in Sources */,

+ 56 - 0
o2ios/O2Platform/App/BBS-论坛/BBSViewModel.swift

@@ -0,0 +1,56 @@
+//
+//  BBSViewModel.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/28.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import Promises
+
+
+
+class BBSViewModel : NSObject {
+    override init() {
+        super.init()
+    }
+    private let bbsAPI = OOMoyaProvider<O2BBSAPI>()
+}
+
+extension BBSViewModel {
+    
+    //获取附件列表
+    func getSubjectAttachmentList(subjectId: String) -> Promise<[O2BBSSubjectAttachmentInfo]> {
+        return Promise{ fulfill, reject in
+            self.bbsAPI.request(.getSubjectAttachmentList(subjectId), completion: { result in
+                let response = OOResult<BaseModelClass<[O2BBSSubjectAttachmentInfo]>>(result)
+                if response.isResultSuccess() {
+                    if let data = response.model?.data {
+                        fulfill(data)
+                    }else {
+                        reject(OOAppError.apiEmptyResultError)
+                    }
+                }else {
+                    reject(response.error!)
+                }
+            })
+        }
+    }
+    
+    //下载附件
+    func downloadAttachment(att: O2BBSSubjectAttachmentInfo) -> Promise<URL> {
+        return Promise { fulfill, reject in
+            self.bbsAPI.request(.downloadAttachForSubject(att), completion: {result in
+                switch result {
+                case .success(_):
+                    //下载成功
+                    let fileURL = O2CloudFileManager.shared.cloudFileLocalFolder().appendingPathComponent(att.fileName!)
+                    fulfill(fileURL)
+                case .failure(let err):
+                    reject(err)
+                }
+            })
+        }
+    }
+    
+}

+ 230 - 94
o2ios/O2Platform/App/BBS-论坛/bbs.storyboard

@@ -1,12 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="WEC-RV-idi">
-    <device id="retina5_5" orientation="portrait">
-        <adaptation id="fullscreen"/>
-    </device>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="WEC-RV-idi">
+    <device id="retina5_5" orientation="portrait" appearance="light"/>
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
-        <capability name="Alignment constraints to the first baseline" minToolsVersion="6.0"/>
-        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
@@ -73,13 +70,13 @@
                                     <autoresizingMask key="autoresizingMask"/>
                                     <subviews>
                                         <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="todoedStatusIcon" translatesAutoresizingMaskIntoConstraints="NO" id="eCw-XQ-nPh">
-                                            <rect key="frame" x="8" y="13" width="15" height="15"/>
+                                            <rect key="frame" x="8" y="13" width="15" height="14"/>
                                             <constraints>
                                                 <constraint firstAttribute="width" constant="15" id="PmP-an-at8"/>
                                             </constraints>
                                         </imageView>
                                         <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="分区标题" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="44b-Jk-OK6">
-                                            <rect key="frame" x="28" y="10" width="339" height="21"/>
+                                            <rect key="frame" x="28" y="9.6666666666666643" width="378" height="21"/>
                                             <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="15"/>
                                             <nil key="textColor"/>
                                             <nil key="highlightedColor"/>
@@ -149,54 +146,54 @@
                                         <rect key="frame" x="0.0" y="28" width="414" height="70"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ErA-A6-5RQ" id="YdI-rU-dXv">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="69.666666666666671"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="70"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="8Z6-6I-uQ0">
-                                                    <rect key="frame" x="8" y="14" width="40" height="40"/>
+                                                    <rect key="frame" x="20" y="17" width="40" height="36"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="40" id="PtW-Yl-UQc"/>
                                                     </constraints>
                                                 </imageView>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="标题" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kik-Ss-LkJ">
-                                                    <rect key="frame" x="56" y="3" width="328" height="21"/>
+                                                    <rect key="frame" x="68" y="6" width="304" height="21"/>
                                                     <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="15"/>
                                                     <nil key="textColor"/>
                                                     <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="v8A-H1-kpy">
-                                                    <rect key="frame" x="56" y="24" width="350" height="21"/>
+                                                    <rect key="frame" x="68" y="27" width="326" height="16"/>
                                                     <fontDescription key="fontDescription" name="PingFangSC-Light" family="PingFang SC" pointSize="12"/>
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
                                                 <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_bbs_top" translatesAutoresizingMaskIntoConstraints="NO" id="e3D-3V-MR0">
-                                                    <rect key="frame" x="386" y="3" width="20" height="19"/>
+                                                    <rect key="frame" x="374" y="6" width="20" height="19"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="20" id="4Hn-Sw-BFq"/>
                                                     </constraints>
                                                 </imageView>
                                                 <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_bbs_view" translatesAutoresizingMaskIntoConstraints="NO" id="ra0-aj-i6e">
-                                                    <rect key="frame" x="325" y="50" width="15" height="15"/>
+                                                    <rect key="frame" x="313" y="48" width="15" height="15"/>
                                                     <constraints>
                                                         <constraint firstAttribute="height" constant="15" id="YBi-9q-hPx"/>
                                                         <constraint firstAttribute="width" constant="15" id="bKQ-tk-RSJ"/>
                                                     </constraints>
                                                 </imageView>
                                                 <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_bbs_reply" translatesAutoresizingMaskIntoConstraints="NO" id="JKc-Vg-H3T">
-                                                    <rect key="frame" x="365" y="50" width="15" height="15"/>
+                                                    <rect key="frame" x="353" y="48" width="15" height="15"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="15" id="qng-1A-KDn"/>
                                                     </constraints>
                                                 </imageView>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="日期" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zed-8e-goT">
-                                                    <rect key="frame" x="56" y="47" width="269" height="21"/>
+                                                    <rect key="frame" x="68" y="45" width="245" height="21"/>
                                                     <fontDescription key="fontDescription" name="PingFangSC-Light" family="PingFang SC" pointSize="12"/>
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OQZ-wY-Eqd">
-                                                    <rect key="frame" x="340" y="50" width="23" height="15"/>
+                                                    <rect key="frame" x="328" y="48" width="23" height="15"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="23" id="vNO-0X-FKq"/>
                                                     </constraints>
@@ -205,7 +202,7 @@
                                                     <nil key="highlightedColor"/>
                                                 </label>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ad6-Es-Z2s">
-                                                    <rect key="frame" x="380" y="50" width="23" height="15"/>
+                                                    <rect key="frame" x="368" y="48" width="23" height="15"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="23" id="a36-n3-yZt"/>
                                                     </constraints>
@@ -290,169 +287,180 @@
                             <tableViewSection headerTitle="发帖信息" id="OTR-Rg-Xlz">
                                 <cells>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="SsA-gX-Rbw">
-                                        <rect key="frame" x="0.0" y="55.333333333333336" width="414" height="50"/>
+                                        <rect key="frame" x="0.0" y="55.333332061767578" width="414" height="50"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="SsA-gX-Rbw" id="4ze-PR-4jQ">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="49.666666666666664"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="发帖版块" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c5v-yv-12W">
+                                                    <rect key="frame" x="20" y="17" width="89" height="15"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="width" constant="89" id="dGu-FD-09P"/>
+                                                    </constraints>
+                                                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                                    <nil key="textColor"/>
+                                                    <nil key="highlightedColor"/>
+                                                </label>
                                                 <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="10N-By-qwX">
-                                                    <rect key="frame" x="105" y="0.0" width="1" height="49"/>
+                                                    <rect key="frame" x="117" y="0.0" width="1" height="49"/>
                                                     <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
                                                     <constraints>
                                                         <constraint firstAttribute="height" constant="49" id="f5Y-Ru-yr8"/>
                                                         <constraint firstAttribute="width" constant="1" id="n96-im-SIj"/>
                                                     </constraints>
                                                 </view>
-                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="发帖版块" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m5F-2L-UB0">
-                                                    <rect key="frame" x="114" y="14" width="253" height="21"/>
-                                                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="发帖版块" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m5F-2L-UB0">
+                                                    <rect key="frame" x="126" y="15" width="244" height="19"/>
                                                     <fontDescription key="fontDescription" name="PingFangSC-Regular" family="PingFang SC" pointSize="14"/>
                                                     <color key="textColor" red="0.070588235294117646" green="0.070588235294117646" blue="0.070588235294117646" alpha="1" colorSpace="calibratedRGB"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
-                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="发帖版块" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c5v-yv-12W">
-                                                    <rect key="frame" x="43" y="14" width="54" height="21"/>
-                                                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
-                                                    <nil key="textColor"/>
-                                                    <nil key="highlightedColor"/>
-                                                </label>
                                             </subviews>
                                             <constraints>
+                                                <constraint firstItem="c5v-yv-12W" firstAttribute="leading" secondItem="4ze-PR-4jQ" secondAttribute="leadingMargin" id="4LL-7f-Q61"/>
                                                 <constraint firstItem="10N-By-qwX" firstAttribute="top" secondItem="4ze-PR-4jQ" secondAttribute="top" id="6g6-l3-RzA"/>
+                                                <constraint firstAttribute="bottomMargin" secondItem="m5F-2L-UB0" secondAttribute="bottom" constant="4" id="Gj5-U2-Gsd"/>
                                                 <constraint firstAttribute="bottom" secondItem="10N-By-qwX" secondAttribute="bottom" id="LH3-jg-c6Q"/>
+                                                <constraint firstAttribute="bottomMargin" secondItem="c5v-yv-12W" secondAttribute="bottom" constant="6" id="MIa-Aa-7MP"/>
+                                                <constraint firstItem="m5F-2L-UB0" firstAttribute="top" secondItem="4ze-PR-4jQ" secondAttribute="topMargin" constant="4" id="OCO-eZ-FFc"/>
+                                                <constraint firstItem="m5F-2L-UB0" firstAttribute="leading" secondItem="10N-By-qwX" secondAttribute="trailing" constant="8" id="PMc-Sn-c5e"/>
                                                 <constraint firstItem="10N-By-qwX" firstAttribute="leading" secondItem="c5v-yv-12W" secondAttribute="trailing" constant="8" id="R9a-kF-AJw"/>
-                                                <constraint firstItem="c5v-yv-12W" firstAttribute="centerY" secondItem="10N-By-qwX" secondAttribute="centerY" id="fBb-5n-vka"/>
-                                                <constraint firstItem="c5v-yv-12W" firstAttribute="top" secondItem="4ze-PR-4jQ" secondAttribute="topMargin" constant="6" id="puI-zS-lgB"/>
-                                                <constraint firstItem="c5v-yv-12W" firstAttribute="leading" secondItem="4ze-PR-4jQ" secondAttribute="leadingMargin" constant="35" id="wFL-ZP-X9Q"/>
+                                                <constraint firstAttribute="trailingMargin" secondItem="m5F-2L-UB0" secondAttribute="trailing" constant="24" id="iNc-n6-VUt"/>
+                                                <constraint firstItem="c5v-yv-12W" firstAttribute="top" secondItem="4ze-PR-4jQ" secondAttribute="topMargin" constant="6" id="m6G-Q7-yt6"/>
                                             </constraints>
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="aP3-PV-VE0">
-                                        <rect key="frame" x="0.0" y="105.33333333333334" width="414" height="50"/>
+                                        <rect key="frame" x="0.0" y="105.33333206176758" width="414" height="50"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="aP3-PV-VE0" id="68U-mJ-dtd">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="49.666666666666664"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
-                                                <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jej-9K-Wwd">
-                                                    <rect key="frame" x="105" y="0.0" width="40" height="49"/>
-                                                    <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
-                                                </view>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="主题分类" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bq6-o8-XQc">
-                                                    <rect key="frame" x="43" y="14" width="54" height="21"/>
+                                                    <rect key="frame" x="20" y="17" width="89" height="16"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="width" constant="89" id="0X1-bp-qUG"/>
+                                                    </constraints>
                                                     <fontDescription key="fontDescription" type="system" pointSize="13"/>
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
-                                                <pickerView contentMode="left" translatesAutoresizingMaskIntoConstraints="NO" id="O4S-3V-wYR">
-                                                    <rect key="frame" x="153" y="4" width="142" height="40"/>
+                                                <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jej-9K-Wwd">
+                                                    <rect key="frame" x="117" y="0.0" width="1" height="50"/>
+                                                    <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
                                                     <constraints>
-                                                        <constraint firstAttribute="width" constant="142" id="RLr-iY-eA3"/>
+                                                        <constraint firstAttribute="width" constant="1" id="gvD-g8-nLP"/>
                                                     </constraints>
+                                                </view>
+                                                <pickerView contentMode="left" translatesAutoresizingMaskIntoConstraints="NO" id="O4S-3V-wYR">
+                                                    <rect key="frame" x="126" y="-83" width="276" height="216"/>
                                                 </pickerView>
                                             </subviews>
                                             <constraints>
+                                                <constraint firstAttribute="bottomMargin" secondItem="bq6-o8-XQc" secondAttribute="bottom" constant="6" id="0ni-gU-aaq"/>
                                                 <constraint firstItem="jej-9K-Wwd" firstAttribute="top" secondItem="68U-mJ-dtd" secondAttribute="top" id="B1w-Kr-Kfw"/>
                                                 <constraint firstItem="jej-9K-Wwd" firstAttribute="centerY" secondItem="O4S-3V-wYR" secondAttribute="centerY" id="Cwh-GD-EWg"/>
+                                                <constraint firstItem="bq6-o8-XQc" firstAttribute="top" secondItem="68U-mJ-dtd" secondAttribute="topMargin" constant="6" id="OaW-D1-iXG"/>
                                                 <constraint firstAttribute="bottom" secondItem="jej-9K-Wwd" secondAttribute="bottom" id="RPX-TD-sna"/>
-                                                <constraint firstItem="jej-9K-Wwd" firstAttribute="leading" secondItem="bq6-o8-XQc" secondAttribute="trailing" constant="8" symbolic="YES" id="ReC-44-FA0"/>
-                                                <constraint firstItem="bq6-o8-XQc" firstAttribute="top" secondItem="68U-mJ-dtd" secondAttribute="topMargin" constant="6" id="ajf-ZP-AKs"/>
-                                                <constraint firstItem="O4S-3V-wYR" firstAttribute="top" secondItem="68U-mJ-dtd" secondAttribute="topMargin" constant="-4" id="eQM-mi-5vL"/>
-                                                <constraint firstItem="bq6-o8-XQc" firstAttribute="leading" secondItem="68U-mJ-dtd" secondAttribute="leadingMargin" constant="35" id="hCw-dm-9Q3"/>
-                                                <constraint firstItem="O4S-3V-wYR" firstAttribute="trailing" secondItem="68U-mJ-dtd" secondAttribute="trailingMargin" constant="-111" id="khw-9H-d5g"/>
-                                                <constraint firstItem="O4S-3V-wYR" firstAttribute="leading" secondItem="jej-9K-Wwd" secondAttribute="trailing" constant="8" symbolic="YES" id="oIN-ay-8aQ"/>
-                                                <constraint firstItem="bq6-o8-XQc" firstAttribute="centerY" secondItem="jej-9K-Wwd" secondAttribute="centerY" id="zjL-mV-Stb"/>
+                                                <constraint firstItem="jej-9K-Wwd" firstAttribute="leading" secondItem="bq6-o8-XQc" secondAttribute="trailing" constant="8" id="ReC-44-FA0"/>
+                                                <constraint firstItem="bq6-o8-XQc" firstAttribute="leading" secondItem="68U-mJ-dtd" secondAttribute="leadingMargin" id="hCw-dm-9Q3"/>
+                                                <constraint firstItem="O4S-3V-wYR" firstAttribute="trailing" secondItem="68U-mJ-dtd" secondAttribute="trailingMargin" constant="8" id="khw-9H-d5g"/>
+                                                <constraint firstItem="O4S-3V-wYR" firstAttribute="leading" secondItem="jej-9K-Wwd" secondAttribute="trailing" constant="8" id="oIN-ay-8aQ"/>
                                             </constraints>
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="Hli-rZ-69M">
-                                        <rect key="frame" x="0.0" y="155.33333333333334" width="414" height="50"/>
+                                        <rect key="frame" x="0.0" y="155.33333206176758" width="414" height="50"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Hli-rZ-69M" id="hqn-jq-lGd">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="49.666666666666664"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="主题" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eKF-8f-lk7">
-                                                    <rect key="frame" x="42" y="17" width="54" height="16"/>
+                                                    <rect key="frame" x="20" y="17" width="89" height="16"/>
                                                     <constraints>
-                                                        <constraint firstAttribute="width" constant="54" id="50E-aB-Kt6"/>
+                                                        <constraint firstAttribute="width" constant="89" id="50E-aB-Kt6"/>
                                                     </constraints>
                                                     <fontDescription key="fontDescription" type="system" pointSize="13"/>
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
+                                                <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="weU-We-eXr">
+                                                    <rect key="frame" x="117" y="0.0" width="1" height="50"/>
+                                                    <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="width" constant="1" id="NVz-Wh-aFM"/>
+                                                    </constraints>
+                                                </view>
                                                 <textField opaque="NO" clipsSubviews="YES" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="P2q-FF-3d3">
-                                                    <rect key="frame" x="156" y="9" width="250" height="30"/>
+                                                    <rect key="frame" x="126" y="13" width="276" height="24"/>
                                                     <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
                                                     <constraints>
-                                                        <constraint firstAttribute="width" constant="250" id="XuE-Tb-NXG"/>
+                                                        <constraint firstAttribute="height" constant="24" id="YEY-jO-Zwu"/>
                                                     </constraints>
-                                                    <nil key="textColor"/>
                                                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                     <textInputTraits key="textInputTraits" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
                                                 </textField>
-                                                <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="weU-We-eXr">
-                                                    <rect key="frame" x="105" y="0.0" width="40" height="49"/>
-                                                    <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
-                                                </view>
                                             </subviews>
                                             <constraints>
+                                                <constraint firstItem="eKF-8f-lk7" firstAttribute="leading" secondItem="hqn-jq-lGd" secondAttribute="leadingMargin" id="2ht-LN-tZ4"/>
                                                 <constraint firstItem="weU-We-eXr" firstAttribute="top" secondItem="hqn-jq-lGd" secondAttribute="top" id="3wN-QW-05b"/>
                                                 <constraint firstItem="weU-We-eXr" firstAttribute="centerY" secondItem="P2q-FF-3d3" secondAttribute="centerY" id="Jx1-9Q-gRk"/>
-                                                <constraint firstItem="weU-We-eXr" firstAttribute="leading" secondItem="eKF-8f-lk7" secondAttribute="trailing" constant="9" id="Mfx-j3-i85"/>
-                                                <constraint firstItem="P2q-FF-3d3" firstAttribute="top" secondItem="hqn-jq-lGd" secondAttribute="topMargin" constant="1" id="Y3Y-Ob-6hb"/>
-                                                <constraint firstItem="eKF-8f-lk7" firstAttribute="centerY" secondItem="weU-We-eXr" secondAttribute="centerY" id="bZe-Zk-9Kw"/>
-                                                <constraint firstItem="P2q-FF-3d3" firstAttribute="trailing" secondItem="hqn-jq-lGd" secondAttribute="trailingMargin" id="fLv-mH-Rvr"/>
-                                                <constraint firstItem="P2q-FF-3d3" firstAttribute="leading" secondItem="weU-We-eXr" secondAttribute="trailing" constant="11" id="iUS-dO-YOe"/>
-                                                <constraint firstItem="weU-We-eXr" firstAttribute="leading" secondItem="hqn-jq-lGd" secondAttribute="leading" constant="105" id="kwR-gv-DZs"/>
+                                                <constraint firstItem="weU-We-eXr" firstAttribute="leading" secondItem="eKF-8f-lk7" secondAttribute="trailing" constant="8" id="PG5-Fx-XgM"/>
+                                                <constraint firstAttribute="bottomMargin" secondItem="eKF-8f-lk7" secondAttribute="bottom" constant="6" id="ep8-da-lRJ"/>
+                                                <constraint firstItem="P2q-FF-3d3" firstAttribute="trailing" secondItem="hqn-jq-lGd" secondAttribute="trailingMargin" constant="8" id="fLv-mH-Rvr"/>
+                                                <constraint firstItem="eKF-8f-lk7" firstAttribute="top" secondItem="hqn-jq-lGd" secondAttribute="topMargin" constant="6" id="h9A-g0-4M7"/>
+                                                <constraint firstItem="P2q-FF-3d3" firstAttribute="leading" secondItem="weU-We-eXr" secondAttribute="trailing" constant="8" id="iUS-dO-YOe"/>
                                                 <constraint firstAttribute="bottom" secondItem="weU-We-eXr" secondAttribute="bottom" id="xDa-xi-lHS"/>
                                             </constraints>
                                         </tableViewCellContentView>
                                     </tableViewCell>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="5To-8g-yGx">
-                                        <rect key="frame" x="0.0" y="205.33333333333334" width="414" height="50"/>
+                                        <rect key="frame" x="0.0" y="205.33333206176758" width="414" height="50"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5To-8g-yGx" id="hnE-2h-G77">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="49.666666666666664"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="摘要" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="j89-tM-Che">
-                                                    <rect key="frame" x="43" y="14" width="54" height="21"/>
+                                                    <rect key="frame" x="20" y="17" width="89" height="15"/>
                                                     <constraints>
-                                                        <constraint firstAttribute="width" constant="54" id="vr9-VH-V3L"/>
+                                                        <constraint firstAttribute="width" constant="89" id="vr9-VH-V3L"/>
                                                     </constraints>
                                                     <fontDescription key="fontDescription" type="system" pointSize="13"/>
                                                     <nil key="textColor"/>
                                                     <nil key="highlightedColor"/>
                                                 </label>
                                                 <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9Wf-8S-tJ9">
-                                                    <rect key="frame" x="105" y="0.0" width="1" height="49"/>
+                                                    <rect key="frame" x="117" y="0.0" width="1" height="49"/>
                                                     <color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="1" colorSpace="calibratedRGB"/>
                                                     <constraints>
                                                         <constraint firstAttribute="width" constant="1" id="bfK-wO-keP"/>
-                                                        <constraint firstAttribute="height" constant="49" id="onb-Ld-PFX"/>
                                                     </constraints>
                                                 </view>
                                                 <textField opaque="NO" clipsSubviews="YES" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="QW9-uT-w7q">
-                                                    <rect key="frame" x="117" y="9" width="289" height="30"/>
+                                                    <rect key="frame" x="126" y="12" width="276" height="24"/>
                                                     <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
-                                                    <nil key="textColor"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="24" id="VQs-GS-MPC"/>
+                                                    </constraints>
                                                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                     <textInputTraits key="textInputTraits" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
                                                 </textField>
                                             </subviews>
                                             <constraints>
-                                                <constraint firstItem="j89-tM-Che" firstAttribute="centerY" secondItem="9Wf-8S-tJ9" secondAttribute="centerY" id="0MR-b4-SYU"/>
-                                                <constraint firstAttribute="bottom" secondItem="9Wf-8S-tJ9" secondAttribute="bottom" id="4K8-Ms-Dy8"/>
+                                                <constraint firstAttribute="bottom" secondItem="9Wf-8S-tJ9" secondAttribute="bottom" id="7FC-Ck-pSM"/>
+                                                <constraint firstItem="QW9-uT-w7q" firstAttribute="leading" secondItem="9Wf-8S-tJ9" secondAttribute="trailing" constant="8" id="8Q5-fg-4mo"/>
                                                 <constraint firstItem="QW9-uT-w7q" firstAttribute="top" secondItem="hnE-2h-G77" secondAttribute="topMargin" constant="1" id="9nR-Wk-UkC"/>
-                                                <constraint firstItem="9Wf-8S-tJ9" firstAttribute="leading" secondItem="j89-tM-Che" secondAttribute="trailing" constant="8" symbolic="YES" id="ICz-aN-B7Q"/>
-                                                <constraint firstItem="QW9-uT-w7q" firstAttribute="leading" secondItem="9Wf-8S-tJ9" secondAttribute="trailing" constant="11" id="JRo-bb-7DD"/>
-                                                <constraint firstItem="QW9-uT-w7q" firstAttribute="trailing" secondItem="hnE-2h-G77" secondAttribute="trailingMargin" id="L2j-mS-VT1"/>
-                                                <constraint firstItem="j89-tM-Che" firstAttribute="top" secondItem="hnE-2h-G77" secondAttribute="topMargin" constant="6" id="YAK-gK-kQu"/>
+                                                <constraint firstItem="QW9-uT-w7q" firstAttribute="trailing" secondItem="hnE-2h-G77" secondAttribute="trailingMargin" constant="8" id="CKB-Qg-st8"/>
                                                 <constraint firstItem="9Wf-8S-tJ9" firstAttribute="top" secondItem="hnE-2h-G77" secondAttribute="top" id="ilW-BI-5Wi"/>
-                                                <constraint firstItem="j89-tM-Che" firstAttribute="centerY" secondItem="QW9-uT-w7q" secondAttribute="centerY" id="inU-0A-5v6"/>
-                                                <constraint firstItem="j89-tM-Che" firstAttribute="leading" secondItem="hnE-2h-G77" secondAttribute="leadingMargin" constant="35" id="rkN-IC-U1z"/>
+                                                <constraint firstItem="j89-tM-Che" firstAttribute="top" secondItem="hnE-2h-G77" secondAttribute="topMargin" constant="6" id="oZ3-MP-xUl"/>
+                                                <constraint firstAttribute="bottomMargin" secondItem="j89-tM-Che" secondAttribute="bottom" constant="6" id="p30-Dx-y8B"/>
+                                                <constraint firstItem="QW9-uT-w7q" firstAttribute="centerY" secondItem="hnE-2h-G77" secondAttribute="centerY" id="qNs-Z4-2BK"/>
+                                                <constraint firstItem="j89-tM-Che" firstAttribute="leading" secondItem="hnE-2h-G77" secondAttribute="leadingMargin" id="rkN-IC-U1z"/>
+                                                <constraint firstItem="9Wf-8S-tJ9" firstAttribute="leading" secondItem="j89-tM-Che" secondAttribute="trailing" constant="8" id="wlj-gI-f0e"/>
                                             </constraints>
                                         </tableViewCellContentView>
                                     </tableViewCell>
@@ -461,14 +469,14 @@
                             <tableViewSection headerTitle="主题内容" id="5NA-G9-NMb">
                                 <cells>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="292" id="QrM-zd-ggt">
-                                        <rect key="frame" x="0.0" y="311.33333333333337" width="414" height="292"/>
+                                        <rect key="frame" x="0.0" y="311.33333206176758" width="414" height="292"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="QrM-zd-ggt" id="aDQ-GC-gCE">
-                                            <rect key="frame" x="0.0" y="0.0" width="414" height="291.66666666666669"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="414" height="292"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <webView contentMode="scaleToFill" allowsInlineMediaPlayback="NO" mediaPlaybackRequiresUserAction="NO" mediaPlaybackAllowsAirPlay="NO" keyboardDisplayRequiresUserAction="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BuN-0G-Kfq">
-                                                    <rect key="frame" x="0.0" y="0.0" width="414" height="291"/>
+                                                    <rect key="frame" x="0.0" y="0.0" width="414" height="292"/>
                                                     <color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                 </webView>
                                             </subviews>
@@ -508,7 +516,7 @@
                 <placeholder placeholderIdentifier="IBFirstResponder" id="nIO-g1-962" userLabel="First Responder" sceneMemberID="firstResponder"/>
                 <exit id="lp1-k7-1Bm" userLabel="Exit" sceneMemberID="exit"/>
             </objects>
-            <point key="canvasLocation" x="2709.5999999999999" y="-107.49625187406298"/>
+            <point key="canvasLocation" x="2708.6956521739135" y="-107.60869565217392"/>
         </scene>
         <!--主题内容-->
         <scene sceneID="WVJ-LU-xxx">
@@ -519,7 +527,7 @@
                         <viewControllerLayoutGuide type="bottom" id="yUj-ny-2sr"/>
                     </layoutGuides>
                     <view key="view" contentMode="scaleToFill" id="gR5-ax-AlI">
-                        <rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="716"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                     </view>
@@ -557,25 +565,72 @@
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Akk-vR-6JN">
-                                <rect key="frame" x="0.0" y="64" width="414" height="2"/>
+                                <rect key="frame" x="0.0" y="44" width="414" height="2"/>
                             </progressView>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="i8Q-Zy-ou1">
+                                <rect key="frame" x="0.0" y="46" width="414" height="654"/>
+                                <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                            </view>
+                            <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eaE-vD-SEu">
+                                <rect key="frame" x="342" y="648" width="40" height="40"/>
+                                <color key="backgroundColor" red="0.98431372549999996" green="0.2784313725" blue="0.2784313725" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="40" id="8f7-bC-0xg"/>
+                                    <constraint firstAttribute="width" constant="40" id="UU5-lg-wTb"/>
+                                </constraints>
+                                <state key="normal" image="icon_tu"/>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="20"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                                <connections>
+                                    <action selector="clickAttachmentBtn:" destination="NrM-as-KMX" eventType="touchUpInside" id="qIi-rT-Aa5"/>
+                                </connections>
+                            </button>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" pointerInteraction="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xcv-tG-eaX">
+                                <rect key="frame" x="0.0" y="700" width="414" height="36"/>
+                                <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="36" id="MEl-uW-98Y"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                <state key="normal" title="写评论">
+                                    <color key="titleColor" cocoaTouchSystemColor="darkTextColor"/>
+                                </state>
+                                <connections>
+                                    <action selector="replaySubject:" destination="NrM-as-KMX" eventType="touchUpInside" id="pNN-AF-Imz"/>
+                                </connections>
+                            </button>
                         </subviews>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                         <constraints>
+                            <constraint firstItem="i8Q-Zy-ou1" firstAttribute="leading" secondItem="3FR-QI-FR9" secondAttribute="leading" id="2Bl-6f-gcE"/>
+                            <constraint firstItem="i8Q-Zy-ou1" firstAttribute="top" secondItem="Akk-vR-6JN" secondAttribute="bottom" id="AE1-HJ-hDZ"/>
                             <constraint firstItem="Akk-vR-6JN" firstAttribute="top" secondItem="vpJ-pG-keM" secondAttribute="bottom" id="Dmz-Vi-Pop"/>
                             <constraint firstAttribute="trailing" secondItem="Akk-vR-6JN" secondAttribute="trailing" id="J5K-Y9-svZ"/>
+                            <constraint firstAttribute="trailing" secondItem="i8Q-Zy-ou1" secondAttribute="trailing" id="QGr-gd-PrC"/>
+                            <constraint firstAttribute="trailing" secondItem="xcv-tG-eaX" secondAttribute="trailing" id="WZ0-G6-Cle"/>
+                            <constraint firstItem="xcv-tG-eaX" firstAttribute="top" secondItem="eaE-vD-SEu" secondAttribute="bottom" constant="12" id="aoM-63-FKg"/>
+                            <constraint firstItem="xcv-tG-eaX" firstAttribute="top" secondItem="i8Q-Zy-ou1" secondAttribute="bottom" id="d9r-7V-WT7"/>
+                            <constraint firstItem="xcv-tG-eaX" firstAttribute="leading" secondItem="3FR-QI-FR9" secondAttribute="leading" id="dEU-cE-lQ9"/>
+                            <constraint firstAttribute="trailingMargin" secondItem="eaE-vD-SEu" secondAttribute="trailing" constant="12" id="fcw-Hj-yEU"/>
                             <constraint firstItem="Akk-vR-6JN" firstAttribute="leading" secondItem="3FR-QI-FR9" secondAttribute="leading" id="uFf-zV-Irc"/>
+                            <constraint firstItem="NJN-cN-NpB" firstAttribute="top" secondItem="xcv-tG-eaX" secondAttribute="bottom" id="vaa-9Z-8Zw"/>
                         </constraints>
                     </view>
                     <navigationItem key="navigationItem" title="帖子详细" id="Ay2-kD-eE6"/>
                     <connections>
+                        <outlet property="attachmentBtn" destination="eaE-vD-SEu" id="UKT-VQ-WJw"/>
                         <outlet property="progressView" destination="Akk-vR-6JN" id="DP8-IQ-Oya"/>
+                        <outlet property="webViewContainer" destination="i8Q-Zy-ou1" id="ScW-bZ-3t8"/>
                         <segue destination="XX2-U5-jZ2" kind="show" identifier="showReplyActionSegue" id="vTH-tB-kgB"/>
+                        <segue destination="AVx-tq-ogH" kind="show" identifier="showSubAttachmentActionSegue" id="YRv-7t-BC3"/>
                     </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="lRs-If-sZJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
-            <point key="canvasLocation" x="2711.1999999999998" y="603.14842578710648"/>
+            <point key="canvasLocation" x="2710.144927536232" y="602.44565217391312"/>
         </scene>
         <!--回帖-->
         <scene sceneID="xzo-uP-W1c">
@@ -617,7 +672,7 @@
                 <navigationController automaticallyAdjustsScrollViewInsets="NO" id="WEC-RV-idi" customClass="ZLNavigationController" customModule="O2Platform" customModuleProvider="target" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="sHw-y8-D2g">
-                        <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -635,7 +690,7 @@
                 <navigationController automaticallyAdjustsScrollViewInsets="NO" id="XX2-U5-jZ2" customClass="ZLNavigationController" customModule="O2Platform" customModuleProvider="target" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="FZc-TX-cBF">
-                        <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -647,13 +702,73 @@
             </objects>
             <point key="canvasLocation" x="3559" y="603"/>
         </scene>
+        <!--附件列表-->
+        <scene sceneID="Wye-zE-rG9">
+            <objects>
+                <tableViewController id="jw1-bl-BWV" customClass="BBSSubjectAttachmentViewController" customModule="O2Platform" customModuleProvider="target" sceneMemberID="viewController">
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="ioC-Rq-Dxq">
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                        <prototypes>
+                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="subjectAttachmentCell" id="Exz-Xm-k3F" customClass="BBSSubjectAttachmentViewCell" customModule="O2Platform" customModuleProvider="target">
+                                <rect key="frame" x="0.0" y="28" width="414" height="43.666667938232422"/>
+                                <autoresizingMask key="autoresizingMask"/>
+                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Exz-Xm-k3F" id="CUi-FS-STd">
+                                    <rect key="frame" x="0.0" y="0.0" width="414" height="43.666667938232422"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                    <subviews>
+                                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_moren" translatesAutoresizingMaskIntoConstraints="NO" id="mWX-iw-NIE">
+                                            <rect key="frame" x="12" y="4" width="36" height="36"/>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="36" id="rQV-1r-6vR"/>
+                                                <constraint firstAttribute="width" constant="36" id="vUW-9L-17u"/>
+                                            </constraints>
+                                        </imageView>
+                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="文件.pdf" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9q8-ZA-rPN">
+                                            <rect key="frame" x="72" y="13.333333333333336" width="54.333333333333343" height="17"/>
+                                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                            <nil key="textColor"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                    <constraints>
+                                        <constraint firstItem="9q8-ZA-rPN" firstAttribute="leading" secondItem="mWX-iw-NIE" secondAttribute="trailing" constant="24" id="Ppt-X1-TIK"/>
+                                        <constraint firstItem="mWX-iw-NIE" firstAttribute="leading" secondItem="CUi-FS-STd" secondAttribute="leading" constant="12" id="YLI-ml-reW"/>
+                                        <constraint firstItem="mWX-iw-NIE" firstAttribute="centerY" secondItem="CUi-FS-STd" secondAttribute="centerY" id="kbw-6C-qVb"/>
+                                        <constraint firstItem="9q8-ZA-rPN" firstAttribute="centerY" secondItem="CUi-FS-STd" secondAttribute="centerY" id="mgh-sU-k86"/>
+                                    </constraints>
+                                </tableViewCellContentView>
+                                <connections>
+                                    <outlet property="fileNameLabel" destination="9q8-ZA-rPN" id="udp-77-gAL"/>
+                                    <outlet property="typeImage" destination="mWX-iw-NIE" id="fpJ-37-UhH"/>
+                                </connections>
+                            </tableViewCell>
+                        </prototypes>
+                        <connections>
+                            <outlet property="dataSource" destination="jw1-bl-BWV" id="nTq-0N-7Fj"/>
+                            <outlet property="delegate" destination="jw1-bl-BWV" id="3e8-Pf-ueS"/>
+                        </connections>
+                    </tableView>
+                    <navigationItem key="navigationItem" title="附件列表" id="Tal-mN-hrK">
+                        <barButtonItem key="leftBarButtonItem" title="关闭" id="lue-5t-S3f">
+                            <connections>
+                                <action selector="closeAction:" destination="jw1-bl-BWV" id="pTs-c1-rDk"/>
+                            </connections>
+                        </barButtonItem>
+                    </navigationItem>
+                </tableViewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="lXO-nd-bq8" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="4465.217391304348" y="1297.0108695652175"/>
+        </scene>
         <!--Navigation Controller-->
         <scene sceneID="59C-FF-LRs">
             <objects>
                 <navigationController automaticallyAdjustsScrollViewInsets="NO" id="Owj-wk-JM6" customClass="ZLNavigationController" customModule="O2Platform" customModuleProvider="target" sceneMemberID="viewController">
                     <toolbarItems/>
                     <navigationBar key="navigationBar" contentMode="scaleToFill" id="ry5-8Z-U7w">
-                        <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="56"/>
                         <autoresizingMask key="autoresizingMask"/>
                     </navigationBar>
                     <nil name="viewControllers"/>
@@ -665,12 +780,33 @@
             </objects>
             <point key="canvasLocation" x="3668" y="-107.49625187406298"/>
         </scene>
+        <!--Navigation Controller-->
+        <scene sceneID="QHB-rq-K3F">
+            <objects>
+                <navigationController automaticallyAdjustsScrollViewInsets="NO" id="AVx-tq-ogH" customClass="ZLNavigationController" customModule="O2Platform" customModuleProvider="target" sceneMemberID="viewController">
+                    <toolbarItems/>
+                    <navigationItem key="navigationItem" id="Cs6-ep-mlf"/>
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Nrt-Do-VFm">
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </navigationBar>
+                    <nil name="viewControllers"/>
+                    <connections>
+                        <segue destination="jw1-bl-BWV" kind="relationship" relationship="rootViewController" id="shq-cV-eeK"/>
+                    </connections>
+                </navigationController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="bPo-wG-IaD" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="3557.971014492754" y="1296.1956521739132"/>
+        </scene>
     </scenes>
     <resources>
         <image name="icon_bbs_publish_item" width="16" height="16"/>
         <image name="icon_bbs_reply" width="24" height="24"/>
         <image name="icon_bbs_top" width="13" height="12"/>
         <image name="icon_bbs_view" width="24" height="24"/>
+        <image name="icon_moren" width="40" height="40"/>
+        <image name="icon_tu" width="22" height="22"/>
         <image name="todoedStatusIcon" width="32" height="32"/>
     </resources>
 </document>

+ 0 - 3
o2ios/O2Platform/App/BBS-论坛/c/BBSReplySubjectViewController.swift

@@ -30,14 +30,11 @@ class BBSReplySubjectViewController: UIViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         htmlEditorController  = ZSSRichTextEditor()
-        //htmlEditorController.setSelectedColor(<#T##color: UIColor!##UIColor!#>, tag: <#T##Int32#>)
         htmlEditorController.view.frame = self.view.frame
         self.view.addSubview(htmlEditorController.view)
         htmlEditorController.alwaysShowToolbar = true
         htmlEditorController.placeholder = "请输入回复内容"
         self.addChild(htmlEditorController)
-
-        
     }
 
     override func didReceiveMemoryWarning() {

+ 82 - 0
o2ios/O2Platform/App/BBS-论坛/c/BBSSubjectAttachmentViewController.swift

@@ -0,0 +1,82 @@
+//
+//  BBSSubjectAttachmentViewController.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/28.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+import QuickLook
+import CocoaLumberjack
+
+class BBSSubjectAttachmentViewController: UITableViewController {
+    
+    
+    var attachmentList:[O2BBSSubjectAttachmentInfo] = []
+    
+    //预览文件
+    private lazy var previewVC: CloudFilePreviewController = {
+        return CloudFilePreviewController()
+    }()
+    
+    private lazy var viewModel: BBSViewModel = {
+       return BBSViewModel()
+   }()
+    
+    @IBAction func closeAction(_ sender: UIBarButtonItem) {
+        self.dismiss(animated: true, completion: nil)
+    }
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        self.tableView.tableFooterView = UIView()
+        
+    }
+
+    // MARK: - Table view data source
+
+    override func numberOfSections(in tableView: UITableView) -> Int {
+        
+        return 1
+    }
+
+    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        
+        return self.attachmentList.count
+    }
+    
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        if let cell = tableView.dequeueReusableCell(withIdentifier: "subjectAttachmentCell", for: indexPath) as? BBSSubjectAttachmentViewCell {
+            cell.setAttachment(file: self.attachmentList[indexPath.row])
+            return cell
+        }
+        return UITableViewCell()
+    }
+    
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        tableView.deselectRow(at: indexPath, animated: false)
+        self.showLoading()
+        self.viewModel
+            .downloadAttachment(att: self.attachmentList[indexPath.row])
+            .always {
+                self.hideLoading()
+        }.then({ (url)  in
+            let currentURL = NSURL(fileURLWithPath: url.path)
+            if QLPreviewController.canPreview(currentURL) {
+                self.previewVC.currentFileURLS.removeAll()
+                self.previewVC.currentFileURLS.append(currentURL)
+                self.previewVC.reloadData()
+                self.pushVC(self.previewVC)
+            }else {
+                self.showError(title: "当前文件类型不支持预览!")
+            }
+        }).catch { (err) in
+            DDLogError(err.localizedDescription)
+            self.showError(title: "下载文件失败!")
+        }
+    }
+
+     
+
+}

+ 1 - 1
o2ios/O2Platform/App/BBS-论坛/c/BBSSubjectCreateTableViewController.swift

@@ -17,7 +17,7 @@ import CocoaLumberjack
 class BBSSubjectCreateTableViewController: UITableViewController {
 
     
-    let subjectcategory = ["讨论","投票","新闻","悬赏","辩论","灌水","知识","动态"]
+    let subjectcategory = ["讨论","新闻","灌水","知识","动态"]
     
     var sectionData:BBSectionListData?
     

+ 55 - 34
o2ios/O2Platform/App/BBS-论坛/c/BBSSubjectDetailViewController.swift

@@ -18,53 +18,69 @@ class BBSSubjectDetailViewController: BaseWebViewUIViewController {
     
     
     @IBOutlet weak var progressView: UIProgressView!
-    
+    @IBOutlet weak var webViewContainer: UIView!
+    @IBOutlet weak var attachmentBtn: UIButton!
     var loadUrl:String?
     
-    var window:UIWindow?
-    
-    var button:UIButton?
-    
     var subject:BBSSubjectData? {
         didSet {
             loadUrl = AppDelegate.o2Collect.genrateURLWithWebContextKey(DesktopContext.DesktopContextKey, query: DesktopContext.bbsItemDetailQuery, parameter: ["##subjectId##":subject?.id as AnyObject])
         }
     }
     
+    private lazy var viewModel: BBSViewModel = {
+        return BBSViewModel()
+    }()
+    private var attachmentList: [O2BBSSubjectAttachmentInfo] = []
+    
     override func viewWillAppear(_ animated: Bool) {
-        self.window?.isHidden = false
+        //监控进度
+        webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
     }
     
     override func viewWillDisappear(_ animated: Bool) {
-        self.window?.isHidden = true
+        webView.removeObserver(self, forKeyPath: "estimatedProgress")
     }
-
+    
+    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
+       if keyPath == "estimatedPrgress" {
+           progressView.isHidden = webView.estimatedProgress == 1
+           progressView.setProgress(Float(webView.estimatedProgress), animated: true)
+       }
+   }
+    
+    
     override func viewDidLoad() {
         super.viewDidLoad()
-        createButton()
+        self.attachmentBtn.isHidden = true
+        if let subjectId = self.subject?.id {
+            self.viewModel.getSubjectAttachmentList(subjectId: subjectId)
+                .then { attachments  in
+                    if attachments.count > 0 {
+                        self.attachmentList = attachments
+                        self.attachmentBtn.isHidden = false
+                    }
+            }.catch { (error) in
+                DDLogError(error.localizedDescription)
+            }
+        }
+        
         self.theWebView()
-        self.view = webView
+        self.webViewContainer.addSubview(self.webView)
+        
     }
     
-    func createButton(){
-        let width = SCREEN_WIDTH
-        let height = SCREEN_HEIGHT
-        self.button  = UIButton(frame: CGRect(x: 0,y: 0,width: 40,height: 40))
-        self.button?.setImage(UIImage(named: "icon_bbs_reply_white"), for: UIControl.State())
-        self.button?.addTarget(self, action: #selector(replyAction), for: .touchUpInside)
-        self.window = UIWindow(frame: CGRect(x: width - 60, y: height - 60, width: 40, height: 40))
-        self.window?.windowLevel = UIWindow.Level.alert + 1
-        self.window?.backgroundColor = UIColor.green
-        self.window?.layer.cornerRadius = 20
-        self.window?.layer.masksToBounds = true
-        self.window?.addSubview(self.button!)
-        self.window?.makeKeyAndVisible()
-    }
     
-    @objc func replyAction(sender:Any?){
-        self.performSegue(withIdentifier:"showReplyActionSegue", sender: nil)
+    @IBAction func clickAttachmentBtn(_ sender: UIButton) {
+        DDLogDebug("点击附件列表")
+        if self.attachmentList.count > 0 {
+            self.performSegue(withIdentifier: "showSubAttachmentActionSegue", sender: nil)
+        }else {
+            self.showError(title: "没有附件!")
+        }
     }
     
+    
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         if segue.identifier == "showReplyActionSegue" {
             let navVC = segue.destination as! ZLNavigationController
@@ -73,6 +89,10 @@ class BBSSubjectDetailViewController: BaseWebViewUIViewController {
             if let parentId = sender {
                 destVC.parentId = parentId as? String
             }
+        }else if segue.identifier == "showSubAttachmentActionSegue" {
+            let navVC = segue.destination as! ZLNavigationController
+            let destVC = navVC.topViewController as! BBSSubjectAttachmentViewController
+            destVC.attachmentList = self.attachmentList
         }
     }
     
@@ -101,17 +121,18 @@ class BBSSubjectDetailViewController: BaseWebViewUIViewController {
         loadDetailSubject()
     }
 
+    //写评论
+    @IBAction func replaySubject(_ sender: UIButton) {
+        self.performSegue(withIdentifier:"showReplyActionSegue", sender: nil)
+    }
+    
+    
     override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
     }
     
-    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
-        if keyPath == "estimatedPrgress" {
-            progressView.isHidden = webView.estimatedProgress == 1
-            progressView.setProgress(Float(webView.estimatedProgress), animated: true)
-        }
-    }
+   
     
 
 }
@@ -121,12 +142,12 @@ class BBSSubjectDetailViewController: BaseWebViewUIViewController {
 extension BBSSubjectDetailViewController:WKNavigationDelegate,WKUIDelegate {
     
     func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
-        DDLogDebug("didFailProvisionalNavigation \(navigation)  error = \(error)")
+        DDLogDebug("didFailProvisionalNavigation \(String(describing: navigation))  error = \(error)")
     }
 
     
     func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
-        DDLogDebug("didStartProvisionalNavigation \(navigation)")
+        DDLogDebug("didStartProvisionalNavigation \(String(describing: navigation))")
     }
     
     func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {

+ 2 - 1
o2ios/O2Platform/App/BBS-论坛/c/BBSSubjectListViewController.swift

@@ -77,7 +77,7 @@ class BBSSubjectListViewController: UIViewController {
         self.button?.addTarget(self, action: #selector(createAction), for: .touchUpInside)
         self.window = UIWindow(frame: CGRect(x: width - 60, y: height - 60, width: 40, height: 40))
         self.window?.windowLevel = UIWindow.Level.alert + 1
-        self.window?.backgroundColor = UIColor.green
+        self.window?.backgroundColor = base_color
         self.window?.layer.cornerRadius = 20
         self.window?.layer.masksToBounds = true
         self.window?.addSubview(self.button!)
@@ -184,6 +184,7 @@ extension BBSSubjectListViewController:UITableViewDataSource {
 
 extension BBSSubjectListViewController:UITableViewDelegate {
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        tableView.deselectRow(at: indexPath, animated: false)
         let subject = subjects[indexPath.row]
         self.performSegue(withIdentifier: "showSubjectDetailSegue", sender: subject)
     }

+ 176 - 141
o2ios/O2Platform/App/BBS-论坛/m/OOBBSModels.swift

@@ -8,24 +8,27 @@
 
 import Foundation
 import HandyJSON
+import ObjectMapper
+
+
 // MARK:- 读取Section列表参数
 class SubjectsParameter {
-    var sectionId:String?
-    var withTopSubject:Bool?
-    var pageParameter:CommonPageParameter?
+    var sectionId: String?
+    var withTopSubject: Bool?
+    var pageParameter: CommonPageParameter?
 }
 
 
 class CommonPageParameter {
     //当前页
-    var currentPageNo:Int = 1
+    var currentPageNo: Int = 1
     //每页行数
-    let countByPage:Int = 20
+    let countByPage: Int = 20
     //总页数
     private var totalPageCount = 1
-    
+
     //总行数
-    var totalLineCount:Int = -1 {
+    var totalLineCount: Int = -1 {
         didSet {
             if totalLineCount > 0 && totalLineCount > countByPage * currentPageNo {
                 //总页数
@@ -33,168 +36,200 @@ class CommonPageParameter {
             }
         }
     }
-    
+
     init() {
-        
+
     }
-    
+
     func calcNextPageNo() -> Bool {
         if currentPageNo < totalPageCount {
             currentPageNo += 1
             return true
-        }else{
+        } else {
             return false
         }
     }
 }
 
 // MARK:- O2ForumInfo
-class O2ForumInfo:NSObject,DataModel {
-    var createTime : String?
-    var creatorName : String?
-    var forumColor : String?
-    var forumIndexStyle : String?
-    var forumManagerName : String?
-    var forumName : String?
-    var forumNotice : String?
-    var forumStatus : String?
-    var forumVisible : String?
-    var id : String?
-    var indexListStyle : String?
-    var indexRecommendable : Bool?
-    var orderNumber : Int?
-    var replyNeedAudit : Bool?
-    var replyPublishAble : String?
-    var replyTotal : Int?
-    var replyTotalToday : Int?
-    var sectionCreateAble : Bool?
-    var sectionInfoList : [O2SectionInfo]?
-    var sectionTotal : Int?
-    var subjectNeedAudit : Bool?
-    var subjectPublishAble : String?
-    var subjectTotal : Int?
-    var subjectTotalToday : Int?
-    var subjectType : String?
-    var typeCategory : String?
-    var updateTime : String?
-    
+class O2ForumInfo: NSObject, DataModel {
+    var createTime: String?
+    var creatorName: String?
+    var forumColor: String?
+    var forumIndexStyle: String?
+    var forumManagerName: String?
+    var forumName: String?
+    var forumNotice: String?
+    var forumStatus: String?
+    var forumVisible: String?
+    var id: String?
+    var indexListStyle: String?
+    var indexRecommendable: Bool?
+    var orderNumber: Int?
+    var replyNeedAudit: Bool?
+    var replyPublishAble: String?
+    var replyTotal: Int?
+    var replyTotalToday: Int?
+    var sectionCreateAble: Bool?
+    var sectionInfoList: [O2SectionInfo]?
+    var sectionTotal: Int?
+    var subjectNeedAudit: Bool?
+    var subjectPublishAble: String?
+    var subjectTotal: Int?
+    var subjectTotalToday: Int?
+    var subjectType: String?
+    var typeCategory: String?
+    var updateTime: String?
+
     required override init() {
-        
+
     }
 }
 
 
 // MARK:- O2SectionInfo
-class O2SectionInfo:NSObject,DataModel {
-    var createTime : String?
-    var creatorName : String?
-    var forumId : String?
-    var forumName : String?
-    var icon : String?
-    var id : String?
-    var indexRecommendable : Bool?
-    var mainSectionId : String?
-    var mainSectionName : String?
-    var moderatorNames : String?
-    var orderNumber : Int?
-    var replyNeedAudit : Bool?
-    var replyPublishAble : String?
-    var replyTotal : Int?
-    var replyTotalToday : Int?
-    var sectionDescription : String?
-    var sectionLevel : String?
-    var sectionName : String?
-    var sectionNotice : String?
-    var sectionStatus : String?
-    var sectionType : String?
-    var sectionVisible : String?
-    var subSectionCreateAble : Bool?
-    var subjectNeedAudit : Bool?
-    var subjectPublishAble : String?
-    var subjectTotal : Int?
-    var subjectTotalToday : Int?
-    var subjectType : String?
-    var typeCategory : String?
-    var updateTime : String?
+class O2SectionInfo: NSObject, DataModel {
+    var createTime: String?
+    var creatorName: String?
+    var forumId: String?
+    var forumName: String?
+    var icon: String?
+    var id: String?
+    var indexRecommendable: Bool?
+    var mainSectionId: String?
+    var mainSectionName: String?
+    var moderatorNames: String?
+    var orderNumber: Int?
+    var replyNeedAudit: Bool?
+    var replyPublishAble: String?
+    var replyTotal: Int?
+    var replyTotalToday: Int?
+    var sectionDescription: String?
+    var sectionLevel: String?
+    var sectionName: String?
+    var sectionNotice: String?
+    var sectionStatus: String?
+    var sectionType: String?
+    var sectionVisible: String?
+    var subSectionCreateAble: Bool?
+    var subjectNeedAudit: Bool?
+    var subjectPublishAble: String?
+    var subjectTotal: Int?
+    var subjectTotalToday: Int?
+    var subjectType: String?
+    var typeCategory: String?
+    var updateTime: String?
     required override init() {
-        
+
     }
 }
 
 
 // MARK:- O2BBSubjectDetailInfo
-class O2BBSubjectDetailInfo:NSObject,DataModel {
-    var lastSubject:O2BBSSubjectInfo?
-    var currentSubject:O2BBSSubjectInfo?
-    var nextSubject:O2BBSSubjectInfo?
+class O2BBSubjectDetailInfo: NSObject, DataModel {
+    var lastSubject: O2BBSSubjectInfo?
+    var currentSubject: O2BBSSubjectInfo?
+    var nextSubject: O2BBSSubjectInfo?
     required override init() {
-        
+
     }
 }
 
 // MARK:- O2BBSSubjectInfo
-class O2BBSSubjectInfo:NSObject,DataModel {
-    var acceptReplyId : String?
-    var attachmentList : [AnyObject]?
-    var auditorName : String?
-    var auditorNameShort : String?
-    var bBSIndexSetterName : String?
-    var bBSIndexSetterNameShort : String?
-    var createTime : String?
-    var creatorName : String?
-    var creatorNameShort : String?
-    var forumId : String?
-    var forumIndexSetterName : String?
-    var forumName : String?
-    var hostIp : String?
-    var hot : Int?
-    var id : String?
-    var isCompleted : Bool?
-    var isCreamSubject : Bool?
-    var isOriginalSubject : Bool?
-    var isRecommendSubject : Bool?
-    var isTopSubject : Bool?
-    var latestReplyId : String?
-    var latestReplyTime : String?
-    var latestReplyUser : String?
-    var latestReplyUserShort : String?
-    var machineName : String?
-    var mainSectionId : String?
-    var mainSectionName : String?
-    var orderNumber : Int?
-    var originalSetterName : String?
-    var originalSetterNameShort : String?
-    var picId : String?
-    var recommendTime : String?
-    var recommendToBBSIndex : Bool?
-    var recommendToForumIndex : Bool?
-    var recommendorName : String?
-    var replyTotal : Int?
-    var screamSetterName : String?
-    var screamSetterNameShort : String?
-    var screamSetterTime : String?
-    var sectionId : String?
-    var sectionName : String?
-    var stopReply : Bool?
-    var subjectAuditStatus : String?
-    var subjectStatus : String?
-    var summary : String?
-    var systemType : String?
-    var title : String?
-    var topToBBS : Bool?
-    var topToForum : Bool?
-    var topToMainSection : Bool?
-    var topToSection : Bool?
-    var type : String?
-    var typeCategory : String?
-    var updateTime : String?
-    var viewTotal : Int?
-    var voteCount : Int?
-    var votePersonVisible : Bool?
-    var voteResultVisible : Bool?
-    var voted : Bool?
-    required override init() {
-        
-    }
+class O2BBSSubjectInfo: NSObject, DataModel {
+    var acceptReplyId: String?
+    var attachmentList: [AnyObject]?
+    var auditorName: String?
+    var auditorNameShort: String?
+    var bBSIndexSetterName: String?
+    var bBSIndexSetterNameShort: String?
+    var createTime: String?
+    var creatorName: String?
+    var creatorNameShort: String?
+    var forumId: String?
+    var forumIndexSetterName: String?
+    var forumName: String?
+    var hostIp: String?
+    var hot: Int?
+    var id: String?
+    var isCompleted: Bool?
+    var isCreamSubject: Bool?
+    var isOriginalSubject: Bool?
+    var isRecommendSubject: Bool?
+    var isTopSubject: Bool?
+    var latestReplyId: String?
+    var latestReplyTime: String?
+    var latestReplyUser: String?
+    var latestReplyUserShort: String?
+    var machineName: String?
+    var mainSectionId: String?
+    var mainSectionName: String?
+    var orderNumber: Int?
+    var originalSetterName: String?
+    var originalSetterNameShort: String?
+    var picId: String?
+    var recommendTime: String?
+    var recommendToBBSIndex: Bool?
+    var recommendToForumIndex: Bool?
+    var recommendorName: String?
+    var replyTotal: Int?
+    var screamSetterName: String?
+    var screamSetterNameShort: String?
+    var screamSetterTime: String?
+    var sectionId: String?
+    var sectionName: String?
+    var stopReply: Bool?
+    var subjectAuditStatus: String?
+    var subjectStatus: String?
+    var summary: String?
+    var systemType: String?
+    var title: String?
+    var topToBBS: Bool?
+    var topToForum: Bool?
+    var topToMainSection: Bool?
+    var topToSection: Bool?
+    var type: String?
+    var typeCategory: String?
+    var updateTime: String?
+    var viewTotal: Int?
+    var voteCount: Int?
+    var votePersonVisible: Bool?
+    var voteResultVisible: Bool?
+    var voted: Bool?
+    
+    required override init() {}
 }
 
+
+//附件对象列表
+class O2BBSSubjectAttachmentInfo: NSObject, DataModel {
+    @objc var id: String?
+    @objc var createTime: String?
+    @objc var updateTime: String?
+    @objc var lastUpdateTime: String?
+    @objc var storage: String?
+    @objc var forumId: String?
+    @objc var forumName: String?
+    @objc var sectionId: String?
+    @objc var sectionName: String?
+    @objc var mainSectionId: String?
+    @objc var mainSectionName: String?
+    @objc var subjectId: String?
+    @objc var title: String?
+    @objc var name: String?
+    @objc var fileName: String?
+    @objc var fileHost: String?
+    @objc var filePath: String?
+    @objc var storageName: String?
+    @objc var desc: String?
+    @objc var creatorUid: String?
+    @objc var ext: String?
+    var length: Int?
+
+    required override init() {}
+
+    func mapping(mapper: HelpingMapper) {
+        mapper <<< self.ext <-- "extension"
+        mapper <<< self.desc <-- "description"
+    }
+}

+ 72 - 0
o2ios/O2Platform/App/BBS-论坛/v/BBSSubjectAttachmentViewCell.swift

@@ -0,0 +1,72 @@
+//
+//  BBSSubjectAttachmentViewCell.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/6/28.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+
+class BBSSubjectAttachmentViewCell: UITableViewCell {
+
+    @IBOutlet weak var fileNameLabel: UILabel!
+    @IBOutlet weak var typeImage: UIImageView!
+    
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        // Initialization code
+    }
+
+    override func setSelected(_ selected: Bool, animated: Bool) {
+        super.setSelected(selected, animated: animated)
+
+        // Configure the view for the selected state
+    }
+    
+    func setAttachment(file: O2BBSSubjectAttachmentInfo)  {
+        self.fileNameLabel.text = file.name
+        self.setFileTypeImage(ext: file.ext)
+    }
+
+    private func setFileTypeImage(ext: String?) {
+        if let type = ext {
+            switch type {
+            case "jpg", "png", "jepg", "gif":
+                self.typeImage.image = UIImage(named: "icon_img")
+                break
+            case "html":
+                self.typeImage.image = UIImage(named: "icon_html")
+                break
+            case "xls", "xlsx":
+                self.typeImage.image = UIImage(named: "icon_excel")
+                break
+            case "doc", "docx":
+                self.typeImage.image = UIImage(named: "icon_word")
+                break
+            case "ppt", "pptx":
+                self.typeImage.image = UIImage(named: "icon_ppt")
+                break
+            case "pdf":
+                self.typeImage.image = UIImage(named: "icon_pdf")
+                break
+            case "mp4":
+                self.typeImage.image = UIImage(named: "icon_mp4")
+                break
+            case "mp3":
+                self.typeImage.image = UIImage(named: "icon_mp3")
+                break
+            case "zip", "rar", "7z":
+                self.typeImage.image = UIImage(named: "icon_zip")
+                break
+            default :
+                self.typeImage.image = UIImage(named: "icon_moren")
+                break
+            }
+        }else {
+            self.typeImage.image = UIImage(named: "icon_moren")
+        }
+    }
+    
+}

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

@@ -15,7 +15,7 @@ class IMViewModel: NSObject {
     }
 
 
-    let communicateAPI = OOMoyaProvider<CommunicateAPI>()
+    private let communicateAPI = OOMoyaProvider<CommunicateAPI>()
 }
 
 extension IMViewModel {

+ 1 - 0
o2ios/O2Platform/App/IM-聊天/View/IMChatMessageViewCell.swift

@@ -54,6 +54,7 @@ class IMChatMessageViewCell: UITableViewCell {
             let date = time.toDate(formatter: "yyyy-MM-dd HH:mm:ss")
             self.timeLabel.text = date.friendlyTime()
         }
+        self.messageBackgroundView.removeSubviews()
         if let msg = item.title {
             textMsgRender(msg: msg)
         }

+ 5 - 12
o2ios/O2Platform/App/NewAttance-考勤打卡/c/OOAttanceCheckInController.swift

@@ -55,31 +55,23 @@ class OOAttanceCheckInController: UITableViewController {
     
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
-        getWorkPlace()
+        
     }
     
 
    
     override func viewDidLoad() {
         super.viewDidLoad()
-//        title = "打卡"
-        
-//        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "关闭", style: .plain, target: self, action: #selector(closeWindow))
-        //tableView.tableHeaderView = headerView
-        //tableView.contentInset = UIEdgeInsets(top: 230, left: 0, bottom: 0, right: 0)
-        //register Cell
         tableView.register(UINib.init(nibName: "OOAttanceItemCell", bundle: nil), forCellReuseIdentifier: "OOAttanceItemCell")
         
         getCurrentCheckinList()
         getMyRecords()
         self.perform(#selector(createButton), with: nil, afterDelay: 0)
+        
+        getWorkPlace()
     }
     
     
-//    @objc func closeWindow() {
-//        self.tabBarController?.navigationController?.dismiss(animated: true, completion: nil)
-//    }
-    
     //创建打卡按钮
     @objc private func createButton() {
         let window = UIApplication.shared.windows[0]
@@ -167,13 +159,14 @@ class OOAttanceCheckInController: UITableViewController {
         viewModel.getLocationWorkPlace { (myResult) in
             switch myResult {
             case .ok(let result):
+                DDLogDebug("有打卡位置了。。。。。。")
                 let model = result as? [OOAttandanceWorkPlace]
                 DispatchQueue.main.async {
                    self.headerView.workPlaces = model
                 }
                 break
             case .fail(let s):
-                MBProgressHUD_JChat.show(text: "错误:\n\(s)", view: self.view, 2)
+                self.showError(title: "错误:\n\(s)")
                 break
             default:
                 break

+ 15 - 11
o2ios/O2Platform/Framework/O2API/BBSAPI/O2BBSAPI.swift

@@ -32,8 +32,10 @@ enum O2BBSAPI {
     case subjectFromSectionByPageQuery(SubjectsParameter)
     case createSubject
     case replySubject
+    case getAttachment(String)
     case uploadAttachForSubject(String)
-    case downloadAttachForSubject(String)
+    case downloadAttachForSubject(O2BBSSubjectAttachmentInfo)
+    case getSubjectAttachmentList(String)
 }
 
 // MARK:- 上下文实现
@@ -71,21 +73,25 @@ extension O2BBSAPI:TargetType{
         case .subjectByIdQuery(let id):
             return "/jaxrs/subject/view/\(id.urlEscaped)"
         case .subjectFromSectionByPageQuery(let parameter):
-            return "jaxrs/subject/filter/list/page/\(parameter.pageParameter!.currentPageNo)/count/\(parameter.pageParameter!.countByPage)"
+            return "/jaxrs/subject/filter/list/page/\(parameter.pageParameter!.currentPageNo)/count/\(parameter.pageParameter!.countByPage)"
         case .createSubject:
             return "/jaxrs/user/subject"
         case .replySubject:
             return "/jaxrs/user/reply"
+        case .getAttachment(let attId):
+            return "/jaxrs/attachment/\(attId)"
         case .uploadAttachForSubject(let subjectId):
             return "/jaxrs/attachment/upload/subject/\(subjectId)"
-        case .downloadAttachForSubject(let attachId):
-            return "/jaxrs/attachment/download/\(attachId)"
+        case .downloadAttachForSubject(let att):
+            return "/jaxrs/attachment/download/\(att.id!)"
+        case .getSubjectAttachmentList(let subjectId):
+            return "/jaxrs/subjectattach/list/subject/\(subjectId)"
         }
     }
     
     var method: Moya.Method {
         switch self {
-        case .getCategoryAndSectionQuery:
+        case .getCategoryAndSectionQuery, .getSubjectAttachmentList(_), .getAttachment(_):
             return .get
         case .getSectionItemQuery(_):
             return .get
@@ -112,8 +118,8 @@ extension O2BBSAPI:TargetType{
     
     var task: Task {
         switch self {
-        case .downloadAttachForSubject(_):
-            let myDest = getDownDest()
+        case .downloadAttachForSubject(let attachment):
+            let myDest = getDownDest(filename: attachment.fileName!)
             return .downloadDestination(myDest)
         case .uploadAttachForSubject(_):
             return .requestPlain
@@ -129,11 +135,9 @@ extension O2BBSAPI:TargetType{
         return nil
     }
     
-    func getDownDest() -> DownloadDestination {
+    func getDownDest(filename: String) -> DownloadDestination {
         let myDest:DownloadDestination = { temporaryURL, response in
-            let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
-            let fileName = response.suggestedFilename!
-            let fileURL = documentsURL.appendingPathComponent("O2").appendingPathComponent("cloud").appendingPathComponent(fileName)
+            let fileURL = O2CloudFileManager.shared.cloudFileLocalFolder().appendingPathComponent(filename)
             return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
             
         }