Jelajahi Sumber

文生图新增风格选择

100Years 4 minggu lalu
induk
melakukan
13d1422c76
56 mengubah file dengan 1326 tambahan dan 255 penghapusan
  1. 83 15
      AIEmoji.xcodeproj/project.pbxproj
  2. 6 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/Contents.json
  3. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/Contents.json
  4. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/ttp_selected_border@2x.png
  5. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/ttp_selected_border@3x.png
  6. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/Contents.json
  7. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/ttp_style_0@2x.png
  8. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/ttp_style_0@3x.png
  9. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/Contents.json
  10. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/ttp_style_1@2x.png
  11. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/ttp_style_1@3x.png
  12. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/Contents.json
  13. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/ttp_style_2@2x.png
  14. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/ttp_style_2@3x.png
  15. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/Contents.json
  16. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/ttp_style_3@2x.png
  17. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/ttp_style_3@3x.png
  18. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/Contents.json
  19. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/ttp_style_4@2x.png
  20. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/ttp_style_4@3x.png
  21. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/Contents.json
  22. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/ttp_style_5@2x.png
  23. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/ttp_style_5@3x.png
  24. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/Contents.json
  25. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/ttp_style_6@2x.png
  26. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/ttp_style_6@3x.png
  27. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/Contents.json
  28. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/ttp_style_7@2x.png
  29. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/ttp_style_7@3x.png
  30. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/Contents.json
  31. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/ttp_style_8@2x.png
  32. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/ttp_style_8@3x.png
  33. 22 0
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/Contents.json
  34. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/ttp_style_9@2x.png
  35. TEMPAT SAMPAH
      AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/ttp_style_9@3x.png
  36. 1 1
      AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift
  37. 75 0
      AIEmoji/Business/Data/TSUserDefaultData.swift
  38. 5 4
      AIEmoji/Business/TSTabBarController/TSTabBarController.swift
  39. 145 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift
  40. 84 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/VM/TSTTPInputVM.swift
  41. 51 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSGeneralBtnView.swift
  42. 22 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPTPEnterView.swift
  43. 149 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPromptTextView.swift
  44. 165 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTTPStyleView.swift
  45. 26 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTitleView.swift
  46. 32 39
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/TSTextGeneralPictureVC.swift
  47. 148 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/View/TSTTPSelectStyleCell.swift
  48. 19 103
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift
  49. 1 0
      AIEmoji/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift
  50. 1 1
      AIEmoji/Common/NetworkManager/TSNetWork/TSNetworkManager.swift
  51. 0 90
      AIEmoji/Common/View/UIStackView/TSCustomStackView.swift
  52. 0 0
      AIEmoji/Res/photo_to_photo_style.json
  53. 0 0
      AIEmoji/Res/sticker.json
  54. 0 0
      AIEmoji/Res/templates.json
  55. 63 0
      AIEmoji/Res/text_to_photo_style.json
  56. 8 2
      Podfile.lock

+ 83 - 15
AIEmoji.xcodeproj/project.pbxproj

@@ -7,6 +7,13 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		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 */; };
+		A80327BF2D81578900AF7878 /* TSPromptTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327BE2D81576C00AF7878 /* TSPromptTextView.swift */; };
+		A80327C12D8157CB00AF7878 /* TSTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327C02D8157C500AF7878 /* TSTitleView.swift */; };
+		A80327C32D81581D00AF7878 /* TSTTPStyleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327C22D81580800AF7878 /* TSTTPStyleView.swift */; };
+		A80327C52D81584500AF7878 /* TSGeneralBtnView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327C42D81582F00AF7878 /* TSGeneralBtnView.swift */; };
 		A80E721A2D3F393A00C64288 /* DiyStickerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72192D3F393500C64288 /* DiyStickerModel.swift */; };
 		A80E721E2D3F3A7500C64288 /* DiyElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E721D2D3F3A7500C64288 /* DiyElement.swift */; };
 		A80E72202D3F3A8600C64288 /* DiyElementBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E721F2D3F3A8600C64288 /* DiyElementBaseView.swift */; };
@@ -71,7 +78,6 @@
 		A80EDD642D6C3F82003CD332 /* MarkdownStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDD322D6C3F82003CD332 /* MarkdownStyle.swift */; };
 		A80EDD682D6C5098003CD332 /* TSChatMsgBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDD672D6C507D003CD332 /* TSChatMsgBaseView.swift */; };
 		A80EDD6A2D6C518E003CD332 /* TSChatMsgToolView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDD692D6C5176003CD332 /* TSChatMsgToolView.swift */; };
-		A80EDDD92D6D9713003CD332 /* TSCustomStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDDD82D6D9713003CD332 /* TSCustomStackView.swift */; };
 		A80EDDDB2D6EB0D0003CD332 /* Untitled.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDDDA2D6EB0BB003CD332 /* Untitled.swift */; };
 		A80EDDE02D6EB1B9003CD332 /* TSPTPGeneratorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDDDF2D6EB1B8003CD332 /* TSPTPGeneratorCell.swift */; };
 		A80EDDE22D6EB8D8003CD332 /* TSPTPUploadCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80EDDE12D6EB8C7003CD332 /* TSPTPUploadCell.swift */; };
@@ -96,6 +102,9 @@
 		A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */; };
 		A85E47C32D6964A50018D62D /* TSMSGAIDefaultHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */; };
 		A85E47C62D697E750018D62D /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A85E47C52D697E750018D62D /* SwiftUIX */; };
+		A875870F2D81689A00286A66 /* TSPTPEnterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A875870E2D81689600286A66 /* TSPTPEnterView.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 */; };
 		A89EA64B2D59A588000EB181 /* MessageKit in Frameworks */ = {isa = PBXBuildFile; productRef = A89EA64A2D59A588000EB181 /* MessageKit */; };
 		A89EA6542D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */; };
 		A89EA6552D59A9F4000EB181 /* TSChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6502D59A9F4000EB181 /* TSChatMessage.swift */; };
@@ -183,6 +192,13 @@
 /* Begin PBXFileReference section */
 		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>"; };
+		A80327B22D813D4800AF7878 /* TSTTPInputVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPInputVC.swift; sourceTree = "<group>"; };
+		A80327B52D813D8100AF7878 /* TSTTPInputVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPInputVM.swift; sourceTree = "<group>"; };
+		A80327BE2D81576C00AF7878 /* TSPromptTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPromptTextView.swift; sourceTree = "<group>"; };
+		A80327C02D8157C500AF7878 /* TSTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTitleView.swift; sourceTree = "<group>"; };
+		A80327C22D81580800AF7878 /* TSTTPStyleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPStyleView.swift; sourceTree = "<group>"; };
+		A80327C42D81582F00AF7878 /* TSGeneralBtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralBtnView.swift; sourceTree = "<group>"; };
 		A80E72192D3F393500C64288 /* DiyStickerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyStickerModel.swift; sourceTree = "<group>"; };
 		A80E721D2D3F3A7500C64288 /* DiyElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyElement.swift; sourceTree = "<group>"; };
 		A80E721F2D3F3A8600C64288 /* DiyElementBaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyElementBaseView.swift; sourceTree = "<group>"; };
@@ -253,7 +269,6 @@
 		A80EDD402D6C3F82003CD332 /* MarkdownParser+UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarkdownParser+UIKit.swift"; sourceTree = "<group>"; };
 		A80EDD672D6C507D003CD332 /* TSChatMsgBaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatMsgBaseView.swift; sourceTree = "<group>"; };
 		A80EDD692D6C5176003CD332 /* TSChatMsgToolView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatMsgToolView.swift; sourceTree = "<group>"; };
-		A80EDDD82D6D9713003CD332 /* TSCustomStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSCustomStackView.swift; sourceTree = "<group>"; };
 		A80EDDDA2D6EB0BB003CD332 /* Untitled.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Untitled.swift; sourceTree = "<group>"; };
 		A80EDDDF2D6EB1B8003CD332 /* TSPTPGeneratorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPGeneratorCell.swift; sourceTree = "<group>"; };
 		A80EDDE12D6EB8C7003CD332 /* TSPTPUploadCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPTPUploadCell.swift; sourceTree = "<group>"; };
@@ -277,6 +292,9 @@
 		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>"; };
 		A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSMSGAIDefaultHeaderView.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>"; };
+		A87587152D81733C00286A66 /* text_to_photo_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = text_to_photo_style.json; sourceTree = "<group>"; };
 		A89EA64C2D59A9F4000EB181 /* CustomMessageFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageFlowLayout.swift; sourceTree = "<group>"; };
 		A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLayoutSizeCalculator.swift; sourceTree = "<group>"; };
 		A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTextLayoutSizeCalculator.swift; sourceTree = "<group>"; };
@@ -393,6 +411,44 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
+		A80327AE2D8139F200AF7878 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		A80327B12D813D1B00AF7878 /* TSTTPInputVC */ = {
+			isa = PBXGroup;
+			children = (
+				A80327BD2D81576700AF7878 /* View */,
+				A80327B42D813D7900AF7878 /* VM */,
+				A80327B22D813D4800AF7878 /* TSTTPInputVC.swift */,
+			);
+			path = TSTTPInputVC;
+			sourceTree = "<group>";
+		};
+		A80327B42D813D7900AF7878 /* VM */ = {
+			isa = PBXGroup;
+			children = (
+				A80327B52D813D8100AF7878 /* TSTTPInputVM.swift */,
+			);
+			path = VM;
+			sourceTree = "<group>";
+		};
+		A80327BD2D81576700AF7878 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A875870E2D81689600286A66 /* TSPTPEnterView.swift */,
+				A80327C42D81582F00AF7878 /* TSGeneralBtnView.swift */,
+				A80327C22D81580800AF7878 /* TSTTPStyleView.swift */,
+				A80327C02D8157C500AF7878 /* TSTitleView.swift */,
+				A80327BE2D81576C00AF7878 /* TSPromptTextView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		A80E72182D3F390A00C64288 /* DiySticker */ = {
 			isa = PBXGroup;
 			children = (
@@ -442,8 +498,6 @@
 		A80E72442D3F4EDC00C64288 /* Json */ = {
 			isa = PBXGroup;
 			children = (
-				A80E72452D3F4EED00C64288 /* sticker.json */,
-				A80E72472D3F4F0500C64288 /* templates.json */,
 			);
 			path = Json;
 			sourceTree = "<group>";
@@ -824,14 +878,6 @@
 			path = MarkdownKit;
 			sourceTree = "<group>";
 		};
-		A80EDDD72D6D9705003CD332 /* UIStackView */ = {
-			isa = PBXGroup;
-			children = (
-				A80EDDD82D6D9713003CD332 /* TSCustomStackView.swift */,
-			);
-			path = UIStackView;
-			sourceTree = "<group>";
-		};
 		A80EDDDC2D6EB17D003CD332 /* TSPTPGeneratorVC */ = {
 			isa = PBXGroup;
 			children = (
@@ -899,7 +945,6 @@
 		A80EDDED2D6EC020003CD332 /* M */ = {
 			isa = PBXGroup;
 			children = (
-				A80EDDFC2D6EF34C003CD332 /* photo_to_photo_style.json */,
 				A80EDDEF2D6EC044003CD332 /* TSPTPStyleModel.swift */,
 			);
 			path = M;
@@ -924,6 +969,7 @@
 		A85E478D2D670DF10018D62D /* TSTextGeneralPictureVC */ = {
 			isa = PBXGroup;
 			children = (
+				A80327B12D813D1B00AF7878 /* TSTTPInputVC */,
 				A85E47942D672AC30018D62D /* TSTextPicGennerateVC */,
 				A85E47932D672AB40018D62D /* TSTextGeneralPictureVC */,
 			);
@@ -941,6 +987,7 @@
 		A85E47932D672AB40018D62D /* TSTextGeneralPictureVC */ = {
 			isa = PBXGroup;
 			children = (
+				A80327AE2D8139F200AF7878 /* View */,
 				A85E47902D6728810018D62D /* ViewModel */,
 				A85E478E2D6711590018D62D /* TSTextGeneralPictureVC.swift */,
 			);
@@ -976,6 +1023,14 @@
 			path = TSCellView;
 			sourceTree = "<group>";
 		};
+		A87587112D81702700286A66 /* Data */ = {
+			isa = PBXGroup;
+			children = (
+				A87587102D81702700286A66 /* TSUserDefaultData.swift */,
+			);
+			path = Data;
+			sourceTree = "<group>";
+		};
 		A89EA64D2D59A9F4000EB181 /* Layout */ = {
 			isa = PBXGroup;
 			children = (
@@ -1133,6 +1188,7 @@
 		A8F774922D38EA8C00AA6E93 /* Business */ = {
 			isa = PBXGroup;
 			children = (
+				A87587112D81702700286A66 /* Data */,
 				A80EDDDC2D6EB17D003CD332 /* TSPTPGeneratorVC */,
 				A85E478D2D670DF10018D62D /* TSTextGeneralPictureVC */,
 				A80E74222D5996BF00C64288 /* AIChat */,
@@ -1198,7 +1254,6 @@
 			isa = PBXGroup;
 			children = (
 				A80EDDFE2D6EFD1A003CD332 /* TSPhotoPickerManager */,
-				A80EDDD72D6D9705003CD332 /* UIStackView */,
 				A8F776292D3A70AA00AA6E93 /* UILabel */,
 			);
 			path = View;
@@ -1477,6 +1532,10 @@
 				A8EEADD52D3E6CD30032C5A0 /* Fish🐠.json */,
 				A8EEADD32D3E6C610032C5A0 /* Flower💐.json */,
 				A8FB02D02D3E6B240031A396 /* Cat🐱.json */,
+				A80E72452D3F4EED00C64288 /* sticker.json */,
+				A80E72472D3F4F0500C64288 /* templates.json */,
+				A80EDDFC2D6EF34C003CD332 /* photo_to_photo_style.json */,
+				A87587152D81733C00286A66 /* text_to_photo_style.json */,
 			);
 			path = Res;
 			sourceTree = "<group>";
@@ -1564,6 +1623,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				A80E72482D3F4F0A00C64288 /* templates.json in Resources */,
+				A87587162D81734300286A66 /* text_to_photo_style.json in Resources */,
 				A8EEADD42D3E6C660032C5A0 /* Flower💐.json in Resources */,
 				A8EEADE92D3E76D90032C5A0 /* Beauty👸.json in Resources */,
 				A89EA6982D5B1A01000EB181 /* Butterfly🦋.json in Resources */,
@@ -1643,6 +1703,7 @@
 				A89EA6542D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift in Sources */,
 				A89EA6552D59A9F4000EB181 /* TSChatMessage.swift in Sources */,
 				A89EA6562D59A9F4000EB181 /* TSChatUser.swift in Sources */,
+				A80327C12D8157CB00AF7878 /* TSTitleView.swift in Sources */,
 				A89EA6582D59A9F4000EB181 /* TSLayoutSizeCalculator.swift in Sources */,
 				A89EA6592D59A9F4000EB181 /* CustomMessageFlowLayout.swift in Sources */,
 				A80E72792D42285500C64288 /* TSBootPageVC.swift in Sources */,
@@ -1664,6 +1725,7 @@
 				A89EA6BF2D5E03D6000EB181 /* Notification+Ex.swift in Sources */,
 				A8F774E12D38EA8C00AA6E93 /* TSFileManagerTool.swift in Sources */,
 				A80E73E42D533EB000C64288 /* TSPurchaseManager.swift in Sources */,
+				A80327C52D81584500AF7878 /* TSGeneralBtnView.swift in Sources */,
 				A8F7762F2D3A765400AA6E93 /* TSGenmojiViewModel.swift in Sources */,
 				A8F7751B2D38EC9800AA6E93 /* TSGenmojiVC.swift in Sources */,
 				A80EDD462D6C3F82003CD332 /* MarkdownEscaping.swift in Sources */,
@@ -1677,6 +1739,7 @@
 				A80EDD4F2D6C3F82003CD332 /* MarkdownParser+UIKit.swift in Sources */,
 				A80EDD502D6C3F82003CD332 /* MarkdownFont+Traits.swift in Sources */,
 				A80EDD512D6C3F82003CD332 /* MarkdownCode.swift in Sources */,
+				A875870F2D81689A00286A66 /* TSPTPEnterView.swift in Sources */,
 				A80EDD522D6C3F82003CD332 /* MarkdownCode+AppKit.swift in Sources */,
 				A80EDD532D6C3F82003CD332 /* MarkdownHeader.swift in Sources */,
 				A80EDD542D6C3F82003CD332 /* MarkdownQuote.swift in Sources */,
@@ -1710,6 +1773,7 @@
 				A8F7763F2D3B68E100AA6E93 /* TSGenmojiGennerateViewModel.swift in Sources */,
 				A80E72352D3F473400C64288 /* DiyPaperTemplateBaseView.swift in Sources */,
 				A80E72362D3F473400C64288 /* DiyPaperTemplate.swift in Sources */,
+				A80327C32D81581D00AF7878 /* TSTTPStyleView.swift in Sources */,
 				A85E47922D6728A00018D62D /* TSTextGeneralPictureVM.swift in Sources */,
 				A89EA6B82D5D7EE9000EB181 /* TSAIChatHistoryModel.swift in Sources */,
 				A80E72722D40F86000C64288 /* TSLaunchVC.swift in Sources */,
@@ -1726,6 +1790,7 @@
 				A80EDDE02D6EB1B9003CD332 /* TSPTPGeneratorCell.swift in Sources */,
 				A80EDDDB2D6EB0D0003CD332 /* Untitled.swift in Sources */,
 				A8F776352D3A7C2B00AA6E93 /* TSGenmojiColSectionView.swift in Sources */,
+				A80327B32D813D4900AF7878 /* TSTTPInputVC.swift in Sources */,
 				A80E724F2D3F6D7F00C64288 /* DiyFixedTextElement.swift in Sources */,
 				A85E478F2D67115A0018D62D /* TSTextGeneralPictureVC.swift in Sources */,
 				A89EA6C42D5F40CC000EB181 /* TSChatInputBarVC.swift in Sources */,
@@ -1740,6 +1805,7 @@
 				A80E72772D41EFF900C64288 /* TSEmojisTutorialsVC.swift in Sources */,
 				A8F776482D3DE9F600AA6E93 /* TSSmallIconBrowseCell.swift in Sources */,
 				A8F7753D2D3918F800AA6E93 /* TSNetWork+Business.swift in Sources */,
+				A80327BF2D81578900AF7878 /* TSPromptTextView.swift in Sources */,
 				A80EDE022D6F1CCD003CD332 /* TSPTPGeneratorVC.swift in Sources */,
 				A85E479F2D6859FA0018D62D /* TSRandomTextPicker.swift in Sources */,
 				A80E72262D3F3A9A00C64288 /* HYHAddImageView.m in Sources */,
@@ -1758,6 +1824,7 @@
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
 				A89EA66C2D59AA31000EB181 /* TSMessageContentCell.swift in Sources */,
+				A87587122D81702700286A66 /* TSUserDefaultData.swift in Sources */,
 				A89EA66D2D59AA31000EB181 /* TableViewCells.swift in Sources */,
 				A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */,
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
@@ -1768,7 +1835,6 @@
 				A8F7753F2D39340E00AA6E93 /* TSSetingVC.swift in Sources */,
 				A8F7762B2D3A70B200AA6E93 /* PaddedLabel.swift in Sources */,
 				A80E73E62D5348D000C64288 /* SettingPurchaseTopView.swift in Sources */,
-				A80EDDD92D6D9713003CD332 /* TSCustomStackView.swift in Sources */,
 				A80EDDE22D6EB8D8003CD332 /* TSPTPUploadCell.swift in Sources */,
 				A80EDDF62D6EC1ED003CD332 /* TSPhotoToPhotoVM.swift in Sources */,
 				A80E72382D3F473B00C64288 /* DiyPaperProtocol.swift in Sources */,
@@ -1779,10 +1845,12 @@
 				A89EA6C62D5F5C22000EB181 /* TSChatInputFullScreenVC.swift in Sources */,
 				A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */,
 				A85E479B2D6808C40018D62D /* TSBigIconBrowseVC.swift in Sources */,
+				A80327B62D813D8700AF7878 /* TSTTPInputVM.swift in Sources */,
 				A89EA6B12D5C9D0C000EB181 /* TSAIChatHistoryVC.swift in Sources */,
 				A8FB02B72D3E3A3D0031A396 /* TSEmojisChildViewModel.swift in Sources */,
 				A8F7754B2D39376800AA6E93 /* TSSettingListView.swift in Sources */,
 				A8F7748B2D38E8B700AA6E93 /* AppDelegate.swift in Sources */,
+				A80327B02D813A0200AF7878 /* TSTTPSelectStyleCell.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 6 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/ttp_selected_border@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_selected_border.imageset/ttp_selected_border@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/ttp_style_0@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_0.imageset/ttp_style_0@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/ttp_style_1@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_1.imageset/ttp_style_1@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/ttp_style_2@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_2.imageset/ttp_style_2@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/ttp_style_3@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_3.imageset/ttp_style_3@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/ttp_style_4@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_4.imageset/ttp_style_4@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/ttp_style_5@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_5.imageset/ttp_style_5@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/ttp_style_6@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_6.imageset/ttp_style_6@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/ttp_style_7@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_7.imageset/ttp_style_7@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/ttp_style_8@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_8.imageset/ttp_style_8@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/Contents.json

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

TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/ttp_style_9@2x.png


TEMPAT SAMPAH
AIEmoji/Assets.xcassets/Genmoji/ttp_style/ttp_style_9.imageset/ttp_style_9@3x.png


+ 1 - 1
AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift

@@ -62,7 +62,7 @@ extension TSAIChatVM {
         ]
 
         AiMDString = ""
-        streamRequest = TSNetworkShared.postStream(urlType: .chat,parameters: parameters) {[weak self] string in
+        streamRequest = TSNetworkShared.postStream(urlType: .chatV2,parameters: parameters) {[weak self] string in
             guard let self = self else { return }
             
             if AiMDString.count == 0 {

+ 75 - 0
AIEmoji/Business/Data/TSUserDefaultData.swift

@@ -0,0 +1,75 @@
+//
+//  TSUserDefaultData.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/5.
+//
+import ObjectMapper
+
+
+//海报历史记录
+class TSTextToPicHistory{
+    @UserDefault(key: "textPicHistoryListString", defaultValue: "")
+    static private var historyString: String
+    static var listModelArray: [TSGenmojiModel] = {
+        
+//        if UserDefaults.standard.string(forKey: "insertPosterExampleData") == nil {
+//            insertExampleData()
+//            UserDefaults.standard.set("1", forKey: "insertPosterExampleData")
+//            UserDefaults.standard.synchronize()
+//        }
+        
+        if let listModelArray = Mapper<TSGenmojiModel>().mapArray(JSONString: historyString){
+            return listModelArray
+        }
+        return []
+    }()
+    
+    static func saveModel(model:TSGenmojiModel){
+        listModelArray.insert(model, at: 0)
+        saveHistoryString()
+    }
+    
+    static func removeModel(model:TSGenmojiModel){
+        listModelArray.removeAll { $0 === model }
+        saveHistoryString()
+    }
+    
+    static func removeIndex(index:Int){
+        listModelArray.remove(at: index)
+        saveHistoryString()
+    }
+    
+    static func removeAll(){
+        listModelArray.removeAll()
+        saveHistoryString()
+    }
+    
+    static func saveHistoryString(){
+        if let jsonString = listModelArray.toJSONString() {
+            historyString = jsonString
+        }
+    }
+    
+//    private static func insertExampleData(){
+//        let array = [
+//            createExampleModel(imageName: "poster_example_0"),
+//            createExampleModel(imageName: "poster_example_1"),
+//            createExampleModel(imageName: "poster_example_2")
+//        ]
+//        if let jsonString = array.toJSONString() {
+//            historyString = jsonString
+//        }
+//    }
+    
+//    private static func createExampleModel(imageName:String)->TSActionInfoModel{
+//        let model = TSActionInfoModel()
+//        model.modelType = .example
+//        model.request.prompt = "Example"
+//        model.request.promptSort = "Example"
+//        model.request.width = kTextPicW
+//        model.request.height = kTextPicH
+//        model.response.resultUrl = imageName
+//        return model
+//    }
+}

+ 5 - 4
AIEmoji/Business/TSTabBarController/TSTabBarController.swift

@@ -24,17 +24,18 @@ class TSTabBarController: UITabBarController {
     }
 
     @objc private func setUpData() {
-        viewControllerArray = ["TSChatViewController", "TSTextGeneralPictureVC","TSEmojisVC","TSSetingVC"]
-        titleArray = ["Chat","Wallpaper","Emojis","Setting"]
+        viewControllerArray = ["TSTextGeneralPictureVC","TSChatViewController","TSEmojisVC","TSSetingVC"]
+//        viewControllerArray = ["TSTTPInputVC","TSChatViewController","TSEmojisVC","TSSetingVC"]
+        titleArray = ["Wallpaper","Chat","Emojis","Setting"]
         selectedImageArray = [
-            "tabbar_select_aichat",
             "tabbar_select_pic",
+            "tabbar_select_aichat",
             "tabbar_select_emoji",
             "tabbar_select_setting"
         ]
         unselectedImageArray = [
-            "tabbar_unSelect_aichat",
             "tabbar_unSelect_pic",
+            "tabbar_unSelect_aichat",
             "tabbar_unSelect_emoji",
             "tabbar_unSelect_setting"
         ]

+ 145 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift

@@ -0,0 +1,145 @@
+//
+//  TSTTPInputVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+class TSTTPInputVC: TSBaseVC {
+    
+    var viewH:CGFloat{
+        get {
+            if cusStackView.viewH > 0{
+                return cusStackView.viewH
+            }
+            return 647.0
+        }
+    }
+    
+    var reloadUIBlock:(()->Void)?
+    var jumpPTPBlock:(()->Void)?
+    lazy var viewModel: TSTTPInputVM = {
+        let viewModel:TSTTPInputVM = TSTTPInputVM()
+        viewModel.isCanGennerateBlock = { [weak self] enabled in
+            guard let self = self else { return }
+            creatBtnView.setBtnEnabled(isEnabled: enabled)
+        }
+        return viewModel
+    }()
+    
+    //###################################### cusStackView ######################################
+    lazy var cusStackView: TSCustomStackView = {
+        let cusStackView = TSCustomStackView(axis: .vertical,spacing: 8)
+        return cusStackView
+    }()
+    
+    //###################################### 输入框 ######################################
+    lazy var enterView: TSPTPEnterView = {
+        let enterView = TSPTPEnterView()
+        enterView.bannerBtn.addTarget(self, action: #selector(clickPTPEnterView), for: .touchUpInside)
+        return enterView
+    }()
+    
+    //###################################### 输入框 ######################################
+    lazy var promptTextView: TSPromptTextView = {
+        let promptTextView = TSPromptTextView(randomTextArray: kRandomTextArray) { [weak self] text in
+            guard let self = self else { return }
+            viewModel.promptText = text
+        }
+        return promptTextView
+    }()
+    
+    //###################################### Prompt类型 ######################################
+    lazy var promptStyleView: TSTTPStyleView = {
+        let promptStyleView = TSTTPStyleView()
+        promptStyleView.dataArray = viewModel.ptpStyleModels
+        promptStyleView.selectedValueBlock = { [weak self] model in
+            guard let self = self else { return }
+            viewModel.selectPromptModel = model
+        }
+        return promptStyleView
+    }()
+    
+    
+    //###################################### Button ######################################
+    lazy var creatBtnView:TSGeneralBtnView  = {
+        let creatBtnView = TSGeneralBtnView {[weak self] in
+            guard let self = self else { return }
+            generateImage()
+        }
+        creatBtnView.setBtnEnabled(isEnabled: false)
+        return creatBtnView
+    }()
+    
+    //###################################### Generate History ######################################
+    lazy var historyTitleView: TSTitleView = {
+        let historyTitleView = TSTitleView()
+        historyTitleView.titleLab.text = "Generate History".localized
+        return historyTitleView
+    }()
+    
+
+
+    override func createView() {
+        view.backgroundColor = .clear
+        
+        setNavBarViewHidden(true)
+    
+        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
+        tapGesture.cancelsTouchesInView = false
+        view.addGestureRecognizer(tapGesture)
+        
+        contentView.addSubview(cusStackView)
+        cusStackView.snp.makeConstraints { make in
+            make.top.leading.bottom.trailing.equalTo(0)
+        }
+
+        
+        cusStackView.addSubviewToStack(enterView)
+        cusStackView.addSubviewToStack(promptTextView)
+        
+        cusStackView.addSubviewToStack(promptStyleView)
+
+        cusStackView.addSubviewToStack(creatBtnView)
+        creatBtnView.snp.makeConstraints { make in
+            make.height.equalTo(creatBtnView.viewH)
+            make.width.equalTo(k_ScreenWidth)
+        }
+    }
+    
+    override func dealThings() {
+     
+    }
+    
+    @objc func clickView() {
+        view.endEditing(true)
+    }
+
+    @objc func clickCollectionView() {
+        view.endEditing(true)
+    }
+    
+    @objc func clickPTPEnterView() {
+        jumpPTPBlock?()
+    }
+    
+}
+
+extension TSTTPInputVC {
+    func generateImage() {
+        
+        //判断 vip
+        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .textGeneratePic) == false, vc: self) {[weak self] in
+            guard let self = self else { return }
+        }{ return }
+        
+        let gennerateVC = TSTextPicGennerateVC(aiText: viewModel.prompt) {[weak self] model in
+            guard let self = self else { return }
+            viewModel.saveModel(model: model)
+            reloadUIBlock?()
+        }
+        
+        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+    }
+
+}

+ 84 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/VM/TSTTPInputVM.swift

@@ -0,0 +1,84 @@
+//
+//  TSTTPInputVM.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+import ObjectMapper
+
+let kRandomTextToRintone:[String] = [
+    "Create a upbeat Pop ringtone with a catchy melody, bright synths, and a cheerful vibe. Use a BPM of 120-130 and keep it energetic and memorable.",
+    "Generate a cinematic ringtone with orchestral strings, powerful brass, and a dramatic build-up. Use a BPM of 60-80 for a grand, inspiring feel.",
+    "Produce a Lo-Fi ringtone with a relaxed piano melody, soft beats, and warm vinyl crackle. Use a BPM of 70-90 for a cozy, laid-back vibe.",
+    "Create a EDM ringtone with a pulsating bassline, uplifting synths, and a quick build-up. Use a BPM of 128-132 for a high-energy, festival-ready sound.",
+    "Generate a Jazz ringtone with a smooth saxophone melody, soft piano chords, and a gentle swing rhythm. Use a BPM of 90-100 for a classy, sophisticated tone.",
+    "Produce a Funk ringtone with a groovy bassline, rhythmic guitar chops, and punchy brass hits. Use a BPM of 100-110 for a lively, danceable vibe.",
+    "Create a Dubstep ringtone with heavy bass wobbles, aggressive synths, and a quick drop. Use a BPM of 140-150 for an intense, edgy sound.",
+    "Generate a Folk ringtone with a fingerpicked acoustic guitar melody and light percussion. Use a BPM of 80-90 for a warm, earthy feel.",
+    "Produce a Synthwave ringtone with retro arpeggiated synths, a driving beat, and an 80s-inspired vibe. Use a BPM of 100-110 for a nostalgic, futuristic tone.",
+    "Create a Techno ringtone with a repetitive bassline, crisp hi-hats, and subtle synth textures. Use a BPM of 125-130 for a sleek, modern sound.",
+]
+
+class TSTTPInputVM {
+    
+    //选择 prompt 类型组
+    lazy var ptpStyleModels: [TSPTPStyleModel] = {
+        var ptpStyleModels = [TSPTPStyleModel]()
+        if let dataArray = Mapper<TSPTPStyleModel>().mapArray(JSONfile: "text_to_photo_style.json"){
+            ptpStyleModels = dataArray
+            
+            if let model = dataArray.first {
+                selectPromptModel = model //加上默认的选择
+            }
+        }
+        
+        return ptpStyleModels
+    }()
+    
+    //输入框内容
+    var promptText:String = "" {
+        didSet{
+            isCanGennerateBlock?(isCanGennerate)
+        }
+    }
+    
+
+    //选择的 prompt 类型
+    var selectPromptModel:TSPTPStyleModel?{
+        didSet{
+            isCanGennerateBlock?(isCanGennerate)
+        }
+    }
+    
+    //可生成状态变化 block
+    var isCanGennerateBlock:((Bool)->Void)?
+}
+
+
+extension TSTTPInputVM {
+    //是否满足生成条件
+    var isCanGennerate:Bool {
+        if  selectPromptModel != nil ,
+            promptText.replacingOccurrences(of: " ", with: "").count > 0
+        {
+            return true
+        }
+        return false
+    }
+
+
+    var prompt:String{
+        var prompt = promptText
+        if let selectPromptModel = selectPromptModel {
+            prompt+=", \(selectPromptModel.prompt)"
+        }
+        return prompt
+    }
+
+    func saveModel(model:TSGenmojiModel){
+        TSTextToPicHistory.saveModel(model: model)
+    }
+}
+
+

+ 51 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSGeneralBtnView.swift

@@ -0,0 +1,51 @@
+//
+//  TSGeneralBtnView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+class TSGeneralBtnView: TSBaseView {
+
+    var viewH:CGFloat = 64
+    
+    var clickBlock:()->Void
+
+    init(clickBlock: @escaping () -> Void) {
+        self.clickBlock = clickBlock
+        super.init(frame: .zero)
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    //###################################### Button ######################################
+    lazy var creatBtn: UIButton = {
+        let submitBtn = kCreateNormalSubmitBtn(title: "Generate".localized) { [weak self]  in
+            guard let self = self else { return }
+            clickBlock()
+        }
+        submitBtn.cornerRadius = 24.0
+        submitBtn.isEnabled = false
+        return submitBtn
+    }()
+    
+
+
+    override func creatUI() {
+        
+        contentView.addSubview(creatBtn)
+        creatBtn.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(48)
+        }
+
+    }
+
+    func setBtnEnabled(isEnabled:Bool) {
+        creatBtn.isEnabled = isEnabled
+    }
+}

+ 22 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPTPEnterView.swift

@@ -0,0 +1,22 @@
+//
+//  TSPTPEnterView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/12.
+//
+
+class TSPTPEnterView : TSBaseView{
+    
+    lazy var bannerBtn: UIButton = {
+        let bannerBtn = UIButton.createButton(backgroundImage: UIImage(named: "ptp_banner"))
+        return bannerBtn
+    }()
+    
+    override func creatUI() {
+        contentView.addSubview(bannerBtn)
+        bannerBtn.snp.makeConstraints { make in
+            make.edges.equalTo(UIEdgeInsets(top: 17, left: 17, bottom: 0, right: 15))
+        }
+    }
+    
+}

+ 149 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPromptTextView.swift

@@ -0,0 +1,149 @@
+//
+//  TSPromptTextView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+class TSPromptTextView : TSBaseView{
+    
+    var randomTextArray:[String]
+    var textChangedBlock:((String)->Void)
+    
+    init(randomTextArray: [String], textChangedBlock: @escaping (String) -> Void) {
+        self.randomTextArray = randomTextArray
+        self.textChangedBlock = textChangedBlock
+        super.init(frame: .zero)
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    lazy var robotImageView: UIImageView = {
+        let robotImageView = UIImageView.createImageView(imageName: "aichat_avatar")
+        return robotImageView
+    }()
+    
+    
+    lazy var randomTextPicker: TSRandomTextPicker = {
+        let textPicker = TSRandomTextPicker(texts: kRandomTextArray)
+        return textPicker
+    }()
+    
+    lazy var textBgView: UIView = {
+        let textBgView = UIView()
+        textBgView.backgroundColor = "#333333".uiColor
+        textBgView.cornerRadius = 12
+        return textBgView
+    }()
+    
+    lazy var customTextView: TSPlaceholderTextView = {
+        let customTextView = TSPlaceholderTextView(
+            placeholder: "Type your idea here.",
+            text: "",
+            font: .font(size: 14),
+            textColor: .white,
+            backgroundColor: "#333333".uiColor
+        )
+        customTextView.delegate = self
+        customTextView.returnKeyType = .send
+        return customTextView
+    }()
+    
+    lazy var inspirationBtn: UIButton = {
+        let inspirationBtn = UIButton.createButton(
+            title: "Hint Inspiration".localized,
+            image: UIImage(named: "inspiration_yellow"),
+            backgroundColor:"#FECB34".uiColor.withAlphaComponent(0.1),
+            font: .font(size: 12),
+            titleColor: .themeColor,
+            corner: 8.0)
+        { [weak self]  in
+            guard let self = self else { return }
+            customTextView.text = randomTextPicker.getRandomText()
+            textViewDidChange(customTextView)
+        }
+        inspirationBtn.contentEdgeInsets = UIEdgeInsets(top: 4, left: 7, bottom: 4, right: 7)
+        inspirationBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: -4, bottom: 0, right: 0)
+        inspirationBtn.isHidden = false
+        return inspirationBtn
+    }()
+    
+    lazy var clearBtn: UIButton = {
+        let clearBtn = UIButton.createButton(
+            image: UIImage(named: "clear_text")
+        )
+        { [weak self]  in
+            guard let self = self else { return }
+            customTextView.text = ""
+            textViewDidChange(customTextView)
+        }
+        clearBtn.isHidden = true
+        return clearBtn
+    }()
+    
+    override func creatUI() {
+        
+        contentView.addSubview(robotImageView)
+        robotImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(16)
+            make.width.height.equalTo(82)
+        }
+        
+        contentView.addSubview(textBgView)
+        textBgView.snp.makeConstraints { make in
+            make.top.equalTo(57)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(182.0*kDesignScale)
+//            make.bottom.equalTo(-20)
+            make.bottom.equalTo(0)
+        }
+   
+        textBgView.addSubview(customTextView)
+        customTextView.snp.makeConstraints { make in
+            make.top.equalTo(21)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.bottom.equalTo(-21)
+        }
+        
+        textBgView.addSubview(inspirationBtn)
+        inspirationBtn.snp.makeConstraints { make in
+            make.height.equalTo(28)
+            make.bottom.equalTo(-16)
+            make.leading.equalTo(16)
+        }
+        
+        textBgView.addSubview(clearBtn)
+        clearBtn.snp.makeConstraints { make in
+            make.width.height.equalTo(16)
+            make.bottom.equalTo(-16)
+            make.trailing.equalTo(-16)
+        }
+
+    }
+
+    func getVipText()->String{
+        if kPurchaseDefault.isVip {
+            return "Generate"
+        }
+        return "Generate (\(kPurchaseDefault.freeNum(type: .generatePic)))"
+    }
+    
+}
+
+extension TSPromptTextView: UITextViewDelegate{
+    
+//    func textViewDidBeginEditing(_ textView: UITextView) {
+//        self.colComponent?.collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredVertically, animated: true)
+//    }
+    
+    func textViewDidChange(_ textView: UITextView) {
+        let text = textView.text.replacingOccurrences(of: " ", with: "")
+        clearBtn.isHidden = text.count > 0 ? false : true
+        textChangedBlock(textView.text)
+    }
+    
+}

+ 165 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTTPStyleView.swift

@@ -0,0 +1,165 @@
+//
+//  TSTTPStyleView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+class TSTTPStyleView:TSBaseView {
+    
+    var selectedValueBlock:((TSPTPStyleModel)->Void)?
+    
+    var dataArray: [TSPTPStyleModel] = [TSPTPStyleModel](){
+        didSet{
+            styleCollectionView.reloadData()
+            if dataArray.count > 0 {
+                self.styleCollectionView.selectItem(at: self.currentIndexPath, animated: true, scrollPosition: .centeredHorizontally)
+            }
+        }
+    }
+    
+    lazy var layout: UICollectionViewFlowLayout = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        layout.itemSize = CGSize(width: 100, height: 110)
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 0.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        return layout
+    }()
+    
+    
+    lazy var styleCollectionView: UICollectionView = {
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSPromptStyleViewCell.self, forCellWithReuseIdentifier: TSPromptStyleViewCell.cellID)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+
+    var currentIndexPath:IndexPath = IndexPath(item: 0, section: 0)
+    
+    
+    lazy var titleView: TSTitleView = {
+        let titleView = TSTitleView()
+        titleView.titleLab.text = "Genre".localized
+        return titleView
+    }()
+    
+    
+    override func creatUI() {
+        
+        let titleViewH = titleView.viewH
+        contentView.addSubview(titleView)
+        titleView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.trailing.equalTo(0)
+            make.height.equalTo(titleViewH)
+        }
+        
+        currentIndexPath = IndexPath(item: 0, section: 0)
+        contentView.addSubview(styleCollectionView)
+        styleCollectionView.snp.makeConstraints { make in
+            make.top.equalTo(titleView.snp.bottom)
+            make.leading.trailing.equalTo(0)
+            make.height.equalTo(110)
+            make.bottom.equalTo(0)
+        }
+    }
+    
+    func unCheck(){
+        styleCollectionView.deselectItem(at: currentIndexPath, animated: true)
+    }
+    
+}
+
+extension TSTTPStyleView: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return dataArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSPromptStyleViewCell.cellID, for: indexPath)
+        if let cell = cell as? TSPromptStyleViewCell,let itemModel = dataArray.safeObj(At: indexPath.item){
+            cell.itemModel = itemModel
+        }
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let model = dataArray.safeObj(At: indexPath.item){
+            currentIndexPath = indexPath
+            selectedValueBlock?(model)
+        }
+    }
+}
+
+class TSPromptStyleViewCell: TSBaseCollectionCell {
+    
+    static let cellID = "TSPromptStyleViewCell"
+
+    override var isSelected: Bool{
+        didSet{
+            boardImageView.isHidden = isSelected ? false : true
+        }
+    }
+    
+    var itemModel:TSPTPStyleModel = TSPTPStyleModel(){
+        didSet{
+            imageView.image = UIImage(named: itemModel.imageName)
+            textLabel.text = itemModel.imageText
+        }
+    }
+    
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView()
+        return imageView
+    }()
+    
+    lazy var boardImageView: UIImageView = {
+        let boardImageView = UIImageView.createImageView(imageName: "ttp_selected_border")
+        boardImageView.isHidden = true
+        return boardImageView
+    }()
+
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 14),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        return textLabel
+    }()
+    
+    override func creatUI() {
+        //cell 100*110
+   
+        bgContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalToSuperview()
+            make.width.height.equalTo(80)
+        }
+        
+        imageView.addSubview(boardImageView)
+        boardImageView.snp.makeConstraints { make in
+            make.top.bottom.leading.trailing.equalTo(0)
+        }
+ 
+        bgContentView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(imageView.snp.bottom).offset(4)
+            make.centerX.equalToSuperview()
+        }
+    }
+    
+}
+

+ 26 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTitleView.swift

@@ -0,0 +1,26 @@
+//
+//  TSTitleView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+
+class TSTitleView: TSBaseView {
+    
+    static let viewH:Float = 60.0
+    let viewH:Float = TSTitleView.viewH
+    
+    lazy var titleLab: UILabel = {
+        let titleLab = UILabel.createLabel(font: .font(size: 18),textColor: .white)
+        return titleLab
+    }()
+    
+    override func creatUI() {
+        contentView.addSubview(titleLab)
+        titleLab.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.centerY.equalToSuperview()
+        }
+    }
+}

+ 32 - 39
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/TSTextGeneralPictureVC.swift

@@ -55,33 +55,20 @@ class TSTextGeneralPictureVC: TSBaseVC {
         let layout = UICollectionViewFlowLayout()
         let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [ :])
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
-        cp.itemActionHandler = { [weak self] cellCp, indexPath in
-            guard let self = self else { return }
-           if let text = cellCp as? String ,indexPath == IndexPath(item: 0, section: 1) {
-                generateImage(text: text)
-            }
-        }
-        
+
         cp.sectionActionHandler = { [weak self] cellCp, indexPath in
             guard let self = self else { return }
             if let cmd = cellCp as? String, cmd == "delete"  {
                 showCustomAlert(message: "Are you sure to delete".localized, deleteHandler:  {
                     self.viewModel.removeAllHistoryList()
-                    self.collectionComponent.clear()
-                    self.collectionComponent.reloadView(with: self.viewModel.colDataArray)
+                    self.updateListView()
                 })
             }
         }
         
         cp.itemDidSelectedHandler = { [weak self] (object, indexPath) in
             guard let self = self else { return }
-
             if indexPath.section == 0{
-                kPushVC(target: self, modelVC: TSPhotoToPhotoVC())
-
-            }else if indexPath.section == 1{
-   
-            }else if indexPath.section == 2{
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
                     var dataModelArray:[TSGenmojiModel] = []
                     for itemModel in sections.items {
@@ -94,12 +81,26 @@ class TSTextGeneralPictureVC: TSBaseVC {
                     kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
                 }
             }
-            
         }
-
         return cp
     }()
 
+    
+    lazy var generalRintoneVC: TSTTPInputVC = {
+        let generalRintoneVC = TSTTPInputVC()
+        generalRintoneVC.reloadUIBlock = { [weak self]  in
+            guard let self = self else { return }
+            viewModel.updateRecentData()
+            updateListView()
+        }
+        
+        generalRintoneVC.jumpPTPBlock = { [weak self]  in
+            guard let self = self else { return }
+            kPushVC(target: self, modelVC: TSPhotoToPhotoVC())
+        }
+        return generalRintoneVC
+    }()
+    
     override func createView() {
     
         navBarContentView.addSubview(navBarView)
@@ -112,6 +113,16 @@ class TSTextGeneralPictureVC: TSBaseVC {
             make.edges.equalToSuperview()
         }
         
+        let vcViewH = generalRintoneVC.viewH
+        collectionComponent.collectionView.addSubview(generalRintoneVC.view)
+        collectionComponent.collectionView.contentInset = UIEdgeInsets(top: vcViewH, left: 0, bottom: 20, right: 0)
+        generalRintoneVC.view.snp.makeConstraints { make in
+            make.top.equalTo(-vcViewH)
+            make.leading.trailing.equalTo(0)
+            make.height.equalTo(vcViewH)
+        }
+        
+        
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickCollectionView))
         tapGesture.cancelsTouchesInView = false // 确保不影响其他点击事件
         collectionComponent.collectionView.addGestureRecognizer(tapGesture)
@@ -135,27 +146,9 @@ class TSTextGeneralPictureVC: TSBaseVC {
     @objc func clickCollectionView() {
         view.endEditing(true)
     }
-}
-
-extension TSTextGeneralPictureVC {
-    func generateImage(text:String) {
-        
-        //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .textGeneratePic) == false, vc: self) {[weak self] in
-            guard let self = self else { return }
-        }{ return }
-        
-        let gennerateVC = TSTextPicGennerateVC(aiText: text) {[weak self] model in
-            guard let self = self else { return }
-            if viewModel.saveModel(model:model) {
-                collectionComponent.clear()
-                collectionComponent.reloadView(with:viewModel.colDataArray)
-            }else{
-                collectionComponent.reloadData()
-            }
-        }
-        
-        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+    
+    func updateListView(){
+        self.collectionComponent.clear()
+        self.collectionComponent.reloadView(with: self.viewModel.colDataArray)
     }
-
 }

+ 148 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/View/TSTTPSelectStyleCell.swift

@@ -0,0 +1,148 @@
+//
+//  TSTTPSelectStyleCell.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/3/11.
+//
+
+class TSTTPSelectStyleCell : TSBaseCollectionCell{
+    var dataArray: [TSPTPStyleModel] = [TSPTPStyleModel](){
+        didSet{
+            styleCollectionView.reloadData()
+        }
+    }
+    
+    lazy var layout: UICollectionViewFlowLayout = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        layout.itemSize = CGSize(width: 100, height: 110)
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 0.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        return layout
+    }()
+    
+    lazy var styleCollectionView: UICollectionView = {
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSTTPSelectStyleCCell.self, forCellWithReuseIdentifier: TSTTPSelectStyleCCell.cellID)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+
+    var currentIndexPath:IndexPath = IndexPath(item: 0, section: 0)
+    
+    override func creatUI() {
+        currentIndexPath = IndexPath(item: 0, section: 0)
+        addSubview(styleCollectionView)
+        styleCollectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+    
+    func unCheck(){
+        styleCollectionView.deselectItem(at: currentIndexPath, animated: true)
+    }
+    
+    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
+        super.renderView(with: object, component: component, attributes: attributes)
+        if let itemModel = object as? TSGenmojiCoLItemModel{
+            dataArray = itemModel.ptpStyleModels
+            if self.dataArray.count > 0 {
+                kDelayMainShort{
+                    self.styleCollectionView.selectItem(at: self.currentIndexPath, animated: true, scrollPosition: .centeredHorizontally)
+                }
+            }
+        }
+    }
+}
+
+extension TSTTPSelectStyleCell: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return dataArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSTTPSelectStyleCCell.cellID, for: indexPath)
+        if let cell = cell as? TSTTPSelectStyleCCell,let itemModel = dataArray.safeObj(At: indexPath.item){
+            cell.itemModel = itemModel
+        }
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let model = dataArray.safeObj(At: indexPath.item){
+            currentIndexPath = indexPath
+            actionHandler(any: model)
+        }
+    }
+}
+
+class TSTTPSelectStyleCCell: TSBaseCollectionCell {
+    
+    static let cellID = "TSTTPSelectStyleCCell"
+
+    override var isSelected: Bool{
+        didSet{
+            boardImageView.isHidden = isSelected ? false : true
+        }
+    }
+    
+    var itemModel:TSPTPStyleModel = TSPTPStyleModel(){
+        didSet{
+            imageView.image = UIImage(named: itemModel.imageName)
+            textLabel.text = itemModel.imageText
+        }
+    }
+    
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView()
+        return imageView
+    }()
+    
+    lazy var boardImageView: UIImageView = {
+        let boardImageView = UIImageView.createImageView(imageName: "ptp_selected_border")
+        boardImageView.isHidden = true
+        return boardImageView
+    }()
+
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 14),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        return textLabel
+    }()
+    
+    override func creatUI() {
+        //cell 100*110
+   
+        bgContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalTo(0)
+            make.width.height.equalTo(80)
+        }
+        
+        imageView.addSubview(boardImageView)
+        boardImageView.snp.makeConstraints { make in
+            make.top.bottom.leading.trailing.equalTo(0)
+        }
+ 
+        bgContentView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(imageView.snp.bottom).offset(4)
+            make.centerX.equalTo(0)
+        }
+    }
+    
+}

+ 19 - 103
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift

@@ -7,8 +7,6 @@
 
 import ObjectMapper
 
-
-
 let kRandomTextArray:[String] = [
     "Ultra-detailed northern lights over a glacial lake, mirrored reflections with vibrant turquoise and magenta hues, surreal celestial atmosphere, digital painting style with soft glow effects.",
     "Neon-lit cyberpunk night market in a rainy Asian metropolis, holographic food stalls and floating drones, teal-orange color grading, retro-futuristic architecture with glowing Kanji signs",
@@ -26,124 +24,42 @@ let kRandomTextArray:[String] = [
 class TSTextGeneralPictureVM {
     var colDataArray:[TSComponent] = [TSComponent]()
 
-    
-    lazy var ptpEntranceSectionModel: TSGenmojiCoLSectionModel = {
-        let ptpEntranceSectionModel = TSGenmojiCoLSectionModel()
-        ptpEntranceSectionModel.style = .ptpEntrance
-        ptpEntranceSectionModel.name = ""
-        
-        let itemModel = TSGenmojiCoLItemModel()
-        itemModel.style = .ptpEntrance
-        ptpEntranceSectionModel.items = [itemModel]
-        
-        return ptpEntranceSectionModel
-    }()
-    
-    
-    lazy var generateSectionModel: TSGenmojiCoLSectionModel = {
-        let generateSectionModel = TSGenmojiCoLSectionModel()
-        generateSectionModel.style = .textPicGenerate
-        generateSectionModel.name = ""
-        
-        let itemModel = TSGenmojiCoLItemModel()
-        itemModel.style = .textPicGenerate
-        generateSectionModel.items = [itemModel]
-        
-        return generateSectionModel
-    }()
-    
-    //历史记录
-    @UserDefault(key: "textPicHistoryListString", defaultValue: "")
-    private var enmojiHistoryListString: String
-    
-    
-    lazy var listModelArray: [TSGenmojiModel] = {
-        if let listModelArray = Mapper<TSGenmojiModel>().mapArray(JSONString: enmojiHistoryListString){
-            return listModelArray
-        }
-        return []
-    }()
-    
     lazy var enmojiHistorySeciton: TSGenmojiCoLSectionModel = {
         let sectionModel = TSGenmojiCoLSectionModel()
         sectionModel.style = .textPicHistory
         sectionModel.name = "History".localized
-        for model in listModelArray {
-            let itemModel = TSGenmojiCoLItemModel()
-            itemModel.style = sectionModel.style
-            itemModel.dataModel = model
-            sectionModel.items.append(itemModel)
-        }
         return sectionModel
     }()
     
     init() {
-        combinedData()
+        updateRecentData()
     }
     
-    func combinedData(){
-        colDataArray.removeAll()
-        colDataArray.append(ptpEntranceSectionModel)
-        colDataArray.append(generateSectionModel)
-        
-        if enmojiHistorySeciton.items.count > 0 {
-            colDataArray.append(enmojiHistorySeciton)
+    
+    func updateRecentData() {
+        let listModelArray = TSTextToPicHistory.listModelArray
+        if listModelArray.count == 0 {
+            colDataArray = []
+        }else{
+            var array = [TSGenmojiCoLItemModel]()
+            listModelArray.forEach { model in
+                let itemModel = TSGenmojiCoLItemModel()
+                itemModel.dataModel = model
+                itemModel.style = .textPicHistory
+                array.append(itemModel)
+            }
+            enmojiHistorySeciton.items = array
+            
+            colDataArray = [enmojiHistorySeciton]
         }
     }
-    
+
 }
  
 extension TSTextGeneralPictureVM {
-    //历史记录
-    var modelArray:[TSGenmojiModel]{
-        get{
-            let sectionModel = TSGenmojiCoLSectionModel()
-            sectionModel.style = .textPicHistory
-            sectionModel.name = "History".localized
-        
-            if let modelArray = Mapper<TSGenmojiModel>().mapArray(JSONString: enmojiHistoryListString){
-                return modelArray
-            }
-            return []
-        }
-        set{
-            if let jsonString = newValue.toJSONString() {
-                enmojiHistoryListString = jsonString
-            }
-        }
-    }
-    
-    //返回值,是否需要清空后刷新
-    func saveModel(model:TSGenmojiModel)->Bool{
-        listModelArray.insert(model, at: 0)
-        if let jsonString = listModelArray.toJSONString() {
-            enmojiHistoryListString = jsonString
-        }
-        var isNeed = false
-        if enmojiHistorySeciton.items.count == 0 {
-            colDataArray.append(enmojiHistorySeciton)
-            isNeed = true
-        }
-          
-        let colItemModel = TSGenmojiCoLItemModel()
-        colItemModel.style = .textPicHistory
-        colItemModel.dataModel = model
-        enmojiHistorySeciton.items.insert(colItemModel, at: 0)
-        return isNeed
-    }
-    
-    
-    
     func removeAllHistoryList(){
-        listModelArray.removeAll()
-        if let jsonString = listModelArray.toJSONString() {
-            enmojiHistoryListString = jsonString
-        }
-        
-        enmojiHistorySeciton.items.removeAll()
-        colDataArray.removeLast()
+        TSTextToPicHistory.removeAll()
     }
-    
 }
 
 

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

@@ -16,6 +16,7 @@ enum TSNeURLType:String {
     case textPicCreate = "/api/image/create"     //文生图
     case upload = "/api/upload"                  //上传图片
     case imageRewrite = "/api/image/rewrite"     //图生图
+    case chatV2 = "/api/text/chat/v2"             //AI 对话接口V2,扩展了 DeepSeek 深度思考
     
     func getUrlString() -> String {
         return baseURL + self.rawValue

+ 1 - 1
AIEmoji/Common/NetworkManager/TSNetWork/TSNetworkManager.swift

@@ -60,7 +60,7 @@ class TSNetworkManager {
             case .stream(let result):
                 switch result {
                 case .success(let string):
-                    dePrint("Stream Received string: \(string)")
+                    dePrint("🚰🚰🚰Stream Received string string: \(string)")
                     streamHandler(string)
                 case .failure(let error):
                     dePrint("Stream error: \(error)")

+ 0 - 90
AIEmoji/Common/View/UIStackView/TSCustomStackView.swift

@@ -1,90 +0,0 @@
-//
-//  CustomStackView.swift
-//  TestUIKit
-//
-//  Created by 100Years on 2025/2/24.
-//
-
-import UIKit
-import SnapKit
-
-class TSCustomStackView: UIView {
-    // 内部的 UIStackView
-    private let stackView: UIStackView
-    
-    // 开放的属性,用于设置方向和间距
-    var axis: NSLayoutConstraint.Axis {
-        get {
-            return stackView.axis
-        }
-        set {
-            stackView.axis = newValue
-        }
-    }
-    
-    var spacing: CGFloat {
-        get {
-            return stackView.spacing
-        }
-        set {
-            stackView.spacing = newValue
-        }
-    }
-    
-    // 初始化方法
-    init(axis: NSLayoutConstraint.Axis = .vertical, spacing: CGFloat = 0) {
-        self.stackView = UIStackView()
-        self.stackView.axis = axis
-        self.stackView.spacing = spacing
-        self.stackView.alignment = .fill
-        self.stackView.distribution = .fill
-        super.init(frame: .zero)
-        setupUI()
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    // 设置 UI
-    private func setupUI() {
-        addSubview(stackView)
-        stackView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
-    }
-    
-    // 动态添加子视图的方法
-    func addSubviewToStack(_ view: UIView) {
-        stackView.addArrangedSubview(view)
-        // 可以根据需要对子视图进行额外的布局设置
-        view.snp.makeConstraints { make in
-            if axis == .vertical {
-                make.width.equalTo(stackView)
-            } else {
-                make.height.equalTo(stackView)
-            }
-        }
-    }
-    
-    
-    // 动态添加子视图的方法
-    func insertViewToStack(_ view: UIView, at stackIndex: Int){
-        stackView.insertArrangedSubview(view, at: 0)
-        // 可以根据需要对子视图进行额外的布局设置
-        view.snp.makeConstraints { make in
-            if axis == .vertical {
-                make.width.equalTo(stackView)
-            } else {
-                make.height.equalTo(stackView)
-            }
-        }
-    }
-        
-    func removeViewToStack(_ view: UIView){
-        stackView.removeArrangedSubview(view)
-        view.removeFromSuperview()
-    }
-        
-        
-}

+ 0 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/photo_to_photo_style.json → AIEmoji/Res/photo_to_photo_style.json


+ 0 - 0
AIEmoji/Business/TSWallpaperVC/Json/sticker.json → AIEmoji/Res/sticker.json


+ 0 - 0
AIEmoji/Business/TSWallpaperVC/Json/templates.json → AIEmoji/Res/templates.json


+ 63 - 0
AIEmoji/Res/text_to_photo_style.json

@@ -0,0 +1,63 @@
+[
+    {
+        "imageName": "ttp_style_0",
+        "imageText": "Pop Art",
+        "prompt":"Pop Art comic book style, bold color blocks of neon pink and electric blue, retro 1960s American diner scene with a jukebox and hamburger motifs, Roy Lichtenstein-inspired halftone dots and speech bubbles, glossy acrylic finish --stylize 850 --ar 3:2",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_1",
+        "imageText": "Graffiti",
+        "prompt":"Urban street art mural in Brooklyn style, spray-painted graffiti tags with dripping textures, vibrant turquoise and chrome silver palette, depicting a breakdancer mid-spin, social justice slogans in stencil fonts, raw concrete wall background --stylize 800 --ar 16:9",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_2",
+        "imageText": "Cyberpunk",
+        "prompt":"Cyberpunk dystopian cityscape, neon-lit rainy streets with holographic advertisements, cyborgs with glowing cybernetic implants, towering megastructures in chrome and matte black, Blade Runner 2049 cinematic lighting --stylize 900 --ar 21:9",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_3",
+        "imageText": "Abstract",
+        "prompt":"Abstract expressionist painting, Jackson Pollock-inspired drips and splatters of cadmium red and Prussian blue, dynamic impasto brushstrokes on raw canvas, chaotic yet balanced composition --stylize 750 --ar 1:1",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_4",
+        "imageText": "Retro Americana",
+        "prompt":"1950s American retro travel poster, vintage palette of mustard yellow and seafoam green, Route 66 highway with classic Chevrolet convertible, stylized typography 'Visit California', linen paper texture --stylize 700 --ar 4:3",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_5",
+        "imageText": "Lowbrow Art",
+        "prompt":"Lowbrow pop surrealism, tattoo-inspired design of a pin-up girl with octopus tentacles, hot rod flames and dice motifs, saturated colors with black outlines, Robert Williams comic grotesque style --stylize 820 --ar 2:1",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_6",
+        "imageText": "Photorealism",
+        "prompt":"Photorealistic portrait of a cowboy in Texas, hyper-detailed skin pores and denim fabric texture, golden hour sunlight casting long shadows on desert landscape, Hasselblad medium format film grain --stylize 950 --ar 5:4",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_7",
+        "imageText": "Vaporwave",
+        "prompt":"Vaporwave aesthetic, 80s Miami sunset with palm trees and Greek statues, CRT screen glitch effects, pastel pink and cyan gradients, retro computer UI elements floating in the air --stylize 780 --ar 16:10",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_8",
+        "imageText": "Comic",
+        "prompt":"Marvel comic book cover style, superheroine in dynamic pose with energy beams radiating from fists, Ben-Day dots shading, bold inking lines, Stan Lee signature logo at bottom --stylize 830 --ar 3:4",
+        "isVip": false
+    },
+    {
+        "imageName": "ttp_style_9",
+        "imageText": "Social Realism",
+        "prompt":"Social realism painting, Depression-era factory workers in muted brown tones, dramatic chiaroscuro lighting highlighting exhausted faces, dust and smoke textures, reminiscent of Diego Rivera murals --stylize 720 --ar 16:9",
+        "isVip": false
+    }
+]
+

+ 8 - 2
Podfile.lock

@@ -52,12 +52,16 @@ PODS:
   - RealmSwift (10.54.2):
     - Realm (= 10.54.2)
   - SnapKit (5.7.1)
+  - SVProgressHUD (2.3.1):
+    - SVProgressHUD/Core (= 2.3.1)
+  - SVProgressHUD/Core (2.3.1)
   - SwipeCellKit (2.7.1)
-  - TSSmalCoacopods (0.1.0):
+  - TSSmalCoacopods (1.0.0):
     - Alamofire
     - Kingfisher (= 7.10.0)
     - ObjectMapper (~> 4.2)
     - SnapKit
+    - SVProgressHUD
 
 DEPENDENCIES:
   - Alamofire
@@ -93,6 +97,7 @@ SPEC REPOS:
     - Realm
     - RealmSwift
     - SnapKit
+    - SVProgressHUD
     - SwipeCellKit
 
 EXTERNAL SOURCES:
@@ -118,8 +123,9 @@ SPEC CHECKSUMS:
   Realm: 16852517a207e98cc6acba9336b56c30d06d84ad
   RealmSwift: bca777b3904ee58a9b16036e1840012f03348060
   SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
+  SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
   SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
-  TSSmalCoacopods: 9a7d88d8a76e8317722e5247a6b3b89b0fe32982
+  TSSmalCoacopods: 6aa97167f0c76b16fc7d1fd1eb198bb6aece4f68
 
 PODFILE CHECKSUM: 5f1a9b50d5f2041d75518c8ffbc2f8cd02fa11a2