瀏覽代碼

1.2(2)打包上架

100Years 1 月之前
父節點
當前提交
0828defce4
共有 32 個文件被更改,包括 345 次插入373 次删除
  1. 4 8
      AIRingtone.xcodeproj/project.pbxproj
  2. 1 1
      AIRingtone.xcodeproj/xcshareddata/xcschemes/AIRingtone.xcscheme
  3. 二進制
      AIRingtone/Assets.xcassets/VIP/vip_icon_white.imageset/vip_icon_white@2x.png
  4. 二進制
      AIRingtone/Assets.xcassets/VIP/vip_icon_white.imageset/vip_icon_white@3x.png
  5. 6 16
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/TSAIPhotoChildVC.swift
  6. 1 0
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/View/TSAIPhotoImageCell.swift
  7. 1 1
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoVC.swift
  8. 2 6
      AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGeneralPicVC.swift
  9. 38 10
      AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGenneralPicVM.swift
  10. 8 23
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/TSTextGeneralPicVC.swift
  11. 0 1
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/VM/TSTextGeneralPicVM.swift
  12. 11 9
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptTextView.swift
  13. 3 9
      AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC.swift
  14. 4 16
      AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVM.swift
  15. 7 28
      AIRingtone/Business/TSAIRintoneVC/TSTextGeneralRintoneVC/TSTextGeneralRintoneVC.swift
  16. 5 23
      AIRingtone/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift
  17. 1 1
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingVC.swift
  18. 2 2
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift
  19. 30 29
      AIRingtone/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift
  20. 1 1
      AIRingtone/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift
  21. 2 9
      AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/TSThemeBrowseVC.swift
  22. 19 8
      AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/View/TSTBBtnView.swift
  23. 1 1
      AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/View/TSTSIslandView.swift
  24. 3 4
      AIRingtone/Business/TSThemeVC/TSThemeSetVC/TSThemeSetItemView.swift
  25. 7 12
      AIRingtone/Business/TSThemeVC/TSThemeSetVC/TSThemeSetVC.swift
  26. 18 4
      AIRingtone/Business/TSTutorialsVC/TSTutorialPopupVC.swift
  27. 126 45
      AIRingtone/Business/VIewTool/TSButton.swift
  28. 0 24
      AIRingtone/Business/VIewTool/TSViewTool.swift
  29. 5 0
      AIRingtone/Common/Ex/Notification+TSEx.swift
  30. 1 10
      AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseManager.swift
  31. 38 1
      AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseTool.swift
  32. 0 71
      AIRingtone/Common/Tool/WindowHelper.swift

+ 4 - 8
AIRingtone.xcodeproj/project.pbxproj

@@ -20,7 +20,6 @@
 		A80EDEE92D718CEA003CD332 /* TSFileManagerTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */; };
 		A80EDEE92D718CEA003CD332 /* TSFileManagerTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */; };
 		A80EDEEA2D718CEA003CD332 /* PaddedLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEBF2D718CEA003CD332 /* PaddedLabel.swift */; };
 		A80EDEEA2D718CEA003CD332 /* PaddedLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEBF2D718CEA003CD332 /* PaddedLabel.swift */; };
 		A80EDEEB2D718CEA003CD332 /* StreamPostRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDE6F2D718CEA003CD332 /* StreamPostRequest.swift */; };
 		A80EDEEB2D718CEA003CD332 /* StreamPostRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDE6F2D718CEA003CD332 /* StreamPostRequest.swift */; };
-		A80EDEEC2D718CEA003CD332 /* WindowHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEB92D718CEA003CD332 /* WindowHelper.swift */; };
 		A80EDEF52D718DEA003CD332 /* TSTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF32D718DEA003CD332 /* TSTabBarController.swift */; };
 		A80EDEF52D718DEA003CD332 /* TSTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF32D718DEA003CD332 /* TSTabBarController.swift */; };
 		A80EDF012D718DF1003CD332 /* TSBusinessWebVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF62D718DF1003CD332 /* TSBusinessWebVC.swift */; };
 		A80EDF012D718DF1003CD332 /* TSBusinessWebVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF62D718DF1003CD332 /* TSBusinessWebVC.swift */; };
 		A80EDF022D718DF1003CD332 /* TSSettingListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF92D718DF1003CD332 /* TSSettingListView.swift */; };
 		A80EDF022D718DF1003CD332 /* TSSettingListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDEF92D718DF1003CD332 /* TSSettingListView.swift */; };
@@ -132,7 +131,6 @@
 		A80EDE6F2D718CEA003CD332 /* StreamPostRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamPostRequest.swift; sourceTree = "<group>"; };
 		A80EDE6F2D718CEA003CD332 /* StreamPostRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamPostRequest.swift; sourceTree = "<group>"; };
 		A80EDEB32D718CEA003CD332 /* TSRandomTextPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRandomTextPicker.swift; sourceTree = "<group>"; };
 		A80EDEB32D718CEA003CD332 /* TSRandomTextPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRandomTextPicker.swift; sourceTree = "<group>"; };
 		A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSFileManagerTool.swift; sourceTree = "<group>"; };
 		A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSFileManagerTool.swift; sourceTree = "<group>"; };
-		A80EDEB92D718CEA003CD332 /* WindowHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowHelper.swift; sourceTree = "<group>"; };
 		A80EDEBB2D718CEA003CD332 /* TSPhotoPickerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPhotoPickerManager.swift; sourceTree = "<group>"; };
 		A80EDEBB2D718CEA003CD332 /* TSPhotoPickerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPhotoPickerManager.swift; sourceTree = "<group>"; };
 		A80EDEBF2D718CEA003CD332 /* PaddedLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddedLabel.swift; sourceTree = "<group>"; };
 		A80EDEBF2D718CEA003CD332 /* PaddedLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddedLabel.swift; sourceTree = "<group>"; };
 		A80EDEF32D718DEA003CD332 /* TSTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTabBarController.swift; sourceTree = "<group>"; };
 		A80EDEF32D718DEA003CD332 /* TSTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTabBarController.swift; sourceTree = "<group>"; };
@@ -362,7 +360,6 @@
 				A80EDEB32D718CEA003CD332 /* TSRandomTextPicker.swift */,
 				A80EDEB32D718CEA003CD332 /* TSRandomTextPicker.swift */,
 				A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */,
 				A80EDEB62D718CEA003CD332 /* TSFileManagerTool.swift */,
 				A868A8EE2D77040F00F6D884 /* TSLoadingAnimation.swift */,
 				A868A8EE2D77040F00F6D884 /* TSLoadingAnimation.swift */,
-				A80EDEB92D718CEA003CD332 /* WindowHelper.swift */,
 			);
 			);
 			path = Tool;
 			path = Tool;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1084,7 +1081,6 @@
 				A8272E9D2D7A8F4600F1C814 /* TSGeneralRintoneVC+Event.swift in Sources */,
 				A8272E9D2D7A8F4600F1C814 /* TSGeneralRintoneVC+Event.swift in Sources */,
 				A80EDF072D718DF1003CD332 /* TSSetingViewModel.swift in Sources */,
 				A80EDF072D718DF1003CD332 /* TSSetingViewModel.swift in Sources */,
 				A868A8C72D76A44500F6D884 /* TSThemeSetVC.swift in Sources */,
 				A868A8C72D76A44500F6D884 /* TSThemeSetVC.swift in Sources */,
-				A80EDEEC2D718CEA003CD332 /* WindowHelper.swift in Sources */,
 				A868A8D02D76D03900F6D884 /* TSRingToneCellView.swift in Sources */,
 				A868A8D02D76D03900F6D884 /* TSRingToneCellView.swift in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1111,7 +1107,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 3;
+				CURRENT_PROJECT_VERSION = 2;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				GENERATE_INFOPLIST_FILE = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
@@ -1130,7 +1126,7 @@
 					"$(inherited)",
 					"$(inherited)",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 				);
 				);
-				MARKETING_VERSION = 1.1;
+				MARKETING_VERSION = 1.2;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -1153,7 +1149,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 3;
+				CURRENT_PROJECT_VERSION = 2;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				GENERATE_INFOPLIST_FILE = YES;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
@@ -1172,7 +1168,7 @@
 					"$(inherited)",
 					"$(inherited)",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 				);
 				);
-				MARKETING_VERSION = 1.1;
+				MARKETING_VERSION = 1.2;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

+ 1 - 1
AIRingtone.xcodeproj/xcshareddata/xcschemes/AIRingtone.xcscheme

@@ -31,7 +31,7 @@
       shouldAutocreateTestPlan = "YES">
       shouldAutocreateTestPlan = "YES">
    </TestAction>
    </TestAction>
    <LaunchAction
    <LaunchAction
-      buildConfiguration = "Release"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
       launchStyle = "0"

二進制
AIRingtone/Assets.xcassets/VIP/vip_icon_white.imageset/vip_icon_white@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/vip_icon_white.imageset/vip_icon_white@3x.png


+ 6 - 16
AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/TSAIPhotoChildVC.swift

@@ -59,37 +59,31 @@ class TSAIPhotoChildVC: TSBaseVC {
         edgesForExtendedLayout = []
         edgesForExtendedLayout = []
         setNavBarViewHidden(true)
         setNavBarViewHidden(true)
         contentView.addSubview(collectionComponent.collectionView)
         contentView.addSubview(collectionComponent.collectionView)
-        reloadView()
     }
     }
     
     
     func reloadView(){
     func reloadView(){
-        collectionComponent.clear()
-        collectionComponent.reloadView(with:vm.colDataArray)
+        kExecuteOnMainThread {
+            self.collectionComponent.clear()
+            self.collectionComponent.reloadView(with:self.vm.colDataArray)
+        }
     }
     }
 
 
     override func viewDidLayoutSubviews() {
     override func viewDidLayoutSubviews() {
         super.viewDidLayoutSubviews()
         super.viewDidLayoutSubviews()
-//        print("View did layout subviews")
         self.collectionComponent.collectionView.frame = self.view.bounds
         self.collectionComponent.collectionView.frame = self.view.bounds
-        self.collectionComponent.collectionView.reloadData()
     }
     }
     
     
-    
     override func dealThings() {
     override func dealThings() {
-    
         reloadView()
         reloadView()
-        
         NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { notification in
         NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { notification in
             if let userInfo = notification.userInfo as? [String: TSGennerateType], let myEnum = userInfo["TSGennerateType"] {
             if let userInfo = notification.userInfo as? [String: TSGennerateType], let myEnum = userInfo["TSGennerateType"] {
                 if myEnum == self.style {
                 if myEnum == self.style {
                     self.vm.setRecentData()
                     self.vm.setRecentData()
-                    self.collectionComponent.clear()
-                    self.collectionComponent.reloadView(with:self.vm.colDataArray)
+                    self.reloadView()
                 }
                 }
             }
             }
         }
         }
     }
     }
-    
 }
 }
 
 
 
 
@@ -106,11 +100,7 @@ extension TSAIPhotoChildVC: JXPagingViewListViewDelegate {
     func listView() -> UIView { view }
     func listView() -> UIView { view }
     
     
     func listWillAppear() {
     func listWillAppear() {
-//        print("\(title ?? ""):\(#function)")
-        if collectionComponent.collectionView.visibleCells.count == 0 {
-            debugPrint("遇到空了")
-            reloadView()
-        }
+        
     }
     }
 
 
     func listDidAppear() {
     func listDidAppear() {

+ 1 - 0
AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/View/TSAIPhotoImageCell.swift

@@ -59,6 +59,7 @@ class TSAIPhotoImageCell: TSBaseCollectionCell {
         super.renderView(with: object, component: component, attributes: attributes)
         super.renderView(with: object, component: component, attributes: attributes)
         if let itemModel = object as? TSColVVMItemModel{
         if let itemModel = object as? TSColVVMItemModel{
             if let generalPicModel = itemModel.dataModel as? TSActionInfoModel{
             if let generalPicModel = itemModel.dataModel as? TSActionInfoModel{
+                showImageView.image = nil
                 showImageView.setAsyncImage(urlString: generalPicModel.response.resultUrl,placeholder: kPlaceholderImage,contentMode: .scaleAspectFill)
                 showImageView.setAsyncImage(urlString: generalPicModel.response.resultUrl,placeholder: kPlaceholderImage,contentMode: .scaleAspectFill)
                 exampleView.isHidden = generalPicModel.modelType == .example ? false : true
                 exampleView.isHidden = generalPicModel.modelType == .example ? false : true
             }
             }

+ 1 - 1
AIRingtone/Business/TSAIPhotoVC/TSAIPhotoVC.swift

@@ -26,7 +26,7 @@ class TSAIPhotoVC: TSBaseVC {
     
     
     var tableHeaderViewHeight: CGFloat{
     var tableHeaderViewHeight: CGFloat{
         get{
         get{
-            generalPicVC.viewH <= 10 ? 543.0 : generalPicVC.viewH
+            generalPicVC.viewH <= 10 ? 542.0 : generalPicVC.viewH
         }
         }
     }
     }
     var headerInSectionHeight: Int = 44
     var headerInSectionHeight: Int = 44

+ 2 - 6
AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGeneralPicVC.swift

@@ -87,9 +87,7 @@ class TSGeneralPicVC: TSBottomAlertVC {
     
     
     override func clickAgainBtn() {
     override func clickAgainBtn() {
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
+        if kPurchaseToolShared.kJudgeVipFreeType(vipFreeNumType: vipFreeNumType, vc: self){ return }
         viewModel.creatImageEmoji(text:aiText)
         viewModel.creatImageEmoji(text:aiText)
     }
     }
     
     
@@ -116,9 +114,7 @@ class TSGeneralPicVC: TSBottomAlertVC {
 
 
     override func dealThings() {
     override func dealThings() {
         //判断 vip
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
+        if kPurchaseToolShared.kJudgeVipFreeType(vipFreeNumType: vipFreeNumType, vc: self){ return }
         viewModel.creatImageEmoji(text: self.aiText)
         viewModel.creatImageEmoji(text: self.aiText)
         viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
         viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
             guard let self = self else { return }
             guard let self = self else { return }

+ 38 - 10
AIRingtone/Business/TSAIPhotoVC/TSGeneralPicVC/TSGenneralPicVM.swift

@@ -11,6 +11,32 @@ import Alamofire
 let kTextPicW:Int = 800
 let kTextPicW:Int = 800
 let kTextPicH:Int = 1440
 let kTextPicH:Int = 1440
 
 
+
+
+let actionInfoDictPoster:[String:Any] = [
+    "actionType":"image_create",
+    "comments": "Success",
+    "costTime":9,
+    "createdTimestamp":1742183242,
+    "id":2449,
+    "percent":1,
+    "request":"{\"prompt\": \"Traditional Chinese ink painting style phoenix soaring through misty mountain peaks, dynamic black brushstrokes with crimson accents on rice paper texture, Googie architecture space station, 1950s atomic age aesthetic, curved aluminum panels, starburst patterns, glass dome observatory --edge_threshold 0.5 --atomic_age_style 0.8 --chrome_reflection 1.2\", \"width\": 800, \"height\": 1440, \"countryCode\": \"FR\"}",
+    "response": "{\"resultUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/4c946f78-b1e7-4ffe-ba18-fff26b10178c.png\"}",
+    "status":"success"
+]
+
+let actionInfoDictPhoto:[String:Any] = [
+    "actionType":"image_create",
+    "comments": "Success",
+    "costTime":7,
+    "createdTimestamp":1742183588,
+    "id":2450,
+    "percent":1,
+    "request":"{\"prompt\": \"Steampunk floating library with brass gears and clockwork mechanisms, leather-bound books flying through amber-lit fog, Victorian-era architecture blended with retro-futurism, retro anime cel-shading, 1980s Toei Animation style, bold black outlines, limited color palette (--color 1980s_anime), visible film grain --edge_threshold 0.4 --cel_shading 0.8, Retain the original stone size of the photo\", \"width\": 800, \"height\": 800, \"countryCode\": \"US\"}",
+    "response":"{\"resultUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/8b7fcac9-c691-4c3a-b497-401204fad3e9.png\"}",
+    "status":"success"
+]
+
 class TSGenneralPicVM {
 class TSGenneralPicVM {
     
     
     var creatRequest:Request?
     var creatRequest:Request?
@@ -22,21 +48,23 @@ class TSGenneralPicVM {
     var gennerateType:TSGennerateType = .poster
     var gennerateType:TSGennerateType = .poster
     var generatingProgress = 0
     var generatingProgress = 0
     
     
-    
-    
+//    //模拟数据
 //    func creatImageEmoji(text:String) {
 //    func creatImageEmoji(text:String) {
-//
 //        stateDatauPblished = (.start,nil)
 //        stateDatauPblished = (.start,nil)
 //        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
 //        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
-//        
-////        kDelayOnMainThread(2.0) {
-////            self.stateDatauPblished = (.failed("error?.localizedDescription" ?? ""),nil)
-////        }
 //
 //
-//        kDelayOnMainThread(2.0) {
-//            self.stateDatauPblished = (.success(nil),TSActionInfoModel())
+//        kDelayOnMainThread(0.2) {
+//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.5)),nil)
+//        }
+//
+//        kDelayOnMainThread(1.0) {
+//            if Bool.random() {
+//                let infoModel = TSActionInfoModel(JSON: self.gennerateType == .poster ? actionInfoDictPoster : actionInfoDictPhoto)
+//                self.stateDatauPblished = (.success(nil),infoModel)
+//            }else{
+//                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
+//            }
 //        }
 //        }
-//        
 //    }
 //    }
     
     
     //width 和 height 必须是 32 的倍数
     //width 和 height 必须是 32 的倍数

+ 8 - 23
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/TSTextGeneralPicVC.swift

@@ -43,7 +43,7 @@ class TSTextGeneralPicVC: TSBaseVC {
         photoStyleView.selectedValueBlock = { [weak self] index in
         photoStyleView.selectedValueBlock = { [weak self] index in
             guard let self = self else { return }
             guard let self = self else { return }
             viewModel.gennerateType = TSGennerateType(rawValue: index) ?? .poster
             viewModel.gennerateType = TSGennerateType(rawValue: index) ?? .poster
-            updateVipView()
+            creatBtnView.vipFreeNumType = vipFreeNumType
         }
         }
         photoStyleView.moreInfoBtn.addTarget(self, action: #selector(clickMoreInfoBtn), for: .touchUpInside)
         photoStyleView.moreInfoBtn.addTarget(self, action: #selector(clickMoreInfoBtn), for: .touchUpInside)
         return photoStyleView
         return photoStyleView
@@ -63,8 +63,9 @@ class TSTextGeneralPicVC: TSBaseVC {
     
     
     
     
     //###################################### Button ######################################
     //###################################### Button ######################################
-    lazy var creatBtnView:TSCreatBtnView  = {
-        let creatBtnView = TSCreatBtnView {[weak self] in
+    lazy var creatBtnView:TSAppBtnView  = {
+        let creatBtnView = TSAppBtnView()
+        creatBtnView.setUpButton(style: .generate, vipFreeNumType: .posetr) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             generateImage()
             generateImage()
         }
         }
@@ -72,6 +73,8 @@ class TSTextGeneralPicVC: TSBaseVC {
         return creatBtnView
         return creatBtnView
     }()
     }()
     
     
+    
+    
     //###################################### Generate History ######################################
     //###################################### Generate History ######################################
     lazy var historyTitleView: TSTGPTitleView = {
     lazy var historyTitleView: TSTGPTitleView = {
         let historyTitleView = TSTGPTitleView()
         let historyTitleView = TSTGPTitleView()
@@ -115,29 +118,17 @@ class TSTextGeneralPicVC: TSBaseVC {
     }
     }
     
     
     override func dealThings() {
     override func dealThings() {
-        self.updateVipView()
-        NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
-        self.creatBtnView.setVip(vip: true)
-    }
-    
-    @objc func vipInfoChanged() {
-        kExecuteOnMainThread {
-            self.updateVipView()
-        }
+
     }
     }
     
     
     func updateVipView() {
     func updateVipView() {
-//        self.creatBtnView.setVip(vip: kPurchaseDefault.generateVipShow(type: self.vipFreeNumType))
+        
     }
     }
     
     
     @objc func clickView() {
     @objc func clickView() {
         view.endEditing(true)
         view.endEditing(true)
     }
     }
 
 
-    
-    @objc func clickCollectionView() {
-        view.endEditing(true)
-    }
     @objc func clickMoreInfoBtn() {
     @objc func clickMoreInfoBtn() {
         kPresentModalVC(target: self, modelVC: TSTutorialPopupVC(selectedIndex: tutorialPopupSelectedIndex),transitionStyle: .crossDissolve)
         kPresentModalVC(target: self, modelVC: TSTutorialPopupVC(selectedIndex: tutorialPopupSelectedIndex),transitionStyle: .crossDissolve)
     }
     }
@@ -167,17 +158,11 @@ extension TSTextGeneralPicVC {
 extension TSTextGeneralPicVC {
 extension TSTextGeneralPicVC {
     func generateImage() {
     func generateImage() {
 
 
-        //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
-        
         let gennerateVC = TSGeneralPicVC(aiText: viewModel.prompt, gennerateType: viewModel.gennerateType)
         let gennerateVC = TSGeneralPicVC(aiText: viewModel.prompt, gennerateType: viewModel.gennerateType)
         {[weak self] model in
         {[weak self] model in
             guard let self = self else { return }
             guard let self = self else { return }
             model.request.promptSort = viewModel.promptText
             model.request.promptSort = viewModel.promptText
             viewModel.saveModel(model:model)
             viewModel.saveModel(model:model)
-            self.updateVipView()
             NotificationCenter.default.post(name: .kReloadUIData, object: nil, userInfo: ["TSGennerateType": viewModel.gennerateType])
             NotificationCenter.default.post(name: .kReloadUIData, object: nil, userInfo: ["TSGennerateType": viewModel.gennerateType])
         }
         }
         
         

+ 0 - 1
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/VM/TSTextGeneralPicVM.swift

@@ -26,7 +26,6 @@ enum TSGennerateType:Int,Equatable{
     case photo  = 1     //头像
     case photo  = 1     //头像
 }
 }
 
 
-
 class TSTextGeneralPicVM {
 class TSTextGeneralPicVM {
     
     
     //选择 prompt 类型组
     //选择 prompt 类型组

+ 11 - 9
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptTextView.swift

@@ -56,6 +56,7 @@ class TSPromptTextView : TSBaseView{
             backgroundColor: .clear
             backgroundColor: .clear
         )
         )
         customTextView.delegate = self
         customTextView.delegate = self
+        customTextView.returnKeyType = .done
         return customTextView
         return customTextView
     }()
     }()
     
     
@@ -191,24 +192,25 @@ class TSPromptTextView : TSBaseView{
 
 
     func getVipText()->String{
     func getVipText()->String{
         return "Generate"
         return "Generate"
-//        if kPurchaseDefault.isVip {
-//            return "Generate"
-//        }
-//        return "Generate (\(kPurchaseDefault.freeNum(type: .generatePic)))"
     }
     }
     
     
 }
 }
 
 
 extension TSPromptTextView: UITextViewDelegate{
 extension TSPromptTextView: UITextViewDelegate{
-    
-    func textViewDidBeginEditing(_ textView: UITextView) {
-//        self.colComponent?.collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredVertically, animated: true)
-    }
-    
+
     func textViewDidChange(_ textView: UITextView) {
     func textViewDidChange(_ textView: UITextView) {
         currenMun = textView.text.count
         currenMun = textView.text.count
         clearBtn.isEnabled = currenMun > 0
         clearBtn.isEnabled = currenMun > 0
         textChangedBlock(textView.text)
         textChangedBlock(textView.text)
     }
     }
     
     
+    // 监听键盘的 Return 键(Done 键)
+     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
+         if text == "\n" { // 检测到 Return 键
+             textView.resignFirstResponder() // 收起键盘
+             return false // 阻止换行
+         }
+         return true
+     }
+    
 }
 }

+ 3 - 9
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC.swift

@@ -89,10 +89,7 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     
     
     override func clickAgainBtn() {
     override func clickAgainBtn() {
         audioPlayer.stop()
         audioPlayer.stop()
-        //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
+        if kPurchaseToolShared.kJudgeVipFreeType(vipFreeNumType: .ringtones, vc: self){ return }//判断 vip
         viewModel.creatRintone(text:aiText)
         viewModel.creatRintone(text:aiText)
     }
     }
     
     
@@ -102,7 +99,7 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
             kShowToastDataMissing()
             kShowToastDataMissing()
             return
             return
         }
         }
-
+        audioPlayer.stop()
         ringTool.shareBand(with: model.response.musicUrl, fileName: model.response.title) { success in
         ringTool.shareBand(with: model.response.musicUrl, fileName: model.response.title) { success in
             
             
         }
         }
@@ -117,10 +114,7 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     }
     }
     
     
     override func dealThings() {
     override func dealThings() {
-        //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
+        if kPurchaseToolShared.kJudgeVipFreeType(vipFreeNumType: .ringtones, vc: self){ return }//判断 vip
         viewModel.creatRintone(text: self.aiText)
         viewModel.creatRintone(text: self.aiText)
         viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
         viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
             guard let self = self else { return }
             guard let self = self else { return }

+ 4 - 16
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVM.swift

@@ -29,28 +29,16 @@ class TSGeneralRintoneVM {
     @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil)
     @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil)
     var aiText:String = ""
     var aiText:String = ""
     var generatingProgress = 0
     var generatingProgress = 0
-    
+//    //模拟数据
 //    func creatRintone(text:String) {
 //    func creatRintone(text:String) {
 //
 //
 //        stateDatauPblished = (.start,nil)
 //        stateDatauPblished = (.start,nil)
 //        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
 //        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
 //
 //
 //        kDelayOnMainThread(0.2) {
 //        kDelayOnMainThread(0.2) {
-//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.2)),nil)
-//        }
-//        
-//        kDelayOnMainThread(0.4) {
-//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.4)),nil)
-//        }
-//        
-//        kDelayOnMainThread(0.6) {
-//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.6)),nil)
+//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.5)),nil)
 //        }
 //        }
-//        
-//        kDelayOnMainThread(0.8) {
-//            self.stateDatauPblished = (.progressString(self.generating(progress: 0.8)),nil)
-//        }
-//        
+//
 //        kDelayOnMainThread(1.0) {
 //        kDelayOnMainThread(1.0) {
 //            if Bool.random() {
 //            if Bool.random() {
 //                let infoModel = TSActionInfoModel(JSON: actionInfoDict)
 //                let infoModel = TSActionInfoModel(JSON: actionInfoDict)
@@ -67,7 +55,7 @@ class TSGeneralRintoneVM {
         aiText = text
         aiText = text
         let postDict:[String : Any] = [
         let postDict:[String : Any] = [
             "prompt":text,
             "prompt":text,
-            "duration":30
+            "duration":20
         ]
         ]
         stateDatauPblished = (.start,nil)
         stateDatauPblished = (.start,nil)
         stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
         stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)

+ 7 - 28
AIRingtone/Business/TSAIRintoneVC/TSTextGeneralRintoneVC/TSTextGeneralRintoneVC.swift

@@ -56,8 +56,9 @@ class TSTextGeneralRintoneVC: TSBaseVC {
     
     
     
     
     //###################################### Button ######################################
     //###################################### Button ######################################
-    lazy var creatBtnView:TSCreatBtnView  = {
-        let creatBtnView = TSCreatBtnView {[weak self] in
+    lazy var creatBtnView:TSAppBtnView  = {
+        let creatBtnView = TSAppBtnView()
+        creatBtnView.setUpButton(style: .generate, vipFreeNumType: .ringtones) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             generateImage()
             generateImage()
         }
         }
@@ -97,46 +98,24 @@ class TSTextGeneralRintoneVC: TSBaseVC {
             make.width.equalTo(k_ScreenWidth)
             make.width.equalTo(k_ScreenWidth)
         }
         }
     }
     }
-    
+
     override func dealThings() {
     override func dealThings() {
-        self.updateVipView()
-        NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
-        self.creatBtnView.setVip(vip: true)
-    }
-    
-    @objc func vipInfoChanged() {
-        kExecuteOnMainThread {
-            self.updateVipView()
-        }
-    }
-    
-    @objc func clickView() {
-        view.endEditing(true)
-    }
 
 
-    func updateVipView() {
-//        self.creatBtnView.setVip(vip: kPurchaseDefault.generateVipShow(type: .ringtones))
     }
     }
-    
-    @objc func clickCollectionView() {
+
+    @objc func clickView() {
         view.endEditing(true)
         view.endEditing(true)
     }
     }
 }
 }
 
 
 extension TSTextGeneralRintoneVC {
 extension TSTextGeneralRintoneVC {
     func generateImage() {
     func generateImage() {
-        
-        //判断 vip
-        if kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: .ringtones) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
-        
+
         let gennerateVC = TSGeneralRintoneVC(aiText:viewModel.prompt)
         let gennerateVC = TSGeneralRintoneVC(aiText:viewModel.prompt)
         {[weak self] model in
         {[weak self] model in
             guard let self = self else { return }
             guard let self = self else { return }
             model.request.promptSort = viewModel.promptText
             model.request.promptSort = viewModel.promptText
             viewModel.saveModel(model:model)
             viewModel.saveModel(model:model)
-            updateVipView()
             reloadUIBlock?()
             reloadUIBlock?()
         }
         }
         
         

+ 5 - 23
AIRingtone/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift

@@ -182,24 +182,6 @@ class TSPurchaseVC: TSBaseVC {
 }
 }
 
 
 
 
-
-
-
-
-func kJudgeVip(externalBool:Bool,
-               vc:UIViewController,
-               closePageBlock:(()->Void)? = nil) -> Bool {
-    //判断 vip
-    if externalBool,
-       kPurchaseDefault.isVip == false
-    {
-        TSPurchaseVC.show(target: vc, closePageBlock: nil)
-        return true
-    }
-    return false
-}
-
-
 extension TSPurchaseVC{
 extension TSPurchaseVC{
     
     
     static func show(target:UIViewController,closePageBlock:(()->Void)?){
     static func show(target:UIViewController,closePageBlock:(()->Void)?){
@@ -222,9 +204,8 @@ struct PurchaseView :View {
 //            Spacer().frame(height: 44)
 //            Spacer().frame(height: 44)
             
             
             VStack {
             VStack {
-                Image("vip_big_icon").resizable().frame(width: 163, height: 164)
-                Spacer().frame(height: 13)
-                
+                Image("vip_big_icon").resizable().frame(width: 163, height: 163)
+      
                 Text(" AI Ringtone Pro")
                 Text(" AI Ringtone Pro")
                     .font(.font(name: .PoppinsBlackItalic,size: 30))
                     .font(.font(name: .PoppinsBlackItalic,size: 30))
                     .gradientForeground(
                     .gradientForeground(
@@ -264,7 +245,7 @@ struct PurchaseView :View {
          
          
             }
             }
             
             
-            Spacer().frame(height: 25)
+            Spacer().frame(height: 48)
             
             
             
             
             VStack(spacing: 12) {
             VStack(spacing: 12) {
@@ -286,7 +267,8 @@ struct PurchaseView :View {
 //                        viewModel.selectedType = .week
 //                        viewModel.selectedType = .week
 //                    }
 //                    }
 //                }
 //                }
-
+                
+                Spacer().frame(height: 2)
                 Button {
                 Button {
                     viewModel.buyPublisher.send(true)
                     viewModel.buyPublisher.send(true)
                 } label: {
                 } label: {

+ 1 - 1
AIRingtone/Business/TSSetingVC/SetingVC/TSSetingVC.swift

@@ -95,7 +95,7 @@ class TSSetingVC: TSBaseVC {
     
     
     @objc func vipInfoChanged() {
     @objc func vipInfoChanged() {
         kExecuteOnMainThread {
         kExecuteOnMainThread {
-            self.viewModel.isViper = kPurchaseDefault.isVip
+            self.viewModel.isViper = kPurchaseToolShared.isVip
         }
         }
     }
     }
 }
 }

+ 2 - 2
AIRingtone/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift

@@ -10,7 +10,7 @@ import StoreKit
 class TSSetingViewModel: ObservableObject {
 class TSSetingViewModel: ObservableObject {
     
     
     @Published var settingTypes: [SettingType] = SettingType.allCases
     @Published var settingTypes: [SettingType] = SettingType.allCases
-    @Published var isViper: Bool = kPurchaseDefault.isVip
+    @Published var isViper: Bool = kPurchaseToolShared.isVip
     
     
     var appid = "6741563341"
     var appid = "6741563341"
     // todo.kailen-privacy
     // todo.kailen-privacy
@@ -80,7 +80,7 @@ class TSSetingViewModel: ObservableObject {
     func pushVipPurchase(parent: UIViewController) {
     func pushVipPurchase(parent: UIViewController) {
         TSPurchaseVC.show(target: parent) {[weak self]  in
         TSPurchaseVC.show(target: parent) {[weak self]  in
             guard let self = self else { return }
             guard let self = self else { return }
-            isViper = kPurchaseDefault.isVip
+            isViper = kPurchaseToolShared.isVip
         }
         }
 //        pushTutorials(parent: parent)
 //        pushTutorials(parent: parent)
     }
     }

+ 30 - 29
AIRingtone/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift

@@ -16,23 +16,12 @@ struct SettingPurchaseTopView: View {
                     Spacer().frame(width:20)
                     Spacer().frame(width:20)
                     VStack(alignment: .leading,spacing: 16) {
                     VStack(alignment: .leading,spacing: 16) {
                         HStack {
                         HStack {
-                            Text(" AI Ringtone Pro")
-                                .font(.font(name: .PoppinsBlackItalic,size: 20))
-                                .gradientForeground(
-                                    colors: [Color.white, "#F7B7FF".uiColor.color],
-                                    startPoint: UnitPoint.top,
-                                    endPoint: UnitPoint.bottom
-                                )
-                                .frame(height: 20)
-                            
+                            customText(text: " AI Ringtone Pro")
                             Spacer()
                             Spacer()
                         }
                         }
                         
                         
                         HStack {
                         HStack {
-                            Text("Due Date:".localized + " \(kPurchaseDefault.expiredDateString)")
-                                .foregroundColor(.white.opacity(0.6))
-                                .font(.font(size: 14,weight: .medium))
-                                .frame(height: 14)
+                            customTimeText(text: "Due Date:".localized + " \(kPurchaseDefault.expiredDateString)")
                             Spacer()
                             Spacer()
                         }
                         }
                     }
                     }
@@ -47,24 +36,12 @@ struct SettingPurchaseTopView: View {
                     Spacer().frame(width:20)
                     Spacer().frame(width:20)
                     VStack(alignment: .leading,spacing: 16) {
                     VStack(alignment: .leading,spacing: 16) {
                         HStack {
                         HStack {
-                            Text("Get Pro")
-                                .font(.font(name: .PoppinsBlackItalic,size: 20))
-                                .gradientForeground(
-                                    colors: [Color.white, "#F7B7FF".uiColor.color],
-                                    startPoint: UnitPoint.top,
-                                    endPoint: UnitPoint.bottom
-                                )
-                                .frame(height: 20)
-                            
+                            customText(text: " Get Pro")
                             Spacer()
                             Spacer()
                         }
                         }
                         
                         
                         HStack {
                         HStack {
-                            Text("Limited Time Discount")
-                                .font(.font(size: 14))
-                                .frame(height: 14)
-                                .foregroundColor(UIColor.white.withAlphaComponent(0.6).color)
-                            
+                            customTimeText(text: "Limited Time Discount")
                             Spacer()
                             Spacer()
                         }
                         }
                     }
                     }
@@ -75,11 +52,11 @@ struct SettingPurchaseTopView: View {
                         .font(.font(size: 14,weight: .medium))
                         .font(.font(size: 14,weight: .medium))
                         .padding(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12))
                         .padding(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12))
                         .frame(height: 26) // 设置高度
                         .frame(height: 26) // 设置高度
-                        .foregroundColor("#010101".uiColor.color)
+                        .foregroundColor("#FBDAFF".uiColor.color)
                         .background(UIColor.themeColor.color)
                         .background(UIColor.themeColor.color)
                         .cornerRadius(13.0) // 圆角
                         .cornerRadius(13.0) // 圆角
                         .onTapGesture {
                         .onTapGesture {
-                            if kPurchaseDefault.isVip {
+                            if kPurchaseToolShared.isVip {
                                 return
                                 return
                             }
                             }
                             eventPublisher.enterPurchasePublisher.send(true)
                             eventPublisher.enterPurchasePublisher.send(true)
@@ -90,4 +67,28 @@ struct SettingPurchaseTopView: View {
             }
             }
         }
         }
     }
     }
+    
+    // 定义一个返回 View 的方法
+    func customText(text:String) -> some View {
+        let gorgeousColor = "#F7B7FF".uiColor.color
+        return Text(" AI Ringtone Pro")
+            .font(.font(name: .PoppinsBlackItalic,size: 20))
+            .gradientForeground(
+                colors: [Color.white, gorgeousColor],
+                startPoint: UnitPoint.top,
+                endPoint: UnitPoint.bottom
+            )
+            .shadow(color: gorgeousColor.opacity(0.7), radius: 6, x: 0, y: 0)
+            .frame(height: 20)
+    }
+
+
+    // 定义一个返回 View 的方法
+    func customTimeText(text:String) -> some View {
+        Text("Limited Time Discount")
+            .font(.font(size: 14))
+            .frame(height: 14)
+            .foregroundColor(UIColor.white.withAlphaComponent(0.6).color)
+        
+    }
 }
 }

+ 1 - 1
AIRingtone/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift

@@ -19,7 +19,7 @@ struct TSSettingListView: View {
                 SettingPurchaseTopView(eventPublisher: publisher, isViper: $viewModel.isViper)
                 SettingPurchaseTopView(eventPublisher: publisher, isViper: $viewModel.isViper)
                     .frame(height: 109*kDesignScale)
                     .frame(height: 109*kDesignScale)
                     .onTapGesture {
                     .onTapGesture {
-                        if kPurchaseDefault.isVip {
+                        if kPurchaseToolShared.isVip {
                             return
                             return
                         }
                         }
                         publisher.enterPurchasePublisher.send(true)
                         publisher.enterPurchasePublisher.send(true)

+ 2 - 9
AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/TSThemeBrowseVC.swift

@@ -151,19 +151,12 @@ class TSThemeBrowseVC: TSBaseVC {
             guard let self = self else { return }
             guard let self = self else { return }
             setVipUI()
             setVipUI()
         }
         }
-        self.btnView.doneBtn.setImage(UIImage(named: "vip_icon_white"), for: .normal)
-        NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
+        
         setVipUI()
         setVipUI()
     }
     }
     
     
-    @objc func vipInfoChanged() {
-        self.setVipUI()
-    }
-    
     func setVipUI(){
     func setVipUI(){
-        kExecuteOnMainThread {
-            self.btnView.doneBtn.setImage(self.getNeedVip ? UIImage(named: "vip_icon_white"): nil, for: .normal)
-        }
+        self.btnView.doneBtnView.setVip(vip: self.getNeedVip)
     }
     }
     
     
     var getNeedVip:Bool{
     var getNeedVip:Bool{

+ 19 - 8
AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/View/TSTBBtnView.swift

@@ -65,10 +65,21 @@ class TSTBBtnView: TSBaseView {
         return btn
         return btn
     }()
     }()
     
     
-    lazy var doneBtn: UIButton = {
-        let btn = kCreateNormalSubmitBtn(title: "Set Now".localized)
-        btn.addTarget(targetVC, action: doneSelector, for: .touchUpInside)
-        return btn
+//    lazy var doneBtn: UIButton = {
+//        let btn = kCreateNormalSubmitBtn(title: "Set Now".localized)
+//        btn.addTarget(targetVC, action: doneSelector, for: .touchUpInside)
+//        return btn
+//    }()
+    
+    lazy var doneBtnView: TSAppBtnView = {
+        let doneBtnView = TSAppBtnView()
+        doneBtnView.setUpButton(style: .themeSet, vipFreeNumType: .none) { [weak self]  in
+            guard let self = self else { return }
+            if let targetVC = targetVC {
+                targetVC.perform(doneSelector)
+            }
+        }
+        return doneBtnView
     }()
     }()
     
     
     init(targetVC:UIViewController,
     init(targetVC:UIViewController,
@@ -142,12 +153,12 @@ class TSTBBtnView: TSBaseView {
     
     
     
     
     func setDone() {
     func setDone() {
-        contentView.addSubview(doneBtn)
-        doneBtn.snp.makeConstraints { make in
+        contentView.addSubview(doneBtnView)
+        doneBtnView.snp.makeConstraints { make in
             make.bottom.equalTo(-k_Height_safeAreaInsetsBottom()-10)
             make.bottom.equalTo(-k_Height_safeAreaInsetsBottom()-10)
             make.centerX.equalToSuperview()
             make.centerX.equalToSuperview()
-            make.width.equalTo(doneBtn.width)
-            make.height.equalTo(doneBtn.height)
+            make.width.equalTo(doneBtnView.button.width)
+            make.height.equalTo(doneBtnView.button.height)
         }
         }
     }
     }
     
     

+ 1 - 1
AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/View/TSTSIslandView.swift

@@ -35,7 +35,7 @@ class TSTSIslandView: TSBaseView {
         islandImageView.addSubview(showImageView)
         islandImageView.addSubview(showImageView)
         showImageView.snp.makeConstraints { make in
         showImageView.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.centerY.equalToSuperview()
-            make.leading.equalTo(24)
+            make.leading.equalTo(14)
             make.width.height.equalTo(56)
             make.width.height.equalTo(56)
         }
         }
         
         

+ 3 - 4
AIRingtone/Business/TSThemeVC/TSThemeSetVC/TSThemeSetItemView.swift

@@ -25,14 +25,13 @@ class TSThemeSetItemView: TSBaseView {
     
     
     let diyView = UIView()
     let diyView = UIView()
     
     
-    let setBtn:UIButton = UIButton.createButton(title: "Set Now".localized,backgroundColor: .themeColor,font: .font(size: 16),titleColor: "#111111".uiColor,corner: 16)
+    let setBtn:UIButton = UIButton.createButton(title: "Set Now".localized,backgroundColor: .themeColor,font: .font(size: 16),titleColor: .white,corner: 16)
     
     
     let moreInfoBtn = kCreateMoreInfoBtn()
     let moreInfoBtn = kCreateMoreInfoBtn()
     
     
     override func creatUI() {
     override func creatUI() {
-        
-        setBtn.imageEdgeInsets = UIEdgeInsets(top:0, left: -8, bottom: 0, right: 16)
-        
+
+        setBtn.setTitleImageSpace(spacing: 4)
         contentView.snp.updateConstraints { make in
         contentView.snp.updateConstraints { make in
             make.top.equalTo(16)
             make.top.equalTo(16)
         }
         }

+ 7 - 12
AIRingtone/Business/TSThemeVC/TSThemeSetVC/TSThemeSetVC.swift

@@ -116,9 +116,9 @@ class TSThemeSetVC: TSBaseVC {
     }
     }
     
     
     func setVipUI(){
     func setVipUI(){
-        self.ringView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_black"): nil, for: .normal)
-        self.posterView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_black"): nil, for: .normal)
-        self.photoView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_black"): nil, for: .normal)
+        self.ringView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_white"): nil, for: .normal)
+        self.posterView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_white"): nil, for: .normal)
+        self.photoView.setBtn.setImage(getNeedVip ? UIImage(named: "vip_icon_white"): nil, for: .normal)
     }
     }
     
     
 
 
@@ -162,10 +162,8 @@ extension TSThemeSetVC {
     }
     }
     
     
     @objc func clickSetRing(){
     @objc func clickSetRing(){
-        
-        //判断 vip
-        if kJudgeVip(externalBool: getNeedVip, vc: self) { return }
-        
+        audioPlayer.stop()
+        if kPurchaseToolShared.kJudgeVip(externalBool: getNeedVip, vc: self){ return }//判断 vip
         ringTool.shareBand(with: model.ringtone, fileName: model.name) { success in
         ringTool.shareBand(with: model.ringtone, fileName: model.name) { success in
             
             
         }
         }
@@ -173,8 +171,7 @@ extension TSThemeSetVC {
     
     
     @objc func clickSetPoster(){
     @objc func clickSetPoster(){
         
         
-        //判断 vip
-        if kJudgeVip(externalBool: getNeedVip, vc: self){ return }
+        if kPurchaseToolShared.kJudgeVip(externalBool: getNeedVip, vc: self){ return }//判断 vip
         
         
         if let image = posterView.netWorkImageView.image{
         if let image = posterView.netWorkImageView.image{
             PhotoManagerShared.saveImageToAlbum(image) { success, error in
             PhotoManagerShared.saveImageToAlbum(image) { success, error in
@@ -191,9 +188,7 @@ extension TSThemeSetVC {
     
     
     @objc func clickPhoto(){
     @objc func clickPhoto(){
         
         
-        //判断 vip
-        if kJudgeVip(externalBool: getNeedVip, vc: self)
-        { return }
+        if kPurchaseToolShared.kJudgeVip(externalBool: getNeedVip, vc: self){ return }//判断 vip
         
         
         guard let photo = avatarImage else { return }
         guard let photo = avatarImage else { return }
         contactsTool.setContactsAvatar(avatarImage: photo) { data, error in
         contactsTool.setContactsAvatar(avatarImage: photo) { data, error in

+ 18 - 4
AIRingtone/Business/TSTutorialsVC/TSTutorialPopupVC.swift

@@ -89,7 +89,8 @@ class TSTutorialPopupVC: TSBaseVC {
     }()
     }()
     
     
     lazy var pagingView: JXPagingView = {
     lazy var pagingView: JXPagingView = {
-        let pagingView = JXPagingView(delegate: self)
+        let pagingView: JXPagingView = JXPagingListRefreshView(delegate: self) //整个刷新
+//        let pagingView = JXPagingView(delegate: self)
         pagingView.mainTableView.backgroundColor = .clear
         pagingView.mainTableView.backgroundColor = .clear
         pagingView.frame = CGRect(x: 0, y: 25, width:popupContentViewW, height:popupContentViewH-72-25)
         pagingView.frame = CGRect(x: 0, y: 25, width:popupContentViewW, height:popupContentViewH-72-25)
         pagingView.listContainerView.listCellBackgroundColor = .clear
         pagingView.listContainerView.listCellBackgroundColor = .clear
@@ -171,6 +172,7 @@ extension TSTutorialPopupVC: JXPagingViewDelegate {
     lazy var stackView: TSCustomStackView = {
     lazy var stackView: TSCustomStackView = {
         let stackView = TSCustomStackView()
         let stackView = TSCustomStackView()
         stackView.scrollView.delegate = self
         stackView.scrollView.delegate = self
+        stackView.scrollView.isScrollEnabled = false
         return stackView
         return stackView
     }()
     }()
     
     
@@ -219,7 +221,19 @@ extension TSTutorialPopupVC: JXPagingViewDelegate {
         
         
         popupContentView.imageView0.image = UIImage(named: imageNamed0)
         popupContentView.imageView0.image = UIImage(named: imageNamed0)
         popupContentView.imageView1.image = UIImage(named: imageNamed1)
         popupContentView.imageView1.image = UIImage(named: imageNamed1)
-        popupContentView.infoLabel.text = info
+        
+
+        let attributedString = NSMutableAttributedString(string: info)
+        let paragraphStyle = NSMutableParagraphStyle()
+        paragraphStyle.lineSpacing = 10
+        paragraphStyle.alignment = .center
+        attributedString.addAttribute(
+          .paragraphStyle,
+          value: paragraphStyle,
+          range: NSRange(location: 0, length: attributedString.length)
+        )
+        popupContentView.infoLabel.attributedText = attributedString
+//        popupContentView.infoLabel.text = info
     }
     }
 }
 }
 
 
@@ -299,8 +313,8 @@ class TSTutorialPopupContentView: TSBaseView {
         
         
         infoLabel.snp.makeConstraints { make in
         infoLabel.snp.makeConstraints { make in
             make.top.equalTo(imageView0.snp.bottom).offset(20)
             make.top.equalTo(imageView0.snp.bottom).offset(20)
-            make.leading.bottom.equalTo(20)
-            make.trailing.equalTo(-20)
+            make.leading.equalTo(20)
+            make.bottom.trailing.equalTo(-20)
         }
         }
         
         
     }
     }

+ 126 - 45
AIRingtone/Business/VIewTool/TSButton.swift

@@ -24,77 +24,158 @@ class TSNormalCancelBtn: TSAppBtn {
 
 
 }
 }
 
 
-//常用提交按钮
-func kCreateNormalSubmitBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
-    
-    let btn = TSNormalSubmitBtn()
-    btn.setUpButton(title:title,font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24,action: action)
-    btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
-    btn.imageEdgeInsets = UIEdgeInsets(top:0, left: -8, bottom: 0, right: 16)
-    btn.frame = CGRectMake(0, 0, 200, 48)
-    btn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
-    return btn
-}
+////常用取消按钮
+//func kCreateNormalCancelBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
+//    let btn = UIButton.createButton(title:title,backgroundColor: .fromHex("#FFFFFF", alpha: 0.4),font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 30,action: action)
+//    return btn
+//}
+////常用确定按钮
+//func kCreateNormalConfirmBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
+//    let btn = UIButton.createButton(title:title,backgroundImage:UIImage(named: "submit_btn_small_bg"),font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 30,action: action)
+//    return btn
+//}
 
 
 
 
 class TSAppBtnView: TSBaseView {
 class TSAppBtnView: TSBaseView {
     enum ViewStyle {
     enum ViewStyle {
-        case created   //创造类的按钮
+        case normal
+        case generate   //创造类的按钮
+        case themeSet   //主题页设置按钮
+        
     }
     }
     
     
     var viewH:CGFloat = 64
     var viewH:CGFloat = 64
-    var style:ViewStyle
-    var clickBlock:()->Void
-    
-    init(style:ViewStyle,clickBlock: @escaping () -> Void) {
-        self.style = style
-        self.clickBlock = clickBlock
-        super.init(frame: .zero)
+    var style:ViewStyle = .normal
+    var vipFreeNumType:VipFreeNumType = .none{
+        didSet{
+            updateVipView()
+        }
     }
     }
+    var clickBlock:(()->Void)?
     
     
-    @MainActor required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
+    //###################################### Button ######################################
+    var button:UIButton = UIButton()
+
+    override func creatUI() {
+
     }
     }
     
     
+    override func dealThings(){
+        
+    }
+
+    func setUpButton(style:ViewStyle,vipFreeNumType:VipFreeNumType,clickBlock: @escaping () -> Void) {
+        
+        self.style = style
+        self.vipFreeNumType = vipFreeNumType
+        self.clickBlock = clickBlock
+        
+        contentView.removeAllSubviews()
+        
+        switch style {
+        case .generate:
+            setUpGenerate()
+            launchVipLogic()
+        case .themeSet:
+            setUpThemeSet()
+        default:
+            break
+        }
+        
+    }
+}
+
+extension TSAppBtnView{
     
     
-    //###################################### Button ######################################
-    lazy var creatBtn:UIButton  = {
+    func launchVipLogic(){
+        //监听 Vip 变化
+        NotificationCenter.default.addObserver(forName: .kPurchaseDidChanged, object: nil, queue: OperationQueue.main) { [weak self] notification in
+            guard let self = self else { return }
+            updateVipView()
+        }
         
         
-        let btn = UIButton.createButton(title:"Create Now",font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24)
-        {[weak self] in
+        NotificationCenter.default.addObserver(forName: .kVipFreeNumChanged, object: nil, queue: OperationQueue.main) { [weak self] notification in
             guard let self = self else { return }
             guard let self = self else { return }
-            clickBlock()
+            if let userInfo = notification.userInfo as? [String: VipFreeNumType], let myEnum = userInfo["VipFreeNumType"] {
+                if myEnum == self.vipFreeNumType {
+                    self.updateVipView()
+                }
+            }
         }
         }
-        btn.frame = CGRectMake(0, 0, k_ScreenWidth - 32, 48)
-        btn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
-        btn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 0)
-        btn.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
-        return btn
-    }()
+        
+        updateVipView()
+    }
 
 
-    
-    override func creatUI() {
-        contentView.addSubview(creatBtn)
-        creatBtn.snp.makeConstraints { make in
-            make.center.equalToSuperview()
-            make.leading.equalTo(16)
-            make.trailing.equalTo(-16)
-            make.height.equalTo(creatBtn.height)
+    func updateVipView() {
+        switch style {
+        case .generate:
+            setVip(vip: kPurchaseToolShared.generateVipShow(type: self.vipFreeNumType))
+        default:
+            break
         }
         }
-        setVip(vip:true)
     }
     }
     
     
     func setBtnEnabled(isEnabled:Bool) {
     func setBtnEnabled(isEnabled:Bool) {
-        creatBtn.isEnabled = isEnabled
-        creatBtn.alpha = isEnabled ? 1.0 : 0.6
+        button.isEnabled = isEnabled
+        button.alpha = isEnabled ? 1.0 : 0.6
     }
     }
     
     
     func setVip(vip:Bool) {
     func setVip(vip:Bool) {
         if vip {
         if vip {
-            creatBtn.setImage(UIImage(named: "vip_icon_white"), for: .normal)
+            button.setImage(UIImage(named: "vip_icon_white"), for: .normal)
         }else{
         }else{
-            creatBtn.setImage(nil, for: .normal)
+            button.setImage(nil, for: .normal)
         }
         }
     }
     }
     
     
 }
 }
+//创造按钮
+extension TSAppBtnView{
+    //常用提交按钮
+    func kCreateNormalSubmitBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
+        let btn = TSNormalSubmitBtn()
+        btn.setUpButton(title:title,font: UIFont.font(size: 16,weight: .regular),titleColor:.white,corner: 24,action: action)
+
+        btn.setTitleImageSpace(spacing: 4)
+        return btn
+    }
+
+
+    func setUpGenerate() {
+        button = kCreateNormalSubmitBtn(title: "Create Now", action: { [weak self]  in
+            guard let self = self else { return }
+            if let vc = WindowHelper.getCurrentViewController() {
+                if kPurchaseToolShared.kJudgeVipFreeType(vipFreeNumType: vipFreeNumType, vc: vc){ return }
+            }
+
+            clickBlock?()
+        })
+        button.frame = CGRectMake(0, 0, k_ScreenWidth - 32, 48)
+        button.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+        contentView.addSubview(button)
+        button.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.width.equalTo(button.width)
+            make.height.equalTo(button.height)
+        }
+   
+        
+        viewH = 64
+    }
+    
+    func setUpThemeSet() {
+        button = kCreateNormalSubmitBtn(title: "Set Now", action: { [weak self]  in
+            guard let self = self else { return }
+            clickBlock?()
+        })
+        button.frame = CGRectMake(0, 0, 200, 48)
+        button.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
+        contentView.addSubview(button)
+        button.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.width.equalTo(button.width)
+            make.height.equalTo(button.height)
+        }
+   
+    }
+}

+ 0 - 24
AIRingtone/Business/VIewTool/TSViewTool.swift

@@ -7,10 +7,8 @@
 
 
 class TSViewTool: UIView {
 class TSViewTool: UIView {
     
     
-
 }
 }
 
 
-
 func createBlurEffectView(style:UIBlurEffect.Style,backgroundColor:UIColor? = nil) -> UIVisualEffectView {
 func createBlurEffectView(style:UIBlurEffect.Style,backgroundColor:UIColor? = nil) -> UIVisualEffectView {
     let blurEffect = UIBlurEffect(style: style)
     let blurEffect = UIBlurEffect(style: style)
     let blurEffectView = UIVisualEffectView(effect: blurEffect)
     let blurEffectView = UIVisualEffectView(effect: blurEffect)
@@ -23,39 +21,17 @@ func createBlurEffectView(style:UIBlurEffect.Style,backgroundColor:UIColor? = ni
     return blurEffectView
     return blurEffectView
 }
 }
 
 
-
 func kAddNormalSubmitGradientBg(view:UIView){
 func kAddNormalSubmitGradientBg(view:UIView){
     kDelayMainShort {
     kDelayMainShort {
         view.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
         view.addGradientBg(colors: ["#E961F6".uiColor.cgColor,"#7E57F4".uiColor.cgColor])
     }
     }
 }
 }
 
 
-
 func kCreateMoreInfoBtn() -> UIButton{
 func kCreateMoreInfoBtn() -> UIButton{
     let btn = TSUIExpandedTouchButton()
     let btn = TSUIExpandedTouchButton()
     btn.setImage(UIImage(named: "more_info_white"), for: .normal)
     btn.setImage(UIImage(named: "more_info_white"), for: .normal)
     return btn
     return btn
 }
 }
 
 
-
-////常用提交按钮
-//func kCreateNormalSubmitBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
-//    let btn = UIButton.createButton(title:title,backgroundColor: .black,font: UIFont.font(size: 16,weight: .regular),titleColor:.themeColor,corner: 24,action: action)
-//    btn.layer.borderWidth = 1
-//    btn.layer.borderColor = UIColor.themeColor.cgColor
-//    btn.frame = CGRectMake(0, 0, 200, 48)
-//    return btn
-//}
-////常用取消按钮
-//func kCreateNormalCancelBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
-//    let btn = UIButton.createButton(title:title,backgroundColor: .fromHex("#FFFFFF", alpha: 0.4),font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 30,action: action)
-//    return btn
-//}
-////常用确定按钮
-//func kCreateNormalConfirmBtn(title:String, action: (() -> Void)? = nil) -> UIButton {
-//    let btn = UIButton.createButton(title:title,backgroundImage:UIImage(named: "submit_btn_small_bg"),font: UIFont.font(size: 14,weight: .medium),titleColor:.white,corner: 30,action: action)
-//    return btn
-//}
-
 let kPlaceholderImage = UIImage(named: "placeholderImage")
 let kPlaceholderImage = UIImage(named: "placeholderImage")
 let kViewBJ = "view_bj"
 let kViewBJ = "view_bj"

+ 5 - 0
AIRingtone/Common/Ex/Notification+TSEx.swift

@@ -9,6 +9,11 @@
 extension Notification.Name {
 extension Notification.Name {
     static let kReloadUIData = Notification.Name("kReloadUIData")   //通知页面刷新数据,具体类型,根据参数来区分
     static let kReloadUIData = Notification.Name("kReloadUIData")   //通知页面刷新数据,具体类型,根据参数来区分
     static let kBusinessAudioStateChange = Notification.Name("kBusinessAudioStateChange")   //通知页面刷新数据,具体类型,根据参数来区分
     static let kBusinessAudioStateChange = Notification.Name("kBusinessAudioStateChange")   //通知页面刷新数据,具体类型,根据参数来区分
+    
+    
+    
+    
+    static let kVipFreeNumChanged = Notification.Name("kVipFreeNumChanged")   //Vip免费次数发生变化
 }
 }
 
 
 
 

+ 1 - 10
AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseManager.swift

@@ -16,12 +16,6 @@ public enum PremiumPeriod: String, CaseIterable {
     case lifetime       = "Lifetime"
     case lifetime       = "Lifetime"
 }
 }
 
 
-public enum VipFreeNumType: String, CaseIterable {
-    case ringtones           = "kRingtonesFreeNum"
-    case posetr              = "kPosetrFreeNum"
-    case photo               = "kPhotoFreeNum"
-}
-
 public struct PurchaseProduct {
 public struct PurchaseProduct {
     public let productId: String
     public let productId: String
     public let period: PremiumPeriod
     public let period: PremiumPeriod
@@ -63,7 +57,7 @@ private let kPremiumExpiredInfoKey = "premiumExpiredInfoKey"
 
 
 typealias PurchaseStateChangeHandler = (_ manager: PurchaseManager, _ state: PremiumRequestState, _ object: Any?) -> Void
 typealias PurchaseStateChangeHandler = (_ manager: PurchaseManager, _ state: PremiumRequestState, _ object: Any?) -> Void
 
 
-let kPurchaseDefault = PurchaseManager.default
+public let kPurchaseDefault = PurchaseManager.default
 public class PurchaseManager: NSObject {
 public class PurchaseManager: NSObject {
     @objc public static let `default` = PurchaseManager()
     @objc public static let `default` = PurchaseManager()
 
 
@@ -129,9 +123,6 @@ public class PurchaseManager: NSObject {
     }
     }
 
 
     @objc public var isVip: Bool {
     @objc public var isVip: Bool {
-//        #if DEBUG
-//            return true
-//        #endif
         guard let expiresDate = expiredDate else {
         guard let expiresDate = expiredDate else {
             return false
             return false
         }
         }

+ 38 - 1
AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseTool.swift

@@ -5,7 +5,14 @@
 //  Created by 100Years on 2025/3/16.
 //  Created by 100Years on 2025/3/16.
 //
 //
 
 
-/// 免费生成图片次数
+/// 免费生成图片次
+public enum VipFreeNumType: String, CaseIterable {
+    case none                = "kNone"
+    case ringtones           = "kRingtonesFreeNum"
+    case posetr              = "kPosetrFreeNum"
+    case photo               = "kPhotoFreeNum"
+}
+
 
 
 let kPurchaseToolShared = TSPurchaseTool.shared
 let kPurchaseToolShared = TSPurchaseTool.shared
 class TSPurchaseTool {
 class TSPurchaseTool {
@@ -20,6 +27,9 @@ class TSPurchaseTool {
     var freeDict:[String:Int] = [:]
     var freeDict:[String:Int] = [:]
     
     
     var isVip:Bool{
     var isVip:Bool{
+//        #if DEBUG
+//            return true
+//        #endif
         return kPurchaseDefault.isVip
         return kPurchaseDefault.isVip
     }
     }
     /// 使用一次免费次数
     /// 使用一次免费次数
@@ -40,6 +50,8 @@ class TSPurchaseTool {
         
         
         freeDict[type.rawValue] = freeNum
         freeDict[type.rawValue] = freeNum
         saveForFree()
         saveForFree()
+        
+        NotificationCenter.default.post(name: .kVipFreeNumChanged, object: nil, userInfo: ["VipFreeNumType": type])
     }
     }
     
     
     func freeNum(type:VipFreeNumType) -> Int{
     func freeNum(type:VipFreeNumType) -> Int{
@@ -99,3 +111,28 @@ extension TSPurchaseTool{
     }
     }
     
     
 }
 }
+
+extension TSPurchaseTool{
+    func kJudgeVipFreeType(vipFreeNumType:VipFreeNumType,
+                   vc:UIViewController,
+                   closePageBlock:(()->Void)? = nil) -> Bool {
+        //判断 vip
+        return kJudgeVip(externalBool: kPurchaseToolShared.freeNumAvailable(type: vipFreeNumType) == false, vc: vc,closePageBlock: closePageBlock)
+    }
+
+
+    func kJudgeVip(externalBool:Bool,
+                   vc:UIViewController,
+                   closePageBlock:(()->Void)? = nil) -> Bool {
+        //判断 vip
+        if externalBool,
+           kPurchaseToolShared.isVip == false
+        {
+            TSPurchaseVC.show(target: vc, closePageBlock: nil)
+            return true
+        }
+        return false
+    }
+
+}
+

+ 0 - 71
AIRingtone/Common/Tool/WindowHelper.swift

@@ -1,71 +0,0 @@
-//
-//  WindowHelper.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-
-class WindowHelper {
-    
-    /// 获取当前的 keyWindow
-    static func getKeyWindow() -> UIWindow? {
-        // 在 iOS 13 及以上,SceneDelegate 管理窗口
-        if #available(iOS 13.0, *) {
-            return UIApplication.shared.connectedScenes
-                .compactMap { $0 as? UIWindowScene }
-                .flatMap { $0.windows }
-                .first { $0.isKeyWindow }
-        } else {
-            // iOS 13 以下直接获取 keyWindow
-            return UIApplication.shared.keyWindow
-        }
-    }
-    
-    /// 获取当前窗口,兼容 iOS 13 及以上版本
-    static func getCurrentWindow() -> UIWindow? {
-        if #available(iOS 13.0, *) {
-            // iOS 13 及以上使用 `scene` 获取当前 window
-            guard let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene else {
-                return nil
-            }
-            return scene.windows.first { $0.isKeyWindow }
-        } else {
-            // iOS 12 及以下直接从 keyWindow 获取
-            return UIApplication.shared.keyWindow
-        }
-    }
-    
-    /// 获取当前根视图控制器
-    static func getRootViewController() -> UIViewController? {
-        guard let window = getCurrentWindow() else {
-            return nil
-        }
-        return window.rootViewController
-    }
-    
-    /// 获取当前的视图控制器
-    static func getCurrentViewController() -> UIViewController? {
-        var currentViewController = getRootViewController()
-        
-        while let presentedViewController = currentViewController?.presentedViewController {
-            currentViewController = presentedViewController
-        }
-        
-        return currentViewController
-    }
-    
-    
-    static func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
-        if let nav = base as? UINavigationController {
-            return topViewController(base: nav.visibleViewController)
-        } else if let tab = base as? UITabBarController {
-            return topViewController(base: tab.selectedViewController)
-        } else if let presented = base?.presentedViewController {
-            return topViewController(base: presented)
-        }
-        debugPrint("当前顶层 VC 是: \(base)")
-        return base
-    }
-}