瀏覽代碼

feat:生成图片开发完毕

100Years 2 月之前
父節點
當前提交
65853d361f
共有 35 個文件被更改,包括 647 次插入304 次删除
  1. 28 8
      TSLiveWallpaper.xcodeproj/project.pbxproj
  2. 1 1
      TSLiveWallpaper/AppDelegate.swift
  3. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/Contents.json
  4. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/ai_delete@2x.png
  5. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/ai_delete@3x.png
  6. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/Contents.json
  7. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/btnImage_vip@2x.png
  8. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/btnImage_vip@3x.png
  9. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/Contents.json
  10. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/generator_failed@2x.png
  11. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/generator_failed@3x.png
  12. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/Contents.json
  13. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/network_error@2x.png
  14. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/network_error@3x.png
  15. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@2x.png
  16. 二進制
      TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@3x.png
  17. 9 20
      TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratorErrorView.swift
  18. 2 2
      TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratoringAnimationView.swift
  19. 17 16
      TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratorloadingView.swift
  20. 4 4
      TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift
  21. 16 17
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryCell.swift
  22. 55 38
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift
  23. 1 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift
  24. 231 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift
  25. 124 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/View/TSImageIPanComparisonView.swift
  26. 19 167
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift
  27. 19 7
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVM.swift
  28. 4 9
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift
  29. 6 6
      TSLiveWallpaper/Common/Purchase/TSPurchaseBusiness.swift
  30. 3 0
      TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift
  31. 6 1
      TSLiveWallpaper/Data/Model/TSActionInfoModel.swift
  32. 6 4
      TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift
  33. 2 3
      TSLiveWallpaper/Data/TSDBManager/TSDBManager.swift
  34. 6 0
      TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift
  35. 二進制
      TSLiveWallpaper/Resource/generat_loading.gif

+ 28 - 8
TSLiveWallpaper.xcodeproj/project.pbxproj

@@ -189,6 +189,9 @@
 		A86857D12DF977980089D222 /* TSAIListPhotoGeneratorVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857D02DF9778B0089D222 /* TSAIListPhotoGeneratorVM.swift */; };
 		A86857D32DF978740089D222 /* TSProgressState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857D22DF978730089D222 /* TSProgressState.swift */; };
 		A86857D52DF97A2A0089D222 /* TSAIExpandChangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */; };
+		A86857D72DF983620089D222 /* generat_loading.gif in Resources */ = {isa = PBXBuildFile; fileRef = A86857D62DF983620089D222 /* generat_loading.gif */; };
+		A86857DA2DF994600089D222 /* TSAIPhotoDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */; };
+		A86857DD2DF99C200089D222 /* TSImageIPanComparisonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857DC2DF99C200089D222 /* TSImageIPanComparisonView.swift */; };
 		A8C4C0982D242154003C46FC /* LivePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = A858EE162D1CF49B004B680F /* LivePhoto.swift */; };
 		A8C4C0A42D24218A003C46FC /* metadata.mov in Resources */ = {isa = PBXBuildFile; fileRef = A8C4C09E2D24218A003C46FC /* metadata.mov */; };
 		A8C4C0A52D24218A003C46FC /* Converter4Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8C4C09B2D24218A003C46FC /* Converter4Video.swift */; };
@@ -406,6 +409,9 @@
 		A86857D02DF9778B0089D222 /* TSAIListPhotoGeneratorVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListPhotoGeneratorVM.swift; sourceTree = "<group>"; };
 		A86857D22DF978730089D222 /* TSProgressState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSProgressState.swift; sourceTree = "<group>"; };
 		A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandChangeView.swift; sourceTree = "<group>"; };
+		A86857D62DF983620089D222 /* generat_loading.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = generat_loading.gif; sourceTree = "<group>"; };
+		A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoDetailsVC.swift; sourceTree = "<group>"; };
+		A86857DC2DF99C200089D222 /* TSImageIPanComparisonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSImageIPanComparisonView.swift; sourceTree = "<group>"; };
 		A8C4C0992D24218A003C46FC /* AVAssetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVAssetExtension.swift; sourceTree = "<group>"; };
 		A8C4C09A2D24218A003C46FC /* Converter4Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter4Image.swift; sourceTree = "<group>"; };
 		A8C4C09B2D24218A003C46FC /* Converter4Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter4Video.swift; sourceTree = "<group>"; };
@@ -785,7 +791,6 @@
 				A86857C12DF926EB0089D222 /* TSPhotoSizeHelper.swift */,
 				A86857A52DF920400089D222 /* ViewTool */,
 				A86857832DF81B510089D222 /* TSNetWork */,
-				A8F76C452D3510E700AA6E93 /* NetworkManager */,
 				A8F76C402D350A9600AA6E93 /* Purchase */,
 				A858EE182D1CF635004B680F /* ThirdParty */,
 				A81CA4882D15840F00A3AAC8 /* Tool */,
@@ -938,6 +943,7 @@
 		A81CA4B12D1695F300A3AAC8 /* Resource */ = {
 			isa = PBXGroup;
 			children = (
+				A86857D62DF983620089D222 /* generat_loading.gif */,
 				606372D62D545E55005C82CF /* Example */,
 				A81F5B502D19684D00740085 /* Json */,
 				A81CA4B22D1695F800A3AAC8 /* Font */,
@@ -1171,6 +1177,7 @@
 		A86857A92DF9210D0089D222 /* TSAIListVC */ = {
 			isa = PBXGroup;
 			children = (
+				A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */,
 				A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */,
 				A86857CD2DF9775D0089D222 /* TSAIPhotoGeneratorVC */,
 				A86857BA2DF926070089D222 /* TSAIListHistoryVC */,
@@ -1223,6 +1230,23 @@
 			path = TSAIPhotoGeneratorVC;
 			sourceTree = "<group>";
 		};
+		A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */ = {
+			isa = PBXGroup;
+			children = (
+				A86857DB2DF99C170089D222 /* View */,
+				A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */,
+			);
+			path = TSAIPhotoDetailsVC;
+			sourceTree = "<group>";
+		};
+		A86857DB2DF99C170089D222 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A86857DC2DF99C200089D222 /* TSImageIPanComparisonView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		A8C4C0A12D24218A003C46FC /* Util */ = {
 			isa = PBXGroup;
 			children = (
@@ -1293,13 +1317,6 @@
 			path = Purchase;
 			sourceTree = "<group>";
 		};
-		A8F76C452D3510E700AA6E93 /* NetworkManager */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = NetworkManager;
-			sourceTree = "<group>";
-		};
 		A8F778B52D1BE98D00BF55D5 /* TSLiveWallpaperBrowseVC */ = {
 			isa = PBXGroup;
 			children = (
@@ -1388,6 +1405,7 @@
 			files = (
 				606372D82D545E6C005C82CF /* Example Music.mp3 in Resources */,
 				A8C4C0A42D24218A003C46FC /* metadata.mov in Resources */,
+				A86857D72DF983620089D222 /* generat_loading.gif in Resources */,
 				A86857C62DF92BE70089D222 /* ZillaSlab-Bold.ttf in Resources */,
 				60553FC42D3B528A00BAAD7F /* IJKPlayer.md in Resources */,
 				609B6EA52D6F1221007942D4 /* Localizable.strings in Resources */,
@@ -1571,6 +1589,7 @@
 				60553F9C2D3B528A00BAAD7F /* BubbleMenuView.swift in Sources */,
 				60553F9D2D3B528A00BAAD7F /* SongListViewModel.swift in Sources */,
 				60553F9E2D3B528A00BAAD7F /* SearchResultStateView.swift in Sources */,
+				A86857DD2DF99C200089D222 /* TSImageIPanComparisonView.swift in Sources */,
 				60553F9F2D3B528A00BAAD7F /* FilterBarView.swift in Sources */,
 				60553FA02D3B528A00BAAD7F /* SongListViewController+Target.swift in Sources */,
 				60553FA12D3B528A00BAAD7F /* ToastView.swift in Sources */,
@@ -1591,6 +1610,7 @@
 				60553FAD2D3B528A00BAAD7F /* ImageTextControl.swift in Sources */,
 				60553FAE2D3B528A00BAAD7F /* CWProgressView.swift in Sources */,
 				60553FAF2D3B528A00BAAD7F /* TipsView.swift in Sources */,
+				A86857DA2DF994600089D222 /* TSAIPhotoDetailsVC.swift in Sources */,
 				60553FB02D3B528A00BAAD7F /* PlayMiniBar.swift in Sources */,
 				A86857CF2DF977640089D222 /* TSAIListPhotoGeneratorVC.swift in Sources */,
 				60553FB12D3B528A00BAAD7F /* SongDownloadCell.swift in Sources */,

+ 1 - 1
TSLiveWallpaper/AppDelegate.swift

@@ -18,7 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         window = UIWindow(frame: UIScreen.main.bounds)
-        window?.backgroundColor = UIColor.white
+        window?.backgroundColor = UIColor.black
         window?.makeKeyAndVisible()
         goToLoadVC()
         initBaseDatas()

+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/Contents.json

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

二進制
TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/ai_delete@2x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/ai_delete.imageset/ai_delete@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/Contents.json

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

二進制
TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/btnImage_vip@2x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/btnImage_vip.imageset/btnImage_vip@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/Contents.json

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

二進制
TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/generator_failed@2x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/generator_failed.imageset/generator_failed@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/Contents.json

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

二進制
TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/network_error@2x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/generator_network_error.imageset/network_error@3x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@2x.png


二進制
TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@3x.png


+ 9 - 20
TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratorErrorView.swift

@@ -44,6 +44,8 @@ class TSGeneratorErrorView: TSBaseView {
     lazy var submitBtn: UIButton = {
         let btn = UIButton.createButton(title: "Generate in the background".localized,backgroundImage: kSubmitBtnNormalbg,font: .font(size: 16),titleColor: "#111111".uiColor,corner: 24)
         btn.titleLabel?.adjustsFontSizeToFitWidth = true
+        btn.layer.borderColor = "#E4A858".uiCGColor
+        btn.layer.borderWidth = 1.0
         return btn
     }()
     
@@ -57,7 +59,7 @@ class TSGeneratorErrorView: TSBaseView {
         cusStackView.addArrangedSubview(errorImageView)
         errorImageView.snp.makeConstraints { make in
             make.top.equalTo(0)
-            make.width.height.equalTo(56)
+            make.width.height.equalTo(120)
         }
         
         cusStackView.addSpacing(length: 12.0)
@@ -87,11 +89,8 @@ extension TSGeneratorErrorView {
     
     func sensitiveErrorView() {
         submitBtn.setTitle(isUploadImage ? "Reselect photos".localized : "Got it".localized, for: .normal)
-        errorImageView.image = UIImage(named: "yellow_warning")
+        errorImageView.image = UIImage(named: "generator_failed")
         
-        errorImageView.snp.updateConstraints { make in
-            make.width.height.equalTo(56)
-        }
 
         textLabel.text = "Your photo may contain nudity, gore or violence that does not comply with the health policy, please replace the photo and try again.".localized
         
@@ -99,35 +98,25 @@ extension TSGeneratorErrorView {
     
     func generalErrorView() {
         submitBtn.setTitle("Got it".localized, for: .normal)
-        errorImageView.image = UIImage(named: "failed_big")
-        
-        errorImageView.snp.updateConstraints { make in
-            make.width.height.equalTo(120)
-        }
+        errorImageView.image = UIImage(named: "generator_failed")
         
+
         textLabel.text = "Sorry there was a slight problem with the image processing, please try again later.".localized
     }
     
     
     func netWorkErrorView() {
         submitBtn.setTitle("Try Again".localized, for: .normal)
-        errorImageView.image = UIImage(named: "network_error")
-        
-        errorImageView.snp.updateConstraints { make in
-            make.width.height.equalTo(120)
-        }
+        errorImageView.image = UIImage(named: "generator_network_error")
         
+
         textLabel.text = "No network, please check your network and try again.".localized
     }
     
     func generateTooMuchView() {
         submitBtn.setTitle("Got it".localized, for: .normal)
-        errorImageView.image = UIImage(named: "yellow_warning")
+        errorImageView.image = UIImage(named: "generator_failed")
         
-        errorImageView.snp.updateConstraints { make in
-            make.width.height.equalTo(56)
-        }
-
         textLabel.text = "Your photo may contain nudity, gore or violence that does not comply with the health policy, please replace the photo and try again.".localized
     }
 }

+ 2 - 2
TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratoringAnimationView.swift

@@ -27,7 +27,7 @@ class TSGeneratoringAnimationView : TSBaseView {
     lazy var animatedImageView: AnimatedImageView = {
         let animatedImageView = AnimatedImageView()
         animatedImageView.autoPlayAnimatedImage = false
-        if let gifURL = Bundle.main.url(forResource: "rotatingAnimation_1", withExtension: "gif") {
+        if let gifURL = Bundle.main.url(forResource: "generat_loading", withExtension: "gif") {
             animatedImageView.kf.setImage(with: gifURL, options: [.cacheOriginalImage]) { result in
                 switch result {
                 case .success(let value):
@@ -61,7 +61,7 @@ class TSGeneratoringAnimationView : TSBaseView {
     
     lazy var backgroundGenerateBtn: UIButton = {
         let btn = UIButton.createButton(title: "Generate in the background".localized,font: .font(size: 16),titleColor: .themeColor,corner: 24)
-        btn.layer.borderColor = UIColor.themeColor.cgColor
+        btn.layer.borderColor = "#E4A858".uiCGColor
         btn.layer.borderWidth = 1.0
         btn.titleLabel?.adjustsFontSizeToFitWidth = true
         btn.isHidden = true

+ 17 - 16
TSLiveWallpaper/Business/BusinessView/TSGeneratorloadingView/TSGeneratorloadingView.swift

@@ -25,7 +25,7 @@ class TSGeneratorView: TSBaseView {
     var style:Style = .generalError
     var clickBackstageBlock:(()->Void)?
     var clickErrorBlock:((Style)->Void)?
-    
+    var clickCloseBlock:(()->Void)?
     var isUploadImage:Bool = true{
         didSet {
             errorView.isUploadImage = isUploadImage
@@ -45,26 +45,28 @@ class TSGeneratorView: TSBaseView {
         return errorView
     }()
 
-    lazy var blurEffect: TSDynamicBlurView = {
-        return TSDynamicBlurView()
-    }()
+//    lazy var blurEffect: TSDynamicBlurView = {
+//        return TSDynamicBlurView()
+//    }()
     
     lazy var xBtn: UIButton = {
-        let xBtn = UIButton.createButton(image: UIImage(named: "close_gray")) { [weak self]  in
+        let xBtn = UIButton.createButton(image: .icClose) { [weak self]  in
             guard let self = self else { return }
-            self.isHidden = true
+            clickCloseBlock?()
         }
-        xBtn.isHidden = true
+  
         return xBtn
     }()
     
 
     override func creatUI() {
-        contentView.addSubview(blurEffect)
-        blurEffect.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
-
+//        contentView.addSubview(blurEffect)
+//        blurEffect.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
+        
+        self.backgroundColor = .black
+        
         contentView.addSubview(animationView)
         animationView.snp.makeConstraints { make in
             make.leading.trailing.centerY.equalToSuperview()
@@ -80,9 +82,9 @@ class TSGeneratorView: TSBaseView {
         contentView.addSubview(xBtn)
         xBtn.snp.makeConstraints { make in
             make.top.equalTo(k_Height_StatusBar + 4)
-            make.leading.equalTo(16)
-            make.width.equalTo(36)
-            make.height.equalTo(36)
+            make.trailing.equalTo(-16)
+            make.width.equalTo(24)
+            make.height.equalTo(24)
         }
     }
     
@@ -141,7 +143,6 @@ class TSGeneratorView: TSBaseView {
     }
 
     func setBackgroundColor(color:UIColor){
-        blurEffect.removeFromSuperview()
         contentView.backgroundColor = color
     }
     

+ 4 - 4
TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift

@@ -5,10 +5,10 @@
 //  Created by 100Years on 2025/6/10.
 //
 
-enum TSGeneratorImageStyle {
-    case enhance    //照片变高清
-    case colorize    //黑白变颜色
-    case descratch    //旧照片修复
+enum TSGeneratorImageStyle:String {
+    case enhance = "enhance"   //照片变高清
+    case colorize = "colorize"   //黑白变颜色
+    case descratch = "descratch"   //旧照片修复
 
     var imageMaxKb:Int{
         switch self {

+ 16 - 17
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryCell.swift

@@ -4,27 +4,25 @@
 //
 //  Created by 100Years on 2025/6/10.
 //
-
-class TSAIListHistoryCell: TSBaseCollectionCell,TSSimpleConfigurableView {
-    weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
-    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
-    var data: Any? {
+import RealmSwift
+class TSAIListHistoryCell: TSBaseCollectionCell {
+    var data:TSDBActionInfoModel?{
         didSet {
 //            debugPrint("TSAIListHistoryBaseCell data didSet")
-            if let dataModel = data as? TSActionInfoModel{
+            if let dataModel = data{
                 videoIconImageView.isHidden = true
                 exampleView.isHidden = true
-                if dataModel.modelType == .example {
+                if dataModel.modelType == 1 {
                     textLabel.text = "Example".localized
                     exampleView.isHidden = false
-                    showImageView.image = UIImage(named: dataModel.response.resultUrl)
+                    showImageView.image = UIImage(named: dataModel.response!.resultUrl)
                 }else{
-                    if dataModel.isVideo {
-                        videoIconImageView.isHidden = false
-                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoThumbnailURL.path)
-                    }else {
-                        showImageView.setAsyncImage(urlString: dataModel.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
-                    }
+//                    if dataModel.isVideo {
+//                        videoIconImageView.isHidden = false
+//                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoThumbnailURL.path)
+//                    }else {
+                        showImageView.setAsyncImage(urlString: dataModel.response!.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+//                    }
                 }
             }
         }
@@ -48,14 +46,12 @@ class TSAIListHistoryCell: TSBaseCollectionCell,TSSimpleConfigurableView {
             make.top.edges.equalTo(UIEdgeInsets(top: 4, left: 6, bottom: 4, right: 6))
         }
         exampleView.isHidden = true
-        exampleView.cornerRadius = 10.0
         return exampleView
     }()
     
     lazy var showImageView: UIImageView = {
         let showImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
         showImageView.backgroundColor = .gray
-        showImageView.layer.cornerRadius = 18
         return showImageView
     }()
     
@@ -67,7 +63,10 @@ class TSAIListHistoryCell: TSBaseCollectionCell,TSSimpleConfigurableView {
     
     
     override func creatUI() {
-//        debugPrint("TSAIListHistoryBaseCell creatUI")
+
+        contentView.layer.borderWidth = 3
+        contentView.layer.borderColor = "#DFD7C0".uiCGColor
+        
         contentView.addSubview(showImageView)
         showImageView.snp.makeConstraints { make in
             make.top.equalTo(0)

+ 55 - 38
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift

@@ -5,31 +5,38 @@
 //  Created by 100Years on 2025/6/10.
 //
 
+import RealmSwift
 
 class TSAIListHistoryVC: TSBaseVC {
 
-    var listModelArray: [TSActionInfoModel] = []
+    var listModelArray:List<TSDBActionInfoModel> = List<TSDBActionInfoModel>()
     //###################################### 集合视图 ######################################
     let collectionViewBtootm:CGFloat = 80
-    lazy var collectionView: TSSimpleCollectionView = {
-        let identifier = "TSAIListHistoryCell"
+
+    let identifier = "TSAIListHistoryCell"
+    lazy var collectionView: UICollectionView = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
         
         let itemW = (k_ScreenWidth-32.0-12.0-2.0)/2.0
-        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 293.0), width: itemW)
+        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 220.0), width: itemW)
+
+        layout.itemSize = CGSize(width: itemW, height: itemH)
+        layout.minimumInteritemSpacing = 8
+        layout.minimumLineSpacing = 8
+        layout.sectionInset = UIEdgeInsets(top: 10, left: 16, bottom: k_Height_TabBar+20, right: 16)
         
-        let layout = UICollectionViewFlowLayout()
-        let cp = TSSimpleCollectionView()
-        cp.layout.itemSize = CGSize(width: itemW, height: itemH)
-        cp.layout.minimumLineSpacing = 12
-        cp.layout.minimumInteritemSpacing = 12
-        cp.delegate = self
-        cp.collectionView.contentInset = UIEdgeInsets(top: 16, left: 16, bottom: collectionViewBtootm, right: 16)
-        cp.registerCell(TSAIListHistoryCell.self,identifier:identifier)
-        cp.cellIdentifierForItem = { data in
-            return identifier
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSAIListHistoryCell.self, forCellWithReuseIdentifier: identifier)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
         }
-
-        return cp
+        return collectionView
     }()
     
     lazy var pageNullView: TSPageNullView = {
@@ -61,15 +68,17 @@ class TSAIListHistoryVC: TSBaseVC {
     }
     
     func updateDataView(){
-        dbHistory.getModelList { [weak self] array in
-            guard let self = self else { return }
-            listModelArray = array
-            updateView()
-        }
+//        dbHistory.getModelList { [weak self] array in
+//            guard let self = self else { return }
+//            listModelArray = array
+//            updateView()
+//        }
+        listModelArray = dbHistory.listModels
+        updateView()
     }
     
     func updateView() {
-        collectionView.reload(with:[TSSimpleSectionData(items: listModelArray)])
+        collectionView.reloadData()
         
         navRightBtn.isHidden = listModelArray.count <= 0
         pageNullView.isHidden = listModelArray.count > 0
@@ -83,28 +92,36 @@ class TSAIListHistoryVC: TSBaseVC {
     }
     
 }
+extension TSAIListHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
 
-extension TSAIListHistoryVC: TSSimpleCollectionViewDelegate {
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return listModelArray.count
+    }
     
-    func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
-        switch event.action {
-//        case .tap:
-//            let browseVC = TSAIPhotoBrowseVC()
-//            browseVC.dataModelArray = listModelArray
-//            browseVC.currentIndex = event.indexPath.item
-//            browseVC.deleteComplete = { [weak self]  deleteModel in
-//                guard let self = self else { return }
-//                dbHistory.deleteListModel(id: deleteModel.id)
-//                updateDataView()
-//            }
-//            kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
-        default:
-            break
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
+        if let cell = cell as? TSAIListHistoryCell {
+            if let dbModel = listModelArray[safe: indexPath.row]{
+                cell.data = dbModel
+            }
+        }
+        
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+
+        if let dbModel = listModelArray[safe: indexPath.row]{
+            let vc = TSAIPhotoDetailsVC()
+            vc.imageModel = dbModel.getModel()
+            kPushVC(target: self, modelVC: vc)
         }
     }
-    
 }
 
+
 extension TSAIListHistoryVC{
     func removeAllHistoryList(){
         dbHistory.delete()

+ 1 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift

@@ -88,7 +88,7 @@ class TSAIListVC: TSBaseVC {
         recordBtn.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.trailing.equalTo(-16)
-           make.width.height.equalTo(24)
+           make.width.height.equalTo(36)
        }
        
        return navBarView

+ 231 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift

@@ -0,0 +1,231 @@
+//
+//  TSAIPhotoDetailsVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/11.
+//
+
+class TSAIPhotoDetailsVC: TSBaseVC {
+    
+    var imageModel:TSActionInfoModel?{
+        didSet{
+            updateImageView()
+        }
+    }
+
+    lazy var bottomViewH = 60+k_Height_safeAreaInsetsBottom()
+//    lazy var netWorkImageView: UIImageView = {
+//        let netWorkImageView = UIImageView(frame: CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight-bottomViewH))
+//        netWorkImageView.backgroundColor = "#111111".uiColor
+//        netWorkImageView.contentMode = .scaleAspectFit
+//        netWorkImageView.isUserInteractionEnabled = true
+//        return netWorkImageView
+//    }()
+    
+    lazy var panComparisonView : TSImageIPanComparisonView = {
+        let panComparisonView = TSImageIPanComparisonView()
+        return panComparisonView
+    }()
+    
+    lazy var expandAreaView: TSAIExpandChangeView = {
+        let view = TSAIExpandChangeView()
+        return view
+    }()
+    
+    lazy var switchOriginalPictureBtn: TSUIExpandedTouchButton = {
+        let switchOriginalPictureBtn = TSUIExpandedTouchButton()
+        switchOriginalPictureBtn.setUpButton(image:UIImage(named: "switch_original_picture"))
+        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchDown), for: .touchDown)
+        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchUp), for: [.touchUpInside, .touchUpOutside, .touchCancel])
+        switchOriginalPictureBtn.isHidden = true
+        return switchOriginalPictureBtn
+    }()
+    
+//    lazy var rotatingPictureBtn: TSUIExpandedTouchButton = {
+//        let rotatingPictureBtn = TSUIExpandedTouchButton()
+//        rotatingPictureBtn.setUpButton(image:UIImage(named: "rotating_picture")){ [weak self]  in
+//            guard let self = self else { return }
+//            //旋转图片并储存
+//            if let image = netWorkImageView.image?.rotated(by: .degrees90) {
+//                netWorkImageView.image = image
+//                if let resultUrl = self.imageModel?.response.resultUrl,
+//                   let url = URL(string: resultUrl){
+//                    ImageCache.default.store(image, forKey: url.cacheKey)
+//                }
+//            }
+//        }
+//        rotatingPictureBtn.isHidden = true
+//        return rotatingPictureBtn
+//    }()
+    
+    
+    lazy var saveBtn: UIButton = {
+        let saveBtn = kCreateNormalSubmitBtn(title: "Save".localized) { [weak self]  in
+            guard let self = self else { return }
+            clickSaveBtn()
+        }
+        return saveBtn
+    }()
+    
+    override func createView() {
+        
+        let imageView = UIImageView.createImageView(image: .navShadow,contentMode: .scaleToFill)
+        navBarContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        addNormalNavBarView()
+        setPageTitle("Result".localized)
+        contentView.snp.updateConstraints { make in
+            make.top.equalTo(0)
+        }
+
+        contentView.addSubview(panComparisonView)
+        panComparisonView.snp.makeConstraints { make in
+            make.height.equalTo(k_ScreenHeight)
+            make.leading.trailing.equalTo(0)
+            make.centerY.equalToSuperview()
+        }
+        
+        contentView.addSubview(saveBtn)
+        saveBtn.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.width.equalTo(250*kDesignScale)
+            make.height.equalTo(48)
+            make.bottom.equalTo(-12-k_Height_safeAreaInsetsBottom())
+        }
+        
+        contentView.addSubview(switchOriginalPictureBtn)
+        switchOriginalPictureBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
+            make.trailing.equalTo(-16)
+            make.width.equalTo(40)
+            make.height.equalTo(40)
+        }
+        
+//        contentView.addSubview(rotatingPictureBtn)
+//        rotatingPictureBtn.snp.makeConstraints { make in
+//            make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
+//            make.trailing.equalTo(-16)
+//            make.width.equalTo(40)
+//            make.height.equalTo(40)
+//        }
+        
+        saveBtn.setTitleImageSpace(spacing: 0)
+        
+//        if viewModel.generatorModel.generatorStyle == .photoExpand {
+//            setUpExpandAreaView()
+//        }
+
+    }
+    
+//    func setUpExpandAreaView(){
+//        netWorkImageView.addSubview(expandAreaView)
+//        expandAreaView.snp.makeConstraints { make in
+//            make.top.leading.trailing.bottom.equalTo(0)
+//        }
+//
+//        expandAreaView.showImageView.isHidden = true
+//        expandAreaView.boardView.isHidden = true
+//
+//        if let sizes = self.viewModel.generatorModel.expandViewSizes {
+//            expandAreaView.updateExpandAreaView(width: sizes.0.width, height: sizes.0.height)
+//            expandAreaView.updateImageView(width: sizes.1.width, height: sizes.1.height)
+//        }
+//    }
+
+    //保存功能
+    @objc func clickSaveBtn(){
+        guard let imageModel = imageModel else { return }
+//        if viewModel.generatorModel.generatorStyle == .photoLive{
+//            TSDownloadManager.getDownLoadVideo(urlString: imageModel.response.resultUrl) { url, success in
+//                if let url = url {
+//                    PhotoManagerShared.saveVideoToAlbum(videoURL: url) { [weak self] success, error in
+//                        guard let self = self else { return }
+//                        if success {
+//                            isSavePhotoMark = true
+//                            kSaveSuccesswShared.show(atView:self.view)
+//                        }else{
+//                            debugPrint(error)
+//                        }
+//                    }
+//                }
+//            }
+//        }else{
+            UIImageView.downloadImageWithProgress(urlString: imageModel.response.resultUrl) { image in
+                if let image = image {
+                    PhotoManagerShared.saveImageToAlbum(image) { [weak self] success, error in
+                        guard let self = self else { return }
+                        if success {
+                            kSaveSuccesswShared.show(atView:self.view)
+                        }else{
+                            debugPrint(error)
+                        }
+                    }
+                }
+            }
+//        }
+    }
+    
+}
+
+
+extension TSAIPhotoDetailsVC {
+    
+    
+    func updateImageView(){
+        
+        uploadPanComparisonView()
+        
+//        self.netWorkImageView.setAsyncImage(urlString:imageModel.response.resultUrl,placeholder:kPlaceholderImage)
+    }
+    
+    func uploadPanComparisonView(){
+        guard let imageModel = imageModel else { return }
+        var oldImage:UIImage?
+        var newImage:UIImage?
+        let grounp = DispatchGroup()
+        grounp.enter()
+        UIImageView.downloadImageWithProgress(urlString: imageModel.request.imageUrl) { image in
+            grounp.leave()
+            oldImage = image
+            
+        }
+        
+        grounp.enter()
+        UIImageView.downloadImageWithProgress(urlString: imageModel.response.resultUrl) { image in
+            grounp.leave()
+            newImage = image
+        }
+        
+        grounp.notify(queue: .main) {
+            if let oldImage = oldImage,let newImage = newImage {
+                let size = oldImage.size.height > newImage.size.height ? oldImage.size : newImage.size
+                self.panComparisonView.snp.updateConstraints { make in
+                    make.height.equalTo(kGetUIWdith(designSize: size, currentW: k_ScreenWidth))
+                }
+            }
+            
+            self.panComparisonView.configure(oldImage: oldImage, newImage: newImage)
+        }
+    }
+    @objc func switchOriginalPictureTouchDown() {
+//        if viewModel.generatorModel.generatorStyle == .photoExpand {
+//            expandAreaView.onlyBgImage(only: false)
+//        }else{
+//        guard let imageModel = imageModel else { return }
+//        self.netWorkImageView.setAsyncImage(urlString: imageModel.request.imageUrl,placeholder:kPlaceholderImage)
+//        }
+    }
+    
+    @objc func switchOriginalPictureTouchUp() {
+        guard let imageModel = imageModel else { return }
+        
+//        if viewModel.generatorModel.generatorStyle == .photoExpand {
+//            expandAreaView.onlyBgImage(only: true)
+//        }else{
+//            self.netWorkImageView.setAsyncImage(urlString:imageModel.response.resultUrl,placeholder:kPlaceholderImage)
+//        }
+    }
+}

+ 124 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/View/TSImageIPanComparisonView.swift

@@ -0,0 +1,124 @@
+//
+//  TSImageIPanComparisonView.swift
+//  testApp
+//
+//  Created by 100Years on 2025/5/11.
+//
+
+import UIKit
+
+class TSImageIPanComparisonView: UIView {
+    // MARK: - 属性
+    let oldImageView = UIImageView()
+    let newImageView = UIImageView()
+    private let lineView = UIView()
+
+    private var maskLayer = CAShapeLayer()
+ 
+    // MARK: - 初始化
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupViews()
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        setupViews()
+    }
+    
+    lazy var lineX:CGFloat = self.bounds.size.width/2.0 {
+        didSet{
+            updateView()
+        }
+    }
+    
+    
+    // MARK: - 视图设置
+    private func setupViews() {
+        // 旧图片视图(初始显示)
+        oldImageView.contentMode = .scaleAspectFill
+        oldImageView.clipsToBounds = true
+        addSubview(oldImageView)
+        
+        // 新图片视图(初始隐藏)
+        newImageView.contentMode = .scaleAspectFill
+        newImageView.clipsToBounds = true
+        addSubview(newImageView)
+        
+        // 分割线样式
+        lineView.backgroundColor = .white
+        lineView.isHidden = true
+        addSubview(lineView)
+        
+        let leftRigntImageView = UIImageView.createImageView(image: .leftContrastRight)
+        addSubview(leftRigntImageView)
+        leftRigntImageView.snp.makeConstraints { make in
+            make.center.equalTo(lineView.snp.center)
+        }
+
+        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
+        addGestureRecognizer(panGesture)
+      
+    }
+    
+    // 处理拖动手势
+    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
+    
+        // 获取手指在视图中的移动距离(相对起点)
+        let translation = gesture.translation(in: self)
+        if translation.x > 0 {
+            print("向右移动: \(translation.x) 像素")
+            lineX = min(lineX + translation.x, self.width)
+        } else if translation.x < 0 {
+            lineX = max(lineX + translation.x, 0)
+            print("向左移动: \(translation.x) 像素")
+        }
+        gesture.setTranslation(.zero, in: self) // 重置位移
+    }
+
+
+    // MARK: - 布局
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        oldImageView.frame = bounds
+        newImageView.frame = bounds
+        lineView.frame = CGRect(x: lineX, y: 0, width: 1, height: bounds.height)
+    }
+    
+    // MARK: - 公开方法
+    func configure(oldImage: UIImage?, newImage: UIImage?) {
+        oldImageView.image = oldImage
+        newImageView.image = newImage
+        lineView.isHidden = false
+        updateView()
+    }
+    
+    func configure(oldImageURLString: String, newImageURLString: String) {
+        oldImageView.setAsyncImage(urlString: oldImageURLString)
+        newImageView.setAsyncImage(urlString: newImageURLString)
+        lineView.isHidden = false
+        updateView()
+    }
+ 
+    // MARK: - 动画更新
+    @objc private func updateView() {
+        let x = lineX
+        let frame = CGRect(
+            x: x,
+            y: 0,
+            width: bounds.width - x,
+            height: bounds.height
+        )
+        let path = UIBezierPath(rect: frame)
+        
+        // 更新分割线位置
+        lineView.frame.origin.x = x
+//        print("frame=\(frame)")
+        
+    
+        maskLayer.path = path.cgPath
+        newImageView.layer.mask = maskLayer
+
+    }
+
+}

+ 19 - 167
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift

@@ -33,7 +33,7 @@ struct TSAIListPhotoGeneratorModel {
     }
 }
 
-class TSAIListPhotoGeneratorVC: TSBaseVC {
+class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
 
     init(generatorModel:TSAIListPhotoGeneratorModel,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.complete = complete
@@ -44,7 +44,6 @@ class TSAIListPhotoGeneratorVC: TSBaseVC {
         fatalError("init(coder:) has not been implemented")
     }
     
-    var imageModel:TSActionInfoModel?
     var complete:((TSActionInfoModel)->Void)
     var progressState = TSProgressState.none
     
@@ -57,16 +56,7 @@ class TSAIListPhotoGeneratorVC: TSBaseVC {
     }
     
     var viewModel: TSAIListPhotoGeneratorBaseVM!
-//    var videoPlayerVC: TSAIListVideoPlayerVC = TSAIListVideoPlayerVC(videoURL: URL(string: "www.baidu.com")!)
-    lazy var bottomViewH = 60+k_Height_safeAreaInsetsBottom()
-    lazy var netWorkImageView: UIImageView = {
-        let netWorkImageView = UIImageView(frame: CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight-bottomViewH))
-        netWorkImageView.backgroundColor = "#111111".uiColor
-        netWorkImageView.contentMode = .scaleAspectFit
-        netWorkImageView.isUserInteractionEnabled = true
-        return netWorkImageView
-    }()
-    
+
     lazy var generateInView : TSGeneratorView = {
         let generateInView = TSGeneratorView()
         generateInView.isUploadImage = false
@@ -83,97 +73,24 @@ class TSAIListPhotoGeneratorVC: TSBaseVC {
             }
         }
         
-        
-        return generateInView
-    }()
-    
-    lazy var expandAreaView: TSAIExpandChangeView = {
-        let view = TSAIExpandChangeView()
-        return view
-    }()
-    
-    lazy var switchOriginalPictureBtn: TSUIExpandedTouchButton = {
-        let switchOriginalPictureBtn = TSUIExpandedTouchButton()
-        switchOriginalPictureBtn.setUpButton(image:UIImage(named: "switch_original_picture"))
-        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchDown), for: .touchDown)
-        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchUp), for: [.touchUpInside, .touchUpOutside, .touchCancel])
-        switchOriginalPictureBtn.isHidden = true
-        return switchOriginalPictureBtn
-    }()
-    
-//    lazy var rotatingPictureBtn: TSUIExpandedTouchButton = {
-//        let rotatingPictureBtn = TSUIExpandedTouchButton()
-//        rotatingPictureBtn.setUpButton(image:UIImage(named: "rotating_picture")){ [weak self]  in
-//            guard let self = self else { return }
-//            //旋转图片并储存
-//            if let image = netWorkImageView.image?.rotated(by: .degrees90) {
-//                netWorkImageView.image = image
-//                if let resultUrl = self.imageModel?.response.resultUrl,
-//                   let url = URL(string: resultUrl){
-//                    ImageCache.default.store(image, forKey: url.cacheKey)
-//                }
-//            }
-//        }
-//        rotatingPictureBtn.isHidden = true
-//        return rotatingPictureBtn
-//    }()
-    
-    
-    lazy var saveBtn: UIButton = {
-        let saveBtn = kCreateNormalSubmitBtn(title: "Save".localized) { [weak self]  in
+        generateInView.clickCloseBlock = { [weak self]  in
             guard let self = self else { return }
-            clickSaveBtn()
+            closePage()
         }
-        return saveBtn
+        return generateInView
     }()
     
-    override func createView() {
 
-        contentView.addSubview(generateInView)
-        generateInView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
+    override func createView() {
         
         super.createView()
         
-        contentView.addSubview(switchOriginalPictureBtn)
-        switchOriginalPictureBtn.snp.makeConstraints { make in
-            make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
-            make.trailing.equalTo(-16)
-            make.width.equalTo(40)
-            make.height.equalTo(40)
+        view.addSubview(generateInView)
+        generateInView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
         }
-        
-//        contentView.addSubview(rotatingPictureBtn)
-//        rotatingPictureBtn.snp.makeConstraints { make in
-//            make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
-//            make.trailing.equalTo(-16)
-//            make.width.equalTo(40)
-//            make.height.equalTo(40)
-//        }
-        
-        saveBtn.setTitleImageSpace(spacing: 0)
-        
-//        if viewModel.generatorModel.generatorStyle == .photoExpand {
-//            setUpExpandAreaView()
-//        }
-
     }
-    
-//    func setUpExpandAreaView(){
-//        netWorkImageView.addSubview(expandAreaView)
-//        expandAreaView.snp.makeConstraints { make in
-//            make.top.leading.trailing.bottom.equalTo(0)
-//        }
-//        
-//        expandAreaView.showImageView.isHidden = true
-//        expandAreaView.boardView.isHidden = true
-//        
-//        if let sizes = self.viewModel.generatorModel.expandViewSizes {
-//            expandAreaView.updateExpandAreaView(width: sizes.0.width, height: sizes.0.height)
-//            expandAreaView.updateImageView(width: sizes.1.width, height: sizes.1.height)
-//        }
-//    }
+
     
     func closePage() {
     
@@ -234,45 +151,11 @@ class TSAIListPhotoGeneratorVC: TSBaseVC {
     //重新生成
     @objc func clickRegenerateBtn(){
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseBusiness.isVip , vc: self){ return }
+        if kJudgeVip(externalBool: true , vc: self){ return }
         
         viewModel.uploadAndCreatImage()
     }
-    
-    //保存功能
-    @objc func clickSaveBtn(){
-        guard let imageModel = imageModel else { return }
-//        if viewModel.generatorModel.generatorStyle == .photoLive{
-//            TSDownloadManager.getDownLoadVideo(urlString: imageModel.response.resultUrl) { url, success in
-//                if let url = url {
-//                    PhotoManagerShared.saveVideoToAlbum(videoURL: url) { [weak self] success, error in
-//                        guard let self = self else { return }
-//                        if success {
-//                            isSavePhotoMark = true
-//                            kSaveSuccesswShared.show(atView:self.view)
-//                        }else{
-//                            debugPrint(error)
-//                        }
-//                    }
-//                }
-//            }
-//        }else{
-            UIImageView.downloadImageWithProgress(urlString: imageModel.response.resultUrl) { image in
-                if let image = image {
-                    PhotoManagerShared.saveImageToAlbum(image) { [weak self] success, error in
-                        guard let self = self else { return }
-                        if success {
-                            isSavePhotoMark = true
-                            kSaveSuccesswShared.show(atView:self.view)
-                        }else{
-                            debugPrint(error)
-                        }
-                    }
-                }
-            }
-//        }
-    }
-    
+
     override func dealThings() {
         viewModel.uploadAndCreatImage()
         viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
@@ -281,17 +164,18 @@ class TSAIListPhotoGeneratorVC: TSBaseVC {
         }.store(in: &cancellable)
     }
     
+    override func navBarClickLeftAction() {
+        navigationController?.popToRootViewController(animated: true)
+    }
 }
 
 extension TSAIListPhotoGeneratorVC {
-    
     func getSuccessImage()->UIImage?{
-        if let image = netWorkImageView.image {
+        if let image = panComparisonView.newImageView.image {
             return image.pngImage
         }
         return nil
     }
-    
 }
 extension TSAIListPhotoGeneratorVC {
     
@@ -315,11 +199,7 @@ extension TSAIListPhotoGeneratorVC {
     
     func showProgress(text:String) {
         generateInView.updateShowProgress(text: text)
-        
-        netWorkImageView.isHidden = true
-        switchOriginalPictureBtn.isHidden = true
-        
-        setVideoHidden()
+//        setVideoHidden()
     }
     
     func showLoading(){
@@ -329,51 +209,23 @@ extension TSAIListPhotoGeneratorVC {
     
     func showError(text:String,code:Int = 0){
         generateInView.updateShowError(text: text,code: code)
-
-        
     }
     
     func showSuccess(model:TSActionInfoModel){
         generateInView.updateShowSuccess()
 
         imageModel = model
-        
-
-        netWorkImageView.isHidden = false
-        
 //        if viewModel.generatorModel.generatorStyle == .futureBaby {
 //            rotatingPictureBtn.isHidden = false
 //        }else{
-            switchOriginalPictureBtn.isHidden = false
+//            switchOriginalPictureBtn.isHidden = false
 //        }
-        
-        isSavePhotoMark = false
-        self.netWorkImageView.setAsyncImage(urlString: model.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
-        
         if let model = imageModel {
             complete(model)
         }
         
 //        setVideoURL()
-        setExpandAreaImage()
-    }
-    
-    @objc func switchOriginalPictureTouchDown() {
-//        if viewModel.generatorModel.generatorStyle == .photoExpand {
-//            expandAreaView.onlyBgImage(only: false)
-//        }else{
-            self.netWorkImageView.image = self.viewModel.generatorModel.upLoadImage
-//        }
-    }
-    
-    @objc func switchOriginalPictureTouchUp() {
-        guard let imageModel = imageModel else { return }
-        
-//        if viewModel.generatorModel.generatorStyle == .photoExpand {
-//            expandAreaView.onlyBgImage(only: true)
-//        }else{
-            self.netWorkImageView.setAsyncImage(urlString: imageModel.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
-//        }
+//        setExpandAreaImage()
     }
 }
 

+ 19 - 7
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVM.swift

@@ -162,13 +162,13 @@ class TSAIListPhotoGeneratorBaseVM {
         switch generatorModel.generatorStyle {
         case .enhance:
             urlType = .imageRewrite
-            postDict = ["prompt":"把图片变清晰"]
+            postDict["prompt"] = "把图片变清晰"
         case .colorize:
             urlType = .imageRewrite
-            postDict = ["prompt":"Add suitable colors to photos"]
+            postDict["prompt"] = "Add suitable colors to photos"
         case .descratch:
             urlType = .imageRewrite
-            postDict = ["prompt":"Remove the photo's scratches and dirt"]
+            postDict["prompt"] = "Remove the photo's scratches and dirt"
         }
         
         creatRequest = TSNetworkShared.post(urlType: urlType,parameters: postDict) { [weak self] data,error in
@@ -214,10 +214,22 @@ class TSAIListPhotoGeneratorBaseVM {
 //                                    }
 //                                }
 //                            }else {
-                                downloadImage(urlString: genmojiModel.response.resultUrl) { [weak self] in
-                                    guard let self = self else { return }
-                                    self.stateDatauPblished = (.success(nil),genmojiModel)
-                                }
+                            
+                            let group = DispatchGroup()
+                            group.enter()
+                            downloadImage(urlString: genmojiModel.request.imageUrl) {
+                                group.leave()
+                            }
+                            
+                            group.enter()
+                            downloadImage(urlString: genmojiModel.response.resultUrl) {
+                                group.leave()
+                            }
+                
+                            group.notify(queue: .main) {
+                                self.stateDatauPblished = (.success(nil),genmojiModel)
+                            }
+                            
 //                            }
                         }else{
                             self.stateDatauPblished = (.success(nil),genmojiModel)

+ 4 - 9
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift

@@ -42,6 +42,7 @@ class TSAIUploadPhotoVC: TSBaseVC {
             guard let self = self else { return }
             generateImage()
         }
+        kSetBtnVipIcon(btn: submitBtn, show: true)
         return submitBtn
     }()
 
@@ -179,7 +180,7 @@ class TSAIUploadPhotoVC: TSBaseVC {
         
         addNormalNavBarView()
         setPageTitle(titleString)
-        _ = setNavigationItem("", imageName: "aichat_history", direction: .right, action: #selector(clickNavRight))
+        _ = setNavigationItem("", imageName: "replace_photo", direction: .right, action: #selector(clickNavRight))
         
         contentView.addSubview(submitBtn)
         submitBtn.snp.makeConstraints { make in
@@ -269,7 +270,7 @@ extension TSAIUploadPhotoVC {
 extension TSAIUploadPhotoVC {
 
     @objc func clickNavRight() {
-        kPushVC(target: self, modelVC: TSAIListHistoryVC())
+        pickSinglePhoto()
     }
     
     @objc func clickBgView() {
@@ -302,17 +303,11 @@ extension TSAIUploadPhotoVC {
             additionalPrompt = ""
 //        }
         let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel: TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)){ [weak self] model in
-            guard let self = self else { return }
-            saveModel(model: model)
+            TSRMShared.aiListDB.updateData(model)
         }
         
         kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
     }
-    
-    func saveModel(model:TSActionInfoModel){
-        TSRMShared.aiListDB.updateData(model)
-    }
-
 }
 
 

+ 6 - 6
TSLiveWallpaper/Common/Purchase/TSPurchaseBusiness.swift

@@ -26,7 +26,8 @@ class TSPurchaseBusiness {
     }
     
     var isVip:Bool{
-        return PurchaseManager.default.isVip
+        return true
+//        return PurchaseManager.default.isVip
     }
     
     var vipType:PremiumPeriod{
@@ -137,9 +138,8 @@ extension TSPurchaseBusiness{
         //判断 vip
         return kJudgeVip(externalBool: kPurchaseBusiness.freeNumAvailable(type: vipFreeNumType) == false, vc: vc,closePageBlock: closePageBlock)
     }
-
-
-    func kJudgeVip(externalBool:Bool,
+    
+    func kJudgeVip(externalBool:Bool,//(externalBool)功能是否需要vip
                    vc:UIViewController? = nil,
                    closePageBlock:(()->Void)? = nil) -> Bool {
         //判断 vip
@@ -158,12 +158,12 @@ extension TSPurchaseBusiness{
     }
 }
 
-func kJudgeVip(externalBool:Bool,
+func kJudgeVip(externalBool:Bool,//(externalBool)功能是否需要vip
                vc:UIViewController? = nil,
                closePageBlock:(()->Void)? = nil) -> Bool {
     //判断 vip
     if externalBool,
-       PurchaseManager.default.isVip == false
+       kPurchaseBusiness.isVip == false
     {
         if let vc = vc {
             TSPurchaseVC.show(target: vc, closePageBlock: nil)

+ 3 - 0
TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift

@@ -55,6 +55,7 @@ class TSPhotoPickerManager: NSObject {
     
     /// 打开照片选择器
     private func openPhotoPicker() {
+        TSToastShared.showLoading(containerView: viewController?.view)
         imagePicker = UIImagePickerController()
         imagePicker.sourceType = .photoLibrary
         imagePicker.delegate = self
@@ -91,6 +92,7 @@ class TSPhotoPickerManager: NSObject {
 // MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate (iOS 14 以下)
 extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
     func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
+        TSToastShared.hideLoading()
 //        picker.dismiss(animated: true) {
             if let image = info[.originalImage] as? UIImage {
                 self.completionHandler?(image,info[.phAsset] as? PHAsset )
@@ -106,6 +108,7 @@ extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationCon
     }
     
     func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
+        TSToastShared.hideLoading()
 //        self.completionHandler?(nil,nil)
 //        if completionSizeHandler == nil {
             picker.dismiss(animated: true, completion: nil)

+ 6 - 1
TSLiveWallpaper/Data/Model/TSActionInfoModel.swift

@@ -36,7 +36,10 @@ class TSActionInfoModel: TSBaseModel {
     var percent:Float = 0.0
     var actionStatus:ActionStatus = .failed
     
-    var type:Int = 0
+    
+    
+    var generateStyle:String = ""
+    
     var videoThumbnailPath:String = ""
     var videoPath:String = ""
     
@@ -56,6 +59,8 @@ class TSActionInfoModel: TSBaseModel {
         actionStatus = ActionStatus.from(status)
         videoThumbnailPath      <- map["videoThumbnailPath"]
         videoPath      <- map["videoPath"]
+        generateStyle      <- map["generateStyle"]
+        
         
         uuid      <- map["uuid"]
     }

+ 6 - 4
TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift

@@ -13,7 +13,7 @@ class TSDBActionInfoModel: Object {
     @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
     @Persisted var createdAt: Date = Date()
     
-    @Persisted var dbType:String    //储存的业务类型
+    @Persisted var generateStyle:String    //储存的业务类型
 
     @Persisted var modelType:Int = 0
     @Persisted var id:Int = 0
@@ -30,9 +30,8 @@ class TSDBActionInfoModel: Object {
     @Persisted var videoPath:String = ""
     @Persisted var uuid:String = UUID().uuidString
     
-    static func createDBModel(actionInfoModel:TSActionInfoModel,dbType:String) -> TSDBActionInfoModel{
+    static func createDBModel(actionInfoModel:TSActionInfoModel) -> TSDBActionInfoModel{
         let dbModel = TSDBActionInfoModel()
-        dbModel.dbType = dbType
         dbModel.saveData(infoModel: actionInfoModel)
         return dbModel
     }
@@ -41,6 +40,8 @@ class TSDBActionInfoModel: Object {
         self.modelType = infoModel.modelType.rawValue
         self.id = infoModel.id
         self.actionType = infoModel.actionType
+        self.generateStyle = infoModel.generateStyle
+        
         self.comments = infoModel.comments
 
         self.createdTimestamp = infoModel.createdTimestamp
@@ -63,7 +64,8 @@ class TSDBActionInfoModel: Object {
         infoModel.id = self.id
         infoModel.actionType = self.actionType
         infoModel.comments = self.comments
-
+        infoModel.generateStyle = self.generateStyle
+        
         infoModel.createdTimestamp = self.createdTimestamp
         infoModel.status = self.status
         infoModel.costTime = self.costTime

+ 2 - 3
TSLiveWallpaper/Data/TSDBManager/TSDBManager.swift

@@ -88,7 +88,7 @@ class TSDBHistory: Object {
     }
     
     func updateData(_ actionInfoModel:TSActionInfoModel,id:Int? = nil){
-        let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel,dbType: self.primaryKey)
+        let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
             var replaceID = dbModel.id
             if let id = id {
                 replaceID = id
@@ -117,7 +117,7 @@ class TSDBHistory: Object {
     
     func addDatas(_ actionInfoModels:[TSActionInfoModel]){
         for actionInfoModel in actionInfoModels {
-            let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel,dbType: self.primaryKey)
+            let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
             TSRMShared.writeThread {
                 listModels.append(dbModel)
             }
@@ -168,4 +168,3 @@ extension TSRealmManager {
     }
     
 }
-

+ 6 - 0
TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift

@@ -11,6 +11,12 @@ let TSRMShared = TSRealmManager.shared
 
 
 
+extension List {
+    subscript(safe index: Int) -> Element? {
+        return indices.contains(index) ? self[index] : nil
+    }
+}
+
 
 class TSRealmManager {
     static let shared = TSRealmManager()

二進制
TSLiveWallpaper/Resource/generat_loading.gif