Переглянути джерело

功能开发完毕,剩下版本号判断

100Years 3 тижнів тому
батько
коміт
f1dfb52baa
23 змінених файлів з 688 додано та 866 видалено
  1. 9 25
      AIRingtone.xcodeproj/project.pbxproj
  2. 62 31
      AIRingtone/AppDelegate.swift
  3. 47 41
      AIRingtone/Business/LaunchVC/TSLaunchVC.swift
  4. 3 1
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/View/TSAIPhotoImageCell.swift
  5. 4 3
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/TSTextGeneralPicVC.swift
  6. 0 7
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/VM/TSTextGeneralPicVM.swift
  7. 10 8
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptTextView.swift
  8. 4 23
      AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/TSAIRintoneVC.swift
  9. 0 1
      AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/View/TSAIRintoneHistoryCell.swift
  10. 2 1
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingModel.swift
  11. 4 1
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingVC.swift
  12. 8 0
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift
  13. 12 3
      AIRingtone/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift
  14. 1 9
      AIRingtone/Common/Ex/Notification+TSEx.swift
  15. 1 0
      AIRingtone/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift
  16. 142 0
      AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift
  17. 135 0
      AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePhotoOperation.swift
  18. 136 0
      AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift
  19. 108 0
      AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateRintoneOperation.swift
  20. 0 239
      AIRingtone/Common/Tool/OperationQueue/TSGeneratePhotoOperation/TSGeneratePhotoOperation.swift
  21. 0 239
      AIRingtone/Common/Tool/OperationQueue/TSGeneratePosterOperation/TSGeneratePosterOperation.swift
  22. 0 224
      AIRingtone/Common/Tool/OperationQueue/TSGenerateRintoneOperation/TSGenerateRintoneOperation.swift
  23. 0 10
      AIRingtone/Common/Tool/OperationQueue/TSGenerateRintoneOperation/TSGenerateRintoneOperationQueue.swift

+ 9 - 25
AIRingtone.xcodeproj/project.pbxproj

@@ -50,7 +50,6 @@
 		A83F87202D794FF000D29B1B /* TSAIPhotoImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F871F2D794FE600D29B1B /* TSAIPhotoImageCell.swift */; };
 		A83F87202D794FF000D29B1B /* TSAIPhotoImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F871F2D794FE600D29B1B /* TSAIPhotoImageCell.swift */; };
 		A83F87222D7953C000D29B1B /* Notification+TSEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F87212D7953BA00D29B1B /* Notification+TSEx.swift */; };
 		A83F87222D7953C000D29B1B /* Notification+TSEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F87212D7953BA00D29B1B /* Notification+TSEx.swift */; };
 		A83F87242D7954BB00D29B1B /* TSAIPhotoChildVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F87232D7954B800D29B1B /* TSAIPhotoChildVM.swift */; };
 		A83F87242D7954BB00D29B1B /* TSAIPhotoChildVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F87232D7954B800D29B1B /* TSAIPhotoChildVM.swift */; };
-		A840A7EB2D8D81CD0044B8B9 /* TSGenerateRintoneOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7EA2D8D81C90044B8B9 /* TSGenerateRintoneOperationQueue.swift */; };
 		A840A7ED2D8D81DB0044B8B9 /* TSGenerateRintoneOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */; };
 		A840A7ED2D8D81DB0044B8B9 /* TSGenerateRintoneOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */; };
 		A840A7F02D8E5BA00044B8B9 /* TSRingLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7EF2D8E5B8F0044B8B9 /* TSRingLoadingView.swift */; };
 		A840A7F02D8E5BA00044B8B9 /* TSRingLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7EF2D8E5B8F0044B8B9 /* TSRingLoadingView.swift */; };
 		A840A7F22D8E60A40044B8B9 /* ringAnimation.gif in Resources */ = {isa = PBXBuildFile; fileRef = A840A7F12D8E60A40044B8B9 /* ringAnimation.gif */; };
 		A840A7F22D8E60A40044B8B9 /* ringAnimation.gif in Resources */ = {isa = PBXBuildFile; fileRef = A840A7F12D8E60A40044B8B9 /* ringAnimation.gif */; };
@@ -58,6 +57,7 @@
 		A840A7F62D8EA0470044B8B9 /* TSGeneralPosterBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7F52D8EA0380044B8B9 /* TSGeneralPosterBrowseVC.swift */; };
 		A840A7F62D8EA0470044B8B9 /* TSGeneralPosterBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7F52D8EA0380044B8B9 /* TSGeneralPosterBrowseVC.swift */; };
 		A840A7FA2D916D9B0044B8B9 /* TSGeneratePosterOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */; };
 		A840A7FA2D916D9B0044B8B9 /* TSGeneratePosterOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */; };
 		A840A7FE2D916DB50044B8B9 /* TSGeneratePhotoOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */; };
 		A840A7FE2D916DB50044B8B9 /* TSGeneratePhotoOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */; };
+		A840A8032D91945A0044B8B9 /* TSGenerateBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A840A8022D9194590044B8B9 /* TSGenerateBaseOperation.swift */; };
 		A868A89A2D75505E00F6D884 /* TSThemeBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A8992D75505800F6D884 /* TSThemeBannerCell.swift */; };
 		A868A89A2D75505E00F6D884 /* TSThemeBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A8992D75505800F6D884 /* TSThemeBannerCell.swift */; };
 		A868A89C2D75506C00F6D884 /* TSThemeContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A89B2D75506500F6D884 /* TSThemeContentCell.swift */; };
 		A868A89C2D75506C00F6D884 /* TSThemeContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A89B2D75506500F6D884 /* TSThemeContentCell.swift */; };
 		A868A8A22D7560B900F6D884 /* TSPageNullView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A89D2D7560B900F6D884 /* TSPageNullView.swift */; };
 		A868A8A22D7560B900F6D884 /* TSPageNullView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868A89D2D7560B900F6D884 /* TSPageNullView.swift */; };
@@ -189,7 +189,6 @@
 		A83F871F2D794FE600D29B1B /* TSAIPhotoImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoImageCell.swift; sourceTree = "<group>"; };
 		A83F871F2D794FE600D29B1B /* TSAIPhotoImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoImageCell.swift; sourceTree = "<group>"; };
 		A83F87212D7953BA00D29B1B /* Notification+TSEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+TSEx.swift"; sourceTree = "<group>"; };
 		A83F87212D7953BA00D29B1B /* Notification+TSEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+TSEx.swift"; sourceTree = "<group>"; };
 		A83F87232D7954B800D29B1B /* TSAIPhotoChildVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoChildVM.swift; sourceTree = "<group>"; };
 		A83F87232D7954B800D29B1B /* TSAIPhotoChildVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoChildVM.swift; sourceTree = "<group>"; };
-		A840A7EA2D8D81C90044B8B9 /* TSGenerateRintoneOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateRintoneOperationQueue.swift; sourceTree = "<group>"; };
 		A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateRintoneOperation.swift; sourceTree = "<group>"; };
 		A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateRintoneOperation.swift; sourceTree = "<group>"; };
 		A840A7EF2D8E5B8F0044B8B9 /* TSRingLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRingLoadingView.swift; sourceTree = "<group>"; };
 		A840A7EF2D8E5B8F0044B8B9 /* TSRingLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRingLoadingView.swift; sourceTree = "<group>"; };
 		A840A7F12D8E60A40044B8B9 /* ringAnimation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = ringAnimation.gif; sourceTree = "<group>"; };
 		A840A7F12D8E60A40044B8B9 /* ringAnimation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = ringAnimation.gif; sourceTree = "<group>"; };
@@ -197,6 +196,7 @@
 		A840A7F52D8EA0380044B8B9 /* TSGeneralPosterBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralPosterBrowseVC.swift; sourceTree = "<group>"; };
 		A840A7F52D8EA0380044B8B9 /* TSGeneralPosterBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralPosterBrowseVC.swift; sourceTree = "<group>"; };
 		A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePosterOperation.swift; sourceTree = "<group>"; };
 		A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePosterOperation.swift; sourceTree = "<group>"; };
 		A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePhotoOperation.swift; sourceTree = "<group>"; };
 		A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePhotoOperation.swift; sourceTree = "<group>"; };
+		A840A8022D9194590044B8B9 /* TSGenerateBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateBaseOperation.swift; sourceTree = "<group>"; };
 		A868A8992D75505800F6D884 /* TSThemeBannerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSThemeBannerCell.swift; sourceTree = "<group>"; };
 		A868A8992D75505800F6D884 /* TSThemeBannerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSThemeBannerCell.swift; sourceTree = "<group>"; };
 		A868A89B2D75506500F6D884 /* TSThemeContentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSThemeContentCell.swift; sourceTree = "<group>"; };
 		A868A89B2D75506500F6D884 /* TSThemeContentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSThemeContentCell.swift; sourceTree = "<group>"; };
 		A868A89D2D7560B900F6D884 /* TSPageNullView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPageNullView.swift; sourceTree = "<group>"; };
 		A868A89D2D7560B900F6D884 /* TSPageNullView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPageNullView.swift; sourceTree = "<group>"; };
@@ -635,15 +635,6 @@
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
-		A840A7E92D8D81350044B8B9 /* TSGenerateRintoneOperation */ = {
-			isa = PBXGroup;
-			children = (
-				A840A7EA2D8D81C90044B8B9 /* TSGenerateRintoneOperationQueue.swift */,
-				A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */,
-			);
-			path = TSGenerateRintoneOperation;
-			sourceTree = "<group>";
-		};
 		A840A7EE2D8D82100044B8B9 /* NotUse */ = {
 		A840A7EE2D8D82100044B8B9 /* NotUse */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -654,20 +645,15 @@
 			path = NotUse;
 			path = NotUse;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
-		A840A7F72D916D7F0044B8B9 /* TSGeneratePhotoOperation */ = {
-			isa = PBXGroup;
-			children = (
-				A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */,
-			);
-			path = TSGeneratePhotoOperation;
-			sourceTree = "<group>";
-		};
-		A840A7F82D916D8E0044B8B9 /* TSGeneratePosterOperation */ = {
+		A840A8012D91944F0044B8B9 /* TSGenerateBaseOperation */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				A840A8022D9194590044B8B9 /* TSGenerateBaseOperation.swift */,
 				A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */,
 				A840A7F92D916D9A0044B8B9 /* TSGeneratePosterOperation.swift */,
+				A840A7FD2D916DB40044B8B9 /* TSGeneratePhotoOperation.swift */,
+				A840A7EC2D8D81DA0044B8B9 /* TSGenerateRintoneOperation.swift */,
 			);
 			);
-			path = TSGeneratePosterOperation;
+			path = TSGenerateBaseOperation;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
 		A868A8982D75505100F6D884 /* View */ = {
 		A868A8982D75505100F6D884 /* View */ = {
@@ -1054,9 +1040,7 @@
 		A8D776F62D8D342D007EAB35 /* OperationQueue */ = {
 		A8D776F62D8D342D007EAB35 /* OperationQueue */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				A840A7F82D916D8E0044B8B9 /* TSGeneratePosterOperation */,
-				A840A7F72D916D7F0044B8B9 /* TSGeneratePhotoOperation */,
-				A840A7E92D8D81350044B8B9 /* TSGenerateRintoneOperation */,
+				A840A8012D91944F0044B8B9 /* TSGenerateBaseOperation */,
 				A8D776F72D8D343F007EAB35 /* TSBaseOperationQueue.swift */,
 				A8D776F72D8D343F007EAB35 /* TSBaseOperationQueue.swift */,
 				A8D776F92D8D345B007EAB35 /* TSBaseOperation.swift */,
 				A8D776F92D8D345B007EAB35 /* TSBaseOperation.swift */,
 			);
 			);
@@ -1199,7 +1183,6 @@
 			files = (
 			files = (
 				A899D3742D87B15F00AB9C1C /* TSPurchaseTool.swift in Sources */,
 				A899D3742D87B15F00AB9C1C /* TSPurchaseTool.swift in Sources */,
 				A868A9072D77EED800F6D884 /* TSTGPTitleView.swift in Sources */,
 				A868A9072D77EED800F6D884 /* TSTGPTitleView.swift in Sources */,
-				A840A7EB2D8D81CD0044B8B9 /* TSGenerateRintoneOperationQueue.swift in Sources */,
 				A868A8C22D76A2A700F6D884 /* UIFont+TSEx.swift in Sources */,
 				A868A8C22D76A2A700F6D884 /* UIFont+TSEx.swift in Sources */,
 				A868A91A2D78559800F6D884 /* TSProgressState.swift in Sources */,
 				A868A91A2D78559800F6D884 /* TSProgressState.swift in Sources */,
 				A899D3842D88303E00AB9C1C /* TSDiscoverVC.swift in Sources */,
 				A899D3842D88303E00AB9C1C /* TSDiscoverVC.swift in Sources */,
@@ -1212,6 +1195,7 @@
 				A8D776FA2D8D345C007EAB35 /* TSBaseOperation.swift in Sources */,
 				A8D776FA2D8D345C007EAB35 /* TSBaseOperation.swift in Sources */,
 				A899D3602D82C8D800AB9C1C /* TSPurchaseManager.swift in Sources */,
 				A899D3602D82C8D800AB9C1C /* TSPurchaseManager.swift in Sources */,
 				A868A8F12D77081C00F6D884 /* TSContactsTool.swift in Sources */,
 				A868A8F12D77081C00F6D884 /* TSContactsTool.swift in Sources */,
+				A840A8032D91945A0044B8B9 /* TSGenerateBaseOperation.swift in Sources */,
 				A80EDF2D2D71C2CA003CD332 /* TSThemeModel.swift in Sources */,
 				A80EDF2D2D71C2CA003CD332 /* TSThemeModel.swift in Sources */,
 				A80EDE582D718623003CD332 /* AppDelegate.swift in Sources */,
 				A80EDE582D718623003CD332 /* AppDelegate.swift in Sources */,
 				A868A8EF2D77041400F6D884 /* TSLoadingAnimation.swift in Sources */,
 				A868A8EF2D77041400F6D884 /* TSLoadingAnimation.swift in Sources */,

+ 62 - 31
AIRingtone/AppDelegate.swift

@@ -7,6 +7,7 @@
 
 
 import UIKit
 import UIKit
 
 
+var kAppNewVerison = ""
 @main
 @main
 class AppDelegate: UIResponder, UIApplicationDelegate {
 class AppDelegate: UIResponder, UIApplicationDelegate {
 
 
@@ -55,7 +56,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
 
     func initPlatform() {
     func initPlatform() {
         TSColorConfigShared.naviMianTextColor = .white
         TSColorConfigShared.naviMianTextColor = .white
-        purchaseDidChanged()
     }
     }
 
 
 }
 }
@@ -63,10 +63,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 extension AppDelegate {
 extension AppDelegate {
 
 
     func applicationDidEnterBackground(_ application: UIApplication) {
     func applicationDidEnterBackground(_ application: UIApplication) {
+        
+//        // 2. 获取上次弹窗的日期
+//        let userDefaults = UserDefaults.standard
+//        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
+//        userDefaults.set(String(Int(lastGreetingDateString!)!+1), forKey: "kEveryDayPopPurchase")//测试用的
+
         TSBusinessAudioPlayer.shared.stop()
         TSBusinessAudioPlayer.shared.stop()
         beginBackgroundTask()
         beginBackgroundTask()
     }
     }
     
     
+    
+    func applicationWillEnterForeground(_ application: UIApplication) {
+        handleShowEveryDayPopPurchase()
+        checkAppConfig()
+    }
     func beginBackgroundTask() {
     func beginBackgroundTask() {
         backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask { [weak self] in
         backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask { [weak self] in
             self?.endBackgroundTask()
             self?.endBackgroundTask()
@@ -81,49 +92,69 @@ extension AppDelegate {
     }
     }
     
     
     func applicationWillTerminate(_ application: UIApplication) {
     func applicationWillTerminate(_ application: UIApplication) {
-        
+    
     }
     }
     
     
 }
 }
 
 
 extension AppDelegate {
 extension AppDelegate {
     
     
-    
-    func purchaseDidChanged(){
-//        NotificationCenter.default.addObserver(forName: .kPurchasePrepared, object: nil, queue: OperationQueue.main) {notification in
-//            self.showEveryDayPopPurchase()
-//        }
+    func handleShowEveryDayPopPurchase() {
+        AppDelegate.showEveryDayPopPurchase { vc in
+            if let vc = vc ,let rootvc = self.window?.rootViewController {
+                vc.modalPresentationStyle = .fullScreen
+                rootvc.present(vc, animated: true)
+            }
+        }
     }
     }
     
     
-    func showEveryDayPopPurchase() {
-            // 1. 获取当前日期
-            let currentDate = Date()
-            let dateFormatter = DateFormatter()
-            dateFormatter.dateFormat = "yyyy-MM-dd"
-            let currentDateString = dateFormatter.string(from: currentDate)
-            
-            // 2. 获取上次弹窗的日期
-            let userDefaults = UserDefaults.standard
-            let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
+    static func showEveryDayPopPurchase(showVCHandle:@escaping (UIViewController?)->Void) {
+        
+        if UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil || kPurchaseToolShared.isVip {
+            //启动页->引导图->会员购买
+            showVCHandle(nil)
+            return
+        }
+        
+        //启动页->会员购买
+        // 1. 获取当前日期
+        let currentDate = Date()
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "yyyyMMdd"
+        let currentDateString = dateFormatter.string(from: currentDate)
+        
+        // 2. 获取上次弹窗的日期
+        let userDefaults = UserDefaults.standard
+        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
+        
+        // 3. 检查是否需要显示弹窗 "20250319"
+        if lastGreetingDateString != currentDateString {
             
             
-            // 3. 检查是否需要显示弹窗 "2025-03-19"
-            if lastGreetingDateString != currentDateString {
-                
-                // 4. 弹窗付费引导
-                if showTSPurchaseVC() {
-                    // 5. 更新上次弹窗的日期
-                    userDefaults.set(currentDateString, forKey: "kEveryDayPopPurchase")
-                }
+            // 4. 弹窗付费引导
+            let vc = TSPurchaseVC()
+            vc.closePageBlock = {
+                showVCHandle(nil)
             }
             }
+
+            showVCHandle(vc)
+            // 5. 更新上次弹窗的日期
+            userDefaults.set(currentDateString, forKey: "kEveryDayPopPurchase")
+            
+//            userDefaults.set(String(Int(currentDateString)!+1), forKey: "kEveryDayPopPurchase")测试用的
+        }else{
+            showVCHandle(nil)
+        }
     }
     }
     
     
-    func showTSPurchaseVC() -> Bool{
-        if kPurchaseDefault.products.count > 0 {
-            if let vc = window?.rootViewController {
-                TSPurchaseVC.show(target: vc, closePageBlock: nil)
-                return true
+    func checkAppConfig(){
+        _ = TSNetworkShared.get(urlType: .config) { [weak self] data,error in
+            guard let self = self else { return }
+            
+            if let result = kNetWorkResultSuccess(data: data) {
+                kAppNewVerison = result.safeString(forKey: "version")
             }
             }
+     
         }
         }
-        return false
     }
     }
+    
 }
 }

+ 47 - 41
AIRingtone/Business/LaunchVC/TSLaunchVC.swift

@@ -58,9 +58,13 @@ class TSLaunchVC: UIViewController {
     }
     }
 
 
     func enterApp() {
     func enterApp() {
-        
-        showEveryDayPopPurchase()
-        
+        AppDelegate.showEveryDayPopPurchase { vc in
+            if let vc = vc {
+                self.navigationController?.pushViewController(vc, animated: true)
+            }else{
+                self.dismissHandler?()
+            }
+        }
 //        DispatchQueue.main.async {
 //        DispatchQueue.main.async {
 //            self.dismissHandler?()
 //            self.dismissHandler?()
 //        }
 //        }
@@ -120,42 +124,44 @@ class TSLaunchVC: UIViewController {
 
 
 extension TSLaunchVC {
 extension TSLaunchVC {
     
     
-    func showEveryDayPopPurchase() {
-        
-        if UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil || kPurchaseToolShared.isVip {
-            //启动页->引导图->会员购买
-            dismissHandler?()
-            return
-        }
-        
-        //启动页->会员购买
-        // 1. 获取当前日期
-        let currentDate = Date()
-        let dateFormatter = DateFormatter()
-        dateFormatter.dateFormat = "yyyyMMdd"
-        let currentDateString = dateFormatter.string(from: currentDate)
-        
-        // 2. 获取上次弹窗的日期
-        let userDefaults = UserDefaults.standard
-        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
-        
-        // 3. 检查是否需要显示弹窗 "20250319"
-        if lastGreetingDateString != currentDateString {
-            
-            // 4. 弹窗付费引导
-            let vc = TSPurchaseVC()
-            vc.closePageBlock = { [weak self]  in
-                guard let self = self else { return }
-                dismissHandler?()
-            }
-            self.navigationController?.pushViewController(vc, animated: true)
-        
-            // 5. 更新上次弹窗的日期
-            userDefaults.set(currentDateString, forKey: "kEveryDayPopPurchase")
-            
-//            userDefaults.set(String(Int(currentDateString)!+1), forKey: "kEveryDayPopPurchase")测试用的
-        }else{
-            dismissHandler?()
-        }
-    }
+//    func showEveryDayPopPurchase() {
+//        
+//        if UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil || kPurchaseToolShared.isVip {
+//            //启动页->引导图->会员购买
+//            dismissHandler?()
+//            return
+//        }
+//        
+//        //启动页->会员购买
+//        // 1. 获取当前日期
+//        let currentDate = Date()
+//        let dateFormatter = DateFormatter()
+//        dateFormatter.dateFormat = "yyyyMMdd"
+//        let currentDateString = dateFormatter.string(from: currentDate)
+//        
+//        // 2. 获取上次弹窗的日期
+//        let userDefaults = UserDefaults.standard
+//        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
+//        
+//        // 3. 检查是否需要显示弹窗 "20250319"
+//        if lastGreetingDateString != currentDateString {
+//            
+//            // 4. 弹窗付费引导
+//            let vc = TSPurchaseVC()
+//            vc.closePageBlock = { [weak self]  in
+//                guard let self = self else { return }
+//                dismissHandler?()
+//            }
+//            self.navigationController?.pushViewController(vc, animated: true)
+//        
+//            // 5. 更新上次弹窗的日期
+//            userDefaults.set(currentDateString, forKey: "kEveryDayPopPurchase")
+//            
+////            userDefaults.set(String(Int(currentDateString)!+1), forKey: "kEveryDayPopPurchase")测试用的
+//        }else{
+//            dismissHandler?()
+//        }
+//    }
+    
+
 }
 }

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

@@ -197,12 +197,14 @@ class TSImageGenerateView:TSBaseView {
         }else if style == .photoHistory {
         }else if style == .photoHistory {
             infoLabel.text = "Working on your contact photo\(progressInt)%..."
             infoLabel.text = "Working on your contact photo\(progressInt)%..."
         }
         }
-        
+        infoLabel.textColor = "#E961F6".uiColor
+//        infoLabel.applyGradient(colors: ["#E961F6".uiColor,"#7E57F4".uiColor])
     }
     }
     
     
     func setFail(){
     func setFail(){
         setProgress(progress: 0.0)
         setProgress(progress: 0.0)
         infoLabel.text = "Generation Failed".localized
         infoLabel.text = "Generation Failed".localized
+        infoLabel.textColor = .white
         refreshBtn.isHidden = false
         refreshBtn.isHidden = false
     }
     }
 }
 }

+ 4 - 3
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/TSTextGeneralPicVC.swift

@@ -19,7 +19,7 @@ class TSTextGeneralPicVC: TSBaseVC {
         let viewModel:TSTextGeneralPicVM = TSTextGeneralPicVM()
         let viewModel:TSTextGeneralPicVM = TSTextGeneralPicVM()
         viewModel.isCanGennerateBlock = { [weak self] enabled in
         viewModel.isCanGennerateBlock = { [weak self] enabled in
             guard let self = self else { return }
             guard let self = self else { return }
-            creatBtnView.setBtnEnabled(isEnabled: enabled)
+            setCreatBtnEnabled()
         }
         }
         return viewModel
         return viewModel
     }()
     }()
@@ -51,9 +51,9 @@ class TSTextGeneralPicVC: TSBaseVC {
         let photoStyleView = TSTGPPhotoStyleView()
         let photoStyleView = TSTGPPhotoStyleView()
         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
             creatBtnView.vipFreeNumType = vipFreeNumType
             creatBtnView.vipFreeNumType = vipFreeNumType
             selectedIndex?(index)
             selectedIndex?(index)
+            viewModel.gennerateType = TSGennerateType(rawValue: index) ?? .poster
         }
         }
         photoStyleView.moreInfoBtn.addTarget(self, action: #selector(clickMoreInfoBtn), for: .touchUpInside)
         photoStyleView.moreInfoBtn.addTarget(self, action: #selector(clickMoreInfoBtn), for: .touchUpInside)
         return photoStyleView
         return photoStyleView
@@ -182,7 +182,6 @@ extension TSTextGeneralPicVC {
         let gennerateVC = TSGeneralPicVC(prompt: viewModel.prompt, promptSort: viewModel.promptSort, gennerateType: viewModel.gennerateType) { [weak self] model in
         let gennerateVC = TSGeneralPicVC(prompt: viewModel.prompt, promptSort: viewModel.promptSort, gennerateType: viewModel.gennerateType) { [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)
 //            NotificationCenter.default.post(name: .kReloadUIData, object: nil, userInfo: ["TSGennerateType": viewModel.gennerateType])
 //            NotificationCenter.default.post(name: .kReloadUIData, object: nil, userInfo: ["TSGennerateType": viewModel.gennerateType])
         }
         }
         
         
@@ -198,7 +197,9 @@ extension TSTextGeneralPicVC {
         if viewModel.isCanGennerate,isAvailability {
         if viewModel.isCanGennerate,isAvailability {
             creatBtnView.setBtnEnabled(isEnabled: true)
             creatBtnView.setBtnEnabled(isEnabled: true)
             creatBtnView.loadingAnimation(loading: false)
             creatBtnView.loadingAnimation(loading: false)
+            dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
         }else{
         }else{
+            dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
             creatBtnView.setBtnEnabled(isEnabled: false)
             creatBtnView.setBtnEnabled(isEnabled: false)
             creatBtnView.loadingAnimation(loading: !isAvailability)
             creatBtnView.loadingAnimation(loading: !isAvailability)
         }
         }

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

@@ -92,11 +92,4 @@ extension TSTextGeneralPicVM {
         return promptText
         return promptText
     }
     }
 
 
-//    func saveModel(model:TSActionInfoModel){
-//        if gennerateType == .poster {
-//            TSPosterHistory.saveModel(model: model)
-//        }else if gennerateType == .photo{
-//            TSPhotoHistory.saveModel(model: model)
-//        }
-//    }
 }
 }

+ 10 - 8
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptTextView.swift

@@ -52,6 +52,10 @@ class TSPromptTextView : TSBaseView{
         )
         )
         customTextView.delegate = self
         customTextView.delegate = self
         customTextView.returnKeyType = .done
         customTextView.returnKeyType = .done
+        customTextView.textViewTextChanged = { [weak self]  in
+            guard let self = self else { return }
+            textViewTextChanged(textView: customTextView)
+        }
         return customTextView
         return customTextView
     }()
     }()
     
     
@@ -66,7 +70,7 @@ class TSPromptTextView : TSBaseView{
         { [weak self]  in
         { [weak self]  in
             guard let self = self else { return }
             guard let self = self else { return }
             customTextView.text = randomTextPicker.getRandomText()
             customTextView.text = randomTextPicker.getRandomText()
-            textViewDidChange(customTextView)
+            textViewTextChanged(textView: customTextView)
         }
         }
         inspirationBtn.contentEdgeInsets = UIEdgeInsets(top: 4, left: 40, bottom: 4, right: 50)
         inspirationBtn.contentEdgeInsets = UIEdgeInsets(top: 4, left: 40, bottom: 4, right: 50)
         inspirationBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 0)
         inspirationBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 0)
@@ -80,7 +84,7 @@ class TSPromptTextView : TSBaseView{
         { [weak self]  in
         { [weak self]  in
             guard let self = self else { return }
             guard let self = self else { return }
             customTextView.text = ""
             customTextView.text = ""
-            textViewDidChange(customTextView)
+            textViewTextChanged(textView: customTextView)
         }
         }
         clearBtn.setImage(UIImage(named: "clear_gary_text"), for: .disabled)
         clearBtn.setImage(UIImage(named: "clear_gary_text"), for: .disabled)
         clearBtn.isEnabled = false
         clearBtn.isEnabled = false
@@ -175,16 +179,14 @@ class TSPromptTextView : TSBaseView{
         return "Generate"
         return "Generate"
     }
     }
     
     
-}
-
-extension TSPromptTextView: UITextViewDelegate{
-
-    func textViewDidChange(_ textView: UITextView) {
+    func textViewTextChanged(textView: UITextView) {
         currenMun = textView.text.count
         currenMun = textView.text.count
         clearBtn.isEnabled = currenMun > 0
         clearBtn.isEnabled = currenMun > 0
         textChangedBlock(textView.text)
         textChangedBlock(textView.text)
     }
     }
-    
+}
+
+extension TSPromptTextView: UITextViewDelegate{
     // 监听键盘的 Return 键(Done 键)
     // 监听键盘的 Return 键(Done 键)
      func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
      func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
          if text == "\n" { // 检测到 Return 键
          if text == "\n" { // 检测到 Return 键

+ 4 - 23
AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/TSAIRintoneVC.swift

@@ -116,38 +116,19 @@ class TSAIRintoneVC: TSBaseVC {
             collectionView.reloadData()
             collectionView.reloadData()
         }
         }
         
         
-//        NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationStart, object: nil, queue: nil) { notification in
-//            self.viewModel.updateRecentData()
-//            self.updateListView()
-//        }
-  
         NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) { notification in
         NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) { notification in
             if let userInfo = notification.userInfo as? [String: Any], let uuid = userInfo["uuid"] as? String,let state = userInfo["state"] as? TSProgressState {
             if let userInfo = notification.userInfo as? [String: Any], let uuid = userInfo["uuid"] as? String,let state = userInfo["state"] as? TSProgressState {
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
                 switch state {
                 switch state {
-                case .start, .success(_),.failed(_):
+                case .start:
                     self.viewModel.updateRecentData()
                     self.viewModel.updateRecentData()
                     self.updateGeneratedHistory()
                     self.updateGeneratedHistory()
+//                case .start, .success(_),.failed(_):
+//                    self.viewModel.updateRecentData()
+//                    self.updateGeneratedHistory()
                 default:break
                 default:break
                 }
                 }
             }
             }
-            
-//            if let userInfo = notification.userInfo as? [String: Any], let uuid = userInfo["uuid"] as? String{
-//                
-//                if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateRintoneOperation {
-//                    switch rintoneOperation.stateDatauPblished.0 {
-//                    case .start, .success(_),.failed(_):
-//                        self.viewModel.updateRecentData()
-//                        self.updateListView()
-//                    default:break
-//                    }
-//                }
-//            }
-            
-//            if let userInfo = notification.userInfo as? [String: Any], let uuid = userInfo["uuid"] as? String,let state = userInfo["state"] as? TSProgressState {
-//                self.viewModel.updateRecentData()
-//                self.updateGeneratedList(num: 1)
-//            }
         }
         }
         
         
         TSAIRintoneHistory.dePrintAllModel()
         TSAIRintoneHistory.dePrintAllModel()

+ 0 - 1
AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/View/TSAIRintoneHistoryCell.swift

@@ -105,7 +105,6 @@ class TSAIRintoneHistoryCell: SwipeCollectionViewCell  {
             if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: model.uuid) as? TSGenerateRintoneOperation {
             if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: model.uuid) as? TSGenerateRintoneOperation {
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
                     rintoneOperation.currentActionInfoModelChanged =
                     rintoneOperation.currentActionInfoModelChanged =
-                    
                     //                rintoneOperation.$currentActionInfoModel.sink
                     //                rintoneOperation.$currentActionInfoModel.sink
                     { [weak self] actionInfoModel in
                     { [weak self] actionInfoModel in
                         guard let self = self else { return }
                         guard let self = self else { return }

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

@@ -7,9 +7,10 @@
 
 
 enum SettingType: String, CaseIterable {
 enum SettingType: String, CaseIterable {
     case tutorial = "Tutorial"
     case tutorial = "Tutorial"
+    case update = "Update"
     case rateus = "Rate us"
     case rateus = "Rate us"
     case shareus = "Share us"
     case shareus = "Share us"
     case privacy = "Privacy Policy"
     case privacy = "Privacy Policy"
     case agreement = "Terms of Service"
     case agreement = "Terms of Service"
-    case about = "About us"
+//    case about = "About us"
 }
 }

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

@@ -82,8 +82,11 @@ class TSSetingVC: TSBaseVC {
                 viewModel.showAgreement(parent: self)
                 viewModel.showAgreement(parent: self)
             case .privacy:
             case .privacy:
                 viewModel.showPrivacy(parent: self)
                 viewModel.showPrivacy(parent: self)
-            case .about:
+            case .update:
+                viewModel.updateApp(parent: self)
                 break
                 break
+//            case .about:
+//                break
             case .rateus:
             case .rateus:
                 viewModel.rateAction()
                 viewModel.rateAction()
             }
             }

+ 8 - 0
AIRingtone/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift

@@ -44,7 +44,15 @@ class TSSetingViewModel: ObservableObject {
         parent.present(vc, animated: true)
         parent.present(vc, animated: true)
         
         
     }
     }
+    func updateApp(parent: UIViewController) {
+        let httpAppStoreLink = "https://apps.apple.com/app/id\(appid)"
+        if let url = URL(string: httpAppStoreLink),
+            UIApplication.shared.canOpenURL(url) {
+            UIApplication.shared.open(url)
+        }
+    }
     
     
+
     func rateAction() {
     func rateAction() {
         let countKey = "ProcessCompletedCountKey"
         let countKey = "ProcessCompletedCountKey"
         // If the app doesn't store the count, this returns 0.
         // If the app doesn't store the count, this returns 0.

+ 12 - 3
AIRingtone/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift

@@ -52,11 +52,20 @@ struct SettingListItemView: View {
             HStack {
             HStack {
                 Text(type.rawValue).font(.font(size: 16.0)).foregroundColor(.white)
                 Text(type.rawValue).font(.font(size: 16.0)).foregroundColor(.white)
                 Spacer()
                 Spacer()
-                if type != .about {
-                    Image(.whiteRightArrow)
-                }else{
+//                if type != .about {
+//                    Image(.whiteRightArrow)
+//                }else{
+//                    Text(appVersion()).foregroundColor(.hex("#FFFFFF").opacity(0.4)).font(.font(size: 16))
+//                }
+                if type == .update {
+                    if kAppNewVerison != appVersion() {
+                        Color.hex("#E661F6").frame(width: 4, height: 4).cornerRadius(2)
+                        Spacer().frame(width: 4)
+                    }
                     Text(appVersion()).foregroundColor(.hex("#FFFFFF").opacity(0.4)).font(.font(size: 16))
                     Text(appVersion()).foregroundColor(.hex("#FFFFFF").opacity(0.4)).font(.font(size: 16))
                 }
                 }
+            
+                Image(.whiteRightArrow)
             }.padding(.horizontal)
             }.padding(.horizontal)
         }
         }
         .frame(height: 64)
         .frame(height: 64)

+ 1 - 9
AIRingtone/Common/Ex/Notification+TSEx.swift

@@ -9,17 +9,9 @@
 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免费次数发生变化
     static let kVipFreeNumChanged = Notification.Name("kVipFreeNumChanged")   //Vip免费次数发生变化
     
     
-    static let kGenerateRintoneOperationStart = Notification.Name("kGenerateRintoneOperationStart") //生成铃声任务开发
-    
-    
-    
-    
     static let kBaseOperationQueueCountChanged = Notification.Name("kBaseOperationQueueCountChanged") //任务数量放生变化
     static let kBaseOperationQueueCountChanged = Notification.Name("kBaseOperationQueueCountChanged") //任务数量放生变化
     static let kGenerateRintoneOperationChanged = Notification.Name("kGenerateRintoneOperationChanged") //生成铃声任务发生变化
     static let kGenerateRintoneOperationChanged = Notification.Name("kGenerateRintoneOperationChanged") //生成铃声任务发生变化
     static let kGeneratePosterOperationChanged = Notification.Name("kGeneratePosterOperationChanged") //生成海报任务发生变化
     static let kGeneratePosterOperationChanged = Notification.Name("kGeneratePosterOperationChanged") //生成海报任务发生变化

+ 1 - 0
AIRingtone/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift

@@ -25,6 +25,7 @@ enum TSNeURLType:String {
     case rings = "/api/ops/rings"                       //铃声分类下内容接口
     case rings = "/api/ops/rings"                       //铃声分类下内容接口
     case ringRecommend = "/api/ops/ring-recommend"       //铃声内容推荐接口
     case ringRecommend = "/api/ops/ring-recommend"       //铃声内容推荐接口
     
     
+    case config = "/api/ops/ring-config"       //App配置
     func getUrlString() -> String {
     func getUrlString() -> String {
         return baseURL + self.rawValue
         return baseURL + self.rawValue
     }
     }

+ 142 - 0
AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift

@@ -0,0 +1,142 @@
+//
+//  TSGenerateBaseOperation.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/24.
+//
+
+import Combine
+import Alamofire
+class TSGenerateBaseOperationQueue: TSBaseOperationQueue {
+    // 存储每个操作的 AnyCancellable
+    var stateables: [String: AnyCancellable] = [:]
+    
+    var generateOperationStateChanged:((String)->Void)?
+    
+    
+    override func cancelOperations(uuid: String) {
+        super.cancelOperations(uuid: uuid)
+        stateables.removeValue(forKey: uuid)
+    }
+
+    func handleStateDatauPblished(uuid:String,generateOperation: TSGenerateBaseOperation,notificationName:Notification.Name) {
+        stateables[uuid] = generateOperation.$stateDatauPblished.sink { [weak self] state in
+            guard let self = self else { return }
+            DispatchQueue.main.async {
+                self.generateOperationStateChanged?(uuid)
+                
+                let uuidData = self.getUUIDData(uuid: uuid)
+                NotificationCenter.default.post(
+                    name: notificationName,
+                    object: nil,
+                    userInfo: [
+                        "uuid": uuid,
+                        "count":self.queue.maxConcurrentOperationCount,
+                        "state":uuidData.0,
+                        "actionInfo":uuidData.1,
+                    ])
+            }
+        }
+    }
+    
+    func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+        return (.none,TSActionInfoModel())
+    }
+    
+}
+
+class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
+    
+    var actionInfoDict:[String:Any]{
+        return [
+            "actionType":"music_create",
+            "comments": "Success",
+            "costTime":15,
+            "createdTimestamp":1741338454,
+            "id":1536,
+            "percent":1,
+            "request":"{\"prompt\": \"Create a Techno ringtone with a repetitive bassline, crisp hi-hats, and subtle synth textures. Use a BPM of 125-130 for a sleek, modern sound., Create a uplifting and modern music track blending Pop, Electronic, and Ambient elements. Use a BPM of 100-120, a catchy melody with synth or piano, warm harmonies, and a mix of electronic and organic sounds. Ensure a clear structure (Intro, Verse, Chorus, Outro) and a light, positive vibe suitable for background or casual listening\", \"duration\": 5}",
+            "response":"{\"coverUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/f0fb7739-a5cc-4805-9b68-b4a5890eb285.png\", \"title\": \"Neon Pulse\\\"  \\n\\\"Horizon Glow\", \"musicUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/c47d40dd-d07c-4edc-a6d9-8382438149d1.wav\"}",
+            "status":"success"
+        ]
+    }
+    
+    @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
+        didSet{
+            dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
+            if case .start = stateDatauPblished.0 {
+                start()
+            }else if stateDatauPblished.0.isResult {
+                finished()
+            }
+        }
+    }
+    
+    var creatRequest:Request?
+    var queryRequest:Request?
+    var stopNetwork = false
+    var generatingProgress = 0
+    var action_id:Int = 0
+    
+    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
+    @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
+    
+    func getActionInfo(action_id:Int){
+        self.action_id = action_id
+        queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
+            guard let self = self else { return }
+            if let result = kNetWorkResultSuccess(data: data) {
+                if let genmojiModel = TSActionInfoModel(JSON: result) {
+                    switch genmojiModel.actionStatus {
+                    case .success:
+                        TSToastShared.hideLoading()
+                        self.stateDatauPblished = (.success(nil),genmojiModel)
+                        generatingProgress = 0
+                    case .failed:
+                        self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
+                        generatingProgress = 0
+                    default:
+                        stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
+                        if stopNetwork == false {
+                            kDelayOnMainThread(1.0) {
+                                self.getActionInfo(action_id: action_id)
+                            }
+                        }
+                    }
+                }
+            }else{
+                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
+            }
+        }
+    }
+     func generating(progress:Float) -> String {
+
+         //Generating 0%-100%
+         var progressInt = Int(progress*100)
+
+         if generatingProgress >= progressInt{
+             return getGeneratingProgressText()
+         }
+
+         if progressInt > 99 {
+             progressInt = 99
+         }
+         
+         generatingProgress = progressInt
+         return getGeneratingProgressText()
+     }
+     
+     
+    func getGeneratingProgressText()->String{
+        return "Generating \(generatingProgress)%"
+    }
+     
+     func cancelAllRequest(){
+         creatRequest?.cancel()
+         queryRequest?.cancel()
+         stopNetwork = true
+         
+         cancel()
+     }
+     
+}

+ 135 - 0
AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePhotoOperation.swift

@@ -0,0 +1,135 @@
+//
+//  TSGeneratePhotoOperation.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/24.
+//
+import Combine
+import Alamofire
+class TSGeneratePhotoOperationQueue: TSGenerateBaseOperationQueue {
+
+    static let shared:TSGeneratePhotoOperationQueue = TSGeneratePhotoOperationQueue()
+    func creatOperation(uuid: String) -> TSGeneratePhotoOperation {
+        let operation = super.creatOperation(uuid: uuid, type: TSGeneratePhotoOperation.self)
+        handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGeneratePhotoOperationChanged)
+        return operation as! TSGeneratePhotoOperation
+    }
+    
+    override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+        if let photoOperation = TSGeneratePhotoOperationQueue.shared.findOperation(uuid: uuid) as? TSGeneratePhotoOperation {
+            dePrint("TSBaseOperation stateDatauPblished 发送 = \(photoOperation.stateDatauPblished)")
+            return (photoOperation.stateDatauPblished.0,photoOperation.currentActionInfoModel)
+        }
+        return (.none,TSActionInfoModel())
+    }
+}
+
+class TSGeneratePhotoOperation: TSGenerateBaseOperation , @unchecked Sendable{
+    override var actionInfoDict:[String:Any]{
+        return [
+            "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"
+        ]
+    }
+
+
+    var gennerateType:TSGennerateType = .photo
+
+    func replaceSaveInfoModel(model:TSActionInfoModel){
+        model.uuid = uuid
+        TSPhotoHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
+        currentActionInfoModel = model
+        dePrint("TSPhotoHistory.listModelArray.count=\(TSPhotoHistory.listModelArray.count)")
+        dePrint("model actionStatus 发出=\(model.actionStatus)")
+        currentActionInfoModelChanged?(currentActionInfoModel)
+    }
+    
+    //模拟数据
+    func creatPhoto(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
+        stateDatauPblished = (.start,nil)
+        if let model = oldModel {
+            currentActionInfoModel = model
+        }else {
+            currentActionInfoModel.id = Int.timestampInt()
+            currentActionInfoModel.request.prompt = prompt
+            currentActionInfoModel.request.promptSort = promptSort
+            currentActionInfoModel.actionStatus = .pending
+            currentActionInfoModel.status = "pending"
+        }
+        
+        replaceSaveInfoModel(model: currentActionInfoModel)
+        stateDatauPblished = (.start,currentActionInfoModel)
+        let time = 5.0
+        
+        for i in 0..<Int(time){
+            kDelayOnMainThread(Double(i)) {
+                let progress = Float(i)/100.0
+                self.currentActionInfoModel.percent = progress
+                self.currentActionInfoModel.actionStatus = .running
+                self.currentActionInfoModel.status = "running"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
+            }
+        }
+
+        kDelayOnMainThread(time+1.0) {
+            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
+                infoModel.id = Int.uuid
+                self.replaceSaveInfoModel(model: infoModel)
+                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
+            }else{
+                self.currentActionInfoModel.actionStatus = .failed
+                self.currentActionInfoModel.status = "failed"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
+            }
+//            TSPhotoHistory.dePrintAllModel()
+        }
+    }
+    
+
+    
+//    //width 和 height 必须是 32 的倍数
+//    func creatImageEmoji(text:String) {
+//        generatingProgress = 0
+//        aiText = text
+//        let postDict:[String : Any] = [
+//            "prompt":text,
+//            "width":textPicW,
+//            "height":textPicH
+//        ]
+//        stateDatauPblished = (.start,nil)
+//        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
+//        creatRequest = TSNetworkShared.post(urlType: .textPicCreate,parameters: postDict) { [weak self] data,error in
+//            guard let self = self else { return }
+//            if let dataDict = data as? [String:Any] ,
+//               dataDict.safeInt(forKey: "code") == 200,
+//               let actionId = dataDict["actionId"] as? Int{
+//                if stopNetwork == false {
+//                    self.getActionInfo(action_id:actionId)
+//                }
+//            }else{
+//                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
+//            }
+//        }
+//    }
+    
+    override func getGeneratingProgressText()->String{
+        return "Working on your contact Photo \(generatingProgress)% ..."
+    }
+
+    var textPicW:Int{
+        return kTextPicW
+    }
+    
+    var textPicH:Int{
+        return kTextPicW
+    }
+}

+ 136 - 0
AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift

@@ -0,0 +1,136 @@
+//
+//  TSGeneratePosterOperation.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/24.
+//
+import Combine
+import Alamofire
+class TSGeneratePosterOperationQueue: TSGenerateBaseOperationQueue {
+    static let shared:TSGeneratePosterOperationQueue = TSGeneratePosterOperationQueue()
+
+    func creatOperation(uuid: String) -> TSGeneratePosterOperation {
+        let operation = super.creatOperation(uuid: uuid, type: TSGeneratePosterOperation.self)
+        handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGeneratePosterOperationChanged)
+        return operation as! TSGeneratePosterOperation
+    }
+    
+    override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+        if let PosterOperation = TSGeneratePosterOperationQueue.shared.findOperation(uuid: uuid) as? TSGeneratePosterOperation {
+            dePrint("TSBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
+            return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
+        }
+        return (.none,TSActionInfoModel())
+    }
+    
+}
+
+class TSGeneratePosterOperation: TSGenerateBaseOperation , @unchecked Sendable{
+    
+    override var actionInfoDict:[String:Any]{
+        return [
+            "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"
+        ]
+    }
+    var gennerateType:TSGennerateType = .poster
+
+
+    func replaceSaveInfoModel(model:TSActionInfoModel){
+        model.uuid = uuid
+        TSPosterHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
+        currentActionInfoModel = model
+        dePrint("TSPosterHistory.listModelArray.count=\(TSPosterHistory.listModelArray.count)")
+        dePrint("model actionStatus 发出=\(model.actionStatus)")
+        currentActionInfoModelChanged?(currentActionInfoModel)
+    }
+
+    //模拟数据
+    func creatPoster(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
+        stateDatauPblished = (.start,nil)
+        if let model = oldModel {
+            currentActionInfoModel = model
+        }else {
+            currentActionInfoModel.id = Int.timestampInt()
+            currentActionInfoModel.request.prompt = prompt
+            currentActionInfoModel.request.promptSort = promptSort
+            currentActionInfoModel.actionStatus = .pending
+            currentActionInfoModel.status = "pending"
+        }
+        
+        replaceSaveInfoModel(model: currentActionInfoModel)
+        stateDatauPblished = (.start,currentActionInfoModel)
+        let time = 100.0
+        
+        for i in 0..<Int(time){
+            kDelayOnMainThread(Double(i)) {
+                let progress = Float(i)/100.0
+                self.currentActionInfoModel.percent = progress
+                self.currentActionInfoModel.actionStatus = .running
+                self.currentActionInfoModel.status = "running"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
+            }
+        }
+
+        kDelayOnMainThread(time+1.0) {
+            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
+                infoModel.id = Int.uuid
+                self.replaceSaveInfoModel(model: infoModel)
+                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
+            }else{
+                self.currentActionInfoModel.actionStatus = .failed
+                self.currentActionInfoModel.status = "failed"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
+            }
+//            TSPosterHistory.dePrintAllModel()
+        }
+    }
+    
+
+    
+    //width 和 height 必须是 32 的倍数
+    func creatImageEmoji(text:String) {
+        generatingProgress = 0
+        let postDict:[String : Any] = [
+            "prompt":text,
+            "width":textPicW,
+            "height":textPicH
+        ]
+        stateDatauPblished = (.start,nil)
+        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
+        creatRequest = TSNetworkShared.post(urlType: .textPicCreate,parameters: postDict) { [weak self] data,error in
+            guard let self = self else { return }
+            if let dataDict = data as? [String:Any] ,
+               dataDict.safeInt(forKey: "code") == 200,
+               let actionId = dataDict["actionId"] as? Int{
+                if stopNetwork == false {
+                    self.getActionInfo(action_id:actionId)
+                }
+            }else{
+                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
+            }
+        }
+    }
+    
+
+    override func getGeneratingProgressText()->String{
+        return "Working on your contact poster \(generatingProgress)% ..."
+    }
+    
+    var textPicW:Int{
+        return kTextPicW
+    }
+    
+    var textPicH:Int{
+        return kTextPicH
+    }
+}

+ 108 - 0
AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateRintoneOperation.swift

@@ -0,0 +1,108 @@
+//
+//  TSGenerateRintoneOperation.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/21.
+//
+
+import Combine
+import Alamofire
+
+
+class TSGenerateRintoneOperationQueue: TSGenerateBaseOperationQueue {
+    static let shared:TSGenerateRintoneOperationQueue = TSGenerateRintoneOperationQueue()
+    func creatOperation(uuid: String) -> TSGenerateRintoneOperation {
+        let operation = super.creatOperation(uuid: uuid, type: TSGenerateRintoneOperation.self)
+        handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGenerateRintoneOperationChanged)
+        return operation as! TSGenerateRintoneOperation
+    }
+    
+    override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+        if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateRintoneOperation {
+            dePrint("TSBaseOperation stateDatauPblished 发送 = \(rintoneOperation.stateDatauPblished)")
+            return (rintoneOperation.stateDatauPblished.0,rintoneOperation.currentActionInfoModel)
+        }
+        return (.none,TSActionInfoModel())
+    }
+    
+
+}
+
+class TSGenerateRintoneOperation: TSGenerateBaseOperation , @unchecked Sendable{
+    
+    func replaceSaveInfoModel(model:TSActionInfoModel){
+        model.uuid = uuid
+        TSAIRintoneHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
+        currentActionInfoModel = model
+        dePrint("TSAIRintoneHistory.listModelArray.count=\(TSAIRintoneHistory.listModelArray.count)")
+        dePrint("model actionStatus 发出=\(model.actionStatus)")
+        currentActionInfoModelChanged?(currentActionInfoModel)
+    }
+
+    //模拟数据
+    func creatRintone(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
+        stateDatauPblished = (.start,nil)
+        if let model = oldModel {
+            currentActionInfoModel = model
+        }else {
+            currentActionInfoModel.id = Int.timestampInt()
+            currentActionInfoModel.request.prompt = prompt
+            currentActionInfoModel.request.promptSort = promptSort
+            currentActionInfoModel.actionStatus = .pending
+            currentActionInfoModel.status = "pending"
+        }
+        
+        replaceSaveInfoModel(model: currentActionInfoModel)
+        stateDatauPblished = (.start,currentActionInfoModel)
+        let time = 2.0
+        
+        for i in 0..<Int(time){
+            kDelayOnMainThread(Double(i)) {
+                let progress = Float(i)/100.0
+                self.currentActionInfoModel.percent = progress
+                self.currentActionInfoModel.actionStatus = .running
+                self.currentActionInfoModel.status = "running"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
+            }
+        }
+
+        kDelayOnMainThread(time+1.0) {
+            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
+                infoModel.id = Int.uuid
+                self.replaceSaveInfoModel(model: infoModel)
+                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
+            }else{
+                self.currentActionInfoModel.actionStatus = .failed
+                self.currentActionInfoModel.status = "failed"
+                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
+            }
+            TSAIRintoneHistory.dePrintAllModel()
+        }
+    }
+    
+//   func creatRintone(text:String) {
+//       generatingProgress = 0
+//       aiText = text
+//       let postDict:[String : Any] = [
+//           "prompt":text,
+//           "duration":20
+//       ]
+//       stateDatauPblished = (.start,nil)
+//       creatRequest = TSNetworkShared.post(urlType: .musicCreate,parameters: postDict) { [weak self] data,error in
+//           guard let self = self else { return }
+//           if let dataDict = data as? [String:Any] ,
+//              dataDict.safeInt(forKey: "code") == 200,
+//              let actionId = dataDict["actionId"] as? Int{
+//               if stopNetwork == false {
+//                   self.getActionInfo(action_id:actionId)
+//               }
+//           }else{
+//               self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
+//           }
+//       }
+//   }
+
+    
+}

+ 0 - 239
AIRingtone/Common/Tool/OperationQueue/TSGeneratePhotoOperation/TSGeneratePhotoOperation.swift

@@ -1,239 +0,0 @@
-//
-//  TSGeneratePhotoOperation.swift
-//  AIRingtone
-//
-//  Created by 100Years on 2025/3/24.
-//
-import Combine
-import Alamofire
-class TSGeneratePhotoOperationQueue: TSBaseOperationQueue {
-    static let shared:TSGeneratePhotoOperationQueue = TSGeneratePhotoOperationQueue()
-    
-    
-    // 存储每个操作的 AnyCancellable
-    private var stateables: [String: AnyCancellable] = [:]
-    
-    var photoOperationStateChanged:((String)->Void)?
-    
-
-    func creatOperation(uuid: String) -> TSGeneratePhotoOperation {
-        let operation = super.creatOperation(uuid: uuid, type: TSGeneratePhotoOperation.self)
-        if let photoOperation = operation as? TSGeneratePhotoOperation {
-            stateables[uuid] = photoOperation.$stateDatauPblished.sink { [weak self] state in
-                guard let self = self else { return }
-                DispatchQueue.main.async {
-                    self.photoOperationStateChanged?(uuid)
-                    
-                    let uuidData = self.getUUIDData(uuid: uuid)
-                    NotificationCenter.default.post(
-                        name: .kGeneratePhotoOperationChanged,
-                        object: nil,
-                        userInfo: [
-                            "uuid": uuid,
-                            "count":self.queue.maxConcurrentOperationCount,
-                            "state":uuidData.0,
-                            "actionInfo":uuidData.1,
-                        ])
-                }
-            }
-        }
-        return operation as! TSGeneratePhotoOperation
-    }
-    
-    func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
-        if let photoOperation = TSGeneratePhotoOperationQueue.shared.findOperation(uuid: uuid) as? TSGeneratePhotoOperation {
-            dePrint("TSBaseOperation stateDatauPblished 发送 = \(photoOperation.stateDatauPblished)")
-            return (photoOperation.stateDatauPblished.0,photoOperation.currentActionInfoModel)
-        }
-        return (.none,TSActionInfoModel())
-    }
-    
-    override func cancelOperations(uuid: String) {
-        super.cancelOperations(uuid: uuid)
-        stateables.removeValue(forKey: uuid)
-    }
-}
-
-class TSGeneratePhotoOperation: TSBaseOperation , @unchecked Sendable{
-    
-    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"
-    ]
-    
-    @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
-        didSet{
-            dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
-            if case .start = stateDatauPblished.0 {
-                start()
-            }else if stateDatauPblished.0.isResult {
-                finished()
-            }
-        }
-    }
-    var gennerateType:TSGennerateType = .photo
-    private var creatRequest:Request?
-    private var queryRequest:Request?
-    private var stopNetwork = false
-    private var generatingProgress = 0
-    private var aiText:String = ""
-    private var action_id:Int = 0
-   
-    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
-    @Published  var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
-
-    func replaceSaveInfoModel(model:TSActionInfoModel){
-        model.uuid = uuid
-        TSPhotoHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
-        currentActionInfoModel = model
-        dePrint("TSPhotoHistory.listModelArray.count=\(TSPhotoHistory.listModelArray.count)")
-        dePrint("model actionStatus 发出=\(model.actionStatus)")
-        currentActionInfoModelChanged?(currentActionInfoModel)
-    }
-    
-    //模拟数据
-    func creatPhoto(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
-        stateDatauPblished = (.start,nil)
-        if let model = oldModel {
-            currentActionInfoModel = model
-        }else {
-            currentActionInfoModel.id = Int.timestampInt()
-            currentActionInfoModel.request.prompt = prompt
-            currentActionInfoModel.request.promptSort = promptSort
-            currentActionInfoModel.actionStatus = .pending
-            currentActionInfoModel.status = "pending"
-        }
-        
-        replaceSaveInfoModel(model: currentActionInfoModel)
-        stateDatauPblished = (.start,currentActionInfoModel)
-        let time = 5.0
-        
-        for i in 0..<Int(time){
-            kDelayOnMainThread(Double(i)) {
-                let progress = Float(i)/100.0
-                self.currentActionInfoModel.percent = progress
-                self.currentActionInfoModel.actionStatus = .running
-                self.currentActionInfoModel.status = "running"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
-            }
-        }
-
-        kDelayOnMainThread(time+1.0) {
-            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDictPhoto){
-                infoModel.id = Int.uuid
-                self.replaceSaveInfoModel(model: infoModel)
-                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
-            }else{
-                self.currentActionInfoModel.actionStatus = .failed
-                self.currentActionInfoModel.status = "failed"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
-            }
-//            TSPhotoHistory.dePrintAllModel()
-        }
-    }
-    
-
-    
-//    //width 和 height 必须是 32 的倍数
-//    func creatImageEmoji(text:String) {
-//        generatingProgress = 0
-//        aiText = text
-//        let postDict:[String : Any] = [
-//            "prompt":text,
-//            "width":textPicW,
-//            "height":textPicH
-//        ]
-//        stateDatauPblished = (.start,nil)
-//        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
-//        creatRequest = TSNetworkShared.post(urlType: .textPicCreate,parameters: postDict) { [weak self] data,error in
-//            guard let self = self else { return }
-//            if let dataDict = data as? [String:Any] ,
-//               dataDict.safeInt(forKey: "code") == 200,
-//               let actionId = dataDict["actionId"] as? Int{
-//                if stopNetwork == false {
-//                    self.getActionInfo(action_id:actionId)
-//                }
-//            }else{
-//                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-//            }
-//        }
-//    }
-    
-    func getActionInfo(action_id:Int){
-        queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
-            guard let self = self else { return }
-            if let result = kNetWorkResultSuccess(data: data) {
-                if let genmojiModel = TSActionInfoModel(JSON: result) {
-                    switch genmojiModel.actionStatus {
-                    case .success:
-                        TSToastShared.hideLoading()
-                        self.stateDatauPblished = (.success(nil),genmojiModel)
-                        generatingProgress = 0
-                    case .failed:
-                        self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
-                        generatingProgress = 0
-                    default:
-                        stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
-                        if stopNetwork == false {
-                            kDelayOnMainThread(1.0) {
-                                self.getActionInfo(action_id: action_id)
-                            }
-                        }
-                    }
-                }
-            }else{
-                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-            }
-        }
-    }
-    
-    func cancelAllRequest(){
-        creatRequest?.cancel()
-        queryRequest?.cancel()
-        stopNetwork = true
-    }
-    
-    func generating(progress:Float) -> String {
-
-        //Generating 0%-100%
-        var progressInt = Int(progress*100)
-
-        if generatingProgress >= progressInt{
-            return generatingString
-        }
-
-        if progressInt > 99 {
-            progressInt = 99
-        }
-        
-        generatingProgress = progressInt
-        return generatingString
-    }
-     
-    var generatingString:String {
-        if gennerateType == .photo {
-            return "Working on your contact photo \(generatingProgress)% ..."
-        }
-        return "Working on your contact Photo \(generatingProgress)% ..."
-    }
-    
-    var textPicW:Int{
-        return kTextPicW
-    }
-    
-    var textPicH:Int{
-        if gennerateType == .photo {
-            return kTextPicW
-        }
-        return kTextPicH
-    }
-}

+ 0 - 239
AIRingtone/Common/Tool/OperationQueue/TSGeneratePosterOperation/TSGeneratePosterOperation.swift

@@ -1,239 +0,0 @@
-//
-//  TSGeneratePosterOperation.swift
-//  AIRingtone
-//
-//  Created by 100Years on 2025/3/24.
-//
-import Combine
-import Alamofire
-class TSGeneratePosterOperationQueue: TSBaseOperationQueue {
-    static let shared:TSGeneratePosterOperationQueue = TSGeneratePosterOperationQueue()
-    
-    
-    // 存储每个操作的 AnyCancellable
-    private var stateables: [String: AnyCancellable] = [:]
-    
-    var PosterOperationStateChanged:((String)->Void)?
-    
-
-    func creatOperation(uuid: String) -> TSGeneratePosterOperation {
-        let operation = super.creatOperation(uuid: uuid, type: TSGeneratePosterOperation.self)
-        if let PosterOperation = operation as? TSGeneratePosterOperation {
-            stateables[uuid] = PosterOperation.$stateDatauPblished.sink { [weak self] state in
-                guard let self = self else { return }
-                DispatchQueue.main.async {
-                    self.PosterOperationStateChanged?(uuid)
-                    
-                    let uuidData = self.getUUIDData(uuid: uuid)
-                    NotificationCenter.default.post(
-                        name: .kGeneratePosterOperationChanged,
-                        object: nil,
-                        userInfo: [
-                            "uuid": uuid,
-                            "count":self.queue.maxConcurrentOperationCount,
-                            "state":uuidData.0,
-                            "actionInfo":uuidData.1,
-                        ])
-                }
-            }
-        }
-        return operation as! TSGeneratePosterOperation
-    }
-    
-    func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
-        if let PosterOperation = TSGeneratePosterOperationQueue.shared.findOperation(uuid: uuid) as? TSGeneratePosterOperation {
-            dePrint("TSBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
-            return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
-        }
-        return (.none,TSActionInfoModel())
-    }
-    
-    override func cancelOperations(uuid: String) {
-        super.cancelOperations(uuid: uuid)
-        stateables.removeValue(forKey: uuid)
-    }
-}
-
-class TSGeneratePosterOperation: TSBaseOperation , @unchecked Sendable{
-    
-    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"
-    ]
-    
-    @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
-        didSet{
-            dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
-            if case .start = stateDatauPblished.0 {
-                start()
-            }else if stateDatauPblished.0.isResult {
-                finished()
-            }
-        }
-    }
-    var gennerateType:TSGennerateType = .poster
-    private var creatRequest:Request?
-    private var queryRequest:Request?
-    private var stopNetwork = false
-    private var generatingProgress = 0
-    private var aiText:String = ""
-    private var action_id:Int = 0
-   
-    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
-    @Published  var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
-
-    func replaceSaveInfoModel(model:TSActionInfoModel){
-        model.uuid = uuid
-        TSPosterHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
-        currentActionInfoModel = model
-        dePrint("TSPosterHistory.listModelArray.count=\(TSPosterHistory.listModelArray.count)")
-        dePrint("model actionStatus 发出=\(model.actionStatus)")
-        currentActionInfoModelChanged?(currentActionInfoModel)
-    }
-
-    //模拟数据
-    func creatPoster(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
-        stateDatauPblished = (.start,nil)
-        if let model = oldModel {
-            currentActionInfoModel = model
-        }else {
-            currentActionInfoModel.id = Int.timestampInt()
-            currentActionInfoModel.request.prompt = prompt
-            currentActionInfoModel.request.promptSort = promptSort
-            currentActionInfoModel.actionStatus = .pending
-            currentActionInfoModel.status = "pending"
-        }
-        
-        replaceSaveInfoModel(model: currentActionInfoModel)
-        stateDatauPblished = (.start,currentActionInfoModel)
-        let time = 5.0
-        
-        for i in 0..<Int(time){
-            kDelayOnMainThread(Double(i)) {
-                let progress = Float(i)/100.0
-                self.currentActionInfoModel.percent = progress
-                self.currentActionInfoModel.actionStatus = .running
-                self.currentActionInfoModel.status = "running"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
-            }
-        }
-
-        kDelayOnMainThread(time+1.0) {
-            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDictPoster){
-                infoModel.id = Int.uuid
-                self.replaceSaveInfoModel(model: infoModel)
-                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
-            }else{
-                self.currentActionInfoModel.actionStatus = .failed
-                self.currentActionInfoModel.status = "failed"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
-            }
-//            TSPosterHistory.dePrintAllModel()
-        }
-    }
-    
-
-    
-//    //width 和 height 必须是 32 的倍数
-//    func creatImageEmoji(text:String) {
-//        generatingProgress = 0
-//        aiText = text
-//        let postDict:[String : Any] = [
-//            "prompt":text,
-//            "width":textPicW,
-//            "height":textPicH
-//        ]
-//        stateDatauPblished = (.start,nil)
-//        stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
-//        creatRequest = TSNetworkShared.post(urlType: .textPicCreate,parameters: postDict) { [weak self] data,error in
-//            guard let self = self else { return }
-//            if let dataDict = data as? [String:Any] ,
-//               dataDict.safeInt(forKey: "code") == 200,
-//               let actionId = dataDict["actionId"] as? Int{
-//                if stopNetwork == false {
-//                    self.getActionInfo(action_id:actionId)
-//                }
-//            }else{
-//                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-//            }
-//        }
-//    }
-    
-    func getActionInfo(action_id:Int){
-        queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
-            guard let self = self else { return }
-            if let result = kNetWorkResultSuccess(data: data) {
-                if let genmojiModel = TSActionInfoModel(JSON: result) {
-                    switch genmojiModel.actionStatus {
-                    case .success:
-                        TSToastShared.hideLoading()
-                        self.stateDatauPblished = (.success(nil),genmojiModel)
-                        generatingProgress = 0
-                    case .failed:
-                        self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
-                        generatingProgress = 0
-                    default:
-                        stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
-                        if stopNetwork == false {
-                            kDelayOnMainThread(1.0) {
-                                self.getActionInfo(action_id: action_id)
-                            }
-                        }
-                    }
-                }
-            }else{
-                self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-            }
-        }
-    }
-    
-    func cancelAllRequest(){
-        creatRequest?.cancel()
-        queryRequest?.cancel()
-        stopNetwork = true
-    }
-    
-    func generating(progress:Float) -> String {
-
-        //Generating 0%-100%
-        var progressInt = Int(progress*100)
-
-        if generatingProgress >= progressInt{
-            return generatingString
-        }
-
-        if progressInt > 99 {
-            progressInt = 99
-        }
-        
-        generatingProgress = progressInt
-        return generatingString
-    }
-     
-    var generatingString:String {
-        if gennerateType == .poster {
-            return "Working on your contact Poster \(generatingProgress)% ..."
-        }
-        return "Working on your contact poster \(generatingProgress)% ..."
-    }
-    
-    var textPicW:Int{
-        return kTextPicW
-    }
-    
-    var textPicH:Int{
-        if gennerateType == .poster {
-            return kTextPicW
-        }
-        return kTextPicH
-    }
-}

+ 0 - 224
AIRingtone/Common/Tool/OperationQueue/TSGenerateRintoneOperation/TSGenerateRintoneOperation.swift

@@ -1,224 +0,0 @@
-//
-//  TSGenerateRintoneOperation.swift
-//  AIRingtone
-//
-//  Created by 100Years on 2025/3/21.
-//
-
-import Combine
-import Alamofire
-
-class TSGenerateRintoneOperationQueue: TSBaseOperationQueue {
-    static let shared:TSGenerateRintoneOperationQueue = TSGenerateRintoneOperationQueue()
-    
-    
-    // 存储每个操作的 AnyCancellable
-    private var stateables: [String: AnyCancellable] = [:]
-    
-    var rintoneOperationStateChanged:((String)->Void)?
-    
-
-    func creatOperation(uuid: String) -> TSGenerateRintoneOperation {
-        let operation = super.creatOperation(uuid: uuid, type: TSGenerateRintoneOperation.self)
-        if let rintoneOperation = operation as? TSGenerateRintoneOperation {
-            stateables[uuid] = rintoneOperation.$stateDatauPblished.sink { [weak self] state in
-                guard let self = self else { return }
-                DispatchQueue.main.async {
-                    self.rintoneOperationStateChanged?(uuid)
-                    
-                    let uuidData = self.getUUIDData(uuid: uuid)
-                    NotificationCenter.default.post(
-                        name: .kGenerateRintoneOperationChanged,
-                        object: nil,
-                        userInfo: [
-                            "uuid": uuid,
-                            "count":self.queue.maxConcurrentOperationCount,
-                            "state":uuidData.0,
-                            "actionInfo":uuidData.1,
-                        ])
-                }
-            }
-        }
-        return operation as! TSGenerateRintoneOperation
-    }
-    
-    func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
-        if let rintoneOperation = TSGenerateRintoneOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateRintoneOperation {
-            dePrint("TSBaseOperation stateDatauPblished 发送 = \(rintoneOperation.stateDatauPblished)")
-            return (rintoneOperation.stateDatauPblished.0,rintoneOperation.currentActionInfoModel)
-        }
-        return (.none,TSActionInfoModel())
-    }
-    
-    override func cancelOperations(uuid: String) {
-        super.cancelOperations(uuid: uuid)
-        stateables.removeValue(forKey: uuid)
-    }
-}
-
-class TSGenerateRintoneOperation: TSBaseOperation , @unchecked Sendable{
-    
-    let actionInfoDict:[String:Any] = [
-        "actionType":"music_create",
-        "comments": "Success",
-        "costTime":15,
-        "createdTimestamp":1741338454,
-        "id":1536,
-        "percent":1,
-        "request":"{\"prompt\": \"Create a Techno ringtone with a repetitive bassline, crisp hi-hats, and subtle synth textures. Use a BPM of 125-130 for a sleek, modern sound., Create a uplifting and modern music track blending Pop, Electronic, and Ambient elements. Use a BPM of 100-120, a catchy melody with synth or piano, warm harmonies, and a mix of electronic and organic sounds. Ensure a clear structure (Intro, Verse, Chorus, Outro) and a light, positive vibe suitable for background or casual listening\", \"duration\": 5}",
-        "response":"{\"coverUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/f0fb7739-a5cc-4805-9b68-b4a5890eb285.png\", \"title\": \"Neon Pulse\\\"  \\n\\\"Horizon Glow\", \"musicUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/c47d40dd-d07c-4edc-a6d9-8382438149d1.wav\"}",
-        "status":"success"
-    ]
-    
-    @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
-        didSet{
-            dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
-            if case .start = stateDatauPblished.0 {
-                start()
-            }else if stateDatauPblished.0.isResult {
-                finished()
-            }
-        }
-    }
-    
-    private var creatRequest:Request?
-    private var queryRequest:Request?
-    private var stopNetwork = false
-    private var generatingProgress = 0
-    private var aiText:String = ""
-    private var action_id:Int = 0    
-   
-    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
-    @Published  var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
-
-    func replaceSaveInfoModel(model:TSActionInfoModel){
-        model.uuid = uuid
-        TSAIRintoneHistory.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
-        currentActionInfoModel = model
-        dePrint("TSAIRintoneHistory.listModelArray.count=\(TSAIRintoneHistory.listModelArray.count)")
-        dePrint("model actionStatus 发出=\(model.actionStatus)")
-        currentActionInfoModelChanged?(currentActionInfoModel)
-    }
-
-    //模拟数据
-    func creatRintone(oldModel:TSActionInfoModel? = nil,prompt:String,promptSort:String) {
-        stateDatauPblished = (.start,nil)
-        if let model = oldModel {
-            currentActionInfoModel = model
-        }else {
-            currentActionInfoModel.id = Int.timestampInt()
-            currentActionInfoModel.request.prompt = prompt
-            currentActionInfoModel.request.promptSort = promptSort
-            currentActionInfoModel.actionStatus = .pending
-            currentActionInfoModel.status = "pending"
-        }
-        
-        replaceSaveInfoModel(model: currentActionInfoModel)
-        stateDatauPblished = (.start,currentActionInfoModel)
-        let time = 2.0
-        
-        for i in 0..<Int(time){
-            kDelayOnMainThread(Double(i)) {
-                let progress = Float(i)/100.0
-                self.currentActionInfoModel.percent = progress
-                self.currentActionInfoModel.actionStatus = .running
-                self.currentActionInfoModel.status = "running"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.progressString(self.generating(progress: progress)),nil)
-            }
-        }
-
-        kDelayOnMainThread(time+1.0) {
-            if Bool.random(), let infoModel = TSActionInfoModel(JSON: self.actionInfoDict){
-                infoModel.id = Int.uuid
-                self.replaceSaveInfoModel(model: infoModel)
-                self.stateDatauPblished = (.success(nil),self.currentActionInfoModel)
-            }else{
-                self.currentActionInfoModel.actionStatus = .failed
-                self.currentActionInfoModel.status = "failed"
-                self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-                self.stateDatauPblished = (.failed("error?.localizedDescription"),nil)
-            }
-            TSAIRintoneHistory.dePrintAllModel()
-        }
-    }
-    
-//   func creatRintone(text:String) {
-//       generatingProgress = 0
-//       aiText = text
-//       let postDict:[String : Any] = [
-//           "prompt":text,
-//           "duration":20
-//       ]
-//       stateDatauPblished = (.start,nil)
-//       creatRequest = TSNetworkShared.post(urlType: .musicCreate,parameters: postDict) { [weak self] data,error in
-//           guard let self = self else { return }
-//           if let dataDict = data as? [String:Any] ,
-//              dataDict.safeInt(forKey: "code") == 200,
-//              let actionId = dataDict["actionId"] as? Int{
-//               if stopNetwork == false {
-//                   self.getActionInfo(action_id:actionId)
-//               }
-//           }else{
-//               self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-//           }
-//       }
-//   }
-   
-   func getActionInfo(action_id:Int){
-       self.action_id = action_id
-       queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
-           guard let self = self else { return }
-           if let result = kNetWorkResultSuccess(data: data) {
-               if let genmojiModel = TSActionInfoModel(JSON: result) {
-                   switch genmojiModel.actionStatus {
-                   case .success:
-                       TSToastShared.hideLoading()
-                       self.stateDatauPblished = (.success(nil),genmojiModel)
-                       generatingProgress = 0
-                   case .failed:
-                       self.stateDatauPblished = (.failed(kNetWorkMessage(data: data) ?? ""),nil)
-                       generatingProgress = 0
-                   default:
-                       stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),nil)
-                       if stopNetwork == false {
-                           kDelayOnMainThread(1.0) {
-                               self.getActionInfo(action_id: action_id)
-                           }
-                       }
-                   }
-               }
-           }else{
-               self.stateDatauPblished = (.failed(error?.localizedDescription ?? ""),nil)
-           }
-       }
-   }
-    func generating(progress:Float) -> String {
-
-        //Generating 0%-100%
-        var progressInt = Int(progress*100)
-
-        if generatingProgress >= progressInt{
-            return "Generating \(generatingProgress)%"
-        }
-
-        if progressInt > 99 {
-            progressInt = 99
-        }
-        
-        generatingProgress = progressInt
-        return "Generating \(progressInt)%"
-    }
-    
-    
-    
-    func cancelAllRequest(){
-        creatRequest?.cancel()
-        queryRequest?.cancel()
-        stopNetwork = true
-        
-        cancel()
-    }
-    
-    
-}

+ 0 - 10
AIRingtone/Common/Tool/OperationQueue/TSGenerateRintoneOperation/TSGenerateRintoneOperationQueue.swift

@@ -1,10 +0,0 @@
-//
-//  TSGenerateRintoneOperationQueue.swift
-//  AIRingtone
-//
-//  Created by 100Years on 2025/3/21.
-//
-
-//class TSGenerateRintoneOperationQueue: TSBaseOperationQueue {
-//    let shared:TSGenerateRintoneOperationQueue = TSGenerateRintoneOperationQueue()
-//}