From e821bea13d9f20905bba3972c4e9c4964994db5d Mon Sep 17 00:00:00 2001 From: 杨锴 <841720330@qq.com> Date: 星期四, 24 十月 2024 21:04:22 +0800 Subject: [PATCH] fix API TEST --- XQMuse/Root/Course/VC/CourseDetialVC.swift | 73 + XQMuse/Root/Home/VC/CommentListVC.swift | 19 XQMuse/Root/Me/VC/BindPhone_2_VC.swift | 2 XQMuse/Config/StoreKit/InPurchaseManager.swift | 305 ++++++++ XQMuse/Root/Login/VC/ForgotPasswordInputCodeVC.swift | 2 Pods/Pods.xcodeproj/project.pbxproj | 12 XQMuse/Root/Course/CourseVC.swift | 2 XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/组 20@3x.png | 0 XQMuse/Base/BaseNav.swift | 2 XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.xib | 35 XQMuse.xcodeproj/project.pbxproj | 48 + XQMuse/Root/Home/View/PaymentOrderResultTopView.swift | 8 XQMuse/Root/Login/VC/RegisterVC.swift | 4 XQMuse/XQMuse.entitlements | 4 XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.swift | 3 XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.swift | 23 XQMuse/Config/StoreKit/XQMuseStoreKit.storekit | 247 +++++++ XQMuse/Root/Home/VC/HomeItemDetailVC.swift | 48 XQMuse/Root/Network/NetworkRequest.swift | 27 XQMuse/SceneDelegate.swift | 47 + XQMuse/Root/Me/VC/AddBankInfoVC.swift | 2 XQMuse/Root/Login/LoginVC.swift | 9 XQMuse/Root/Plans/PlanGuideVC.swift | 27 XQMuse/Root/Home/HomeVC.swift | 27 XQMuse/Config/WeChatTools.swift | 205 ++++++ XQMuse/Root/Home/VC/SearchVC.xib | 10 XQMuse/Root/Login/LoginVC.xib | 27 XQMuse/Root/Course/VC/CourseDetialVideoVC.swift | 1 XQMuse/Root/Network/Services.swift | 37 XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.swift | 2 XQMuse/Root/Home/TCell/Home_Style_2_TCell.swift | 3 XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.xib | 5 XQMuse/Root/ViewModel/RefreshModel.swift | 2 XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.xib | 11 XQMuse/Root/Pavilion/VC/PavilionDetailVC.xib | 8 XQMuse/Root/Login/VC/UpdatePhoneVC.swift | 2 XQMuse/Root/Home/VC/PaymentOrderVC.swift | 24 XQMuse/Config/Def.swift | 133 +- XQMuse/Root/Home/VC/SearchContentVC.swift | 104 ++ XQMuse/Root/Home/VC/SearchVC.swift | 46 + XQMuse/Root/Network/Models.swift | 5 XQMuse/Root/Home/TCell/Home_Style_2_TCell.xib | 7 XQMuse/Root/Plans/PlanGuide_3_VC.swift | 2 XQMuse/Root/Course/CCell/CourseOfficalCommendTopCCell.swift | 6 XQMuse/AppDelegate.swift | 41 + XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/组 20@2x.png | 0 XQMuse/Root/Me/MeVC.xib | 8 XQMuse/Config/XQMuse-Bridging-Header.h | 12 XQMuse/Root/Home/VC/PaymentOrderResultVC.swift | 13 XQMuse/Config/Layouts/HoverHeaderFlowLayout.swift | 99 ++ XQMuse/Root/Pavilion/VC/PavilionSearchVC.swift | 2 /dev/null | 136 ---- XQMuse/Root/Plans/PlanGuide_2_VC.swift | 2 XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift | 5 XQMuse/Root/Home/VC/HomeItemDetailVC.xib | 9 XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/Contents.json | 22 XQMuse/Info.plist | 21 XQMuse/Root/Other/View/CommonBannerView.swift | 1 58 files changed, 1,570 insertions(+), 417 deletions(-) diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 2735751..87df656 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -13214,7 +13214,7 @@ GCC_PREFIX_HEADER = "Target Support Files/ObjectMapper/ObjectMapper-prefix.pch"; INFOPLIST_FILE = "Target Support Files/ObjectMapper/ObjectMapper-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -14164,7 +14164,7 @@ GCC_PREFIX_HEADER = "Target Support Files/ObjectMapper/ObjectMapper-prefix.pch"; INFOPLIST_FILE = "Target Support Files/ObjectMapper/ObjectMapper-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -14761,7 +14761,7 @@ DEVELOPMENT_TEAM = 5ZV937VB25; IBSC_MODULE = ObjectMapper; INFOPLIST_FILE = "Target Support Files/ObjectMapper/ResourceBundle-Privacy-ObjectMapper-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = Privacy; SDKROOT = iphoneos; @@ -15103,7 +15103,7 @@ DEVELOPMENT_TEAM = 5ZV937VB25; IBSC_MODULE = ObjectMapper; INFOPLIST_FILE = "Target Support Files/ObjectMapper/ResourceBundle-Privacy-ObjectMapper-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = Privacy; SDKROOT = iphoneos; @@ -15269,7 +15269,7 @@ DEVELOPMENT_TEAM = 5ZV937VB25; IBSC_MODULE = SnapKit; INFOPLIST_FILE = "Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = SnapKit_Privacy; SDKROOT = iphoneos; @@ -15506,7 +15506,7 @@ DEVELOPMENT_TEAM = 5ZV937VB25; IBSC_MODULE = SnapKit; INFOPLIST_FILE = "Target Support Files/SnapKit/ResourceBundle-SnapKit_Privacy-SnapKit-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = SnapKit_Privacy; SDKROOT = iphoneos; diff --git a/XQMuse.xcodeproj/project.pbxproj b/XQMuse.xcodeproj/project.pbxproj index 4af8913..f1523eb 100644 --- a/XQMuse.xcodeproj/project.pbxproj +++ b/XQMuse.xcodeproj/project.pbxproj @@ -60,6 +60,7 @@ 1327C6822C81D107005DA44B /* PlanGuide_3_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1327C6802C81D107005DA44B /* PlanGuide_3_VC.swift */; }; 1327C6832C81D107005DA44B /* PlanGuide_3_VC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1327C6812C81D107005DA44B /* PlanGuide_3_VC.xib */; }; 132C40292C816003002E3270 /* SourceHanSerifCN-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 132C40282C816002002E3270 /* SourceHanSerifCN-Medium.otf */; }; + 132C4B782CC0E63D00EA56AF /* WeChatTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132C4B772CC0E63D00EA56AF /* WeChatTools.swift */; }; 132C7EF12C8FE3B900A4CA18 /* ChooseOptTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 132C7EF02C8FE3B900A4CA18 /* ChooseOptTitleView.swift */; }; 132C7EF32C8FE3BF00A4CA18 /* ChooseOptTitleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 132C7EF22C8FE3BF00A4CA18 /* ChooseOptTitleView.xib */; }; 132C7EF72C8FE9BB00A4CA18 /* ChooseOptTitleTCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 132C7EF62C8FE9BB00A4CA18 /* ChooseOptTitleTCell.xib */; }; @@ -361,6 +362,8 @@ 1327C6802C81D107005DA44B /* PlanGuide_3_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanGuide_3_VC.swift; sourceTree = "<group>"; }; 1327C6812C81D107005DA44B /* PlanGuide_3_VC.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PlanGuide_3_VC.xib; sourceTree = "<group>"; }; 132C40282C816002002E3270 /* SourceHanSerifCN-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceHanSerifCN-Medium.otf"; sourceTree = "<group>"; }; + 132C4B762CC0E5CA00EA56AF /* XQMuse-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XQMuse-Bridging-Header.h"; sourceTree = "<group>"; }; + 132C4B772CC0E63D00EA56AF /* WeChatTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeChatTools.swift; sourceTree = "<group>"; }; 132C7EF02C8FE3B900A4CA18 /* ChooseOptTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseOptTitleView.swift; sourceTree = "<group>"; }; 132C7EF22C8FE3BF00A4CA18 /* ChooseOptTitleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ChooseOptTitleView.xib; sourceTree = "<group>"; }; 132C7EF52C8FE9BB00A4CA18 /* ChooseOptTitleTCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseOptTitleTCell.swift; sourceTree = "<group>"; }; @@ -714,6 +717,26 @@ path = VC; sourceTree = "<group>"; }; + 132C4B792CC0EBDD00EA56AF /* Layouts */ = { + isa = PBXGroup; + children = ( + 139C165F2C6A0FBB00A924D9 /* TestLeftRightCollectionViewFlowLayout.swift */, + 1336EFA42C6DEB550075E070 /* HoverHeaderFlowLayout.swift */, + 13897D882C7DB9D7006209E0 /* EqualCellSpaceFlowLayout.swift */, + ); + path = Layouts; + sourceTree = "<group>"; + }; + 132C4B7A2CC0EBFA00EA56AF /* StoreKit */ = { + isa = PBXGroup; + children = ( + 1304526E2CB4FF280049FB3A /* InPurchaseManager.swift */, + 130452692CB4CA310049FB3A /* XQMuseStoreKit.storekit */, + 1304526B2CB4CB210049FB3A /* StoreKitTestCertificate.cer */, + ); + path = StoreKit; + sourceTree = "<group>"; + }; 132C7EF42C8FE9A800A4CA18 /* TCell */ = { isa = PBXGroup; children = ( @@ -1058,18 +1081,16 @@ 13985DB32C69B7D40046B6DC /* Config */ = { isa = PBXGroup; children = ( + 132C4B7A2CC0EBFA00EA56AF /* StoreKit */, + 132C4B792CC0EBDD00EA56AF /* Layouts */, + 132C4B772CC0E63D00EA56AF /* WeChatTools.swift */, 13D2A0542CB671D9005F6014 /* SDK */, - 1304526E2CB4FF280049FB3A /* InPurchaseManager.swift */, - 130452692CB4CA310049FB3A /* XQMuseStoreKit.storekit */, - 1304526B2CB4CB210049FB3A /* StoreKitTestCertificate.cer */, 13A0A8A02C746ADA00DF08B6 /* Enums */, - 139C165F2C6A0FBB00A924D9 /* TestLeftRightCollectionViewFlowLayout.swift */, - 1336EFA42C6DEB550075E070 /* HoverHeaderFlowLayout.swift */, 137175C42C6C3C2100B38EF1 /* Fonts */, 13985DB42C69B7DF0046B6DC /* Def.swift */, 13985DB72C69B80D0046B6DC /* Themes.swift */, - 13897D882C7DB9D7006209E0 /* EqualCellSpaceFlowLayout.swift */, 135B1D1F2C8863D10089A9BE /* Types.swift */, + 132C4B762CC0E5CA00EA56AF /* XQMuse-Bridging-Header.h */, ); path = Config; sourceTree = "<group>"; @@ -1717,6 +1738,7 @@ 130913EF2C6DE67E00418201 /* HomeRelaxBanner_2_1_CCell.swift in Sources */, 1333DC7A2C72D8C400D8ACAE /* CourseDetail_3_TCell.swift in Sources */, 135C2A752C7F033300CC2A67 /* CLPlayerView.swift in Sources */, + 132C4B782CC0E63D00EA56AF /* WeChatTools.swift in Sources */, 1300BD3C2C6DFB1C000BCA5E /* VIPCenterVC.swift in Sources */, 134803D62C76E3E000F4FDDA /* WatchHistoryVC.swift in Sources */, 13D2A0492CB670BF005F6014 /* OBSUploader.swift in Sources */, @@ -1890,8 +1912,6 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/XQMuse/Config/SDK\\ 2", - "$(PROJECT_DIR)/XQMuse/Config/SDK\\ 2", "$(PROJECT_DIR)/XQMuse/Config/SDK", ); GENERATE_INFOPLIST_FILE = YES; @@ -1914,7 +1934,8 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-l\"WechatOpenSDK\"", + "-ObjC", + "-\"WechatOpenSDK\"", "-l\"c++\"", "-l\"resolv\"", "-l\"sqlite3.0\"", @@ -2014,6 +2035,7 @@ "\"XCGLogger\"", "-force_load", "$(SRCROOT)/XQMuse/Config/SDK/OBS.framework/OBS", + "\"-ld64\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2023,6 +2045,7 @@ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "/Users/yvkd/XiLaida/XQMuse/XQMuse/Config/XQMuse-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; @@ -2043,8 +2066,6 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/XQMuse/Config/SDK\\ 2", - "$(PROJECT_DIR)/XQMuse/Config/SDK\\ 2", "$(PROJECT_DIR)/XQMuse/Config/SDK", ); GENERATE_INFOPLIST_FILE = YES; @@ -2067,7 +2088,8 @@ MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", - "-l\"WechatOpenSDK\"", + "-ObjC", + "-\"WechatOpenSDK\"", "-l\"c++\"", "-l\"resolv\"", "-l\"sqlite3.0\"", @@ -2167,6 +2189,7 @@ "\"XCGLogger\"", "-force_load", "$(SRCROOT)/XQMuse/Config/SDK/OBS.framework/OBS", + "\"-ld64\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.sinata.XQMuse.test; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2176,6 +2199,7 @@ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "/Users/yvkd/XiLaida/XQMuse/XQMuse/Config/XQMuse-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; diff --git a/XQMuse/AppDelegate.swift b/XQMuse/AppDelegate.swift index 513a285..3aa82dc 100644 --- a/XQMuse/AppDelegate.swift +++ b/XQMuse/AppDelegate.swift @@ -9,19 +9,47 @@ @main -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate,WXApiDelegate{ var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - + WeChatTools.register(appid: WeChatAPPID, link: "https://app.xqzhihui.com/app/") return true } func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .allButUpsideDown } + + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool { + return WXApi.handleOpenUniversalLink(userActivity, delegate: self) + } + + func application(_ application: UIApplication, handleOpen url: URL) -> Bool { + + if url.scheme == WeChatAPPID{ + return WXApi.handleOpen(url, delegate: self) + } + return true + } + + func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { + if url.scheme == WeChatAPPID{ + return WXApi.handleOpen(url, delegate: self) + } + return true + } + + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + + if url.scheme == WeChatAPPID{ + return WXApi.handleOpen(url, delegate: self) + } + return true + } + // MARK: UISceneSession Lifecycle @@ -37,6 +65,15 @@ // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } + func onReq(_ req: BaseReq) { + + } + + func onResp(_ resp: BaseResp) { + + } + } + diff --git a/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@2x.png b/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@2x.png deleted file mode 100644 index 360ded4..0000000 --- a/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@2x.png +++ /dev/null Binary files differ diff --git a/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@3x.png b/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@3x.png deleted file mode 100644 index b12715f..0000000 --- a/XQMuse/Assets.xcassets/Btns/btn_share_1.imageset/btn_share@3x.png +++ /dev/null Binary files differ diff --git a/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/Contents.json b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/Contents.json new file mode 100644 index 0000000..2ba0785 --- /dev/null +++ b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "组 20@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "组 20@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@2x.png" "b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@2x.png" new file mode 100644 index 0000000..eac36e3 --- /dev/null +++ "b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@2x.png" Binary files differ diff --git "a/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@3x.png" "b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@3x.png" new file mode 100644 index 0000000..f2f4c2b --- /dev/null +++ "b/XQMuse/Assets.xcassets/Placeholder/bg_guide_home.imageset/\347\273\204 20@3x.png" Binary files differ diff --git a/XQMuse/Base/BaseNav.swift b/XQMuse/Base/BaseNav.swift index dbe40a8..c2846ae 100644 --- a/XQMuse/Base/BaseNav.swift +++ b/XQMuse/Base/BaseNav.swift @@ -12,7 +12,7 @@ /// 需要透明Nav的VC private var lucencyVCs = [LoginVC.self] - private var whiteStyleVCs = [HomeItemDetailVC.self,CourseDetialVC.self,HomeItemDetailVC.self,CourseDetialVideoVC.self,PavilionDetailVC.self] + private var whiteStyleVCs = [HomeItemDetailVC.self,CourseDetialVC.self,CourseDetialVideoVC.self,PavilionDetailVC.self] open override func viewDidLoad() { super.viewDidLoad() diff --git a/XQMuse/Config/Def.swift b/XQMuse/Config/Def.swift index 5f08538..c6b580b 100644 --- a/XQMuse/Config/Def.swift +++ b/XQMuse/Config/Def.swift @@ -12,7 +12,8 @@ import QMUIKit import OSLog -//https://dummyimage.com/100x100 +let WeChatAPPID = "wx4b9c1d814c2902a3" +let WeChatSecrect = "60fed4b6f52603ba6769e1118b4a57ae" let app = UIApplication.shared.delegate as! AppDelegate @@ -20,110 +21,110 @@ let ShareAppleKey = "" var sceneDelegate:SceneDelegate? = { - var uiScreen:UIScene? - UIApplication.shared.connectedScenes.forEach { scenes in - uiScreen = scenes - } - return (uiScreen?.delegate as? SceneDelegate) + var uiScreen:UIScene? + UIApplication.shared.connectedScenes.forEach { scenes in + uiScreen = scenes + } + return (uiScreen?.delegate as? SceneDelegate) }() func LogSuccess(_ items:Any...,separator:String=" ",file:String=#file,function:String=#function,line:Int=#line){ #if DEBUG - if #available(iOS 14.0, *) { - let logger = Logger(subsystem: "WanPai", category: function) - logger.error("\(items)") - }else{ - let file = (file as NSString).lastPathComponent.split(separator: ".").first!; - print("✅✅✅ SUCCESS: \(file) \(function) [Line: \(line)]: \(items)",separator); - } + if #available(iOS 14.0, *) { + let logger = Logger(subsystem: "WanPai", category: function) + logger.error("\(items)") + }else{ + let file = (file as NSString).lastPathComponent.split(separator: ".").first!; + print("✅✅✅ SUCCESS: \(file) \(function) [Line: \(line)]: \(items)",separator); + } #endif } func LogError(_ items:Any...,separator:String=" ",file:String=#file,function:String=#function,line:Int=#line){ #if DEBUG - if #available(iOS 14.0, *) { - let logger = Logger(subsystem: "WanPai", category: function) - logger.error("\(items)") - }else{ - let file = (file as NSString).lastPathComponent.split(separator: ".").first!; - print("❌❌❌ ERROR: \(file) \(function) [Line: \(line)]: \(items)",separator); - } + if #available(iOS 14.0, *) { + let logger = Logger(subsystem: "WanPai", category: function) + logger.error("\(items)") + }else{ + let file = (file as NSString).lastPathComponent.split(separator: ".").first!; + print("❌❌❌ ERROR: \(file) \(function) [Line: \(line)]: \(items)",separator); + } #endif } func LogInfo(_ items:Any...,separator:String=" ",file:String=#file,function:String=#function,line:Int=#line){ #if DEBUG - if #available(iOS 14.0, *) { - let logger = Logger(subsystem: "WanPai", category: function) - logger.error("\(items)") - }else{ - let file = (file as NSString).lastPathComponent.split(separator: ".").first!; - print("⚠️⚠️⚠️INFO: \(file) \(function) [Line: \(line)]: \(items)",separator); - } + if #available(iOS 14.0, *) { + let logger = Logger(subsystem: "WanPai", category: function) + logger.error("\(items)") + }else{ + let file = (file as NSString).lastPathComponent.split(separator: ".").first!; + print("⚠️⚠️⚠️INFO: \(file) \(function) [Line: \(line)]: \(items)",separator); + } #endif } func LogResponse(_ items:Any...,separator:String=" ",file:String=#file,function:String=#function,line:Int=#line){ #if DEBUG - print("返回数据") - print(items); + print("返回数据") + print(items); #endif } //提示框 func alert(msg: String) { - SVProgressHUD.showInfo(withStatus: msg) + SVProgressHUD.showInfo(withStatus: msg) } func alertError(msg:String){ - SVProgressHUD.showError(withStatus: msg) + SVProgressHUD.showError(withStatus: msg) } func alertSuccess(msg:String){ - SVProgressHUD.showSuccess(withStatus: msg) + SVProgressHUD.showSuccess(withStatus: msg) } func showHUD(_ text:String? = nil){ - SVProgressHUD.show(withStatus: text) + SVProgressHUD.show(withStatus: text) } func hiddenHUD(_ delay:TimeInterval? = nil){ - if delay != nil{ - SVProgressHUD.dismiss(withDelay: delay!) - }else{ - SVProgressHUD.dismiss() - } + if delay != nil{ + SVProgressHUD.dismiss(withDelay: delay!) + }else{ + SVProgressHUD.dismiss() + } } extension UIButton { - func localGradientColor(cornerRadius:Double,bounds:CGRect? = nil){ - self.layer.sublayers?.removeAll(where: {$0 is CAGradientLayer}) - self.jq_gradientColor(colorArr: [UIColor(hexStr: "#8EA47A").cgColor,UIColor(hexStr: "#AFCA98").cgColor], cornerRadius: cornerRadius, startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 1), bounds: bounds) - } + func localGradientColor(cornerRadius:Double,bounds:CGRect? = nil){ + self.layer.sublayers?.removeAll(where: {$0 is CAGradientLayer}) + self.jq_gradientColor(colorArr: [UIColor(hexStr: "#8EA47A").cgColor,UIColor(hexStr: "#AFCA98").cgColor], cornerRadius: cornerRadius, startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0, y: 1), bounds: bounds) + } - public func openCountDown(_ t:Int = 59,defultTitle:String = "获取验证码"){ - var time = t //倒计时时间 - let queue = DispatchQueue.global() - let timer = DispatchSource.makeTimerSource(flags: [], queue: queue) - timer.schedule(wallDeadline: DispatchWallTime.now(), repeating: .seconds(1)); - timer.setEventHandler(handler: { - if time <= 0 { - timer.cancel() - DispatchQueue.main.async(execute: { - self.setTitle(defultTitle, for: .normal) - self.setTitleColor(UIColor(hexStr: "#63BDDB"), for: .normal) - self.isUserInteractionEnabled = true - }); - }else { - DispatchQueue.main.async(execute: { - self.setTitle("\(time)s", for: .normal) - self.setTitleColor(UIColor.gray, for: .normal) - self.isUserInteractionEnabled = false - }); - } - time -= 1 - }); - timer.resume() - } + public func openCountDown(_ t:Int = 59,defultTitle:String = "获取验证码"){ + var time = t //倒计时时间 + let queue = DispatchQueue.global() + let timer = DispatchSource.makeTimerSource(flags: [], queue: queue) + timer.schedule(wallDeadline: DispatchWallTime.now(), repeating: .seconds(1)); + timer.setEventHandler(handler: { + if time <= 0 { + timer.cancel() + DispatchQueue.main.async(execute: { + self.setTitle(defultTitle, for: .normal) + self.setTitleColor(UIColor(hexStr: "#63BDDB"), for: .normal) + self.isUserInteractionEnabled = true + }); + }else { + DispatchQueue.main.async(execute: { + self.setTitle("\(time)s", for: .normal) + self.setTitleColor(UIColor.gray, for: .normal) + self.isUserInteractionEnabled = false + }); + } + time -= 1 + }); + timer.resume() + } } diff --git a/XQMuse/Config/EqualCellSpaceFlowLayout.swift b/XQMuse/Config/EqualCellSpaceFlowLayout.swift deleted file mode 100644 index c23442b..0000000 --- a/XQMuse/Config/EqualCellSpaceFlowLayout.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// EqualCellSpaceFlowLayout.swift -// XQMuse -// -// Created by 无故事王国 on 2024/8/27. -// - -import UIKit -enum AlignType : NSInteger { - case left = 0 - case center = 1 - case right = 2 -} - - -class EqualCellSpaceFlowLayout: UICollectionViewFlowLayout { - //两个Cell之间的距离 - private var horizontalSpace : CGFloat{ - didSet{ - self.minimumInteritemSpacing = horizontalSpace - } - } - //cell对齐方式 - private var alignType : AlignType = AlignType.center - //在居中对齐的时候需要知道这行所有cell的宽度总和 - var cellWidthInLine : CGFloat = 0.0 - - override init() { - horizontalSpace = 5.0 - super.init() - scrollDirection = UICollectionView.ScrollDirection.vertical - minimumLineSpacing = 5 - sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) - } - convenience init(_ cellType:AlignType){ - self.init() - self.alignType = cellType - } - convenience init(_ cellType: AlignType, _ horizontalSpace: CGFloat){ - self.init() - self.alignType = cellType - self.horizontalSpace = horizontalSpace - } - - required init?(coder aDecoder: NSCoder) { - horizontalSpace = 5.0 - super.init(coder: aDecoder) - scrollDirection = UICollectionView.ScrollDirection.vertical - minimumLineSpacing = 5 - sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) - } - - override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { - - let layoutAttributes_super : [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: rect) ?? [UICollectionViewLayoutAttributes]() - let layoutAttributes:[UICollectionViewLayoutAttributes] = NSArray(array: layoutAttributes_super, copyItems:true)as! [UICollectionViewLayoutAttributes] - var layoutAttributes_t : [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]() - for index in 0..<layoutAttributes.count{ - - print("index in 0..<layoutAttributes.count ==============") - - let currentAttr = layoutAttributes[index] - let previousAttr = index == 0 ? nil : layoutAttributes[index-1] - let nextAttr = index + 1 == layoutAttributes.count ? - nil : layoutAttributes[index+1] - - layoutAttributes_t.append(currentAttr) - cellWidthInLine += currentAttr.frame.size.width - - let previousY :CGFloat = previousAttr == nil ? 0 : previousAttr!.frame.maxY - let currentY :CGFloat = currentAttr.frame.maxY - let nextY:CGFloat = nextAttr == nil ? 0 : nextAttr!.frame.maxY - - if currentY != previousY && currentY != nextY{ - if currentAttr.representedElementKind == UICollectionView.elementKindSectionHeader{ - layoutAttributes_t.removeAll() - cellWidthInLine = 0.0 - print("currentAttr.representedElementKind == UICollectionView.elementKindSectionHeader =========== Header") - }else if currentAttr.representedElementKind == UICollectionView.elementKindSectionFooter{ - layoutAttributes_t.removeAll() - cellWidthInLine = 0.0 - print("currentAttr.representedElementKind == UICollectionView.elementKindSectionFooter ============ Footer") - }else{ - self.setCellFrame(with: layoutAttributes_t) - layoutAttributes_t.removeAll() - cellWidthInLine = 0.0 - print("currentY != previousY && currentY != nextY ============== Item") - } - } else if currentY != nextY { //这里currentY == previousY 说明和上一个项目在同一行,currentY != nextY说明下一个项目要换行了,这种情况直接计算本行的对齐方式 - self.setCellFrame(with: layoutAttributes_t) - layoutAttributes_t.removeAll() - cellWidthInLine = 0.0 - print("currentY != nextY ======== Else") - } - } - return layoutAttributes - } - - /// 调整Cell的Frame - /// - /// - Parameter layoutAttributes: layoutAttribute 数组 - func setCellFrame(with layoutAttributes : [UICollectionViewLayoutAttributes]){ - var nowWidth : CGFloat = 0.0 - switch alignType { - case AlignType.left: - nowWidth = self.sectionInset.left - for attributes in layoutAttributes { - var nowFrame = attributes.frame - nowFrame.origin.x = nowWidth - attributes.frame = nowFrame - nowWidth += nowFrame.size.width + self.horizontalSpace - } - break; - case AlignType.center: - nowWidth = (self.collectionView!.frame.size.width - cellWidthInLine - (CGFloat(layoutAttributes.count - 1) * horizontalSpace)) / 2 - for attributes in layoutAttributes{ - var nowFrame = attributes.frame - nowFrame.origin.x = nowWidth - attributes.frame = nowFrame - nowWidth += nowFrame.size.width + self.horizontalSpace - } - break; - case AlignType.right: - nowWidth = self.collectionView!.frame.size.width - self.sectionInset.right - for var index in 0 ..< layoutAttributes.count{ - index = layoutAttributes.count - 1 - index - let attributes = layoutAttributes[index] - var nowFrame = attributes.frame - nowFrame.origin.x = nowWidth - nowFrame.size.width - attributes.frame = nowFrame - nowWidth = nowWidth - nowFrame.size.width - horizontalSpace - } - break; - } - } -} diff --git a/XQMuse/Config/Layouts/HoverHeaderFlowLayout.swift b/XQMuse/Config/Layouts/HoverHeaderFlowLayout.swift new file mode 100644 index 0000000..86843a1 --- /dev/null +++ b/XQMuse/Config/Layouts/HoverHeaderFlowLayout.swift @@ -0,0 +1,99 @@ +// +// HoverHeaderFlowLayout.swift +// XQMuse +// +// Created by 无故事王国 on 2024/8/15. +// + +import Foundation +import UIKit +import JQTools + +/// 悬浮HeaderView +class HoverHeaderFlowLayout:UICollectionViewFlowLayout{ + var naviHeight:CGFloat = JQ_NavBarHeight//默认分组停放高度 + override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { + //UICollectionViewLayoutAttributes:我称它为collectionView中的item(包括cell和header、footer这些)的结构信息 + //截取到父类所返回的数组(里面放的是当前屏幕所能展示的item的结构信息),并转化成不可变数组 + var superArray = super.layoutAttributesForElements(in: rect) + //创建存索引的数组,无符号(正整数),无序(不能通过下标取值),不可重复(重复的话会自动过滤) + let noneHeaderSections=NSMutableIndexSet(); + for attributes:UICollectionViewLayoutAttributes in superArray! { + //如果当前的元素分类是一个cell,将cell所在的分区section加入数组,重复的话会自动过滤 + if attributes.representedElementCategory == .cell{ + noneHeaderSections.add(attributes.indexPath.section) + } + } + //遍历superArray,将当前屏幕中拥有的header的section从数组中移除,得到一个当前屏幕中没有header的section数组 + //正常情况下,随着手指往上移,header脱离屏幕会被系统回收而cell尚在,也会触发该方法 + for attributes:UICollectionViewLayoutAttributes in superArray! { + //如果当前的元素是一个header,将header所在的section从数组中移除 + if attributes.representedElementKind == UICollectionView.elementKindSectionHeader { + noneHeaderSections.remove(attributes.indexPath.section) + } + } + //遍历当前屏幕中没有header的section数组 + noneHeaderSections .enumerate({ (idx, obj) -> Void in + //取到当前section中第一个item的indexPath + let indexPath = NSIndexPath(item: 0, section: idx) + let attributes=self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: indexPath as IndexPath) + //如果当前分区确实有因为离开屏幕而被系统回收的header + if attributes != nil { + //将该header结构信息重新加入到superArray中去 + superArray?.append(attributes!) + } + }) + //遍历superArray,改变header结构信息中的参数,使它可以在当前section还没完全离开屏幕的时候一直显示 + for attributes:UICollectionViewLayoutAttributes in superArray! { + //如果当前item是header + if attributes.representedElementKind == UICollectionView.elementKindSectionHeader { + //得到当前header所在分区的cell的数量 + let numberOfItemsInSection=self.collectionView!.numberOfItems(inSection: attributes.indexPath.section) + //取到当前section中第一个item的indexPath + let firstItemIndexPath = NSIndexPath(item: 0, section: attributes.indexPath.section) + //得到最后一个item的indexPath + let lastItemIndexPath = NSIndexPath(item: max(0, numberOfItemsInSection-1), section: attributes.indexPath.section) + //得到第一个item和最后一个item的结构信息 + var firstItemAttributes, lastItemAttributes:UICollectionViewLayoutAttributes + if numberOfItemsInSection>0 { + //cell有值,则获取第一个cell和最后一个cell的结构信息 + firstItemAttributes=self.layoutAttributesForItem(at: firstItemIndexPath as IndexPath)! + lastItemAttributes=self.layoutAttributesForItem(at: lastItemIndexPath as IndexPath)! + }else{ + //cell没值,就新建一个UICollectionViewLayoutAttributes + firstItemAttributes=UICollectionViewLayoutAttributes() + //然后模拟出在当前分区中的唯一一个cell,cell在header的下面,高度为0,还与header隔着可能存在的sectionInset的top + let y=attributes.frame.maxY + sectionInset.top + firstItemAttributes.frame=CGRect(x: 0, y: y, width: 0, height: 0) + //因为只有一个cell,所以最后一个cell等于第一个cell + lastItemAttributes=firstItemAttributes; + } + //获取当前header的frame + var rect=attributes.frame; + //当前的滑动距离 + 因为导航栏产生的偏移量,默认为0(如果app需求不同,需自己设置) + let offset=(self.collectionView?.contentOffset.y)! + naviHeight + //第一个cell的y值 - 当前header的高度 - 可能存在的sectionInset的top + let headerY=firstItemAttributes.frame.origin.y-rect.size.height-sectionInset.top + //哪个大取哪个,保证header悬停 + //针对当前header基本上都是offset更加大,针对下一个header则会是headerY大,各自处理 + let maxY=max(offset, headerY) + //最后一个cell的y值 + 最后一个cell的高度 + 可能存在的sectionInset的bottom - 当前header的高度 + //当当前section的footer或者下一个section的header接触到当前header的底部,计算出的headerMissingY即为有效值 + let headerMissingY = lastItemAttributes.frame.maxY + sectionInset.bottom - rect.size.height; + //给rect的y赋新值,因为在最后消失的临界点要跟谁消失,所以取小 + rect.origin.y=min(maxY, headerMissingY) + //给header的结构信息的frame重新赋值 + attributes.frame=rect + //如果按照正常情况下,header离开屏幕被系统回收,而header的层次关系又与cell相等,如果不去理会,会出现cell在header上面的情况 + //通过打印可以知道cell的层次关系zIndex数值为0,我们可以将header的zIndex设置成1,如果不放心,也可以将它设置成非常大,这里随便填了个7 + attributes.zIndex=7 + + } + } + return superArray + } + //return true;表示一旦滑动就实时调用上面这个layoutAttributesForElementsInRect:方法 + override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { + return true + } +} diff --git a/XQMuse/Config/StoreKit/InPurchaseManager.swift b/XQMuse/Config/StoreKit/InPurchaseManager.swift new file mode 100644 index 0000000..84e42e8 --- /dev/null +++ b/XQMuse/Config/StoreKit/InPurchaseManager.swift @@ -0,0 +1,305 @@ +// +// StoreTransaction.swift +// ExplorerProject +// +// Created by 无故事王国 on 2024/4/1. +// Copyright © 2024 younger_times. All rights reserved. +// + +import SwiftyStoreKit +import StoreKit +import HandyJSON + +struct PurchaseModel:HandyJSON{ + var environment: String? + var receipt:PurchaseReceiptModel? + var status: Int = 0 +} + +struct PurchaseReceiptModel:HandyJSON{ + var adam_id: Int = 0 + var app_item_id: Int = 0 + var application_version: Int = 0 + var bundle_id: String? + var download_id: Int = 0 + var in_app = [PurchageInAppModel]() + var original_application_version: String? + var original_purchase_date: String? + var original_purchase_date_ms: Int = 0 + var original_purchase_date_pst: String? + var receipt_creation_date: String? + var receipt_creation_date_ms: Int = 0 + var receipt_creation_date_pst: String? + var receipt_type: String? + var request_date: String? + var request_date_ms: Int = 0 + var request_date_pst: String? + var version_external_identifier: Int = 0 +} + +struct PurchageInAppModel:HandyJSON{ + +} + +struct PurchaseResultModel:HandyJSON{ + var environment: String? + var receipt: PurchaseReceipt? + var status: Int = 0 +} + +struct PurchaseReceipt:HandyJSON{ + var adam_id: Int = 0 + var app_item_id: Int = 0 + var application_version: String? + var bundle_id: String? + var download_id: Int = 0 + var in_app = [PurchaseInAPP]() + var original_application_version: String? + var original_purchase_date: String? + var original_purchase_date_ms: String? + var original_purchase_date_pst: String? + var receipt_creation_date: String? + var receipt_creation_date_ms: String? + var receipt_creation_date_pst: String? + var receipt_type: String? + var request_date: String? + var request_date_ms: String? + var request_date_pst: String? + var version_external_identifier: Int = 0 +} + +struct PurchaseInAPP:HandyJSON{ + var in_app_ownership_type: String? + var is_trial_period: String? + var original_purchase_date: String? + var original_purchase_date_ms: String? + var original_purchase_date_pst: String? + var original_transaction_id: String? + var product_id: String? + var purchase_date: String? + var purchase_date_ms: String? + var purchase_date_pst: String? + var quantity: String? + var transaction_id: String? + +} + +class InPurchaseManager:NSObject{ + + private static var _sharedInstance: InPurchaseManager! + private var productList = Set<String>() + private(set) var products = Set<SKProduct>() + + @discardableResult + public class func instance() -> InPurchaseManager { + guard let instance = _sharedInstance else { + _sharedInstance = InPurchaseManager() + return _sharedInstance! + } + return instance + } + + func setProductList(_ list:Set<String>,clouse:@escaping (Set<SKProduct>)->Void){ + productList = list + + SwiftyStoreKit.retrieveProductsInfo(list) { result in + if result.retrievedProducts.count > 0 { + InPurchaseManager._sharedInstance.products = result.retrievedProducts + clouse(result.retrievedProducts) + } + } + } + + func getIPAPrice(_ price:Int,clouse:@escaping (SKProduct)->Void){ + var ipaId = "" + switch price { + case 98: ipaId = "com.jkfitness.a.price.1" + case 298:ipaId = "com.jkfitness.a.price.2" + case 488:ipaId = "com.jkfitness.a.price.3" + case 698:ipaId = "com.jkfitness.a.price.4" + case 998:ipaId = "com.jkfitness.a.price.5" + default:break + } + + var productIds = Set<String>() + productIds.insert(ipaId) + + InPurchaseManager.instance().setProductList(productIds) {products in + if let product = products.first{ + clouse(product) + } + } + } + + + func dismiss(){ + InPurchaseManager._sharedInstance = nil + } + + /// 购买 + /// - Parameters: + /// - ID: ID值 + /// - quantity: 购买数量 + /// - applicationUsername: 购买用户名的唯一标识 + class func purchaseProduct(ID:String,quantity:Int = 1,applicationUsername:String, completion: @escaping ( PurchaseResultModel) -> Void,errorClouse:@escaping (Error)->Void){ + var purcahseProduct:SKProduct? + for product in _sharedInstance.products { + if product.productIdentifier == ID{ + purcahseProduct = product;break + } + } + + guard let product = purcahseProduct else {return} + var inSanbox:Bool = false + +#if DEBUG + inSanbox = true +#endif + + SwiftyStoreKit.completeTransactions { purchases in + if let product = purchases.first{ + switch product.transaction.transactionState { + case .purchased: + alertSuccess(msg: "完成购买") + case .purchasing: + showHUD("购买中") + case .failed: + alertError(msg: "购买失败") + case .restored: + alertSuccess(msg: "恢复购买") + default:break + } + } + } + + SwiftyStoreKit.purchaseProduct(product, quantity: quantity, atomically: true, applicationUsername: applicationUsername, simulatesAskToBuyInSandbox: false, paymentDiscount: nil) { result in + switch result { + case .success(let purchase): + var type:AppleReceiptValidator.VerifyReceiptURLType = .production + if inSanbox{ + type = .sandbox + } + + var recepit = AppleReceiptValidator(service: type, sharedSecret: nil) + SwiftyStoreKit.verifyReceipt(using: recepit) { result in + switch result { + case .success(let receipt): + if let model = PurchaseResultModel.deserialize(from: receipt){ + completion(model) + } + break + case .error(let error): + errorClouse(error) + // print(error.localizedDescription) + } + } + case .error(let error): + // print(error.localizedDescription) + errorClouse(error) + } + } + } + + /// 恢复购买 + class func resotrePurchase(applicationUsername:String, completion: @escaping ( PurchaseResultModel) -> Void,errorClouse:@escaping (Error)->Void){ + + SwiftyStoreKit.completeTransactions { purchases in + if let product = purchases.first{ + switch product.transaction.transactionState { + case .purchased: + alertSuccess(msg: "完成购买") + case .purchasing: + showHUD("购买中") + case .failed: + alertError(msg: "购买失败") + case .restored: + alertSuccess(msg: "恢复购买") + default:break + } + } + } + + + SwiftyStoreKit.restorePurchases(atomically: true, applicationUsername: applicationUsername) { result in + if result.restoreFailedPurchases.count > 0 { + //恢复失败 + print("restore Failed:\(result.restoredPurchases)") + }else if result.restoredPurchases.count > 0 { + print("restore Success") + var inSanbox:Bool = false + +#if DEBUG + inSanbox = true +#endif + var type:AppleReceiptValidator.VerifyReceiptURLType = .production + if inSanbox{ + type = .sandbox + } + let recepit = AppleReceiptValidator(service: type, sharedSecret: nil) + SwiftyStoreKit.verifyReceipt(using: recepit) { result in + switch result { + case .success(let receipt): + if let model = PurchaseResultModel.deserialize(from: receipt){ + completion(model) + } + break + case .error(let error): + errorClouse(error) + } + } + }else{ + print("Nothing to Restore") + } + } + } + + //获取APP 首次安装时间 + func test1(){ + + let queue = DispatchQueue(label: "inapppurchasequeue") + queue.async { + let receiptURL = Bundle.main.appStoreReceiptURL + guard receiptURL?.path != nil else { return } + do { + let receiptData = try Data(contentsOf: receiptURL!, options: .alwaysMapped) + let base64EncodedReceipt = receiptData.base64EncodedString(options: []) + var verifyReceipt:String = AppleReceiptValidator.VerifyReceiptURLType.sandbox.rawValue +#if !DEBUG + verifyReceipt = AppleReceiptValidator.VerifyReceiptURLType.production.rawValue +#endif + let purchaseURL = URL(string: verifyReceipt)! + + var request = URLRequest(url: purchaseURL) + request.httpMethod = "POST" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + let jsonBody: [String: Any] = [ + "receipt-data": base64EncodedReceipt, + "password": ShareAppleKey // 你的共享密钥 + ] + + let jsonData = try JSONSerialization.data(withJSONObject: jsonBody, options: []) + request.httpBody = jsonData + + let session = URLSession.shared + let task = session.dataTask(with: request) { (data, response, error) in + if let error = error {return} + guard let data = data else { return } + do { + if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { + print(json) + if let purchageModel = PurchaseModel.deserialize(from: json),purchageModel.status == 0{ + + } + } + } catch { + print("JSON processing failed: \(error)") + } + } + task.resume() + } catch { + print("Error reading receipt data: \(error)") + } + } + } +} diff --git a/XQMuse/Config/StoreKit/XQMuseStoreKit.storekit b/XQMuse/Config/StoreKit/XQMuseStoreKit.storekit new file mode 100644 index 0000000..1fc0aa3 --- /dev/null +++ b/XQMuse/Config/StoreKit/XQMuseStoreKit.storekit @@ -0,0 +1,247 @@ +{ + "appPolicies" : { + "eula" : "", + "policies" : [ + { + "locale" : "en_US", + "policyText" : "", + "policyURL" : "" + } + ] + }, + "identifier" : "3D29D5F7", + "nonRenewingSubscriptions" : [ + { + "displayPrice" : "299", + "familyShareable" : false, + "internalID" : "7BDE4968", + "localizations" : [ + { + "description" : "购买一个月会员", + "displayName" : "一个月会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.VIP.month.0", + "referenceName" : "购买一个月会员", + "type" : "NonRenewingSubscription" + }, + { + "displayPrice" : "499", + "familyShareable" : false, + "internalID" : "DDDE321B", + "localizations" : [ + { + "description" : "购买6个月会员", + "displayName" : "半年会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.VIP.semester.0", + "referenceName" : "购买半年会员", + "type" : "NonRenewingSubscription" + }, + { + "displayPrice" : "499", + "familyShareable" : false, + "internalID" : "436E2DBE", + "localizations" : [ + { + "description" : "购买12个月会员", + "displayName" : "年度会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.VIP.year.0", + "referenceName" : "购买年度会员", + "type" : "NonRenewingSubscription" + } + ], + "products" : [ + { + "displayPrice" : "0.99", + "familyShareable" : false, + "internalID" : "521CE106", + "localizations" : [ + { + "description" : "购买10颗疗愈币", + "displayName" : "10币", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.p.0", + "referenceName" : "充值10疗愈币", + "type" : "Consumable" + }, + { + "displayPrice" : "1.99", + "familyShareable" : false, + "internalID" : "E7DC523B", + "localizations" : [ + { + "description" : "购买20颗疗愈币", + "displayName" : "20币", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.p.1", + "referenceName" : "充值20疗愈币", + "type" : "Consumable" + }, + { + "displayPrice" : "2.99", + "familyShareable" : false, + "internalID" : "6AD670BC", + "localizations" : [ + { + "description" : "购买50颗疗愈币", + "displayName" : "50币", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.p.2", + "referenceName" : "充值50疗愈币", + "type" : "Consumable" + }, + { + "displayPrice" : "3.99", + "familyShareable" : false, + "internalID" : "C8E195D0", + "localizations" : [ + { + "description" : "购买100颗疗愈币", + "displayName" : "100币", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.p.3", + "referenceName" : "充值100疗愈币", + "type" : "Consumable" + } + ], + "settings" : { + "_billingGracePeriodEnabled" : true, + "_failTransactionsEnabled" : false, + "_locale" : "zh_CN", + "_storefront" : "CHN", + "_storeKitErrors" : [ + { + "current" : null, + "enabled" : false, + "name" : "Load Products" + }, + { + "current" : null, + "enabled" : false, + "name" : "Purchase" + }, + { + "current" : null, + "enabled" : false, + "name" : "Verification" + }, + { + "current" : { + "index" : 2, + "type" : "generic" + }, + "enabled" : false, + "name" : "App Store Sync" + }, + { + "current" : null, + "enabled" : false, + "name" : "Subscription Status" + }, + { + "current" : { + "index" : 3, + "type" : "generic" + }, + "enabled" : false, + "name" : "App Transaction" + }, + { + "current" : null, + "enabled" : false, + "name" : "Manage Subscriptions Sheet" + }, + { + "current" : null, + "enabled" : false, + "name" : "Refund Request Sheet" + }, + { + "current" : null, + "enabled" : false, + "name" : "Offer Code Redeem Sheet" + } + ] + }, + "subscriptionGroups" : [ + { + "id" : "1B73E9E9", + "localizations" : [ + + ], + "name" : "Years", + "subscriptions" : [ + { + "adHocOffers" : [ + { + "internalID" : "B4ECD233", + "offerID" : "LAJ234QMZ5801AAC", + "paymentMode" : "free", + "referenceName" : "促销码", + "subscriptionPeriod" : "P1Y" + } + ], + "codeOffers" : [ + { + "displayPrice" : "200", + "eligibility" : [ + "existing", + "expired", + "new" + ], + "internalID" : "F62AF748", + "isStackable" : true, + "paymentMode" : "payUpFront", + "referenceName" : "促销", + "subscriptionPeriod" : "P6M" + } + ], + "displayPrice" : "149", + "familyShareable" : false, + "groupNumber" : 1, + "internalID" : "D8314451", + "introductoryOffer" : { + "displayPrice" : "0.99", + "internalID" : "89D5DFC5", + "paymentMode" : "free", + "subscriptionPeriod" : "P3D" + }, + "localizations" : [ + { + "description" : "包年", + "displayName" : "包年年度会员", + "locale" : "zh_CN" + } + ], + "productID" : "com.XQMuse.VIP.year.renewing.0", + "recurringSubscriptionPeriod" : "P1Y", + "referenceName" : "购买年度会员(持续订阅)", + "subscriptionGroupID" : "1B73E9E9", + "type" : "RecurringSubscription", + "winbackOffers" : [ + + ] + } + ] + } + ], + "version" : { + "major" : 4, + "minor" : 0 + } +} diff --git a/XQMuse/Config/WeChatTools.swift b/XQMuse/Config/WeChatTools.swift new file mode 100644 index 0000000..8d547a9 --- /dev/null +++ b/XQMuse/Config/WeChatTools.swift @@ -0,0 +1,205 @@ +// +// WeChatTools.swift +// WanPai +// +// Created by 无故事王国 on 2023/9/26. +// + +import Foundation +import HandyJSON + +typealias WeachatClosure = (WechatModel?)->(Void) +typealias WechatUserClosure = (WechatUserInfoModel?)->(Void) + +struct WechatModel:HandyJSON{ + var access_token = "" + var expires_in = 0 + var openid = "" + var refresh_token = "" + var scope = "" + var unionid = "" +} + +struct WechatUserInfoModel:HandyJSON{ + var openid = "" + var nickname = "" + var sex = 1 + var province = "" + var city = "" + var country = "" + var headimgurl = "" + var privilege = "" + var unionid = "" +} + +class WeChatTools{ + + static func register(appid:String,link:String){ + WXApi.registerApp(appid, universalLink: link) + } + + /// 授权登录 + static func sendAuthRequest(){ + let sendAuthReq = SendAuthReq() + sendAuthReq.scope = "snsapi_userinfo" + sendAuthReq.state = "XQMuse_iOS" + WXApi.send(sendAuthReq) + } + + /// 完成授权登录,获取token + static func getAccessToken(_ resp:SendAuthResp, loginInfo:WeachatClosure?){ + guard resp.code != nil else { + return + } + let url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=\(WeChatAPPID)&secret=\(WeChatSecrect)&code=\(resp.code!)&grant_type=authorization_code" + let Url = URL(string: url) + let session = URLSession.shared + let task = session.dataTask(with: Url!) { (data, response, error) in + if error != nil{ + return + } + do{ + if let dataAsJSON = try JSONSerialization.jsonObject(with: data!) as? Dictionary<String, Any>{ + let model = WechatModel.deserialize(from: dataAsJSON) + loginInfo?(model) + }else{ + loginInfo?(nil) + } + }catch{ + loginInfo?(nil) + } + } + task.resume() + } + + /// 获取用资料 + static func getUserInfo(access_token:String,openId:String,userInfo:WechatUserClosure?){ + guard !access_token.isEmpty else { + return + } + + guard !openId.isEmpty else { + return + } + + let url = "https://api.weixin.qq.com/sns/userinfo?access_token=\(access_token)&openid=\(openId)" + let Url = URL(string: url) + let session = URLSession.shared + let task = session.dataTask(with: Url!) { (data, response, error) in + if error != nil{ + return + } + do{ + if let dataAsJSON = try JSONSerialization.jsonObject(with: data!) as? Dictionary<String, Any>{ + let model = WechatUserInfoModel.deserialize(from: dataAsJSON) + userInfo?(model) + }else{ + userInfo?(nil) + } + }catch{ + userInfo?(nil) + } + } + task.resume() + } + + /// 分享文本 + static func shareText(_ text:String,scene:WXScene = WXSceneSession){ + let req = SendMessageToWXReq() + req.bText = true + req.text = text + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } + + /// 分享图片 + static func sharePic(_ img:UIImage,thumb:UIImage,scale:CGFloat = 0.6,scene:WXScene = WXSceneTimeline){ + + let imageObject = WXImageObject() + imageObject.imageData = img.jpegData(compressionQuality: scale)! + + let mediaMessage = WXMediaMessage() + mediaMessage.thumbData = thumb.jpegData(compressionQuality: scale) + mediaMessage.mediaObject = imageObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = mediaMessage + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } + + /// 分享音乐 + static func shareMusic(_ musicUrl:String,musicLowBandUrl:String,title:String,desc:String,thumb:UIImage,scene:WXScene = WXSceneSession){ + let musicObject = WXMusicObject() + musicObject.musicUrl = musicUrl + musicObject.musicLowBandUrl = musicLowBandUrl + + let mediaMessage = WXMediaMessage() + mediaMessage.title = title + mediaMessage.description = desc + mediaMessage.setThumbImage(thumb) + mediaMessage.mediaObject = musicObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = mediaMessage + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } + + /// 分享音乐 + static func shareMusic(_ musicData:String,musicLowBandData:String,title:String,desc:String,thumb:UIImage,scene:WXScene = WXSceneSession){ + let musicObject = WXMusicObject() + musicObject.musicDataUrl = musicData + musicObject.musicLowBandUrl = musicLowBandData + + let mediaMessage = WXMediaMessage() + mediaMessage.title = title + mediaMessage.description = desc + mediaMessage.setThumbImage(thumb) + mediaMessage.mediaObject = musicObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = mediaMessage + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } + + static func shareUrl(_ url:String,title:String,desc:String,thumb:UIImage,scene:WXScene = WXSceneSession){ + + let webpageObject = WXWebpageObject() + webpageObject.webpageUrl = url + + let mediaMessage = WXMediaMessage() + mediaMessage.title = title + mediaMessage.description = desc + mediaMessage.setThumbImage(thumb) + mediaMessage.mediaObject = webpageObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = mediaMessage + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } + + static func shareVideo(_ url:String,videoLowBandUrl:String,title:String,desc:String,thumb:UIImage, scene:WXScene = WXSceneSession){ + let videoObject = WXVideoObject() + videoObject.videoUrl = url + videoObject.videoLowBandUrl = videoLowBandUrl + + let mediaMessage = WXMediaMessage() + mediaMessage.title = title + mediaMessage.description = desc + mediaMessage.setThumbImage(thumb) + mediaMessage.mediaObject = videoObject + + let req = SendMessageToWXReq() + req.bText = false + req.message = mediaMessage + req.scene = Int32(scene.rawValue) + WXApi.send(req) + } +} diff --git a/XQMuse/Config/XQMuse-Bridging-Header.h b/XQMuse/Config/XQMuse-Bridging-Header.h new file mode 100644 index 0000000..70c2cdb --- /dev/null +++ b/XQMuse/Config/XQMuse-Bridging-Header.h @@ -0,0 +1,12 @@ +// +// XQMuse-Bridging-Header.h +// XQMuse +// +// Created by 无故事王国 on 2024/10/17. +// + +#ifndef XQMuse_Bridging_Header_h +#define XQMuse_Bridging_Header_h +#import "WXApi.h" + +#endif /* XQMuse_Bridging_Header_h */ diff --git a/XQMuse/Info.plist b/XQMuse/Info.plist index d8c6797..13fbc52 100644 --- a/XQMuse/Info.plist +++ b/XQMuse/Info.plist @@ -2,6 +2,27 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>CFBundleAllowMixedLocalizations</key> + <true/> + <key>CFBundleURLTypes</key> + <array> + <dict> + <key>CFBundleTypeRole</key> + <string>Editor</string> + <key>CFBundleURLSchemes</key> + <array> + <string>wx4b9c1d814c2902a3</string> + </array> + </dict> + </array> + <key>LSApplicationQueriesSchemes</key> + <array> + <string>weixin</string> + <string>weixinULAPI</string> + <string>weixinURLParamsAPI</string> + </array> + <key>Localization native development region</key> + <string>China</string> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> diff --git a/XQMuse/Root/Course/CCell/CourseOfficalCommendTopCCell.swift b/XQMuse/Root/Course/CCell/CourseOfficalCommendTopCCell.swift index d427d0e..8431167 100644 --- a/XQMuse/Root/Course/CCell/CourseOfficalCommendTopCCell.swift +++ b/XQMuse/Root/Course/CCell/CourseOfficalCommendTopCCell.swift @@ -33,7 +33,11 @@ func setBanners(_ items:[CommonBannerModel]){ bannerModels = items - view_bannerContentView.setItems(items: items) + view_bannerContentView.setItems(items: items) { m in + if let id = m.courseId?.int{ + JQ_currentNavigationController().pushViewController(CourseDetialVC(courseId: id)) + } + } } func clickAtClouse(_ clouse:@escaping (Int)->Void){ diff --git a/XQMuse/Root/Course/CourseVC.swift b/XQMuse/Root/Course/CourseVC.swift index 21f7221..96c8bc7 100644 --- a/XQMuse/Root/Course/CourseVC.swift +++ b/XQMuse/Root/Course/CourseVC.swift @@ -111,7 +111,7 @@ @objc func searchAction(){ - let vc = SearchVC() + let vc = SearchVC(serchType: .course) push(vc: vc) } diff --git a/XQMuse/Root/Course/VC/CourseDetialVC.swift b/XQMuse/Root/Course/VC/CourseDetialVC.swift index 27558db..0912a2e 100644 --- a/XQMuse/Root/Course/VC/CourseDetialVC.swift +++ b/XQMuse/Root/Course/VC/CourseDetialVC.swift @@ -20,6 +20,7 @@ class CourseDetialVC: BaseVC { private var tableView:UITableView? + private var collect_bitem:UIBarButtonItem! private let studyBtn = QMUIButton(type: .custom) private var headerView = CourseDetailHeaderView.jq_loadNibView() private var barStyle:UIStatusBarStyle = .lightContent @@ -118,7 +119,12 @@ self.tableView!.tableHeaderView = self.headerView } - setFootView() + collect_bitem = UIBarButtonItem(image: UIImage(named: "btn_collect"), style: .plain, target: self, action: #selector(collectionAction)) + collect_bitem.tintColor = .white + let share_bitem = UIBarButtonItem(image: UIImage(named: "btn_share"), style: .plain, target: self, action: #selector(shareAction)) + share_bitem.tintColor = .white + share_bitem.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 15) + navigationItem.rightBarButtonItems = [share_bitem,collect_bitem] } private func getData(){ @@ -129,7 +135,15 @@ self.section1TCell.setItems(m) self.section2TCell.setItems(m.list2) - if m.isBuy != .yes{ + //是否需要购买 + var needPayment:Bool = true + switch m.chargeType{ + case .free:needPayment = false + case .payment:needPayment = !(m.isBuy == .yes) + case .vipFree:needPayment = !(UserViewModel.getAvatarInfo().isVip == .yes) + } + + if needPayment{ 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) } @@ -142,6 +156,7 @@ self.pageMenu.setItems(["简介"], selectedItemIndex: 0) } self.tableView?.reloadData() + self.setFootView() } }).disposed(by: disposeBag) } @@ -155,19 +170,21 @@ make.height.equalTo(84) } - let giftBtn = QMUIButton(type: .custom) - giftBtn.imagePosition = .left - giftBtn.spacingBetweenImageAndTitle = 7.5 - giftBtn.setTitleColor(UIColor(hexString: "#464646"), for: .normal) - giftBtn.setImage(UIImage(named: "btn_sendGift"), for: .normal) - giftBtn.setTitle("赠送好友", for: .normal) - giftBtn.addTarget(self, action: #selector(sendGift(_:)), for: .touchUpInside) - giftBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold) - footView.addSubview(giftBtn) - giftBtn.snp.makeConstraints { make in - make.left.equalTo(26) - make.top.equalTo(26.5) - } + if courseDetailModel?.chargeType == .payment{ + let giftBtn = QMUIButton(type: .custom) + giftBtn.imagePosition = .left + giftBtn.spacingBetweenImageAndTitle = 7.5 + giftBtn.setTitleColor(UIColor(hexString: "#464646"), for: .normal) + giftBtn.setImage(UIImage(named: "btn_sendGift"), for: .normal) + giftBtn.setTitle("赠送好友", for: .normal) + giftBtn.addTarget(self, action: #selector(sendGift(_:)), for: .touchUpInside) + giftBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold) + footView.addSubview(giftBtn) + giftBtn.snp.makeConstraints { make in + make.left.equalTo(26) + make.top.equalTo(26.5) + } + } studyBtn.setTitleColor(UIColor.white, for: .normal) studyBtn.setTitle(" 立即学习 ", for: .normal) @@ -178,7 +195,7 @@ footView.addSubview(studyBtn) studyBtn.snp.makeConstraints { make in make.right.equalTo(-20) - make.centerY.equalTo(giftBtn) + make.top.equalTo(22) make.height.equalTo(34) } } @@ -203,10 +220,32 @@ }).disposed(by: disposeBag) } + @objc func collectionAction(){ + Services.meditationFavorite(id: courseId).subscribe(onNext: {data in + self.courseDetailModel?.isCollect.troggle() + if self.courseDetailModel?.isCollect == .yes{ + alertSuccess(msg: "收藏成功") + self.collect_bitem.image = UIImage(named: "btn_collect_1_s") + self.collect_bitem.tintColor = UIColor(hexString: "fe5b60") + }else{ + alertSuccess(msg: "已取消收藏") + self.collect_bitem.image = UIImage(named: "btn_collect") + self.collect_bitem.tintColor = .white + } + }).disposed(by: disposeBag) + } + + @objc func shareAction(){ + ShareView.show() + } + @objc func handleAction(_ btn:QMUIButton){ if let m = courseDetailModel{ if m.chargeType == .free || (m.chargeType == .vipFree && UserViewModel.getAvatarInfo().isVip == .yes) || (m.chargeType == .payment && m.isBuy == .yes){ + guard m.list.count != 0 else { + alertError(msg: "课程目录异常");return + } let vc = CourseDetialVideoVC(items: m.list, selectIndex: IndexPath(row: 0, section: 0)) push(vc: vc);return } @@ -334,11 +373,9 @@ } } - let offSetY = scrollView.contentOffset.y + CGRectGetHeight(scrollView.frame) / 2; if let currentIndex = tableView?.indexPathForRow(at: CGPoint(x: 0, y: offSetY)){ - print(scrollView.isDragging) if !isAnimationing{ if currentShowIndex != currentIndex{ diff --git a/XQMuse/Root/Course/VC/CourseDetialVideoVC.swift b/XQMuse/Root/Course/VC/CourseDetialVideoVC.swift index 17b5ef8..952ca3e 100644 --- a/XQMuse/Root/Course/VC/CourseDetialVideoVC.swift +++ b/XQMuse/Root/Course/VC/CourseDetialVideoVC.swift @@ -36,6 +36,7 @@ title = "课程详情" videoView = VideoView(url: items[selectIndex.row].videoUrl) + videoView?.player.play() view_bg_video.addSubview(videoView!) videoView!.snp.makeConstraints { make in make.edges.equalToSuperview() diff --git a/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift b/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift index 593cece..241bcfc 100644 --- a/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift +++ b/XQMuse/Root/Course/VC/CourseVCOfficalCommentVC.swift @@ -12,8 +12,9 @@ class CourseVCOfficalViewModel:RefreshInnerModel<CourseModel>{ var cateId = BehaviorRelay<Int?>(value: nil) + var search = BehaviorRelay<String?>(value: nil) override func api() -> (Observable<BaseResponse<BaseResponseList<CourseModel>>>)? { - return Services.getCoursePageList(page: page) + return Services.getCoursePageList(page: page,courseTitle: search.value) } } @@ -40,7 +41,7 @@ Services.getCourseBannerList().subscribe(onNext: {data in for (index,v) in (data.data ?? []).enumerated(){ - self.bannerModels.append(CommonBannerModel(index: index, id: v.id, name: v.name, resource:v.imageUrl, mediaType: .imageUrl)) + self.bannerModels.append(CommonBannerModel(index: index, id: v.id, name: v.name, resource:v.imageUrl, mediaType: .imageUrl,courseId: v.courseId)) } self.collectionView.reloadData() }).disposed(by: disposeBag) diff --git a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.swift b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.swift index 93a8fff..69a3f2b 100644 --- a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.swift +++ b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.swift @@ -15,7 +15,8 @@ @IBOutlet weak var label_title: UILabel! @IBOutlet weak var label_subTitle: UILabel! @IBOutlet weak var label_num: UILabel! - + @IBOutlet weak var img_isFree: UIImageView! + override func awakeFromNib() { super.awakeFromNib() // Initialization code diff --git a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.xib b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.xib index 7a76534..5f19c3a 100644 --- a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.xib +++ b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_1_CCell.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -90,6 +90,7 @@ <size key="customSize" width="160" height="196"/> <connections> <outlet property="img_cover" destination="VwD-36-ent" id="93Z-v8-bjM"/> + <outlet property="img_isFree" destination="C5o-Fs-4Xu" id="eut-gN-uQO"/> <outlet property="label_num" destination="Wxc-EY-qwU" id="zxI-Y4-tTv"/> <outlet property="label_subTitle" destination="EeQ-hi-VEz" id="U39-7s-GGD"/> <outlet property="label_title" destination="6md-5M-Pce" id="j50-e3-otB"/> diff --git a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.swift b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.swift index 59a67be..96714da 100644 --- a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.swift +++ b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.swift @@ -18,7 +18,10 @@ @IBOutlet weak var label_subTitle: UILabel! @IBOutlet weak var label_num: UILabel! @IBOutlet weak var cons_maxSubTitle: NSLayoutConstraint! - + @IBOutlet weak var view_price: UIView! + @IBOutlet weak var label_price: UILabel! + @IBOutlet weak var image_free: UIImageView! + private var meditationModel:MeditationModel? override func awakeFromNib() { super.awakeFromNib() @@ -35,6 +38,8 @@ visualEffectView.alpha = 0.7 view_text_bg.sendSubviewToBack(visualEffectView) visualEffectView.layer.masksToBounds = true + + view_price.jq_cornerRadius = 12.55 } func setMeditationModel(_ model:MeditationModel){ @@ -50,5 +55,21 @@ label_title.text = model.courseTitle label_subTitle.text = model.briefIntroduction label_num.text = "\(model.count)" + img_vip.isHidden = model.isVip != .yes + + switch model.chargeType { + case .payment: + image_free.isHidden = true + view_price.isHidden = false + label_price.attributedText = AttributedStringbuilder.build().add(string: "¥", withFont: UIFont(name: "DIN-Bold", size: 7.11) ?? UIFont.systemFont(ofSize: 7, weight: .bold), withColor: .white).add(string: model.generalPrice.jq_formatFloat, withFont: UIFont(name: "DIN-Bold", size: 11.44) ?? .systemFont(ofSize: 11,weight: .bold), withColor: .white).mutableAttributedString + case .free: + image_free.isHidden = false + view_price.isHidden = true + img_vip.isHidden = true + case .vipFree: + image_free.isHidden = true + view_price.isHidden = true + img_vip.isHidden = false + } } } diff --git a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.xib b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.xib index 4844006..18f93d1 100644 --- a/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.xib +++ b/XQMuse/Root/Home/CCell/HomeRelaxBanner_2_CCell.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <objects> @@ -64,34 +64,65 @@ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_vip" translatesAutoresizingMaskIntoConstraints="NO" id="yBF-fO-fwz"> <rect key="frame" x="14.666666666666666" y="7.6666666666666661" width="21.333333333333336" height="21.333333333333336"/> </imageView> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rmi-DQ-cp9"> + <rect key="frame" x="14.666666666666664" y="7.6666666666666679" width="25" height="25.000000000000004"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kTL-dA-lNA"> + <rect key="frame" x="0.0" y="0.0" width="25" height="25"/> + <fontDescription key="fontDescription" type="system" pointSize="11"/> + <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <color key="backgroundColor" red="0.89803921568627454" green="0.71372549019607845" blue="0.39215686274509803" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <constraints> + <constraint firstAttribute="trailing" secondItem="kTL-dA-lNA" secondAttribute="trailing" id="4rs-Ms-47V"/> + <constraint firstAttribute="bottom" secondItem="kTL-dA-lNA" secondAttribute="bottom" id="Gk6-tP-QxW"/> + <constraint firstItem="kTL-dA-lNA" firstAttribute="leading" secondItem="rmi-DQ-cp9" secondAttribute="leading" id="Utr-e1-5lW"/> + <constraint firstAttribute="width" constant="25.100000000000001" id="j5h-a9-Qj3"/> + <constraint firstItem="kTL-dA-lNA" firstAttribute="top" secondItem="rmi-DQ-cp9" secondAttribute="top" id="qKa-MB-Ohi"/> + <constraint firstAttribute="height" constant="25.100000000000001" id="xtT-s6-JWf"/> + </constraints> + </view> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_freee" translatesAutoresizingMaskIntoConstraints="NO" id="deT-IZ-PtZ"> + <rect key="frame" x="8" y="7" width="50" height="18"/> + </imageView> </subviews> </view> <constraints> <constraint firstItem="yBF-fO-fwz" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="7.5" id="136-6N-kY2"/> + <constraint firstItem="rmi-DQ-cp9" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="14.5" id="7EM-yV-ddi"/> <constraint firstAttribute="bottom" secondItem="cCC-0f-GSV" secondAttribute="bottom" id="FP4-wO-vdE"/> + <constraint firstItem="deT-IZ-PtZ" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="8" id="Gs7-Se-Ivy"/> <constraint firstAttribute="trailing" secondItem="Fb9-IV-vVk" secondAttribute="trailing" id="HZP-qu-QnA"/> <constraint firstItem="yBF-fO-fwz" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="14.5" id="R10-E8-6fB"/> <constraint firstItem="Fb9-IV-vVk" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="WI6-dS-4aK"/> <constraint firstAttribute="trailing" secondItem="cCC-0f-GSV" secondAttribute="trailing" id="brF-kM-RJ7"/> <constraint firstItem="cCC-0f-GSV" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="c6s-ah-BAB"/> <constraint firstAttribute="bottom" secondItem="Fb9-IV-vVk" secondAttribute="bottom" id="jcg-ng-xeW"/> + <constraint firstItem="deT-IZ-PtZ" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="7" id="tPU-LR-azA"/> <constraint firstItem="cCC-0f-GSV" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="tmD-tf-gYR"/> + <constraint firstItem="rmi-DQ-cp9" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="7.5" id="wLQ-lC-KXg"/> </constraints> <size key="customSize" width="178" height="301"/> <connections> <outlet property="cons_maxSubTitle" destination="Fam-ne-FM1" id="L5X-GP-uev"/> + <outlet property="image_free" destination="deT-IZ-PtZ" id="kI7-7g-aIM"/> <outlet property="img_cover" destination="cCC-0f-GSV" id="85x-ue-edy"/> <outlet property="img_tipPeople" destination="hE1-AV-t8f" id="ObN-5h-jnl"/> <outlet property="img_vip" destination="yBF-fO-fwz" id="icq-m9-dx3"/> <outlet property="label_num" destination="JaY-19-IAL" id="2RU-X7-0wb"/> + <outlet property="label_price" destination="kTL-dA-lNA" id="lNC-ej-0H3"/> <outlet property="label_subTitle" destination="z5u-My-91l" id="j4L-bl-DhS"/> <outlet property="label_title" destination="byc-Ar-sJL" id="CAQ-8Z-yC9"/> + <outlet property="view_price" destination="rmi-DQ-cp9" id="Kh2-av-YYy"/> <outlet property="view_text_bg" destination="Fb9-IV-vVk" id="Ol7-cR-BWU"/> </connections> <point key="canvasLocation" x="236.64122137404578" y="108.80281690140846"/> </collectionViewCell> </objects> <resources> + <image name="icon_freee" width="50" height="18"/> <image name="icon_use_small" width="10" height="10.666666984558105"/> <image name="icon_vip" width="21.666666030883789" height="21.666666030883789"/> </resources> diff --git a/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.swift b/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.swift index b6af8e0..32268e5 100644 --- a/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.swift +++ b/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.swift @@ -19,7 +19,7 @@ override func awakeFromNib() { super.awakeFromNib() - view_shadow.jq_gradientColor(colorArr: [UIColor.black.withAlphaComponent(0.2).cgColor,UIColor.clear.cgColor], cornerRadius: 0, startPoint: CGPoint(x: 1, y: 1), endPoint: CGPoint(x: 1, y: 0), bounds: nil, locations: nil) + view_shadow.jq_gradientColor(colorArr: [UIColor.black.withAlphaComponent(0.3).cgColor,UIColor.clear.cgColor], cornerRadius: 0, startPoint: CGPoint(x: 1, y: 1), endPoint: CGPoint(x: 1, y: 0), bounds: nil, locations: nil) } diff --git a/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.xib b/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.xib index c6b20e9..a92b905 100644 --- a/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.xib +++ b/XQMuse/Root/Home/CCell/Home_Style_4_Inner_1_CCell.xib @@ -1,10 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> - <capability name="System colors in document resources" minToolsVersion="11.0"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <objects> @@ -24,7 +23,7 @@ <constraint firstAttribute="height" constant="9.5" id="wsl-qN-1LP"/> </constraints> </view> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ajx-e3-nPT"> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ajx-e3-nPT"> <rect key="frame" x="0.0" y="0.0" width="413" height="255.66666666666666"/> </imageView> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="all-AA-1bU"> @@ -50,7 +49,6 @@ <nil key="highlightedColor"/> </label> </subviews> - <color key="backgroundColor" systemColor="systemBackgroundColor"/> <constraints> <constraint firstAttribute="trailing" secondItem="NTV-9E-3YX" secondAttribute="trailing" constant="10" id="1d8-hO-XQO"/> <constraint firstItem="NTV-9E-3YX" firstAttribute="leading" secondItem="tDO-qY-aGP" secondAttribute="leading" id="51K-EF-Rvn"/> @@ -89,8 +87,5 @@ </objects> <resources> <image name="icon_pay_s" width="14.666666984558105" height="18.666666030883789"/> - <systemColor name="systemBackgroundColor"> - <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - </systemColor> </resources> </document> diff --git a/XQMuse/Root/Home/HomeVC.swift b/XQMuse/Root/Home/HomeVC.swift index 6755dea..2aff568 100644 --- a/XQMuse/Root/Home/HomeVC.swift +++ b/XQMuse/Root/Home/HomeVC.swift @@ -9,6 +9,7 @@ import JQTools import RxSwift import MediaPlayer +import MJRefresh let SetBGMSuccess_Noti = Notification.Name.init("SetBGMSuccess_Noti") @@ -48,6 +49,10 @@ AudioPlayer.getSharedInstance().playSceneAt(audioFile) } } + + tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: { + self.getData() + }) getData() } @@ -140,6 +145,7 @@ } private func getData(){ + tableView.mj_header?.endRefreshing() Services.getCategoryListByType(type: 1).subscribe(onNext: { data in var items = [HomeTopMenuItem]() @@ -183,6 +189,7 @@ self.viewModel.meditationList.removeAll() self.viewModel.meditationList = m for v in self.viewModel.meditationList{ + if v.clientMeditationCategoryVO?.categoryName.isEmpty ?? true{continue} self.titleItems.append(TitleItem(title: v.clientMeditationCategoryVO?.categoryName ?? "", subTitle: v.clientMeditationCategoryVO?.description ?? "",hasMore:true)) } self.tableView.reloadData() @@ -191,17 +198,13 @@ } @objc func searchAction(){ - let vc = SearchVC() + let vc = SearchVC(serchType: .muse) push(vc: vc) } @objc func settingvoiceAction(){ -// let vc = BackgroundVoiceVC() -// push(vc: vc) - - let nav = LoginNav(rootViewController: LoginVC()) - nav.modalPresentationStyle = .fullScreen - present(nav, animated: true) + let vc = BackgroundVoiceVC() + push(vc: vc) } @objc func jumpMoreAction(_ sender:UIButton){ @@ -235,16 +238,20 @@ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.section == 0{ + //每日疗愈 let cell = tableView.dequeueReusableCell(withIdentifier: "_Home_Style_1_TCell") as! Home_Style_1_TCell cell.model = viewModel.todyModel return cell }else if indexPath.section == 1{ + //私人定制 let cell = tableView.dequeueReusableCell(withIdentifier: "_Home_Style_4_TCell") as! Home_Style_4_TCell cell.style = .style1 cell.setModels(viewModel.privateTodyModels) return cell }else if indexPath.section == 2{ + // 新手冥想指南 let cell = tableView.dequeueReusableCell(withIdentifier: "_Home_Style_2_TCell") as! Home_Style_2_TCell + cell.imgView.image = UIImage(named: "bg_guide_home") cell.view_shadow.isHidden = true return cell }else { @@ -326,7 +333,9 @@ extension HomeVC:UIScrollViewDelegate{ func scrollViewDidScroll(_ scrollView: UIScrollView) { - let v = min(scrollView.contentOffset.y / JQ_NavBarHeight, 1) - navigationController?.navigationBar.standardAppearance.backgroundColor = .white.withAlphaComponent(v) +// let v = min(scrollView.contentOffset.y / JQ_NavBarHeight, 1) +// navigationController?.navigationBar.standardAppearance.backgroundColor = .white.withAlphaComponent(v) + navigationController?.navigationBar.standardAppearance.backgroundColor = .white + navigationController?.navigationBar.scrollEdgeAppearance?.backgroundColor = .white } } diff --git a/XQMuse/Root/Home/TCell/Home_Style_2_TCell.swift b/XQMuse/Root/Home/TCell/Home_Style_2_TCell.swift index 0bba8ae..e55a25c 100644 --- a/XQMuse/Root/Home/TCell/Home_Style_2_TCell.swift +++ b/XQMuse/Root/Home/TCell/Home_Style_2_TCell.swift @@ -11,7 +11,8 @@ class Home_Style_2_TCell: UITableViewCell { @IBOutlet weak var view_shadow: UIView! - + @IBOutlet weak var imgView: UIImageView! + override func awakeFromNib() { super.awakeFromNib() selectionStyle = .none diff --git a/XQMuse/Root/Home/TCell/Home_Style_2_TCell.xib b/XQMuse/Root/Home/TCell/Home_Style_2_TCell.xib index 69a2012..471ad91 100644 --- a/XQMuse/Root/Home/TCell/Home_Style_2_TCell.xib +++ b/XQMuse/Root/Home/TCell/Home_Style_2_TCell.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> @@ -18,7 +18,7 @@ <rect key="frame" x="0.0" y="0.0" width="475" height="351"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Pyg-Ek-VBf"> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Pyg-Ek-VBf"> <rect key="frame" x="0.0" y="0.0" width="475" height="341.66666666666669"/> </imageView> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WXB-JU-fQz"> @@ -78,6 +78,7 @@ </tableViewCellContentView> <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> <connections> + <outlet property="imgView" destination="Pyg-Ek-VBf" id="aL8-Jj-6BS"/> <outlet property="view_shadow" destination="WXB-JU-fQz" id="PbM-TY-SlG"/> </connections> <point key="canvasLocation" x="257.25190839694653" y="128.52112676056339"/> diff --git a/XQMuse/Root/Home/VC/CommentListVC.swift b/XQMuse/Root/Home/VC/CommentListVC.swift index a6519b4..1984a32 100644 --- a/XQMuse/Root/Home/VC/CommentListVC.swift +++ b/XQMuse/Root/Home/VC/CommentListVC.swift @@ -29,6 +29,16 @@ @IBOutlet weak var cons_height: NSLayoutConstraint! private var viewModel = CommentListViewModel() + private var id:Int! + + init(id:Int) { + super.init(nibName: nil, bundle: nil) + self.id = id + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } override func viewDidLoad() { super.viewDidLoad() @@ -63,7 +73,16 @@ } @IBAction func sendAction(_ sender: UIButton) { + guard !tf_input.text!.isEmpty else { + alert(msg: "请输入您的提问");return + } + tf_input.resignFirstResponder() + Services.addQuestion(content: tf_input.text!, meditationId: id).subscribe(onNext: {_ in + + }, onError: {_ in + + }).disposed(by: disposeBag) } @objc func longPressAction(_ gesture:UITapGestureRecognizer){ diff --git a/XQMuse/Root/Home/VC/HomeItemDetailVC.swift b/XQMuse/Root/Home/VC/HomeItemDetailVC.swift index 3a5a744..216de5d 100644 --- a/XQMuse/Root/Home/VC/HomeItemDetailVC.swift +++ b/XQMuse/Root/Home/VC/HomeItemDetailVC.swift @@ -11,7 +11,8 @@ class HomeItemDetailVC: BaseVC,PayMusicDelegate{ @IBOutlet weak var slider_voice: UISlider! - @IBOutlet weak var view_function: UIView! + @IBOutlet weak var img_background: UIImageView! + @IBOutlet weak var view_function: UIView! @IBOutlet weak var btn_play: UIButton! @IBOutlet weak var label_title: UILabel! @IBOutlet weak var label_subtitle: UILabel! @@ -62,26 +63,28 @@ Services.getMeditationDetail(id: id).subscribe(onNext: {[unowned self] data in self.model = data.data - self.collect_bitem.image = data.data?.favorite == .yes ? UIImage(named: "btn_collect_s"):UIImage(named: "btn_collect_1") + self.collect_bitem.image = data.data?.favorite == .yes ? UIImage(named: "btn_collect_1_s"):UIImage(named: "btn_collect_1") self.collect_bitem.tintColor = data.data?.favorite == .yes ? UIColor(hexString: "fe5b60"):.white - + self.img_background.sd_setImage(with: URL(string: data.data?.backgroundUrl ?? "")) if audioPlayer.meditationModel?.id == data.data?.id{ audioPlayer.delegate = self } }).disposed(by: disposeBag) + + //如果从支付过来的,移除支付 + navigationController!.viewControllers.removeAll { vc in + if vc is PaymentOrderResultVC || vc is PaymentOrderVC{ + return true + } + return false + } } - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - //如果从支付过来的,移除支付 - navigationController!.viewControllers.removeAll { vc in - if vc is PaymentOrderResultVC || vc is PaymentOrderVC{ - return true - } - return false - } - } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + (navigationItem.leftBarButtonItem?.customView as? UIButton)?.setImage(UIImage(named: "btn_back")?.withTintColor(.white), for: .normal) + navigationController?.navigationBar.scrollEdgeAppearance?.backgroundColor = .clear + } override func setUI() { @@ -124,11 +127,6 @@ }.disposed(by: disposeBag) } - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - (navigationItem.leftBarButtonItem?.customView as? UIButton)?.setImage(UIImage(named: "btn_back")?.withTintColor(.white), for: .normal) - } - private func startMiniRunloop(){ // 创建旋转动画 let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z") @@ -146,13 +144,7 @@ } @IBAction func playAction(_ sender: UIButton) { - -// showHUD("准备播放") - - if var m = model{ - m.backgroundUrl = "https://downsc.chinaz.net/Files/DownLoad/sound1/201906/11582.mp3,https://www.cambridgeenglish.org/images/153149-movers-sample-listening-test-vol2.mp3" - - m.tutorAudioUrl = "https://downsc.chinaz.net/files/download/sound1/201206/1638.mp3" + if let m = model{ audioPlayer.playBGMAt(firstPlayIndex: 0, model: m, delegate: self) } } @@ -187,7 +179,9 @@ } @IBAction func commentAction(_ sender: TapBtn) { - let vc = CommentListVC() + guard let m = model else{return} + + let vc = CommentListVC(id: m.id) vc.modalPresentationStyle = .custom present(vc, animated: true) } diff --git a/XQMuse/Root/Home/VC/HomeItemDetailVC.xib b/XQMuse/Root/Home/VC/HomeItemDetailVC.xib index 5d83e74..7efec0b 100644 --- a/XQMuse/Root/Home/VC/HomeItemDetailVC.xib +++ b/XQMuse/Root/Home/VC/HomeItemDetailVC.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -12,6 +12,7 @@ <connections> <outlet property="btn_play" destination="Qgc-UW-rO1" id="MUw-JK-1pS"/> <outlet property="btn_playMode" destination="9t3-fS-clT" id="0me-mK-vhP"/> + <outlet property="img_background" destination="pbM-Fi-Xil" id="cuG-Hk-KlP"/> <outlet property="img_countdonw" destination="gxd-0O-eUD" id="rzB-8i-qOk"/> <outlet property="label_commentNum" destination="IkS-qR-riK" id="9zO-Xt-6XC"/> <outlet property="label_countdown" destination="akf-L4-aPE" id="goO-Gd-TLu"/> @@ -174,10 +175,10 @@ </connections> </button> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3rZ-t0-pdK"> - <rect key="frame" x="68.666666666666686" y="524.66666666666663" width="256" height="29"/> + <rect key="frame" x="71.333333333333329" y="524.66666666666663" width="250.66666666666669" height="29"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="当前播放模式已设置为顺序播放" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4zW-Bq-V7P"> - <rect key="frame" x="28" y="7.3333333333333712" width="200" height="14"/> + <rect key="frame" x="28" y="7.3333333333333712" width="194.66666666666666" height="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> diff --git a/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift b/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift index 47de44e..2a8f721 100644 --- a/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift +++ b/XQMuse/Root/Home/VC/PaymentOrderResultVC.swift @@ -29,6 +29,14 @@ super.viewDidLoad() title = "支付结果" + //如果从支付过来的,移除支付 + navigationController!.viewControllers.removeAll { vc in + if vc is PaymentOrderResultVC || vc is PaymentOrderVC{ + return true + } + return false + } + NotificationCenter.default.post(name: CourseRefresh_Noti, object: nil) yy_popBlock = { [weak self] () in @@ -45,7 +53,7 @@ } } - topView.setPrice(price) + topView.setPrice(courseId: courseId, price: price) Services.paymentSuccess(courseId: courseId).subscribe(onNext: {data in self.models = data.data ?? [] @@ -122,7 +130,8 @@ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_HomeRelaxBanner_2_1_CCell", for: indexPath) as! HomeRelaxBanner_2_1_CCell - cell.backgroundColor = .jq_randomColor + let model = models[indexPath.row] + cell.setCourseModel(model) return cell } diff --git a/XQMuse/Root/Home/VC/PaymentOrderVC.swift b/XQMuse/Root/Home/VC/PaymentOrderVC.swift index 47c8036..ad2c25f 100644 --- a/XQMuse/Root/Home/VC/PaymentOrderVC.swift +++ b/XQMuse/Root/Home/VC/PaymentOrderVC.swift @@ -134,6 +134,20 @@ @IBAction func completeAction(_ sender: UIButton) { guard let m = courseModel else {return} + guard btn_isRead.isSelected else { + alertError(msg: "请先阅读并同意《课程/疗愈音频购买协议》");return + } + + if giftToOther { + + guard !tf_phone.text!.isEmpty else { + alertError(msg: "请输入您要赠送人的手机号");return + } + + guard giftUserId != nil else { + alertError(msg: "请先查询赠送人是否存在");return + } + } guard balance > m.generalPrice else{ CommonAlertView.show(title: "提示", content: "当前余额不足,请先充值", cancelStr: "暂不充值", completeStr: "去充值", isSingle: false) { state in @@ -142,16 +156,6 @@ } } 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) diff --git a/XQMuse/Root/Home/VC/SearchContentVC.swift b/XQMuse/Root/Home/VC/SearchContentVC.swift index 7441048..86087c5 100644 --- a/XQMuse/Root/Home/VC/SearchContentVC.swift +++ b/XQMuse/Root/Home/VC/SearchContentVC.swift @@ -24,11 +24,23 @@ @IBOutlet weak var tf_search: UITextField! @IBOutlet weak var collectionView: UICollectionView! - private var viewModel = SearchContentViewModel() + private var museViewModel:SearchContentViewModel? + private var courseViewModel:CourseVCOfficalViewModel? + private var serchType:SearchVC.SearchType! - init(content:String) { + init(content:String,type:SearchVC.SearchType) { super.init(nibName: nil, bundle: nil) - self.viewModel.search.accept(content) + self.serchType = type + + if type == .course{ + courseViewModel = CourseVCOfficalViewModel() + courseViewModel?.search.accept(content) + } + + if type == .muse{ + museViewModel = SearchContentViewModel() + museViewModel?.search.accept(content) + } } required init?(coder: NSCoder) { @@ -39,7 +51,11 @@ super.viewDidLoad() title = "心泉·疗愈" - tf_search.text = viewModel.search.value + switch serchType{ + case .course:tf_search.text = courseViewModel?.search.value ?? "" + case .muse:tf_search.text = museViewModel?.search.value ?? "" + default:break + } } override func setUI() { @@ -54,7 +70,12 @@ collectionView.register(UINib(nibName: "HomeRelaxBanner_2_CCell", bundle: nil), forCellWithReuseIdentifier: "_HomeRelaxBanner_2_CCell") collectionView.emptyDataSetView {[unowned self] v in + + guard v.viewWithTag(1301) == nil else {return} + let emptyImageView = UIImageView(image: UIImage(named: "bg_empty")) + emptyImageView.tag = 1301 + v.addSubview(emptyImageView) emptyImageView.snp.makeConstraints { make in make.top.equalTo(56.5) @@ -71,8 +92,15 @@ } } - viewModel.configure(collectionView) - viewModel.beginRefresh() + switch serchType{ + case .course: + self.courseViewModel?.configure(collectionView) + self.courseViewModel?.beginRefresh() + case .muse: + self.museViewModel?.configure(collectionView) + self.museViewModel?.beginRefresh() + default:break + } } @@ -83,8 +111,15 @@ alert(msg: "请输入搜索内容");return } - viewModel.search.accept(tf_search.text!) - viewModel.beginRefresh() + switch serchType{ + case .course: + self.courseViewModel?.search.accept(tf_search.text!) + self.courseViewModel?.beginRefresh() + case .muse: + self.museViewModel?.search.accept(tf_search.text!) + self.museViewModel?.beginRefresh() + default:break + } } } @@ -92,21 +127,46 @@ extension SearchContentVC:UICollectionViewDelegate & UICollectionViewDataSource{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let m = viewModel.dataSource.value!.list[indexPath.row] - let vc = CourseDetialVC(courseId: m.id) - JQ_currentViewController().jq_push(vc: vc) + + switch serchType{ + case .course: + let m = courseViewModel!.dataSource.value!.list[indexPath.row] + let vc = CourseDetialVC(courseId: m.id) + JQ_currentViewController().jq_push(vc: vc) + + case .muse: + let m = museViewModel!.dataSource.value!.list[indexPath.row] + let vc = HomeItemDetailVC(id: m.id) + JQ_currentViewController().jq_push(vc: vc) + default:break + } + } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let m = viewModel.dataSource.value!.list[indexPath.row] - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_HomeRelaxBanner_2_CCell", for: indexPath) as! HomeRelaxBanner_2_CCell - cell.backgroundColor = .jq_randomColor - cell.setMeditationModel(m) + + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_HomeRelaxBanner_2_CCell", for: indexPath) as! HomeRelaxBanner_2_CCell + + switch serchType{ + case .course:break + + case .muse: + let m = museViewModel!.dataSource.value!.list[indexPath.row] + cell.setMeditationModel(m) + default:break + } + return cell } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return viewModel.dataSource.value?.list.count ?? 0 + switch serchType{ + case .course: + return courseViewModel!.dataSource.value?.list.count ?? 0 + case .muse: + return museViewModel!.dataSource.value?.list.count ?? 0 + default:return 0 + } } } @@ -136,9 +196,15 @@ alert(msg: "请输入搜索内容") return true } - - viewModel.search.accept(textField.text!) - viewModel.beginRefresh() + switch serchType{ + case .course: + self.courseViewModel?.search.accept(tf_search.text!) + self.courseViewModel?.beginRefresh() + case .muse: + self.museViewModel?.search.accept(tf_search.text!) + self.museViewModel?.beginRefresh() + default:break + } return true } } diff --git a/XQMuse/Root/Home/VC/SearchVC.swift b/XQMuse/Root/Home/VC/SearchVC.swift index ab57b61..4da2fa7 100644 --- a/XQMuse/Root/Home/VC/SearchVC.swift +++ b/XQMuse/Root/Home/VC/SearchVC.swift @@ -15,12 +15,12 @@ static var array = NSMutableArray() static let cacheSearchPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("search") - static func readList()->NSMutableArray{ + static func readList(_ serchType:SearchVC.SearchType)->NSMutableArray{ if !FileManager.default.fileExists(atPath: cacheSearchPath.absoluteString){ try? FileManager.default.createDirectory(at: cacheSearchPath, withIntermediateDirectories: true) } - let searchPlistPath = cacheSearchPath.appendingPathComponent("search.plist") + let searchPlistPath = cacheSearchPath.appendingPathComponent(serchType.infoPlist) if let tempArray = NSMutableArray(contentsOfFile: searchPlistPath.droppedScheme()!.absoluteString){ array = tempArray } @@ -43,8 +43,8 @@ } } - static func writeToPath(){ - let searchPlistPath = cacheSearchPath.appendingPathComponent("search.plist") + static func writeToPath(_ serchType:SearchVC.SearchType){ + let searchPlistPath = cacheSearchPath.appendingPathComponent(serchType.infoPlist) array.write(to: searchPlistPath, atomically: true) } @@ -54,18 +54,48 @@ } class SearchVC: BaseVC { + + enum SearchType { + case muse //疗愈 + case course //课程 + + var infoPlist:String{ + switch self { + case .muse:return "searchmuse.plist" + case .course:return "searchcourse.plist" + } + } + } + @IBOutlet weak var cacheSearchCollectionView: UICollectionView! @IBOutlet weak var cacheSearchHei: NSLayoutConstraint! @IBOutlet weak var tf_search: UITextField! @IBOutlet weak var tableView: UITableView! - + @IBOutlet weak var view_hotKeyword: UIView! + @IBOutlet weak var label_hotSearhTitle: UILabel! + private var hotWords = [String]() + private var serchType:SearchType! + init(serchType:SearchType) { + super.init(nibName: nil, bundle: nil) + self.serchType = serchType + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func viewDidLoad() { super.viewDidLoad() title = "心泉·疗愈" - _ = SearchCache.readList() + view_hotKeyword.isHidden = serchType == .course + label_hotSearhTitle.isHidden = serchType == .course + + tf_search.placeholder = serchType == .course ? "搜索你喜欢的课程~":"请输入冥想搜索内容" + + _ = SearchCache.readList(serchType) cacheSearchCollectionView.reloadData() Services.getHotWordList().subscribe(onNext: {data in @@ -78,7 +108,7 @@ override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) - SearchCache.writeToPath() + SearchCache.writeToPath(serchType) } override func setUI() { @@ -139,7 +169,7 @@ tf_search.resignFirstResponder() SearchCache.writeToList(tf_search.text!) - let vc = SearchContentVC(content: tf_search.text!) + let vc = SearchContentVC(content: tf_search.text!, type: serchType) jq_push(vc: vc) } } diff --git a/XQMuse/Root/Home/VC/SearchVC.xib b/XQMuse/Root/Home/VC/SearchVC.xib index b820eed..28eae51 100644 --- a/XQMuse/Root/Home/VC/SearchVC.xib +++ b/XQMuse/Root/Home/VC/SearchVC.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> @@ -13,9 +13,11 @@ <connections> <outlet property="cacheSearchCollectionView" destination="hyl-1O-IfF" id="xLr-Xr-lJL"/> <outlet property="cacheSearchHei" destination="5YE-JH-tVc" id="ktS-NR-z7Y"/> + <outlet property="label_hotSearhTitle" destination="Mda-xm-ljU" id="sc7-eb-G0P"/> <outlet property="tableView" destination="RTG-Tg-r7D" id="pq2-Aa-jvq"/> <outlet property="tf_search" destination="Rbv-zT-iOu" id="Dxb-Mb-ezs"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> + <outlet property="view_hotKeyword" destination="U44-7x-wSJ" id="I6D-Jd-rhG"/> </connections> </placeholder> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> @@ -64,7 +66,7 @@ </connections> </button> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="历史搜索" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gQh-cp-6ml"> - <rect key="frame" x="24" y="156" width="69.333333333333329" height="16"/> + <rect key="frame" x="24" y="156" width="67.666666666666671" height="16"/> <constraints> <constraint firstAttribute="height" constant="16" id="qdH-3T-iMm"/> </constraints> @@ -86,7 +88,7 @@ </collectionViewFlowLayout> </collectionView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="热门搜索" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mda-xm-ljU"> - <rect key="frame" x="24" y="245.66666666666666" width="69.333333333333329" height="15.999999999999972"/> + <rect key="frame" x="24" y="245.66666666666666" width="67.666666666666671" height="15.999999999999972"/> <constraints> <constraint firstAttribute="height" constant="16" id="WZa-u0-Fx3"/> </constraints> diff --git a/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift b/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift index 0cfff23..bfad3e9 100644 --- a/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift +++ b/XQMuse/Root/Home/View/PaymentOrderResultTopView.swift @@ -12,12 +12,14 @@ @IBOutlet weak var label_price: UILabel! @IBOutlet weak var btn_lookCourse: UIButton! + private var courseId:Int! override func awakeFromNib() { super.awakeFromNib() } - func setPrice(_ price:Double){ + func setPrice(courseId:Int,price:Double){ + self.courseId = courseId label_price.text = "\(price.jq_formatFloat)" } @@ -26,8 +28,8 @@ } @IBAction func lookCourseAction(_ sender: UIButton) { -// let vc = HomeItemDetailVC() -// JQ_currentViewController().jq_push(vc: vc) + let vc = CourseDetialVC(courseId: courseId) + JQ_currentViewController().jq_push(vc: vc) } diff --git a/XQMuse/Root/Login/LoginVC.swift b/XQMuse/Root/Login/LoginVC.swift index 68f2464..f9d87a4 100644 --- a/XQMuse/Root/Login/LoginVC.swift +++ b/XQMuse/Root/Login/LoginVC.swift @@ -57,7 +57,8 @@ @IBOutlet weak var btn_login: UIButton! @IBOutlet weak var btn_sendCode: UIButton! @IBOutlet weak var btn_isRead: UIButton! - + @IBOutlet weak var btn_wechat: UIButton! + private var viewModel = LoginViewModel() private let unlineImageView = UIImageView(image: UIImage(named: "icon_unline")) @@ -117,6 +118,8 @@ override func setUI() { + btn_wechat.isHidden = !WXApi.isWXAppInstalled() + navigationItem.leftBarButtonItem = UIBarButtonItem.jq_creat(image: nav_back_img, target: self, alignment:.left, action: #selector(backAction)).item btn_eye.isSelected = true @@ -164,7 +167,7 @@ guard !viewModel.loginPhone.value.isEmpty else {alert(msg: "请输入手机号");return} guard viewModel.loginPhone.value.jq_isPhone else {alert(msg: "请输入正确手机号");return} - Services.sendCode(type: .codeLogin).subscribe(onNext: {data in + Services.sendCode(phone:tf_phone.text!,type: .codeLogin).subscribe(onNext: {data in if let _ = data.data{ sender.jq_openCountDown(60, defultTitle: "发送验证码") { sender.titleLabel?.font = UIFont.systemFont(ofSize: 12) @@ -229,7 +232,7 @@ guard btn_isRead.isSelected else { alertError(msg: "请阅读并同意《用户注册协议》和《用户隐私协议》");return } - //todo + WeChatTools.sendAuthRequest() } @IBAction func loginByAppleAction(_ sender: UIButton) { diff --git a/XQMuse/Root/Login/LoginVC.xib b/XQMuse/Root/Login/LoginVC.xib index 15a5f29..ff9ac7c 100644 --- a/XQMuse/Root/Login/LoginVC.xib +++ b/XQMuse/Root/Login/LoginVC.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -17,6 +17,7 @@ <outlet property="btn_loginByPwd" destination="Ec8-sg-6R6" id="Y2P-aU-5lk"/> <outlet property="btn_register" destination="k1h-gO-9vj" id="AxQ-S9-3oN"/> <outlet property="btn_sendCode" destination="cUd-a4-RTn" id="n26-3e-uaI"/> + <outlet property="btn_wechat" destination="2Fj-Y0-NYp" id="M7L-LL-Se8"/> <outlet property="tf_content" destination="x0Y-XG-Xsv" id="GVf-UU-yCe"/> <outlet property="tf_phone" destination="9rD-4T-K6b" id="ynF-y5-xQD"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> @@ -35,7 +36,7 @@ <rect key="frame" x="0.0" y="248" width="393" height="604"/> <subviews> <button opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ec8-sg-6R6"> - <rect key="frame" x="23" y="22" width="74" height="22"/> + <rect key="frame" x="23" y="22" width="72" height="22"/> <constraints> <constraint firstAttribute="height" constant="22" id="eDS-Kw-vhp"/> </constraints> @@ -49,7 +50,7 @@ </connections> </button> <button opaque="NO" tag="11" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Afa-A3-2l1"> - <rect key="frame" x="125" y="22" width="92" height="22"/> + <rect key="frame" x="123" y="22" width="90" height="22"/> <constraints> <constraint firstAttribute="height" constant="22" id="na9-Gz-KYA"/> </constraints> @@ -66,7 +67,7 @@ <rect key="frame" x="31" y="118" width="24" height="24"/> </imageView> <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入您的手机号" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="9rD-4T-K6b" customClass="QMUITextField"> - <rect key="frame" x="66" y="120.6666666666667" width="114.33333333333331" height="18.666666666666671"/> + <rect key="frame" x="66" y="120.6666666666667" width="111.33333333333331" height="18.666666666666671"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits" keyboardType="numberPad"/> <userDefinedRuntimeAttributes> @@ -86,7 +87,7 @@ <rect key="frame" x="31" y="187" width="24" height="24"/> </imageView> <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入密码" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="x0Y-XG-Xsv" customClass="QMUITextField"> - <rect key="frame" x="66" y="189.66666666666669" width="71.666666666666686" height="18.666666666666657"/> + <rect key="frame" x="66" y="189.66666666666669" width="69.666666666666686" height="18.666666666666657"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits"/> </textField> @@ -132,7 +133,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EBj-o7-Mca"> - <rect key="frame" x="31" y="357" width="56" height="27"/> + <rect key="frame" x="31" y="357" width="54" height="27"/> <fontDescription key="fontDescription" type="system" pointSize="12"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="忘记密码?"> @@ -143,7 +144,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k1h-gO-9vj"> - <rect key="frame" x="312" y="357" width="50" height="27"/> + <rect key="frame" x="314" y="357" width="48" height="27"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="注册账号"> @@ -175,13 +176,13 @@ </subviews> </stackView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="第三方登录" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Rg-d1-NE7"> - <rect key="frame" x="166" y="441.66666666666663" width="61.333333333333343" height="14.333333333333314"/> + <rect key="frame" x="166.66666666666666" y="441.66666666666663" width="59.666666666666657" height="14.333333333333314"/> <fontDescription key="fontDescription" type="system" pointSize="12"/> <color key="textColor" red="0.5725490196078431" green="0.56862745098039214" blue="0.56862745098039214" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cUd-a4-RTn"> - <rect key="frame" x="293" y="184.66666666666669" width="72" height="29"/> + <rect key="frame" x="295" y="184.66666666666669" width="70" height="29"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="发送验证码"> @@ -205,13 +206,13 @@ </connections> </button> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我已阅读并同意" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="esZ-HR-QwQ"> - <rect key="frame" x="57" y="240" width="86" height="14.333333333333343"/> + <rect key="frame" x="57.000000000000007" y="240" width="83.666666666666686" height="14.333333333333343"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MNJ-Ag-zfE"> - <rect key="frame" x="148" y="233.66666666666669" width="87" height="27"/> + <rect key="frame" x="145.66666666666666" y="233.66666666666669" width="84" height="27"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="《用户注册协议》"> @@ -222,7 +223,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eq2-Wp-Yza"> - <rect key="frame" x="243" y="233.66666666666669" width="87" height="27"/> + <rect key="frame" x="237.66666666666663" y="233.66666666666669" width="84" height="27"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" title="《用户隐私协议》"> diff --git a/XQMuse/Root/Login/VC/ForgotPasswordInputCodeVC.swift b/XQMuse/Root/Login/VC/ForgotPasswordInputCodeVC.swift index 1b6cc8a..651b436 100644 --- a/XQMuse/Root/Login/VC/ForgotPasswordInputCodeVC.swift +++ b/XQMuse/Root/Login/VC/ForgotPasswordInputCodeVC.swift @@ -94,7 +94,7 @@ private func sendCode(){ - Services.sendCode(type: .forgetPwd).subscribe(onNext: { _ in + Services.sendCode(phone:phone,type: .forgetPwd).subscribe(onNext: { _ in self.starTimer() }).disposed(by: disposeBag) } diff --git a/XQMuse/Root/Login/VC/RegisterVC.swift b/XQMuse/Root/Login/VC/RegisterVC.swift index e9cca1f..5b3f4d0 100644 --- a/XQMuse/Root/Login/VC/RegisterVC.swift +++ b/XQMuse/Root/Login/VC/RegisterVC.swift @@ -89,8 +89,8 @@ guard !viewModel.phone.value.isEmpty else {alertError(msg: "请输入手机号");return} guard viewModel.phone.value.jq_isPhone else {alertError(msg: "请输入正确手机号");return} - Services.sendCode(type: .register).subscribe(onNext: {data in - if let _ = data.data{ + Services.sendCode(phone:viewModel.phone.value,type: .register).subscribe(onNext: {data in + if data.code == 200{ sender.jq_openCountDown(60, defultTitle: "发送验证码") { sender.titleLabel?.font = UIFont.systemFont(ofSize: 12) sender.setTitleColor(.black.withAlphaComponent(0.3), for: .normal) diff --git a/XQMuse/Root/Login/VC/UpdatePhoneVC.swift b/XQMuse/Root/Login/VC/UpdatePhoneVC.swift index a8daffc..7aecee0 100644 --- a/XQMuse/Root/Login/VC/UpdatePhoneVC.swift +++ b/XQMuse/Root/Login/VC/UpdatePhoneVC.swift @@ -38,7 +38,7 @@ alertError(msg: "请输入正确的手机号");return } - Services.sendCode(type: .threePlantform).subscribe(onNext: {data in + Services.sendCode(phone:tf_phone.text!,type: .threePlantform).subscribe(onNext: {data in if let _ = data.data{ sender.jq_openCountDown(60, defultTitle: "发送验证码") { sender.titleLabel?.font = UIFont.systemFont(ofSize: 12) diff --git a/XQMuse/Root/Me/MeVC.xib b/XQMuse/Root/Me/MeVC.xib index 0ab640c..b146618 100644 --- a/XQMuse/Root/Me/MeVC.xib +++ b/XQMuse/Root/Me/MeVC.xib @@ -276,8 +276,12 @@ <color key="textColor" red="0.13725490196078433" green="0.13725490196078433" blue="0.13725490196078433" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> </label> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_vip_level" translatesAutoresizingMaskIntoConstraints="NO" id="dut-7H-aMv"> - <rect key="frame" x="70.333333333333314" y="11.333333333333373" width="95.666666666666686" height="27.666666666666671"/> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_vip_level" translatesAutoresizingMaskIntoConstraints="NO" id="dut-7H-aMv"> + <rect key="frame" x="70.333333333333343" y="11.333333333333373" width="95.333333333333343" height="27.666666666666671"/> + <constraints> + <constraint firstAttribute="width" constant="95.5" id="9QQ-4F-lHB"/> + <constraint firstAttribute="height" constant="27.5" id="vly-QN-iWG"/> + </constraints> </imageView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="查看详情" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="flg-Hv-HHC"> <rect key="frame" x="266.66666666666669" y="18.666666666666742" width="44" height="13.333333333333336"/> diff --git a/XQMuse/Root/Me/VC/AddBankInfoVC.swift b/XQMuse/Root/Me/VC/AddBankInfoVC.swift index 772b321..0707948 100644 --- a/XQMuse/Root/Me/VC/AddBankInfoVC.swift +++ b/XQMuse/Root/Me/VC/AddBankInfoVC.swift @@ -119,7 +119,7 @@ alertError(msg: "请输入手机号");return } - Services.sendCode(type: .addBank).subscribe(onNext: {_ in + Services.sendCode(phone:tf_phone.text!,type: .addBank).subscribe(onNext: {_ in sender.jq_openCountDown(60, defultTitle: "发送验证码") { sender.titleLabel?.font = UIFont.systemFont(ofSize: 12) sender.setTitleColor(.black.withAlphaComponent(0.3), for: .normal) diff --git a/XQMuse/Root/Me/VC/BindPhone_2_VC.swift b/XQMuse/Root/Me/VC/BindPhone_2_VC.swift index 1a9f5b2..d334cca 100644 --- a/XQMuse/Root/Me/VC/BindPhone_2_VC.swift +++ b/XQMuse/Root/Me/VC/BindPhone_2_VC.swift @@ -20,7 +20,7 @@ } @IBAction func sendCodeAction(_ sender: UIButton) { - Services.sendCode(type: .exchangePhone).subscribe(onNext: { data in + Services.sendCode(phone:tf_phone.text!,type: .exchangePhone).subscribe(onNext: { data in if let _ = data.data{ sender.jq_openCountDown(60, defultTitle: "发送验证码") { sender.titleLabel?.font = UIFont.systemFont(ofSize: 12) diff --git a/XQMuse/Root/Network/Models.swift b/XQMuse/Root/Network/Models.swift index 7f6b751..9bfb397 100644 --- a/XQMuse/Root/Network/Models.swift +++ b/XQMuse/Root/Network/Models.swift @@ -116,6 +116,7 @@ var tutorAudioUrl: String = "" var virtualLearnedNum: Int = 0 var favorite:ConditionType = .no // 是否收藏:1:是 2:否 + var meditationMusicList = [String]() } struct CommentModel:HandyJSON{ @@ -157,6 +158,7 @@ var id = 0 var imageUrl = "" var name = "" + var courseId:String? } struct CourseModel:HandyJSON{ @@ -184,6 +186,7 @@ var sortNum: Int = 0 var tutor:String = "" var wxQrCode:String = "" + var isCollect:ConditionType = .no // 是否收藏:1:是 2:否 var list2 = [CourseModel]() var list = [CourseItemModel]() @@ -457,7 +460,7 @@ struct ResponseUserAnswerModel:HandyJSON{ - var tagsId = "" //问题二 多个tagId使用英文逗号拼接字符串 + var tagIds = "" //问题二 多个tagId使用英文逗号拼接字符串 var userAnswerOneDTOList = [ResponseUserAnswerDTOModel]() } diff --git a/XQMuse/Root/Network/NetworkRequest.swift b/XQMuse/Root/Network/NetworkRequest.swift index d316951..5cdea49 100644 --- a/XQMuse/Root/Network/NetworkRequest.swift +++ b/XQMuse/Root/Network/NetworkRequest.swift @@ -193,10 +193,10 @@ if progress {showHUD()} var headers = HTTPHeaders() -// if let token = UserViewModel.getToken(){ -// headers.add(name: "Authorization", value: "Bearer" + " " + token) -// LogInfo("USER_token:Bearer \(token)") -// } + if let token = UserViewModel.getLoginInfo()?.accessToken{ + headers.add(name: "Authorization", value: "Bearer" + " " + token) + LogInfo("USER_token:Bearer \(token)") + } if encoding is JSONEncoding { headers.add(name: "Content-Type", value: "application/json;charset=UTF-8") @@ -206,11 +206,11 @@ if encoding != nil { newEncoding = encoding! } else { - #if DEBUG - newEncoding = URLEncoding.queryString - #else +// #if DEBUG +// newEncoding = URLEncoding.queryString +// #else newEncoding = method == .post ? URLEncoding.httpBody : URLEncoding.queryString - #endif +// #endif } sharedSessionManager.request(params.url.absoluteString, method: method, parameters:params.done(), encoding: newEncoding, headers:headers).validate().responseData{response in @@ -237,16 +237,7 @@ if let next = BaseResponse<T>.deserialize(from: jsonString){ switch next.code{ case 200:ob.onNext(next) - case 501: -// CommonAlertView.show(title: "提示", content: next.msg,isSingle: true) { _ in -// -// } - ob.onError(NetRequestError.InvaildSession) - case 600: - if !ignoreAlert{ - alertError(msg: "登录失效,请重新登录");ob.onError(NetRequestError.InvaildSession) - } -// app.needLogin() + case 401:ob.onError(NetRequestError.InvaildSession) default: if !ignoreAlert{ alertError(msg: "\(next.msg)") diff --git a/XQMuse/Root/Network/Services.swift b/XQMuse/Root/Network/Services.swift index 951f44f..a127156 100644 --- a/XQMuse/Root/Network/Services.swift +++ b/XQMuse/Root/Network/Services.swift @@ -13,7 +13,8 @@ import CoreLocation #if DEBUG -let All_Url = "https://mock.apipost.net/mock/31b303c60464000" +let All_Url = "http://192.168.110.64:9000" +//let All_Url = "https://mock.apipost.net/mock/31b303c60464000" #else let All_Url = "http://" //正式地址 #endif @@ -41,7 +42,7 @@ .append(key: "captcha",value:content) .append(key: "apipost_id", value: "246d780670e265") } - return NetworkRequest.request(params: params, method: .post, progress: true) + return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding(), progress: true) } @@ -50,6 +51,17 @@ params.interface(url: "/auth/app/appleLogin") .append(key: "appleId", value: appleId) .append(key: "apipost_id", value: "246d780670e264") + return NetworkRequest.request(params: params, method: .post, progress: true) + } + + class func loginByWechat(headImgUrl:String,nickname:String,sex:Int,wxOpenId:String)->Observable<BaseResponse<LoginUserInfoModel>>{ + let params = ParamsAppender.build(url: All_Url) + params.interface(url: "/auth/app/appleLogin") + .append(key: "headImgUrl", value: headImgUrl) + .append(key: "nickname", value: nickname) + .append(key: "sex", value: sex) + .append(key: "wxOpenId", value: wxOpenId) + .append(key: "apipost_id", value: "246d7806b0e26c") return NetworkRequest.request(params: params, method: .post, progress: true) } @@ -68,10 +80,11 @@ } /// 发送验证码 - class func sendCode(type:SendCodeType)->Observable<BaseResponse<SimpleModel>>{ + class func sendCode(phone:String,type:SendCodeType)->Observable<BaseResponse<SimpleModel>>{ let params = ParamsAppender.build(url: All_Url) params.interface(url: "/auth/app/sendCaptchaCode") .append(key: "type", value: type.rawValue) + .append(key: "cellPhone", value: phone) .append(key: "apipost_id", value: "246d7806b0e269") return NetworkRequest.request(params: params, method: .get, progress: true) } @@ -85,7 +98,7 @@ .append(key: "inviteUserId", value: inviteUserId) .append(key: "password", value: password.jq_md5String().uppercased()) .append(key: "apipost_id", value: "246d7806b0e268") - return NetworkRequest.request(params: params, method: .post, progress: true) + return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding(), progress: true) } /// 找回密码验证手机号 @@ -201,7 +214,7 @@ params.interface(url: "/meditation/client/meditation/home/favorite") .append(key: "id", value: id) .append(key: "apipost_id", value: "2aa4e14ab0e159") - return NetworkRequest.request(params: params, method: .get, progress: true) + return NetworkRequest.request(params: params, method: .post, progress: false) } /// 获取热词 @@ -215,12 +228,12 @@ /// 搜索 class func search(text:String,page:Int,pageSize:Int = 20)->Observable<BaseResponse<BaseResponseList<MeditationModel>>>{ let params = ParamsAppender.build(url: All_Url) - params.interface(url: "/meditation/client/meditation/home/getHotWordList") + params.interface(url: "/meditation/client/meditation/home/search") .append(key: "condition", value: text) .append(key: "pageCurr", value: page) .append(key: "pageSize", value: pageSize) .append(key: "apipost_id", value: "25c3e3d0b0e160") - return NetworkRequest.request(params: params, method: .get, progress: false) + return NetworkRequest.request(params: params, method: .post, progress: false) } } @@ -372,7 +385,7 @@ let params = ParamsAppender.build(url: All_Url) params.interface(url: "/user/client/app-user/getTagList") .append(key: "apipost_id", value: "25c3dab9f0e024") - return NetworkRequest.request(params: params, method: .post, progress: true) + return NetworkRequest.request(params: params, method: .get, progress: true) } class func saveUserAnswers(_ model:ResponseUserAnswerModel)->Observable<BaseResponse<SimpleModel>>{ @@ -380,7 +393,7 @@ params.interface(url: "/user/client/app-user/saveUserAnswers") .append(dic: model.toJSON()!) .append(key: "apipost_id", value: "25c3dab9f0e025") - return NetworkRequest.request(params: params, method: .post, progress: true) + return NetworkRequest.request(params: params, method: .post,encoding: JSONEncoding(), progress: true) } /// 冥想等级 @@ -607,6 +620,12 @@ return NetworkRequest.request(params: params, method: .post, progress: false) } + class func addQuestion(content:String,meditationId:Int)->Observable<BaseResponse<SimpleModel>>{ + let params = ParamsAppender.build(url: All_Url) + .interface(url: "/meditation/client/meditation/home/addQuestion") + return NetworkRequest.request(params: params, method: .post, progress: true) + } + /// 问题列表 class func commonQuestionDetailBy(id:Int)->Observable<BaseResponse<CommonQuestionModel>>{ let params = ParamsAppender.build(url: All_Url) diff --git a/XQMuse/Root/Other/View/CommonBannerView.swift b/XQMuse/Root/Other/View/CommonBannerView.swift index fad18d3..107cf96 100644 --- a/XQMuse/Root/Other/View/CommonBannerView.swift +++ b/XQMuse/Root/Other/View/CommonBannerView.swift @@ -13,6 +13,7 @@ var name:String? //名称 var resource:String? //数据源:URL等 var mediaType:CommonBannerView.MediaType? + var courseId:String? } class CommonBannerView: UIView, UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout { diff --git a/XQMuse/Root/Pavilion/VC/PavilionDetailVC.xib b/XQMuse/Root/Pavilion/VC/PavilionDetailVC.xib index 07509f6..cf9d7a5 100644 --- a/XQMuse/Root/Pavilion/VC/PavilionDetailVC.xib +++ b/XQMuse/Root/Pavilion/VC/PavilionDetailVC.xib @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina6_12" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/> <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -40,7 +40,7 @@ </constraints> </view> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="心泉疗愈馆" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ej2-gY-nmo"> - <rect key="frame" x="26.666666666666671" y="346" width="102.00000000000001" height="24"/> + <rect key="frame" x="26.666666666666671" y="346" width="96" height="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="20"/> <color key="textColor" red="0.039215686274509803" green="0.25882352941176467" blue="0.074509803921568626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> @@ -144,7 +144,7 @@ </subviews> </stackView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="简介" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dmh-Sc-k0l"> - <rect key="frame" x="26.666666666666671" y="484.33333333333331" width="41" height="24"/> + <rect key="frame" x="26.666666666666668" y="484.33333333333331" width="38.333333333333329" height="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="20"/> <color key="textColor" red="0.039215686270000001" green="0.25882352939999997" blue="0.074509803920000006" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <nil key="highlightedColor"/> diff --git a/XQMuse/Root/Pavilion/VC/PavilionSearchVC.swift b/XQMuse/Root/Pavilion/VC/PavilionSearchVC.swift index 32f3d82..5e8f3b7 100644 --- a/XQMuse/Root/Pavilion/VC/PavilionSearchVC.swift +++ b/XQMuse/Root/Pavilion/VC/PavilionSearchVC.swift @@ -63,8 +63,8 @@ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let model = viewModel!.dataSource.value!.list[indexPath.row] let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_PavilionItemCell", for: indexPath) as! PavilionItemCell - cell.backgroundColor = .jq_randomColor cell.jq_cornerRadius = 16 + cell.backgroundColor = .white cell.setPavilionDetailModel(model) return cell } diff --git a/XQMuse/Root/Plans/PlanGuideVC.swift b/XQMuse/Root/Plans/PlanGuideVC.swift index 3d0d788..21e8199 100644 --- a/XQMuse/Root/Plans/PlanGuideVC.swift +++ b/XQMuse/Root/Plans/PlanGuideVC.swift @@ -11,6 +11,8 @@ let PlantGuideQuit_Noti = Notification.Name.init(rawValue: "PlantGuideQuit_Noti") +let backgroundVoiceUrl = "https://xqgwzh.obs.cn-south-1.myhuaweicloud.com/question/backgroundQuestion.wav" + class PlanGuideVC: BaseVC { @IBOutlet weak var view_gradient: UIView! @@ -19,6 +21,8 @@ @IBOutlet weak var label_subTitle: UILabel! @IBOutlet weak var label_info: UILabel! @IBOutlet weak var btn_custom: UIButton! + + private let masterPlayer = AudioPlayer.getSharedInstance() private lazy var player:AVPlayer = { let bgPath = Bundle.main.url(forResource: "bg_movie", withExtension: "mov") @@ -35,7 +39,7 @@ override func viewDidLoad() { super.viewDidLoad() - + masterPlayer.playBGMAt(firstPlayIndex: 0, model: MeditationModel(backgroundUrl:backgroundVoiceUrl), delegate: self) } override func viewWillAppear(_ animated: Bool) { @@ -84,11 +88,11 @@ self?.player.play() } - NotificationCenter.default.rx.notification(PlantGuideQuit_Noti).take(until: self.rx.deallocated).subscribe(onNext: {data in + NotificationCenter.default.rx.notification(PlantGuideQuit_Noti).take(until: self.rx.deallocated).subscribe(onNext: {[weak self]data in if data.object as? Bool == true{ } - self.dismiss(animated: true) + self?.dismiss(animated: true) }).disposed(by: disposeBag) } @@ -101,13 +105,13 @@ } @IBAction func customAction(_ sender: UIButton) { - PlanGuidePromptView.show { type in + PlanGuidePromptView.show {[weak self] type in switch type { case .seeOther: let vc = PlanGuide_1_VC() - self.jq_push(vc: vc) + self?.jq_push(vc: vc) case .toSeting: - self.dismiss(animated: true) { + self?.dismiss(animated: true) { let vc = BackgroundVoiceVC() vc.hidesBottomBarWhenPushed = true JQ_currentNavigationController().pushViewController(vc) @@ -115,4 +119,15 @@ } } } + + deinit{ + masterPlayer.clean() + } +} + +extension PlanGuideVC:PayMusicDelegate{ + func playState(_ state: PlayMusicState) { + + } + } diff --git a/XQMuse/Root/Plans/PlanGuide_2_VC.swift b/XQMuse/Root/Plans/PlanGuide_2_VC.swift index 84a14b1..6b5561a 100644 --- a/XQMuse/Root/Plans/PlanGuide_2_VC.swift +++ b/XQMuse/Root/Plans/PlanGuide_2_VC.swift @@ -19,7 +19,7 @@ @IBOutlet weak var btn_OnceInAWel: UIButton! private var questions = [String]() - private var questionIndex = -1 + private var questionIndex = 0 private var responseUserAnswerModel = ResponseUserAnswerModel() diff --git a/XQMuse/Root/Plans/PlanGuide_3_VC.swift b/XQMuse/Root/Plans/PlanGuide_3_VC.swift index 6ecd191..3ee6853 100644 --- a/XQMuse/Root/Plans/PlanGuide_3_VC.swift +++ b/XQMuse/Root/Plans/PlanGuide_3_VC.swift @@ -57,7 +57,7 @@ } @IBAction func nextAction(_ sender: UIButton) { - responseUserAnswerModel.tagsId = selectModels.map({"\($0.id)"}).joined(separator: ",") + responseUserAnswerModel.tagIds = selectModels.map({"\($0.id)"}).joined(separator: ",") Services.saveUserAnswers(responseUserAnswerModel).subscribe(onNext: { data in NotificationCenter.default.post(name: PlantGuideQuit_Noti, object: true) }).disposed(by: disposeBag) diff --git a/XQMuse/Root/ViewModel/RefreshModel.swift b/XQMuse/Root/ViewModel/RefreshModel.swift index 6b77ca9..dc2ae1e 100644 --- a/XQMuse/Root/ViewModel/RefreshModel.swift +++ b/XQMuse/Root/ViewModel/RefreshModel.swift @@ -181,7 +181,7 @@ var new = self.dataSource.value?.list ?? [] new.append(contentsOf: data.data?.list ?? []) var model = self.dataSource.value - model!.list = new + model?.list = new self.dataSource.accept(model) if data.data?.list.count == 0{ self.refreshSubject.onNext(.completedLoadWithNoMoreData) diff --git a/XQMuse/SceneDelegate.swift b/XQMuse/SceneDelegate.swift index ade4cca..c5019cb 100644 --- a/XQMuse/SceneDelegate.swift +++ b/XQMuse/SceneDelegate.swift @@ -10,7 +10,7 @@ import JQTools import AuthenticationServices -class SceneDelegate: UIResponder, UIWindowSceneDelegate { +class SceneDelegate: UIResponder, UIWindowSceneDelegate, WXApiDelegate{ var window: UIWindow? @@ -71,6 +71,44 @@ } + func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { + + if URLContexts.first?.url.scheme == WeChatAPPID,let code = URLContexts.first?.url.jq_params?["code"]{ + DispatchQueue.main.async { + hiddenHUD() + let resp = SendAuthResp() + resp.code = code + WeChatTools.getAccessToken(resp) { model in + if let m = model{ + WeChatTools.getUserInfo(access_token: m.access_token, openId: m.openid) { userInfoModel in + if let u = userInfoModel{ + Services.loginByWechat(headImgUrl: u.headimgurl, nickname: u.nickname, sex: u.sex, wxOpenId: u.openid).subscribe(onNext: {data in + if let model = data.data{ + sceneDelegate?.loginSuccess() + JQ_currentViewController().dismiss(animated:true) + UserViewModel.saveLoginInfo(model) + + Services.getUserInfo().subscribe(onNext: {data in + if let model = data.data{ + UserViewModel.saveAvatarInfo(model) + } + }).disposed(by: JQ_disposeBag) + } + }).disposed(by: JQ_disposeBag) + }else{ + alertError(msg: "获取信息失败") + } + } + } + } + } + } + } + + func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { + WXApi.handleOpenUniversalLink(userActivity, delegate: self) + } + func sceneDidDisconnect(_ scene: UIScene) { // Called as the scene is being released by the system. // This occurs shortly after the scene enters the background, or when its session is discarded. @@ -99,6 +137,13 @@ // to restore the scene back to its current state. } + func onReq(_ req: BaseReq) { + + } + + func onResp(_ resp: BaseResp) { + + } } diff --git a/XQMuse/XQMuse.entitlements b/XQMuse/XQMuse.entitlements index a812db5..4252539 100644 --- a/XQMuse/XQMuse.entitlements +++ b/XQMuse/XQMuse.entitlements @@ -6,5 +6,9 @@ <array> <string>Default</string> </array> + <key>com.apple.developer.associated-domains</key> + <array> + <string>webcredentials:app.xqzhihui.com/app/</string> + </array> </dict> </plist> -- Gitblit v1.7.1