From b1e53d01722f1705d99f5cf6ec63c8c493811405 Mon Sep 17 00:00:00 2001 From: 杨锴 <841720330@qq.com> Date: 星期五, 13 九月 2024 18:56:16 +0800 Subject: [PATCH] fix API --- XQMuse/Root/Course/VC/CourseDetialVC.swift | 67 ++- XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png | 0 XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png | 0 XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift | 2 XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png | 0 XQMuse/Root/TreeGroup/TreeTeskVC.swift | 128 +++++--- XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png | 0 XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift | 51 ++ XQMuse/Root/Home/VC/PaymentOrderVC.swift | 117 +++++++ XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png | 0 XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png | 0 XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png | 0 XQMuse.xcodeproj/project.pbxproj | 48 +++ XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png | 0 XQMuse/Root/Home/View/PaymentOrderResultTopView.swift | 5 XQMuse/Root/Network/Models.swift | 86 +++++ XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png | 0 XQMuse/Root/Login/VC/RegisterVC.swift | 8 XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png | 0 XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib | 6 XQMuse/Root/Home/VC/PaymentOrderResultVC.swift | 48 ++ XQMuse/Root/Home/View/PaymentOrderResultTopView.xib | 4 XQMuse/Root/Network/NetworkRequest.swift | 4 XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png | 0 XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png | 0 XQMuse/SceneDelegate.swift | 4 XQMuse/Root/Login/LoginVC.swift | 9 XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png | 0 XQMuse/Root/Network/ViewModels/UserViewModel.swift | 33 + XQMuse/Config/Enums/Enums.swift | 60 +++ XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift | 9 XQMuse/Root/Other/View/VideoView.swift | 66 +++ XQMuse/Root/Home/VC/PaymentOrderVC.xib | 16 + XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift | 23 + XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png | 0 XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png | 0 XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift | 12 XQMuse/Root/Network/Services.swift | 62 ++++ 38 files changed, 730 insertions(+), 138 deletions(-) diff --git a/XQMuse.xcodeproj/project.pbxproj b/XQMuse.xcodeproj/project.pbxproj index aff3e2f..8a952a2 100644 --- a/XQMuse.xcodeproj/project.pbxproj +++ b/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 */, diff --git a/XQMuse/Config/Enums/Enums.swift b/XQMuse/Config/Enums/Enums.swift index bdf9198..197f863 100644 --- a/XQMuse/Config/Enums/Enums.swift +++ b/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 "第十" + } + } +} diff --git a/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift b/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift index 5e4b714..af7b5e0 100644 --- a/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.swift +++ b/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) } } diff --git a/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib b/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib index fd0731e..be16fa8 100644 --- a/XQMuse/Root/Course/TCell/CourseDetail_1_TCell.xib +++ b/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> diff --git a/XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift b/XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift index ddda173..f9077e7 100644 --- a/XQMuse/Root/Course/TCell/CourseDetail_2_TCell.swift +++ b/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 diff --git a/XQMuse/Root/Course/VC/CourseDetialVC.swift b/XQMuse/Root/Course/VC/CourseDetialVC.swift index 4165914..8417269 100644 --- a/XQMuse/Root/Course/VC/CourseDetialVC.swift +++ b/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) } } diff --git a/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift b/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift index af899b8..0518eb6 100644 --- a/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift +++ b/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) +// } } diff --git a/XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift b/XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift index 7a686ca..7944004 100644 --- a/XQMuse/Root/Course/VC/CourseVCTeacherSpecialVC.swift +++ b/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") diff --git a/XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift b/XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift index 78d2f57..51e7a40 100644 --- a/XQMuse/Root/Home/TCell/Home_Style_3_TCell.swift +++ b/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 } diff --git a/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift b/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift index a8abf8e..47de44e 100644 --- a/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift +++ b/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 { diff --git a/XQMuse/Root/Home/VC/PaymentOrderVC.swift b/XQMuse/Root/Home/VC/PaymentOrderVC.swift index 14e6be9..47c8036 100644 --- a/XQMuse/Root/Home/VC/PaymentOrderVC.swift +++ b/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) } } diff --git a/XQMuse/Root/Home/VC/PaymentOrderVC.xib b/XQMuse/Root/Home/VC/PaymentOrderVC.xib index 73f19a8..d653f4f 100644 --- a/XQMuse/Root/Home/VC/PaymentOrderVC.xib +++ b/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"/> diff --git a/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift b/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift index 704b384..0cfff23 100644 --- a/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift +++ b/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) } diff --git a/XQMuse/Root/Home/View/PaymentOrderResultTopView.xib b/XQMuse/Root/Home/View/PaymentOrderResultTopView.xib index 2768715..cc97225 100644 --- a/XQMuse/Root/Home/View/PaymentOrderResultTopView.xib +++ b/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> diff --git a/XQMuse/Root/Login/LoginVC.swift b/XQMuse/Root/Login/LoginVC.swift index c98775f..041e323 100644 --- a/XQMuse/Root/Login/LoginVC.swift +++ b/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) } diff --git a/XQMuse/Root/Login/VC/RegisterVC.swift b/XQMuse/Root/Login/VC/RegisterVC.swift index 006e180..e9cca1f 100644 --- a/XQMuse/Root/Login/VC/RegisterVC.swift +++ b/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) } diff --git a/XQMuse/Root/Network/Models.swift b/XQMuse/Root/Network/Models.swift index 1bf6b35..e3dfe7e 100644 --- a/XQMuse/Root/Network/Models.swift +++ b/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否(暂时不用) +} + diff --git a/XQMuse/Root/Network/NetworkRequest.swift b/XQMuse/Root/Network/NetworkRequest.swift index 5ee4147..a4a1945 100644 --- a/XQMuse/Root/Network/NetworkRequest.swift +++ b/XQMuse/Root/Network/NetworkRequest.swift @@ -49,6 +49,10 @@ } +extension Double: HandyJSON{ + +} + class ParamsAppender: NSObject { var url: URL var params:Dictionary = [String: Any]() diff --git a/XQMuse/Root/Network/Services.swift b/XQMuse/Root/Network/Services.swift index 30cd640..ede648b 100644 --- a/XQMuse/Root/Network/Services.swift +++ b/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>>{ diff --git a/XQMuse/Root/Network/ViewModels/UserViewModel.swift b/XQMuse/Root/Network/ViewModels/UserViewModel.swift index 5c962f6..86f4104 100644 --- a/XQMuse/Root/Network/ViewModels/UserViewModel.swift +++ b/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() } } diff --git a/XQMuse/Root/Other/View/VideoView.swift b/XQMuse/Root/Other/View/VideoView.swift index 6ad8734..930adee 100644 --- a/XQMuse/Root/Other/View/VideoView.swift +++ b/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") } diff --git a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png index d3377ce..58f4538 100644 --- a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png +++ b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-1.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png index 4ff1233..1b228ff 100644 --- a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png +++ b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-2.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png index 5cfbdec..212d4cd 100644 --- a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png +++ b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-3.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png index 01c4f7a..d83606d 100644 --- a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png +++ b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-4.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png index 6f41051..8595004 100644 --- a/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png +++ b/XQMuse/Root/TreeGroup/Pngs/apngb-animated-level-5.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png new file mode 100644 index 0000000..1af4266 --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-1.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png new file mode 100644 index 0000000..6b7639e --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-10.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png new file mode 100644 index 0000000..1ca093d --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-2.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png new file mode 100644 index 0000000..25751b1 --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-3.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png new file mode 100644 index 0000000..ce78a1c --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-4.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png new file mode 100644 index 0000000..4fe4fd2 --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-5.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png new file mode 100644 index 0000000..885136d --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-6.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png new file mode 100644 index 0000000..d7f5db3 --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-7.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png new file mode 100644 index 0000000..b3ff39e --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-8.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png new file mode 100644 index 0000000..ce2a9a1 --- /dev/null +++ b/XQMuse/Root/TreeGroup/Pngs/droop/static-level-9.png Binary files differ diff --git a/XQMuse/Root/TreeGroup/TreeTeskVC.swift b/XQMuse/Root/TreeGroup/TreeTeskVC.swift index 469f18e..45d3a6b 100644 --- a/XQMuse/Root/TreeGroup/TreeTeskVC.swift +++ b/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) + } } } } diff --git a/XQMuse/SceneDelegate.swift b/XQMuse/SceneDelegate.swift index a73d4e8..441054d 100644 --- a/XQMuse/SceneDelegate.swift +++ b/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) -- Gitblit v1.7.1