Эх сурвалжийг харах

feat: 历史记录整改完毕

100Years 3 долоо хоног өмнө
parent
commit
84dd5b05c9
39 өөрчлөгдсөн 1564 нэмэгдсэн , 394 устгасан
  1. 64 4
      AIEmoji.xcodeproj/project.pbxproj
  2. 3 1
      AIEmoji/AppDelegate.swift
  3. 116 38
      AIEmoji/Business/Data/TSDBHistoryManager.swift
  4. 1 1
      AIEmoji/Business/Data/TSUserDefaultData.swift
  5. 4 0
      AIEmoji/Business/General/Ex/Notification+Ex.swift
  6. 2 2
      AIEmoji/Business/General/TSBigIconBrowseVC/TSBigIconBrowseVC.swift
  7. 1 1
      AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/TSAIExpandImageVC.swift
  8. 1 1
      AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseCell.swift
  9. 13 9
      AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVC.swift
  10. 12 2
      AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift
  11. 4 2
      AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoGeneratorBaseVM/TSAIListPhotoGeneratorBaseVM.swift
  12. 20 2
      AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift
  13. 1 1
      AIEmoji/Business/TSAILIstVC/TSPredictBabyVC/TSFutureBabyVC.swift
  14. 44 10
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift
  15. 44 7
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSDBActionInfoModel.swift
  16. 1 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift
  17. 24 25
      AIEmoji/Business/TSPTPGeneratorVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoBrowseVC.swift
  18. 2 2
      AIEmoji/Business/TSPTPGeneratorVC/TSAbnormalPopUpAlertVC/TSAbnormalPopUpAlertVC.swift
  19. 1 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPBrowseVC/TSPTPBrowseVC.swift
  20. 2 2
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift
  21. 12 4
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPHistoryVC/TSPTPHistoryVC.swift
  22. 14 9
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift
  23. 1 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/TSPhotoToPhotoVC.swift
  24. 1 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/VM/TSPhotoToPhotoVM.swift
  25. 6 2
      AIEmoji/Business/TSTabBarController/TSTabBarController.swift
  26. 6 5
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC+Col.swift
  27. 1 1
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift
  28. 2 1
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/TSTextGeneralPictureVC.swift
  29. 27 0
      AIEmoji/Business2/Data/TSDiscoverViewModel.swift
  30. 239 0
      AIEmoji/Business2/TSGenerateHistoryVC/TSGenerateHistoryVC.swift
  31. 193 0
      AIEmoji/Business2/TSGenerateHistoryVC/View/TSGenerateHistoryCell.swift
  32. 124 0
      AIEmoji/Business2/TSGenerateHistoryVC/View/TSGennerateCellView.swift
  33. 6 6
      AIEmoji/Common/Purchase/TSPurchaseManager.swift
  34. 7 4
      AIEmoji/Common/TSRealmManager/TSRealmManager.swift
  35. 0 208
      AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift
  36. 9 12
      AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift
  37. 283 0
      AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBaseOperation.swift
  38. 273 0
      AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBasePhotoOperation.swift
  39. 0 28
      AIEmoji/Common/Tool/TSCommonTool/TSCommonTool.swift

+ 64 - 4
AIEmoji.xcodeproj/project.pbxproj

@@ -109,7 +109,6 @@
 		A82D60812DB7A1E600596190 /* activePhoto.gif in Resources */ = {isa = PBXBuildFile; fileRef = A82D60802DB7A1E600596190 /* activePhoto.gif */; };
 		A82D60812DB7A1E600596190 /* activePhoto.gif in Resources */ = {isa = PBXBuildFile; fileRef = A82D60802DB7A1E600596190 /* activePhoto.gif */; };
 		A82D60832DB87D1A00596190 /* TSAIExpandChangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60822DB87D1900596190 /* TSAIExpandChangeView.swift */; };
 		A82D60832DB87D1A00596190 /* TSAIExpandChangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60822DB87D1900596190 /* TSAIExpandChangeView.swift */; };
 		A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D608A2DB9CE7A00596190 /* MXParallaxHeader+Ex.swift */; };
 		A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D608A2DB9CE7A00596190 /* MXParallaxHeader+Ex.swift */; };
-		A82D60942DB9D45900596190 /* TSGenerateBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D608C2DB9D45900596190 /* TSGenerateBaseOperation.swift */; };
 		A82D60952DB9D45900596190 /* TSGeneratePosterOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */; };
 		A82D60952DB9D45900596190 /* TSGeneratePosterOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */; };
 		A82D60972DB9D45900596190 /* TSBaseOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */; };
 		A82D60972DB9D45900596190 /* TSBaseOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */; };
 		A82D60982DB9D45900596190 /* TSBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60922DB9D45900596190 /* TSBaseOperation.swift */; };
 		A82D60982DB9D45900596190 /* TSBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60922DB9D45900596190 /* TSBaseOperation.swift */; };
@@ -140,6 +139,7 @@
 		A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */; };
 		A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */; };
 		A85E47C32D6964A50018D62D /* TSMSGAIDefaultHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */; };
 		A85E47C32D6964A50018D62D /* TSMSGAIDefaultHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */; };
 		A85E47C62D697E750018D62D /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A85E47C52D697E750018D62D /* SwiftUIX */; };
 		A85E47C62D697E750018D62D /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A85E47C52D697E750018D62D /* SwiftUIX */; };
+		A8708A0C2E08F5C600601686 /* TSGennerateCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8708A0B2E08F5C600601686 /* TSGennerateCellView.swift */; };
 		A875870F2D81689A00286A66 /* TSPTPEnterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A875870E2D81689600286A66 /* TSPTPEnterView.swift */; };
 		A875870F2D81689A00286A66 /* TSPTPEnterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A875870E2D81689600286A66 /* TSPTPEnterView.swift */; };
 		A87587122D81702700286A66 /* TSUserDefaultData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87587102D81702700286A66 /* TSUserDefaultData.swift */; };
 		A87587122D81702700286A66 /* TSUserDefaultData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87587102D81702700286A66 /* TSUserDefaultData.swift */; };
 		A87587162D81734300286A66 /* text_to_photo_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A87587152D81733C00286A66 /* text_to_photo_style.json */; };
 		A87587162D81734300286A66 /* text_to_photo_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A87587152D81733C00286A66 /* text_to_photo_style.json */; };
@@ -183,6 +183,11 @@
 		A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */; };
 		A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */; };
 		A89EA6CC2D642CE2000EB181 /* TSChatViewController+NaviBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */; };
 		A89EA6CC2D642CE2000EB181 /* TSChatViewController+NaviBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */; };
 		A89EA6CF2D6430F3000EB181 /* TSChatViewController+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */; };
 		A89EA6CF2D6430F3000EB181 /* TSChatViewController+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */; };
+		A8B70BC62E06B9D7003177FA /* TSDiscoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */; };
+		A8B70BC92E08E416003177FA /* TSGenerateHistoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BC82E08E416003177FA /* TSGenerateHistoryVC.swift */; };
+		A8B70BCB2E08F28F003177FA /* TSGenerateHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BCA2E08F28B003177FA /* TSGenerateHistoryCell.swift */; };
+		A8B70BD22E08F2F4003177FA /* TSGenerateBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BCD2E08F2F4003177FA /* TSGenerateBaseOperation.swift */; };
+		A8B70BD42E08F2F4003177FA /* TSGenerateBasePhotoOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BCE2E08F2F4003177FA /* TSGenerateBasePhotoOperation.swift */; };
 		A8BA763C2DA4C225000B6707 /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A8BA763B2DA4C225000B6707 /* SwiftUIX */; };
 		A8BA763C2DA4C225000B6707 /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A8BA763B2DA4C225000B6707 /* SwiftUIX */; };
 		A8BA763F2DA4C908000B6707 /* TSPTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA763E2DA4C906000B6707 /* TSPTPInputVC.swift */; };
 		A8BA763F2DA4C908000B6707 /* TSPTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA763E2DA4C906000B6707 /* TSPTPInputVC.swift */; };
 		A8BA76422DA4C924000B6707 /* TSPTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76412DA4C920000B6707 /* TSPTPInputVM.swift */; };
 		A8BA76422DA4C924000B6707 /* TSPTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76412DA4C920000B6707 /* TSPTPInputVM.swift */; };
@@ -385,7 +390,6 @@
 		A82D60802DB7A1E600596190 /* activePhoto.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = activePhoto.gif; sourceTree = "<group>"; };
 		A82D60802DB7A1E600596190 /* activePhoto.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = activePhoto.gif; sourceTree = "<group>"; };
 		A82D60822DB87D1900596190 /* TSAIExpandChangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandChangeView.swift; sourceTree = "<group>"; };
 		A82D60822DB87D1900596190 /* TSAIExpandChangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandChangeView.swift; sourceTree = "<group>"; };
 		A82D608A2DB9CE7A00596190 /* MXParallaxHeader+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MXParallaxHeader+Ex.swift"; sourceTree = "<group>"; };
 		A82D608A2DB9CE7A00596190 /* MXParallaxHeader+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MXParallaxHeader+Ex.swift"; sourceTree = "<group>"; };
-		A82D608C2DB9D45900596190 /* TSGenerateBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateBaseOperation.swift; sourceTree = "<group>"; };
 		A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePosterOperation.swift; sourceTree = "<group>"; };
 		A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneratePosterOperation.swift; sourceTree = "<group>"; };
 		A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperationQueue.swift; sourceTree = "<group>"; };
 		A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperationQueue.swift; sourceTree = "<group>"; };
 		A82D60922DB9D45900596190 /* TSBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperation.swift; sourceTree = "<group>"; };
 		A82D60922DB9D45900596190 /* TSBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperation.swift; sourceTree = "<group>"; };
@@ -436,6 +440,7 @@
 		A85E47BD2D68999B0018D62D /* ShareActivityItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareActivityItemProvider.swift; sourceTree = "<group>"; };
 		A85E47BD2D68999B0018D62D /* ShareActivityItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareActivityItemProvider.swift; sourceTree = "<group>"; };
 		A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatMessageUIModel.swift; sourceTree = "<group>"; };
 		A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatMessageUIModel.swift; sourceTree = "<group>"; };
 		A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSMSGAIDefaultHeaderView.swift; sourceTree = "<group>"; };
 		A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSMSGAIDefaultHeaderView.swift; sourceTree = "<group>"; };
+		A8708A0B2E08F5C600601686 /* TSGennerateCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennerateCellView.swift; sourceTree = "<group>"; };
 		A875870E2D81689600286A66 /* TSPTPEnterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPEnterView.swift; sourceTree = "<group>"; };
 		A875870E2D81689600286A66 /* TSPTPEnterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPEnterView.swift; sourceTree = "<group>"; };
 		A87587102D81702700286A66 /* TSUserDefaultData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSUserDefaultData.swift; sourceTree = "<group>"; };
 		A87587102D81702700286A66 /* TSUserDefaultData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSUserDefaultData.swift; sourceTree = "<group>"; };
 		A87587152D81733C00286A66 /* text_to_photo_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = text_to_photo_style.json; sourceTree = "<group>"; };
 		A87587152D81733C00286A66 /* text_to_photo_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = text_to_photo_style.json; sourceTree = "<group>"; };
@@ -478,6 +483,11 @@
 		A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+SendMsg.swift"; sourceTree = "<group>"; };
 		A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+SendMsg.swift"; sourceTree = "<group>"; };
 		A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+NaviBar.swift"; sourceTree = "<group>"; };
 		A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+NaviBar.swift"; sourceTree = "<group>"; };
 		A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+Keyboard.swift"; sourceTree = "<group>"; };
 		A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+Keyboard.swift"; sourceTree = "<group>"; };
+		A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiscoverViewModel.swift; sourceTree = "<group>"; };
+		A8B70BC82E08E416003177FA /* TSGenerateHistoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateHistoryVC.swift; sourceTree = "<group>"; };
+		A8B70BCA2E08F28B003177FA /* TSGenerateHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateHistoryCell.swift; sourceTree = "<group>"; };
+		A8B70BCD2E08F2F4003177FA /* TSGenerateBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateBaseOperation.swift; sourceTree = "<group>"; };
+		A8B70BCE2E08F2F4003177FA /* TSGenerateBasePhotoOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateBasePhotoOperation.swift; sourceTree = "<group>"; };
 		A8BA763E2DA4C906000B6707 /* TSPTPInputVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPInputVC.swift; sourceTree = "<group>"; };
 		A8BA763E2DA4C906000B6707 /* TSPTPInputVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPInputVC.swift; sourceTree = "<group>"; };
 		A8BA76412DA4C920000B6707 /* TSPTPInputVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPInputVM.swift; sourceTree = "<group>"; };
 		A8BA76412DA4C920000B6707 /* TSPTPInputVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPInputVM.swift; sourceTree = "<group>"; };
 		A8BA76442DA4CB99000B6707 /* TSPTPUploadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPUploadView.swift; sourceTree = "<group>"; };
 		A8BA76442DA4CB99000B6707 /* TSPTPUploadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPUploadView.swift; sourceTree = "<group>"; };
@@ -1231,7 +1241,6 @@
 		A82D60902DB9D45900596190 /* TSGenerateBaseOperation */ = {
 		A82D60902DB9D45900596190 /* TSGenerateBaseOperation */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				A82D608C2DB9D45900596190 /* TSGenerateBaseOperation.swift */,
 				A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */,
 				A82D608D2DB9D45900596190 /* TSGeneratePosterOperation.swift */,
 			);
 			);
 			path = TSGenerateBaseOperation;
 			path = TSGenerateBaseOperation;
@@ -1240,6 +1249,7 @@
 		A82D60932DB9D45900596190 /* OperationQueue */ = {
 		A82D60932DB9D45900596190 /* OperationQueue */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				A8708A092E08F34800601686 /* V2 */,
 				A82D60902DB9D45900596190 /* TSGenerateBaseOperation */,
 				A82D60902DB9D45900596190 /* TSGenerateBaseOperation */,
 				A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */,
 				A82D60912DB9D45900596190 /* TSBaseOperationQueue.swift */,
 				A82D60922DB9D45900596190 /* TSBaseOperation.swift */,
 				A82D60922DB9D45900596190 /* TSBaseOperation.swift */,
@@ -1330,6 +1340,24 @@
 			path = TSChatMsgBaseView;
 			path = TSChatMsgBaseView;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		A8708A092E08F34800601686 /* V2 */ = {
+			isa = PBXGroup;
+			children = (
+				A8B70BCD2E08F2F4003177FA /* TSGenerateBaseOperation.swift */,
+				A8B70BCE2E08F2F4003177FA /* TSGenerateBasePhotoOperation.swift */,
+			);
+			path = V2;
+			sourceTree = "<group>";
+		};
+		A8708A0A2E08F5B700601686 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A8708A0B2E08F5C600601686 /* TSGennerateCellView.swift */,
+				A8B70BCA2E08F28B003177FA /* TSGenerateHistoryCell.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		A87587112D81702700286A66 /* Data */ = {
 		A87587112D81702700286A66 /* Data */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1511,6 +1539,32 @@
 			path = TSChatViewController;
 			path = TSChatViewController;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		A8B70BC32E06B9AE003177FA /* Business2 */ = {
+			isa = PBXGroup;
+			children = (
+				A8B70BC72E08E408003177FA /* TSGenerateHistoryVC */,
+				A8B70BC42E06B9C1003177FA /* Data */,
+			);
+			path = Business2;
+			sourceTree = "<group>";
+		};
+		A8B70BC42E06B9C1003177FA /* Data */ = {
+			isa = PBXGroup;
+			children = (
+				A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */,
+			);
+			path = Data;
+			sourceTree = "<group>";
+		};
+		A8B70BC72E08E408003177FA /* TSGenerateHistoryVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8708A0A2E08F5B700601686 /* View */,
+				A8B70BC82E08E416003177FA /* TSGenerateHistoryVC.swift */,
+			);
+			path = TSGenerateHistoryVC;
+			sourceTree = "<group>";
+		};
 		A8BA763D2DA4C8F9000B6707 /* TSPTPInputVC */ = {
 		A8BA763D2DA4C8F9000B6707 /* TSPTPInputVC */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1682,6 +1736,7 @@
 				A8FDB1702DCC4B1100E9919B /* Enums */,
 				A8FDB1702DCC4B1100E9919B /* Enums */,
 				A8FB02AE2D3E38FA0031A396 /* Res */,
 				A8FB02AE2D3E38FA0031A396 /* Res */,
 				A8F7751E2D38ED4500AA6E93 /* DataManger */,
 				A8F7751E2D38ED4500AA6E93 /* DataManger */,
+				A8B70BC32E06B9AE003177FA /* Business2 */,
 				A8F774922D38EA8C00AA6E93 /* Business */,
 				A8F774922D38EA8C00AA6E93 /* Business */,
 				A8F774D82D38EA8C00AA6E93 /* Common */,
 				A8F774D82D38EA8C00AA6E93 /* Common */,
 				A8F774812D38E8B700AA6E93 /* AppDelegate.swift */,
 				A8F774812D38E8B700AA6E93 /* AppDelegate.swift */,
@@ -2267,6 +2322,7 @@
 				A80EDE002D6EFD22003CD332 /* TSPhotoPickerManager.swift in Sources */,
 				A80EDE002D6EFD22003CD332 /* TSPhotoPickerManager.swift in Sources */,
 				A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */,
 				A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */,
 				A81BECA32DD1EA1E005D06A2 /* TSGeneratorErrorView.swift in Sources */,
 				A81BECA32DD1EA1E005D06A2 /* TSGeneratorErrorView.swift in Sources */,
+				A8B70BCB2E08F28F003177FA /* TSGenerateHistoryCell.swift in Sources */,
 				A8BA766F2DA65824000B6707 /* TSAIListPhotoGeneratorBaseVM.swift in Sources */,
 				A8BA766F2DA65824000B6707 /* TSAIListPhotoGeneratorBaseVM.swift in Sources */,
 				A80E72532D3F985E00C64288 /* TSWallpaperVC.swift in Sources */,
 				A80E72532D3F985E00C64288 /* TSWallpaperVC.swift in Sources */,
 				A8FB02B32D3E39A40031A396 /* TSEmojisModel.swift in Sources */,
 				A8FB02B32D3E39A40031A396 /* TSEmojisModel.swift in Sources */,
@@ -2382,10 +2438,12 @@
 				A82D609E2DBA0FEA00596190 /* TSAppBtnView.swift in Sources */,
 				A82D609E2DBA0FEA00596190 /* TSAppBtnView.swift in Sources */,
 				A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */,
 				A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */,
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
+				A8B70BC92E08E416003177FA /* TSGenerateHistoryVC.swift in Sources */,
 				A8BA76772DA68619000B6707 /* TSAIListHistoryBaseVM.swift in Sources */,
 				A8BA76772DA68619000B6707 /* TSAIListHistoryBaseVM.swift in Sources */,
 				A80EDDE42D6EB8FA003CD332 /* TSPTPSelectStyleCell.swift in Sources */,
 				A80EDDE42D6EB8FA003CD332 /* TSPTPSelectStyleCell.swift in Sources */,
 				A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */,
 				A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */,
 				A80E73E12D533E5800C64288 /* TSPurchaseVC.swift in Sources */,
 				A80E73E12D533E5800C64288 /* TSPurchaseVC.swift in Sources */,
+				A8708A0C2E08F5C600601686 /* TSGennerateCellView.swift in Sources */,
 				A80EDDE02D6EB1B9003CD332 /* TSPTPGeneratorCell.swift in Sources */,
 				A80EDDE02D6EB1B9003CD332 /* TSPTPGeneratorCell.swift in Sources */,
 				A81BECA62DD1EFAF005D06A2 /* TSGeneratorloadingContentView.swift in Sources */,
 				A81BECA62DD1EFAF005D06A2 /* TSGeneratorloadingContentView.swift in Sources */,
 				A8F776352D3A7C2B00AA6E93 /* TSGenmojiColSectionView.swift in Sources */,
 				A8F776352D3A7C2B00AA6E93 /* TSGenmojiColSectionView.swift in Sources */,
@@ -2413,7 +2471,6 @@
 				A83404D12D9D16FA00C140E4 /* TSAIPhotoGeneratorBaseVC.swift in Sources */,
 				A83404D12D9D16FA00C140E4 /* TSAIPhotoGeneratorBaseVC.swift in Sources */,
 				A80327BF2D81578900AF7878 /* TSPromptTextView.swift in Sources */,
 				A80327BF2D81578900AF7878 /* TSPromptTextView.swift in Sources */,
 				A80EDE022D6F1CCD003CD332 /* TSPTPGeneratorVC.swift in Sources */,
 				A80EDE022D6F1CCD003CD332 /* TSPTPGeneratorVC.swift in Sources */,
-				A82D60942DB9D45900596190 /* TSGenerateBaseOperation.swift in Sources */,
 				A82D60952DB9D45900596190 /* TSGeneratePosterOperation.swift in Sources */,
 				A82D60952DB9D45900596190 /* TSGeneratePosterOperation.swift in Sources */,
 				A82D60972DB9D45900596190 /* TSBaseOperationQueue.swift in Sources */,
 				A82D60972DB9D45900596190 /* TSBaseOperationQueue.swift in Sources */,
 				A82D60982DB9D45900596190 /* TSBaseOperation.swift in Sources */,
 				A82D60982DB9D45900596190 /* TSBaseOperation.swift in Sources */,
@@ -2439,8 +2496,11 @@
 				A83404D32D9D23FA00C140E4 /* TSGeneratorloadingView.swift in Sources */,
 				A83404D32D9D23FA00C140E4 /* TSGeneratorloadingView.swift in Sources */,
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
+				A8B70BC62E06B9D7003177FA /* TSDiscoverViewModel.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
 				605E205B2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift in Sources */,
 				605E205B2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift in Sources */,
+				A8B70BD22E08F2F4003177FA /* TSGenerateBaseOperation.swift in Sources */,
+				A8B70BD42E08F2F4003177FA /* TSGenerateBasePhotoOperation.swift in Sources */,
 				A804B98F2DC0F0F700C494C7 /* TSTTPRatioView.swift in Sources */,
 				A804B98F2DC0F0F700C494C7 /* TSTTPRatioView.swift in Sources */,
 				A8FDB17C2DCC5A1000E9919B /* TSTTPInputVC+Col.swift in Sources */,
 				A8FDB17C2DCC5A1000E9919B /* TSTTPInputVC+Col.swift in Sources */,
 				A83404D52D9D28D700C140E4 /* TSAIPhotoBrowseVC.swift in Sources */,
 				A83404D52D9D28D700C140E4 /* TSAIPhotoBrowseVC.swift in Sources */,

+ 3 - 1
AIEmoji/AppDelegate.swift

@@ -9,6 +9,7 @@ import UIKit
 var kAppNewVerison = ""
 var kAppNewVerison = ""
 @main
 @main
 class AppDelegate: UIResponder, UIApplicationDelegate {
 class AppDelegate: UIResponder, UIApplicationDelegate {
+    static var tabbar:TSTabBarController?
     var window: UIWindow?
     var window: UIWindow?
     var backgroundTaskIdentifier: UIBackgroundTaskIdentifier = .invalid
     var backgroundTaskIdentifier: UIBackgroundTaskIdentifier = .invalid
 
 
@@ -31,7 +32,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     }
     }
 
 
     func goToTab() {
     func goToTab() {
-        window?.rootViewController = TSTabBarController()
+        Self.tabbar = TSTabBarController()
+        window?.rootViewController = Self.tabbar
     }
     }
 
 
     func JudgmentSkipPage() {
     func JudgmentSkipPage() {

+ 116 - 38
AIEmoji/Business/Data/TSDBHistoryManager.swift

@@ -27,13 +27,17 @@ enum TSDBHistoryType: String,CaseIterable {
     case motherDay = "kTSAIMotherDayHistoryListString"   //母亲节
     case motherDay = "kTSAIMotherDayHistoryListString"   //母亲节
     case catTohuman = "kTSAICatTohumanHistoryListString"   //猫变人
     case catTohuman = "kTSAICatTohumanHistoryListString"   //猫变人
     case futureBaby = "kTSAIFutureBabyHistoryListString"   //预测宝宝
     case futureBaby = "kTSAIFutureBabyHistoryListString"   //预测宝宝
+    
+    
+    
+    case aiGenerate = "kTSAiGenerateHistoryListString"  //通用的 AI 生成
 }
 }
 
 
 
 
 //MARK: TSDBAIChatList - 用于存储会话及消息列表
 //MARK: TSDBAIChatList - 用于存储会话及消息列表
 class TSDBHistory: Object {
 class TSDBHistory: Object {
     @Persisted(primaryKey: true) var primaryKey: String = ""
     @Persisted(primaryKey: true) var primaryKey: String = ""
-    @Persisted var listModels = List<TSDBActionInfoModel>()
+    @Persisted var listModels = List<TSDBActionInfoModel>()//惰性加载特性
     
     
     var type: TSDBHistoryType {
     var type: TSDBHistoryType {
         get { TSDBHistoryType(rawValue: primaryKey) ?? .ptp }
         get { TSDBHistoryType(rawValue: primaryKey) ?? .ptp }
@@ -45,7 +49,7 @@ class TSDBHistory: Object {
         self.primaryKey = type.rawValue
         self.primaryKey = type.rawValue
     }
     }
     
     
-
+    
     func getModelList() -> [TSActionInfoModel] {
     func getModelList() -> [TSActionInfoModel] {
         var msgModel:[TSActionInfoModel] = []
         var msgModel:[TSActionInfoModel] = []
         for msgDBModel in listModels {
         for msgDBModel in listModels {
@@ -90,35 +94,52 @@ class TSDBHistory: Object {
         }
         }
     }
     }
     
     
-    static func deleteAll() {
-        do {
-            let realm = try Realm()
-            try realm.write {
-                let allPersons = realm.objects(TSDBHistory.self)
-                realm.delete(allPersons)
+    func deleteListModel(uuid:String) {
+        TSRMShared.writeThread {
+            if let index = listModels.firstIndex(where: { $0.uuid == uuid }) {
+                listModels.remove(at: index)
+                debugPrint("listModels.remove(at: \(index))")
             }
             }
-        } catch {
-            debugPrint("删除 TSDBPTPHistory 模型数据时出错: \(error)")
+        }
+    }
+
+    func deleteListModel(index:Int) {
+        TSRMShared.writeThread {
+            deleteResources(index:index)
+            listModels.remove(at: index)
+            debugPrint("listModels.remove(at: \(index))")
         }
         }
     }
     }
     
     
-    func updateData(_ actionInfoModel:TSActionInfoModel,id:Int? = nil){
-            let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
-            var replaceID = dbModel.id
-            if let id = id {
-                replaceID = id
-            }
-            
+    func deleteResources(index:Int) {
+        if let model = listModels[safe: index] {
+            model.deleteResources()
+        }
+    }
+    
+    
+    func deleteAll() {
+        for index in listModels.indices {
+            deleteResources(index: index)
+        }
+        TSRMShared.writeThread {
+            listModels.removeAll()
+        }
+    }
+    
+    func updateData(_ actionInfoModel:TSActionInfoModel,uuid:String? = nil){
+        let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
+            let replaceUUID = uuid ?? dbModel.uuid
             let frozenList = self.listModels.freeze()
             let frozenList = self.listModels.freeze()
-            if let index = frozenList.firstIndex(where: { $0.id == replaceID }) {
+            if let index = frozenList.firstIndex(where: { $0.uuid == replaceUUID }) {
+                dePrint("updateData 替换 \(dbModel)")
                 TSRMShared.writeThread {
                 TSRMShared.writeThread {
                     listModels[index] = dbModel// 如果找到,替换该元素
                     listModels[index] = dbModel// 如果找到,替换该元素
                 }
                 }
             } else {
             } else {
-                print("Thread.current insert1=\(Thread.current)")
                 TSRMShared.writeThread {
                 TSRMShared.writeThread {
+                    dePrint("updateData 插入 \(dbModel)")
                     listModels.insert(dbModel, at: 0)// 如果没有找到,添加到末尾
                     listModels.insert(dbModel, at: 0)// 如果没有找到,添加到末尾
-                    print("Thread.current insert2=\(Thread.current)")
                 }
                 }
             }
             }
     }
     }
@@ -175,6 +196,80 @@ extension TSDBHistory {
 }
 }
 
 
 
 
+//从App 大改版本后,基本就用这两个,其他的历史记录不再使用
+extension TSRealmManager {
+    
+    var aiGenerateDB:TSDBHistory {
+        let history = getDBHistory(type: TSDBHistoryType.aiGenerate)
+        let forKey = "insertAIGenerateExampleData1"
+        if history.listModels.count == 0,UserDefaults.standard.string(forKey: forKey) == nil {
+            
+//            mergeAllDataToAIGenerateDB(history: history)
+            
+            let id = Date.timestampInt
+            history.updateDatas([
+                createExampleModel(id:id, imageName: "ttp_example_image0"),
+                createExampleModel(id:id+1, imageName: "ttp_example_image1")
+            ])
+            UserDefaults.standard.set("1", forKey: forKey)
+            UserDefaults.standard.synchronize()
+    
+        }
+        
+        mergeAllDataToAIGenerateDB(history: history)
+        
+        return history
+    }
+    //文生图
+    var ttpDBHistory:TSDBHistory {
+        
+        let history = getDBHistory(type: TSDBHistoryType.ttp)
+        
+        if history.listModels.count == 0,UserDefaults.standard.string(forKey: "insertTTPExampleData") == nil {
+            let id = Date.timestampInt
+            history.updateDatas([
+                createExampleModel(id:id, imageName: "ttp_example_image0"),
+                createExampleModel(id:id+1, imageName: "ttp_example_image1")
+            ])
+            UserDefaults.standard.set("1", forKey: "insertTTPExampleData")
+            UserDefaults.standard.synchronize()
+        }
+        
+        return history
+    }
+    
+    
+    
+    //同时这里提供数据合并后的获取方式
+    
+    func mergeAllDataToAIGenerateDB(history:TSDBHistory){
+        let predicate = NSPredicate(format: "actionType != %@ AND modelType != %d",
+                                  "image_create", 1)
+        let results = realm.objects(TSDBActionInfoModel.self)
+            .filter(predicate)
+            .sorted(byKeyPath: "createdTimestamp", ascending: false)
+//        let sortedArray = Array(results)
+//        for model in sortedArray {
+//            print("Model: \(model), Timestamp: \(model.createdTimestamp)")
+//        }
+        
+        let combinedList = List<TSDBActionInfoModel>()
+        combinedList.append(objectsIn: results)
+        TSRMShared.writeThread {
+            history.listModels = combinedList
+        }
+        
+//        let combinedList = List<TSDBActionInfoModel>()
+//        combinedList.append(objectsIn: results)
+//        combinedList.append(objectsIn: history.listModels)
+//        TSRMShared.writeThread {
+//            history.listModels = combinedList
+//        }
+    }
+    
+    
+}
+
 extension TSRealmManager {
 extension TSRealmManager {
     func getDBHistory(type:TSDBHistoryType) -> TSDBHistory {
     func getDBHistory(type:TSDBHistoryType) -> TSDBHistory {
         let predicate = NSPredicate(format: "primaryKey == %@",type.rawValue)
         let predicate = NSPredicate(format: "primaryKey == %@",type.rawValue)
@@ -193,7 +288,7 @@ extension TSRealmManager {
         model.id = id
         model.id = id
         model.modelType = .example
         model.modelType = .example
         model.request.prompt = "Example"
         model.request.prompt = "Example"
-        model.request.promptSort = "Example"
+        model.request.inputText = "Example"
         model.request.width = 330
         model.request.width = 330
         model.request.height = 440
         model.request.height = 440
         model.response.resultUrl = imageName
         model.response.resultUrl = imageName
@@ -239,24 +334,7 @@ extension TSRealmManager {
         return ptpHistory
         return ptpHistory
     }
     }
     
     
-    //文生图
-    var ttpDBHistory:TSDBHistory {
 
 
-        let history = getDBHistory(type: TSDBHistoryType.ttp)
-        
-        if history.listModels.count == 0,UserDefaults.standard.string(forKey: "insertTTPExampleData") == nil {
-            let id = Date.timestampInt
-            history.updateDatas([
-                createExampleModel(id:id, imageName: "ttp_example_image0"),
-                createExampleModel(id:id+1, imageName: "ttp_example_image1")
-            ])
-            UserDefaults.standard.set("1", forKey: "insertTTPExampleData")
-            UserDefaults.standard.synchronize()
-        }
-        
-        return history
-        
-    }
 
 
     //文生表情
     //文生表情
     var ttEnmojiDBHistory:TSDBHistory {
     var ttEnmojiDBHistory:TSDBHistory {

+ 1 - 1
AIEmoji/Business/Data/TSUserDefaultData.swift

@@ -12,7 +12,7 @@ func kHandleDBHistoryOperation(){
         if model.modelType != 1 {
         if model.modelType != 1 {
             if model.isResult == false,model.id > 0 {
             if model.isResult == false,model.id > 0 {
                 let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: model.uuid)
                 let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: model.uuid)
-                generatePTPOperation.isSaveDB = true
+                generatePTPOperation.isSaveProcessToDB = true
                 generatePTPOperation.getActionInfo(oldModel: model.getModel())
                 generatePTPOperation.getActionInfo(oldModel: model.getModel())
             }
             }
         }
         }

+ 4 - 0
AIEmoji/Business/General/Ex/Notification+Ex.swift

@@ -21,4 +21,8 @@ extension Notification.Name {
     
     
     static let kOpenMotherDayVC = Notification.Name("kOpenMotherDayVC") //打开母亲节 vc
     static let kOpenMotherDayVC = Notification.Name("kOpenMotherDayVC") //打开母亲节 vc
     static let kOpenCatTohumanVC = Notification.Name("kOpenCatTohumanVC") //打开猫咪变人 vc
     static let kOpenCatTohumanVC = Notification.Name("kOpenCatTohumanVC") //打开猫咪变人 vc
+    
+    
+    static let kGenerateBasePhotoOperation = Notification.Name("TSGenerateBasePhotoOperation") //生成图生图任务发生变化
+    static let kAIPhotoDataChanged = Notification.Name("kGenerateBasePhotoChanged") //生成图片数据发生改变
 }
 }

+ 2 - 2
AIEmoji/Business/General/TSBigIconBrowseVC/TSBigIconBrowseVC.swift

@@ -201,8 +201,8 @@ extension TSBigIconBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate
             cell.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder: kPlaceholderImage,contentMode: .scaleAspectFill)
             cell.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder: kPlaceholderImage,contentMode: .scaleAspectFill)
             cell.vipImageView.isHidden = !model.response.vip
             cell.vipImageView.isHidden = !model.response.vip
             
             
-            if model.request.promptSort.count > 0 {
-                cell.textLabel.text = model.request.promptSort
+            if model.request.inputText.count > 0 {
+                cell.textLabel.text = model.request.inputText
             }else{
             }else{
                 cell.textLabel.text = model.request.prompt
                 cell.textLabel.text = model.request.prompt
             }
             }

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/TSAIExpandImageVC.swift

@@ -233,7 +233,7 @@ extension TSAIExpandImageVC {
         if kJudgeVip(externalBool: true, vc: self){ return } //判断 vip
         if kJudgeVip(externalBool: true, vc: self){ return } //判断 vip
         
         
         guard let upLoadImage = upLoadImage else { return }
         guard let upLoadImage = upLoadImage else { return }
-        let model = TSAIListPhotoGeneratorModel(
+        let model = TSAIGeneratorModel(
             upLoadImage: upLoadImage,
             upLoadImage: upLoadImage,
             generatorStyle: .photoExpand,
             generatorStyle: .photoExpand,
             expandEdge: photoExpand,
             expandEdge: photoExpand,

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseCell.swift

@@ -21,7 +21,7 @@ class TSAIListHistoryBaseCell: TSBaseCollectionCell,TSSimpleConfigurableView {
                 }else{
                 }else{
                     if dataModel.isVideo {
                     if dataModel.isVideo {
                         videoIconImageView.isHidden = false
                         videoIconImageView.isHidden = false
-                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoThumbnailURL.path)
+                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoPreviewUrlString)
                     }else {
                     }else {
                         showImageView.setAsyncImage(urlString: dataModel.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
                         showImageView.setAsyncImage(urlString: dataModel.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
                     }
                     }

+ 13 - 9
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVC.swift

@@ -4,7 +4,7 @@
 //
 //
 //  Created by 100Years on 2025/4/9.
 //  Created by 100Years on 2025/4/9.
 //
 //
-
+import RealmSwift
 class TSAIListHistoryBaseVC: TSBaseVC {
 class TSAIListHistoryBaseVC: TSBaseVC {
     var generatorStyle:TSGeneratorImageStyle
     var generatorStyle:TSGeneratorImageStyle
     var titleString:String?
     var titleString:String?
@@ -16,8 +16,7 @@ class TSAIListHistoryBaseVC: TSBaseVC {
     @MainActor required init?(coder: NSCoder) {
     @MainActor required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
         fatalError("init(coder:) has not been implemented")
     }
     }
-    
-    var listModelArray: [TSActionInfoModel] = []
+    var listModelArray = List<TSDBActionInfoModel>()//惰性加载特性
     //###################################### 集合视图 ######################################
     //###################################### 集合视图 ######################################
     let collectionViewBtootm:CGFloat = 80
     let collectionViewBtootm:CGFloat = 80
     lazy var collectionView: TSSimpleCollectionView = {
     lazy var collectionView: TSSimpleCollectionView = {
@@ -75,15 +74,18 @@ class TSAIListHistoryBaseVC: TSBaseVC {
     }
     }
     
     
     func updateDataView(){
     func updateDataView(){
-        dbHistory.getModelList { [weak self] array in
-            guard let self = self else { return }
-            listModelArray = array
-            updateView()
-        }
+//        dbHistory.getModelList { [weak self] array in
+//            guard let self = self else { return }
+//            listModelArray = array
+//            updateView()
+//        }
+        
+        listModelArray = dbHistory.listModels
+        updateView()
     }
     }
     
     
     func updateView() {
     func updateView() {
-        collectionView.reload(with:[TSSimpleSectionData(items: listModelArray)])
+//        collectionView.reload(with:[TSSimpleSectionData(items: listModelArray)])
         
         
         navRightBtn.isHidden = listModelArray.count <= 0
         navRightBtn.isHidden = listModelArray.count <= 0
         pageNullView.isHidden = listModelArray.count > 0
         pageNullView.isHidden = listModelArray.count > 0
@@ -149,6 +151,8 @@ extension TSAIListHistoryBaseVC{
             TSRMShared.catTohumanDBHistory
             TSRMShared.catTohumanDBHistory
         case .futureBaby:
         case .futureBaby:
             TSRMShared.futureBabyDBHistory
             TSRMShared.futureBabyDBHistory
+        default:
+            TSRMShared.futureBabyDBHistory
         }
         }
     }
     }
     
     

+ 12 - 2
AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift

@@ -5,7 +5,10 @@
 //  Created by 100Years on 2025/4/9.
 //  Created by 100Years on 2025/4/9.
 //
 //
 import Kingfisher
 import Kingfisher
-struct TSAIListPhotoGeneratorModel {
+
+
+
+class TSAIGeneratorModel {
     var upLoadImage:UIImage
     var upLoadImage:UIImage
     var generatorStyle:TSGeneratorImageStyle
     var generatorStyle:TSGeneratorImageStyle
     var expandEdge:UIEdgeInsets
     var expandEdge:UIEdgeInsets
@@ -30,11 +33,18 @@ struct TSAIListPhotoGeneratorModel {
         self.additionalPrompt = additionalPrompt
         self.additionalPrompt = additionalPrompt
         self.upLoadImages = upLoadImages
         self.upLoadImages = upLoadImages
     }
     }
+    
+    
+    var prompt:String = ""
+    var inputText:String = ""
+    var upLoadImageUrl:String?
+    var model:String = ""   //决定生图的模型
+    
 }
 }
 
 
 class TSAIListPhotoGeneratorBaseVC: TSAIPhotoGeneratorBaseVC {
 class TSAIListPhotoGeneratorBaseVC: TSAIPhotoGeneratorBaseVC {
 
 
-    init(generatorModel:TSAIListPhotoGeneratorModel,complete:@escaping ((TSActionInfoModel)->Void)) {
+    init(generatorModel:TSAIGeneratorModel,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.complete = complete
         self.complete = complete
         self.viewModel = TSAIListPhotoGeneratorBaseVM(generatorModel: generatorModel)
         self.viewModel = TSAIListPhotoGeneratorBaseVM(generatorModel: generatorModel)
         super.init()
         super.init()

+ 4 - 2
AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoGeneratorBaseVM/TSAIListPhotoGeneratorBaseVM.swift

@@ -33,8 +33,8 @@ class TSAIListPhotoGeneratorBaseVM {
     
     
     var imageUrl:String?
     var imageUrl:String?
     var imageUrls:[String]?
     var imageUrls:[String]?
-    var generatorModel:TSAIListPhotoGeneratorModel
-    init(generatorModel:TSAIListPhotoGeneratorModel) {
+    var generatorModel:TSAIGeneratorModel
+    init(generatorModel:TSAIGeneratorModel) {
         self.generatorModel = generatorModel
         self.generatorModel = generatorModel
     }
     }
     
     
@@ -199,6 +199,8 @@ class TSAIListPhotoGeneratorBaseVM {
                         "imageUrls":imageUrls
                         "imageUrls":imageUrls
                         ]
                         ]
             postDict.removeValue(forKey: "imageUrl")
             postDict.removeValue(forKey: "imageUrl")
+        default:
+            break;
         }
         }
         postDict["device"] = getUserInfoJsonString()
         postDict["device"] = getUserInfoJsonString()
         postDict["imageUrl"] = imageUrl
         postDict["imageUrl"] = imageUrl

+ 20 - 2
AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift

@@ -19,7 +19,7 @@ enum TSGeneratorImageStyle {
     case motherDay    //母亲节
     case motherDay    //母亲节
     case catTohuman    //猫变人
     case catTohuman    //猫变人
     case futureBaby    //预测宝宝
     case futureBaby    //预测宝宝
-    
+    case ptp            //通用的图生图
     
     
     var imageMaxKb:Int{
     var imageMaxKb:Int{
         switch self {
         switch self {
@@ -45,6 +45,8 @@ enum TSGeneratorImageStyle {
             return 10*1024
             return 10*1024
         case .futureBaby:
         case .futureBaby:
             return 10*1024
             return 10*1024
+        default:
+            return 10*1024
         }
         }
     }
     }
     
     
@@ -72,6 +74,8 @@ enum TSGeneratorImageStyle {
             return kUploadImageMaxBit10Size
             return kUploadImageMaxBit10Size
         case .futureBaby:
         case .futureBaby:
             return kUploadImageMaxBit10Size
             return kUploadImageMaxBit10Size
+        default:
+            return kUploadImageMaxBit10Size
         }
         }
     }
     }
     
     
@@ -99,6 +103,8 @@ enum TSGeneratorImageStyle {
             return "isFirstAICatTohuman"
             return "isFirstAICatTohuman"
         case .futureBaby:
         case .futureBaby:
             return "isFirstAIFutureBaby"
             return "isFirstAIFutureBaby"
+        default:
+            return ""
         }
         }
     }
     }
     
     
@@ -126,6 +132,9 @@ enum TSGeneratorImageStyle {
             return .catTohumanConfig
             return .catTohumanConfig
         case .futureBaby:
         case .futureBaby:
             return .futureBabyConfig
             return .futureBabyConfig
+            
+        default:
+            return .futureBabyConfig
         }
         }
     }
     }
     
     
@@ -137,6 +146,13 @@ enum TSGeneratorImageStyle {
             return false
             return false
         }
         }
     }
     }
+    
+    var isVideo:Bool{
+        if self == .photoLive {
+            return true
+        }
+        return false
+    }
 }
 }
 
 
 class TSAIUploadPhotoBaseVC: TSBaseVC {
 class TSAIUploadPhotoBaseVC: TSBaseVC {
@@ -455,7 +471,7 @@ extension TSAIUploadPhotoBaseVC {
         if generatorStyle != .catTohuman {
         if generatorStyle != .catTohuman {
             additionalPrompt = ""
             additionalPrompt = ""
         }
         }
-        let gennerateVC = TSAIListPhotoGeneratorBaseVC(generatorModel: TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)){ [weak self] model in
+        let gennerateVC = TSAIListPhotoGeneratorBaseVC(generatorModel: TSAIGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)){ [weak self] model in
             guard let self = self else { return }
             guard let self = self else { return }
             saveModel(model: model)
             saveModel(model: model)
         }
         }
@@ -485,6 +501,8 @@ extension TSAIUploadPhotoBaseVC {
             TSRMShared.motherDayDBHistory.updateData(model)
             TSRMShared.motherDayDBHistory.updateData(model)
         case .catTohuman:
         case .catTohuman:
             TSRMShared.catTohumanDBHistory.updateData(model)
             TSRMShared.catTohumanDBHistory.updateData(model)
+        default:
+            break;
         }
         }
     }
     }
 
 

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSPredictBabyVC/TSFutureBabyVC.swift

@@ -145,7 +145,7 @@ extension TSFutureBabyVC {
         }
         }
         
         
         let gennerateVC = TSAIListPhotoGeneratorBaseVC(generatorModel:
         let gennerateVC = TSAIListPhotoGeneratorBaseVC(generatorModel:
-            TSAIListPhotoGeneratorModel(
+            TSAIGeneratorModel(
                 upLoadImage: upLoadImage1,
                 upLoadImage: upLoadImage1,
                 generatorStyle: .futureBaby,
                 generatorStyle: .futureBaby,
                 additionalPrompt: additionalPrompt,
                 additionalPrompt: additionalPrompt,

+ 44 - 10
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift

@@ -35,8 +35,7 @@ class TSActionInfoModel: TSBaseModel {
     var percent:Float = 0.0
     var percent:Float = 0.0
     var actionStatus:ActionStatus = .failed
     var actionStatus:ActionStatus = .failed
     
     
-    var videoThumbnailPath:String = ""
-    var videoPath:String = ""
+
     
     
     var uuid:String = UUID().uuidString
     var uuid:String = UUID().uuidString
     override func mapping(map: ObjectMapper.Map) {
     override func mapping(map: ObjectMapper.Map) {
@@ -57,19 +56,31 @@ class TSActionInfoModel: TSBaseModel {
         
         
         uuid      <- map["uuid"]
         uuid      <- map["uuid"]
     }
     }
+    
+    
+
+    
+    var videoThumbnailPath:String = ""
+    var videoPath:String = ""
 }
 }
 
 
 extension TSActionInfoModel {
 extension TSActionInfoModel {
     var isVideo:Bool{
     var isVideo:Bool{
-        return videoThumbnailPath.count > 0
+        return videoThumbnailPath.count > 0 || response.videoDocument.count > 0
     }
     }
     
     
-    var videoThumbnailURL: URL {
-        return videoThumbnailPath.fillDocumentURL
+    var videoPreviewUrlString: String {
+        if videoThumbnailPath.count > 0 {
+            return videoThumbnailPath.fillDocumentPath
+        }
+        return response.previewUrl
     }
     }
     
     
     var videoURL: URL {
     var videoURL: URL {
-        return videoPath.fillDocumentURL
+        if videoPath.count > 0 {
+            return videoPath.fillDocumentURL
+        }
+        return response.videoDocument.fillDocumentURL
     }
     }
     
     
     
     
@@ -92,19 +103,20 @@ extension TSActionInfoModel {
 
 
 class TSActionRequestModel : TSBaseModel {
 class TSActionRequestModel : TSBaseModel {
     var prompt:String = ""
     var prompt:String = ""
-    var promptSort:String = ""  //用户自己输入的内容
+    var inputText:String = ""  //用户自己输入的内容
     var width:Int = 0
     var width:Int = 0
     var height:Int = 0
     var height:Int = 0
     
     
     var imageUrl:String = ""
     var imageUrl:String = ""
     var imageUrlTimestamp:Int = 0
     var imageUrlTimestamp:Int = 0
-    var style:String = ""
-    var advance:Bool = false//决定生图的模型
+
+    
     var model:String = ""   //决定生图的模型
     var model:String = ""   //决定生图的模型
+    var generatorStyle:TSGeneratorImageStyle = .ptp
     
     
     override func mapping(map: ObjectMapper.Map) {
     override func mapping(map: ObjectMapper.Map) {
         prompt              <- map["prompt"]
         prompt              <- map["prompt"]
-        promptSort          <- map["promptSort"]
+        inputText           <- map["inputText"]
         width               <- map["width"]
         width               <- map["width"]
         height              <- map["height"]
         height              <- map["height"]
         
         
@@ -113,15 +125,33 @@ class TSActionRequestModel : TSBaseModel {
         style               <- map["style"]
         style               <- map["style"]
         advance             <- map["advance"]
         advance             <- map["advance"]
         model               <- map["model"]
         model               <- map["model"]
+        generatorStyle      <- map["generatorStyle"]
     }
     }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    var style:String = ""
+    var advance:Bool = false//决定生图的模型
 }
 }
 
 
 class TSActionResponseModel : TSBaseModel {
 class TSActionResponseModel : TSBaseModel {
     var resultUrl:String = ""
     var resultUrl:String = ""
+    var previewUrl:String = ""
+    var videoDocument:String = ""
+    
     var code:Int = 0
     var code:Int = 0
     var vip:Bool = false
     var vip:Bool = false
     override func mapping(map: ObjectMapper.Map) {
     override func mapping(map: ObjectMapper.Map) {
         resultUrl           <- map["resultUrl"]
         resultUrl           <- map["resultUrl"]
+        previewUrl           <- map["previewUrl"]
+        videoDocument           <- map["videoDocument"]
+        
         vip                 <- map["vip"]
         vip                 <- map["vip"]
         code                <- map["code"]
         code                <- map["code"]
     }
     }
@@ -134,5 +164,9 @@ class TSActionResponseModel : TSBaseModel {
     var sensitiveError:Bool {
     var sensitiveError:Bool {
         return TSNetWorkCode.sensitiveError(code: code)
         return TSNetWorkCode.sensitiveError(code: code)
     }
     }
+    
+    var videoURL: URL {
+        return videoDocument.fillDocumentURL
+    }
 }
 }
 
 

+ 44 - 7
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSDBActionInfoModel.swift

@@ -12,7 +12,7 @@ class TSDBActionInfoModel: Object {
     @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
     @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
     @Persisted var createdAt: Date = Date()
     @Persisted var createdAt: Date = Date()
     
     
-    @Persisted var modelType:Int = 0
+    @Persisted var modelType:Int = 0 //0普通 1 示例
     @Persisted var id:Int = 0
     @Persisted var id:Int = 0
     @Persisted var actionType:String = ""
     @Persisted var actionType:String = ""
     @Persisted var comments:String = ""
     @Persisted var comments:String = ""
@@ -23,8 +23,10 @@ class TSDBActionInfoModel: Object {
     @Persisted var costTime:Int = 0
     @Persisted var costTime:Int = 0
     @Persisted var percent:Float = 0.0
     @Persisted var percent:Float = 0.0
     
     
+    //活照片用到的,后续慢慢废弃
     @Persisted var videoThumbnailPath:String = ""
     @Persisted var videoThumbnailPath:String = ""
     @Persisted var videoPath:String = ""
     @Persisted var videoPath:String = ""
+    
     @Persisted var uuid:String = UUID().uuidString
     @Persisted var uuid:String = UUID().uuidString
     
     
     static func createDBModel(actionInfoModel:TSActionInfoModel) -> TSDBActionInfoModel{
     static func createDBModel(actionInfoModel:TSActionInfoModel) -> TSDBActionInfoModel{
@@ -81,6 +83,19 @@ class TSDBActionInfoModel: Object {
     }
     }
     
     
     
     
+
+}
+
+
+extension TSDBActionInfoModel {
+    
+    var isVideo:Bool{
+        if let response = response,!response.videoDocument.isEmpty {
+            return true
+        }
+        return !videoThumbnailPath.isEmpty
+    }
+    
     var isResult:Bool {
     var isResult:Bool {
         if status.count > 0 {
         if status.count > 0 {
             if status == "pending" ||
             if status == "pending" ||
@@ -92,17 +107,32 @@ class TSDBActionInfoModel: Object {
         return true
         return true
     }
     }
 
 
+    
+    func deleteResources() {
+        if let response = response {
+            TSImageStoreTool.removeImage(urlString:response.resultUrl)
+            TSImageStoreTool.removeImage(urlString:response.previewUrl)
+            if !response.videoDocument.isEmpty {
+                TSFileManagerTool.removeItem(from: response.videoDocument.fillDocumentURL)
+            }
+            
+        }
+        
+        if !videoPath.isEmpty {
+            TSFileManagerTool.removeItem(from: videoPath.fillDocumentURL)
+        }
+        if !videoThumbnailPath.isEmpty {
+            TSFileManagerTool.removeItem(from: videoThumbnailPath.fillDocumentURL)
+        }
+    }
 }
 }
-
-
-
 class TSDBActionRequestModel : Object {
 class TSDBActionRequestModel : Object {
     
     
     @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
     @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
     @Persisted var createdAt: Date = Date()
     @Persisted var createdAt: Date = Date()
     
     
     @Persisted var prompt:String = ""
     @Persisted var prompt:String = ""
-    @Persisted var promptSort:String = ""  //用户自己输入的内容
+    @Persisted var inputText:String = ""  //用户自己输入的内容
     @Persisted var width:Int = 0
     @Persisted var width:Int = 0
     @Persisted var height:Int = 0
     @Persisted var height:Int = 0
     
     
@@ -119,7 +149,7 @@ class TSDBActionRequestModel : Object {
     
     
     func saveData(requestModel:TSActionRequestModel) {
     func saveData(requestModel:TSActionRequestModel) {
         self.prompt = requestModel.prompt
         self.prompt = requestModel.prompt
-        self.promptSort = requestModel.promptSort
+        self.inputText = requestModel.inputText
         self.width = requestModel.width
         self.width = requestModel.width
         self.height = requestModel.height
         self.height = requestModel.height
         
         
@@ -133,7 +163,7 @@ class TSDBActionRequestModel : Object {
     func getModel()->TSActionRequestModel{
     func getModel()->TSActionRequestModel{
         let model = TSActionRequestModel()
         let model = TSActionRequestModel()
         model.prompt = self.prompt
         model.prompt = self.prompt
-        model.promptSort = self.promptSort
+        model.inputText = self.inputText
         model.width = self.width
         model.width = self.width
         model.height = self.height
         model.height = self.height
         
         
@@ -152,6 +182,9 @@ class TSDBActionResponseModel : Object {
     @Persisted var createdAt: Date = Date()
     @Persisted var createdAt: Date = Date()
     
     
     @Persisted var resultUrl:String = ""
     @Persisted var resultUrl:String = ""
+    @Persisted var previewUrl:String = ""
+    @Persisted var videoDocument:String = ""
+    
     @Persisted var code:Int = 0
     @Persisted var code:Int = 0
     @Persisted var vip:Bool = false
     @Persisted var vip:Bool = false
     
     
@@ -163,6 +196,8 @@ class TSDBActionResponseModel : Object {
     
     
     func saveData(responseModel:TSActionResponseModel) {
     func saveData(responseModel:TSActionResponseModel) {
         self.resultUrl = responseModel.resultUrl
         self.resultUrl = responseModel.resultUrl
+        self.previewUrl = responseModel.previewUrl
+        self.videoDocument = responseModel.videoDocument
         self.code = responseModel.code
         self.code = responseModel.code
         self.vip = responseModel.vip
         self.vip = responseModel.vip
     }
     }
@@ -171,6 +206,8 @@ class TSDBActionResponseModel : Object {
     func getModel()->TSActionResponseModel{
     func getModel()->TSActionResponseModel{
         let model = TSActionResponseModel()
         let model = TSActionResponseModel()
         model.resultUrl = self.resultUrl
         model.resultUrl = self.resultUrl
+        model.previewUrl = self.previewUrl
+        model.videoDocument = self.videoDocument
         model.code = self.code
         model.code = self.code
         model.vip = self.vip
         model.vip = self.vip
         return model
         return model

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift

@@ -83,7 +83,7 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
                 if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
                 if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
                 if TSGeneratePTPOperationQueue.shared.isAvailability {
                 if TSGeneratePTPOperationQueue.shared.isAvailability {
                     let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: dataModel.uuid)
                     let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: dataModel.uuid)
-                    generatePTPOperation.isSaveDB = true
+                    generatePTPOperation.isSaveProcessToDB = true
                     generatePTPOperation.creatImage(oldModel: dataModel)
                     generatePTPOperation.creatImage(oldModel: dataModel)
                     generateView.setProgress(progress: 0)
                     generateView.setProgress(progress: 0)
                 }
                 }

+ 24 - 25
AIEmoji/Business/TSPTPGeneratorVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoBrowseVC.swift

@@ -7,9 +7,10 @@
 
 
 private let cellId = "TSAIPhotoBrowseCell"
 private let cellId = "TSAIPhotoBrowseCell"
 private let videoCellId = "TSAIVideoBrowseCell"
 private let videoCellId = "TSAIVideoBrowseCell"
+import RealmSwift
 class TSAIPhotoBrowseVC: TSBaseVC {
 class TSAIPhotoBrowseVC: TSBaseVC {
-    var deleteComplete:((TSActionInfoModel)->Void)?
-    var dataModelArray = [TSActionInfoModel]()
+    var deleteComplete:((TSDBActionInfoModel)->Void)?
+    var dataModelArray = List<TSDBActionInfoModel>()//惰性加载特性
     var currentImage:UIImage?{
     var currentImage:UIImage?{
         let cell = collectionView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? TSAIPhotoBrowseCell
         let cell = collectionView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? TSAIPhotoBrowseCell
         var image = cell?.netWorkImageView.image
         var image = cell?.netWorkImageView.image
@@ -17,8 +18,8 @@ class TSAIPhotoBrowseVC: TSBaseVC {
         return image
         return image
     }
     }
 
 
-    var currentModel:TSActionInfoModel?{
-        if let model = dataModelArray.safeObj(At: currentIndex){
+    var currentModel:TSDBActionInfoModel?{
+        if let model = dataModelArray[safe:currentIndex]{
             return model
             return model
         }
         }
         return nil
         return nil
@@ -209,13 +210,10 @@ class TSAIPhotoBrowseVC: TSBaseVC {
         addPullDownClosePage()
         addPullDownClosePage()
     }
     }
     @objc func clickSubmitBtn(){
     @objc func clickSubmitBtn(){
-        
-        if JudgeVip(){
-            return
-        }
-        
+
         guard let currentModel = currentModel else { return }
         guard let currentModel = currentModel else { return }
-        let urlString = currentModel.response.resultUrl
+        guard let response = currentModel.response else { return }
+        let urlString = response.resultUrl
         if currentModel.isVideo {
         if currentModel.isVideo {
             TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
             TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
                 if let url = url {
                 if let url = url {
@@ -256,9 +254,9 @@ class TSAIPhotoBrowseVC: TSBaseVC {
     }
     }
     
     
     
     
-    func JudgeVip() -> Bool {
-        return kJudgeVip(externalBool: currentModel?.response.vip ?? false , vc: self, closePageBlock: nil)
-    }
+//    func JudgeVip() -> Bool {
+//        return kJudgeVip(externalBool: currentModel?.response.vip ?? false , vc: self, closePageBlock: nil)
+//    }
     
     
     @objc func clickXBtn(){
     @objc func clickXBtn(){
         pop()
         pop()
@@ -269,7 +267,8 @@ class TSAIPhotoBrowseVC: TSBaseVC {
 //        kShareContent(target: self, anyData: image)
 //        kShareContent(target: self, anyData: image)
         
         
         guard let currentModel = currentModel else { return }
         guard let currentModel = currentModel else { return }
-        let urlString = currentModel.response.resultUrl
+        guard let response = currentModel.response else { return }
+        let urlString = response.resultUrl
         if currentModel.isVideo {
         if currentModel.isVideo {
             TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
             TSDownloadManager.getDownLoadVideo(urlString: urlString) { url, _ in
                 if let url = url {
                 if let url = url {
@@ -318,29 +317,29 @@ extension TSAIPhotoBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate
     }
     }
     
     
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        if let model = dataModelArray.safeObj(At: indexPath.item){
+        if let model = dataModelArray[safe:indexPath.item]{
             if model.isVideo {
             if model.isVideo {
                 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: videoCellId, for: indexPath) as! TSAIVideoBrowseCell
                 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: videoCellId, for: indexPath) as! TSAIVideoBrowseCell
-                cell.model = model
+                cell.model = model.getModel()
+                return cell
+            }else{
+                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! TSAIPhotoBrowseCell
+                cell.model = model.getModel()
                 return cell
                 return cell
             }
             }
         }
         }
         
         
-        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! TSAIPhotoBrowseCell
-        if let model = dataModelArray.safeObj(At: indexPath.item){
-            cell.model = model
-        }
-        return cell
+        return UICollectionViewCell()
     }
     }
     
     
     func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
     func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
-        if let model = dataModelArray.safeObj(At: indexPath.item){
+        if let model = dataModelArray[safe:indexPath.item]{
             if model.isVideo {
             if model.isVideo {
                 guard let cell = cell as? TSAIVideoBrowseCell else { return }
                 guard let cell = cell as? TSAIVideoBrowseCell else { return }
-                cell.model = model
+                cell.model = model.getModel()
             }else{
             }else{
                 guard let cell = cell as? TSAIPhotoBrowseCell else { return }
                 guard let cell = cell as? TSAIPhotoBrowseCell else { return }
-                cell.model = model
+                cell.model = model.getModel()
             }
             }
         }
         }
     }
     }
@@ -349,7 +348,7 @@ extension TSAIPhotoBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate
                       didEndDisplaying cell: UICollectionViewCell,
                       didEndDisplaying cell: UICollectionViewCell,
                       forItemAt indexPath: IndexPath) {
                       forItemAt indexPath: IndexPath) {
 
 
-        if let model = dataModelArray.safeObj(At: indexPath.item){
+        if let model = dataModelArray[safe:indexPath.item]{
             if model.isVideo {
             if model.isVideo {
                 guard let cell = cell as? TSAIVideoBrowseCell else { return }
                 guard let cell = cell as? TSAIVideoBrowseCell else { return }
                 cell.videoPlayerVC?.playPause()
                 cell.videoPlayerVC?.playPause()

+ 2 - 2
AIEmoji/Business/TSPTPGeneratorVC/TSAbnormalPopUpAlertVC/TSAbnormalPopUpAlertVC.swift

@@ -12,7 +12,7 @@ class TSAbnormalPopUpAlertVC: TSBaseVC {
     var text:String = "" {
     var text:String = "" {
         didSet{
         didSet{
             textLab.text = text
             textLab.text = text
-            textLab.setLineSpacing(6.0, alignment: .center)
+            textLab.setLineSpacing(6.0)
         }
         }
     }
     }
     var isAddView:Bool = false
     var isAddView:Bool = false
@@ -38,7 +38,7 @@ class TSAbnormalPopUpAlertVC: TSBaseVC {
     
     
     lazy var textLab: UILabel = {
     lazy var textLab: UILabel = {
         let textLab = UILabel.createLabel(text: text,font: .font(size: 16),textColor: .white,textAlignment: .center,numberOfLines: 0)
         let textLab = UILabel.createLabel(text: text,font: .font(size: 16),textColor: .white,textAlignment: .center,numberOfLines: 0)
-        textLab.setLineSpacing(6.0, alignment: .center)
+        textLab.setLineSpacing(6.0)
         return textLab
         return textLab
     }()
     }()
     lazy var submitBtn: UIButton = {
     lazy var submitBtn: UIButton = {

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPTPBrowseVC/TSPTPBrowseVC.swift

@@ -196,7 +196,7 @@ extension TSPTPBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate {
             }
             }
 
 
             cell.vipImageView.isHidden = !model.response.vip
             cell.vipImageView.isHidden = !model.response.vip
-            cell.textLabel.text = model.request.promptSort
+            cell.textLabel.text = model.request.inputText
         }
         }
         return cell
         return cell
     }
     }

+ 2 - 2
AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift

@@ -142,7 +142,7 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
     
     
     //后台生成
     //后台生成
     @objc func clickBackstageBtn() {
     @objc func clickBackstageBtn() {
-        self.operation.isSaveDB = true //后台生成,让数据库保存数据
+        self.operation.isSaveProcessToDB = true //后台生成,让数据库保存数据
         if let model = infoModel {
         if let model = infoModel {
             TSRMShared.ptpDBHistory.updateData(model)
             TSRMShared.ptpDBHistory.updateData(model)
             debugPrint("图生图进入后台,保存数据listModels.first=\(TSRMShared.ptpDBHistory.listModels.first)")
             debugPrint("图生图进入后台,保存数据listModels.first=\(TSRMShared.ptpDBHistory.listModels.first)")
@@ -340,7 +340,7 @@ extension TSPTPGeneratorVC {
         self.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
         self.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
         
         
         if let model = infoModel {
         if let model = infoModel {
-            model.request.promptSort = viewModel.generateStyleModel.inputText
+            model.request.inputText = viewModel.generateStyleModel.inputText
             complete(model)
             complete(model)
         }
         }
     }
     }

+ 12 - 4
AIEmoji/Business/TSPTPGeneratorVC/TSPTPHistoryVC/TSPTPHistoryVC.swift

@@ -111,17 +111,25 @@ class TSPTPHistoryVC: TSBaseVC {
         })
         })
     }
     }
 }
 }
-
+import RealmSwift
 extension TSPTPHistoryVC: TSSimpleCollectionViewDelegate {
 extension TSPTPHistoryVC: TSSimpleCollectionViewDelegate {
     
     
     func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
     func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
         switch event.action {
         switch event.action {
         case .tap:
         case .tap:
             guard let selectedModel = listModelArray.safeObj(At: event.indexPath.item) else { return }
             guard let selectedModel = listModelArray.safeObj(At: event.indexPath.item) else { return }
-            let dataModelArray = listModelArray.filter{$0.status == "success" || $0.modelType == .example}
+//            let dataModelArray = listModelArray.filter{$0.status == "success" || $0.modelType == .example}
+            
+            
+            let filteredResults = TSRMShared.ptpDBHistory.listModels.filter("status == %@", "success")//直接过滤List(返回Results类型)
+            let filteredList = List<TSDBActionInfoModel>()
+            filteredList.append(objectsIn: filteredResults)
+            
+            
             let browseVC = TSAIPhotoBrowseVC()
             let browseVC = TSAIPhotoBrowseVC()
-            browseVC.dataModelArray = dataModelArray
-            browseVC.currentIndex = dataModelArray.firstIndex(of: selectedModel) ?? 0
+//            browseVC.dataModelArray = dataModelArray
+            browseVC.dataModelArray = filteredList
+            browseVC.currentIndex = filteredList.firstIndex(where: { $0.id == selectedModel.id }) ?? 0
             browseVC.deleteComplete = { [weak self]  deleteModel in
             browseVC.deleteComplete = { [weak self]  deleteModel in
                 guard let self = self else { return }
                 guard let self = self else { return }
                 dbHistory.deleteListModel(id: deleteModel.id)
                 dbHistory.deleteListModel(id: deleteModel.id)

+ 14 - 9
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift

@@ -4,7 +4,7 @@
 //
 //
 //  Created by 100Years on 2025/4/7.
 //  Created by 100Years on 2025/4/7.
 //
 //
-
+import RealmSwift
 import PhotosUI
 import PhotosUI
 class TSPTPInputVC: TSBaseVC {
 class TSPTPInputVC: TSBaseVC {
     lazy var viewModel: TSPTPInputVM = {
     lazy var viewModel: TSPTPInputVM = {
@@ -230,16 +230,21 @@ class TSPTPInputVC: TSBaseVC {
             guard let self = self else { return }
             guard let self = self else { return }
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
                let dataModel = sections.items.safeObj(At: indexPath.item)?.dataModel {
                let dataModel = sections.items.safeObj(At: indexPath.item)?.dataModel {
-                var dataModelArray: [TSActionInfoModel] = []
-                for itemModel in sections.items {
-                    if itemModel.dataModel.status == "success" || itemModel.dataModel.modelType == .example {
-                        dataModelArray.append(itemModel.dataModel)
-                    }
-                }
+//                var dataModelArray: [TSActionInfoModel] = []
+//                for itemModel in sections.items {
+//                    if itemModel.dataModel.status == "success" || itemModel.dataModel.modelType == .example {
+//                        dataModelArray.append(itemModel.dataModel)
+//                    }
+//                }
+                
+                
+                let filteredResults = TSRMShared.ptpDBHistory.listModels.filter("status == %@", "success")//直接过滤List(返回Results类型)
+                let filteredList = List<TSDBActionInfoModel>()
+                filteredList.append(objectsIn: filteredResults)
 
 
                 let browseVC = TSAIPhotoBrowseVC()
                 let browseVC = TSAIPhotoBrowseVC()
-                browseVC.dataModelArray = dataModelArray
-                browseVC.currentIndex = dataModelArray.firstIndex(of: dataModel) ?? 0
+                browseVC.dataModelArray = filteredList
+                browseVC.currentIndex = filteredList.firstIndex(where: { $0.id == dataModel.id }) ?? 0
                 browseVC.deleteComplete = { [weak self]  deleteModel in
                 browseVC.deleteComplete = { [weak self]  deleteModel in
                     guard let self = self else { return }
                     guard let self = self else { return }
                     TSRMShared.ptpDBHistory.deleteListModel(id: deleteModel.id)
                     TSRMShared.ptpDBHistory.deleteListModel(id: deleteModel.id)

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/TSPhotoToPhotoVC.swift

@@ -336,7 +336,7 @@ extension TSPhotoToPhotoVC {
         guard let selectedPTPStyleModel = viewModel.selectedPTPStyleModel else { return }
         guard let selectedPTPStyleModel = viewModel.selectedPTPStyleModel else { return }
         guard let upLoadImage = viewModel.upLoadImage else { return }
         guard let upLoadImage = viewModel.upLoadImage else { return }
 
 
-        let gennerateVC = TSPTPGeneratorVC(prompt: selectedPTPStyleModel.prompt,promptSort: selectedPTPStyleModel.imageText , imageUrl: "",upLoadImage: upLoadImage,style: selectedPTPStyleModel.style) { [weak self] model in
+        let gennerateVC = TSPTPGeneratorVC(prompt: selectedPTPStyleModel.prompt,inputText: selectedPTPStyleModel.imageText , imageUrl: "",upLoadImage: upLoadImage,style: selectedPTPStyleModel.style) { [weak self] model in
             guard let self = self else { return }
             guard let self = self else { return }
             if viewModel.saveModel(model:model) {
             if viewModel.saveModel(model:model) {
                 collectionComponent.clear()
                 collectionComponent.clear()

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/VM/TSPhotoToPhotoVM.swift

@@ -132,7 +132,7 @@ class TSPhotoToPhotoVM {
         let model = TSActionInfoModel()
         let model = TSActionInfoModel()
         model.modelType = .example
         model.modelType = .example
         model.request.prompt = "Example"
         model.request.prompt = "Example"
-        model.request.promptSort = "Example"
+        model.request.inputText = "Example"
         model.request.width = 330
         model.request.width = 330
         model.request.height = 440
         model.request.height = 440
         model.response.resultUrl = imageName
         model.response.resultUrl = imageName

+ 6 - 2
AIEmoji/Business/TSTabBarController/TSTabBarController.swift

@@ -43,8 +43,8 @@ class TSTabBarController: UITabBarController {
 
 
     @objc private func setUpData() {
     @objc private func setUpData() {
 
 
-        viewControllerArray = ["TSPTPInputVC","TSAILIstVC","TSTTPInputVC","TSChatViewController","TSSetingVC"]
-        titleArray = ["Photo","AI Store","Text","Chat","Setting"]
+        viewControllerArray = ["TSPTPInputVC","TSAILIstVC","TSTTPInputVC","TSGenerateHistoryVC","TSSetingVC"]
+        titleArray = ["Photo","AI Store","Text","Creations","Setting"]
         selectedImageArray = [
         selectedImageArray = [
             "tabbar_select_pic",
             "tabbar_select_pic",
             "tabbar_select_ailist",
             "tabbar_select_ailist",
@@ -135,6 +135,10 @@ extension TSTabBarController {
             }
             }
         }
         }
     }
     }
+    
+    func changeSelectedIndex(index:Int){
+        self.selectedIndex = index
+    }
 }
 }
 
 
 extension TSTabBarController:UITabBarControllerDelegate {
 extension TSTabBarController:UITabBarControllerDelegate {

+ 6 - 5
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC+Col.swift

@@ -32,13 +32,14 @@ extension TSTTPInputVC {
             guard let self = self else { return }
             guard let self = self else { return }
             if indexPath.section == 0{
             if indexPath.section == 0{
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
-                    var dataModelArray:[TSActionInfoModel] = []
-                    for itemModel in sections.items {
-                        dataModelArray.append(itemModel.dataModel)
-                    }
+//                    var dataModelArray:[TSActionInfoModel] = []
+//                    for itemModel in sections.items {
+//                        dataModelArray.append(itemModel.dataModel)
+//                    }
                     
                     
                     let browseVC = TSAIPhotoBrowseVC()
                     let browseVC = TSAIPhotoBrowseVC()
-                    browseVC.dataModelArray = dataModelArray
+//                    browseVC.dataModelArray = dataModelArray
+                    browseVC.dataModelArray = TSRMShared.ttpDBHistory.listModels
                     browseVC.currentIndex = indexPath.item
                     browseVC.currentIndex = indexPath.item
                     browseVC.deleteComplete = { [weak self]  deleteModel in
                     browseVC.deleteComplete = { [weak self]  deleteModel in
                         guard let self = self else { return }
                         guard let self = self else { return }

+ 1 - 1
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift

@@ -216,7 +216,7 @@ extension TSTTPInputVC {
         if kJudgeVip(externalBool: isVip, vc: self) { return } //判断 vip
         if kJudgeVip(externalBool: isVip, vc: self) { return } //判断 vip
         let gennerateVC = TSTextPicGennerateVC(generateStyleModel: viewModel.generateStyleModel) {[weak self] model in
         let gennerateVC = TSTextPicGennerateVC(generateStyleModel: viewModel.generateStyleModel) {[weak self] model in
             guard let self = self else { return }
             guard let self = self else { return }
-            model.request.promptSort = viewModel.promptText
+            model.request.inputText = viewModel.promptText
             viewModel.saveModel(model: model)
             viewModel.saveModel(model: model)
             updateVipView()
             updateVipView()
             reloadUIBlock?()
             reloadUIBlock?()

+ 2 - 1
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/TSTextGeneralPictureVC.swift

@@ -63,7 +63,8 @@ class TSTextGeneralPictureVC: TSBaseVC {
                     }
                     }
                     
                     
                     let browseVC = TSAIPhotoBrowseVC()
                     let browseVC = TSAIPhotoBrowseVC()
-                    browseVC.dataModelArray = dataModelArray
+//                    browseVC.dataModelArray = dataModelArray
+                    browseVC.dataModelArray = TSRMShared.ttpDBHistory.listModels
                     browseVC.currentIndex = indexPath.item
                     browseVC.currentIndex = indexPath.item
                     browseVC.deleteComplete = { [weak self]  deleteModel in
                     browseVC.deleteComplete = { [weak self]  deleteModel in
                         guard let self = self else { return }
                         guard let self = self else { return }

+ 27 - 0
AIEmoji/Business2/Data/TSDiscoverViewModel.swift

@@ -0,0 +1,27 @@
+//
+//  TSHomeViewModel.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/6/21.
+//
+
+
+
+
+class aaa {
+    
+}
+
+class TSDiscoverViewModel {
+    
+    
+    
+    
+    //顶部功能 1
+    lazy var topFunc0: [Int] = {
+        
+        return []
+    }()
+    
+    
+}

+ 239 - 0
AIEmoji/Business2/TSGenerateHistoryVC/TSGenerateHistoryVC.swift

@@ -0,0 +1,239 @@
+//
+//  TSGenerateHistoryVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/6/22.
+//
+
+import RealmSwift
+
+class TSGenerateHistoryVC: TSBaseVC {
+
+    var listModelArray = List<TSDBActionInfoModel>()//惰性加载特性
+    //###################################### 导航栏 view ######################################
+    lazy var vipBtn: UIButton = {
+       let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self]  in
+           guard let self = self else { return }
+           TSPurchaseVC.show(target: self) {}
+       }
+       return vipBtn
+   }()
+    
+    lazy var navBarView: TSBaseNavContentBarView = {
+        let navBarView = TSBaseNavContentBarView()
+
+        let label = UILabel.createLabel(text: "Creations".localized,font: .font(name: .KelsiFill,size: 28))
+        navBarView.barView.addSubview(label)
+        label.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(17.0)
+        }
+        
+        navBarView.barView.addSubview(vipBtn)
+        vipBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-16)
+            make.width.height.equalTo(32)
+        }
+        
+        kMainAsync {
+            label.applyGradient(colors: ["#FA794F".uiColor,"#F8C32A".uiColor,"#FEFBF4".uiColor])
+        }
+        
+       return navBarView
+    }()
+    
+    //###################################### 集合视图 ######################################
+    let collectionViewBtootm:CGFloat = 80
+
+    let identifier = "TSAIListHistoryCell"
+    lazy var collectionView: UICollectionView = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
+        
+        let itemW = (k_ScreenWidth-32.0-13.0-2.0)/2.0
+        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 220.0), width: itemW)
+
+        layout.itemSize = CGSize(width: itemW, height: itemH)
+        layout.minimumInteritemSpacing = 13
+        layout.minimumLineSpacing = 16
+        layout.sectionInset = UIEdgeInsets(top: 10, left: 16, bottom: k_Height_TabBar+20, right: 16)
+        
+        let collectionView = TSBaseCollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.register(TSGenerateHistoryCell.self, forCellWithReuseIdentifier: identifier)
+        return collectionView
+    }()
+    
+    lazy var pageNullView: TSPageNullView = {
+        let pageNullView = TSPageNullView()
+        pageNullView.isHidden = true
+        return pageNullView
+    }()
+    
+    override func createData() {
+        
+    }
+    
+    var navRightBtn = UIButton()
+    override func createView() {
+        addNormalNavBarView()
+
+        navBarContentView.addSubview(navBarView)
+        navBarView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        contentView.addSubview(pageNullView)
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+    
+    override func dealThings() {
+        updateDataView()
+        NotificationCenter.default.addObserver(self, selector: #selector(operationChanged(_:)), name: .kGenerateBasePhotoOperation, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(updateDataView), name: .kAIPhotoDataChanged, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(updateVipView), name: .kPurchaseDidChanged, object: nil)
+        updateVipView()
+    }
+    
+    @objc func operationChanged(_ notification: Notification) {
+        if let userInfo = notification.userInfo as? [String: Any],let state = userInfo["state"] as? TSProgressState {
+            if state.reloadNewData {
+                self.updateDataView()
+            }
+        }
+    }
+    
+    @objc func updateVipView() {
+        kMainAsync{
+            self.vipBtn.isHidden = PurchaseManager.default.isVip
+        }
+    }
+    
+    @objc func updateDataView(){
+//        dbHistory.getModelList { [weak self] array in
+//            guard let self = self else { return }
+//            listModelArray = array
+//            updateView()
+//        }
+        listModelArray = dbHistory.listModels//惰性加载特性
+        updateView()
+    }
+    
+
+    func updateView() {
+        collectionView.reloadData()
+        
+        navRightBtn.isHidden = listModelArray.count <= 0
+        pageNullView.isHidden = listModelArray.count > 0
+    }
+    
+    override func viewWillAppear(_ animated: Bool) {
+        print("viewWillAppear")
+    }
+    
+    @objc func clickNavRight() {
+        TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
+            message: "Are you sure to delete all histories?".localized,
+            cancelTitle: "Delete All".localized,
+            cancelColor: .red,
+            confirmTitle: "Retain".localized,
+            confirmColor: .white,
+            cancelAction: { [weak self]  in
+                guard let self = self else { return }
+                self.removeAllHistoryList()
+                self.updateDataView()
+            }
+        ))
+    }
+}
+
+extension TSGenerateHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return listModelArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
+        if let cell = cell as? TSGenerateHistoryCell ,let dbModel = listModelArray[safe:indexPath.row]{
+            cell.dataModel = dbModel.getModel()
+            cell.buttonTapped = { [weak self] cmd in
+                self?.handelCellCmd(cmd: cmd,indexPath: indexPath)
+            }
+        }
+        
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        guard let selectedModel = listModelArray[safe:indexPath.row] else { return }
+        let filteredResults = listModelArray.filter("status == %@", "success")//直接过滤List(返回Results类型)
+        let filteredList = List<TSDBActionInfoModel>()
+        filteredList.append(objectsIn: filteredResults)
+        
+        let browseVC = TSAIPhotoBrowseVC()
+        browseVC.dataModelArray = filteredList
+        browseVC.currentIndex = filteredList.firstIndex(of: selectedModel) ?? 0
+        browseVC.deleteComplete = { [weak self]  deleteModel in
+            guard let self = self else { return }
+            dbHistory.deleteListModel(uuid: deleteModel.uuid)
+            updateDataView()
+        }
+        kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
+    }
+}
+
+extension TSGenerateHistoryVC{
+    func handelCellCmd(cmd:String,indexPath: IndexPath){
+        if let currentActionInfoModel = listModelArray[safe:indexPath.row]{
+            if cmd == "delete_task_expired" {
+                dbHistory.deleteListModel(id: currentActionInfoModel.id)
+                updateDataView()
+            }else if cmd == "delete_task_sensitive" {
+                showDeleteErrorAlert(message: "Delete this error history?".localized, deleteHandler:  { [weak self]  in
+                    guard let self = self else { return }
+                    dbHistory.deleteListModel(id: currentActionInfoModel.id)
+                    updateDataView()
+                })
+            }else if cmd == "delete" {
+                TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
+                    message: "Are you sure to delete?".localized,
+                    cancelTitle: "Delete".localized,
+                    cancelColor: .red,
+                    confirmTitle: "Retain".localized,
+                    confirmColor: .white,
+                    cancelAction: { [weak self]  in
+                        guard let self = self else { return }
+                        removeDelete(index: indexPath.row)
+                    }
+                ))
+            }
+        }
+    }
+    
+    func removeDelete(index:Int){
+        dbHistory.deleteListModel(index: index)
+        updateDataView()
+    }
+    
+    func removeAllHistoryList(){
+        dbHistory.deleteAll()
+        updateDataView()
+    }
+    
+    var dbHistory:TSDBHistory{
+        TSRMShared.aiGenerateDB
+    }
+}
+extension TSGenerateHistoryVC{
+
+    static func showPosition(){
+        AppDelegate.tabbar?.changeSelectedIndex(index: 1)
+    }
+    
+}

+ 193 - 0
AIEmoji/Business2/TSGenerateHistoryVC/View/TSGenerateHistoryCell.swift

@@ -0,0 +1,193 @@
+//
+//  TSGenerateHistoryCell.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/6/22.
+//
+
+import RealmSwift
+class TSGenerateHistoryCell: TSBaseCollectionCell {
+    var buttonTapped:((String)->Void)?
+    var operation:TSGenerateBasePhotoOperation?
+    var dataModel:TSActionInfoModel = TSActionInfoModel(){
+        didSet {
+            self.updataActionInfoModelView(model: dataModel)
+            if let operation = TSGenerateBasePhotoOperationQueue.shared.findOperation(uuid: dataModel.uuid) as? TSGenerateBasePhotoOperation {
+                DispatchQueue.main.async {
+                    operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
+                        guard let self = self else { return }
+                        DispatchQueue.main.async {
+//                            print("actionInfoModel.toJSONString()=\(actionInfoModel.toJSONString())")
+                            self.updataActionInfoModelView(model: actionInfoModel)
+                        }
+                    }
+                    self.operation = operation
+                }
+            }else{
+                self.operation?.currentActionInfoModelChanged = nil
+                self.operation = nil
+            }
+        }
+    }
+    
+
+    lazy var generateView: TSGennerateCellView = {
+        let generateView = TSGennerateCellView()
+        generateView.isHidden = true
+        generateView.refreshHandel = { [weak self]  in
+            guard let self = self else { return }
+            if dataModel.upImageURLExpired { //任务已经过期了
+                buttonTapped?("delete_task_expired")
+            }else if dataModel.response.sensitiveError { //敏感内容
+                buttonTapped?("delete_task_sensitive")
+            }else{
+//                if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
+                if TSGenerateBasePhotoOperationQueue.shared.isAvailability {
+                    let generatePTPOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: dataModel.uuid)
+                    generatePTPOperation.isSaveProcessToDB = true
+                    generatePTPOperation.creatImage(oldModel: dataModel){ complete in }
+                    generateView.setProgress(progress: 0)
+                }
+            }
+        }
+        
+        generateView.longPressHandel = { [weak self]  in
+            guard let self = self else { return }
+            buttonTapped?("delete")
+        }
+        return generateView
+    }()
+    
+    
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(
+            text: "Example".localized,
+            font: .font(size: 12),
+            textColor: .white
+        )
+        return textLabel
+    }()
+    
+    lazy var exampleView: UIView = {
+        let exampleView = UIView()
+        exampleView.backgroundColor = "#232323".uiColor.withAlphaComponent(0.3)
+        
+        exampleView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.edges.equalTo(UIEdgeInsets(top: 4, left: 6, bottom: 4, right: 6))
+        }
+        exampleView.isHidden = true
+        return exampleView
+    }()
+    
+    lazy var showImageView: UIImageView = {
+        let showImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+        showImageView.backgroundColor = .gray
+        return showImageView
+    }()
+    
+    lazy var hiddenImageView: UIImageView = {
+        let hiddenImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+        hiddenImageView.backgroundColor = .gray
+        hiddenImageView.isHidden = true
+        return hiddenImageView
+    }()
+    
+    lazy var videoIconImageView: UIImageView = {
+        let videoIconImageView = UIImageView.createImageView(image:.videoIcon,contentMode: .scaleToFill,autoMirrored:false)
+        videoIconImageView.isHidden = true
+        return videoIconImageView
+    }()
+    
+    @objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
+        // 确保只在手势开始时触发一次
+        guard gestureRecognizer.state == .began else { return }
+        buttonTapped?("delete")
+    }
+    
+    override func creatUI() {
+        
+        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
+        longPressRecognizer.minimumPressDuration = 0.5 // 设置最小长按时间(秒)
+        contentView.addGestureRecognizer(longPressRecognizer)
+        contentView.cornerRadius = 12.0
+
+        contentView.addSubview(hiddenImageView)
+        hiddenImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(0)
+            make.trailing.bottom.equalTo(0)
+        }
+        
+        contentView.addSubview(showImageView)
+        showImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(0)
+            make.trailing.bottom.equalTo(0)
+        }
+        
+        contentView.addSubview(exampleView)
+        exampleView.snp.makeConstraints { make in
+            make.top.equalTo(8)
+            make.leading.equalTo(8)
+            make.height.equalTo(20)
+        }
+        
+        contentView.addSubview(videoIconImageView)
+        videoIconImageView.snp.makeConstraints { make in
+            make.top.equalTo(8)
+            make.leading.equalTo(8)
+            make.width.height.equalTo(20)
+        }
+        
+        contentView.addSubview(generateView)
+        generateView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+}
+
+extension TSGenerateHistoryCell {
+    func updataActionInfoModelView(model:TSActionInfoModel){
+        
+        if model.modelType == .example {
+            model.actionStatus = .success
+        }
+        showImageView.image = nil
+        //dePrint("updataActionInfoModelView model.actionStatus 收到 = \(model.actionStatus)")
+        switch model.actionStatus {
+        case .pending,.running:
+            generateView.isHidden = false
+            generateView.setProgress(progress: model.percent)
+        case .success:
+            generateView.isHidden = true
+            videoIconImageView.isHidden = true
+            if model.modelType == .example {
+                textLabel.text = "Example".localized
+                exampleView.isHidden = false
+                showImageView.image = UIImage(named: model.response.resultUrl)
+            }else{
+                exampleView.isHidden = true
+                
+                videoIconImageView.isHidden = !model.isVideo
+                if dataModel.isVideo {
+                    videoIconImageView.isHidden = false
+                    showImageView.setAsyncImage(urlString: model.videoPreviewUrlString,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                }else {
+                    showImageView.setAsyncImage(urlString: model.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                    hiddenImageView.setAsyncImage(urlString: model.request.imageUrl,contentMode: .scaleAspectFill)
+                }
+            }
+
+        case .failed:
+            generateView.isHidden = false
+            if model.upImageURLExpired { //任务已经过期了
+                generateView.setTaskExpired()
+            }else{
+                generateView.setFailText(text: model.response.codeErrorMsg, refresh: !model.response.sensitiveError)
+            }
+            
+        }
+    }
+}

+ 124 - 0
AIEmoji/Business2/TSGenerateHistoryVC/View/TSGennerateCellView.swift

@@ -0,0 +1,124 @@
+//
+//  TSGennerateCellView.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/16.
+//
+
+class TSGennerateCellView: TSBaseView {
+    
+    var refreshHandel:(()->Void)?
+    var longPressHandel:(()->Void)?
+    lazy var infoLabel: UILabel = {
+        let infoLabel = UILabel.createLabel(font: .font(size: 12),textColor: .themeColor,textAlignment: .center,numberOfLines: 0)
+        return infoLabel
+    }()
+    
+    lazy var refreshBtn: TSUIExpandedTouchButton = {
+        let refreshBtn = TSUIExpandedTouchButton()
+        refreshBtn.setUpButton(image: UIImage(named: "refresh_white"))
+        {[weak self]  in
+            guard let self = self else { return }
+            refreshHandel?()
+        }
+        refreshBtn.isHidden = true
+        return refreshBtn
+    }()
+    
+    
+
+    var titleTop:CGFloat = 86.0 {
+        didSet{
+            infoLabel.snp.updateConstraints { make in
+                make.top.equalTo(titleTop)
+            }
+        }
+    }
+    
+    override func creatUI() {
+        backgroundColor = "#1D1812".uiColor
+
+        contentView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickContentView)))
+        
+
+//        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
+//        longPressRecognizer.minimumPressDuration = 0.5 // 设置最小长按时间(秒)
+//        contentView.addGestureRecognizer(longPressRecognizer)
+        
+        
+        contentView.addSubview(infoLabel)
+        infoLabel.snp.makeConstraints { make in
+//            make.top.equalTo(titleTop)
+            make.leading.equalTo(8)
+            make.trailing.equalTo(-8)
+            make.centerY.equalToSuperview().offset(0)
+        }
+        
+        contentView.addSubview(refreshBtn)
+        refreshBtn.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.top.equalTo(infoLabel.snp.bottom).offset(8)
+            make.width.height.equalTo(24)
+        }
+        
+    }
+    
+    func updateInfoLabelCenterY() {
+        infoLabel.snp.updateConstraints { make in
+            make.centerY.equalToSuperview().offset(refreshBtn.isHidden ? 0 : -14.0)
+        }
+    }
+    
+    private var isCanClick:Bool = false
+    
+    @objc func clickContentView() {
+        if isCanClick{
+            refreshHandel?()
+        }
+    }
+    
+//    @objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
+//        // 确保只在手势开始时触发一次
+//        guard gestureRecognizer.state == .began else { return }
+//        longPressHandel?()
+//    }
+    
+    func setProgress(progress:Float) {
+        refreshBtn.isHidden = true
+        isCanClick = false
+        let progressInt = Int(progress*100)
+
+        infoLabel.text = "Processing you photo".localized + "..." + "\n\n" + kPercentlocalized(progressInt)
+        infoLabel.textColor = .themeColor
+
+        updateInfoLabelCenterY()
+    }
+    
+    
+    func setTaskExpired(){
+        isCanClick = true
+        setProgress(progress: 0.0)
+        infoLabel.text = "This task has expired".localized
+        infoLabel.textColor = .white
+        refreshBtn.isHidden = false
+        isCanClick = true
+        refreshBtn.setImage(UIImage(named: "ai_delete"), for: .normal)
+        
+        updateInfoLabelCenterY()
+    }
+
+    func setFailText(text:String,refresh:Bool = true){
+        setProgress(progress: 0.0)
+        infoLabel.text = text
+        infoLabel.textColor = .white
+        
+        if refresh {
+            refreshBtn.isHidden = false
+            refreshBtn.setImage(UIImage(named: "refresh_white"), for: .normal)
+        }else{
+            refreshBtn.isHidden = true
+        }
+        isCanClick = true
+        updateInfoLabelCenterY()
+    }
+}

+ 6 - 6
AIEmoji/Common/Purchase/TSPurchaseManager.swift

@@ -203,9 +203,9 @@ public class PurchaseManager: NSObject {
     }
     }
 
 
     @objc public var isVip: Bool {
     @objc public var isVip: Bool {
-//#if DEBUG
-//        return vipType != .none
-//#endif
+#if DEBUG
+        return vipType != .none
+#endif
         guard let expiresDate = expiredDate else {
         guard let expiresDate = expiredDate else {
             return false
             return false
         }
         }
@@ -217,9 +217,9 @@ public class PurchaseManager: NSObject {
     }
     }
 
 
     public var vipType: PremiumPeriod {
     public var vipType: PremiumPeriod {
-//#if DEBUG
-//        return PremiumPeriod.none
-//#endif
+#if DEBUG
+        return PremiumPeriod.week
+#endif
         guard isVip, let type = vipInformation["type"] as? String else {
         guard isVip, let type = vipInformation["type"] as? String else {
             return .none
             return .none
         }
         }

+ 7 - 4
AIEmoji/Common/TSRealmManager/TSRealmManager.swift

@@ -9,9 +9,6 @@ import RealmSwift
 
 
 let TSRMShared = TSRealmManager.shared
 let TSRMShared = TSRealmManager.shared
 
 
-
-
-
 class TSRealmManager {
 class TSRealmManager {
     static let shared = TSRealmManager()
     static let shared = TSRealmManager()
     private init() {
     private init() {
@@ -20,9 +17,10 @@ class TSRealmManager {
          1.9 ->2    //新增
          1.9 ->2    //新增
          2.1 ->3    //新增ai思考
          2.1 ->3    //新增ai思考
          3.6.1  ->4   //将UserDefaults 的历史记录迁移到数据库中
          3.6.1  ->4   //将UserDefaults 的历史记录迁移到数据库中
+         ui大改版 - >5
          **/
          **/
    
    
-        let newSchemaVersion: UInt64 = 4
+        let newSchemaVersion: UInt64 = 5
         // 获取默认配置
         // 获取默认配置
         var config = Realm.Configuration.defaultConfiguration
         var config = Realm.Configuration.defaultConfiguration
         // 设置新版本号
         // 设置新版本号
@@ -95,6 +93,11 @@ class TSRealmManager {
     }
     }
 }
 }
 
 
+extension List {
+    subscript(safe index: Int) -> Element? {
+        return indices.contains(index) ? self[index] : nil
+    }
+}
 
 
 /*
 /*
 // 创建数据
 // 创建数据

+ 0 - 208
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift

@@ -1,208 +0,0 @@
-//
-//  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 [:]
-    }
-    
-    @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 {
-                DispatchQueue.main.asyncAfter(deadline: .now()+0.3){//稍微延迟,让通知报成功状态发送出去
-                    self.finished()
-                }
-            }
-        }
-    }
-    
-    var queryRequest:Request?
-    var stopNetwork = false
-    var generatingProgress = 0
-    var action_id:Int = 0
-    var isSaveDB:Bool = false //是否保存到数据库
-    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
-    @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
-    
-    func initializeActionInfoModel(oldModel:TSActionInfoModel) {
-        currentActionInfoModel = oldModel
-        replaceSaveInfoModel(model: currentActionInfoModel)
-        stateDatauPblished = (.start,currentActionInfoModel)
-    }
-    
-    func replaceSaveInfoModel(model:TSActionInfoModel){ }
-    
-    func handleGenerateSuccess(){
-        
-    }
-
-    func handleFailInfoModel(errorString:String?,code:Int = 0){
-        self.currentActionInfoModel.actionStatus = .failed
-        self.currentActionInfoModel.status = "failed"
-        generatingProgress = 0
-        self.replaceSaveInfoModel(model: self.currentActionInfoModel)
-        self.stateDatauPblished = (TSProgressState.getFailed(errorString ?? "",code),self.currentActionInfoModel)
-    }
-    
-    func getActionInfo(oldModel:TSActionInfoModel) {
-        currentActionInfoModel = oldModel
-        self.getActionInfo(action_id:oldModel.id)
-    }
-
-    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 stopNetwork == true {
-                return
-            }
-            
-            if let error = error {
-                debugPrint("getActionInfo error error = \(error)")
-                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
-                return
-            }
-            
-            if let result = kNetWorkResultSuccess(data: data) {
-                if let genmojiModel = TSActionInfoModel(JSON: result) {
-                    
-                    if genmojiModel.actionStatus != .success {
-                        self.replaceSaveInfoModel(model: genmojiModel)
-                    }
-                    
-                    switch genmojiModel.actionStatus {
-                    case .success:
-                        
-                        let successBlock = { [weak self]  in
-                            guard let self = self else { return }
-                            self.replaceSaveInfoModel(model: genmojiModel)
-                            self.stateDatauPblished = (.success(nil),genmojiModel)
-                            generatingProgress = 0
-                            self.handleGenerateSuccess()
-                        }
-                        
-                        if URL(string:genmojiModel.response.resultUrl) != nil {
-                            TSImageStoreTool.downloadImageWithProgress(urlString: genmojiModel.response.resultUrl) { [weak self]  progress in
-                                guard let self = self else { return }
-                                let progressInt = Int(progress*10.0)
-                                let progressString = "Generating".localized + " \(90 + progressInt)%"
-                                stateDatauPblished = (.progressString(progressString),currentActionInfoModel)
-                                dePrint("生成后图片下载进度 \(progress)")
-                            } completion: { image in
-                                successBlock()
-                            }
-
-                        }else{
-                            successBlock()
-                        }
-                    case .failed:
-                        debugPrint("getActionInfo error failed")
-                        handleFailInfoModel(errorString:genmojiModel.response.codeErrorMsg,code: genmojiModel.response.code)
-                    default:
-                        stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),currentActionInfoModel)
-                        if stopNetwork == false {
-                            kDelayOnMainThread(2.0) {
-                                self.getActionInfo(action_id: action_id)
-                            }
-                        }
-                    }
-                    
-                    return
-                }
-            }
-            debugPrint("getActionInfo error nil")
-            handleFailInfoModel(errorString: 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 "Working on your ringtone \(generatingProgress)%..."
-    }
-     
-
-    override func cancelCleanContent() {
-        debugPrint("cancelCleanContent")
-        stopNetwork = true
-        queryRequest?.cancel()
-    }
-}
- var kRandomBoolLastResult:Bool = true
-func kRandomBool() -> Bool {
-    if !kRandomBoolLastResult {
-        // 如果上一次是 false,这次必须返回 true
-        kRandomBoolLastResult = true
-        return true
-    } else {
-        // 如果上一次是 true,随机返回 true 或 false
-        let randomResult = Bool.random()
-        kRandomBoolLastResult = randomResult
-        return randomResult
-    }
-}

+ 9 - 12
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift

@@ -29,10 +29,7 @@ class TSGeneratePTPOperationQueue: TSGenerateBaseOperationQueue {
 }
 }
 
 
 class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
 class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
-    
-    //是否展示成功后的 View 提醒
-    public var isShowSuccessView:Bool = false
-    
+
     override var actionInfoDict:[String:Any]{
     override var actionInfoDict:[String:Any]{
         return [
         return [
             "actionType":"image_create",
             "actionType":"image_create",
@@ -50,8 +47,8 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
     override func replaceSaveInfoModel(model:TSActionInfoModel){
     override func replaceSaveInfoModel(model:TSActionInfoModel){
         model.uuid = uuid
         model.uuid = uuid
         model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
         model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
-        if isSaveDB {
-            TSRMShared.ptpDBHistory.updateData(model,id: currentActionInfoModel.id)
+        if isSaveProcessToDB {
+            TSRMShared.ptpDBHistory.updateData(model,uuid: uuid)
         }
         }
         currentActionInfoModel = model
         currentActionInfoModel = model
         dePrint("model actionStatus 发出=\(model.actionStatus)")
         dePrint("model actionStatus 发出=\(model.actionStatus)")
@@ -60,7 +57,7 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
 
 
     override func handleGenerateSuccess() {
     override func handleGenerateSuccess() {
         kPurchaseDefault.useOnceForFree(type: .picToPic)
         kPurchaseDefault.useOnceForFree(type: .picToPic)
-        TSRMShared.ptpDBHistory.updateData(currentActionInfoModel,id: currentActionInfoModel.id)
+        TSRMShared.ptpDBHistory.updateData(currentActionInfoModel,uuid: currentActionInfoModel.uuid)
         if isShowSuccessView == false {
         if isShowSuccessView == false {
             return
             return
         }
         }
@@ -115,7 +112,7 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         infoModel.request.imageUrlTimestamp = Date.timestampInt
         infoModel.request.imageUrlTimestamp = Date.timestampInt
         
         
         infoModel.request.prompt = generateStyleModel.prompt
         infoModel.request.prompt = generateStyleModel.prompt
-        infoModel.request.promptSort = generateStyleModel.inputText
+        infoModel.request.inputText = generateStyleModel.inputText
         infoModel.request.style = generateStyleModel.style
         infoModel.request.style = generateStyleModel.style
         infoModel.request.advance = generateStyleModel.advance
         infoModel.request.advance = generateStyleModel.advance
         infoModel.request.model = generateStyleModel.model
         infoModel.request.model = generateStyleModel.model
@@ -182,13 +179,13 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         
         
         let request = currentActionInfoModel.request
         let request = currentActionInfoModel.request
         var prompt = request.prompt
         var prompt = request.prompt
-        let promptSort = request.promptSort
+        let inputText = request.inputText
         
         
-        if promptSort.count>0{
+        if inputText.count>0{
             if prompt.count > 0 {
             if prompt.count > 0 {
-                prompt = prompt + ", " + promptSort
+                prompt = prompt + ", " + inputText
             }else {
             }else {
-                prompt = promptSort
+                prompt = inputText
             }
             }
         }
         }
         
         

+ 283 - 0
AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBaseOperation.swift

@@ -0,0 +1,283 @@
+//
+//  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 clearOperationsData(uuid: String) {
+        super.clearOperationsData(uuid: uuid)
+        stateables.removeValue(forKey: uuid)
+    }
+    
+//    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 [:]
+    }
+    
+    @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 {
+                DispatchQueue.main.asyncAfter(deadline: .now()+0.3){//稍微延迟,让通知报成功状态发送出去
+                    self.finished()
+                }
+            }
+        }
+    }
+    
+    var queryRequest:Request?
+    var stopNetwork = false
+    var generatingProgress = 0
+    var action_id:Int = 0
+    var retryDownloadCount = 0
+    public var isShowSuccessView:Bool = false //是否展示成功后的 View 提醒
+    var isSaveProcessToDB:Bool = false //是否保存过程到数据库
+    {
+        didSet{
+            if isSaveProcessToDB == true {
+                saveDataDB()
+            }
+        }
+    }
+    
+    var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
+    @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
+    
+    func initializeActionInfoModel(oldModel:TSActionInfoModel) {
+        currentActionInfoModel = oldModel
+        replaceSaveInfoModel(model: currentActionInfoModel)
+        stateDatauPblished = (.start,currentActionInfoModel)
+    }
+    
+    func replaceSaveInfoModel(model:TSActionInfoModel){ }
+    
+    func handleGenerateSuccess(){}
+    func saveDataDB(){}
+    
+    func backstageGeneration(){
+        isSaveProcessToDB = true
+        isShowSuccessView = true
+    }
+    
+    func handleFailInfoModel(errorString:String?,code:Int = 0){
+        self.currentActionInfoModel.actionStatus = .failed
+        self.currentActionInfoModel.status = "failed"
+        generatingProgress = 0
+        self.replaceSaveInfoModel(model: self.currentActionInfoModel)
+        self.stateDatauPblished = (TSProgressState.getFailed(errorString ?? "",code),self.currentActionInfoModel)
+    }
+    
+    func getActionInfo(oldModel:TSActionInfoModel) {
+        currentActionInfoModel = oldModel
+        self.getActionInfo(action_id:oldModel.id)
+    }
+    
+    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 stopNetwork == true {
+                return
+            }
+            
+            if let error = error {
+                debugPrint("getActionInfo error error = \(error)")
+                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                return
+            }
+            
+            if let result = kNetWorkResultSuccess(data: data) {
+                if let infoModel = TSActionInfoModel(JSON: result) {
+                    
+                    if infoModel.actionStatus != .success {
+                        self.replaceSaveInfoModel(model: infoModel)
+                    }
+                    
+                    switch infoModel.actionStatus {
+                    case .success:
+                        if URL(string:infoModel.response.resultUrl) != nil {
+                            downResultUrl(infoModel: infoModel)
+                        }else{
+                            handleSuccess(infoModel: infoModel)
+                        }
+                    case .failed:
+                        debugPrint("getActionInfo error failed")
+                        handleFailInfoModel(errorString:infoModel.response.codeErrorMsg,code: infoModel.response.code)
+                    default:
+                        stateDatauPblished = (.progressString(generating(progress: infoModel.percent)),currentActionInfoModel)
+                        if stopNetwork == false {
+                            kDelayOnMainThread(2.0) {
+                                self.getActionInfo(action_id: action_id)
+                            }
+                        }
+                    }
+                    
+                    return
+                }
+            }
+            debugPrint("getActionInfo error nil")
+            handleFailInfoModel(errorString: nil)
+            
+        }
+    }
+    
+    
+    func handleSuccess(infoModel:TSActionInfoModel){
+        self.replaceSaveInfoModel(model: infoModel)
+        self.stateDatauPblished = (.success(nil),infoModel)
+        generatingProgress = 0
+        self.handleGenerateSuccess()
+    }
+    
+    func downResultUrl(infoModel:TSActionInfoModel){
+        
+        if retryDownloadCount > 3 {
+            debugPrint("生成后下载视频失败,重新尝试超过 3 次,直接失败")
+            handleFailInfoModel(errorString: nil)
+            return
+        }
+        
+        if currentActionInfoModel.request.generatorStyle.isVideo{
+            let group = DispatchGroup()
+            //下载视频源
+            group.enter()
+            downloadVideo(urlString: infoModel.response.resultUrl) { url in
+                if let url = url {
+                    infoModel.response.videoDocument = url.path.documentLastURLString
+                }
+                group.leave()
+            }
+            //下载封面图
+            group.enter()
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.response.previewUrl) { _ in
+                group.leave()
+            }
+            
+            group.notify(queue: .main){[weak self]  in
+                guard let self = self else { return }
+                if infoModel.response.videoDocument.isEmpty {
+                    debugPrint("生成后下载视频失败,重新尝试retryDownloadCount=\(retryDownloadCount)")
+                    downResultUrl(infoModel: infoModel)
+                }else{
+                    handleSuccess(infoModel: infoModel)
+                }
+            }
+            
+        }else{
+            downloadImage(urlString: infoModel.response.resultUrl) { [weak self] image in
+                guard let self = self else { return }
+                if image == nil {
+                    debugPrint("生成后下载视频失败,重新尝试retryDownloadCount=\(retryDownloadCount)")
+                    downResultUrl(infoModel: infoModel)
+                }else{
+                    handleSuccess(infoModel: infoModel)
+                }
+                
+            }
+        }
+        
+        retryDownloadCount += 1
+    }
+    
+    let generatingText:String = "Processing".localized
+    func downloadVideo(urlString:String,completion:@escaping (URL?)->Void){
+        TSDownloadManager.getDownLoadVideo(urlString: urlString) { progress in
+            let progressInt = Int(progress*10.0)
+            let progressString = "Processing".localized + " " + kPercentlocalized(90 + progressInt)
+            self.stateDatauPblished = (.progressString(progressString),nil)
+            dePrint("生成后视频下载进度: \(progress)")
+        } complete: { url, _ in
+            completion(url)
+        }
+    }
+    
+    func downloadImage(urlString:String,completion:@escaping (UIImage?)->Void){
+        TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { [weak self]  progress in
+            guard let self = self else { return }
+            
+            let progressInt = Int(progress*10.0)
+            let progressString = "Processing".localized + " " + kPercentlocalized(90 + progressInt)
+            stateDatauPblished = (.progressString(progressString),currentActionInfoModel)
+            dePrint("生成后图片下载进度: \(progress)")
+        } completion: { image in
+            completion(image)
+        }
+    }
+    
+    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 "Processing \(generatingProgress)%..."
+    }
+    
+    
+    override func cancelCleanContent() {
+        debugPrint("cancelCleanContent")
+        stopNetwork = true
+        queryRequest?.cancel()
+    }
+}
+
+
+func kPercentlocalized(_ num:Int)-> String{
+    return String(format: "%d%".localized, num)
+}

+ 273 - 0
AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBasePhotoOperation.swift

@@ -0,0 +1,273 @@
+//
+//  TSGenerateBasePhotoOperation.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/24.
+//
+
+import Combine
+import Alamofire
+import ObjectMapper
+import Kingfisher
+class TSGenerateBasePhotoOperationQueue: TSGenerateBaseOperationQueue {
+    static let shared:TSGenerateBasePhotoOperationQueue = TSGenerateBasePhotoOperationQueue()
+
+    func creatOperation(uuid: String) -> TSGenerateBasePhotoOperation {
+        let operation = super.creatOperation(uuid: uuid, type: TSGenerateBasePhotoOperation.self)
+        handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGenerateBasePhotoOperation)
+        return operation as! TSGenerateBasePhotoOperation
+    }
+    
+    override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+        if let PosterOperation = TSGenerateBasePhotoOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateBasePhotoOperation {
+            dePrint("TSBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
+            return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
+        }
+        return (.none,TSActionInfoModel())
+    }
+    
+}
+
+class TSGenerateBasePhotoOperation: 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"
+        ]
+    }
+
+    override func replaceSaveInfoModel(model:TSActionInfoModel){
+        model.uuid = uuid
+        model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
+        model.request.generatorStyle = currentActionInfoModel.request.generatorStyle
+        if isSaveProcessToDB {
+            saveDataDB()
+        }
+        currentActionInfoModel = model
+        dePrint("model actionStatus 发出=\(model.actionStatus)")
+        currentActionInfoModelChanged?(currentActionInfoModel)
+    }
+
+    override func saveDataDB() {
+        if currentActionInfoModel.id == 0 {
+            return
+        }
+        TSRMShared.aiGenerateDB.updateData(currentActionInfoModel,uuid: uuid)
+    }
+    override func handleGenerateSuccess() {
+//        kPurchaseBusiness.useOnceForFree(type: .general)
+        saveDataDB()
+
+        //生成成功后,不再提示用户上传规则弹窗
+        UserDefaults.standard.set("1", forKey: currentActionInfoModel.request.generatorStyle.userDefaultsKey)
+        UserDefaults.standard.synchronize()
+        
+        if isShowSuccessView  {
+            guard let window = WindowHelper.getKeyWindow() else {
+                debugPrint("getKeyWindow nil")
+                return
+            }
+            
+            guard let rootVC = WindowHelper.topViewController() else {
+                debugPrint("handleGenerateSuccess topViewController nil")
+                return
+            }
+            
+            let copyModel = self.currentActionInfoModel.copy()
+            if let cyModel = copyModel as? TSActionInfoModel {
+                let topY = k_Nav_Height+10
+                debugPrint("topY=\(topY)")
+                kSaveSuccesswShared.show(atView: window,text: "Process successfully".localized,deadline: 5.0) {
+//                    let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel: TSAIGeneratorModel(upLoadImage: UIImage(), generatorStyle: cyModel.request.generatorStyle),infoModel: cyModel) { model in }
+//                    gennerateVC.modalPresentationStyle = .overFullScreen
+//                    gennerateVC.modalTransitionStyle = .crossDissolve
+//                    rootVC.present(gennerateVC, animated: true)
+                }
+            }else{
+                debugPrint("copyModel as? TSActionInfoModel error")
+            }
+        }
+
+    }
+    
+
+    /**
+        1.用户上传图片
+        2.调用生成接口
+        3.后台返回查询 id,根据 id 不断查询进度和结果.(此时才允许进度后台)
+     
+        利用3后台返回的TSActionRequestModel中存着关键的请求接口数据,请求数据
+     
+     */
+    
+    private var uploadRequest:Request?
+    private var creatRequest:Request?
+    
+    func createActionInfoModel(generateStyleModel:TSAIGeneratorModel) -> TSActionInfoModel? {
+        guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
+
+        let infoModel = TSActionInfoModel()
+        infoModel.id = Date.timestampInt
+        infoModel.request = TSActionRequestModel()
+        infoModel.request.imageUrl = upLoadImageUrl
+        infoModel.request.imageUrlTimestamp = Date.timestampInt
+        
+        infoModel.request.prompt = generateStyleModel.prompt
+        infoModel.request.inputText = generateStyleModel.inputText
+        infoModel.request.generatorStyle = generateStyleModel.generatorStyle
+        
+        return infoModel
+    }
+    
+    func uploadImage(generateStyleModel:TSAIGeneratorModel,complete:@escaping (TSActionInfoModel?)->Void) {
+        let upLoadImage = generateStyleModel.upLoadImage
+        if let imageUrl = generateStyleModel.upLoadImageUrl,imageUrl.contains("http") {
+            complete(createActionInfoModel(generateStyleModel: generateStyleModel))
+            return
+        }
+        
+        stopNetwork = false
+        stateDatauPblished = (.start,nil)
+        
+        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),currentActionInfoModel)
+        uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb) { [weak self]  progress in
+            guard let self = self else { return }
+            if generatingProgress == 0 {
+                stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),currentActionInfoModel)
+            }
+        } completion: { [weak self]  data, error in
+            guard let self = self else { return }
+            if stopNetwork == true { return }
+            if let error = error {
+                generateStyleModel.upLoadImageUrl = nil
+                self.stateDatauPblished = (TSProgressState.getFailed(error.tsDesc,error.tsCode),nil)
+                complete(nil)
+            }else{
+                if let string = data as? String {
+                    generateStyleModel.upLoadImageUrl = string
+                    TSImageStoreTool.storeImage(image: upLoadImage, urlString: string)
+
+                    complete(createActionInfoModel(generateStyleModel: generateStyleModel))
+                }else{
+                    complete(nil)
+                }
+            }
+        }
+    }
+    
+    func creatImage(oldModel:TSActionInfoModel,complete:@escaping (Bool)->Void) {
+        
+        initializeActionInfoModel(oldModel: oldModel)
+        if oldModel.upImageURLExpired { return  }
+
+        generatingProgress = 0
+        stopNetwork = false
+        stateDatauPblished = (.start,nil)
+
+        currentActionInfoModel.status = "running"
+        currentActionInfoModel.actionStatus = .running
+        currentActionInfoModel.percent = 0
+        replaceSaveInfoModel(model: currentActionInfoModel)
+        
+        stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
+ 
+        
+        let request = currentActionInfoModel.request
+        
+        
+        var urlType:TSNeURLType = .imageRewrite
+        var postDict:[String:Any] = [
+            "device":getUserInfoJsonString(),
+            "imageUrl":request.imageUrl,
+            "model":request.model
+        ]
+//        switch request.generatorStyle {
+//        case .enhance:
+//            urlType = .imageRewrite
+//            postDict["prompt"] = "把图片变清晰"
+//        case .colorize:
+//            urlType = .imageRewrite
+//            postDict["prompt"] = "Add suitable colors to photos"
+//        case .descratch:
+//            urlType = .imageRewrite
+//            postDict["prompt"] = "Remove the photo's scratches and dirt"
+//        case .enlighten:
+//            urlType = .imageRewrite
+//            postDict["prompt"] = "Adjust the light and darkness of the photo to make the overall look coordinated"
+//            
+//        case .recreate:
+//            urlType = .imageRewrite
+//            postDict["prompt"] = "Recreate damaged portraits and added suitable color for photo"
+//            
+//        case .creatVideo:
+//            urlType = .createVideo
+//            postDict["prompt"] = request.prompt
+////            postDict["aspectRatio"] = "9:16"
+//            postDict["duration"] = 5
+//            postDict["quality"] = "720p"
+//        }
+
+        creatRequest = TSNetworkShared.post(urlType: urlType,parameters: postDict) { [weak self] data,error in
+            guard let self = self else { return }
+            if stopNetwork == true { return }
+            
+            if let error = error {
+                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                complete(false)
+            }else{
+                if let dataDict = kNetWorkCodeSuccess(data: data),
+                   let actionId = dataDict["actionId"] as? Int{
+                    if stopNetwork == false {
+                        complete(true)
+                        self.stateDatauPblished = (.pending,nil) //通知首页进行更新
+                        self.getActionInfo(action_id:actionId)
+                    }
+                }else{
+                    handleFailInfoModel(errorString: "",code: 0)
+                    complete(false)
+                }
+            }
+        }
+    }
+    override func generating(progress: Float) -> String {
+        let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
+        //Generating 0%-100%
+        var progressInt = Int(progress*100)
+
+        if progressInt > 99 {
+            progressInt = 99
+        }
+        
+        generatingProgress = progressInt
+        return "Processing".localized + " " + kPercentlocalized(progressInt)
+    }
+
+    var imageMaxKb:Int{
+        return 10*1024
+    }
+    
+    func uploadingPhoto(progress:Float) -> String {
+        //Uploading Photo 0%-100%
+        var progressInt = Int(progress*100)
+        if progressInt > 99 {
+            progressInt = 99
+        }
+        return "Uploading Photo".localized + " " + kPercentlocalized(progressInt)
+    }
+    
+    
+    override func cancelCleanContent() {
+        super.cancelCleanContent()
+        debugPrint("cancelCleanContent")
+        uploadRequest?.cancel()
+        creatRequest?.cancel()
+    }
+}

+ 0 - 28
AIEmoji/Common/Tool/TSCommonTool/TSCommonTool.swift

@@ -193,34 +193,6 @@ class TSCommonTool {
 }
 }
 
 
 let kMainQueue = DispatchQueue.main
 let kMainQueue = DispatchQueue.main
-/// 主线程延迟执行回调
-/// - Parameters:
-///   - delay: 延迟时间(秒)
-///   - completion: 延迟后的回调
-func kDelayOnMainThread(_ delay: TimeInterval, completion: @escaping () -> Void) {
-    DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
-        completion()
-    }
-}
-
-func kDelayMainShort(completion: @escaping () -> Void) {
-    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
-        completion()
-    }
-}
-
-/// 在主线程上执行代码
-/// - Parameter block: 要执行的代码块
-func kExecuteOnMainThread(_ block: @escaping () -> Void) {
-    if Thread.isMainThread {
-        block()
-    } else {
-        DispatchQueue.main.async {
-            block()
-        }
-    }
-}
-
 let appid = "6740220736"
 let appid = "6740220736"
 let kAppName:String = "Picguru" //Picguru Chibii Chibi Ghiblii AI Image Picguru
 let kAppName:String = "Picguru" //Picguru Chibii Chibi Ghiblii AI Image Picguru
 let kUploadImageMaxBit10Size:Int = 10 * 1024 * 1024 //10M
 let kUploadImageMaxBit10Size:Int = 10 * 1024 * 1024 //10M