Bläddra i källkod

feat:3.6.6(1)活照片开发完毕

100Years 2 månader sedan
förälder
incheckning
e387c0ecc5
46 ändrade filer med 1689 tillägg och 452 borttagningar
  1. 85 13
      TSLiveWallpaper.xcodeproj/project.pbxproj
  2. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/Contents.json
  3. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/aiList_Animated@2x.png
  4. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/aiList_Animated@3x.png
  5. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/Contents.json
  6. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/video_icon@2x.png
  7. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/video_icon@3x.png
  8. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/Contents.json
  9. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/video_play@2x.png
  10. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/video_play@3x.png
  11. 22 0
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/Contents.json
  12. BIN
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/hint_Animated_bad@2x.png
  13. BIN
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/hint_Animated_bad@3x.png
  14. 22 0
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/Contents.json
  15. BIN
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/hint_Animated_good@2x.png
  16. BIN
      TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/hint_Animated_good@3x.png
  17. 13 8
      TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift
  18. 22 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift
  19. 13 5
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift
  20. 12 15
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/View/TSAIListHistoryCell.swift
  21. 17 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVM.swift
  22. 266 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVideoPlayerVC/TSAIListVideoPlayerVC.swift
  23. 29 10
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserCell.swift
  24. 23 8
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserVC.swift
  25. 27 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserVideoCell.swift
  26. 53 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Image.swift
  27. 25 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Video.swift
  28. 113 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+View.swift
  29. 129 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift
  30. 37 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/Model/TSAIListPhotoGeneratorModel.swift
  31. 1 86
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift
  32. 21 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Image.swift
  33. 31 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Video.swift
  34. 183 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+View.swift
  35. 58 230
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift
  36. 59 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/View/TSAIUploadPhotoTextView.swift
  37. 42 0
      TSLiveWallpaper/Business/TSPurchaseMembershipVC/TSViewTool/PhotoManager.swift
  38. 2 0
      TSLiveWallpaper/Common/TSNetWork/TSNetWork+Business.swift
  39. 174 0
      TSLiveWallpaper/Common/Tool/TSBusinessFileManager.swift
  40. 46 0
      TSLiveWallpaper/Common/Tool/TSDownloadManager.swift
  41. 18 26
      TSLiveWallpaper/Data/Model/TSActionInfoModel.swift
  42. 60 36
      TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift
  43. 7 0
      TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBasePhotoOperation.swift
  44. 7 9
      TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift
  45. 4 3
      TSLiveWallpaper/Data/TSDBManager/TSDBManager.swift
  46. 2 1
      TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift

+ 85 - 13
TSLiveWallpaper.xcodeproj/project.pbxproj

@@ -139,6 +139,18 @@
 		A8F778B22D1BA07200BF55D5 /* TSRandomWallpaperBrowseSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F778B12D1BA07000BF55D5 /* TSRandomWallpaperBrowseSelectView.swift */; };
 		A8F778B42D1BB8F600BF55D5 /* PhotoManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F778B32D1BB8F300BF55D5 /* PhotoManager.swift */; };
 		A8F778B72D1BE9A500BF55D5 /* TSLiveWallpaperBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F778B62D1BE9A100BF55D5 /* TSLiveWallpaperBrowseVC.swift */; };
+		A8F8BCCF2E03F8BC00EF4AA6 /* TSAIUploadPhotoTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCCE2E03F8BB00EF4AA6 /* TSAIUploadPhotoTextView.swift */; };
+		A8F8BCD12E03FD4200EF4AA6 /* TSAIUploadPhotoVC+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCD02E03FC4E00EF4AA6 /* TSAIUploadPhotoVC+Image.swift */; };
+		A8F8BCD32E03FD5400EF4AA6 /* TSAIUploadPhotoVC+Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCD22E03FD4A00EF4AA6 /* TSAIUploadPhotoVC+Video.swift */; };
+		A8F8BCD52E03FE5000EF4AA6 /* TSAIUploadPhotoVC+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCD42E03FE4C00EF4AA6 /* TSAIUploadPhotoVC+View.swift */; };
+		A8F8BCD82E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCD62E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift */; };
+		A8F8BCDA2E040D8100EF4AA6 /* TSDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCD92E040D8100EF4AA6 /* TSDownloadManager.swift */; };
+		A8F8BCDC2E040D9E00EF4AA6 /* TSBusinessFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCDB2E040D9E00EF4AA6 /* TSBusinessFileManager.swift */; };
+		A8F8BCDE2E0420EE00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCDD2E0420EB00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift */; };
+		A8F8BCE02E04210000EF4AA6 /* TSAIPhotoDetailsVC+Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCDF2E0420FB00EF4AA6 /* TSAIPhotoDetailsVC+Video.swift */; };
+		A8F8BCE32E0423B100EF4AA6 /* TSAIPhotoDetailsVC+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCE22E0423AD00EF4AA6 /* TSAIPhotoDetailsVC+View.swift */; };
+		A8F8BCE62E04F62400EF4AA6 /* TSAIListPhotoGeneratorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCE52E04F62200EF4AA6 /* TSAIListPhotoGeneratorModel.swift */; };
+		A8F8BCE82E04FA5900EF4AA6 /* TSAIPhotoDetailsBrowserVideoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCE72E04FA5200EF4AA6 /* TSAIPhotoDetailsBrowserVideoCell.swift */; };
 		A8FD8F332DFBCB85008CAACF /* ZillaSlab-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F322DFBCB85008CAACF /* ZillaSlab-Regular.ttf */; };
 		A8FD8F342DFBCB85008CAACF /* ZillaSlab-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F312DFBCB85008CAACF /* ZillaSlab-Medium.ttf */; };
 		A8FD8F352DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F302DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf */; };
@@ -296,6 +308,18 @@
 		A8F778B12D1BA07000BF55D5 /* TSRandomWallpaperBrowseSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRandomWallpaperBrowseSelectView.swift; sourceTree = "<group>"; };
 		A8F778B32D1BB8F300BF55D5 /* PhotoManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoManager.swift; sourceTree = "<group>"; };
 		A8F778B62D1BE9A100BF55D5 /* TSLiveWallpaperBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLiveWallpaperBrowseVC.swift; sourceTree = "<group>"; };
+		A8F8BCCE2E03F8BB00EF4AA6 /* TSAIUploadPhotoTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUploadPhotoTextView.swift; sourceTree = "<group>"; };
+		A8F8BCD02E03FC4E00EF4AA6 /* TSAIUploadPhotoVC+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIUploadPhotoVC+Image.swift"; sourceTree = "<group>"; };
+		A8F8BCD22E03FD4A00EF4AA6 /* TSAIUploadPhotoVC+Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIUploadPhotoVC+Video.swift"; sourceTree = "<group>"; };
+		A8F8BCD42E03FE4C00EF4AA6 /* TSAIUploadPhotoVC+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIUploadPhotoVC+View.swift"; sourceTree = "<group>"; };
+		A8F8BCD62E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListVideoPlayerVC.swift; sourceTree = "<group>"; };
+		A8F8BCD92E040D8100EF4AA6 /* TSDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDownloadManager.swift; sourceTree = "<group>"; };
+		A8F8BCDB2E040D9E00EF4AA6 /* TSBusinessFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBusinessFileManager.swift; sourceTree = "<group>"; };
+		A8F8BCDD2E0420EB00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIPhotoDetailsVC+Image.swift"; sourceTree = "<group>"; };
+		A8F8BCDF2E0420FB00EF4AA6 /* TSAIPhotoDetailsVC+Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIPhotoDetailsVC+Video.swift"; sourceTree = "<group>"; };
+		A8F8BCE22E0423AD00EF4AA6 /* TSAIPhotoDetailsVC+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIPhotoDetailsVC+View.swift"; sourceTree = "<group>"; };
+		A8F8BCE52E04F62200EF4AA6 /* TSAIListPhotoGeneratorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListPhotoGeneratorModel.swift; sourceTree = "<group>"; };
+		A8F8BCE72E04FA5200EF4AA6 /* TSAIPhotoDetailsBrowserVideoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoDetailsBrowserVideoCell.swift; sourceTree = "<group>"; };
 		A8FD8F302DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-BoldItalic.ttf"; sourceTree = "<group>"; };
 		A8FD8F312DFBCB85008CAACF /* ZillaSlab-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-Medium.ttf"; sourceTree = "<group>"; };
 		A8FD8F322DFBCB85008CAACF /* ZillaSlab-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-Regular.ttf"; sourceTree = "<group>"; };
@@ -431,6 +455,8 @@
 		A81CA4882D15840F00A3AAC8 /* Tool */ = {
 			isa = PBXGroup;
 			children = (
+				A8F8BCDB2E040D9E00EF4AA6 /* TSBusinessFileManager.swift */,
+				A8F8BCD92E040D8100EF4AA6 /* TSDownloadManager.swift */,
 				A8C4C0EE2D27BFEA003C46FC /* TSNetworkTool.swift */,
 				A84C239E2D1E88C500B61B55 /* TSFileManagerTool.swift */,
 				A81F5B4A2D19658300740085 /* PhotoTools.swift */,
@@ -785,6 +811,7 @@
 		A86857A92DF9210D0089D222 /* TSAIListVC */ = {
 			isa = PBXGroup;
 			children = (
+				A8F8BCD72E0407C800EF4AA6 /* TSAIListVideoPlayerVC */,
 				A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */,
 				A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */,
 				A86857CD2DF9775D0089D222 /* TSAIPhotoGeneratorVC */,
@@ -815,7 +842,11 @@
 		A86857B62DF9258D0089D222 /* TSAIUploadPhotoVC */ = {
 			isa = PBXGroup;
 			children = (
+				A8F8BCCD2E03F88700EF4AA6 /* View */,
 				A86857B52DF9258D0089D222 /* TSAIUploadPhotoVC.swift */,
+				A8F8BCD42E03FE4C00EF4AA6 /* TSAIUploadPhotoVC+View.swift */,
+				A8F8BCD02E03FC4E00EF4AA6 /* TSAIUploadPhotoVC+Image.swift */,
+				A8F8BCD22E03FD4A00EF4AA6 /* TSAIUploadPhotoVC+Video.swift */,
 			);
 			path = TSAIUploadPhotoVC;
 			sourceTree = "<group>";
@@ -832,6 +863,7 @@
 		A86857CD2DF9775D0089D222 /* TSAIPhotoGeneratorVC */ = {
 			isa = PBXGroup;
 			children = (
+				A8F8BCE42E04F61C00EF4AA6 /* Model */,
 				A86857CE2DF977630089D222 /* TSAIListPhotoGeneratorVC.swift */,
 				A86857D02DF9778B0089D222 /* TSAIListPhotoGeneratorVM.swift */,
 			);
@@ -841,21 +873,14 @@
 		A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */ = {
 			isa = PBXGroup;
 			children = (
-				A86857DB2DF99C170089D222 /* View */,
-				A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */,
+				A8F8BCE12E04211300EF4AA6 /* TSAIPhotoDetailsVC */,
 				A87CF8512E0296960063CB7E /* TSAIPhotoDetailsBrowserVC.swift */,
 				A87CF8532E029B3F0063CB7E /* TSAIPhotoDetailsBrowserCell.swift */,
+				A8F8BCE72E04FA5200EF4AA6 /* TSAIPhotoDetailsBrowserVideoCell.swift */,
 			);
 			path = TSAIPhotoDetailsVC;
 			sourceTree = "<group>";
 		};
-		A86857DB2DF99C170089D222 /* View */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = View;
-			sourceTree = "<group>";
-		};
 		A895B50F2E0287F2004F9B85 /* TYCyclePagerView */ = {
 			isa = PBXGroup;
 			children = (
@@ -996,6 +1021,41 @@
 			path = TSLiveWallpaperBrowseVC;
 			sourceTree = "<group>";
 		};
+		A8F8BCCD2E03F88700EF4AA6 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A8F8BCCE2E03F8BB00EF4AA6 /* TSAIUploadPhotoTextView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		A8F8BCD72E0407C800EF4AA6 /* TSAIListVideoPlayerVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8F8BCD62E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift */,
+			);
+			path = TSAIListVideoPlayerVC;
+			sourceTree = "<group>";
+		};
+		A8F8BCE12E04211300EF4AA6 /* TSAIPhotoDetailsVC */ = {
+			isa = PBXGroup;
+			children = (
+				A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */,
+				A8F8BCE22E0423AD00EF4AA6 /* TSAIPhotoDetailsVC+View.swift */,
+				A8F8BCDD2E0420EB00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift */,
+				A8F8BCDF2E0420FB00EF4AA6 /* TSAIPhotoDetailsVC+Video.swift */,
+			);
+			path = TSAIPhotoDetailsVC;
+			sourceTree = "<group>";
+		};
+		A8F8BCE42E04F61C00EF4AA6 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				A8F8BCE52E04F62200EF4AA6 /* TSAIListPhotoGeneratorModel.swift */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
 		A8FD8F362DFBD650008CAACF /* View */ = {
 			isa = PBXGroup;
 			children = (
@@ -1161,6 +1221,7 @@
 				A81CA4832D157F5C00A3AAC8 /* UIImageView+Ex.swift in Sources */,
 				A81F5B492D1956EA00740085 /* UIScreen.swift in Sources */,
 				A8EE92CD2DFFF2860077DFFD /* TSBaseOperation.swift in Sources */,
+				A8F8BCCF2E03F8BC00EF4AA6 /* TSAIUploadPhotoTextView.swift in Sources */,
 				A8EE92CE2DFFF2860077DFFD /* TSGenerateBaseOperation.swift in Sources */,
 				A8EE92CF2DFFF2860077DFFD /* TSGenerateBasePhotoOperation.swift in Sources */,
 				A8EE92D02DFFF2860077DFFD /* TSBaseOperationQueue.swift in Sources */,
@@ -1171,6 +1232,7 @@
 				A895B5002E01370E004F9B85 /* TSTextToastView.swift in Sources */,
 				A81F5B5B2D1A5F2300740085 /* TSHomeTopBannerCell.swift in Sources */,
 				A83946312D1D66A000ABFF0D /* TSTermsServiceVC.swift in Sources */,
+				A8F8BCD52E03FE5000EF4AA6 /* TSAIUploadPhotoVC+View.swift in Sources */,
 				A8C4C0982D242154003C46FC /* LivePhoto.swift in Sources */,
 				A81F5B472D19562800740085 /* EditorVideoControlMaskView.swift in Sources */,
 				A81CA4AA2D16943800A3AAC8 /* TSMineCell.swift in Sources */,
@@ -1184,6 +1246,7 @@
 				60553FD62D3B54A400BAAD7F /* SaveSuccessTipsView.swift in Sources */,
 				60553FD72D3B54A400BAAD7F /* GradientText.swift in Sources */,
 				60553FD82D3B54A400BAAD7F /* LWBaseNavigationController.swift in Sources */,
+				A8F8BCE62E04F62400EF4AA6 /* TSAIListPhotoGeneratorModel.swift in Sources */,
 				60553FD92D3B54A400BAAD7F /* GradientBackgroundModifier.swift in Sources */,
 				A895B5102E0287F2004F9B85 /* TYPageControl.m in Sources */,
 				A895B5112E0287F2004F9B85 /* TYCyclePagerView.m in Sources */,
@@ -1192,6 +1255,7 @@
 				A868579E2DF915E90089D222 /* TSPurchaseBusiness.swift in Sources */,
 				A81F5B5D2D1A906C00740085 /* TSHomeDataModel.swift in Sources */,
 				A81CA49B2D1652CA00A3AAC8 /* TSHomeVC.swift in Sources */,
+				A8F8BCDA2E040D8100EF4AA6 /* TSDownloadManager.swift in Sources */,
 				A86857B02DF921970089D222 /* TSAppBtnView.swift in Sources */,
 				A81CA4B82D16A6BD00A3AAC8 /* View+Ex.swift in Sources */,
 				A8F76C422D350A9600AA6E93 /* TSPurchaseManager.swift in Sources */,
@@ -1220,8 +1284,10 @@
 				A86857872DF81B660089D222 /* TSNetWork+Business.swift in Sources */,
 				A86857882DF81B660089D222 /* TSNetworkManager.swift in Sources */,
 				A86857892DF81B660089D222 /* TSNetworkManager+Loading.swift in Sources */,
+				A8F8BCD12E03FD4200EF4AA6 /* TSAIUploadPhotoVC+Image.swift in Sources */,
 				A86857A32DF91F690089D222 /* TSAILIstCell.swift in Sources */,
 				A868577C2DF819BB0089D222 /* TSDBManager.swift in Sources */,
+				A8F8BCE02E04210000EF4AA6 /* TSAIPhotoDetailsVC+Video.swift in Sources */,
 				A8EE92D22DFFFE2F0077DFFD /* TSMineVM.swift in Sources */,
 				A86857BE2DF926220089D222 /* TSAIListHistoryCell.swift in Sources */,
 				A86857DD2DF99C200089D222 /* TSImageIPanComparisonView.swift in Sources */,
@@ -1234,6 +1300,7 @@
 				A86857BC2DF926110089D222 /* TSAIListHistoryVC.swift in Sources */,
 				A86857932DF845F60089D222 /* TSGeneratorErrorView.swift in Sources */,
 				A86857C02DF926870089D222 /* TSPageNullView.swift in Sources */,
+				A8F8BCD32E03FD5400EF4AA6 /* TSAIUploadPhotoVC+Video.swift in Sources */,
 				A86857942DF845F60089D222 /* TSGeneratorView.swift in Sources */,
 				A868578C2DF843F90089D222 /* TSRealmManager.swift in Sources */,
 				A84C239B2D1E3A4300B61B55 /* GPVideoClipperController.swift in Sources */,
@@ -1257,20 +1324,25 @@
 				A839462F2D1D64BF00ABFF0D /* TSAboutUsVC.swift in Sources */,
 				A8477C972D22737900DF0B93 /* TSBusinessWebVC.swift in Sources */,
 				A81CA4972D1652BD00A3AAC8 /* TSRandomWallpaperVC.swift in Sources */,
+				A8F8BCD82E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift in Sources */,
 				A81F5B622D1AB17E00740085 /* TSRandomWallpaperBrowseVC.swift in Sources */,
 				A839463F2D1D6FB700ABFF0D /* TSLiveWallpaperTutorialsVC.swift in Sources */,
 				A8EE92C02DFFC3B50077DFFD /* TSImageProComparisonView.swift in Sources */,
 				A86857C42DF92AEB0089D222 /* UIFont+Ex.swift in Sources */,
 				A86857A12DF91EB90089D222 /* TSAIListVC.swift in Sources */,
+				A8F8BCE32E0423B100EF4AA6 /* TSAIPhotoDetailsVC+View.swift in Sources */,
 				A81F5B5F2D1A909300740085 /* TSRandomWallpaperModel.swift in Sources */,
 				A8F778B72D1BE9A500BF55D5 /* TSLiveWallpaperBrowseVC.swift in Sources */,
 				A81CA48F2D15857B00A3AAC8 /* TSTabBarController.swift in Sources */,
 				A8C4C0A52D24218A003C46FC /* Converter4Video.swift in Sources */,
 				A8C4C0A62D24218A003C46FC /* AVAssetExtension.swift in Sources */,
 				A8C4C0A72D24218A003C46FC /* LivePhotoUtil.m in Sources */,
+				A8F8BCDE2E0420EE00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift in Sources */,
+				A8F8BCE82E04FA5900EF4AA6 /* TSAIPhotoDetailsBrowserVideoCell.swift in Sources */,
 				A86857AC2DF921160089D222 /* TSAIListHintBaseVC.swift in Sources */,
 				A8C4C0A82D24218A003C46FC /* Converter4Image.swift in Sources */,
 				A83946432D1D701500ABFF0D /* TSLiveWallpaperCopyrightVC.swift in Sources */,
+				A8F8BCDC2E040D9E00EF4AA6 /* TSBusinessFileManager.swift in Sources */,
 				A8C4C0AB2D2427E7003C46FC /* LivePhotoConverter.swift in Sources */,
 				A81F5B3C2D19087100740085 /* TSRandomWallpaperCell.swift in Sources */,
 				A81F5B442D19559C00740085 /* EditorVideoControlViewCell.swift in Sources */,
@@ -1325,7 +1397,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				ENABLE_APP_SANDBOX = NO;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -1342,7 +1414,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.6.5;
+				MARKETING_VERSION = 3.6.6;
 				PRODUCT_BUNDLE_IDENTIFIER = musicplayer.offline.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1365,7 +1437,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				ENABLE_APP_SANDBOX = NO;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -1382,7 +1454,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.6.5;
+				MARKETING_VERSION = 3.6.6;
 				PRODUCT_BUNDLE_IDENTIFIER = musicplayer.offline.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";

+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/aiList_Animated@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Animated.imageset/aiList_Animated@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/video_icon@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/video_icon.imageset/video_icon@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/video_play@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/video_play.imageset/video_play@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/hint_Animated_bad@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_bad.imageset/hint_Animated_bad@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/hint_Animated_good@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Hint/hint_Animated_good.imageset/hint_Animated_good@3x.png


+ 13 - 8
TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift

@@ -23,7 +23,6 @@ class TSAIListHintBaseVC: TSBaseVC {
         var badText:String
         var badInfoText:String
         
-        
         init(imageMaxBitSize: Int, goodImageNamed: String, badImageNamed: String, titleText: String, titleSubText: String, goodText: String, goodInfoText: String, badText: String, badInfoText: String) {
             self.imageMaxBitSize = imageMaxBitSize
             self.goodImageNamed = goodImageNamed
@@ -35,13 +34,7 @@ class TSAIListHintBaseVC: TSBaseVC {
             self.badText = badText
             self.badInfoText = badInfoText
         }
-        
-//        static func getDefaultConfig(imageMaxBitSize:Int) -> Config {
-//            var config = defaultConfig
-//            config.imageMaxBitSize = imageMaxBitSize
-//            return config
-//        }
-        
+
         static var enhanceConfig:Config {
             return Config(imageMaxBitSize: kUploadImageMaxBit5Size,
                           goodImageNamed: "hint_Enhance_good",
@@ -102,6 +95,18 @@ class TSAIListHintBaseVC: TSBaseVC {
                           badText: "Unsuitable".localized,
                           badInfoText: "High resulotion, Severaly damaged and Difficult to recognize the face".localized)
         }
+        
+        static var animatedConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "hint_Animated_good",
+                          badImageNamed: "hint_Animated_bad",
+                          titleText: "Animate Tips".localized,
+                          titleSubText: "",
+                          goodText: "Suitable".localized,
+                          goodInfoText: "Good quality portrair color photos".localized,
+                          badText: "Unsuitable".localized,
+                          badInfoText: "B&W or Severely damaged photos".localized)
+        }
     }
     
     var config:Config = Config.enhanceConfig

+ 22 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift

@@ -12,7 +12,8 @@ enum TSGeneratorImageStyle:String {
     
     case enlighten = "enlighten"   //调整光线
     case recreate = "recreate"   //修复和上色老照片
-
+    case creatVideo = "creatVideo"   //修复和上色老照片
+    
     var imageMaxKb:Int{
         switch self {
         case .descratch:
@@ -47,6 +48,8 @@ enum TSGeneratorImageStyle:String {
             return .enlightenConfig
         case .recreate:
             return .recreateConfig
+        case .creatVideo:
+            return .animatedConfig
         }
     }
     
@@ -57,4 +60,22 @@ enum TSGeneratorImageStyle:String {
     var aiModel:String {
         return "kie"
     }
+    
+    
+    var generatorBtnTitle:String {
+        switch self {
+        case .enhance:
+            return "Enhance Photo".localized
+        case .colorize:
+            return "Colorize Photo".localized
+        case .descratch:
+            return "Descratch Photo".localized
+        case .enlighten:
+            return "Enlighten Photo".localized
+        case .recreate:
+            return "Recreate Photo".localized
+        default:
+            return "Generate".localized
+        }
+    }
 }

+ 13 - 5
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift

@@ -136,6 +136,10 @@ class TSAIListHistoryVC: TSBaseVC {
         pageNullView.isHidden = listModelArray.count > 0
     }
     
+    override func viewWillAppear(_ animated: Bool) {
+        print("viewWillAppear")
+    }
+    
     @objc func clickNavRight() {
         TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
             message: "Are you sure to delete all histories?".localized,
@@ -175,14 +179,18 @@ extension TSAIListHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegat
     public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 
         if let dbModel = listModelArray.safeObj(At:indexPath.row){
-            //单个浏览
-//            let vc = TSAIPhotoDetailsVC()
-//            vc.infoModel = dbModel
-//            vc.deleteBlock = { [weak self]  in
+            
+
+//            //单个浏览
+//            let detailsVC = TSAIPhotoDetailsVC()
+//            detailsVC.infoModel = dbModel
+//            detailsVC.deleteBlock = { [weak self]  in
 //                guard let self = self else { return }
 //                removeDelete(index: indexPath.row)
 //            }
-//            kPresentModalVC(target: self, modelVC: vc)
+//            kPresentModalVC(target: self, modelVC: detailsVC)
+//            return
+
             
             //多个浏览
             var dataModelArray: [TSActionInfoModel] = []

+ 12 - 15
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/View/TSAIListHistoryCell.swift

@@ -16,7 +16,7 @@ class TSAIListHistoryCell: TSBaseCollectionCell {
                     operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
                         guard let self = self else { return }
                         DispatchQueue.main.async {
-                            print("actionInfoModel.toJSONString()=\(actionInfoModel.toJSONString())")
+//                            print("actionInfoModel.toJSONString()=\(actionInfoModel.toJSONString())")
                             self.updataActionInfoModelView(model: actionInfoModel)
                         }
                     }
@@ -36,13 +36,8 @@ class TSAIListHistoryCell: TSBaseCollectionCell {
         generateView.refreshHandel = { [weak self]  in
             guard let self = self else { return }
             if dataModel.upImageURLExpired { //任务已经过期了
-//                self.actionHandler(any: "delete_task_expired")
-//                delegate?.collectionView(didTrigger: TSSimpleCellEvent(action: .buttonTapped("delete_task_expired"), indexPath: indexPath, data: self.dataModel))
-//                
                 buttonTapped?("delete_task_expired")
             }else if dataModel.response.sensitiveError { //敏感内容
-//                self.actionHandler(any: "delete_task_sensitive")
-//                delegate?.collectionView(didTrigger: TSSimpleCellEvent(action: .buttonTapped("delete_task_sensitive"), indexPath: indexPath, data: self.dataModel))
                 buttonTapped?("delete_task_sensitive")
             }else{
 //                if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
@@ -99,7 +94,7 @@ class TSAIListHistoryCell: TSBaseCollectionCell {
     }()
     
     lazy var videoIconImageView: UIImageView = {
-        let videoIconImageView = UIImageView.createImageView(imageName:"video_icon",contentMode: .scaleToFill)
+        let videoIconImageView = UIImageView.createImageView(image:.videoIcon,contentMode: .scaleToFill)
         videoIconImageView.isHidden = true
         return videoIconImageView
     }()
@@ -135,7 +130,7 @@ class TSAIListHistoryCell: TSBaseCollectionCell {
         videoIconImageView.snp.makeConstraints { make in
             make.top.equalTo(8)
             make.leading.equalTo(8)
-            make.width.height.equalTo(24)
+            make.width.height.equalTo(20)
         }
         
         contentView.addSubview(generateView)
@@ -166,13 +161,15 @@ extension TSAIListHistoryCell {
                 showImageView.image = UIImage(named: model.response.resultUrl)
             }else{
                 exampleView.isHidden = true
-                //                    if dataModel.isVideo {
-                //                        videoIconImageView.isHidden = false
-                //                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoThumbnailURL.path)
-                //                    }else {
-                showImageView.setAsyncImage(urlString: model.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
-                hiddenImageView.setAsyncImage(urlString: model.request.imageUrl,contentMode: .scaleAspectFill)
-                //                    }
+                
+                videoIconImageView.isHidden = !model.isVideo
+                if dataModel.isVideo {
+                    videoIconImageView.isHidden = false
+                    showImageView.setAsyncImage(urlString: model.response.previewUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                }else {
+                    showImageView.setAsyncImage(urlString: model.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                    hiddenImageView.setAsyncImage(urlString: model.request.imageUrl,contentMode: .scaleAspectFill)
+                }
             }
 
         case .failed:

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

@@ -54,6 +54,23 @@ class TSAIListVM {
                     }
         }))
         
+        
+        //视频照片
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImageName:"aiList_Animated",
+                leftTitle: "Animated Photos".localized,
+                leftSubTitle: "Turn photos into live moments ".localized,
+                rightViewStyle: 0,
+                tapBlock: { [weak self] model, _, _ in
+                   guard let self = self else { return }
+                    enterSelectPhotos(style: .creatVideo) { image in
+                        let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .creatVideo)
+                        kPushVC(target: self.target, modelVC: baseVc)
+                    }
+        }))
+
+        
         //照片高清修复
         sectionModel.addSubItemModel(
             createItemModel(
@@ -100,7 +117,6 @@ class TSAIListVM {
         }))
         
 
-
         return dataArray
 
     }()

+ 266 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListVideoPlayerVC/TSAIListVideoPlayerVC.swift

@@ -0,0 +1,266 @@
+//
+//  TSVideoPlayerVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/17.
+//
+
+
+import UIKit
+import AVKit
+import SnapKit
+
+class TSAIListVideoPlayerVC: UIViewController {
+    
+    // MARK: - Properties
+    private var player: AVPlayer?
+    private var playerLayer: AVPlayerLayer?
+    private var timeObserverToken: Any?
+    private var isPlaying = false
+    
+    private let videoURL: URL
+    
+    // MARK: - UI Components
+    private lazy var playerContainerView: UIView = {
+        let view = UIView()
+        view.backgroundColor = .clear
+        return view
+    }()
+    
+    private lazy var playPauseButton: UIButton = {
+        let button = UIButton()
+        button.setImage(.videoPlay, for: .normal)
+        button.tintColor = .white
+//        button.addTarget(self, action: #selector(playPauseTapped), for: .touchUpInside)
+        button.isUserInteractionEnabled = false
+        return button
+    }()
+    
+    private lazy var progressSlider: TSProgressSlider = {
+        let slider = TSProgressSlider()
+        slider.minimumTrackTintColor = UIColor.themeColor
+        slider.maximumTrackTintColor = .white.withAlphaComponent(0.2)
+        slider.setThumbImage(UIImage.circle(diameter: 10, color: .white), for: .normal)
+        slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)
+        slider.addTarget(self, action: #selector(sliderTouchEnded(_:)), for: .touchUpInside)
+        slider.addTarget(self, action: #selector(sliderTouchEnded(_:)), for: .touchUpOutside)
+        return slider
+    }()
+    
+    private lazy var currentTimeLabel: UILabel = {
+        let label = UILabel.createLabel(text: "00:00",font:.font(size: 12),textColor: .white)
+        return label
+    }()
+    
+    private lazy var durationLabel: UILabel = {
+        let label = UILabel.createLabel(text: "00:00",font:.font(size: 12),textColor: .white)
+        return label
+    }()
+
+    private lazy var controlsContainerView: UIView = {
+        let view = UIView()
+        return view
+    }()
+    
+    // MARK: - Initialization
+    init(videoURL: URL) {
+        self.videoURL = videoURL
+        super.init(nibName: nil, bundle: nil)
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    // MARK: - Lifecycle
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        setupUI()
+        setupPlayer()
+    }
+    
+    override func viewDidLayoutSubviews() {
+        super.viewDidLayoutSubviews()
+        playerLayer?.frame = playerContainerView.bounds
+    }
+    
+    deinit {
+        removePeriodicTimeObserver()
+    }
+    
+    // MARK: - Setup
+    private func setupUI() {
+        view.backgroundColor = "#111111".uiColor
+        playerContainerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(playPauseTapped)))
+        view.addSubview(playerContainerView)
+        playerContainerView.addSubview(playPauseButton)
+
+        playerContainerView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        playPauseButton.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.centerY.equalToSuperview()//.offset(-50)
+            make.width.height.equalTo(56)
+        }
+        
+        playerContainerView.addSubview(controlsContainerView)
+        controlsContainerView.snp.makeConstraints { make in
+            make.leading.trailing.equalTo(0)
+            make.bottom.equalTo(-80-k_Height_safeAreaInsetsBottom())
+        }
+        
+        controlsContainerView.addSubview(progressSlider)
+        controlsContainerView.addSubview(currentTimeLabel)
+        controlsContainerView.addSubview(durationLabel)
+        
+        progressSlider.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.top.equalTo(0)
+            make.height.equalTo(10)
+        }
+        
+        let label = UILabel.createLabel(text: "/",font: .font(size: 11),textColor: .white)
+        controlsContainerView.addSubview(label)
+        label.snp.makeConstraints { make in
+            make.top.equalTo(progressSlider.snp.bottom).offset(6)
+            make.centerX.equalToSuperview()
+            make.height.equalTo(13)
+            make.bottom.equalToSuperview()
+        }
+        
+        currentTimeLabel.snp.makeConstraints { make in
+            make.height.equalTo(13)
+            make.centerY.equalTo(label)
+            make.trailing.equalTo(label.snp.leading)
+        }
+        
+        durationLabel.snp.makeConstraints { make in
+            make.height.equalTo(13)
+            make.centerY.equalTo(label)
+            make.leading.equalTo(label.snp.trailing)
+        }
+    }
+
+    private func setupPlayer() {
+        player = AVPlayer(url: videoURL)
+        playerLayer = AVPlayerLayer(player: player)
+        playerLayer?.videoGravity = .resizeAspect
+        
+        if let playerLayer = playerLayer {
+            playerContainerView.layer.insertSublayer(playerLayer, at: 0)
+        }
+        
+        // Add time observer to update progress
+        addPeriodicTimeObserver()
+        
+        // Observe when the video ends
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(playerDidFinishPlaying),
+            name: .AVPlayerItemDidPlayToEndTime,
+            object: player?.currentItem
+        )
+        
+        // Get video duration
+        let duration = player?.currentItem?.asset.duration.seconds ?? 0
+        durationLabel.text = formatTime(seconds: Float(duration))
+    }
+    
+    func setControlsBottom(bottem:CGFloat){
+        controlsContainerView.snp.updateConstraints { make in
+            make.bottom.equalTo(bottem)
+        }
+    }
+    
+    // MARK: - Player Controls
+    @objc private func playPauseTapped() {
+        if isPlaying {
+            playPause()
+        } else {
+            playPlay()
+        }
+    }
+    
+    @objc private func playPlay() {
+        player?.play()
+        playPauseButton.isHidden = true
+//        playPauseButton.setImage(UIImage(named: "pause"), for: .normal)
+        isPlaying = true
+    }
+    
+    @objc func playPause() {
+        player?.pause()
+        playPauseButton.isHidden = false
+//        playPauseButton.setImage(UIImage(named: "play"), for: .normal)
+        isPlaying = false
+    }
+    
+    @objc private func playerDidFinishPlaying() {
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1){
+            self.playerDidFinish()
+        }
+    }
+    
+    func playerDidFinish() {
+        player?.seek(to: CMTime.zero)
+        playPauseButton.isHidden = false
+//        playPauseButton.setImage(UIImage(named: "play"), for: .normal)
+        isPlaying = false
+        progressSlider.value = 0
+        currentTimeLabel.text = "00:00"
+    }
+    // MARK: - Progress Slider
+    @objc private func sliderValueChanged(_ sender: UISlider) {
+        playPause()
+        guard let duration = player?.currentItem?.duration else { return }
+        let totalSeconds = CMTimeGetSeconds(duration)
+        let value = Float64(sender.value) * totalSeconds
+        let seekTime = CMTime(value: Int64(value), timescale: 1)
+        currentTimeLabel.text = formatTime(seconds: Float(value))
+    }
+    
+    @objc private func sliderTouchEnded(_ sender: UISlider) {
+        guard let duration = player?.currentItem?.duration else { return }
+        let totalSeconds = CMTimeGetSeconds(duration)
+        let value = Float64(sender.value) * totalSeconds
+        let seekTime = CMTime(value: Int64(value), timescale: 1)
+        player?.seek(to: seekTime, toleranceBefore: .zero, toleranceAfter: .zero)
+        playPlay()
+    }
+    
+    // MARK: - Time Observer
+    private func addPeriodicTimeObserver() {
+        let interval = CMTime(seconds: 0.05, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
+        
+        timeObserverToken = player?.addPeriodicTimeObserver(
+            forInterval: interval,
+            queue: .main
+        ) { [weak self] time in
+            guard let self = self else { return }
+            let timeElapsed = Float(time.seconds)
+            
+            if let duration = self.player?.currentItem?.duration {
+                let durationSeconds = Float(CMTimeGetSeconds(duration))
+                self.progressSlider.value = Float(timeElapsed / durationSeconds)
+                self.currentTimeLabel.text = self.formatTime(seconds: timeElapsed)
+            }
+        }
+    }
+    
+    private func removePeriodicTimeObserver() {
+        if let token = timeObserverToken {
+            player?.removeTimeObserver(token)
+            timeObserverToken = nil
+        }
+    }
+    
+    // MARK: - Helper Methods
+    private func formatTime(seconds: Float) -> String {
+        let minutes = Int(seconds) / 60
+        let seconds = Int(seconds) % 60
+        return String(format: "%02d:%02d", minutes, seconds)
+    }
+}

+ 29 - 10
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserCell.swift

@@ -8,21 +8,22 @@
 class TSAIPhotoDetailsBrowserCell: TSBaseCollectionCell {
     var model:TSActionInfoModel = TSActionInfoModel(){
         didSet{
-            dePrint("TSAIPhotoDetailsBrowserCell didSet model")
-            uploadPanComparisonView()
+            removeVideoView()
+            if model.isVideo {
+                panComparisonView.isHidden = true
+                addVideoView()
+            }else{
+                panComparisonView.isHidden = false
+                uploadPanComparisonView()
+            }
         }
     }
     
-    
-    
-    lazy var panComparisonView : TSImageIPanComparisonView = {
-        let panComparisonView = TSImageIPanComparisonView()
-        return panComparisonView
-    }()
-    
+    lazy var panComparisonView : TSImageIPanComparisonView = TSImageIPanComparisonView()
+    var videoPlayerVC: TSAIListVideoPlayerVC?
     
     override func creatUI() {
-        contentView.addSubview(panComparisonView)
+        bgContentView.addSubview(panComparisonView)
         panComparisonView.snp.makeConstraints { make in
             make.height.equalTo(k_ScreenHeight)
             make.leading.trailing.equalTo(0)
@@ -64,3 +65,21 @@ class TSAIPhotoDetailsBrowserCell: TSBaseCollectionCell {
     }
     
 }
+
+
+extension TSAIPhotoDetailsBrowserCell {
+    func addVideoView(){
+        self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: self.model.response.videoURL)
+        self.bgContentView.addSubview(self.videoPlayerVC!.view)
+        self.videoPlayerVC!.view.snp.remakeConstraints { make in
+            make.center.equalToSuperview()
+            make.width.equalTo(k_ScreenWidth)
+            make.height.equalTo(k_ScreenHeight)
+        }
+    }
+    
+    func removeVideoView(){
+        videoPlayerVC?.view.removeFromSuperview()
+    }
+
+}

+ 23 - 8
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserVC.swift

@@ -102,14 +102,29 @@ class TSAIPhotoDetailsBrowserVC: TSBaseVC {
     //保存功能
     @objc func clickSaveBtn(){
         guard let infoModel = currentModel else { return }
-        TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.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)
+        if infoModel.isVideo{
+            TSDownloadManager.getDownLoadVideo(urlString: infoModel.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 {
+                            kSaveSuccesswShared.show(atView:self.view)
+                        }else{
+                            debugPrint(error)
+                        }
+                    }
+                }
+            }
+        }else{
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.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)
+                        }
                     }
                 }
             }

+ 27 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsBrowserVideoCell.swift

@@ -0,0 +1,27 @@
+//
+//  TSAIPhotoDetailsBrowserVideoCell.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+//class TSAIVideoBrowseCell : TSBaseCollectionCell{
+//
+//    var videoPlayerVC: TSAIListVideoPlayerVC?
+//    override func creatUI() {
+//
+//    }
+//    
+//    var model:TSActionInfoModel = TSActionInfoModel(){
+//        didSet{
+//            self.videoPlayerVC?.view.removeFromSuperview()
+//            self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: self.model.videoURL)
+//            self.bgContentView.addSubview(self.videoPlayerVC!.view)
+//            self.videoPlayerVC!.view.snp.remakeConstraints { make in
+//                make.center.equalToSuperview()
+//                make.width.equalTo(k_ScreenWidth)
+//                make.height.equalTo(k_ScreenHeight)
+//            }
+//        }
+//    }
+//}

+ 53 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Image.swift

@@ -0,0 +1,53 @@
+//
+//  Untitled.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+extension TSAIPhotoDetailsVC {
+    
+    
+    func setUpPhotoSomeView(){
+        contentView.addSubview(panComparisonView)
+        panComparisonView.snp.makeConstraints { make in
+            make.height.equalTo(k_ScreenHeight)
+            make.leading.trailing.equalTo(0)
+            make.centerY.equalToSuperview()
+        }
+    }
+    
+    
+    func uploadPanComparisonView(){
+        guard let infoModel = infoModel else { return }
+        DispatchQueue.global(qos: .userInitiated).async {
+            var oldImage:UIImage?
+            var newImage:UIImage?
+            let grounp = DispatchGroup()
+            grounp.enter()
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.request.imageUrl) { image in
+                grounp.leave()
+                oldImage = image
+                
+            }
+            
+            grounp.enter()
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.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)
+            }
+        }
+    }
+    
+}

+ 25 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Video.swift

@@ -0,0 +1,25 @@
+//
+//  TSAIPhotoDetailsVC+Video.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+extension TSAIPhotoDetailsVC {
+    
+    
+    func setVideoHidden(){
+        videoPlayerVC.removeFromParent()
+        videoPlayerVC.view.removeFromSuperview()
+    }
+    
+    func setVideoURL(){
+        self.panComparisonView.isHidden = true
+        guard let infoModel = infoModel else { return }
+        self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: infoModel.response.videoURL)
+        self.addChild(self.videoPlayerVC)
+        self.videoPlayerVC.view.frame = self.contentView.bounds
+        self.contentView.insertSubview(self.videoPlayerVC.view, at: 0)
+        self.videoPlayerVC.setControlsBottom(bottem: -80-k_Height_safeAreaInsetsBottom())
+    }
+}

+ 113 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+View.swift

@@ -0,0 +1,113 @@
+//
+//  TSAIPhotoDetailsVC+View.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+
+extension TSAIPhotoDetailsVC{
+    
+    
+//    func creatSwitchOriginalPictureBtn() -> 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
+//    }
+    
+    func creatSaveBtn() -> UIButton {
+        let saveBtn = kCreateNormalSubmitBtn(title: "Save".localized) { [weak self]  in
+            guard let self = self else { return }
+            clickSaveBtn()
+        }
+        return saveBtn
+    }
+    
+}
+
+
+
+
+
+
+//extension TSAIPhotoDetailsVC{
+//    @objc func switchOriginalPictureTouchDown() {
+//    //        if viewModel.generatorModel.generatorStyle == .photoExpand {
+//    //            expandAreaView.onlyBgImage(only: false)
+//    //        }else{
+//    //        guard let infoModel = infoModel else { return }
+//    //        self.netWorkImageView.setAsyncImage(urlString: infoModel.request.imageUrl,placeholder:kPlaceholderImage)
+//    //        }
+//    }
+//
+//    @objc func switchOriginalPictureTouchUp() {
+//        guard let infoModel = infoModel else { return }
+//        
+//    //        if viewModel.generatorModel.generatorStyle == .photoExpand {
+//    //            expandAreaView.onlyBgImage(only: true)
+//    //        }else{
+//    //            self.netWorkImageView.setAsyncImage(urlString:infoModel.response.resultUrl,placeholder:kPlaceholderImage)
+//    //        }
+//    }
+//}
+
+
+
+//    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.infoModel?.response.resultUrl,
+//                   let url = URL(string: resultUrl){
+//                    ImageCache.default.store(image, forKey: url.cacheKey)
+//                }
+//            }
+//        }
+//        rotatingPictureBtn.isHidden = true
+//        return rotatingPictureBtn
+//    }()
+//        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)
+//        }
+
+
+//        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)
+//        }
+//    }
+
+
+//extension TSAIListPhotoGeneratorVC {
+//    
+//    func setExpandAreaImage(){
+////        if viewModel.generatorModel.generatorStyle == .photoExpand {
+////            netWorkImageView.image = nil
+////            expandAreaView.bgImageView.setAsyncImage(urlString: infoModel?.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
+////            expandAreaView.showImageView.image = self.viewModel.generatorModel.upLoadImage
+////        }
+//    }
+//}

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

@@ -0,0 +1,129 @@
+//
+//  TSAIPhotoDetailsVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/11.
+//
+
+class TSAIPhotoDetailsVC: TSBaseVC {
+    var deleteBlock:(()->Void)?
+    var infoModel:TSActionInfoModel?{
+        didSet{
+            updateImageView()
+        }
+    }
+
+    lazy var bottomViewH = 60+k_Height_safeAreaInsetsBottom()
+    lazy var panComparisonView : TSImageIPanComparisonView = TSImageIPanComparisonView()
+    var videoPlayerVC: TSAIListVideoPlayerVC = TSAIListVideoPlayerVC(videoURL: URL(string: "www.baidu.com")!)
+    lazy var expandAreaView: TSAIExpandChangeView = TSAIExpandChangeView()
+//    lazy var switchOriginalPictureBtn: TSUIExpandedTouchButton = creatSwitchOriginalPictureBtn()
+    lazy var saveBtn: UIButton = creatSaveBtn()
+    var navRightBtn:UIButton = UIButton()
+    
+    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)
+        navRightBtn = setNavigationItem("", imageName: "ai_delete", direction: .right, action: #selector(clickNavRight))
+        contentView.snp.updateConstraints { make in
+            make.top.equalTo(0)
+        }
+
+        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)
+//        }
+
+        saveBtn.setTitleImageSpace(spacing: 0)
+    
+        setUpPhotoSomeView()
+    }
+    
+
+
+    //保存功能
+    @objc func clickSaveBtn(){
+        guard let infoModel = infoModel else { return }
+        if infoModel.isVideo{
+            TSDownloadManager.getDownLoadVideo(urlString: infoModel.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 {
+                            kSaveSuccesswShared.show(atView:self.view)
+                        }else{
+                            debugPrint(error)
+                        }
+                    }
+                }
+            }
+        }else{
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.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)
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    override func navBarClickLeftAction() {
+        dismiss(animated: true)
+    }
+    
+    @objc func clickNavRight() {
+
+        TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
+            message: "Are you sure to delete?".localized,
+            cancelTitle: "Delete".localized,
+            cancelColor: .red,
+            confirmTitle: "Retain".localized,
+            confirmColor: .white,
+            cancelAction: { [weak self]  in
+                guard let self = self else { return }
+                self.deleteBlock?()
+                self.navBarClickLeftAction()
+            }
+        ))
+    }
+}
+
+
+extension TSAIPhotoDetailsVC {
+    
+    func updateImageView(){
+        kMainAsync {
+            guard let infoModel = self.infoModel else { return }
+            if infoModel.isVideo {
+                self.setVideoURL()
+            }else{
+                self.uploadPanComparisonView()
+            }
+        }
+
+    }
+}

+ 37 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/Model/TSAIListPhotoGeneratorModel.swift

@@ -0,0 +1,37 @@
+//
+//  TSAIListPhotoGeneratorModel.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+class TSAIListPhotoGeneratorModel {
+    var upLoadImage:UIImage
+    var generatorStyle:TSGeneratorImageStyle
+    var expandEdge:UIEdgeInsets
+    var expandViewSizes:(CGSize,CGSize)?
+    var additionalPrompt:String//追加的提示词
+    
+    //预测宝宝
+    var upLoadImages:[UIImage]?
+    
+    init(upLoadImage: UIImage,
+         generatorStyle: TSGeneratorImageStyle,
+         expandEdge:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0),
+         expandViewSizes:(CGSize,CGSize)? = nil,
+         additionalPrompt:String = "",
+         upLoadImages:[UIImage]? = nil
+    ) {
+        self.upLoadImage = upLoadImage
+        self.generatorStyle = generatorStyle
+        self.expandEdge = expandEdge
+        self.expandViewSizes = expandViewSizes
+        self.additionalPrompt = additionalPrompt
+        self.upLoadImages = upLoadImages
+    }
+    
+    var prompt:String = ""
+    var inputText:String = ""
+    var upLoadImageUrl:String?
+    var model:String = ""   //决定生图的模型
+}

+ 1 - 86
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift

@@ -6,43 +6,11 @@
 //
 
 import Kingfisher
-class TSAIListPhotoGeneratorModel {
-    var upLoadImage:UIImage
-    var generatorStyle:TSGeneratorImageStyle
-    var expandEdge:UIEdgeInsets
-    var expandViewSizes:(CGSize,CGSize)?
-    var additionalPrompt:String//追加的提示词
-    
-    //预测宝宝
-    var upLoadImages:[UIImage]?
-    
-    init(upLoadImage: UIImage,
-         generatorStyle: TSGeneratorImageStyle,
-         expandEdge:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0),
-         expandViewSizes:(CGSize,CGSize)? = nil,
-         additionalPrompt:String = "",
-         upLoadImages:[UIImage]? = nil
-    ) {
-        self.upLoadImage = upLoadImage
-        self.generatorStyle = generatorStyle
-        self.expandEdge = expandEdge
-        self.expandViewSizes = expandViewSizes
-        self.additionalPrompt = additionalPrompt
-        self.upLoadImages = upLoadImages
-    }
-    
-    var prompt:String = ""
-    var inputText:String = ""
-    var upLoadImageUrl:String?
-    var model:String = ""   //决定生图的模型
-}
-
 class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
     var generatorModel:TSAIListPhotoGeneratorModel
     init(generatorModel:TSAIListPhotoGeneratorModel,infoModel:TSActionInfoModel? = nil,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.complete = complete
         self.generatorModel = generatorModel
-//        self.viewModel = TSAIListPhotoGeneratorBaseVM(generatorModel: generatorModel)
         super.init()
         self.infoModel = infoModel
     }
@@ -50,8 +18,6 @@ class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
         fatalError("init(coder:) has not been implemented")
     }
     
-    
-    
     var complete:((TSActionInfoModel)->Void)
     var backstageBlock:(()->Void)?
     
@@ -174,26 +140,18 @@ class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
     }
 
     func cancelDidmiss(){
-//        viewModel.cancelAllRequest()
         operation?.cancel()
         self.dismiss(animated: true, completion: nil)
     }
     //重新生成
     @objc func clickRegenerateBtn(){
-        //判断 vip
-        if kJudgeVip(externalBool: true , vc: self){ return }
         
-//        viewModel.uploadAndCreatImage()
+        if kJudgeVip(externalBool: true , vc: self){ return }//判断 vip
         generatorOperation()
     }
 
     override func dealThings() {
         self.uuidString = UUID().uuidString
-//        viewModel.uploadAndCreatImage()
-//        viewModel.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
-//            guard let self = self else { return }
-//            self.upDateView(state: state, model: model)
-//        }.store(in: &cancellable)
         generatorOperation()
     }
     
@@ -253,7 +211,6 @@ extension TSAIListPhotoGeneratorVC {
     }
 }
 extension TSAIListPhotoGeneratorVC {
-    
     func upDateView(state:TSProgressState,model:TSActionInfoModel?){
         progressState = state
         switch state {
@@ -274,7 +231,6 @@ extension TSAIListPhotoGeneratorVC {
     
     func showProgress(text:String) {
         generateInView.updateShowProgress(text: text)
-//        setVideoHidden()
     }
     
     func showLoading(){
@@ -287,50 +243,9 @@ extension TSAIListPhotoGeneratorVC {
     
     func showSuccess(model:TSActionInfoModel){
         generateInView.updateShowSuccess()
-
         infoModel = model
-//        if viewModel.generatorModel.generatorStyle == .futureBaby {
-//            rotatingPictureBtn.isHidden = false
-//        }else{
-//            switchOriginalPictureBtn.isHidden = false
-//        }
         if let model = infoModel {
             complete(model)
         }
-        
-//        setVideoURL()
-//        setExpandAreaImage()
-    }
-}
-
-extension TSAIListPhotoGeneratorVC {
-    func setVideoHidden(){
-//        if viewModel.generatorModel.generatorStyle == .photoLive {
-//            videoPlayerVC.removeFromParent()
-//            videoPlayerVC.view.removeFromSuperview()
-//        }
-    }
-    
-    func setVideoURL(){
-//        if viewModel.generatorModel.generatorStyle == .photoLive {
-//            if let model = infoModel {
-//                switchOriginalPictureBtn.isHidden = true
-//                self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: model.videoURL)
-//                self.addChild(self.videoPlayerVC)
-//                self.videoPlayerVC.view.frame = self.netWorkImageView.bounds
-//                self.netWorkImageView.addSubview(self.videoPlayerVC.view)
-//                self.videoPlayerVC.setControlsBottom(bottem: -20)
-//            }
-//        }
-    }
-}
-extension TSAIListPhotoGeneratorVC {
-    
-    func setExpandAreaImage(){
-//        if viewModel.generatorModel.generatorStyle == .photoExpand {
-//            netWorkImageView.image = nil
-//            expandAreaView.bgImageView.setAsyncImage(urlString: infoModel?.response.resultUrl,placeholder:kPlaceholderImage,backgroundColor:netWorkImageView.backgroundColor!)
-//            expandAreaView.showImageView.image = self.viewModel.generatorModel.upLoadImage
-//        }
     }
 }

+ 21 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Image.swift

@@ -0,0 +1,21 @@
+//
+//  TSAIUploadPhotoVC+Image.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+extension TSAIUploadPhotoVC {
+    
+    func setUpImageUploadView(){
+        //添加上传一大块
+        cusStackView.addSubviewToStack(uploadImageBgView)
+        uploadImageBgView.snp.makeConstraints { make in
+            make.width.equalTo(k_ScreenWidth)
+            make.height.equalTo(k_ScreenHeight-76-k_Height_safeAreaInsetsBottom()-k_Nav_Height)
+        }
+        
+    }
+    
+    
+}

+ 31 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Video.swift

@@ -0,0 +1,31 @@
+//
+//  TSAIUploadPhotoVC+Video.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+extension TSAIUploadPhotoVC {
+    
+    func creatTextView() -> TSAIUploadPhotoTextView {
+        let textView = TSAIUploadPhotoTextView()
+        textView.placeholderTextView.textViewTextChanged = { [weak self] text in
+            guard let self = self else { return }
+            additionalPrompt = text
+        }
+        return textView
+    }
+    
+}
+
+extension TSAIUploadPhotoVC {
+    func setUpVideoUploadView(){
+        cusStackView.addSubviewToStack(uploadImageBgView)
+        uploadImageBgView.snp.makeConstraints { make in
+            make.width.equalTo(k_ScreenWidth)
+            make.height.equalTo(k_ScreenHeight-212-k_Height_safeAreaInsetsBottom()-k_Nav_Height)
+        }
+        cusStackView.addSpacing(length: 32)
+        cusStackView.addSubviewToStack(self.textView)
+    }
+}

+ 183 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+View.swift

@@ -0,0 +1,183 @@
+//
+//  TSAIUploadPhotoVC+View.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+extension TSAIUploadPhotoVC {
+    
+    func creatUploadImageBgView() -> UIView {
+        let bgView = UIView()
+        bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(clickBgView)))
+        let bgImageView = UIImageView.createImageView(imageName: "ailist_upload_big_bg")
+        bgImageView.contentMode = .scaleToFill
+        bgView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.leading.bottom.trailing.top.equalTo(0)
+        }
+
+        bgView.addSubview(upLoadView)
+        upLoadView.snp.makeConstraints { make in
+            make.top.equalTo(244*kDesignScale)
+            make.centerX.equalToSuperview()
+            make.width.lessThanOrEqualTo(k_ScreenWidth - 80)
+        }
+        uploadImageView.contentMode = .scaleAspectFit
+        bgView.addSubview(uploadImageView)
+        uploadImageView.snp.makeConstraints { make in
+            make.top.leading.equalTo(0)
+            make.bottom.trailing.equalTo(0)
+        }
+        
+        return bgView
+    }
+    
+    
+    func creatUpLoadView() -> UIView {
+        let bgView = UIView()
+        
+        let addImageView = UIImageView.createImageView(imageName: "add")
+        bgView.addSubview(addImageView)
+        addImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalToSuperview()
+            make.width.height.equalTo(24)
+        }
+        
+        let textLabel = UILabel.createLabel(text: "Upload Photo".localized,font: .font(size: 16),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        bgView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(addImageView.snp.bottom).offset(16)
+            make.leading.equalTo(18)
+            make.trailing.equalTo(-18)
+        }
+        
+        let subInfoLabel = UILabel.createLabel(text: "Select an image with face fully visible".localized,font: .font(size: 12),textColor: UIColor.white.withAlphaComponent(0.6),textAlignment: .center,numberOfLines: 0)
+        bgView.addSubview(subInfoLabel)
+        
+        subInfoLabel.snp.makeConstraints { make in
+            make.top.equalTo(textLabel.snp.bottom).offset(8)
+            make.leading.equalTo(18)
+            make.trailing.equalTo(-18)
+            make.bottom.equalToSuperview()
+        }
+        
+        return bgView
+    }
+}
+
+extension TSAIUploadPhotoVC {
+    
+    func creatSubmitBtn() -> UIButton {
+        let submitBtn = kCreateNormalSubmitBtn(title: generatorStyle.generatorBtnTitle) { [weak self]  in
+            guard let self = self else { return }
+            generateImage()
+        }
+        kSetBtnVipIcon(btn: submitBtn, show: true)
+        return submitBtn
+    }
+    
+    func creatDeleteBtn() -> UIButton {
+        let deleteBtn = UIButton.createButton(backgroundImage: UIImage(named: "delete_redRound")) { [weak self]  in
+            guard let self = self else { return }
+            upLoadImage = nil
+        }
+        deleteBtn.isHidden = true
+        return deleteBtn
+    }
+}
+
+
+extension TSAIUploadPhotoVC {
+    func pickSinglePhoto(complete: @escaping (UIImage)->Void)  {
+        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+            guard let self = self else { return }
+            if let errorString = errorString {
+                TSToastShared.showToast(text: errorString)
+            }else if let image = image {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+            kDelayMainShort {
+                self.photoPickerManager.dismissPageVC()
+            }
+            
+        }
+    }
+}
+
+
+
+
+
+//lazy var segmentedView: BetterSegmentedControl = {
+//    let segmentedView = BetterSegmentedControl(
+//        frame: .zero,
+//        segments:
+//            LabelSegment.segments(
+//                withTitles: ["Female".localized,"Male".localized,"Random".localized],
+//                normalFont: .font(size: 12.0),
+//                normalTextColor: .white.withAlphaComponent(0.4),
+//                selectedFont: .font(size: 12.0),
+//                selectedTextColor: "#111111".uiColor),
+//        options:[.backgroundColor(.white.withAlphaComponent(0.1)),
+//                 .indicatorViewBackgroundColor(.white),
+//                 .indicatorViewInset(2),
+//                 .cornerRadius(20.0),
+//                 .animationSpringDamping(1.0)]
+//    )
+//    segmentedView.addTarget(self,action: #selector(segmentedControlValueChanged(_:)),for: .valueChanged)
+//    return segmentedView
+//}()
+//var additionalPrompt = ",female"
+//@objc func segmentedControlValueChanged(_ sender: BetterSegmentedControl) {
+//    switch sender.index {
+//    case 0:
+//        additionalPrompt = ",female"//女
+//    case 1:
+//        additionalPrompt = ",male"//男
+//    default:
+//        additionalPrompt = ""
+//    }
+//}
+
+//        if generatorStyle == .catTohuman {
+//            cusStackView.addSpacing(length: 9)
+//            cusStackView.addSubviewToStackWhiteBoard(segmentedView, length: 46)
+//            segmentedView.snp.makeConstraints { make in
+//                make.width.equalTo(k_ScreenWidth-70)
+//                make.height.equalTo(40)
+//                make.center.equalToSuperview()
+//            }
+//        }else{
+    //文字信息区域
+//            cusStackView.addSubviewToStack(getTextInfoCell(text: "Single photo with face fully visible".localized))
+//            cusStackView.addSpacing(length: lineSpacing)
+//            cusStackView.addSubviewToStack(getTextInfoCell(text: "No group photos, covered faces, nudes".localized))
+//        }
+
+//
+//func getTextInfoCell(text:String) -> UIView {
+//
+//let bgView = UIView()
+//let pointView = UIView()
+//pointView.backgroundColor = .white.withAlphaComponent(0.7)
+//pointView.cornerRadius = 1
+//bgView.addSubview(pointView)
+//pointView.snp.makeConstraints { make in
+//    make.top.equalTo(7)
+//    make.leading.equalTo(22)
+//    make.width.height.equalTo(2)
+//}
+//let textLabel1 = UILabel.createLabel(text: text,font: .font(size: 12),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
+//textLabel1.setLineSpacing(lineSpacing)
+//bgView.addSubview(textLabel1)
+//textLabel1.snp.makeConstraints { make in
+//    make.top.bottom.equalToSuperview()
+//    make.leading.equalTo(16+16)
+//    make.trailing.equalTo(-16)
+//}
+//return bgView
+//}

+ 58 - 230
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift

@@ -22,36 +22,28 @@ class TSAIUploadPhotoVC: TSBaseVC {
         fatalError("init(coder:) has not been implemented")
     }
     
-    lazy var viewModel: TSAIListVM = {
-        let viewModel = TSAIListVM(target: self)
-        return viewModel
-    }()
+
+    //###### UI ######
+    lazy var cusStackView: TSCustomStackView = TSCustomStackView(axis: .vertical,spacing: 0)
+
+    //上传区域
+    lazy var upLoadView: UIView = creatUpLoadView()
+    lazy var uploadImageView: UIImageView = UIImageView()
+    lazy var uploadImageBgView: UIView = creatUploadImageBgView()
+    //视频描述
+    lazy var textView: TSAIUploadPhotoTextView = creatTextView()
     
-    //#####################################数据区#####################################
-    let lineSpacing = 6.0
-    lazy var photoPickerManager: TSPhotoPickerManager = {
-        let photoPickerManager = TSPhotoPickerManager(viewController: self)
-        return photoPickerManager
-    }()
+    //提交 btn
+    lazy var submitBtn: UIButton = creatSubmitBtn()
+    //删除按钮
+    lazy var deleteBtn: UIButton = creatDeleteBtn()
     
+    //###### 数据区 ######
+    let lineSpacing = 6.0
+    lazy var photoPickerManager: TSPhotoPickerManager = TSPhotoPickerManager(viewController: self)
     var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .colorizeConfig)
-    //#####################################底部基础#####################################
-    lazy var cusStackView: TSCustomStackView = {
-        let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
-        return cusStackView
-    }()
+    lazy var viewModel: TSAIListVM = TSAIListVM(target: self)
 
-    
-    lazy var submitBtn: UIButton = {
-        let submitBtn = kCreateNormalSubmitBtn(title: generatingText) { [weak self]  in
-            guard let self = self else { return }
-            generateImage()
-        }
-        kSetBtnVipIcon(btn: submitBtn, show: true)
-        return submitBtn
-    }()
-
-    //#####################################上传 view#####################################
     var upLoadImage:UIImage? = nil {
         didSet{
             if let image = upLoadImage {
@@ -69,123 +61,15 @@ class TSAIUploadPhotoVC: TSBaseVC {
             }
         }
     }
-    
-    
-    lazy var subInfoLabel: UILabel = {
-        let textLabel = UILabel.createLabel(text: "Select an image with face fully visible".localized,font: .font(size: 12),textColor: UIColor.white.withAlphaComponent(0.6),textAlignment: .center,numberOfLines: 0)
-        return textLabel
-    }()
-    
-    lazy var upLoadView: UIView = {
-        let bgView = UIView()
-        
-        let addImageView = UIImageView.createImageView(imageName: "add")
-        bgView.addSubview(addImageView)
-        addImageView.snp.makeConstraints { make in
-            make.top.equalTo(0)
-            make.centerX.equalToSuperview()
-            make.width.height.equalTo(24)
-        }
-        
-        let textLabel = UILabel.createLabel(text: "Upload Photo".localized,font: .font(size: 16),textColor: .white,textAlignment: .center,numberOfLines: 0)
-        bgView.addSubview(textLabel)
-        textLabel.snp.makeConstraints { make in
-            make.top.equalTo(addImageView.snp.bottom).offset(16)
-            make.leading.equalTo(18)
-            make.trailing.equalTo(-18)
-        }
-        
-        bgView.addSubview(subInfoLabel)
-        subInfoLabel.snp.makeConstraints { make in
-            make.top.equalTo(textLabel.snp.bottom).offset(8)
-            make.leading.equalTo(18)
-            make.trailing.equalTo(-18)
-            make.bottom.equalToSuperview()
-        }
-        
-        return bgView
-    }()
 
-    lazy var uploadImageView: UIImageView = {
-        let uploadImageView = UIImageView()
-        uploadImageView.contentMode = .scaleAspectFit
-        return uploadImageView
-    }()
-    
-    
-    lazy var uploadImageBgView: UIView = {
-        
-        let bgView = UIView()
-        bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(clickBgView)))
-        let bgImageView = UIImageView.createImageView(imageName: "ailist_upload_big_bg")
-        bgImageView.contentMode = .scaleToFill
-        bgView.addSubview(bgImageView)
-        bgImageView.snp.makeConstraints { make in
-            make.leading.bottom.trailing.top.equalTo(0)
-        }
-
-        bgView.addSubview(upLoadView)
-        upLoadView.snp.makeConstraints { make in
-            make.top.equalTo(244*kDesignScale)
-            make.centerX.equalToSuperview()
-            make.width.lessThanOrEqualTo(k_ScreenWidth - 80)
-        }
-
-        bgView.addSubview(uploadImageView)
-        uploadImageView.snp.makeConstraints { make in
-            make.top.leading.equalTo(0)
-            make.bottom.trailing.equalTo(0)
-        }
-        
-        return bgView
-    }()
-    
-    
-    lazy var deleteBtn: UIButton = {
-        let deleteBtn = UIButton.createButton(backgroundImage: UIImage(named: "delete_redRound")) { [weak self]  in
-            guard let self = self else { return }
-            upLoadImage = nil
-        }
-        deleteBtn.isHidden = true
-        return deleteBtn
-    }()
-
-    lazy var segmentedView: BetterSegmentedControl = {
-        let segmentedView = BetterSegmentedControl(
-            frame: .zero,
-            segments:
-                LabelSegment.segments(
-                    withTitles: ["Female".localized,"Male".localized,"Random".localized],
-                    normalFont: .font(size: 12.0),
-                    normalTextColor: .white.withAlphaComponent(0.4),
-                    selectedFont: .font(size: 12.0),
-                    selectedTextColor: "#111111".uiColor),
-            options:[.backgroundColor(.white.withAlphaComponent(0.1)),
-                     .indicatorViewBackgroundColor(.white),
-                     .indicatorViewInset(2),
-                     .cornerRadius(20.0),
-                     .animationSpringDamping(1.0)]
-        )
-        segmentedView.addTarget(self,action: #selector(segmentedControlValueChanged(_:)),for: .valueChanged)
-        return segmentedView
-    }()
-    var additionalPrompt = ",female"
-    @objc func segmentedControlValueChanged(_ sender: BetterSegmentedControl) {
-        switch sender.index {
-        case 0:
-            additionalPrompt = ",female"//女
-        case 1:
-            additionalPrompt = ",male"//男
-        default:
-            additionalPrompt = ""
-        }
-    }
+    var additionalPrompt = ""
     
     override func createView() {
         
         addNormalNavBarView()
         setPageTitle(titleString)
         _ = setNavigationItem("", imageName: "replace_photo", direction: .right, action: #selector(clickNavRight))
+        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickView)))
         
         contentView.addSubview(submitBtn)
         submitBtn.snp.makeConstraints { make in
@@ -206,97 +90,37 @@ class TSAIUploadPhotoVC: TSBaseVC {
         
         let image = upLoadImage
         upLoadImage = image
-        
-        subInfoLabel.isHidden =  true
     }
 
     
     override func dealThings() {
-        kSetBtnVipIcon(btn: self.submitBtn, show: true)
+        // 监听键盘事件
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
     }
     
 }
 
 extension TSAIUploadPhotoVC {
-    
     func setUpStackView(){
-        //添加上传一大块
-        cusStackView.addSubviewToStack(uploadImageBgView)
-        uploadImageBgView.snp.makeConstraints { make in
-            make.width.equalTo(k_ScreenWidth)
-            make.height.equalTo(k_ScreenHeight-76-k_Height_safeAreaInsetsBottom()-k_Nav_Height)
+        if generatorStyle == .creatVideo {
+            setUpVideoUploadView()
+        }else{
+            setUpImageUploadView()
         }
-        
-//        if generatorStyle == .catTohuman {
-//            cusStackView.addSpacing(length: 9)
-//            cusStackView.addSubviewToStackWhiteBoard(segmentedView, length: 46)
-//            segmentedView.snp.makeConstraints { make in
-//                make.width.equalTo(k_ScreenWidth-70)
-//                make.height.equalTo(40)
-//                make.center.equalToSuperview()
-//            }
-//        }else{
-            //文字信息区域
-//            cusStackView.addSubviewToStack(getTextInfoCell(text: "Single photo with face fully visible".localized))
-//            cusStackView.addSpacing(length: lineSpacing)
-//            cusStackView.addSubviewToStack(getTextInfoCell(text: "No group photos, covered faces, nudes".localized))
-//        }
-
     }
     
-    func getTextInfoCell(text:String) -> UIView {
-        
-        let bgView = UIView()
-        let pointView = UIView()
-        pointView.backgroundColor = .white.withAlphaComponent(0.7)
-        pointView.cornerRadius = 1
-        bgView.addSubview(pointView)
-        pointView.snp.makeConstraints { make in
-            make.top.equalTo(7)
-            make.leading.equalTo(22)
-            make.width.height.equalTo(2)
-        }
-        let textLabel1 = UILabel.createLabel(text: text,font: .font(size: 12),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
-        textLabel1.setLineSpacing(lineSpacing)
-        bgView.addSubview(textLabel1)
-        textLabel1.snp.makeConstraints { make in
-            make.top.bottom.equalToSuperview()
-            make.leading.equalTo(16+16)
-            make.trailing.equalTo(-16)
-        }
-        return bgView
+    @objc func clickView() {
+        self.view.endEditing(true)
     }
     
-    var generatingText:String{
-        
-        
-        switch generatorStyle {
-        case .enhance:
-            return "Enhance Photo".localized
-        case .colorize:
-            return "Colorize Photo".localized
-        case .descratch:
-            return "Descratch Photo".localized
-        case .enlighten:
-            return "Enlighten Photo".localized
-        case .recreate:
-            return "Recreate Photo".localized
-        default:
-            return "Generate".localized
-        }
-        
-        
-        
-    }
-}
-
-extension TSAIUploadPhotoVC {
-
     @objc func clickNavRight() {
+        clickView()
         pickSinglePhoto()
     }
     
     @objc func clickBgView() {
+        clickView()
         pickSinglePhoto()
     }
     
@@ -308,45 +132,49 @@ extension TSAIUploadPhotoVC {
     }
 }
 
-
 extension TSAIUploadPhotoVC {
+        
+    var prompt:String{
+        if self.generatorStyle == .creatVideo {
+            if additionalPrompt.isEmpty {
+                return "Photo animation, Slight head turn, normal eye blinking, smile, realistic facial movement"
+            }
+            return additionalPrompt
+        }
+        return ""
+    }
     
     func generateImage() {
         if kJudgeVip(externalBool: true, vc: self){ return } //判断 vip
         guard let upLoadImage = upLoadImage else { return }
-//        if generatorStyle != .catTohuman {
-            additionalPrompt = ""
-//        }
-        let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel: TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)){ model in }
         
+        let generatorModel = TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)
+        generatorModel.prompt = prompt
         
+        let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel:generatorModel){ model in }
         gennerateVC.backstageBlock = { [weak self]  in
             guard let self = self else { return }
             TSAIListHistoryVC.showPosition()
             self.navigationController?.popToRootViewController(animated: false)
         }
-        
         kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
     }
 }
 
+extension TSAIUploadPhotoVC {
+    @objc func keyboardWillShow(_ notification: Notification) {
+        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
+        let scrollView = cusStackView.scrollView
+        let keyboardHeight = keyboardFrame.height - view.safeAreaInsets.bottom
+//        let textViewFrame = scrollView.convert(customTextView.frame, from: customTextView.superview)
+//        let scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
+        let y = keyboardHeight//(scrollView.bounds.height - keyboardHeight)
+        scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
+    }
 
-extension TSAIUploadPhotoVC{
-    
-    func pickSinglePhoto(complete: @escaping (UIImage)->Void)  {
-        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
-            guard let self = self else { return }
-            if let errorString = errorString {
-                TSToastShared.showToast(text: errorString)
-            }else if let image = image {
-                complete(image)
-            }else{
-                dePrint("图片异常")
-            }
-            kDelayMainShort {
-                self.photoPickerManager.dismissPageVC()
-            }
-            
-        }
+    // MARK: - 键盘隐藏时恢复
+
+    @objc private func keyboardWillHide(_ notification: Notification) {
+        cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
     }
 }

+ 59 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/View/TSAIUploadPhotoTextView.swift

@@ -0,0 +1,59 @@
+//
+//  TSAIUploadPhotoTextView.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/19.
+//
+
+class TSAIUploadPhotoTextView: TSBaseView {
+    
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel.createLabel(text: "Description".localized,font: .font(size: 16.0),textColor: .white)
+        return titleLabel
+    }()
+    
+    lazy var infoLabel: UILabel = {
+        let infoLabel = UILabel.createLabel(text: "(Optional)".localized,font: .font(size: 16.0),textColor: .white.withAlphaComponent(0.6))
+        return infoLabel
+    }()
+    
+    lazy var placeholderTextView: TSPlaceholderTextView = {
+        let placeholderTextView = TSPlaceholderTextView(
+            placeholder: "Describe your animation orleave it blank for Al to create the best motion foryour image.".localized,
+            font: .font(size: 14.0),
+            textColor: .white,
+            backgroundColor: "#333333".uiColor,
+            textInsets:UIEdgeInsets(top: 14, left: 12, bottom: 14, right: 12)
+        )
+        placeholderTextView.maxLength = 200
+        return placeholderTextView
+    }()
+    
+    
+    
+    override func creatUI() {
+        
+        contentView.addSubview(titleLabel)
+        contentView.addSubview(infoLabel)
+        contentView.addSubview(placeholderTextView)
+        
+        titleLabel.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(16)
+        }
+        
+        infoLabel.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(titleLabel.snp.trailing).offset(8)
+        }
+        
+        placeholderTextView.snp.makeConstraints { make in
+            make.top.equalTo(titleLabel.snp.bottom).offset(16)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(68.0)
+            make.bottom.equalTo(0)
+        }
+    }
+    
+}

+ 42 - 0
TSLiveWallpaper/Business/TSPurchaseMembershipVC/TSViewTool/PhotoManager.swift

@@ -145,3 +145,45 @@ class PhotoManager {
         }
     }
 }
+extension PhotoManager {
+    
+    /// 保存图片到相册
+    /// - Parameters:
+    ///   - image: 要保存的 UIImage
+    ///   - completion: 保存结果的回调,返回成功与否和错误信息
+    func saveVideoToAlbum(videoURL:URL, completion: @escaping (Bool, Error?) -> Void) {
+        // 检查相册权限
+        PHPhotoLibrary.requestAuthorization { status in
+            DispatchQueue.main.async {
+                switch status {
+                case .authorized:
+                    // 权限已授权,保存图片
+                    self.save(videoURL: videoURL, completion: completion)
+                case .limited:
+                    // 在受限权限下保存图片
+                    self.save(videoURL: videoURL, completion: completion)
+                case .denied, .restricted:
+                    // 权限被拒绝或受限
+                    completion(false, NSError(domain: "PhotoSaver", code: 1, userInfo: [NSLocalizedDescriptionKey: "Photo Library access is denied."]))
+                case .notDetermined:
+                    // 不会进入这个分支,因为已经请求了权限
+                    completion(false, NSError(domain: "PhotoSaver", code: 2, userInfo: [NSLocalizedDescriptionKey: "Photo Library access not determined."]))
+                @unknown default:
+                    completion(false, NSError(domain: "PhotoSaver", code: 3, userInfo: [NSLocalizedDescriptionKey: "Unknown authorization status."]))
+                }
+            }
+        }
+    }
+
+    /// 保存视频到相册的具体实现
+    private func save(videoURL:URL, completion: @escaping (Bool, Error?) -> Void) {
+        PHPhotoLibrary.shared().performChanges({
+            PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
+        }) { success, error in
+            DispatchQueue.main.async {
+                completion(success, error)
+            }
+        }
+    }
+    
+}

+ 2 - 0
TSLiveWallpaper/Common/TSNetWork/TSNetWork+Business.swift

@@ -21,6 +21,8 @@ enum TSNeURLType:String {
 //    case chatV2 = "/api/text/chat/v2"             //AI 对话接口V2,扩展了 DeepSeek 深度思考
 //    
     case config = "/api/ops/old-photo-config"       //App配置
+    case createVideo = "/api/video/create"               //视频生成
+    
 //
 //    case changeAge = "/api/image/change-age"       //换年龄
 //    case subscriptionApple = "/api/subscription/apple"       //苹果订阅

+ 174 - 0
TSLiveWallpaper/Common/Tool/TSBusinessFileManager.swift

@@ -0,0 +1,174 @@
+//
+//  TSBusinessFileManager.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/27.
+//
+
+class TSBusinessFileManager {
+    
+    /// 获取 Video 下载后保存的的文件件路径
+    static var saveVideoPathURL:URL = {
+        let saveRingPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("video")
+        return saveRingPathURL
+    }()
+    
+    static var saveCacheAllPathURL:URL = {
+        let saveRingPathURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("cacheAll")
+        return saveRingPathURL
+    }()
+    
+    public static func generateFileName(
+        urlString: String,
+        fileEx:String? = nil,
+    missingEx:String? = nil
+    )->String?{
+        guard let url = URL(string: urlString) else{
+            return nil
+        }
+        
+        var fileName = url.path.md5
+
+        // 使用 URL 的 MD5 哈希值作为缓存文件名,附加 URL 的后缀名
+        var fileExtension = ""
+        if let fileEx = fileEx {
+            fileExtension = fileEx
+        }else{
+            var missingExStr = ""
+            if let missingEx = missingEx {
+                missingExStr = missingEx
+            }
+            fileExtension = url.pathExtension.isEmpty ? missingExStr : url.pathExtension
+        }
+
+        if fileExtension.count > 0 {
+            fileName = url.path.md5 + ".\(fileExtension)"
+        }
+         
+        return fileName
+    }
+    
+    //获取 urlstring 本地的缓存 url path
+    public static func getLocalURL(
+        urlString: String,
+        fileEx:String? = nil,
+    missingEx:String? = nil)->URL?{
+        
+        guard let fileName = generateFileName(urlString: urlString,fileEx:fileEx,missingEx: missingEx) else{
+            return nil
+        }
+        
+        //检查文件是否已存在于缓存中
+        let ringFileURL = saveVideoPathURL.appendingPathComponent(fileName)
+        if FileManager.default.fileExists(atPath: ringFileURL.path) {
+            print("文件已存在于缓存中: \(ringFileURL)")
+            return ringFileURL
+        }
+        
+        let cachedFileURL = saveCacheAllPathURL.appendingPathComponent(fileName)
+        if FileManager.default.fileExists(atPath: cachedFileURL.path) {
+            print("文件已存在于缓存中: \(cachedFileURL)")
+            return cachedFileURL
+        }
+        
+        return nil
+    }
+    
+
+}
+
+//缓存路径
+extension TSBusinessFileManager {
+    
+    //检查 url 对不对
+    public static func generateLocalURL(
+        from urlString: String,
+        fileEx:String? = nil,
+        missingEx:String? = nil,
+        frontPathURL:URL,
+        completion:((String?, Error?) -> Void)? = nil
+    )->URL?
+    {
+        guard let url = URL(string: urlString) else{
+            completion?(nil, NSError(domain: "url null", code: 0))
+            return nil
+        }
+        
+        if !urlString.contains("http") && urlString.contains("/"){
+            completion?(urlString.fillCachePath, nil)
+            return nil
+        }
+        
+        let fileManager = FileManager.default
+        let cacheAllDirectory = frontPathURL
+        
+        // 创建 `cacheAll` 文件夹(如果不存在)
+        if !fileManager.fileExists(atPath: cacheAllDirectory.path) {
+            do {
+                try fileManager.createDirectory(at: cacheAllDirectory, withIntermediateDirectories: true, attributes: nil)
+            } catch {
+                completion?(nil, error)
+                return nil
+            }
+        }
+        
+        
+        guard let fileName = generateFileName(urlString: urlString,fileEx:fileEx,missingEx: missingEx) else{
+            completion?(nil, NSError(domain: "url error", code: 0))
+            return nil
+        }
+        
+        let cachedFileURL = cacheAllDirectory.appendingPathComponent(fileName)
+        return cachedFileURL
+    }
+    
+}
+
+//缓存路径
+extension TSBusinessFileManager {
+    
+    //检查 url 对不对
+    public static func generateCachesURL(
+        from urlString: String,
+        fileEx:String? = nil,
+    missingEx:String? = nil,
+        cacheDirectory:String = "cacheAll",
+        completion:((String?, Error?) -> Void)? = nil
+    )->URL?
+    {
+        guard let url = URL(string: urlString) else{
+            completion?(nil, NSError(domain: "url null", code: 0))
+            return nil
+        }
+        
+        if !urlString.contains("http") && urlString.contains("/"){
+            completion?(urlString.fillCachePath, nil)
+            return nil
+        }
+        
+        let fileManager = FileManager.default
+        
+        // 获取缓存目录下的 `cacheAll` 文件夹路径
+        let cachesDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
+        let cacheAllDirectory = cachesDirectory.appendingPathComponent(cacheDirectory)
+        
+        // 创建 `cacheAll` 文件夹(如果不存在)
+        if !fileManager.fileExists(atPath: cacheAllDirectory.path) {
+            do {
+                try fileManager.createDirectory(at: cacheAllDirectory, withIntermediateDirectories: true, attributes: nil)
+            } catch {
+                completion?(nil, error)
+                return nil
+            }
+        }
+        
+        
+        guard let fileName = generateFileName(urlString: urlString,fileEx:fileEx,missingEx: missingEx) else{
+            completion?(nil, NSError(domain: "url error", code: 0))
+            return nil
+        }
+
+        let cachedFileURL = cacheAllDirectory.appendingPathComponent(fileName)
+        return cachedFileURL
+    }
+}

+ 46 - 0
TSLiveWallpaper/Common/Tool/TSDownloadManager.swift

@@ -0,0 +1,46 @@
+//
+//  TSPublicContent.swift
+//  AIRingtone
+//
+//  Created by 100Years on 2025/3/20.
+//
+
+
+import AVFoundation
+import Alamofire
+
+class TSDownloadManager {
+    
+    static func getDownLoadVideo(urlString:String,progressHandler: ((Double) -> Void)? = nil,complete:@escaping (URL?,Bool)->Void){
+        if let path = TSBusinessFileManager.getLocalURL(urlString: urlString,fileEx:nil,missingEx: "mp4") {
+            complete(path,false)
+        }else{
+            _ = TSDownloadManager.downloadVideo(urlString:urlString,missingEx: "mp4",progressHandler: progressHandler) { url, error in
+                if let path = url {
+                    complete(path,true)
+                }else{
+                    complete(nil,true)
+                }
+            }
+        }
+    }
+    
+    static func downloadVideo(
+        urlString: String,
+        fileEx:String? = nil,
+    missingEx:String? = nil,
+        progressHandler: ((Double) -> Void)? = nil,
+        completion: @escaping (URL?, Error?) -> Void
+    ) -> DownloadRequest? {
+        
+        if let fileName = TSBusinessFileManager.getLocalURL(urlString: urlString,fileEx:fileEx,missingEx:missingEx){
+            completion(fileName,nil)
+            return nil
+        }
+        guard let savePath = TSBusinessFileManager.generateLocalURL(from: urlString, fileEx: fileEx, missingEx: missingEx,frontPathURL: TSBusinessFileManager.saveVideoPathURL,completion: { string, error in
+            completion(nil,error)
+        })else { return nil }
+        
+        return TSNetworkShared.downloadFile(urlString: urlString,to: savePath, progressHandler:progressHandler,completion: completion)
+    }
+}

+ 18 - 26
TSLiveWallpaper/Data/Model/TSActionInfoModel.swift

@@ -24,6 +24,7 @@ class TSActionInfoModel: TSBaseModel {
             return ActionStatus(rawValue: string) ?? .failed
         }
     }
+    var uuid:String = UUID().uuidString
     var modelType:ModelType = .normal
     var id:Int = 0
     var actionType:String = ""
@@ -35,15 +36,9 @@ class TSActionInfoModel: TSBaseModel {
     var costTime:Int = 0
     var percent:Float = 0.0
     var actionStatus:ActionStatus = .failed
-    
-    
-    
-    var generateStyle:String = ""
-    
-    var videoThumbnailPath:String = ""
-    var videoPath:String = ""
-    
-    var uuid:String = UUID().uuidString
+    var generateStyle:String = ""//生成的类型
+
+
     override func mapping(map: ObjectMapper.Map) {
         modelType           <- map["modelType"]
         id           <- map["id"]
@@ -57,29 +52,17 @@ class TSActionInfoModel: TSBaseModel {
         percent     <- map["percent"]
         actionStatus      <- map["actionStatus"]
         actionStatus = ActionStatus.from(status)
-        videoThumbnailPath      <- map["videoThumbnailPath"]
-        videoPath      <- map["videoPath"]
         generateStyle      <- map["generateStyle"]
-        
-        
+
         uuid      <- map["uuid"]
     }
 }
 
 extension TSActionInfoModel {
     var isVideo:Bool{
-        return videoThumbnailPath.count > 0
+        return generateStyle == TSGeneratorImageStyle.creatVideo.rawValue
     }
 
-    var videoThumbnailURL: URL {
-        return URL("")!//videoThumbnailPath//.fillDocumentURL
-    }
-    
-    var videoURL: URL {
-        return URL("")!//videoPath//.fillDocumentURL
-    }
-    
-    
     var upImageURLExpired:Bool{
         if request.imageUrl.count == 0 {
             return true
@@ -125,14 +108,18 @@ class TSActionRequestModel : TSBaseModel {
 
 class TSActionResponseModel : TSBaseModel {
     var resultUrl:String = ""
-    var originalPath:String = ""    //原始的本地路径
-
+    var previewUrl:String = ""
+    var videoDocument:String = ""
+    
+    
     var code:Int = 0
     var vip:Bool = false
     
     override func mapping(map: ObjectMapper.Map) {
         resultUrl           <- map["resultUrl"]
-        originalPath           <- map["originalPath"]
+        previewUrl           <- map["previewUrl"]
+        videoDocument           <- map["videoDocument"]
+   
         vip                 <- map["vip"]
         code                <- map["code"]
     }
@@ -145,5 +132,10 @@ class TSActionResponseModel : TSBaseModel {
     var sensitiveError:Bool {
         return TSNetWorkCode.sensitiveError(code: code)
     }
+    
+    var videoURL: URL {
+        return videoDocument.fillDocumentURL
+    }
+    
 }
 

+ 60 - 36
TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift

@@ -141,51 +141,24 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
             }
             
             if let result = kNetWorkResultSuccess(data: data) {
-                if let genmojiModel = TSActionInfoModel(JSON: result) {
+                if let infoModel = TSActionInfoModel(JSON: result) {
                     
-                    if genmojiModel.actionStatus != .success {
-                        self.replaceSaveInfoModel(model: genmojiModel)
+                    if infoModel.actionStatus != .success {
+                        self.replaceSaveInfoModel(model: infoModel)
                     }
                     
-                    switch genmojiModel.actionStatus {
+                    switch infoModel.actionStatus {
                     case .success:
-                        
-                        let successBlock = { [weak self]  in
-                            guard let self = self else { return }
-                            self.replaceSaveInfoModel(model: genmojiModel)
-                            self.stateDatauPblished = (.success(nil),genmojiModel)
-                            generatingProgress = 0
-                            self.handleGenerateSuccess()
-                        }
-                        
-                        if URL(string:genmojiModel.response.resultUrl) != nil {
-                            let group = DispatchGroup()
-//                            group.enter()
-//                            downloadImage(urlString: genmojiModel.request.imageUrl) {
-//                                group.leave()
-//                            }
-                            
-//                            if let generateStyleModel = generateStyleModel {
-//                                TSImageStoreTool.storeImage(image: generateStyleModel.upLoadImage, urlString: genmojiModel.request.imageUrl)
-//                            }
-                  
-                            group.enter()
-                            downloadImage(urlString: genmojiModel.response.resultUrl) {
-                                group.leave()
-                            }
-                
-                            group.notify(queue: .main) {
-                                successBlock()
-                            }
-
+                        if URL(string:infoModel.response.resultUrl) != nil {
+                            downResultUrl(infoModel: infoModel)
                         }else{
-                            successBlock()
+                            handleSuccess(infoModel: infoModel)
                         }
                     case .failed:
                         debugPrint("getActionInfo error failed")
-                        handleFailInfoModel(errorString:genmojiModel.response.codeErrorMsg,code: genmojiModel.response.code)
+                        handleFailInfoModel(errorString:infoModel.response.codeErrorMsg,code: infoModel.response.code)
                     default:
-                        stateDatauPblished = (.progressString(generating(progress: genmojiModel.percent)),currentActionInfoModel)
+                        stateDatauPblished = (.progressString(generating(progress: infoModel.percent)),currentActionInfoModel)
                         if stopNetwork == false {
                             kDelayOnMainThread(2.0) {
                                 self.getActionInfo(action_id: action_id)
@@ -203,6 +176,57 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
     }
     
     
+    func handleSuccess(infoModel:TSActionInfoModel){
+        self.replaceSaveInfoModel(model: infoModel)
+        self.stateDatauPblished = (.success(nil),infoModel)
+        generatingProgress = 0
+        self.handleGenerateSuccess()
+    }
+    
+    func downResultUrl(infoModel:TSActionInfoModel){
+
+        if generateStyleModel?.generatorStyle == .creatVideo {
+            let group = DispatchGroup()
+            //下载视频源
+            group.enter()
+            downloadVideo(urlString: infoModel.response.resultUrl) { url in
+                if let url = url {
+                    infoModel.response.videoDocument = url.path.documentLastURLString
+                }
+                group.leave()
+            }
+            //下载封面图
+            group.enter()
+            TSImageStoreTool.downloadImageWithProgress(urlString: infoModel.response.previewUrl) { _ in
+                group.leave()
+            }
+
+            group.notify(queue: .main){[weak self]  in
+                guard let self = self else { return }
+                handleSuccess(infoModel: infoModel)
+            }
+
+        }else{
+            downloadImage(urlString: infoModel.response.resultUrl) { [weak self]  in
+                guard let self = self else { return }
+                handleSuccess(infoModel: infoModel)
+            }
+        }
+
+    }
+    
+    let generatingText:String = "Processing".localized
+    func downloadVideo(urlString:String,completion:@escaping (URL?)->Void){
+        TSDownloadManager.getDownLoadVideo(urlString: urlString) { progress in
+            let progressInt = Int(progress*10.0)
+            let progressString = "Processing".localized + " " + kPercentlocalized(90 + progressInt)
+            self.stateDatauPblished = (.progressString(progressString),nil)
+            dePrint("生成后视频下载进度: \(progress)")
+        } complete: { url, _ in
+            completion(url)
+        }
+    }
+    
     func downloadImage(urlString:String,completion:@escaping ()->Void){
         TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { [weak self]  progress in
             guard let self = self else { return }

+ 7 - 0
TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBasePhotoOperation.swift

@@ -213,6 +213,13 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
         case .recreate:
             urlType = .imageRewrite
             postDict["prompt"] = "Recreate damaged portraits and added suitable color for photo"
+            
+        case .creatVideo:
+            urlType = .createVideo
+            postDict["prompt"] = request.prompt
+//            postDict["aspectRatio"] = "9:16"
+            postDict["duration"] = 5
+            postDict["quality"] = "720p"
         }
 
         creatRequest = TSNetworkShared.post(urlType: urlType,parameters: postDict) { [weak self] data,error in

+ 7 - 9
TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift

@@ -26,8 +26,6 @@ class TSDBActionInfoModel: Object {
     @Persisted var costTime:Int = 0
     @Persisted var percent:Float = 0.0
     
-    @Persisted var videoThumbnailPath:String = ""
-    @Persisted var videoPath:String = ""
     @Persisted var uuid:String = UUID().uuidString
     
     static func createDBModel(actionInfoModel:TSActionInfoModel) -> TSDBActionInfoModel{
@@ -48,8 +46,6 @@ class TSDBActionInfoModel: Object {
         self.status = infoModel.status
         self.costTime = infoModel.costTime
         self.percent = infoModel.percent
-        self.videoThumbnailPath = infoModel.videoThumbnailPath
-        self.videoPath = infoModel.videoPath
         self.uuid = infoModel.uuid
         
         self.request = TSDBActionRequestModel.createDBModel(requestModel: infoModel.request)
@@ -70,8 +66,6 @@ class TSDBActionInfoModel: Object {
         infoModel.status = self.status
         infoModel.costTime = self.costTime
         infoModel.percent = self.percent
-        infoModel.videoThumbnailPath = self.videoThumbnailPath
-        infoModel.videoPath = self.videoPath
         infoModel.uuid = self.uuid
 
         if let request = self.request {
@@ -161,7 +155,9 @@ class TSDBActionResponseModel : Object {
     @Persisted var createdAt: Date = Date()
     
     @Persisted var resultUrl:String = ""
-    @Persisted var originalPath:String = ""
+    @Persisted var previewUrl:String = ""
+    @Persisted var videoDocument:String = ""
+    
     @Persisted var code:Int = 0
     @Persisted var vip:Bool = false
     
@@ -173,7 +169,8 @@ class TSDBActionResponseModel : Object {
     
     func saveData(responseModel:TSActionResponseModel) {
         self.resultUrl = responseModel.resultUrl
-        self.originalPath = responseModel.originalPath
+        self.previewUrl = responseModel.previewUrl
+        self.videoDocument = responseModel.videoDocument
         self.code = responseModel.code
         self.vip = responseModel.vip
     }
@@ -182,7 +179,8 @@ class TSDBActionResponseModel : Object {
     func getModel()->TSActionResponseModel{
         let model = TSActionResponseModel()
         model.resultUrl = self.resultUrl
-        model.originalPath = self.originalPath
+        model.previewUrl = self.previewUrl
+        model.videoDocument = self.videoDocument
         model.code = self.code
         model.vip = self.vip
         return model

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

@@ -75,8 +75,7 @@ class TSDBHistory: Object {
                 }
             }
         }
-        
-        
+
         TSRMShared.writeThread {
             listModels.removeAll()
         }
@@ -94,6 +93,8 @@ class TSDBHistory: Object {
             if let model = listModels[safe: index] {
                 if let response =  model.response {
                     TSImageStoreTool.removeImage(urlString:response.resultUrl)
+                    TSImageStoreTool.removeImage(urlString:response.previewUrl)
+                    TSFileManagerTool.removeItem(from: response.videoDocument.fillDocumentURL)
                 }
                 
                 if let request =  model.request {
@@ -109,7 +110,7 @@ class TSDBHistory: Object {
     
     func updateData(_ actionInfoModel:TSActionInfoModel,uuid:String? = nil){
         let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
-            var replaceUUID = uuid ?? dbModel.uuid
+            let replaceUUID = uuid ?? dbModel.uuid
             let frozenList = self.listModels.freeze()
             if let index = frozenList.firstIndex(where: { $0.uuid == replaceUUID }) {
                 dePrint("updateData 替换 \(dbModel)")

+ 2 - 1
TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift

@@ -23,9 +23,10 @@ class TSRealmManager {
     private init() {
         /*设置新的版本号
          3.6.1 ->4
+         3.6.6 ->7
          **/
    
-        let newSchemaVersion: UInt64 = 6
+        let newSchemaVersion: UInt64 = 8
         // 获取默认配置
         var config = Realm.Configuration.defaultConfiguration
         // 设置新版本号