Browse Source

Merge branch 'feature/接口' into 合并代码

# Conflicts:
#	AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyleVC.swift
#	AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift
#	AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/View/TSPTPSelectStyleView.swift
#	AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift
100Years 1 month ago
parent
commit
f096e0ce95
29 changed files with 957 additions and 356 deletions
  1. BIN
      .DS_Store
  2. 45 5
      AIEmoji.xcodeproj/project.pbxproj
  3. 23 0
      AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/Contents.json
  4. BIN
      AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@1x.png
  5. BIN
      AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@2x.png
  6. BIN
      AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@3x.png
  7. BIN
      AIEmoji/Assets.xcassets/PTP/style/.DS_Store
  8. 23 0
      AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/Contents.json
  9. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@1x.png
  10. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@2x.png
  11. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@3x.png
  12. 23 0
      AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/Contents.json
  13. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@1x.png
  14. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@2x.png
  15. BIN
      AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@3x.png
  16. 1 48
      AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/TSAIExpandImageVM.swift
  17. 95 0
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleCell.swift
  18. 132 0
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleListVc.swift
  19. 58 0
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleListViewModel.swift
  20. 98 0
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyle/TSGennertatorSelectStyleVC.swift
  21. 29 0
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyle/TSGennertatorSelectStyleViewModel.swift
  22. 4 9
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift
  23. 7 16
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/VM/TSPTPGeneratorVM.swift
  24. 185 181
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift
  25. 31 57
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/VM/TSPTPInputVM.swift
  26. 126 26
      AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/TSPTPStyleModel.swift
  27. 3 1
      AIEmoji/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift
  28. 10 13
      AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift
  29. 64 0
      AIEmoji/Enums/TSLoadState.swift

BIN
.DS_Store


+ 45 - 5
AIEmoji.xcodeproj/project.pbxproj

@@ -7,6 +7,11 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		60B2F0212DC0A18800F1121F /* TSGennertatorSelectStyleListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B2F0202DC0A18800F1121F /* TSGennertatorSelectStyleListViewModel.swift */; };
+		60B2F0242DC0A34900F1121F /* TSLoadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B2F0232DC0A34900F1121F /* TSLoadState.swift */; };
+		60B2F0262DC0A5F600F1121F /* TSGennertatorSelectStyleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B2F0252DC0A5F600F1121F /* TSGennertatorSelectStyleCell.swift */; };
+		60B2F0282DC0AC9100F1121F /* TSGennertatorSelectStyleListVc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B2F0272DC0AC9100F1121F /* TSGennertatorSelectStyleListVc.swift */; };
+		60B2F02A2DC0B17100F1121F /* TSGennertatorSelectStyleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B2F0292DC0B17100F1121F /* TSGennertatorSelectStyleViewModel.swift */; };
 		A80327B02D813A0200AF7878 /* TSTTPSelectStyleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */; };
 		A80327B32D813D4900AF7878 /* TSTTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B22D813D4800AF7878 /* TSTTPInputVC.swift */; };
 		A80327B62D813D8700AF7878 /* TSTTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B52D813D8100AF7878 /* TSTTPInputVM.swift */; };
@@ -171,7 +176,6 @@
 		A8BA763F2DA4C908000B6707 /* TSPTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA763E2DA4C906000B6707 /* TSPTPInputVC.swift */; };
 		A8BA76422DA4C924000B6707 /* TSPTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76412DA4C920000B6707 /* TSPTPInputVM.swift */; };
 		A8BA76452DA4CB9A000B6707 /* TSPTPUploadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76442DA4CB99000B6707 /* TSPTPUploadView.swift */; };
-		A8BA76472DA4CC70000B6707 /* TSPTPSelectStyleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76462DA4CC6C000B6707 /* TSPTPSelectStyleView.swift */; };
 		A8BA764F2DA50B52000B6707 /* CpuMapManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA764E2DA50B52000B6707 /* CpuMapManager.swift */; };
 		A8BA76522DA51600000B6707 /* TSPTPImageHintVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76512DA515FF000B6707 /* TSPTPImageHintVC.swift */; };
 		A8BA76542DA54571000B6707 /* CollectionViewObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76532DA5456E000B6707 /* CollectionViewObserver.swift */; };
@@ -252,6 +256,11 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		60B2F0202DC0A18800F1121F /* TSGennertatorSelectStyleListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennertatorSelectStyleListViewModel.swift; sourceTree = "<group>"; };
+		60B2F0232DC0A34900F1121F /* TSLoadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLoadState.swift; sourceTree = "<group>"; };
+		60B2F0252DC0A5F600F1121F /* TSGennertatorSelectStyleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennertatorSelectStyleCell.swift; sourceTree = "<group>"; };
+		60B2F0272DC0AC9100F1121F /* TSGennertatorSelectStyleListVc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennertatorSelectStyleListVc.swift; sourceTree = "<group>"; };
+		60B2F0292DC0B17100F1121F /* TSGennertatorSelectStyleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennertatorSelectStyleViewModel.swift; sourceTree = "<group>"; };
 		6E77A292B548CD79E381757E /* Pods-AIEmoji.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIEmoji.release.xcconfig"; path = "Target Support Files/Pods-AIEmoji/Pods-AIEmoji.release.xcconfig"; sourceTree = "<group>"; };
 		86FB4D6AEFDDA7A2017F307C /* Pods_AIEmoji.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIEmoji.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPSelectStyleCell.swift; sourceTree = "<group>"; };
@@ -441,7 +450,6 @@
 		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>"; };
 		A8BA76442DA4CB99000B6707 /* TSPTPUploadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPUploadView.swift; sourceTree = "<group>"; };
-		A8BA76462DA4CC6C000B6707 /* TSPTPSelectStyleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPSelectStyleView.swift; sourceTree = "<group>"; };
 		A8BA764A2DA4F689000B6707 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
 		A8BA764B2DA4F689000B6707 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
 		A8BA764C2DA4F689000B6707 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
@@ -551,6 +559,33 @@
 			path = Pods;
 			sourceTree = "<group>";
 		};
+		60B2F0222DC0A32E00F1121F /* Enums */ = {
+			isa = PBXGroup;
+			children = (
+				60B2F0232DC0A34900F1121F /* TSLoadState.swift */,
+			);
+			path = Enums;
+			sourceTree = "<group>";
+		};
+		60B2F02B2DC0B1A900F1121F /* StyleList */ = {
+			isa = PBXGroup;
+			children = (
+				60B2F0202DC0A18800F1121F /* TSGennertatorSelectStyleListViewModel.swift */,
+				60B2F0252DC0A5F600F1121F /* TSGennertatorSelectStyleCell.swift */,
+				60B2F0272DC0AC9100F1121F /* TSGennertatorSelectStyleListVc.swift */,
+			);
+			path = StyleList;
+			sourceTree = "<group>";
+		};
+		60B2F02C2DC0B1B900F1121F /* TSGennertatorSelectStyle */ = {
+			isa = PBXGroup;
+			children = (
+				A88508B52DBF142A000FBCEC /* TSGennertatorSelectStyleVC.swift */,
+				60B2F0292DC0B17100F1121F /* TSGennertatorSelectStyleViewModel.swift */,
+			);
+			path = TSGennertatorSelectStyle;
+			sourceTree = "<group>";
+		};
 		97C7E956DF0731529C52523E /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
@@ -1278,7 +1313,8 @@
 		A88508B42DBF1408000FBCEC /* TSGennertatorSelectStyleVC */ = {
 			isa = PBXGroup;
 			children = (
-				A88508B52DBF142A000FBCEC /* TSGennertatorSelectStyleVC.swift */,
+				60B2F02C2DC0B1B900F1121F /* TSGennertatorSelectStyle */,
+				60B2F02B2DC0B1A900F1121F /* StyleList */,
 			);
 			path = TSGennertatorSelectStyleVC;
 			sourceTree = "<group>";
@@ -1436,7 +1472,6 @@
 			isa = PBXGroup;
 			children = (
 				A82D609F2DBA1B0400596190 /* TSImageGenerateView.swift */,
-				A8BA76462DA4CC6C000B6707 /* TSPTPSelectStyleView.swift */,
 				A8BA76442DA4CB99000B6707 /* TSPTPUploadView.swift */,
 			);
 			path = View;
@@ -1580,6 +1615,7 @@
 		A8F7748A2D38E8B700AA6E93 /* AIEmoji */ = {
 			isa = PBXGroup;
 			children = (
+				60B2F0222DC0A32E00F1121F /* Enums */,
 				A8FB02AE2D3E38FA0031A396 /* Res */,
 				A8F7751E2D38ED4500AA6E93 /* DataManger */,
 				A8F774922D38EA8C00AA6E93 /* Business */,
@@ -2223,7 +2259,9 @@
 				A80EDD6A2D6C518E003CD332 /* TSChatMsgToolView.swift in Sources */,
 				A8F4134C2DA75893001E715A /* TSClickableLinkLabel.swift in Sources */,
 				A80EDD602D6C3F82003CD332 /* MarkdownElement.swift in Sources */,
+				60B2F0212DC0A18800F1121F /* TSGennertatorSelectStyleListViewModel.swift in Sources */,
 				A80EDD612D6C3F82003CD332 /* MarkdownLink+AppKit.swift in Sources */,
+				60B2F0242DC0A34900F1121F /* TSLoadState.swift in Sources */,
 				A80EDD622D6C3F82003CD332 /* MarkdownLink.swift in Sources */,
 				A8BA76722DA65A95000B6707 /* TSAIUploadPhotoBaseVC.swift in Sources */,
 				A80EDD632D6C3F82003CD332 /* MarkdownAutomaticLink.swift in Sources */,
@@ -2259,6 +2297,7 @@
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
 				A8BA76772DA68619000B6707 /* TSAIListHistoryBaseVM.swift in Sources */,
 				A80EDDE42D6EB8FA003CD332 /* TSPTPSelectStyleCell.swift in Sources */,
+				60B2F0282DC0AC9100F1121F /* TSGennertatorSelectStyleListVc.swift in Sources */,
 				A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */,
 				A80E73E12D533E5800C64288 /* TSPurchaseVC.swift in Sources */,
 				A80EDDE02D6EB1B9003CD332 /* TSPTPGeneratorCell.swift in Sources */,
@@ -2292,10 +2331,12 @@
 				A82D60982DB9D45900596190 /* TSBaseOperation.swift in Sources */,
 				A8BA76452DA4CB9A000B6707 /* TSPTPUploadView.swift in Sources */,
 				A85E479F2D6859FA0018D62D /* TSRandomTextPicker.swift in Sources */,
+				60B2F02A2DC0B17100F1121F /* TSGennertatorSelectStyleViewModel.swift in Sources */,
 				A8BA76522DA51600000B6707 /* TSPTPImageHintVC.swift in Sources */,
 				A80E72262D3F3A9A00C64288 /* HYHAddImageView.m in Sources */,
 				A80E72272D3F3A9A00C64288 /* DiyTextElement.swift in Sources */,
 				A8FB02BA2D3E3BB20031A396 /* TSEmojisCoLItemCell.swift in Sources */,
+				60B2F0262DC0A5F600F1121F /* TSGennertatorSelectStyleCell.swift in Sources */,
 				A87587182D81814500286A66 /* TSAIThinkingView.swift in Sources */,
 				A85E47962D672ADA0018D62D /* TSTextPicGennerateVC.swift in Sources */,
 				A82D60A02DBA1B0500596190 /* TSImageGenerateView.swift in Sources */,
@@ -2319,7 +2360,6 @@
 				A8BE26E82DBC6A9F00A1DD18 /* TSDBHistoryManager.swift in Sources */,
 				A8D6383C2DB1FC8D00A96C0E /* TSAIListVideoPlayerVC.swift in Sources */,
 				A89EA66D2D59AA31000EB181 /* TableViewCells.swift in Sources */,
-				A8BA76472DA4CC70000B6707 /* TSPTPSelectStyleView.swift in Sources */,
 				A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */,
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
 				A89EA6BC2D5DFB12000EB181 /* TSViewController.swift in Sources */,

+ 23 - 0
AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "placeholderImageNoAlpha@1x.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "placeholderImageNoAlpha@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "placeholderImageNoAlpha@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@1x.png


BIN
AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@2x.png


BIN
AIEmoji/Assets.xcassets/Common/placeholderImageNoAlpha.imageset/placeholderImageNoAlpha@3x.png


BIN
AIEmoji/Assets.xcassets/PTP/style/.DS_Store


+ 23 - 0
AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "styleplaceholder@1x.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "styleplaceholder@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "styleplaceholder@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@1x.png


BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@2x.png


BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholder.imageset/styleplaceholder@3x.png


+ 23 - 0
AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "styleplaceholderbig@1x.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "styleplaceholderbig@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "styleplaceholderbig@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@1x.png


BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@2x.png


BIN
AIEmoji/Assets.xcassets/PTP/styleplaceholderbig.imageset/styleplaceholderbig@3x.png


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

@@ -10,54 +10,7 @@ import Alamofire
 
 class TSAIExpandImageVM {
     
-    // MARK: - 比例枚举
-    enum AspectRatio: Int {
-        case ratio1_1 = 0
-        case ratio16_9
-        case ratio9_16
-        case ratio4_3
-        case ratio3_4
-        case ratio2_3
-        case ratio3_2
-        
-        var value: CGFloat {
-            switch self {
-            case .ratio1_1: return 1.0
-            case .ratio16_9: return 16.0/9.0
-            case .ratio9_16: return 9.0/16.0
-            case .ratio4_3: return 4.0/3.0
-            case .ratio3_4: return 3.0/4.0
-            case .ratio2_3: return 2.0/3.0
-            case .ratio3_2: return 3.0/2.0
-            }
-        }
-        
-        var displayName: String {
-            switch self {
-            case .ratio1_1: return "1:1"
-            case .ratio16_9: return "16:9"
-            case .ratio9_16: return "9:16"
-            case .ratio4_3: return "4:3"
-            case .ratio3_4: return "3:4"
-            case .ratio2_3: return "2:3"
-            case .ratio3_2: return "3:2"
-            }
-        }
-        
-        static func creatAspectRatio(string:String)->AspectRatio{
-            switch string {
-            case "1:1": return .ratio1_1
-            case "16:9": return .ratio16_9
-            case "9:16": return .ratio9_16
-            case "4:3": return .ratio4_3
-            case "3:4": return .ratio3_4
-            case "2:3": return .ratio2_3
-            case "3:2": return .ratio3_2
-            default: return .ratio1_1
-            }
-        }
-    }
-
+  
     var currentRatio: AspectRatio{
         if let selectStyleModel = selectStyleModel {
             return AspectRatio.creatAspectRatio(string: selectStyleModel.imageText)

+ 95 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleCell.swift

@@ -0,0 +1,95 @@
+//
+//  TSGennertatorSelectStyleCell.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/4/29.
+//
+
+import Foundation
+
+class TSGennertatorSelectStyleCell: TSBaseCollectionCell {
+    
+    static let cellID = "TSGennertatorSelectStyleCell"
+
+    override var isSelected: Bool{
+        didSet{
+            boardImageView.isHidden = isSelected ? false : true
+            textLabel.textColor = isSelected ? .themeColor : .white.withAlphaComponent(0.8)
+        }
+    }
+    
+    var itemModel:TSGenerateOnlineStyleModel = TSGenerateOnlineStyleModel(){
+        didSet{
+            imageView.setAsyncImage(urlString: itemModel.coverUrl,placeholder: UIImage(named: "placeholderImageNoAlpha"))
+            
+            if itemModel.mSpecialType.imageName.isEmpty {
+                hotImageView.image = UIImage(named: itemModel.mSpecialType.imageName)
+                hotImageView.isHidden = false
+            }else{
+                hotImageView.isHidden = true
+            }
+            textLabel.text = itemModel.styleName
+        }
+    }
+    
+    lazy var boardImageView: UIImageView = {
+        let boardImageView = UIImageView()
+        boardImageView.cornerRadius = 16
+        boardImageView.isHidden = true
+        return boardImageView
+    }()
+
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView()
+        imageView.cornerRadius = 12
+        return imageView
+    }()
+    
+    lazy var hotImageView: UIImageView = {
+        let hotImageView = UIImageView.createImageView(imageName: "ptp_style_hot")
+        hotImageView.isHidden = true
+        return hotImageView
+    }()
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 14),textColor: .white,textAlignment: .center,numberOfLines: 2)
+        textLabel.adjustsFontSizeToFitWidth = true
+        return textLabel
+    }()
+    
+    override func creatUI() {
+        let w = contentView.width
+        bgContentView.addSubview(boardImageView)
+        boardImageView.snp.makeConstraints { make in
+            make.top.centerX.equalToSuperview()
+            make.width.height.equalTo(w)
+        }
+        
+        bgContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(4)
+            make.centerX.equalToSuperview()
+            make.width.height.equalTo(w-8)
+        }
+        
+        imageView.addSubview(hotImageView)
+        hotImageView.snp.makeConstraints { make in
+            make.leading.equalTo(0)
+            make.top.equalTo(0.0)
+            make.width.height.equalTo(36)
+        }
+        
+        bgContentView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(boardImageView.snp.bottom).offset(2)
+            make.leading.trailing.bottom.equalToSuperview()
+        }
+    
+        boardImageView.setNeedsLayout()
+        DispatchQueue.main.async {
+            self.boardImageView.addGradientBorder(colors: ["#FA794F".uiColor,"#F8C32A".uiColor,"#FEFBF4".uiColor],width: 1.5,startPoint: CGPoint(x: 0, y: 1),endPoint: CGPoint(x: 1, y: 0))
+        }
+    }
+    
+}
+

+ 132 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleListVc.swift

@@ -0,0 +1,132 @@
+//
+//  TSGennertatorSelectStyleListVc.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/4/29.
+//
+
+import Foundation
+
+class TSGennertatorSelectStyleListVc: TSBaseVC {
+    var viewModel: TSGennertatorSelectStyleListViewModel = .init()
+
+    var selectedValueBlock: ((IndexPath, TSGenerateOnlineStyleModel) -> Void)?
+
+    lazy var styleCollectionView: UICollectionView = {
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: viewModel.layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSGennertatorSelectStyleCell.self, forCellWithReuseIdentifier: TSGennertatorSelectStyleCell.cellID)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+
+    lazy var loadingView: UIImageView = {
+        let loading = UIImageView(image: .init(named: "styleplaceholder"))
+        loading.contentMode = .scaleAspectFit
+        return loading
+    }()
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        addNotifaction()
+        viewModel.requestPTPStyles()
+    }
+
+    func addNotifaction() {
+        viewModel.$loadState.receive(on: DispatchQueue.main).sink { [weak self] state in
+            guard let self = self else { return }
+            switch state {
+            case .loading:
+                self.showLoading()
+            case .success:
+                self.styleCollectionView.reloadData()
+                self.hideloading()
+            case .failed:
+                /// 失败的情况,不需要用户感知,所以不需要隐藏loading鱼骨图
+                break
+            default:
+                break
+            }
+        }.store(in: &cancellable)
+
+        viewModel.$datas.receive(on: DispatchQueue.main).sink { [weak self] datas in
+            guard let self = self else { return }
+            if !datas.isEmpty && viewModel.currentIndexPath.item < datas.count {
+                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
+                    self.styleCollectionView.selectItem(at: self.viewModel.currentIndexPath, animated: true, scrollPosition: .centeredVertically)
+                }
+            }
+        }.store(in: &cancellable)
+    }
+
+    override func createView() {
+        setContentView()
+    }
+
+    private func setContentView() {
+        view.addSubview(styleCollectionView)
+        styleCollectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        view.addSubview(loadingView)
+        loadingView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        if viewModel.isBigLoading {
+            loadingView.image = UIImage(named: "styleplaceholder")
+        } else {
+            loadingView.image = UIImage(named: "styleplaceholderbig")
+        }
+    }
+
+    private func showLoading() {
+        loadingView.isHidden = false
+    }
+
+    private func hideloading() {
+        loadingView.isHidden = true
+    }
+
+    public func selectIndex(indexPath: IndexPath, dir: UICollectionView.ScrollPosition = .centeredHorizontally) {
+        viewModel.currentIndexPath = indexPath
+        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
+            self.styleCollectionView.selectItem(at: self.viewModel.currentIndexPath, animated: true, scrollPosition: dir)
+        }
+    }
+
+    public func reloadDatas() {
+        styleCollectionView.reloadData()
+    }
+}
+
+extension TSGennertatorSelectStyleListVc: UICollectionViewDataSource, UICollectionViewDelegate {
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return viewModel.datas.count
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSGennertatorSelectStyleCell.cellID, for: indexPath)
+        if let cell = cell as? TSGennertatorSelectStyleCell, let itemModel = viewModel.datas.safeObj(At: indexPath.item) {
+            cell.itemModel = itemModel
+        }
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let model = viewModel.datas.safeObj(At: indexPath.item) {
+            selectIndex(indexPath: indexPath, dir: .centeredVertically)
+            selectedValueBlock?(indexPath, model)
+        }
+    }
+}

+ 58 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/StyleList/TSGennertatorSelectStyleListViewModel.swift

@@ -0,0 +1,58 @@
+//
+//  TSGennertatorSelectStyleViewModel.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/4/29.
+//
+
+import Combine
+import Foundation
+import ObjectMapper
+
+class TSGennertatorSelectStyleListViewModel {
+    @Published var loadState: TSLoadState = .idle
+
+    var currentIndexPath: IndexPath = IndexPath(item: 0, section: 0)
+
+    var viewH: CGFloat = 110.0
+    ///是否需要展示鱼骨图
+    var isBigLoading : Bool = true
+
+    var layout: UICollectionViewFlowLayout = {
+        let w = (k_ScreenWidth - 32.0 - 30.0 - 2.0) / 4.0
+        let layout = UICollectionViewFlowLayout()
+        layout.itemSize = CGSize(width: w, height: 110)
+
+        layout.scrollDirection = .vertical
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 10.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: k_Height_safeAreaInsetsBottom(), right: 16)
+        return layout
+    }()
+
+    @Published var datas: [TSGenerateOnlineStyleModel] = []
+
+    func requestPTPStyles() {
+        // 说明不需要请求数据,由外部传入
+        if !datas.isEmpty {
+            loadState = .success(datas)
+            return
+        }
+        loadState = .loading
+        _ = TSNetworkShared.get(urlType: .imageToImageStyle) { [weak self] data, _ in
+            guard let self = self else { return }
+            if let result = kNetWorkResultSuccess(data: data) {
+                if let mResult = Mapper<TSGeneerateOnlineStyleResult>().map(JSON: result) {
+                    self.datas = mResult.img2imgStyles ?? []
+                    self.loadState = .success(self.datas)
+                } else {
+                    requestPTPStyles()
+                    self.loadState = .failed("解析失败")
+                }
+            } else {
+                requestPTPStyles()
+                self.loadState = .failed("请求失败")
+            }
+        }
+    }
+}

+ 98 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyle/TSGennertatorSelectStyleVC.swift

@@ -0,0 +1,98 @@
+//
+//  TSGennertatorSelectStyleVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/27.
+//
+
+class TSGennertatorSelectStyleVC: TSBaseVC {
+    var viewModel: TSGennertatorSelectStyleViewModel = .init()
+
+    lazy var bottomView: UIView = {
+        let bottomView = UIView()
+        bottomView.backgroundColor = .popupColor
+        return bottomView
+    }()
+
+    lazy var xBtn: TSUIExpandedTouchButton = {
+        let xBtn = TSUIExpandedTouchButton()
+        xBtn.setUpButton(image: UIImage(named: "close_gray")) { [weak self] in
+            guard let self = self else { return }
+            self.dismiss(animated: true)
+        }
+        return xBtn
+    }()
+
+    var selectedValueBlock: ((IndexPath, TSGenerateOnlineStyleModel) -> Void)?
+
+    lazy var styleCollectionVc: TSGennertatorSelectStyleListVc = {
+        let vc = TSGennertatorSelectStyleListVc()
+        vc.viewModel.currentIndexPath = viewModel.currentIndexPath
+        vc.viewModel.layout = viewModel.layout
+        vc.viewModel.datas = viewModel.initData
+        vc.viewModel.isBigLoading = false
+        vc.selectedValueBlock = selectedValueBlock
+        vc.view.backgroundColor = .clear
+        return vc
+    }()
+
+    override func createView() {
+        view.backgroundColor = .clear
+        contentView.backgroundColor = .clear
+        setNavBarViewHidden(true)
+
+        contentView.addSubview(bottomView)
+        bottomView.snp.makeConstraints { make in
+            make.bottom.leading.trailing.bottom.equalTo(0)
+            make.top.equalTo(104 + k_Nav_Height)
+        }
+        
+        let topView = UIView()
+        contentView.addSubview(topView)
+        topView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickTopView)))
+        topView.snp.makeConstraints { make in
+            make.top.leading.trailing.equalTo(0)
+            make.bottom.equalTo(bottomView.snp.top)
+        }
+       
+        
+        setContentView()
+
+        kDelayMainShort {
+            self.bottomView.cornersRound(radius: 20, corner: [.topLeft, .topRight])
+        }
+    }
+
+    func setContentView() {
+        let titleLabel = UILabel.createLabel(text: "Select Style".localized, font: .font(size: 16, weight: .medium), textColor: .white)
+        bottomView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.top.equalTo(24)
+        }
+
+        bottomView.addSubview(xBtn)
+        xBtn.snp.makeConstraints { make in
+            make.top.equalTo(8)
+            make.trailing.equalTo(-8)
+            make.width.height.equalTo(24)
+        }
+
+        bottomView.addSubview(styleCollectionVc.view)
+        styleCollectionVc.view.snp.makeConstraints { make in
+            make.top.equalTo(56)
+            make.leading.trailing.equalTo(0)
+            make.bottom.equalTo(0)
+        }
+        addChild(styleCollectionVc)
+        styleCollectionVc.didMove(toParent: self)
+    }
+
+    override func dealThings() {
+        addPullDownClosePage()
+    }
+    
+    @objc func clickTopView(){
+        self.dismiss()
+    }
+}

+ 29 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyle/TSGennertatorSelectStyleViewModel.swift

@@ -0,0 +1,29 @@
+//
+//  TSGennertatorSelectStyleViewModel.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/4/29.
+//
+
+import Foundation
+
+class TSGennertatorSelectStyleViewModel {
+    var currentIndexPath: IndexPath = IndexPath(item: 0, section: 0)
+
+    var viewH: CGFloat = 110.0
+
+    var layout: UICollectionViewFlowLayout = {
+        let w = (k_ScreenWidth - 32.0 - 30.0 - 2.0) / 4.0
+        let layout = UICollectionViewFlowLayout()
+        layout.itemSize = CGSize(width: w, height: 110)
+
+        layout.scrollDirection = .vertical
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 10.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: k_Height_safeAreaInsetsBottom(), right: 16)
+        return layout
+    }()
+    
+    var initData : [TSGenerateOnlineStyleModel] = []
+
+}

+ 4 - 9
AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift

@@ -12,8 +12,8 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
     
     var progressState = TSProgressState.none
 
-    var generateStyleModel:TSGenerateStyleModel
-    init(generateStyleModel:TSGenerateStyleModel,infoModel:TSActionInfoModel? = nil,complete:@escaping ((TSActionInfoModel)->Void)) {
+    var generateStyleModel:TSGenerateOnlineStyleModel
+    init(generateStyleModel:TSGenerateOnlineStyleModel,infoModel:TSActionInfoModel? = nil,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.generateStyleModel = generateStyleModel
         self.infoModel = infoModel
         viewModel = TSPTPGeneratorVM(generateStyleModel: generateStyleModel)
@@ -31,13 +31,8 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
     lazy var generateInView : TSGeneratorloadingView = {
         let generateInView = TSGeneratorloadingView()
         generateInView.backgroundGenerateBtn.addTarget(self, action: #selector(clickBackstageBtn), for: .touchUpInside)
-        if generateStyleModel.advance {
-            generateInView.timeLabel.text = String(format: "~ %d min".localized, 2)
-            generateInView.infoLabel.text = "It is definitely worth your wait. Just watch it".localized
-        }else{
-            generateInView.timeLabel.text = String(format: "~ %d seconds".localized, 20)
-            generateInView.infoLabel.text = ""
-        }
+        generateInView.timeLabel.text = generateStyleModel.mModelType.showTime
+        generateInView.infoLabel.text = generateStyleModel.mModelType.info
         return generateInView
     }()
     

+ 7 - 16
AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/VM/TSPTPGeneratorVM.swift

@@ -41,9 +41,9 @@ class TSPTPGeneratorVM {
     
     @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil)
    
-    var generateStyleModel:TSGenerateStyleModel
+    var generateStyleModel:TSGenerateOnlineStyleModel
     var generatingProgress = 0
-    init(generateStyleModel:TSGenerateStyleModel){
+    init(generateStyleModel:TSGenerateOnlineStyleModel){
         self.generateStyleModel = generateStyleModel
     }
     
@@ -145,22 +145,13 @@ class TSPTPGeneratorVM {
         stopNetwork = false
         stateDatauPblished = (.start,nil)
         stateDatauPblished = (.progressString(generating(progress: 0.0)),nil)
+    
         
-        var prompt = generateStyleModel.prompt
-        if generateStyleModel.input,generateStyleModel.inputText.count>0{
-            if prompt.count > 0 {
-                prompt = prompt + ", " + generateStyleModel.inputText
-            }else {
-                prompt = generateStyleModel.inputText
-            }
-        }
-        
-        creatRequest = TSNetworkShared.post(urlType: .imageRewrite,parameters:
-                                                ["prompt":prompt,
+        creatRequest = TSNetworkShared.post(urlType: .imageRewriteV2,parameters:
+                                                ["prompt":generateStyleModel.inputText,
                                                  "imageUrl":imageUrl,
-                                                 "style":generateStyleModel.style,
-                                                 "device":getUserInfoJsonString(),
-                                                 "advance": generateStyleModel.advance
+                                                 "styleId":generateStyleModel.styleId,
+                                                 "device":getUserInfoJsonString()
                                                 ]) { [weak self] data,error in
             guard let self = self else { return }
             

+ 185 - 181
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift

@@ -7,90 +7,87 @@
 
 import PhotosUI
 class TSPTPInputVC: TSBaseVC {
-
     lazy var viewModel: TSPTPInputVM = {
         let viewModel = TSPTPInputVM()
-        viewModel.isCanGennerateBlock = { [weak self] isCan in
+        viewModel.isCanGennerateBlock = { [weak self] _ in
             guard let self = self else { return }
             setCreatBtnEnabled()
         }
         return viewModel
     }()
-    
+
     lazy var photoPickerManager: TSPhotoPickerManager = {
         let photoPickerManager = TSPhotoPickerManager(viewController: self)
         return photoPickerManager
     }()
-    
+
     private var keyboardHeight: CGFloat = 0
     var hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
-    
-    //###################################### 导航栏 view ######################################
+
+    // ###################################### 导航栏 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
-   }()
-    
+        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 titleImageView = UIImageView.createImageView(imageName: "nav_title_pic",contentMode: .scaleToFill)
-       navBarView.barView.addSubview(titleImageView)
-       titleImageView.snp.makeConstraints { make in
-           make.centerY.equalToSuperview()
-           make.left.equalTo(16)
-       }
-       
-       navBarView.barView.addSubview(vipBtn)
-       vipBtn.snp.makeConstraints { make in
-           make.centerY.equalToSuperview()
-           make.trailing.equalTo(-16)//(-60)
-           make.width.height.equalTo(24)
-       }
-       
-       return navBarView
-   }()
-    
-    //###################################### cusStackView ######################################
+        let navBarView = TSBaseNavContentBarView()
+
+        let titleImageView = UIImageView.createImageView(imageName: "nav_title_pic", contentMode: .scaleToFill)
+        navBarView.barView.addSubview(titleImageView)
+        titleImageView.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.left.equalTo(16)
+        }
+
+        navBarView.barView.addSubview(vipBtn)
+        vipBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-16) // (-60)
+            make.width.height.equalTo(24)
+        }
+
+        return navBarView
+    }()
+
+    // ###################################### cusStackView ######################################
     lazy var cusStackView: TSCustomStackView = {
-        let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
+        let cusStackView = TSCustomStackView(axis: .vertical, spacing: 0)
         cusStackView.scrollView.isScrollEnabled = true
         return cusStackView
     }()
 
-    //###################################### 上传图片 ######################################
+    // ###################################### 上传图片 ######################################
     lazy var uploadView: TSPTPUploadView = {
         let uploadView = TSPTPUploadView()
         uploadView.clickHandel = { [weak self] index in
             guard let self = self else { return }
-            
-            if index == 0 {//删除
+
+            if index == 0 { // 删除
                 viewModel.upLoadImage = nil
                 uploadView.upLoadImage = nil
-            }else{//添加
-                if TSAIListHintBaseVC.isShowUploadImageHint{
+            } else { // 添加
+                if TSAIListHintBaseVC.isShowUploadImageHint {
                     TSAIListHintBaseVC.isShowUploadImageHint = false
                     presentModalHintVC()
-                }else {
+                } else {
                     pickSinglePhoto()
                 }
             }
         }
         return uploadView
     }()
-    
-    
-    func pickSinglePhoto()  {
-        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+
+    func pickSinglePhoto() {
+        photoPickerManager.pickCustomSinglePhoto { [weak self] image, errorString in
             guard let self = self else { return }
             if let errorString = errorString {
                 TSToastShared.showToast(text: errorString)
-            }else{
+            } else {
                 viewModel.upLoadImage = image
                 uploadView.upLoadImage = image
             }
@@ -99,24 +96,35 @@ class TSPTPInputVC: TSBaseVC {
             }
         }
     }
-    
-    //###################################### 选择风格 ######################################
-    lazy var selectStyleView: TSPTPSelectStyleView = {
-        let selectStyleView = TSPTPSelectStyleView()
-        selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
-        selectStyleView.dataArray = viewModel.ptpStyleModels
-        selectStyleView.clickHandle = { [weak self] indexPath ,model in
+
+    // ###################################### 选择风格 ######################################
+    lazy var selectStyleViewLayout: UICollectionViewFlowLayout = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        let w = (k_ScreenWidth - 32.0 - 30.0 - 2.0) / 4.0
+        layout.itemSize = CGSize(width: w, height: 110)
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 10.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        return layout
+    }()
+
+    ///风格视图
+    lazy var selectVc: TSGennertatorSelectStyleListVc = {
+        let selectStyleVC = TSGennertatorSelectStyleListVc()
+        selectStyleVC.viewModel.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
+        selectStyleVC.viewModel.layout = selectStyleViewLayout
+        selectStyleVC.selectedValueBlock = { [weak self] indexPath, model in
             guard let self = self else { return }
             viewModel.selectedPTPStyleModel = model
             viewModel.selectedStyleIndex = indexPath.item
             updateVipView()
             updateTextFiledView()
         }
-        return selectStyleView
+        return selectStyleVC
     }()
-    
-    
-    //###################################### 输入框 ######################################
+
+    // ###################################### 输入框 ######################################
     lazy var customTextView: TSPlaceholderTextView = {
         let customTextView = TSPlaceholderTextView(
             placeholder: "Describe how you want to transform".localized,
@@ -129,13 +137,12 @@ class TSPTPInputVC: TSBaseVC {
         customTextView.returnKeyType = .done
         return customTextView
     }()
-    
+
     lazy var clearBtn: TSUIExpandedTouchButton = {
         let clearBtn = TSUIExpandedTouchButton()
         clearBtn.setUpButton(
             image: UIImage(named: "clear_text")
-        )
-        { [weak self]  in
+        ) { [weak self] in
             guard let self = self else { return }
             customTextView.text = ""
             textViewDidChange(customTextView)
@@ -143,9 +150,9 @@ class TSPTPInputVC: TSBaseVC {
         clearBtn.isHidden = true
         return clearBtn
     }()
-    
-    var promptTextViewH:CGFloat = 96.0
-    lazy var promptTextView:UIView =  {
+
+    var promptTextViewH: CGFloat = 96.0
+    lazy var promptTextView: UIView = {
         let promptTextView = UIView()
         promptTextView.isHidden = true
         promptTextView.clipsToBounds = true
@@ -156,10 +163,10 @@ class TSPTPInputVC: TSBaseVC {
         bgView.snp.makeConstraints { make in
             make.edges.equalTo(UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16))
         }
-        
+
         bgView.addSubview(customTextView)
         bgView.addSubview(clearBtn)
-        
+
         customTextView.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.leading.equalTo(12.0)
@@ -167,50 +174,51 @@ class TSPTPInputVC: TSBaseVC {
             make.bottom.equalTo(-12.0)
             make.trailing.equalTo(-20)
         }
-        
+
         clearBtn.snp.makeConstraints { make in
             make.width.height.equalTo(16.0)
             make.trailing.equalTo(-12)
             make.bottom.equalTo(-12.0)
         }
-        
+
         return promptTextView
     }()
-    //###################################### 集合视图 ######################################
+
+    // ###################################### 集合视图 ######################################
     private var collectionViewObserver: CollectionViewObserver!
-    let collectionViewBtootm:CGFloat = 80
+    let collectionViewBtootm: CGFloat = 80
     lazy var collectionComponent: TSCollectionViewComponent = {
         let layout = UICollectionViewFlowLayout()
         let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [:])
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: collectionViewBtootm, right: 0)
         cp.collectionView.isScrollEnabled = false
- 
+
         // 禁用自动 contentInset 调整
-          if #available(iOS 11.0, *) {
-              cp.collectionView.contentInsetAdjustmentBehavior = .never
-          } else {
-              automaticallyAdjustsScrollViewInsets = false
-          }
+        if #available(iOS 11.0, *) {
+            cp.collectionView.contentInsetAdjustmentBehavior = .never
+        } else {
+            automaticallyAdjustsScrollViewInsets = false
+        }
 
-        cp.sectionActionHandler = { [weak self] cellCp, indexPath in
+        cp.sectionActionHandler = { [weak self] cellCp, _ in
             guard let self = self else { return }
             if let cmd = cellCp as? String {
                 if cmd == "delete" {
-                    showCustomAlert(message: "Are you sure to delete".localized, deleteHandler:  {
+                    showCustomAlert(message: "Are you sure to delete".localized, deleteHandler: {
                         self.viewModel.removeAllHistoryList()
                         self.updataCollectionView()
                     })
-                }else if cmd == "more" {
+                } else if cmd == "more" {
                     let historyVC = TSPTPHistoryVC()
                     kPushVC(target: self, modelVC: historyVC)
                 }
             }
         }
-        
-        cp.itemActionHandler = { [weak self] (object, indexPath) in
+
+        cp.itemActionHandler = { [weak self] object, indexPath in
             guard let self = self else { return }
-            //删除过期的任务
-            if let cmd = object as? String, cmd == "delete_task_expired"  {
+            // 删除过期的任务
+            if let cmd = object as? String, cmd == "delete_task_expired" {
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
                    let currentActionInfoModel = sections.items.safeObj(At: indexPath.item) {
                     TSRMShared.ptpDBHistory.deleteListModel(id: currentActionInfoModel.dataModel.id)
@@ -218,69 +226,69 @@ class TSPTPInputVC: TSBaseVC {
                 }
             }
         }
-        
-        cp.itemDidSelectedHandler = { [weak self] (object, indexPath) in
+
+        cp.itemDidSelectedHandler = { [weak self] _, indexPath in
             guard let self = self else { return }
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
-               let dataModel = sections.items.safeObj(At: indexPath.item)?.dataModel
-            {
-
-                var dataModelArray:[TSActionInfoModel] = []
+               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{
+                    if itemModel.dataModel.status == "success" || itemModel.dataModel.modelType == .example {
                         dataModelArray.append(itemModel.dataModel)
                     }
                 }
-  
+
                 let browseVC = TSAIPhotoBrowseVC()
                 browseVC.dataModelArray = dataModelArray
                 browseVC.currentIndex = dataModelArray.firstIndex(of: dataModel) ?? 0
-                kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
+                kPresentModalVC(target: self, modelVC: browseVC, transitionStyle: .crossDissolve)
             }
         }
         cp.collectionView.keyboardDismissMode = .interactive
         return cp
     }()
-    
-    //###################################### Button ######################################
-    lazy var creatBtnView:TSAppBtnView  = {
+
+    // ###################################### Button ######################################
+    lazy var creatBtnView: TSAppBtnView = {
         let creatBtnView = TSAppBtnView()
         creatBtnView.setUpButton(style: .generate, vipFreeNumType: .picToPic) { [weak self] in
             guard let self = self else { return }
             generateImage()
         }
         creatBtnView.setBtnEnabled(isEnabled: false)
-        creatBtnView.isIconVipBlock = { [weak self]  in
-            guard let self = self else { return false}
+        creatBtnView.isIconVipBlock = { [weak self] in
+            guard let self = self else { return false }
             var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
             if showVip == false {
-                showVip = self.viewModel.selectedPTPStyleModel.isVip
+                showVip = self.viewModel.selectedPTPStyleModel.vip
             }
             return showVip
         }
-        creatBtnView.isClickVipBlock = { [weak self]  in
-            guard let self = self else { return false}
+        creatBtnView.isClickVipBlock = { [weak self] in
+            guard let self = self else { return false }
             var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
-            if viewModel.selectedPTPStyleModel.isVip == true {
+            if viewModel.selectedPTPStyleModel.vip == true {
                 isVip = true
             }
             return isVip
         }
         return creatBtnView
     }()
-    
-    
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+    }
+
     override func createView() {
-        
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
         tapGesture.cancelsTouchesInView = false
         view.addGestureRecognizer(tapGesture)
-        
+
         navBarContentView.addSubview(navBarView)
         navBarView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
-        
+
         contentView.addSubview(cusStackView)
         cusStackView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
@@ -293,44 +301,43 @@ class TSPTPInputVC: TSBaseVC {
             make.trailing.equalTo(-16)
             make.height.equalTo(48)
         }
-        
-        setUpCusStackView()
 
+        setUpCusStackView()
     }
-    
+
     override func dealThings() {
         updataCollectionView()
-        //监听 vip 变化
+        // 监听 vip 变化
         NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
         updateVipView()
-        
+
         TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
 
         // 监听键盘事件
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
-        
-        //监听collectionView 的 contentSize
+
+        // 监听collectionView 的 contentSize
         collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
-        collectionViewObserver.onContentSizeChange = {[weak self]  size in
+        collectionViewObserver.onContentSizeChange = { [weak self] size in
             guard let self = self else { return }
             print("collectionViewObserver 内容大小变化: \(size)")
             self.collectionComponent.collectionView.snp.updateConstraints { make in
-               make.height.equalTo(size.height)
+                make.height.equalTo(size.height)
             }
         }
-        
-        //监听按钮任务生成中
-        NotificationCenter.default.addObserver(forName: .kBaseOperationQueueCountChanged, object: nil, queue: nil) { [weak self] notification in
+
+        // 监听按钮任务生成中
+        NotificationCenter.default.addObserver(forName: .kBaseOperationQueueCountChanged, object: nil, queue: nil) { [weak self] _ in
             guard let self = self else { return }
             setCreatBtnEnabled()
         }
-        
-        //后台生成 UI 任务,刷新 UI界面
+
+        // 后台生成 UI 任务,刷新 UI界面
         NotificationCenter.default.addObserver(forName: .kGeneratePTPOperationChanged, object: nil, queue: nil) { [weak self] notification in
             guard let self = self else { return }
 
-            if let userInfo = notification.userInfo as? [String: Any],let state = userInfo["state"] as? TSProgressState {
+            if let userInfo = notification.userInfo as? [String: Any], let state = userInfo["state"] as? TSProgressState {
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
 //                if state.isResult {//有结果,一定要刷新
 //                    updataCollectionView()
@@ -343,38 +350,35 @@ class TSPTPInputVC: TSBaseVC {
 //                }
             }
         }
-        
-        //同时 VC主动刷新UI界面
-        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: nil) { [weak self] notification in
+
+        // 同时 VC主动刷新UI界面
+        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: nil) { [weak self] _ in
             guard let self = self else { return }
             DispatchQueue.main.async {
                 self.updataCollectionView()
             }
         }
     }
-    
-    func updataCollectionView(){
-        self.viewModel.updateRecentData()
+
+    func updataCollectionView() {
+        viewModel.updateRecentData()
         collectionComponent.clear()
-        collectionComponent.reloadView(with:viewModel.colDataArray)
+        collectionComponent.reloadView(with: viewModel.colDataArray)
     }
-
 }
 
 extension TSPTPInputVC {
-    
-    func presentModalHintVC(){
+    func presentModalHintVC() {
         hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig) { [weak self] image in
             guard let self = self else { return }
             viewModel.upLoadImage = image
             uploadView.upLoadImage = image
             hintBaseVC.dismissPageVC()
         }
-        kPresentModalVC(target: self, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
+        kPresentModalVC(target: self, modelVC: hintBaseVC, transitionStyle: .crossDissolve)
     }
-    
-    func setUpCusStackView(){
 
+    func setUpCusStackView() {
         let uploadPhotoTitleView = TSTitleView.creatTitleView(title: "Upload Photo".localized, subTitle: "")
         cusStackView.addSubviewToStack(uploadPhotoTitleView)
         uploadPhotoTitleView.snp.makeConstraints { make in
@@ -383,7 +387,7 @@ extension TSPTPInputVC {
         }
 
         let hintBtn = TSUIExpandedTouchButton()
-        hintBtn.setUpButton(image: UIImage(named: "ptp_hint")){ [weak self]  in
+        hintBtn.setUpButton(image: UIImage(named: "ptp_hint")) { [weak self] in
             guard let self = self else { return }
             presentModalHintVC()
         }
@@ -393,39 +397,44 @@ extension TSPTPInputVC {
             make.trailing.equalTo(-16)
             make.width.height.equalTo(16)
         }
- 
+
         cusStackView.addSubviewToStack(uploadView)
         uploadView.snp.makeConstraints { make in
             make.height.equalTo(uploadView.viewH)
             make.width.equalTo(k_ScreenWidth)
         }
-        
+
         let selectStyleTitleView = TSTitleMoreView()
-        selectStyleTitleView.setTitle(title: "Select Style".localized) { [weak self]  in
+        selectStyleTitleView.setTitle(title: "Select Style".localized) { [weak self] in
             guard let self = self else { return }
             let selectStyleVC = TSGennertatorSelectStyleVC()
-            selectStyleVC.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
-            selectStyleVC.dataArray = viewModel.ptpStyleModels
-            selectStyleVC.selectedValueBlock = { [weak self] indexPath ,model in
+            selectStyleVC.viewModel.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
+            selectStyleVC.viewModel.initData = self.selectVc.viewModel.datas
+            selectStyleVC.selectedValueBlock = { [weak self] indexPath, model in
                 guard let self = self else { return }
-                selectStyleView.collectionView(selectStyleView.styleCollectionView, didSelectItemAt: indexPath)
+                viewModel.selectedPTPStyleModel = model
+                self.selectVc.selectIndex(indexPath: indexPath,dir: .centeredHorizontally)
+                self.updateVipView()
+                self.updateTextFiledView()
             }
-            kPresentModalVC(target: self, modelVC: selectStyleVC,transitionStyle: .coverVertical)
+            kPresentModalVC(target: self, modelVC: selectStyleVC, transitionStyle: .coverVertical)
         }
         cusStackView.addSubviewToStack(selectStyleTitleView)
         selectStyleTitleView.snp.makeConstraints { make in
             make.height.equalTo(selectStyleTitleView.viewH)
             make.width.equalTo(k_ScreenWidth)
         }
-        
-        cusStackView.addSubviewToStack(selectStyleView)
-        selectStyleView.snp.makeConstraints { make in
-            make.height.equalTo(selectStyleView.viewH)
+
+        cusStackView.addSubviewToStack(selectVc.view)
+        selectVc.view.snp.makeConstraints { make in
+            make.height.equalTo(selectVc.viewModel.viewH)
             make.width.equalTo(k_ScreenWidth)
         }
-        
-        cusStackView.addSubviewToStack(promptTextView,length: promptTextViewH,animate: false)
-        
+        addChild(selectVc)
+        selectVc.didMove(toParent: self)
+
+        cusStackView.addSubviewToStack(promptTextView, length: promptTextViewH, animate: false)
+
         promptTextView.isHidden = !viewModel.selectedPTPStyleModel.input
 
         cusStackView.addSubviewToStack(collectionComponent.collectionView)
@@ -433,95 +442,90 @@ extension TSPTPInputVC {
             make.height.equalTo(0)
             make.width.equalTo(k_ScreenWidth)
         }
-        
+
         cusStackView.addSpacing(length: collectionViewBtootm)
     }
 }
 
-extension TSPTPInputVC: UITextViewDelegate{
+extension TSPTPInputVC: UITextViewDelegate {
     // 实现 UITextViewDelegate 协议方法,控制 return 键行为
     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
         if text == "\n" {
             // 当输入为换行符(即按下 return 键)时,执行相应操作
-            //sendBolck?(textView.text)
+            // sendBolck?(textView.text)
             clickView()
             return false
         }
         return true
     }
-    
-    func textViewDidChange(_ textView: UITextView){
+
+    func textViewDidChange(_ textView: UITextView) {
         clearBtn.isHidden = textView.text.count <= 0
         viewModel.selectedPTPStyleModel.inputText = textView.text
         viewModel.gennerateChange()
     }
-   
 }
 
 extension TSPTPInputVC {
-    
     @objc func vipInfoChanged() {
         kExecuteOnMainThread {
             self.updateVipView()
         }
     }
+
     func updateVipView() {
         kExecuteOnMainThread {
             self.vipBtn.isHidden = PurchaseManager.default.isVip
             self.creatBtnView.updateVipView()
         }
     }
-    
-    func getVipText()->String{
+
+    func getVipText() -> String {
         return "Generate".localized
     }
- 
-
 }
+
 extension TSPTPInputVC {
-    
     @objc func clickView() {
         view.endEditing(true)
     }
-    
+
     func generateImage() {
-        
         viewModel.selectedPTPStyleModel.upLoadImage = viewModel.upLoadImage
         viewModel.selectedPTPStyleModel.upLoadImageUrl = nil
-        let gennerateVC = TSPTPGeneratorVC(generateStyleModel: viewModel.selectedPTPStyleModel) { [weak self] model in
+        let gennerateVC = TSPTPGeneratorVC(generateStyleModel: viewModel.selectedPTPStyleModel) { [weak self] _ in
             guard let self = self else { return }
             updateVipView()
         }
-        
-        gennerateVC.reloadViewBlock = { [weak self]  in
+
+        gennerateVC.reloadViewBlock = { [weak self] in
             guard let self = self else { return }
             updataCollectionView()
         }
-        
+
         gennerateVC.closePageComplete = {
-            [weak self]  in
+            [weak self] in
             guard let self = self else { return }
             updataCollectionView()
         }
-        
-        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+
+        kPresentModalVC(target: self, modelVC: gennerateVC, transitionStyle: .crossDissolve)
     }
-    
+
     func setCreatBtnEnabled() {
         let isAvailability = TSGeneratePTPOperationQueue.shared.isAvailability
-        if viewModel.isCanGennerate,isAvailability {
+        if viewModel.isCanGennerate, isAvailability {
             creatBtnView.setBtnEnabled(isEnabled: true)
             creatBtnView.loading = false
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
-        }else{
+        } else {
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
             creatBtnView.setBtnEnabled(isEnabled: false)
             creatBtnView.loading = !isAvailability
         }
-        
+
         updateVipView()
     }
-
 }
 
 extension TSPTPInputVC {
@@ -532,26 +536,26 @@ extension TSPTPInputVC {
         let textViewFrame = scrollView.convert(customTextView.frame, from: customTextView.superview)
         let scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
         let y = scrollDistance
-        scrollView.setContentOffset(CGPoint(x: 0, y: y),animated: true)
+        scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
     }
-    
+
     // MARK: - 键盘隐藏时恢复
+
     @objc private func keyboardWillHide(_ notification: Notification) {
         cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
     }
 }
+
 extension TSPTPInputVC {
-    
-    func updateTextFiledView () {
+    func updateTextFiledView() {
         if viewModel.selectedPTPStyleModel.input {
             promptTextView.isHidden = false
-        }else{
+        } else {
             promptTextView.isHidden = true
         }
-        
+
         UIView.animate(withDuration: 0.3) {
             self.cusStackView.layoutIfNeeded()
         }
     }
 }
-

+ 31 - 57
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/VM/TSPTPInputVM.swift

@@ -8,45 +8,29 @@
 import Alamofire
 import ObjectMapper
 class TSPTPInputVM {
-    
-    var colDataArray:[TSComponent] = [TSComponent]()
-    var uploadRequest:Request?
-    var selectedPTPStyleModel:TSGenerateStyleModel = TSGenerateStyleModel(){
-        didSet{
+    var colDataArray: [TSComponent] = [TSComponent]()
+    var uploadRequest: Request?
+    var selectedPTPStyleModel: TSGenerateOnlineStyleModel = TSGenerateOnlineStyleModel() {
+        didSet {
             gennerateChange()
         }
     }
-    
-    var selectedStyleIndex:Int = 1
-    
-    var upLoadImage:UIImage?{
-        didSet{
+
+    var selectedStyleIndex: Int = 0
+
+    var upLoadImage: UIImage? {
+        didSet {
             isCanGennerateBlock?(isCanGennerate)
         }
     }
-
-    //选择类型组
-    lazy var ptpStyleModels: [TSGenerateStyleModel] = {
-        var ptpStyleModels = [TSGenerateStyleModel]()
-        if let dataArray = Mapper<TSGenerateStyleModel>().mapArray(JSONfile: "photo_to_photo_style.json"){
-            ptpStyleModels = dataArray
-            
-            if let model = dataArray.safeObj(At: selectedStyleIndex) {
-                selectedPTPStyleModel = model //加上默认的选择
-            }
-        }
-        
-        return ptpStyleModels
-    }()
-    
     
-    var listModels:[TSActionInfoModel]{
+    var listModels: [TSActionInfoModel] {
         debugPrint("listModels.count = 前")
         let array = TSRMShared.ptpDBHistory.getModelList(count: 50)
         debugPrint("listModels.count = \(array.count)")
         return array
     }
-    
+
     lazy var historySeciton: TSGenmojiCoLSectionModel = {
         let sectionModel = TSGenmojiCoLSectionModel()
         sectionModel.style = .ptpPicHistory
@@ -60,72 +44,64 @@ class TSPTPInputVM {
         return sectionModel
     }()
 
-    var isCanGennerate:Bool {
+    var isCanGennerate: Bool {
         if upLoadImage != nil {
-            if selectedPTPStyleModel.imageText == "No Style", selectedPTPStyleModel.input,selectedPTPStyleModel.inputText.replacingOccurrences(of: " ", with: "").count <= 0 {
+            if selectedPTPStyleModel.styleName == "No Style", selectedPTPStyleModel.input, selectedPTPStyleModel.inputText.replacingOccurrences(of: " ", with: "").count <= 0 {
                 return false
             }
             return true
         }
         return false
     }
-    
-    var isCanGennerateBlock:((Bool)->Void)?
+
+    var isCanGennerateBlock: ((Bool) -> Void)?
     init() {
         combinedData()
     }
 
-    func combinedData(){
+    func combinedData() {
         colDataArray.removeAll()
-        
+
         debugPrint("historySeciton start")
         if historySeciton.items.count > 0 {
             colDataArray.append(historySeciton)
         }
-        
+
         debugPrint("historySeciton end")
     }
-    
-    func gennerateChange(){
+
+    func gennerateChange() {
         isCanGennerateBlock?(isCanGennerate)
     }
+
 }
- 
+
 extension TSPTPInputVM {
-    //返回值,是否需要清空后刷新
-    func saveModel(model:TSActionInfoModel)->Bool{
+    // 返回值,是否需要清空后刷新
+    func saveModel(model: TSActionInfoModel) -> Bool {
         TSRMShared.ptpDBHistory.updateData(model)
-        
+
         var isNeed = false
         if historySeciton.items.count == 0 {
             colDataArray.append(historySeciton)
             isNeed = true
         }
-          
+
         let colItemModel = TSGenmojiCoLItemModel()
         colItemModel.style = .ptpPicHistory
         colItemModel.dataModel = model
         historySeciton.items.insert(colItemModel, at: 0)
         return isNeed
     }
-    
-    var prompt:String{
-        var prompt = ""
 
-        if selectedPTPStyleModel.prompt.count > 0 {
-            prompt = "\(selectedPTPStyleModel.prompt)," + prompt
-        }
-        return prompt
-    }
-
-    func removeAllHistoryList(){
+    func removeAllHistoryList() {
         TSRMShared.ptpDBHistory.delete()
         historySeciton.items.removeAll()
         colDataArray.removeLast()
     }
-    
+
     func updateRecentData() {
-        var items:[TSGenmojiCoLItemModel] = []
+        var items: [TSGenmojiCoLItemModel] = []
         for model in listModels {
             let itemModel = TSGenmojiCoLItemModel()
             itemModel.style = historySeciton.style
@@ -133,13 +109,11 @@ extension TSPTPInputVM {
             items.append(itemModel)
         }
         historySeciton.items = items
-        
+
         if listModels.count > 0 {
             colDataArray = [historySeciton]
-        }else {
+        } else {
             colDataArray = []
         }
     }
 }
-
-

+ 126 - 26
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/TSPTPStyleModel.swift

@@ -5,37 +5,137 @@
 //  Created by 100Years on 2025/2/25.
 //
 
-
 import ObjectMapper
 
 class TSGenerateStyleModel: TSBaseModel {
-    var imageName:String = ""
-    var imageText:String = ""
-    var prompt:String = ""
-    var isVip:Bool = false
-    var specialStyle:Int = 0 //0 普通类型,1 热门类型,2 新类型,3 max,
-    var clickType:Int = 0 //0 无响应, 1空类型 2.换图
-    var style:String = ""   //风格类型
-    
-    var input:Bool = false   //是否输入框
-    var advance:Bool = false    //走新的通道
-    
+    var imageName: String = ""
+    var imageText: String = ""
+    var prompt: String = ""
+    var isVip: Bool = false
+    var specialStyle: Int = 0 // 0 普通类型,1 热门类型,2 新类型,3 max,
+    var clickType: Int = 0 // 0 无响应, 1空类型 2.换图
+    var style: String = "" // 风格类型
+
+    var input: Bool = false // 是否输入框
+    var advance: Bool = false // 走新的通道
+
     override func mapping(map: ObjectMapper.Map) {
-        imageName               <- map["imageName"]
-        imageText               <- map["imageText"]
-        prompt                  <- map["prompt"]
-        isVip                   <- map["isVip"]
-        specialStyle            <- map["specialStyle"]
-        clickType               <- map["clickType"]
-        style                   <- map["style"]
-        input                   <- map["input"]
-        advance                 <- map["advance"]
+        imageName <- map["imageName"]
+        imageText <- map["imageText"]
+        prompt <- map["prompt"]
+        isVip <- map["isVip"]
+        specialStyle <- map["specialStyle"]
+        clickType <- map["clickType"]
+        style <- map["style"]
+        input <- map["input"]
+        advance <- map["advance"]
+    }
+
+    var actionInfoModel: TSActionInfoModel? // 对应生成的结果
+    var isSelected: Bool = false // 改风格,是否被选中
+    var inputText: String = "" // 用户自己补充的风格文字
+    var upLoadImage: UIImage? // 上传的图片
+    var upLoadImageUrl: String? // 上传的图片的 url
+}
+
+class TSGeneerateOnlineStyleResult: Mappable {
+    var img2imgStyles: [TSGenerateOnlineStyleModel]?
+
+    // Required initializer for ObjectMapper
+    required init?(map: Map) {
+    }
+
+    // Mapping function to map JSON keys to model properties
+    func mapping(map: Map) {
+        img2imgStyles <- map["img2imgStyles"]
+    }
+}
+
+enum ModelType: String {
+    case kie
+    case editing2
+    case unknowned
+
+    var showTime: String {
+        switch self {
+        case .kie:
+            return String(format: "~ %d min".localized, 2)
+        case .editing2:
+            return String(format: "~ %d seconds".localized, 20)
+        case .unknowned:
+            return String(format: "~ %d seconds".localized, 20)
+        }
     }
+
+    var info: String {
+        switch self {
+        case .kie:
+            return "It is definitely worth your wait. Just watch it".localized
+        case .editing2:
+            return ""
+        case .unknowned:
+            return ""
+        }
+    }
+}
+
+enum SpecialStyle: Int {
+    case hot
+    case new
+    case max
+    case unknown
     
-    var actionInfoModel:TSActionInfoModel? //对应生成的结果
-    var isSelected: Bool = false    //改风格,是否被选中
-    var inputText:String = ""   //用户自己补充的风格文字
-    var upLoadImage:UIImage?    //上传的图片
-    var upLoadImageUrl:String?    //上传的图片的 url
+    var imageName : String {
+        switch self {
+        case .hot:
+            return "ptp_style_hot"
+        case .new:
+            return "ptp_style_new"
+        case .max:
+            return "ptp_style_max"
+        case .unknown:
+            return ""
+        }
+    }
 }
 
+class TSGenerateOnlineStyleModel: TSBaseModel {
+    var vip: Bool = true
+    var styleId: String = ""
+    var coverUrl: String = ""
+    var modelType: String = ""
+    var styleName: String = ""
+    var name: String = ""
+    var input: Bool = false
+    var specialStyle: Int = 0 // 0 普通类型,1 热门类型,2 新类型,3 max,
+
+    // Mapping function to map JSON keys to model properties
+    override func mapping(map: Map) {
+        vip <- map["vip"]
+        styleId <- map["styleId"]
+        coverUrl <- map["coverUrl"]
+        modelType <- map["modelType"]
+        styleName <- map["styleName"]
+        name <- map["name"]
+        input <- map["input"]
+        specialStyle <- map["specialStyle"]
+    }
+
+    required convenience init?(json: [String: Any]) {
+        fatalError("init(json:) has not been implemented")
+    }
+
+    var mModelType: ModelType {
+        return ModelType(rawValue: modelType) ?? .unknowned
+    }
+
+    var mSpecialType: SpecialStyle {
+        return SpecialStyle(rawValue: specialStyle) ?? .unknown
+    }
+
+    /// 自用属性,非模型属性
+    var inputText: String = "" // 用户自己补充的风格文字
+    var isSelected: Bool = false // 改风格,是否被选中
+    var upLoadImage: UIImage? // 上传的图片
+    var upLoadImageUrl: String? // 上传的图片的 url
+}

+ 3 - 1
AIEmoji/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift

@@ -16,7 +16,9 @@ enum TSNeURLType:String {
     case chat = "/api/text/chat"                 //AI 对话接口
     case textPicCreate = "/api/image/create"     //文生图
     case upload = "/api/upload"                  //上传图片
-    case imageRewrite = "/api/image/rewrite"     //图生图
+    case imageRewrite = "/api/image/rewrite"     //图生图(废弃)
+    case imageRewriteV2 = "/api/image/img2img"   //图生图v2接口
+    case imageToImageStyle = "/api/ops/aichat-img2img-config"     //图生图 风格列表
     case chatV2 = "/api/text/chat/v2"             //AI 对话接口V2,扩展了 DeepSeek 深度思考
     
     case config = "/api/ops/aichat-config"       //App配置

+ 10 - 13
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift

@@ -77,11 +77,9 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         }
         
         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: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: topY)) {
-                let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateStyleModel(),infoModel: cyModel) { model in }
+        if let rootVC = WindowHelper.getCurrentViewController() ,let cyModel = copyModel as? TSActionInfoModel {
+            kSaveSuccesswShared.show(atView: rootVC.view,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: k_Nav_Height+10)) {
+                let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateOnlineStyleModel(),infoModel: cyModel) { model in }
                 gennerateVC.modalPresentationStyle = .overFullScreen
                 gennerateVC.modalTransitionStyle = .crossDissolve
                 rootVC.present(gennerateVC, animated: true)
@@ -104,7 +102,7 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
     private var uploadRequest:Request?
     private var creatRequest:Request?
     
-    private func createActionInfoModel(generateStyleModel:TSGenerateStyleModel) -> TSActionInfoModel? {
+    private func createActionInfoModel(generateStyleModel:TSGenerateOnlineStyleModel) -> TSActionInfoModel? {
 
         guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
 
@@ -114,15 +112,15 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         infoModel.request.imageUrl = upLoadImageUrl
         infoModel.request.imageUrlTimestamp = Date.timestampInt
         
-        infoModel.request.prompt = generateStyleModel.prompt
+        infoModel.request.prompt = ""
         infoModel.request.promptSort = generateStyleModel.inputText
-        infoModel.request.style = generateStyleModel.style
-        infoModel.request.advance = generateStyleModel.advance
+        infoModel.request.style = generateStyleModel.styleId
+        infoModel.request.advance = false
         
         return infoModel
     }
     
-    func uploadImage(generateStyleModel:TSGenerateStyleModel,complete:@escaping (TSActionInfoModel?)->Void) {
+    func uploadImage(generateStyleModel:TSGenerateOnlineStyleModel,complete:@escaping (TSActionInfoModel?)->Void) {
         
         guard let upLoadImage = generateStyleModel.upLoadImage else { return  }
         if let imageUrl = generateStyleModel.upLoadImageUrl,imageUrl.contains("http") {
@@ -190,12 +188,11 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
             }
         }
         
-        creatRequest = TSNetworkShared.post(urlType: .imageRewrite,parameters:
+        creatRequest = TSNetworkShared.post(urlType: .imageRewriteV2,parameters:
                                                 ["prompt":prompt,
                                                  "imageUrl":request.imageUrl,
-                                                 "style":request.style,
+                                                 "styleId":request.style,
                                                  "device":getUserInfoJsonString(),
-                                                 "advance": request.advance
                                                 ]) { [weak self] data,error in
             guard let self = self else { return }
             

+ 64 - 0
AIEmoji/Enums/TSLoadState.swift

@@ -0,0 +1,64 @@
+//
+//  TSLoadState.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/4/29.
+//
+
+import Foundation
+
+
+public enum TSLoadState {
+    case idle //啥也没做的情况下
+    case loading //开始加载
+    case success(Any?) // 成功,可以向外传递数据
+    case failed(Any?) // 失败,可以向外传递数据
+}
+
+// MARK: - 比例枚举
+enum AspectRatio: Int {
+    case ratio1_1 = 0
+    case ratio16_9
+    case ratio9_16
+    case ratio4_3
+    case ratio3_4
+    case ratio2_3
+    case ratio3_2
+    
+    var value: CGFloat {
+        switch self {
+        case .ratio1_1: return 1.0
+        case .ratio16_9: return 16.0/9.0
+        case .ratio9_16: return 9.0/16.0
+        case .ratio4_3: return 4.0/3.0
+        case .ratio3_4: return 3.0/4.0
+        case .ratio2_3: return 2.0/3.0
+        case .ratio3_2: return 3.0/2.0
+        }
+    }
+    
+    var displayName: String {
+        switch self {
+        case .ratio1_1: return "1:1"
+        case .ratio16_9: return "16:9"
+        case .ratio9_16: return "9:16"
+        case .ratio4_3: return "4:3"
+        case .ratio3_4: return "3:4"
+        case .ratio2_3: return "2:3"
+        case .ratio3_2: return "3:2"
+        }
+    }
+    
+    static func creatAspectRatio(string:String)->AspectRatio{
+        switch string {
+        case "1:1": return .ratio1_1
+        case "16:9": return .ratio16_9
+        case "9:16": return .ratio9_16
+        case "4:3": return .ratio4_3
+        case "3:4": return .ratio3_4
+        case "2:3": return .ratio2_3
+        case "3:2": return .ratio3_2
+        default: return .ratio1_1
+        }
+    }
+}