杨锴
2024-09-13 b1e53d01722f1705d99f5cf6ec63c8c493811405
fix API
28个文件已修改
10个文件已添加
868 ■■■■ 已修改文件
XQMuse.xcodeproj/project.pbxproj 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Config/Enums/Enums.swift 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/VC/CourseDetialVC.swift 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/VC/PaymentOrderResultVC.swift 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/VC/PaymentOrderVC.swift 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/VC/PaymentOrderVC.xib 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/View/PaymentOrderResultTopView.swift 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Home/View/PaymentOrderResultTopView.xib 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Login/LoginVC.swift 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Login/VC/RegisterVC.swift 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Network/Models.swift 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Network/NetworkRequest.swift 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Network/Services.swift 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Network/ViewModels/UserViewModel.swift 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/Other/View/VideoView.swift 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/Root/TreeGroup/TreeTeskVC.swift 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse/SceneDelegate.swift 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
XQMuse.xcodeproj/project.pbxproj
@@ -164,6 +164,16 @@
        1385E00B2C6C57A900AADB1F /* HomeItemDetailVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1385E0092C6C57A900AADB1F /* HomeItemDetailVC.xib */; };
        1388840E2C92B5E80043AAB4 /* CommonBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1388840D2C92B5E80043AAB4 /* CommonBannerView.swift */; };
        13897D892C7DB9D7006209E0 /* EqualCellSpaceFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13897D882C7DB9D7006209E0 /* EqualCellSpaceFlowLayout.swift */; };
        138995402C943AA700BC7F78 /* static-level-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 138995362C943AA500BC7F78 /* static-level-3.png */; };
        138995412C943AA700BC7F78 /* static-level-5.png in Resources */ = {isa = PBXBuildFile; fileRef = 138995372C943AA500BC7F78 /* static-level-5.png */; };
        138995422C943AA700BC7F78 /* static-level-9.png in Resources */ = {isa = PBXBuildFile; fileRef = 138995382C943AA500BC7F78 /* static-level-9.png */; };
        138995432C943AA700BC7F78 /* static-level-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 138995392C943AA600BC7F78 /* static-level-2.png */; };
        138995442C943AA700BC7F78 /* static-level-8.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953A2C943AA600BC7F78 /* static-level-8.png */; };
        138995452C943AA700BC7F78 /* static-level-6.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953B2C943AA600BC7F78 /* static-level-6.png */; };
        138995462C943AA700BC7F78 /* static-level-7.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953C2C943AA600BC7F78 /* static-level-7.png */; };
        138995472C943AA700BC7F78 /* static-level-4.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953D2C943AA700BC7F78 /* static-level-4.png */; };
        138995482C943AA700BC7F78 /* static-level-10.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953E2C943AA700BC7F78 /* static-level-10.png */; };
        138995492C943AA700BC7F78 /* static-level-1.png in Resources */ = {isa = PBXBuildFile; fileRef = 1389953F2C943AA700BC7F78 /* static-level-1.png */; };
        138F0C322C7594BB0072A16C /* TreatyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138F0C312C7594BB0072A16C /* TreatyVC.swift */; };
        138F0C352C7597CA0072A16C /* HelpCenterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138F0C332C7597CA0072A16C /* HelpCenterVC.swift */; };
        138F0C362C7597CA0072A16C /* HelpCenterVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 138F0C342C7597CA0072A16C /* HelpCenterVC.xib */; };
@@ -448,6 +458,16 @@
        1385E0092C6C57A900AADB1F /* HomeItemDetailVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeItemDetailVC.xib; sourceTree = "<group>"; };
        1388840D2C92B5E80043AAB4 /* CommonBannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommonBannerView.swift; sourceTree = "<group>"; };
        13897D882C7DB9D7006209E0 /* EqualCellSpaceFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EqualCellSpaceFlowLayout.swift; sourceTree = "<group>"; };
        138995362C943AA500BC7F78 /* static-level-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-3.png"; sourceTree = "<group>"; };
        138995372C943AA500BC7F78 /* static-level-5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-5.png"; sourceTree = "<group>"; };
        138995382C943AA500BC7F78 /* static-level-9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-9.png"; sourceTree = "<group>"; };
        138995392C943AA600BC7F78 /* static-level-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-2.png"; sourceTree = "<group>"; };
        1389953A2C943AA600BC7F78 /* static-level-8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-8.png"; sourceTree = "<group>"; };
        1389953B2C943AA600BC7F78 /* static-level-6.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-6.png"; sourceTree = "<group>"; };
        1389953C2C943AA600BC7F78 /* static-level-7.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-7.png"; sourceTree = "<group>"; };
        1389953D2C943AA700BC7F78 /* static-level-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-4.png"; sourceTree = "<group>"; };
        1389953E2C943AA700BC7F78 /* static-level-10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-10.png"; sourceTree = "<group>"; };
        1389953F2C943AA700BC7F78 /* static-level-1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "static-level-1.png"; sourceTree = "<group>"; };
        138F0C312C7594BB0072A16C /* TreatyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreatyVC.swift; sourceTree = "<group>"; };
        138F0C332C7597CA0072A16C /* HelpCenterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCenterVC.swift; sourceTree = "<group>"; };
        138F0C342C7597CA0072A16C /* HelpCenterVC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HelpCenterVC.xib; sourceTree = "<group>"; };
@@ -887,6 +907,7 @@
        137ECADB2C78578A00C338BE /* Pngs */ = {
            isa = PBXGroup;
            children = (
                138995352C943A4300BC7F78 /* droop */,
                13C9DDD02C8EE8EB0008946B /* apngb-animated-level-6.png */,
                13C9DDCF2C8EE8EB0008946B /* apngb-animated-level-7.png */,
                13C9DDD12C8EE8EB0008946B /* apngb-animated-level-8.png */,
@@ -933,6 +954,23 @@
                135B1D212C8868170089A9BE /* Models.swift */,
            );
            path = Network;
            sourceTree = "<group>";
        };
        138995352C943A4300BC7F78 /* droop */ = {
            isa = PBXGroup;
            children = (
                1389953F2C943AA700BC7F78 /* static-level-1.png */,
                138995392C943AA600BC7F78 /* static-level-2.png */,
                138995362C943AA500BC7F78 /* static-level-3.png */,
                1389953D2C943AA700BC7F78 /* static-level-4.png */,
                138995372C943AA500BC7F78 /* static-level-5.png */,
                1389953B2C943AA600BC7F78 /* static-level-6.png */,
                1389953C2C943AA600BC7F78 /* static-level-7.png */,
                1389953A2C943AA600BC7F78 /* static-level-8.png */,
                138995382C943AA500BC7F78 /* static-level-9.png */,
                1389953E2C943AA700BC7F78 /* static-level-10.png */,
            );
            path = droop;
            sourceTree = "<group>";
        };
        139228AD2C6B8339006F3CB6 /* View */ = {
@@ -1345,12 +1383,15 @@
                13A37A012C75C1DE0038D5C8 /* LevelVC.xib in Resources */,
                1324A6452C805B4000AA5098 /* FlyFlowerSong.otf in Resources */,
                130C07092C76D51900ADB098 /* SpendingDetailHeaderVC.xib in Resources */,
                138995412C943AA700BC7F78 /* static-level-5.png in Resources */,
                1327C6832C81D107005DA44B /* PlanGuide_3_VC.xib in Resources */,
                138FE0DF2C757B2A00A964E8 /* BindPhone_1_VC.xib in Resources */,
                138995402C943AA700BC7F78 /* static-level-3.png in Resources */,
                13FB6D842C6EEFE900A0685D /* MenuListTCell.xib in Resources */,
                13B06A082C78A0D300477FA9 /* apngb-animated-level-1.png in Resources */,
                138F0C362C7597CA0072A16C /* HelpCenterVC.xib in Resources */,
                131CE0FB2C91299400D1234A /* TreeTeskListView.xib in Resources */,
                138995432C943AA700BC7F78 /* static-level-2.png in Resources */,
                134803D72C76E3E000F4FDDA /* WatchHistoryVC.xib in Resources */,
                1377768E2C6AFD25004FF994 /* LoginVC.xib in Resources */,
                134CC7E02C73283700EAEFB7 /* PavilionSearchVC.xib in Resources */,
@@ -1368,7 +1409,9 @@
                13FB6D8C2C6EFB5400A0685D /* CourseDetailHeaderView.xib in Resources */,
                1324A64D2C80706700AA5098 /* PlanGuide_1_VC.xib in Resources */,
                13985D9F2C69B2440046B6DC /* Assets.xcassets in Resources */,
                138995472C943AA700BC7F78 /* static-level-4.png in Resources */,
                13FCCE272C75E8C400AC7E02 /* BankInfoTCell.xib in Resources */,
                138995442C943AA700BC7F78 /* static-level-8.png in Resources */,
                13EFCDC22C6DD27A00B51AE6 /* PaymentOrderVC.xib in Resources */,
                13A379FC2C75B7280038D5C8 /* BindAccountVC.xib in Resources */,
                13F24E412C758DF100D2BA90 /* LogoutAccountVC.xib in Resources */,
@@ -1404,6 +1447,7 @@
                137175CC2C6C412A00B38EF1 /* BackgroundVoiceVC.xib in Resources */,
                130602882C91790B0019ECDE /* TreeTeskExchangeSuccessView.xib in Resources */,
                13ED09482C916FD30018BB10 /* TreeTeskEnergyTCell.xib in Resources */,
                138995492C943AA700BC7F78 /* static-level-1.png in Resources */,
                13BF65EB2C804BE100E20F0E /* apngb-animated-flow.png in Resources */,
                13FAD54E2C901D6300566998 /* SearchContentVC.xib in Resources */,
                137776932C6AFE69004FF994 /* SearchVC.xib in Resources */,
@@ -1411,6 +1455,7 @@
                13985DBF2C69DDF90046B6DC /* HomeTopMenuView.xib in Resources */,
                13C5838E2C86A4F90071BCBE /* apngb-animated-level-5.png in Resources */,
                1385E00B2C6C57A900AADB1F /* HomeItemDetailVC.xib in Resources */,
                138995422C943AA700BC7F78 /* static-level-9.png in Resources */,
                13B021DB2C75DD0600414769 /* BankWithdrawVC.xib in Resources */,
                1338A6DE2C76DD5E006CDD15 /* SpendingDetailInfoVC.xib in Resources */,
                137ECAD72C783C7700C338BE /* TreeTeskVC.xib in Resources */,
@@ -1420,6 +1465,8 @@
                13EA70052C75FA16005DF280 /* WalletRechargeVC.xib in Resources */,
                13A0A8AE2C74757200DF08B6 /* MessageTCell.xib in Resources */,
                1324A6482C80632500AA5098 /* SourceHanSerifCN-Semibold.otf in Resources */,
                138995462C943AA700BC7F78 /* static-level-7.png in Resources */,
                138995452C943AA700BC7F78 /* static-level-6.png in Resources */,
                130913EA2C6DE33200418201 /* PaymentOrderResultVC.xib in Resources */,
                139F1F622C81AE920055CE8F /* PlanGuidePromptView.xib in Resources */,
                130ED7ED2C6AF05C00D0736E /* Home_Style_4_Inner_CCell.xib in Resources */,
@@ -1434,6 +1481,7 @@
                13E0FBFB2C6C8BE3009997AE /* CountdownChooseListView.xib in Resources */,
                13A0A89F2C746A8700DF08B6 /* CommonAlertSheetView.xib in Resources */,
                13E4ECEF2C80778A0095AD04 /* PlanGuide_2_VC.xib in Resources */,
                138995482C943AA700BC7F78 /* static-level-10.png in Resources */,
                13F24E462C75901600D2BA90 /* CommonAlertView.xib in Resources */,
                130B765A2C6C4963006371AF /* HomeRelaxVoiceCCell.xib in Resources */,
                130C07122C76DA0500ADB098 /* SpendingDetailContentTCell.xib in Resources */,
XQMuse/Config/Enums/Enums.swift
@@ -35,7 +35,7 @@
                case offline = 2 //线下课程
}
enum ConditionType:Int,HandyJSONEnum{
enum ConditionType:Int,HandyJSONEnum,Codable{
                case yes = 1
                case no = 2
@@ -47,3 +47,61 @@
                                }
                }
}
enum TreeLevel:Int,HandyJSONEnum,Codable{
                case level_1 = 1
                case level_2 = 2
                case level_3 = 3
                case level_4 = 4
                case level_5 = 5
                case level_6 = 6
                case level_7 = 7
                case level_8 = 8
                case level_9 = 9
                case level_10 = 10
                var aniResource:String{
                                switch self {
                                                case .level_1:return "apngb-animated-level-1"
                                                case .level_2:return "apngb-animated-level-2"
                                                case .level_3:return "apngb-animated-level-3"
                                                case .level_4:return "apngb-animated-level-4"
                                                case .level_5:return "apngb-animated-level-5"
                                                case .level_6:return "apngb-animated-level-6"
                                                case .level_7:return "apngb-animated-level-7"
                                                case .level_8:return "apngb-animated-level-8"
                                                case .level_9:return "apngb-animated-level-9"
                                                case .level_10:return "apngb-animated-level-10"
                                }
                }
                var staticDroopResource:String{
                                switch self {
                                                case .level_1:return "static-level-1"
                                                case .level_2:return "static-level-2"
                                                case .level_3:return "static-level-3"
                                                case .level_4:return "static-level-4"
                                                case .level_5:return "static-level-5"
                                                case .level_6:return "static-level-6"
                                                case .level_7:return "static-level-7"
                                                case .level_8:return "static-level-8"
                                                case .level_9:return "static-level-9"
                                                case .level_10:return "static-level-10"
                                }
                }
                var title:String{
                                switch self {
                                                case .level_1:return "第一"
                                                case .level_2:return "第二"
                                                case .level_3:return "第三"
                                                case .level_4:return "第四"
                                                case .level_5:return "第五"
                                                case .level_6:return "第六"
                                                case .level_7:return "第七"
                                                case .level_8:return "第八"
                                                case .level_9:return "第九"
                                                case .level_10:return "第十"
                                }
                }
}
XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift
@@ -26,19 +26,11 @@
                                webView.scrollView.backgroundColor = .clear
                                webView.isOpaque = false
                                self.webView.scrollView.rx.observe(CGSize.self, "contentSize").map { (size) -> CGFloat? in
                                                if let size = size{
                                                                return size.height
                                                }
                                                return nil
                                }.subscribe(onNext: { [unowned self](height) in
                                                if let height = height{
                                                                self.cons_webHei.constant = height
                                                }
                                }).disposed(by: disposeBag)
    }
                func setContent(title:String,content:String){
                                label_title.text = title
                                webView.loadHTMLString(content.jq_wrapHtml(), baseURL: nil)
                }
}
XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib
@@ -17,16 +17,16 @@
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="课程介绍" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lg9-70-w3n">
                        <rect key="frame" x="21.666666666666668" y="35" width="61.333333333333329" height="14"/>
                        <rect key="frame" x="21.666666666666668" y="35" width="61.333333333333329" height="20"/>
                        <constraints>
                            <constraint firstAttribute="height" constant="14" id="WNQ-mw-uOi"/>
                            <constraint firstAttribute="height" constant="20" id="8dQ-Gi-hJh"/>
                        </constraints>
                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
                        <color key="textColor" red="0.15686274509803921" green="0.15686274509803921" blue="0.15686274509803921" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <nil key="highlightedColor"/>
                    </label>
                    <wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WYV-JQ-E3S">
                        <rect key="frame" x="0.0" y="68.666666666666671" width="501" height="100.00000000000001"/>
                        <rect key="frame" x="0.0" y="74.666666666666671" width="501" height="100.00000000000001"/>
                        <constraints>
                            <constraint firstAttribute="height" constant="100" id="hfa-qQ-TpS"/>
                        </constraints>
XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift
@@ -13,7 +13,7 @@
                @IBOutlet weak var tableView: UITableView!
                @IBOutlet weak var cons_tableHei: NSLayoutConstraint!
                private var items = [CourseItemModel]()
                private var model:CourseModel?
                override func awakeFromNib() {
        super.awakeFromNib()
@@ -28,9 +28,9 @@
                                cons_tableHei.constant = 0
    }
                func setItems(_ items:[CourseItemModel]){
                                self.items = items
                                cons_tableHei.constant = 70.5 * Double(items.count)
                func setItems(_ model:CourseModel){
                                self.model = model
                                cons_tableHei.constant = 70.5 * Double(model.list.count)
                                self.tableView.reloadData()
                }
}
@@ -38,16 +38,23 @@
extension CourseDetail_2_TCell:UITableViewDelegate & UITableViewDataSource{
                func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                let vc = CourseDetialVideoVC(items: items, selectIndex: indexPath)
                                JQ_currentViewController().jq_push(vc: vc)
                                guard let m = model else {return}
                                if m.chargeType == .free || (m.chargeType == .vipFree && UserViewModel.getAvatarInfo().isVip == .yes) || (m.chargeType == .payment && m.isBuy == .yes){
                                                let vc = CourseDetialVideoVC(items: model!.list, selectIndex: indexPath)
                                                JQ_currentNavigationController().pushViewController(vc)
                                }else{
                                                let vc = PaymentOrderVC(courseId: m.id)
                                                JQ_currentNavigationController().pushViewController(vc)
                                }
                }
                func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                                return items.count
                                return model?.list.count ?? 0
                }
                
                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                let model = items[indexPath.row]
                                let model = model!.list[indexPath.row]
                                let cell = tableView.dequeueReusableCell(withIdentifier: "_CourseDetail_2_Inner_TCell", for: indexPath) as! CourseDetail_2_Inner_TCell
                                cell.setModel(model, index: indexPath)
                                cell.backgroundColor = .clear
XQMuse/Root/Course/VC/CourseDetialVC.swift
@@ -15,9 +15,12 @@
                case style2 //无视频
}
let CourseRefresh_Noti = Notification.Name.init("CourseRefresh_Noti")
class CourseDetialVC: BaseVC {
                private var tableView:UITableView?
                private let studyBtn = QMUIButton(type: .custom)
                private var headerView = CourseDetailHeaderView.jq_loadNibView()
                private var barStyle:UIStatusBarStyle = .lightContent
                private var scrollShowCell = false
@@ -77,27 +80,10 @@
                                fatalError("init(coder:) has not been implemented")
                }
                
    override func viewDidLoad() {
        super.viewDidLoad()
                override func viewDidLoad() {
                                super.viewDidLoad()
                                title = "课程详情"
                                Services.getCourseDetail(courseId: courseId).subscribe(onNext: {data in
                                                if let m = data.data{
                                                                self.courseDetailModel = m
                                                                self.headerView.setCourseModel(m)
                                                                self.section1TCell.setItems(m.list)
                                                                self.section2TCell.setItems(m.list2)
                                                                if m.detailUrl.jq_isVideo{
                                                                                self.style = .style1
                                                                                self.pageMenu.setItems(["简介","章节","相关推荐"], selectedItemIndex: 0)
                                                                }else{
                                                                                self.style = .style2
                                                                                self.pageMenu.setItems(["简介"], selectedItemIndex: 0)
                                                                }
                                                                self.tableView?.reloadData()
                                                }
                                }).disposed(by: disposeBag)
                                getData()
    }
                override func setUI() {
@@ -135,6 +121,31 @@
                                setFootView()
                }
                private func getData(){
                                Services.getCourseDetail(courseId: courseId).subscribe(onNext: {data in
                                                if let m = data.data{
                                                                self.courseDetailModel = m
                                                                self.headerView.setCourseModel(m)
                                                                self.section1TCell.setItems(m)
                                                                self.section2TCell.setItems(m.list2)
                                                                if m.isBuy != .yes{
                                                                                let attribute    = AttributedStringbuilder.build().add(string: "    疗愈币", withFont: .systemFont(ofSize: 12,weight: .bold), withColor: UIColor(hexString: "#F6F6F6")!).add(string: "\(m.generalPrice.jq_formatFloat)", withFont: .systemFont(ofSize: 21.71, weight: .bold), withColor: UIColor(hexString: "#F6F6F6")!).add(string: "  立即购买     ", withFont: .systemFont(ofSize: 16, weight: .bold), withColor: UIColor(hexString: "#F6F6F6")!).mutableAttributedString
                                                                                self.studyBtn.setAttributedTitle(attribute, for: .normal)
                                                                }
                                                                if m.detailUrl.jq_isVideo{
                                                                                self.style = .style1
                                                                                self.pageMenu.setItems(["简介","章节","相关推荐"], selectedItemIndex: 0)
                                                                }else{
                                                                                self.style = .style2
                                                                                self.pageMenu.setItems(["简介"], selectedItemIndex: 0)
                                                                }
                                                                self.tableView?.reloadData()
                                                }
                                }).disposed(by: disposeBag)
                }
                private func setFootView(){
                                let footView = UIView()
                                footView.backgroundColor = .white
@@ -158,7 +169,6 @@
                                                make.top.equalTo(26.5)
                                }
                                let studyBtn = QMUIButton(type: .custom)
                                studyBtn.setTitleColor(UIColor.white, for: .normal)
                                studyBtn.setTitle("    立即学习    ", for: .normal)
                                studyBtn.addTarget(self, action: #selector(handleAction(_:)), for: .touchUpInside)
@@ -187,11 +197,20 @@
                                                                }
                                                }
                                }).disposed(by: disposeBag)
                                NotificationCenter.default.rx.notification(CourseRefresh_Noti).take(until: self.rx.deallocated).subscribe(onNext: {data in
                                                self.getData()
                                }).disposed(by: disposeBag)
                }
                @objc func handleAction(_ btn:QMUIButton){
                                if let items = courseDetailModel?.list{
                                                let vc = CourseDetialVideoVC(items: items, selectIndex: IndexPath(row: 0, section: 0))
                                if let m = courseDetailModel{
                                                if m.chargeType == .free || (m.chargeType == .vipFree && UserViewModel.getAvatarInfo().isVip == .yes) || (m.chargeType == .payment && m.isBuy == .yes){
                                                                let vc = CourseDetialVideoVC(items: m.list, selectIndex: IndexPath(row: 0, section: 0))
                                                                push(vc: vc);return
                                                }
                                                let vc = PaymentOrderVC(courseId: m.id)
                                                push(vc: vc)
                                }
                }
@@ -199,7 +218,7 @@
                @objc func sendGift(_ btn:QMUIButton){
                                if let price = courseDetailModel?.generalPrice{
                                                CourseSendGiftView.show(price:price) {
                                                                let vc = PaymentOrderVC()
                                                                let vc = PaymentOrderVC(courseId: self.courseDetailModel!.id,giftToOther: true)
                                                                self.push(vc: vc)
                                                }
                                }
XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift
@@ -79,6 +79,15 @@
                                let model = viewModel.dataSource.value!.list[indexPath.row]
                                let vc = CourseDetialVC(courseId: model.id)
                                JQ_currentViewController().jq_push(vc: vc)
//                                let isVip = UserViewModel.getAvatarInfo().isVip == .yes
//                                if model.isBuy == .yes || model.chargeType == .free || (model.chargeType == .vipFree && isVip){
//
//                                                return
//                                }else{
//                                                let vc = CourseDetialVC(courseId: model.id)
//                                                JQ_currentViewController().jq_push(vc: vc)
//                                }
                }
XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift
@@ -11,10 +11,34 @@
class CourseVCTeacherSpecialVC: BaseVC {
                private var tableView:UITableView?
                private var headerView:VideoView!
                private var model:TutorInfoModel?
                private var cell0:CourseDetail_1_TCell?
                private var cell1:CourseDetail_3_TCell?
                override func viewDidDisappear(_ animated: Bool) {
                                super.viewDidDisappear(animated)
                                headerView.pauseVideo()
                }
    override func viewDidLoad() {
        super.viewDidLoad()
                                cell0    = (tableView!.dequeueReusableCell(withIdentifier: "_CourseDetail_1_TCell") as! CourseDetail_1_TCell)
                                cell1 = (tableView!.dequeueReusableCell(withIdentifier: "_CourseDetail_3_TCell") as! CourseDetail_3_TCell)
                                cell0!.backgroundColor = UIColor(hexString: "#f6f6f6")
                                cell1!.backgroundColor = UIColor(hexString: "#f6f6f6")
                                Services.tutorInfo().subscribe(onNext: { data in
                                                if let m = data.data{
                                                                self.model = m
                                                                self.cell0!.setContent(title: "导师简介", content: m.tutorIntroduction)
                                                                self.cell1!.setItems(m.list)
                                                                self.tableView?.reloadData()
                                                                self.headerView.updateVideoUrl(m.videoUrl,autoPlay: false,placeHoderImageUrl: m.coverUrl)
                                                }
                                }).disposed(by: disposeBag)
    }
                override func setUI() {
@@ -39,10 +63,26 @@
                                }
                                DispatchQueue.main.async {
                                                self.headerView = VideoView(url: "http://vfx.mtime.cn/Video/2021/07/10/mp4/210710094507540173.mp4")
                                                self.headerView = VideoView(url: nil)
                                                self.tableView!.tableHeaderView = self.headerView
                                                self.headerView.frame = CGRect(x: 0, y: 0, width: JQ_ScreenW, height: JQ_ScreenW * 0.56)
                                }
                }
                override func setRx() {
                                self.cell0?.webView.scrollView.rx.observe(CGSize.self, "contentSize").map { (size) -> CGFloat? in
                                                if let size = size{
                                                                return size.height
                                                }
                                                return nil
                                }.subscribe(onNext: { [unowned self](height) in
                                                if let height = height{
                                                                if height > self.cell0?.cons_webHei.constant ?? 0{
                                                                                self.cell0?.cons_webHei.constant = height
                                                                                self.tableView?.reloadData()
                                                                }
                                                }
                                }).disposed(by: disposeBag)
                }
                override var shouldAutorotate: Bool{
@@ -68,16 +108,11 @@
                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                if indexPath.row == 0{
                                                let cell = tableView.dequeueReusableCell(withIdentifier: "_CourseDetail_1_TCell") as! CourseDetail_1_TCell
                                                cell.backgroundColor = UIColor(hexString: "#f6f6f6")
                                                cell.setContent(title: "导师简介", content: "")
                                                return cell
                                                return cell0!
                                }
                                if indexPath.row == 1{
                                                let cell = tableView.dequeueReusableCell(withIdentifier: "_CourseDetail_3_TCell") as! CourseDetail_3_TCell
                                                cell.backgroundColor = UIColor(hexString: "#f6f6f6")
                                                return cell
                                                return cell1!
                                }
                                var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift
@@ -57,7 +57,7 @@
                                }
                                if m.chargeType == .payment && m.paidStatus == .no{
                                                let vc = PaymentOrderVC()
                                                let vc = PaymentOrderVC(courseId: m.id)
                                                JQ_currentViewController().jq_push(vc: vc)
                                                return
                                }
XQMuse/Root/Home/VC/PaymentOrderResultVC.swift
@@ -10,13 +10,47 @@
class PaymentOrderResultVC: BaseVC {
                var collectionView:UICollectionView!
                private  let topView = PaymentOrderResultTopView.jq_loadNibView()
//                private let shadowView = UIView()
                private let topView = PaymentOrderResultTopView.jq_loadNibView()
                private var courseId:Int!
                private var price:Double!
                private var models = [CourseModel]()
                init(courseId:Int,price:Double) {
                                super.init(nibName: nil, bundle: nil)
                                self.courseId = courseId
                                self.price = price
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                override func viewDidLoad() {
                                super.viewDidLoad()
                                title = "支付结果"
                                NotificationCenter.default.post(name: CourseRefresh_Noti, object: nil)
                                yy_popBlock = { [weak self] () in
                                                var toVC:UIViewController?
                                                for v in self?.navigationController?.viewControllers ?? []{
                                                                if v is CourseDetialVC{
                                                                                toVC = v;break
                                                                }
                                                }
                                                if toVC != nil{
                                                                self?.navigationController?.popToViewController(toVC!, animated: true)
                                                }else{
                                                                self?.navigationController?.popToRootViewController(animated: true)
                                                }
                                }
                                topView.setPrice(price)
                                Services.paymentSuccess(courseId: courseId).subscribe(onNext: {data in
                                                self.models = data.data ?? []
                                                self.collectionView.reloadData()
                                }).disposed(by: disposeBag)
                }
                override func setUI() {
@@ -66,22 +100,24 @@
                }
}
extension PaymentOrderResultVC:UIScrollViewDelegate{
                func scrollViewDidScroll(_ scrollView: UIScrollView) {
                                let v = (scrollView.contentOffset.y) + 298
                                topView.y = -v
                                navigationController?.navigationBar.standardAppearance.backgroundColor = .white
                }
}
extension PaymentOrderResultVC:UICollectionViewDelegate & UICollectionViewDataSource{
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 50
                                return models.count
                }
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//                                let vc = HomeItemDetailVC()
//                                push(vc: vc)
                                let model = models[indexPath.row]
                                let vc = CourseDetialVC(courseId: model.id)
                                push(vc: vc)
                }
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
XQMuse/Root/Home/VC/PaymentOrderVC.swift
@@ -8,21 +8,84 @@
import UIKit
import QMUIKit
let Refreh_PaymentWallet_Noti = Notification.Name.init("Refreh_PaymentWallet_Noti")
class PaymentOrderVC: BaseVC {
                @IBOutlet weak var image_cover: UIImageView!
                @IBOutlet weak var label_price: UILabel!
                @IBOutlet weak var label_teacher: UILabel!
                @IBOutlet weak var label_paymentCount: UILabel!
                @IBOutlet weak var label_courseName: UILabel!
                @IBOutlet weak var label_orderPrice: UILabel!
                @IBOutlet weak var label_currentAccount: UILabel!
                @IBOutlet weak var label_totalPrice: UILabel!
                @IBOutlet weak var view_searchUserInput: UIView!
                @IBOutlet weak var view_searchUserResult: UIView!
                @IBOutlet weak var image_avatar: UIImageView!
                @IBOutlet weak var label_userName: UILabel!
                @IBOutlet weak var label_userPhone: UILabel!
                @IBOutlet weak var label_searchInfo: UILabel!
                @IBOutlet weak var btn_invate: UIButton!
                @IBOutlet weak var btn_isRead: UIButton!
                @IBOutlet weak var tf_phone: QMUITextField!
                @IBOutlet weak var label_walletBalance: UILabel!
                @IBOutlet weak var btn_isreadAgreement: UIButton!
                private var courseId:Int!
                private var giftUserId:Int?
                private var giftToOther:Bool!
                private var courseModel:CourseModel?
                private var balance:Double = 0
                init(courseId:Int,giftToOther:Bool = false) {
                                super.init(nibName: nil, bundle: nil)
                                self.courseId = courseId
                                self.giftToOther = giftToOther
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                
                override func viewDidLoad() {
        super.viewDidLoad()
                                title = "确认订单"
                                view_searchUserResult.isHidden = true
                                view_searchUserInput.isHidden = !giftToOther
                                getBalance()
                                Services.getCourseDetail(courseId: courseId).subscribe(onNext: {data in
                                                if let m = data.data{
                                                                self.courseModel = m
                                                                self.image_cover.sd_setImage(with: URL(string: m.coverUrl))
                                                                self.label_courseName.text = m.courseTitle
                                                                self.label_price.text = "愈疗币\(m.generalPrice.jq_formatFloat)"
                                                                self.label_teacher.text = "导师\(m.tutor)"
                                                                self.label_paymentCount.text = "x\(m.count)"
                                                                self.label_orderPrice.text = "愈疗币\(m.generalPrice.jq_formatFloat)"
                                                                self.label_totalPrice.text = "愈疗币\(m.generalPrice.jq_formatFloat)"
                                                }
                                }).disposed(by: disposeBag)
    }
                override func setUI() {
                                super.setUI()
                }
                override func setRx() {
                                NotificationCenter.default.rx.notification(Refreh_PaymentWallet_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in
                                                self.getBalance()
                                }).disposed(by: disposeBag)
                }
                private func getBalance(){
                                Services.getUserBalance().subscribe(onNext: {data in
                                                self.balance = data.data ?? 0
                                                self.label_walletBalance.text = String(format: "当前可用 %@疗愈币", data.data?.jq_formatFloat ?? "0")
                                }).disposed(by: disposeBag)
                }
                @IBAction func invateRegisterAction(_ sender: UIButton) {
@@ -30,6 +93,31 @@
                }
                @IBAction func searchUserAction(_ sender: UIButton) {
                                guard !tf_phone.text!.isEmpty else {
                                                alertError(msg: tf_phone.placeholder ?? "请输入好友手机号");return
                                }
                                guard tf_phone.text!.jq_isPhone else {
                                                alertError(msg: "请输入正确的手机号");return
                                }
                                Services.searchUserByPhone(tf_phone.text!).subscribe(onNext: { data in
                                                self.view_searchUserResult.isHidden = false
                                                if let m = data.data,m.id != 0{
                                                                self.giftUserId = m.userId
                                                                self.image_avatar.sd_setImage(with: URL(string: m.avatar))
                                                                self.label_userName.text = m.nickname
                                                                self.label_userPhone.text = m.cellPhone
                                                                self.label_searchInfo.isHidden = true
                                                                self.btn_invate.isHidden = true
                                                }else{
                                                                self.image_avatar.isHidden = true
                                                                self.label_userName.isHidden = true
                                                                self.label_userPhone.isHidden = true
                                                                self.label_searchInfo.isHidden = false
                                                                self.btn_invate.isHidden = false
                                                }
                                }).disposed(by: disposeBag)
                }
@@ -39,11 +127,34 @@
                @IBAction func webAgreementAction(_ sender: UIButton) {
                                let vc = WebVC(type: .course)
                                push(vc: vc)
                }
                @IBAction func completeAction(_ sender: UIButton) {
                                let vc = PaymentOrderResultVC()
                                guard let m = courseModel else {return}
                                guard balance > m.generalPrice else{
                                                CommonAlertView.show(title: "提示", content: "当前余额不足,请先充值", cancelStr: "暂不充值", completeStr: "去充值", isSingle: false) { state in
                                                                if state{
                                                                }
                                                }
                                                return
                                }
                                guard btn_isRead.isSelected else {
                                                alertError(msg: "请先阅读并同意《课程/疗愈音频购买协议》");return
                                }
                                if giftToOther {
                                                guard giftUserId != nil else {
                                                                alertError(msg: "请输入您要赠送人的手机号");return
                                                }
                                }
                                let vc = PaymentOrderResultVC(courseId: courseId, price: m.generalPrice)
                                push(vc: vc)
                }
}
XQMuse/Root/Home/VC/PaymentOrderVC.xib
@@ -11,10 +11,26 @@
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PaymentOrderVC" customModule="XQMuse" customModuleProvider="target">
            <connections>
                <outlet property="btn_invate" destination="3oo-WM-iPM" id="gMF-RC-xpe"/>
                <outlet property="btn_isRead" destination="9jh-cC-nHB" id="a2J-f4-hup"/>
                <outlet property="btn_isreadAgreement" destination="9jh-cC-nHB" id="kmT-qh-HGA"/>
                <outlet property="image_avatar" destination="TT7-tl-th0" id="5bW-5j-b49"/>
                <outlet property="image_cover" destination="LBY-Q2-RQA" id="ygZ-SN-xO1"/>
                <outlet property="label_courseName" destination="GMw-pK-u8J" id="bFk-Vl-gDP"/>
                <outlet property="label_currentAccount" destination="W3z-Hl-09j" id="Lrx-D9-x8Y"/>
                <outlet property="label_orderPrice" destination="s0D-hY-lov" id="Y0T-c6-a7g"/>
                <outlet property="label_paymentCount" destination="hW7-II-bKY" id="6Oe-Qv-0S4"/>
                <outlet property="label_price" destination="iyN-A8-Fyo" id="2M1-II-1hx"/>
                <outlet property="label_searchInfo" destination="jVb-Rt-nvY" id="Vty-h8-0vY"/>
                <outlet property="label_teacher" destination="y7d-Qe-XsO" id="I7L-lZ-geq"/>
                <outlet property="label_totalPrice" destination="M0e-rH-WtI" id="BHo-Bg-EhQ"/>
                <outlet property="label_userName" destination="hrJ-kN-vso" id="HlX-AF-pbk"/>
                <outlet property="label_userPhone" destination="ZF1-aZ-gRo" id="Htl-Of-nO6"/>
                <outlet property="label_walletBalance" destination="W3z-Hl-09j" id="CNw-KV-Uyh"/>
                <outlet property="tf_phone" destination="W3K-U0-zHA" id="IkD-kf-fwY"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
                <outlet property="view_searchUserInput" destination="4AR-Ov-N15" id="PUF-Q2-O32"/>
                <outlet property="view_searchUserResult" destination="nDP-lX-aFn" id="dT4-gg-Lzj"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
XQMuse/Root/Home/View/PaymentOrderResultTopView.swift
@@ -10,7 +10,6 @@
class PaymentOrderResultTopView: UIView,JQNibView{
                @IBOutlet weak var label_price: UILabel!
                @IBOutlet weak var btn_lookCourse: UIButton!
@@ -18,6 +17,10 @@
                                super.awakeFromNib()
                }
                func setPrice(_ price:Double){
                                label_price.text = "\(price.jq_formatFloat)"
                }
                @IBAction func backRootAction(_ sender: UIButton) {
                                JQ_currentNavigationController().popToRootViewController(animated: true)
                }
XQMuse/Root/Home/View/PaymentOrderResultTopView.xib
@@ -30,8 +30,8 @@
                    <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
                    <nil key="highlightedColor"/>
                </label>
                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2980.00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hDa-VO-Vzk">
                    <rect key="frame" x="160.66666666666666" y="165" width="124.99999999999997" height="37"/>
                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hDa-VO-Vzk">
                    <rect key="frame" x="213" y="165" width="20.333333333333343" height="37"/>
                    <constraints>
                        <constraint firstAttribute="height" constant="37" id="9iu-Ck-Y6k"/>
                    </constraints>
XQMuse/Root/Login/LoginVC.swift
@@ -173,8 +173,15 @@
                                Services.loginBy(phone: viewModel.loginPhone.value, content: viewModel.loginContent.value, type: viewModel.loginType.value).subscribe(onNext: { data in
                                                if let model = data.data{
                                                                UserViewModel.saveUserInfo(model)
                                                                sceneDelegate?.loginSuccess()
                                                                UserViewModel.saveLoginInfo(model)
                                                                Services.getUserInfo().subscribe(onNext: {data in
                                                                                if let model = data.data{
                                                                                                UserViewModel.saveAvatarInfo(model)
                                                                                }
                                                                }).disposed(by: self.disposeBag)
                                                }
                                }).disposed(by: disposeBag)
                }
XQMuse/Root/Login/VC/RegisterVC.swift
@@ -112,8 +112,14 @@
                                Services.register(cellPhone: viewModel.phone.value, captcha: viewModel.code.value, password: viewModel.pwd.value).subscribe(onNext: {data in
                                                if let model = data.data{
                                                                UserViewModel.saveUserInfo(model)
                                                                sceneDelegate?.loginSuccess()
                                                                UserViewModel.saveLoginInfo(model)
                                                                Services.getUserInfo().subscribe(onNext: {data in
                                                                                if let model = data.data{
                                                                                                UserViewModel.saveAvatarInfo(model)
                                                                                }
                                                                }).disposed(by: self.disposeBag)
                                                }
                                }).disposed(by: disposeBag)
                }
XQMuse/Root/Network/Models.swift
@@ -171,8 +171,8 @@
                var headers = [String]()
                var id: Int = 0
                var iosPrice: Int = 0
                var isBuy: Int = 0
                var isVip: Int = 0
                var isBuy: ConditionType = .no
                var isVip: ConditionType = .no
                var latitude: Int = 0
                var listingStatus: Int = 0
                var longitude: Int = 0
@@ -205,6 +205,88 @@
}
struct UserInfoModel:HandyJSON,Identifiable,Codable{
                static let idKey = \UserInfoModel.id
                var appleId: String = ""
                var avatar: String = ""
                var balance: Int = 0
                var birthday: String = ""
                var cellPhone: String = ""
                var company: String = ""
                var createBy: String = ""
                var createTime: String = ""
                var delFlag: Int = 0
                var education: String = ""
                var email: String = ""
                var freezingOperator: String = ""
                var freezingReason: String = ""
                var gender: Int = 0
                var hometown: String = ""
                var id: Int = 0
                var income: Int = 0
                var industry: String = ""
                var inviteUserId: Int = 0
                var isFirst: Int = 0
                var levelSettingId: Int = 0
                var location: String = ""
                var logoutTime: String = ""
                var nickname: String = ""
                var occupation: String = ""
                var registerTime: String = ""
                var sanskritFlag: Int = 0
                var signature: String = ""
                var signTime: String = ""
                var tagId: String = ""
                var totalEnergyValue: Int = 0
                var updateBy: String = ""
                var updateTime: String = ""
                var userId: Int = 0
                var userStatus: Int = 0
                var vipExpireTime: String = ""
                var isVip:ConditionType = .no
                var wxOpenId: String = ""
}
struct TutorInfoModel:HandyJSON{
                var id = 0
                var tutorIntroduction = ""
                var coverUrl = ""
                var videoUrl = ""
                var list = [CourseModel]()
}
struct TreeInfoModel:HandyJSON,Identifiable,Codable{
                static let idKey = \TreeInfoModel.id
                var appUserId: Int = 0
                var createBy: String = ""
                var createTime: String = ""
                var currentEnergyValue: Int = 0
                var delFlag: Int = 0
                var growthValue: Int = 0
                var id: Int = 0
                var isSign:  ConditionType = .no
                var nextLevel: Int = 0
                var sowAgain: ConditionType = .no
                var taskOne:  ConditionType = .no
                var taskTwo:  ConditionType = .no
                var treeLevelType: TreeLevel = .level_1
                var updateBy: String = ""
                var updateTime: String = ""
                var status:ConditionType = .no //是否枯萎
}
struct WateringModel:HandyJSON{
                var growthValue = 0
                var nextLevel = 0
                var isNext = false
                var status = 0 //是否枯萎 1是2否(暂时不用)
}
XQMuse/Root/Network/NetworkRequest.swift
@@ -49,6 +49,10 @@
}
extension Double: HandyJSON{
}
class ParamsAppender: NSObject {
                var url: URL
                var params:Dictionary = [String: Any]()
XQMuse/Root/Network/Services.swift
@@ -232,11 +232,19 @@
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
                /// 课程详情
                class func getCourseDetail(courseId:Int)->Observable<BaseResponse<CourseModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/course/client/course/course/getPayCourseInfoById")
                                                .append(key: "id", value: courseId)
                                                .append(key: "apipost_id", value: "2d2eb9d23993bd")
                                return NetworkRequest.request(params: params, method: .post, progress: true)
                }
                class func tutorInfo()->Observable<BaseResponse<TutorInfoModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/course/client/course/tutor-special-column/getCoursePageList")
                                                .append(key: "apipost_id", value: "2d2eb9d23993c2")
                                return NetworkRequest.request(params: params, method: .post, progress: true)
                }
}
@@ -266,6 +274,60 @@
                }
}
///用户相关
extension Services{
                class func searchUserByPhone(_ phone:String)->Observable<BaseResponse<UserInfoModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/user/client/app-user/getUserByPhone")
                                                .append(key: "phone", value: phone)
                                                .append(key: "apipost_id", value: "2e763463799135")
                                return NetworkRequest.request(params: params, method: .post, progress: true)
                }
                /// 获取用户信息
                class func getUserInfo()->Observable<BaseResponse<UserInfoModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/user/client/app-user/getCurrentUser")
                                                .append(key: "apipost_id", value: "2e763463799132")
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
                /// 支付成功
                class func paymentSuccess(courseId:Int)->Observable<BaseResponse<[CourseModel]>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/course/client/course/course/successOrder")
                                                .append(key: "courseId", value: courseId)
                                                .append(key: "apipost_id", value: "2d2eb9d23993c0")
                                return NetworkRequest.request(params: params, method: .post, progress: true)
                }
                class func getUserBalance()->Observable<BaseResponse<Double>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/user/client/app-user/getUserBalance")
                                                .append(key: "apipost_id", value: "2e763463799134")
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
}
/// 树苗
extension Services{
                class func treeInfo()->Observable<BaseResponse<TreeInfoModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/user/client/app-user-tree/getUserTree")
                                                .append(key: "apipost_id", value: "2e76346379912c")
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
                //浇水
                class func watering()->Observable<BaseResponse<WateringModel>>{
                                let params = ParamsAppender.build(url: All_Url)
                                params.interface(url: "/user/client/app-user-tree/watering")
                                                .append(key: "apipost_id", value: "2e763463799130")
                                return NetworkRequest.request(params: params, method: .post, progress: false)
                }
}
extension Services{
                /// 获取协议
                class func agreementBy(_ type:AgreementType)->Observable<BaseResponse<HtmlModel>>{
XQMuse/Root/Network/ViewModels/UserViewModel.swift
@@ -36,7 +36,8 @@
}
class UserViewModel{
                private static let userInfo = UserDefaultsStore<LoginUserInfoModel>(uniqueIdentifier: "UserInfoModel")!
                private static let userLoginInfo = UserDefaultsStore<LoginUserInfoModel>(uniqueIdentifier: "userLoginInfo")!
                private static let userAvatarInfo = UserDefaultsStore<UserInfoModel>(uniqueIdentifier: "userAvatarInfo")!
                static func getToken()->String?{
                                return UserDefaults.standard.object(forKey: "_userToken") as? String
@@ -51,19 +52,37 @@
                                UserDefaults.standard.synchronize()
                }
                static func saveUserInfo(_ model:LoginUserInfoModel){
                static func saveLoginInfo(_ model:LoginUserInfoModel){
                                do{
                                                try UserViewModel.userInfo.save(model)
                                                try UserViewModel.userLoginInfo.save(model)
                                }catch{
                                }
                }
                static func getUserInfo()->LoginUserInfoModel?{
                                return UserViewModel.userInfo.allObjects().first
                static func getLoginInfo()->LoginUserInfoModel?{
                                return UserViewModel.userLoginInfo.allObjects().first
                }
                static func clearUserInfo(){
                                UserViewModel.userInfo.deleteAll()
                static func clearLoginInfo(){
                                UserViewModel.userLoginInfo.deleteAll()
                }
                static func saveAvatarInfo(_ model:UserInfoModel){
                                do{
                                                try UserViewModel.userAvatarInfo.save(model)
                                }catch{
                                }
                }
                static func getAvatarInfo()->UserInfoModel{
                                let userModel = UserViewModel.userAvatarInfo.allObjects().first
                                return userModel == nil ? UserInfoModel():userModel!
                }
                static func clearAvatarInfo(){
                                UserViewModel.userAvatarInfo.deleteAll()
                }
}
XQMuse/Root/Other/View/VideoView.swift
@@ -14,8 +14,9 @@
                private var url:String?
                private var disposeBag = DisposeBag()
                private var placeHoderImageUrl:String?
                private lazy var player: CLPlayer = {
                private(set) lazy var player: CLPlayer = {
                                let p = CLPlayer(frame: .zero) { config in
                                                config.topBarHiddenStyle = .always
                                                config.isHiddenMorePanel = true
@@ -31,28 +32,73 @@
                                return p
                }()
                required    init(url:String) {
                required    init(url:String? = nil,autoPlay:Bool = false,placeHoderImageUrl:String? = nil) {
                                super.init(frame: .zero)
                                self.url = url
                                addSubview(player)
                                player.delegate = self
                                player.snp.makeConstraints { make in
                                                make.edges.equalToSuperview()
                                }
                                self.placeHoderImageUrl = placeHoderImageUrl
                                if placeHoderImageUrl != nil{
                                                addPlaceHoderView(placeHoderImage: placeHoderImageUrl!)
                                }
                                if let Url = URL(string: url){
                                                self.url = url
                                                player.url = Url
                                                addSubview(player)
                                                player.delegate = self
                                                player.snp.makeConstraints { make in
                                                                make.edges.equalToSuperview()
                                                if autoPlay{
                                                                player.play()
                                                }
                                                player.play()
                                }
                }
                func updateVideoUrl(_ url:String){
                func updateVideoUrl(_ url:String,autoPlay:Bool = false,placeHoderImageUrl:String? = nil){
                                self.placeHoderImageUrl = placeHoderImageUrl
                                if placeHoderImageUrl != nil{
                                                addPlaceHoderView(placeHoderImage: placeHoderImageUrl!)
                                }
                                if let Url = URL(string: url){
                                                player.url = Url
                                                player.play()
                                                if autoPlay{
                                                                player.play()
                                                }
                                }
                }
                private func addPlaceHoderView(placeHoderImage:String){
                                let placeV = UIView()
                                placeV.backgroundColor = .black
                                placeV.frame = player.frame
                                let imageView = UIImageView()
                                imageView.sd_setImage(with: URL(string: placeHoderImage))
                                imageView.contentMode = .scaleAspectFill
                                placeV.addSubview(imageView)
                                imageView.frame = player.frame
                                let btn_placeholder = UIButton(type: .custom)
                                btn_placeholder.setImage(UIImage(named: "icon_play"), for: .normal)
                                btn_placeholder.addTarget(self, action: #selector(continueVideo), for: .touchUpInside)
                                placeV.addSubview(btn_placeholder)
                                btn_placeholder.snp.makeConstraints { make in
                                                make.center.equalToSuperview()
                                }
                                player.placeholder = placeV
                }
                func pauseVideo(){
                                player.pause()
                }
                @objc func continueVideo(){
                                player.play()
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png

XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png

XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png

XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png

XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png

XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png
XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png
XQMuse/Root/TreeGroup/TreeTeskVC.swift
@@ -9,36 +9,11 @@
import AVKit
import JQTools
import APNGKit
enum TreeLevel:Int{
                case level_1 = 1
                case level_2 = 2
                case level_3 = 3
                case level_4 = 4
                case level_5 = 5
                case level_6 = 6
                case level_7 = 7
                case level_8 = 8
                case level_9 = 9
                case level_10 = 10
                var aniResource:String{
                                switch self {
                                                case .level_1:return "apngb-animated-level-1"
                                                case .level_2:return "apngb-animated-level-2"
                                                case .level_3:return "apngb-animated-level-3"
                                                case .level_4:return "apngb-animated-level-4"
                                                case .level_5:return "apngb-animated-level-5"
                                                case .level_6:return "apngb-animated-level-6"
                                                case .level_7:return "apngb-animated-level-7"
                                                case .level_8:return "apngb-animated-level-8"
                                                case .level_9:return "apngb-animated-level-9"
                                                case .level_10:return "apngb-animated-level-10"
                                }
                }
}
import UserDefaultsStore
class TreeTeskVC: BaseVC {
                private let cacheTreeInfoModel = UserDefaultsStore<TreeInfoModel>(uniqueIdentifier: "cacheTreeInfoModel")!
                @IBOutlet weak var view_energy: UIView!
                @IBOutlet weak var icon_energy: UILabel!
@@ -51,8 +26,6 @@
                @IBOutlet weak var view_progress: UIView!
                @IBOutlet weak var cons_progressHei: NSLayoutConstraint!
                @IBOutlet weak var label_progress: UILabel!
                private var tempEnergy:Int = 0
                private lazy var player:AVPlayer = {
                                let bgPath = Bundle.main.url(forResource: "bg", withExtension: "mov")
@@ -80,12 +53,7 @@
                private var aPNGSunImageView:APNGImageView?
                private var aPNGActionImageView:APNGImageView?
                private var treeLevel:TreeLevel = .level_1{
                                didSet{
                                                updateAni()
                                }
                }
                private var treeInfoModel:TreeInfoModel?
                override func viewDidDisappear(_ animated: Bool) {
                                super.viewDidDisappear(animated)
@@ -121,7 +89,7 @@
                override func viewDidLoad() {
                                super.viewDidLoad()
                                title = "树苗打卡站"
                                treeLevel = .level_1
                                btn_seedingAgain.isHidden = true
                                if settingModel!.userFirstOpenTreeTask{
                                                DispatchQueue.main.asyncAfter(delay: 2.0) {
@@ -130,13 +98,7 @@
                                                }
                                }
                                let h = (JQ_ScreenW - 90) * 0.7729
                                TreeTeskFirstRuleView.show(title: "升级", content:"恭喜!你的树苗已升级为XX阶段!",textAlignment: .center,height: h,textTopOffset: 57)
                                DispatchQueue.main.asyncAfter(deadline: .now()+2.0) {
                                                self.setProgress(current: 900, total: 1800)
                                }
                                getTreeData()
                }
                override func setUI() {
@@ -176,6 +138,38 @@
                                                make.bottom.equalToSuperview().offset((JQ_ScreenW * 0.655 - 50))
                                                make.height.equalTo(JQ_ScreenW * 0.655)
                                }
                }
                private func getTreeData(){
                                //缓存的树苗信息
                                if let cacheModel = cacheTreeInfoModel.allObjects().first{
                                                treeInfoModel = cacheModel
                                                updateTreeInfo()
                                }
                                Services.treeInfo().subscribe(onNext: {data in
                                                if let m = data.data{
                                                                try? self.cacheTreeInfoModel.save(m)
                                                                //检查hash,进行同步
                                                                if m.toJSON()?.jq_hash() != self.treeInfoModel?.toJSON()?.jq_hash(){
                                                                                self.treeInfoModel = m
                                                                                self.updateTreeInfo()
                                                                }
                                                }
                                }).disposed(by: disposeBag)
                }
                private func updateTreeInfo(){
                                btn_seedingAgain.isHidden = treeInfoModel!.sowAgain == .no
//                                if treeLevel.rawValue != treeInfoModel?.treeLevelType.rawValue{
//                                                treeLevel = treeInfoModel!.treeLevelType
//                                }
                                icon_energy.text = String(format: "当前能量值:%ld", treeInfoModel!.currentEnergyValue)
                                setProgress(current: treeInfoModel!.growthValue, total: treeInfoModel!.nextLevel)
                }
                override func setRx() {
@@ -243,7 +237,6 @@
                //能量明细
                @IBAction func energyDetailAction(_ sender: TapBtn) {
                                let vc = TreeTeskDetailVC()
                                push(vc: vc)
                }
@@ -255,6 +248,32 @@
                }
                @IBAction func wateringAction(_ sender: UIButton) {
                                sender.isUserInteractionEnabled = false
                                if treeInfoModel == nil {return}
//                                guard m.currentEnergyValue != 0 else{
//                                                alert(msg: "已经没有能量值了,快去做任务吧");return
//                                }
                                Services.watering().subscribe(onNext: {data in
                                                if let m = data.data{
                                                                if m.isNext{
                                                                                var type = self.treeInfoModel?.treeLevelType ?? .level_1
                                                                                self.treeInfoModel!.treeLevelType = TreeLevel(rawValue: type.rawValue + 1) ?? .level_1
                                                                                let h = (JQ_ScreenW - 90) * 0.7729
                                                                                TreeTeskFirstRuleView.show(title: "升级", content:"恭喜!你的树苗已升级为\(self.treeInfoModel!.treeLevelType.title)阶段!",textAlignment: .center,height: h,textTopOffset: 57)
                                                                                self.updateAni()
                                                                }
                                                                self.treeInfoModel?.currentEnergyValue = 0
                                                                self.treeInfoModel?.growthValue = m.growthValue
                                                                self.treeInfoModel?.nextLevel = m.nextLevel
                                                                self.updateTreeInfo()
                                                }
                                }).disposed(by: disposeBag)
                                if let waterApngImage = try? APNGImage(fileURL: Bundle.main.url(forResource: "apngb-animated-flow", withExtension:"png")!){
                                                waterApngImage.numberOfPlays = 2
                                                aPNGActionImageView = APNGImageView(image: waterApngImage)
@@ -273,6 +292,7 @@
                                                aPNGActionImageView!.onOnePlayDone.delegate(on: self) {[unowned self] a,b in
                                                                if b == 2{
                                                                                sender.isUserInteractionEnabled = true
                                                                                UIView.animate(withDuration: 0.5) {
                                                                                                self.aPNGActionImageView!.alpha = 0
                                                                                }completion: { _ in
@@ -284,7 +304,7 @@
                }
                @objc func jumpAction(){
                                treeLevel = TreeLevel(rawValue: treeLevel.rawValue + 1) ?? TreeLevel.level_1
                                //                                treeLevel = TreeLevel(rawValue: treeLevel.rawValue + 1) ?? TreeLevel.level_1
                }
                @objc func ruleAction(){
@@ -294,9 +314,12 @@
                }
                private func updateAni(){
                                let treeLevel = treeInfoModel?.treeLevelType ?? .level_1
                                guard let url = Bundle.main.url(forResource: treeLevel.aniResource, withExtension: "png") else {return}
                                if let treeApngImage = try? APNGImage(fileURL: url){
                                guard let animateUrl = Bundle.main.url(forResource: treeLevel.aniResource, withExtension: "png") else {return}
                                guard let staticDroopUrl = Bundle.main.url(forResource: treeLevel.staticDroopResource, withExtension: "png") else {return}
                                if let treeApngImage = try? APNGImage(fileURL: animateUrl){
                                                if treeLevel == .level_1{
                                                                treeApngImage.numberOfPlays = 1
@@ -316,8 +339,7 @@
                                                                view.addSubview(aPNGTreeImageView!)
                                                }
                                                //                                                aPNGTreeImageView!.backgroundColor = .red.withAlphaComponent(0.1)
                                                let scale:Double = 0.55
                                                let scale:Double = 0.55 //放大倍数
                                                aPNGTreeImageView!.snp.remakeConstraints { make in
                                                                make.centerX.equalToSuperview().offset(-10)
@@ -336,6 +358,12 @@
                                                                                                self.aPNGTreeImageView?.alpha = 1
                                                                                }completion: { _ in
                                                                                                self.aPNGTreeImageView!.startAnimating()
                                                                                                if self.treeInfoModel?.status == .yes{
                                                                                                                self.aPNGTreeImageView?.stopAnimating()
                                                                                                                self.aPNGTreeImageView?.image = nil
                                                                                                                self.aPNGTreeImageView?.staticImage = UIImage(contentsOfFile: staticDroopUrl.droppedScheme()!.absoluteString)
                                                                                                }
                                                                                }
                                                                }
                                                }
XQMuse/SceneDelegate.swift
@@ -36,6 +36,10 @@
                }
                func needLogin(){
                                UserViewModel.clearToken()
                                UserViewModel.clearLoginInfo()
                                UserViewModel.clearAvatarInfo()
                                let loginNav = LoginNav(rootViewController: LoginVC())
                                loginNav.modalPresentationStyle = .fullScreen
                                JQ_currentViewController().present(loginNav, animated: true)