Переглянути джерело

feat:细节调整,缺本地化

kailen 1 тиждень тому
батько
коміт
693109e7f8
32 змінених файлів з 922 додано та 501 видалено
  1. 4 0
      AIEmoji.xcodeproj/project.pbxproj
  2. 23 0
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/Contents.json
  3. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@1x.png
  4. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@2x.png
  5. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@3x.png
  6. 23 0
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/Contents.json
  7. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@1x.png
  8. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@2x.png
  9. BIN
      AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@3x.png
  10. 20 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift
  11. 19 0
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSDBActionInfoModel.swift
  12. 2 2
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPromptTextView.swift
  13. 14 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift
  14. 2 2
      AIEmoji/Business2/DIYVideo/Elements/TSAIModelElementView.swift
  15. 1 1
      AIEmoji/Business2/DIYVideo/Elements/TSBaseSegementElementView.swift
  16. 155 0
      AIEmoji/Business2/DIYVideo/Elements/TSDiyStyleElementView.swift
  17. 26 4
      AIEmoji/Business2/DIYVideo/Elements/TSDiyVideoPromptElementView.swift
  18. 27 2
      AIEmoji/Business2/DIYVideo/Elements/TSSegementElements.swift
  19. 43 2
      AIEmoji/Business2/DIYVideo/Model/TSAIDiyVideoGenerateModel.swift
  20. 81 13
      AIEmoji/Business2/DIYVideo/Model/TSDiyVideoElementType.swift
  21. 3 6
      AIEmoji/Business2/DIYVideo/TSAIDiyVideoPTVVC/TSAIDiyVideoPTVVC.swift
  22. 1 1
      AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSAIDiyVideoTTBaseVC.swift
  23. 9 7
      AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSAIDiyVideoTTVVC.swift
  24. 9 9
      AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSDiyVideoPopoverViewController.swift
  25. 14 0
      AIEmoji/Business2/DIYVideo/TSAIDiyVideoVC.swift
  26. 156 177
      AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Data.swift
  27. 127 132
      AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateVC.swift
  28. 1 1
      AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBannerItemCell.swift
  29. 2 1
      AIEmoji/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift
  30. 2 1
      AIEmoji/Common/TSRealmManager/TSRealmManager.swift
  31. 4 1
      AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBaseOperation.swift
  32. 154 138
      AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBasePhotoOperation.swift

+ 4 - 0
AIEmoji.xcodeproj/project.pbxproj

@@ -14,6 +14,7 @@
 		60B3845F2E39BF2700D77E20 /* TSAiModelCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B3845E2E39BF2700D77E20 /* TSAiModelCellView.swift */; };
 		60B384612E39C33200D77E20 /* TSDiyVideoPopoverViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60B384602E39C33200D77E20 /* TSDiyVideoPopoverViewController.swift */; };
 		60C377F92E3A408B0098A601 /* TSDiscoverBannerItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C377F82E3A408B0098A601 /* TSDiscoverBannerItemCell.swift */; };
+		60C805B32E3B1CCB0051164F /* TSDiyStyleElementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C805B22E3B1CCB0051164F /* TSDiyStyleElementView.swift */; };
 		60EE9A782E386EB200565900 /* TSAIModelElementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60EE9A772E386EB200565900 /* TSAIModelElementView.swift */; };
 		60EE9A7D2E38720700565900 /* TSAIDiyVideoTTBaseViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60EE9A7C2E38720700565900 /* TSAIDiyVideoTTBaseViewModel.swift */; };
 		60EE9A7F2E38727100565900 /* TSDiyVideoElementType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60EE9A7E2E38727100565900 /* TSDiyVideoElementType.swift */; };
@@ -379,6 +380,7 @@
 		60B3845E2E39BF2700D77E20 /* TSAiModelCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAiModelCellView.swift; sourceTree = "<group>"; };
 		60B384602E39C33200D77E20 /* TSDiyVideoPopoverViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiyVideoPopoverViewController.swift; sourceTree = "<group>"; };
 		60C377F82E3A408B0098A601 /* TSDiscoverBannerItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiscoverBannerItemCell.swift; sourceTree = "<group>"; };
+		60C805B22E3B1CCB0051164F /* TSDiyStyleElementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiyStyleElementView.swift; sourceTree = "<group>"; };
 		60EE9A772E386EB200565900 /* TSAIModelElementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIModelElementView.swift; sourceTree = "<group>"; };
 		60EE9A7C2E38720700565900 /* TSAIDiyVideoTTBaseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIDiyVideoTTBaseViewModel.swift; sourceTree = "<group>"; };
 		60EE9A7E2E38727100565900 /* TSDiyVideoElementType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiyVideoElementType.swift; sourceTree = "<group>"; };
@@ -805,6 +807,7 @@
 			children = (
 				60B3845E2E39BF2700D77E20 /* TSAiModelCellView.swift */,
 				60EE9A772E386EB200565900 /* TSAIModelElementView.swift */,
+				60C805B22E3B1CCB0051164F /* TSDiyStyleElementView.swift */,
 				60EE9A842E38A7C200565900 /* TSDiyVideoPromptElementView.swift */,
 				60EE9A802E3898A600565900 /* TSBaseSegementElementView.swift */,
 				60EE9A822E38A1ED00565900 /* TSSegementElements.swift */,
@@ -2825,6 +2828,7 @@
 				A80E726A2D409E5400C64288 /* TSDiyTLYFlowersView.swift in Sources */,
 				A8F7764E2D3E00A800AA6E93 /* TSEmojisColViewModel.swift in Sources */,
 				A89EA6C82D6359ED000EB181 /* TSChatViewController+VipView.swift in Sources */,
+				60C805B32E3B1CCB0051164F /* TSDiyStyleElementView.swift in Sources */,
 				A8BA763F2DA4C908000B6707 /* TSPTPInputVC.swift in Sources */,
 				A8F776422D3B75FC00AA6E93 /* TSBottomAlertVC.swift in Sources */,
 				A8F775192D38EC6800AA6E93 /* TSEmojisVC.swift in Sources */,

+ 23 - 0
AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@1x.png


BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@2x.png


BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_animation.imageset/ic_style_animation@3x.png


+ 23 - 0
AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@1x.png


BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@2x.png


BIN
AIEmoji/Assets.xcassets/DiyVideo/ic_style_general.imageset/ic_style_general@3x.png


+ 20 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift

@@ -85,6 +85,11 @@ extension TSActionInfoModel {
     
     
     var upImageURLExpired:Bool{
+        
+        if request.generatorStyle == .textToVideo {
+            return false
+        }
+        
         if request.imageUrl.count == 0 {
             return true
         }
@@ -115,6 +120,14 @@ class TSActionRequestModel : TSBaseModel {
     var generatorStyle:TSFuncStyle = .ptp
     
     var template:String = ""
+    
+    ///文生视频,视频生视频版本新增
+    var duration:Int = 0
+    var resolution:String = ""
+    var movementAmplitude:String = ""
+    var bgm:Bool = true
+    var aspectRatio:String = ""
+    
     override func mapping(map: ObjectMapper.Map) {
         prompt              <- map["prompt"]
         inputText           <- map["inputText"]
@@ -123,12 +136,18 @@ class TSActionRequestModel : TSBaseModel {
         
         imageUrl            <- map["imageUrl"]
         imageUrlTimestamp   <- map["imageUrlTimestamp"]
-        imageUrls            <- map["imageUrls"]
+        imageUrls           <- map["imageUrls"]
         style               <- map["style"]
         advance             <- map["advance"]
         model               <- map["model"]
         generatorStyle      <- map["generatorStyle"]
         template            <- map["template"]
+        
+        template            <- map["template"]
+        resolution          <- map["resolution"]
+        movementAmplitude   <- map["movementAmplitude"]
+        bgm                 <- map["bgm"]
+        aspectRatio         <- map["aspectRatio"]
     }
     
     

+ 19 - 0
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSDBActionInfoModel.swift

@@ -158,6 +158,13 @@ class TSDBActionRequestModel : Object {
     
     @Persisted var template:String = ""
     
+    ///文生视频,视频生视频版本新增
+    @Persisted var duration:Int = 0
+    @Persisted var resolution:String = ""
+    @Persisted var movementAmplitude:String = ""
+    @Persisted var bgm:Bool = true
+    @Persisted var aspectRatio:String = ""
+    
     static func createDBModel(requestModel:TSActionRequestModel) -> TSDBActionRequestModel{
         let dbModel = TSDBActionRequestModel()
         dbModel.saveData(requestModel: requestModel)
@@ -184,6 +191,12 @@ class TSDBActionRequestModel : Object {
         
         
         self.template = requestModel.template
+        self.duration = requestModel.duration
+        self.resolution = requestModel.resolution
+        self.movementAmplitude = requestModel.movementAmplitude
+        self.bgm = requestModel.bgm
+        self.aspectRatio = requestModel.aspectRatio
+        
     }
     
     
@@ -204,6 +217,12 @@ class TSDBActionRequestModel : Object {
         model.generatorStyle = TSFuncStyle(rawValue: self.generatorStyle) ?? .ptp
         
         model.template = self.template
+        
+        model.duration = self.duration
+        model.resolution = self.resolution
+        model.movementAmplitude = self.movementAmplitude
+        model.bgm = self.bgm
+        model.aspectRatio = self.aspectRatio
         return model
     }
 

+ 2 - 2
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSPromptTextView.swift

@@ -27,7 +27,7 @@ class TSPromptTextView: TSBaseView {
     }()
 
     lazy var randomTextPicker: TSRandomTextPicker = {
-        let textPicker = TSRandomTextPicker(texts: kRandomTextArray)
+        let textPicker = TSRandomTextPicker(texts: randomTextArray)
         return textPicker
     }()
 
@@ -76,7 +76,7 @@ class TSPromptTextView: TSBaseView {
         AIView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickAIView)))
 
         let iconImageView = UIImageView.createImageView(imageName: "deepseek_icon")
-        let aiInfoLabel = UILabel.createLabel(text: "DeepSeek-R1", font: .font(size: 14), textColor: "#4D6BFE".uiColor, textAlignment: .left, numberOfLines: 1)
+        let aiInfoLabel = UILabel.createLabel(text: "Prompt Optimization", font: .font(size: 14), textColor: "#4D6BFE".uiColor, textAlignment: .left, numberOfLines: 1)
         let arrowImageView = UIImageView.createImageView(imageName: "blue_down_arrow")
 
         AIView.addSubview(iconImageView)

+ 14 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift

@@ -20,6 +20,20 @@ let kRandomTextArray:[String] = [
     "Minimalist geometric landscape with gradient-colored pyramids, clean lines intersecting with organic cloud formations, symmetrical composition"
 ]
 
+let kRandomImageToVideoArray:[String] = [
+    "A majestic aerial view of a golden sunrise over misty mountains, rivers flowing through dense forests, with birds soaring gracefully — cinematic lighting and natural colors.",
+    "A futuristic neon-lit city at night, flying cars weaving between skyscrapers, glowing holograms everywhere, with a moody, Blade Runner-style atmosphere.",
+    "A magical forest with floating lanterns, glowing mushrooms, and mythical creatures walking under a twilight sky — soft lighting and dreamlike ambiance.",
+    "Clean, minimal shapes in motion — black and white geometric patterns transforming smoothly in a slow, calming loop — abstract and modern design style.",
+    "Extreme sports action: a skateboarder performing tricks in slow motion, dust flying, with dramatic lighting and energetic pacing — dynamic and intense.",
+    "A peaceful village with cherry blossoms falling, wind gently moving clotheslines, warm pastel colors — inspired by Studio Ghibli visual storytelling.",
+    "A desolate alien planet with a cracked surface, twin moons in the sky, a lone explorer in a space suit walking slowly — dark, eerie, cinematic style.",
+    "Vaporwave city with grid floors, purple skies, palm trees and a glowing sunset — synthwave color palette with nostalgic retro-futuristic vibes.",
+    "A bustling urban street through time-lapse: people rushing by, clouds racing overhead, lights turning on at night — documentary and modern style.",
+    "Floating islands drifting in the sky, upside-down waterfalls, and glowing whales flying through clouds — vivid colors, surreal and imaginative tone.",
+]
+
+
 
 class TSTextGeneralPictureVM {
     var colDataArray:[TSComponent] = [TSComponent]()

+ 2 - 2
AIEmoji/Business2/DIYVideo/Elements/TSAIModelElementView.swift

@@ -11,7 +11,7 @@ class TSAIModelElementView: UIView, TSDiyVideoElement {
     var dependElement: (any TSDiyVideoElement)?
     
     var param: String {
-        return modelView.type.rawValue
+        return modelView.type.param
     }
     
     var currentAiModel : TSDiyAiModelType {
@@ -42,7 +42,7 @@ class TSAIModelElementView: UIView, TSDiyVideoElement {
     func addChildren() {
         titleLabel.text = type.sectionTitle
         titleLabel.textColor = .white.withAlphaComponent(0.8)
-        titleLabel.font = .font(name: .PoppinsBlackItalic, size: 14)
+        titleLabel.font = .font(size: 14,weight: .medium)
         bgView.cornerRadius = 16
         bgView.addSubview(modelView)
         bgView.addSubview(arrowIcon)

+ 1 - 1
AIEmoji/Business2/DIYVideo/Elements/TSBaseSegementElementView.swift

@@ -76,7 +76,7 @@ class TSBaseSegementElementView: UIView, TSDiyVideoElement {
     func addChildren() {
         titleLabel.text = type.sectionTitle
         titleLabel.textColor = .white.withAlphaComponent(0.8)
-        titleLabel.font = .font(name: .PoppinsBlackItalic, size: 14)
+        titleLabel.font = .font(size: 14,weight: .medium)
         addSubview(titleLabel)
         addSubview(segmentedView)
     }

+ 155 - 0
AIEmoji/Business2/DIYVideo/Elements/TSDiyStyleElementView.swift

@@ -0,0 +1,155 @@
+//
+//  TSDiyStyleElementView.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/7/31.
+//
+
+import Foundation
+
+class TSDiyStyleElementView: UIView, TSDiyVideoElement {
+    var type: TSDiyVideoElementType {
+        .style
+    }
+
+    var param: String {
+        items.first { item in
+            item.isSelected
+        }?.type.param ?? TSDiyStyleType.general.param
+    }
+
+    lazy var titleLabel: UILabel = {
+        let title: UILabel = .createLabel()
+        title.text = type.sectionTitle
+        title.textColor = .white.withAlphaComponent(0.8)
+        title.font = .font(size: 14, weight: .medium)
+        return title
+    }()
+
+    lazy var general: TSDiyStyleElementItem = {
+        let gen = TSDiyStyleElementItem(type: .general)
+        gen.isSelected = true
+        return gen
+    }()
+
+    lazy var animation: TSDiyStyleElementItem = {
+        let gen = TSDiyStyleElementItem(type: .animation)
+        gen.isSelected = false
+        return gen
+    }()
+
+    var items: [TSDiyStyleElementItem] {
+        [general, animation]
+    }
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        addChildren()
+        makeConstarints()
+    }
+
+    func addChildren() {
+        general.addTapAction { [weak self] in
+            guard let self = self else { return }
+
+            items.forEach {
+                $0.isSelected = false
+            }
+            self.general.isSelected = true
+        }
+        animation.addTapAction { [weak self] in
+            guard let self = self else { return }
+            items.forEach {
+                $0.isSelected = false
+            }
+            self.animation.isSelected = true
+        }
+        addSubview(titleLabel)
+        addSubview(general)
+        addSubview(animation)
+    }
+
+    func makeConstarints() {
+        titleLabel.snp.makeConstraints { make in
+            make.leading.equalToSuperview().offset(16)
+            make.top.equalToSuperview().offset(22)
+        }
+
+        general.snp.makeConstraints { make in
+            make.leading.equalToSuperview().offset(16)
+            make.top.equalTo(titleLabel.snp.bottom).offset(12)
+            make.bottom.equalToSuperview().inset(12)
+            make.height.equalTo(56)
+            make.width.equalTo(100)
+        }
+
+        animation.snp.makeConstraints { make in
+            make.leading.equalTo(general.snp.trailing).offset(12)
+            make.top.equalTo(general)
+            make.height.equalTo(56)
+            make.width.equalTo(100)
+        }
+    }
+
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+}
+
+class TSDiyStyleElementItem: UIView {
+    var type: TSDiyStyleType
+    lazy var bgImageView: UIImageView = .init(image: UIImage(named: type.imgName))
+    lazy var maskBottom: UIView = .creatColor(color: .black.withAlphaComponent(0.5))
+    lazy var titleLabel: UILabel = .createLabel(text: type.rawValue, font: .font(size: 12), textColor: .white)
+    var isSelected: Bool = false {
+        didSet {
+            updateSelected()
+        }
+    }
+
+    func updateSelected() {
+        if isSelected {
+            bgImageView.layer.borderColor = UIColor.fromHex("#FECB34").cgColor
+            bgImageView.layer.borderWidth = 1
+            bgImageView.layer.cornerRadius = 8
+        } else {
+            bgImageView.layer.borderColor = UIColor.clear.cgColor
+            bgImageView.layer.borderWidth = 0
+            bgImageView.layer.cornerRadius = 8
+        }
+    }
+
+    init(type: TSDiyStyleType) {
+        self.type = type
+        super.init(frame: .zero)
+        addChildren()
+        makeConstarints()
+    }
+
+    func addChildren() {
+        addSubview(bgImageView)
+        maskBottom.cornersRound(radius: 8, corner: [.bottomLeft, .bottomRight])
+        bgImageView.addSubview(maskBottom)
+        maskBottom.addSubview(titleLabel)
+    }
+
+    func makeConstarints() {
+        bgImageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        maskBottom.snp.makeConstraints { make in
+            make.height.equalTo(20)
+            make.horizontalEdges.equalToSuperview()
+            make.bottom.equalToSuperview()
+        }
+
+        titleLabel.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+        }
+    }
+
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+}

+ 26 - 4
AIEmoji/Business2/DIYVideo/Elements/TSDiyVideoPromptElementView.swift

@@ -15,6 +15,25 @@ class TSDiyTextPromptElementView: TSPromptTextView, TSDiyVideoElement {
     var param: String {
         ""
     }
+    
+    override init(randomTextArray: [String], textChangedBlock: @escaping (String) -> Void) {
+        super.init(randomTextArray: randomTextArray, textChangedBlock: textChangedBlock)
+        self.inspirationBtn.isHidden = true
+    }
+    
+    override func makeConstraints() {
+        super.makeConstraints()
+
+        AIView.snp.remakeConstraints { make in
+            make.height.equalTo(28)
+            make.bottom.equalTo(-16)
+            make.leading.equalToSuperview().offset(16)
+        }
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
 }
 
 class TSDiyVideoPromptElementView: TSPromptTextView, TSDiyVideoElement {
@@ -41,7 +60,13 @@ class TSDiyVideoPromptElementView: TSPromptTextView, TSDiyVideoElement {
         return upload
     }()
 
-    lazy var titleLabel: UILabel = UILabel.createLabel()
+    lazy var titleLabel: UILabel = {
+        let title : UILabel = .createLabel()
+        title.text = type.sectionTitle
+        title.textColor = .white.withAlphaComponent(0.8)
+        title.font = .font(size: 14,weight: .medium)
+        return title
+    }()
 
     override init(randomTextArray: [String], textChangedBlock: @escaping (String) -> Void) {
         super.init(randomTextArray: randomTextArray, textChangedBlock: textChangedBlock)
@@ -60,9 +85,6 @@ class TSDiyVideoPromptElementView: TSPromptTextView, TSDiyVideoElement {
     }
 
     func addChildren() {
-        titleLabel.text = type.sectionTitle
-        titleLabel.textColor = .white.withAlphaComponent(0.8)
-        titleLabel.font = .font(name: .PoppinsBlackItalic, size: 14)
         contentView.addSubview(titleLabel)
         textBgView.addSubview(uploadView)
     }

+ 27 - 2
AIEmoji/Business2/DIYVideo/Elements/TSSegementElements.swift

@@ -7,10 +7,28 @@
 
 import Foundation
 
+class TSAspectRatioElementView: TSBaseSegementElementView {
+    override var type: TSDiyVideoElementType {
+        .aspectRatio
+    }
+    
+    override var param: String {
+        let raw = type.getModelConfigSegments(aiModel: aiModelType).safeString(At: segmentedView.index)
+        let mType = TSDiyAspectRatioType(rawValue: raw)
+        return mType?.param ?? ""
+    }
+}
+
 class TSMovementElementView: TSBaseSegementElementView {
     override var type: TSDiyVideoElementType {
         .movementAmplitude
     }
+    
+    override var param: String {
+        let raw = type.getModelConfigSegments(aiModel: aiModelType).safeString(At: segmentedView.index)
+        let mType = TSDiyMovementType(rawValue: raw)
+        return mType?.param ?? ""
+    }
 }
 
 class TSStyleElementView: TSBaseSegementElementView {
@@ -21,8 +39,9 @@ class TSStyleElementView: TSBaseSegementElementView {
 
 class TSVideoLengthElementView: TSBaseSegementElementView {
     override var param: String {
-        let raw = type.getModelConfigSegments(aiModel: aiModelType).safeString(At: segmentedView.index).replacingOccurrences(of: "s", with: "")
-        return raw
+        let raw = type.getModelConfigSegments(aiModel: aiModelType).safeString(At: segmentedView.index)
+        let mType = TSDiyVideoLengthType(rawValue: raw)
+        return mType?.param ?? ""
     }
 
     override var type: TSDiyVideoElementType {
@@ -34,4 +53,10 @@ class TSResolutionElementView: TSBaseSegementElementView {
     override var type: TSDiyVideoElementType {
         return .resolution
     }
+    
+    override var param: String {
+        let raw = type.getModelConfigSegments(aiModel: aiModelType).safeString(At: segmentedView.index)
+        let mType = TSDiyResolutionType(rawValue: raw)
+        return mType?.param ?? ""
+    }
 }

+ 43 - 2
AIEmoji/Business2/DIYVideo/Model/TSAIDiyVideoGenerateModel.swift

@@ -5,14 +5,55 @@
 //  Created by 100Years on 2025/7/28.
 //
 
+/*
+ {
+   "model": "viduq1",
+   "imageUrls": ["https://be-aigc.s3-accelerate.amazonaws.com/b0212c77-e7e8-400f-b3d7-30e0f596858a.png"],
+   "prompt": "dancing",
+   "duration": 5,
+   "resolution": "1080p",
+   "movementAmplitude": "auto",
+   "bgm": true
+ }
+ */
+
 class TSAIDiyVideoGenerateModel: TSBaseModel {
     //    图生视频:接 Vidu Q1 和 Vidu 2
     //    文生视频:接 Vidu Q1
     var model: String = ""
     var style: String = ""
     var prompt: String = ""
-    var duration: String = ""
+    var duration: Int = 0
     var resolution: String = ""
     var movement: String = ""
-  
+    var bgm : Bool = true
+    var aspectRatio : String = ""
+    
+    var asDict: [String: Any] {
+        var dict = [String: Any]()
+        
+        if !model.isEmpty {
+            dict["model"] = model
+        }
+        if !style.isEmpty {
+            dict["style"] = style
+        }
+        if !prompt.isEmpty {
+            dict["prompt"] = prompt
+        }
+        if duration != 0 {
+            dict["duration"] = duration
+        }
+        if !resolution.isEmpty {
+            dict["resolution"] = resolution
+        }
+        if !movement.isEmpty {
+            dict["movementAmplitude"] = movement
+        }
+        if !aspectRatio.isEmpty {
+            dict["aspectRatio"] = aspectRatio
+        }
+        dict["bgm"] = bgm
+        return dict
+    }
 }

+ 81 - 13
AIEmoji/Business2/DIYVideo/Model/TSDiyVideoElementType.swift

@@ -19,6 +19,7 @@ enum TSDiyVideoElementType {
     case resolution
     case videoLength
     case style
+    case aspectRatio
     case movementAmplitude
 
     var sectionTitle: String {
@@ -37,10 +38,12 @@ enum TSDiyVideoElementType {
             "Style Preference"
         case .movementAmplitude:
             "Movement Amplitude"
+        case .aspectRatio:
+            "Aspect Ratio"
         }
     }
-    
-    func getModelConfigSegments(aiModel : TSDiyAiModelType) -> [String] {
+
+    func getModelConfigSegments(aiModel: TSDiyAiModelType) -> [String] {
         switch self {
         case .aiModel:
             TSDiyAiModelType.allCases.map {
@@ -58,7 +61,6 @@ enum TSDiyVideoElementType {
             aiModel.lengthTypes.map {
                 $0.rawValue
             }
-
         case .style:
             aiModel.stypeTypes.map {
                 $0.rawValue
@@ -67,29 +69,42 @@ enum TSDiyVideoElementType {
             aiModel.movementTypes.map {
                 $0.rawValue
             }
+        case .aspectRatio:
+            aiModel.aspectRatio.map {
+                $0.rawValue
+            }
         }
     }
 }
 
 enum TSDiyAiModelType: String, CaseIterable {
     case ViduQ1 = "Vidu Q1"
-    case Vidu2 = "Vidu 2"
+//    case Vidu2 = "Vidu 2"
+
+    var param: String {
+        switch self {
+        case .ViduQ1:
+            return "viduq1"
+//        case .Vidu2:
+//            return "vidu2.0"
+        }
+    }
 
     var lengthTypes: [TSDiyVideoLengthType] {
         switch self {
         case .ViduQ1:
-            return [.four, .eight]
-        case .Vidu2:
             return [.five]
+//        case .Vidu2:
+//            return [.five]
         }
     }
 
     var resolutionTypes: [TSDiyResolutionType] {
         switch self {
         case .ViduQ1:
-            return [.p360, .p720, .p1080]
-        case .Vidu2:
-            return [.p720]
+            return [.p1080]
+//        case .Vidu2:
+//            return [.p720]
         }
     }
 
@@ -100,13 +115,17 @@ enum TSDiyAiModelType: String, CaseIterable {
     var movementTypes: [TSDiyMovementType] {
         return TSDiyMovementType.allCases
     }
+    
+    var aspectRatio : [TSDiyAspectRatioType] {
+        return TSDiyAspectRatioType.allCases
+    }
 
     var distribution: String {
         switch self {
         case .ViduQ1:
             return "Precise control over video motion"
-        case .Vidu2:
-            return "Enhanced quality and speed"
+//        case .Vidu2:
+//            return "Enhanced quality and speed"
         }
     }
 }
@@ -116,17 +135,62 @@ enum TSDiyMovementType: String, CaseIterable {
     case small = "Small"
     case medium = "Medium"
     case large = "Large"
+
+    var param: String {
+        switch self {
+        case .auto:
+            "auto"
+        case .small:
+            "small"
+        case .medium:
+            "medium"
+        case .large:
+            "large"
+        }
+    }
 }
 
 enum TSDiyStyleType: String, CaseIterable {
-    case creative = "Creative"
-    case stable = "Stable"
+    case general = "General"
+    case animation = "Animation"
+    
+    var param: String {
+        switch self {
+        case .general:
+            "general"
+        case .animation:
+            "anime"
+        }
+    }
+    
+    var imgName : String {
+        switch self {
+        case .general:
+            "ic_style_general"
+        case .animation:
+            "ic_style_animation"
+        }
+    }
 }
 
 enum TSDiyResolutionType: String, CaseIterable {
     case p360 = "360p"
     case p720 = "720p"
     case p1080 = "1080p"
+
+    var param: String {
+        return rawValue
+    }
+}
+
+enum TSDiyAspectRatioType: String, CaseIterable {
+    case radio_16_9 = "16:9"
+    case radio_9_16 = "9:16"
+    case radio_1_1 = "1:1"
+
+    var param: String {
+        return rawValue
+    }
 }
 
 enum TSDiyVideoLengthType: String, CaseIterable {
@@ -134,6 +198,10 @@ enum TSDiyVideoLengthType: String, CaseIterable {
     case five = "5"
     case eight = "8"
 
+    var param: String {
+        return rawValue
+    }
+
     var showText: String {
         return "\(rawValue)s"
     }

+ 3 - 6
AIEmoji/Business2/DIYVideo/TSAIDiyVideoPTVVC/TSAIDiyVideoPTVVC.swift

@@ -9,7 +9,7 @@ class TSAIDiyVideoPTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
     lazy var aiModelView = TSAIModelElementView(frame: .zero)
 
     lazy var promptTextView: TSDiyVideoPromptElementView = {
-        let promptTextView = TSDiyVideoPromptElementView(randomTextArray: kRandomTextArray) { [weak self] _ in
+        let promptTextView = TSDiyVideoPromptElementView(randomTextArray: kRandomImageToVideoArray) { [weak self] _ in
             guard let self = self else { return }
         }
         promptTextView.uploadClickAction = { [weak self] in
@@ -47,7 +47,6 @@ class TSAIDiyVideoPTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
 
     lazy var resolution = TSResolutionElementView(aiType: viewModel.selectedAiModelType)
     lazy var length = TSVideoLengthElementView(aiType: viewModel.selectedAiModelType)
-    lazy var style = TSStyleElementView(aiType: viewModel.selectedAiModelType)
     lazy var movement = TSMovementElementView(aiType: viewModel.selectedAiModelType)
 
     var viewModel: TSAIDiyVideoPTVViewModel = .init()
@@ -55,10 +54,9 @@ class TSAIDiyVideoPTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
     override var videoGenerateModel: TSAIDiyVideoGenerateModel {
         let model = TSAIDiyVideoGenerateModel()
         model.model = aiModelView.param
-        model.duration = length.param
+        model.duration = Int(length.param) ?? 0
         model.movement = movement.param
         model.resolution = resolution.param
-        model.style = style.param
         model.prompt = viewModel.prompt
         return model
     }
@@ -69,7 +67,6 @@ class TSAIDiyVideoPTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
             promptTextView,
             resolution,
             length,
-            style,
             movement,
         ]
     }
@@ -110,7 +107,7 @@ class TSAIDiyVideoPTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
             if let popoverPresentationController = contentVC.popoverPresentationController {
                 popoverPresentationController.delegate = self
                 popoverPresentationController.sourceView = self.aiModelView
-                popoverPresentationController.sourceRect = .init(origin: .init(x: self.aiModelView.bounds.origin.x, y: self.aiModelView.bounds.origin.y + 142), size: self.aiModelView.bounds.size)
+                popoverPresentationController.sourceRect = .init(origin: .init(x: self.aiModelView.bounds.origin.x, y: self.aiModelView.bounds.origin.y + 100), size: self.aiModelView.bounds.size)
                 popoverPresentationController.permittedArrowDirections = []
                 popoverPresentationController.backgroundColor = .fromHex("#222222")
             }

+ 1 - 1
AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSAIDiyVideoTTBaseVC.swift

@@ -14,7 +14,7 @@ class TSAIDiyVideoTTBaseVC: TSBaseVC {
 
     lazy var cusStackView: TSCustomStackView = {
         let cusStackView = TSCustomStackView(axis: .vertical, alignment: .center, spacing: 0)
-        cusStackView.scrollView.contentInset = .init(top: 0, left: 0, bottom: k_Height_safeAreaInsetsBottom() + 48, right: 0)
+        cusStackView.scrollView.contentInset = .init(top: 0, left: 0, bottom: k_Height_safeAreaInsetsBottom() + 68, right: 0)
         return cusStackView
     }()
 

+ 9 - 7
AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSAIDiyVideoTTVVC.swift

@@ -34,22 +34,23 @@ class TSAIDiyVideoTTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
         }
         return promptTextView
     }()
-
+    lazy var style = TSDiyStyleElementView()
     lazy var resolution = TSResolutionElementView(aiType: viewModel.selectedAiModelType)
     lazy var length = TSVideoLengthElementView(aiType: viewModel.selectedAiModelType)
-    lazy var style = TSStyleElementView(aiType: viewModel.selectedAiModelType)
     lazy var movement = TSMovementElementView(aiType: viewModel.selectedAiModelType)
-
+    lazy var aspectRadio = TSAspectRatioElementView(aiType: viewModel.selectedAiModelType)
+    
     var viewModel: TSAIDiyVideoTTVViewModel = .init()
 
     override var videoGenerateModel: TSAIDiyVideoGenerateModel {
         let model = TSAIDiyVideoGenerateModel()
         model.model = aiModelView.param
-        model.duration = length.param
+        model.duration = Int(length.param) ?? 0
         model.movement = movement.param
         model.resolution = resolution.param
-        model.style = style.param
         model.prompt = viewModel.prompt
+        model.style = style.param
+        model.aspectRatio = aspectRadio.param
         return model
     }
 
@@ -57,10 +58,11 @@ class TSAIDiyVideoTTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
         [
             aiModelView,
             promptTextView,
+            style,
             resolution,
             length,
-            style,
             movement,
+            aspectRadio
         ]
     }
 
@@ -95,7 +97,7 @@ class TSAIDiyVideoTTVVC: TSAIDiyVideoTTBaseVC, UIPopoverPresentationControllerDe
             if let popoverPresentationController = contentVC.popoverPresentationController {
                 popoverPresentationController.delegate = self
                 popoverPresentationController.sourceView = self.aiModelView
-                popoverPresentationController.sourceRect = .init(origin: .init(x: self.aiModelView.bounds.origin.x, y: self.aiModelView.bounds.origin.y + 142), size: self.aiModelView.bounds.size)
+                popoverPresentationController.sourceRect = .init(origin: .init(x: self.aiModelView.bounds.origin.x, y: self.aiModelView.bounds.origin.y + 100), size: self.aiModelView.bounds.size)
                 popoverPresentationController.permittedArrowDirections = []
                 popoverPresentationController.backgroundColor = .fromHex("#222222")
             }

+ 9 - 9
AIEmoji/Business2/DIYVideo/TSAIDiyVideoTTVVC/TSDiyVideoPopoverViewController.swift

@@ -13,7 +13,7 @@ class TSDiyVideoPopoverViewController: UIViewController {
     var onSelected: SelectedHandler?
     var currentType: TSDiyAiModelType = .ViduQ1
     lazy var viduQ1Item: TSAiModelDetailCellView = TSAiModelDetailCellView(type: .ViduQ1)
-    lazy var vidu2Item: TSAiModelDetailCellView = TSAiModelDetailCellView(type: .Vidu2)
+//    lazy var vidu2Item: TSAiModelDetailCellView = TSAiModelDetailCellView(type: .Vidu2)
 
     // 垂直布局的stackView
     lazy var stackView: UIStackView = {
@@ -33,7 +33,7 @@ class TSDiyVideoPopoverViewController: UIViewController {
     private func addChildren() {
         view.addSubview(stackView)
         stackView.addArrangedSubview(viduQ1Item)
-        stackView.addArrangedSubview(vidu2Item)
+//        stackView.addArrangedSubview(vidu2Item)
 
         for item in stackView.arrangedSubviews {
             if let mItem = item as? TSAiModelDetailCellView {
@@ -57,19 +57,19 @@ class TSDiyVideoPopoverViewController: UIViewController {
         viduQ1Item.snp.makeConstraints { make in
             make.height.equalTo(44)
         }
-        vidu2Item.snp.makeConstraints { make in
-            make.height.equalTo(44)
-        }
+//        vidu2Item.snp.makeConstraints { make in
+//            make.height.equalTo(44)
+//        }
     }
 
     // 其他配置:手势、弹窗大小等
     private func setupOtherConfig() {
         // 给单元格添加点击事件
         viduQ1Item.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(itemTapped(_:))))
-        vidu2Item.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(itemTapped(_:))))
+//        vidu2Item.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(itemTapped(_:))))
 
         view.backgroundColor = .fromHex("#222222")
-        preferredContentSize = CGSize(width: k_ScreenWidth - 32, height: 152)
+        preferredContentSize = CGSize(width: k_ScreenWidth - 32, height: 60)
     }
 
     // 单元格点击事件处理
@@ -78,8 +78,8 @@ class TSDiyVideoPopoverViewController: UIViewController {
         switch gesture.view {
         case viduQ1Item:
             onSelected?(.ViduQ1) // 回调ViduQ1类型
-        case vidu2Item:
-            onSelected?(.Vidu2) // 回调Vidu2类型
+//        case vidu2Item:
+//            onSelected?(.Vidu2) // 回调Vidu2类型
         default:
             break
         }

+ 14 - 0
AIEmoji/Business2/DIYVideo/TSAIDiyVideoVC.swift

@@ -99,7 +99,12 @@ class TSAIDiyVideoVC: TSBaseVC {
     init(diyVideoType: Int) {
         self.diyVideoType = diyVideoType
         super.init()
+       
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
+            self.segmentedView.selectItemAt(index: diyVideoType)
+        }
     }
+    
 
     @MainActor required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
@@ -192,6 +197,15 @@ extension TSAIDiyVideoVC {
 
             kPresentModalVC(target: self, modelVC: gennerateVC, transitionStyle: .crossDissolve)
         } else {
+            
+            let generatorModel = TSAIGeneratorModel(upLoadImage: .init(), generatorStyle: .textToVideo)
+            generatorModel.diyVideoGenerateModel = selectedGenerateModel
+            let gennerateVC = TSAIGenerateVC(generatorModel: generatorModel) { [weak self] _ in
+                guard let self = self else { return }
+                updateVipView()
+            }
+
+            kPresentModalVC(target: self, modelVC: gennerateVC, transitionStyle: .crossDissolve)
         }
     }
 }

+ 156 - 177
AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Data.swift

@@ -5,131 +5,130 @@
 //  Created by 100Years on 2025/7/17.
 //
 
-//MARK: 组装数据
+// MARK: 组装数据
+
 let kTSDiscoverVM = TSDiscoverViewModel.shared
 class TSDiscoverViewModel {
+    static let shared: TSDiscoverViewModel = TSDiscoverViewModel()
 
-    static let shared:TSDiscoverViewModel = TSDiscoverViewModel()
-    
     lazy var bannerSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .banner
         section.setTitle(title: "")
         section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Anime", "discover_1_Anime"]),
+                                generateModel: TSGenerateModel(json: ptp_Anime)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Photo Animater.mp4"]),
-                                generateModel: TSGenerateModel(json: video_PhotoAnimater)),
-            TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Animal Diving Show.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Animal Diving Show.mp4"]),
                                 generateModel: TSGenerateModel(json: video_AnimalDivingShow)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Oscar Gala.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Oscar Gala.mp4"]),
                                 generateModel: TSGenerateModel(json: video_OscarGala)),
         ]]
-        
+
         return section
     }()
-    
-    
+
     lazy var videoEffectSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Video Effect".localized,imageNamed: "🎞️",colors: ["#E7D1AB","#FFFFFF"])
+        section.setTitle(title: "Video Effect".localized, imageNamed: "🎞️", colors: ["#E7D1AB", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["360° Microwave.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["360° Microwave.mp4"]),
                                 generateModel: TSGenerateModel(json: video_360Microwave)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Subject 3.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Subject 3.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Subject3)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["PUBG Winner Hit.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["PUBG Winner Hit.mp4"]),
                                 generateModel: TSGenerateModel(json: video_PUBGWinnerHit)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Body Shake.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Body Shake.mp4"]),
                                 generateModel: TSGenerateModel(json: video_BodyShake)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Mermaid.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Mermaid.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Mermaid)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Fairy.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Fairy.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Fairy)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Motor Dance.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Motor Dance.mp4"]),
                                 generateModel: TSGenerateModel(json: video_MotorDance)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Hip Twist.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Hip Twist.mp4"]),
                                 generateModel: TSGenerateModel(json: video_HipTwist)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Lafufu.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Lafufu.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Lafufu)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Anime Me.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Anime Me.mp4"]),
                                 generateModel: TSGenerateModel(json: video_AnimeMe)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Happy Birthday.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Happy Birthday.mp4"]),
                                 generateModel: TSGenerateModel(json: video_HappyBirthday)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Surprise Flower.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Surprise Flower.mp4"]),
                                 generateModel: TSGenerateModel(json: video_SurpriseFlower)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Pet to Human.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Pet to Human.mp4"]),
                                 generateModel: TSGenerateModel(json: video_PettoHuman)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Making Face.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Making Face.mp4"]),
                                 generateModel: TSGenerateModel(json: video_MakingFace)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Pixel World.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Pixel World.mp4"]),
                                 generateModel: TSGenerateModel(json: video_PixelWorld)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Robot.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Robot.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Robot)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Fly.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Fly.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Fly)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Pinch.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Pinch.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Pinch)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Punch Face.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Punch Face.mp4"]),
                                 generateModel: TSGenerateModel(json: video_PunchFace)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Grab doll.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Grab doll.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Grabdoll)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Toy Me.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Toy Me.mp4"]),
                                 generateModel: TSGenerateModel(json: video_ToyMe)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Hulk.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Hulk.mp4"]),
                                 generateModel: TSGenerateModel(json: video_Hulk)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Shake it Down.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Shake it Down.mp4"]),
                                 generateModel: TSGenerateModel(json: video_ShakeitDown)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Walking with Beasts.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Walking with Beasts.mp4"]),
                                 generateModel: TSGenerateModel(json: video_WalkingwithBeasts)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Funny Pet.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["Funny Pet.mp4"]),
                                 generateModel: TSGenerateModel(json: video_FunnyPet)),
             TSDiscoverItemModel(style: .videoV2,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["MuscleUp.mp4"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .video, imageNameds: ["MuscleUp.mp4"]),
                                 generateModel: TSGenerateModel(json: video_MuscleUp)),
 //            TSDiscoverItemModel(style: .videoV2,
 //                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["French Kiss.mp4"]),
 //                                generateModel: TSGenerateModel(json: video_FrenchKiss))
         ]]
-        
+
         return section
     }()
-    
+
 //    //顶部按钮功能(金刚区)
 //    lazy var topFuncSection:TSDiscoverSectionModel = {
 //        let section = TSDiscoverSectionModel()
 //        section.style = .funcItems
 //        section.items = [[
-////            TSDiscoverItemModel(style: .futureBaby,
-////                                viewModel: TSDiscoverBaseItemVM(title: "AI Baby", imageNamed: "discover_AIBaby"),
-////                                generateModel: TSFuncStyle.futureBaby.generateModel),
+    ////            TSDiscoverItemModel(style: .futureBaby,
+    ////                                viewModel: TSDiscoverBaseItemVM(title: "AI Baby", imageNamed: "discover_AIBaby"),
+    ////                                generateModel: TSFuncStyle.futureBaby.generateModel),
 //            TSDiscoverItemModel(style: .ttp,
 //                                viewModel: TSDiscoverBaseItemVM(title: "Text to Image", imageNamed: "discover_TextImage")),
 //            TSDiscoverItemModel(style: .chat,
@@ -144,44 +143,43 @@ class TSDiscoverViewModel {
 //        return section
 //    }()
 
-    
     lazy var popularStylesSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Popular".localized,imageNamed: "🔥",colors: ["#EF2C00","#FEFEE7"])
+        section.setTitle(title: "Popular".localized, imageNamed: "🔥", colors: ["#EF2C00", "#FEFEE7"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_StickerMe","discover_1_StickerMe"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_StickerMe", "discover_1_StickerMe"]),
                                 generateModel: TSGenerateModel(json: ptp_StickerMe)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ToonMe","discover_1_ToonMe"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ToonMe", "discover_1_ToonMe"]),
                                 generateModel: TSGenerateModel(json: ptp_ToonMe)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Bride","discover_1_Bride"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Bride", "discover_1_Bride"]),
                                 generateModel: TSGenerateModel(json: ptp_Bride)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ChibiSticker","discover_1_ChibiSticker"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ChibiSticker", "discover_1_ChibiSticker"]),
                                 generateModel: TSGenerateModel(json: ptp_ChibiSticker)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Irasutoya","discover_1_Irasutoya"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Irasutoya", "discover_1_Irasutoya"]),
                                 generateModel: TSGenerateModel(json: ptp_Irasutoya)),
 
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BlytheDoll","discover_1_BlytheDoll"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BlytheDoll", "discover_1_BlytheDoll"]),
                                 generateModel: TSGenerateModel(json: ptp_BlytheDoll)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Caricature","discover_1_Caricature"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Caricature", "discover_1_Caricature"]),
                                 generateModel: TSGenerateModel(json: ptp_Caricature)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Illustration","discover_1_Illustration"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Illustration", "discover_1_Illustration"]),
                                 generateModel: TSGenerateModel(json: ptp_Illustration)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_90sAnime","discover_1_90sAnime"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_90sAnime", "discover_1_90sAnime"]),
                                 generateModel: TSGenerateModel(json: ptp_90sAnime)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FreshWatercolor","discover_1_FreshWatercolor"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FreshWatercolor", "discover_1_FreshWatercolor"]),
                                 generateModel: TSGenerateModel(json: ptp_FreshWatercolor)),
 
 //            TSDiscoverItemModel(style: .ptp,
@@ -196,9 +194,7 @@ class TSDiscoverViewModel {
         ]]
         return section
     }()
-    
-    
-    
+
     lazy var petToHumanSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .fullCard
@@ -211,45 +207,44 @@ class TSDiscoverViewModel {
                                 ),
                                 generateModel: TSGenerateModel(json: catTohuman)),
         ]
-        
+
         return section
     }()
-    
-    
+
     lazy var figuresToysSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Figures&Toys".localized,imageNamed: "🧸",colors: ["#D7A863","#FFFFFF"])
+        section.setTitle(title: "Figures&Toys".localized, imageNamed: "🧸", colors: ["#D7A863", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimeFigure","discover_1_AnimeFigure"]),
+
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimeFigure", "discover_1_AnimeFigure"]),
                                 generateModel: TSGenerateModel(json: ptp_ActionFigure)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Lafufu","discover_1_Lafufu"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Lafufu", "discover_1_Lafufu"]),
                                 generateModel: TSGenerateModel(json: ptp_Lafufu)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_WhimsicalDoll","discover_1_WhimsicalDoll"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_WhimsicalDoll", "discover_1_WhimsicalDoll"]),
                                 generateModel: TSGenerateModel(json: ptp_WhimsicalDoll)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PushToy","discover_1_PushToy"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PushToy", "discover_1_PushToy"]),
                                 generateModel: TSGenerateModel(json: ptp_PlushToy)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Polaroid","discover_1_Polaroid"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Polaroid", "discover_1_Polaroid"]),
                                 generateModel: TSGenerateModel(json: ptp_Polaroid)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MusicBox","discover_1_MusicBox"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MusicBox", "discover_1_MusicBox"]),
                                 generateModel: TSGenerateModel(json: ptp_MusicBox)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Earphone","discover_1_Earphone"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Earphone", "discover_1_Earphone"]),
                                 generateModel: TSGenerateModel(json: ptp_Earphone)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Kulomi","discover_1_Kulomi"]),
-                                generateModel: TSGenerateModel(json: ptp_Kulomi))
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Kulomi", "discover_1_Kulomi"]),
+                                generateModel: TSGenerateModel(json: ptp_Kulomi)),
         ]]
         return section
     }()
-    
+
 //    lazy var babyCardSection: TSDiscoverSectionModel = {
 //        let section = TSDiscoverSectionModel()
 //        section.style = .fullCard
@@ -266,7 +261,7 @@ class TSDiscoverViewModel {
 //
 //        return section
 //    }()
-    
+
     lazy var babyCardSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .fullCard
@@ -281,102 +276,96 @@ class TSDiscoverViewModel {
         ]
         return section
     }()
-    
 
     lazy var coolPersonalitySection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Cool Personality".localized,imageNamed: "🔮",colors: ["#DB6BE6","#FFFFFF"])
+        section.setTitle(title: "Cool Personality".localized, imageNamed: "🔮", colors: ["#DB6BE6", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cyberpunk","discover_1_Cyberpunk"]),
+
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cyberpunk", "discover_1_Cyberpunk"]),
                                 generateModel: TSGenerateModel(json: ptp_Cyberpunk)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Gothic","discover_1_Gothic"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Gothic", "discover_1_Gothic"]),
                                 generateModel: TSGenerateModel(json: ptp_Gothic)),
             TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Y2K","discover_1_Y2K"]),
+
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Y2K", "discover_1_Y2K"]),
                                 generateModel: TSGenerateModel(json: ptp_Y2KMillennium)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dopamine","discover_1_Dopamine"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dopamine", "discover_1_Dopamine"]),
                                 generateModel: TSGenerateModel(json: ptp_Dopamine)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Neon","discover_1_Neon"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Neon", "discover_1_Neon"]),
                                 generateModel: TSGenerateModel(json: ptp_Neon)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_DarkAcademia","discover_1_DarkAcademia"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_DarkAcademia", "discover_1_DarkAcademia"]),
                                 generateModel: TSGenerateModel(json: ptp_DarkAcademia)),
         ]]
         return section
     }()
-    
-    
-    
+
     lazy var animeCartoonSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Anime&Cartoon".localized,imageNamed: "🧚🏻‍♀️",colors: ["#A4EAD4","#FFFFFF"])
+        section.setTitle(title: "Anime&Cartoon".localized, imageNamed: "🧚🏻‍♀️", colors: ["#A4EAD4", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimalCrossing","discover_1_AnimalCrossing"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimalCrossing", "discover_1_AnimalCrossing"]),
                                 generateModel: TSGenerateModel(json: ptp_AnimalCrossing)),
             TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_YellowBunch","discover_1_YellowBunch"]),
+
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_YellowBunch", "discover_1_YellowBunch"]),
                                 generateModel: TSGenerateModel(json: ptp_YellowBunch)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SweetieCat","discover_1_SweetieCat"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SweetieCat", "discover_1_SweetieCat"]),
                                 generateModel: TSGenerateModel(json: ptp_SweetieCat)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Puppy","discover_1_Puppy"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Puppy", "discover_1_Puppy"]),
                                 generateModel: TSGenerateModel(json: ptp_Puppy)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cibi","discover_1_Cibi"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cibi", "discover_1_Cibi"]),
                                 generateModel: TSGenerateModel(json: ptp_Cibi)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MarinerKing","discover_1_MarinerKing"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MarinerKing", "discover_1_MarinerKing"]),
                                 generateModel: TSGenerateModel(json: ptp_MarinerKing)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SonOfDragon","discover_1_SonOfDragon"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SonOfDragon", "discover_1_SonOfDragon"]),
                                 generateModel: TSGenerateModel(json: ptp_SonOfDragon)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Barbie","discover_1_Barbie"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Barbie", "discover_1_Barbie"]),
                                 generateModel: TSGenerateModel(json: ptp_Barbie)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Chiikawa","discover_1_Chiikawa"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Chiikawa", "discover_1_Chiikawa"]),
                                 generateModel: TSGenerateModel(json: ptp_Chiikawa)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_3DBox","discover_1_3DBox"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_3DBox", "discover_1_3DBox"]),
                                 generateModel: TSGenerateModel(json: ptp_3DBox)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BattleBlitz","discover_1_BattleBlitz"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BattleBlitz", "discover_1_BattleBlitz"]),
                                 generateModel: TSGenerateModel(json: ptp_BattleBlitz)),
 
-            
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mythos","discover_1_Mythos"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mythos", "discover_1_Mythos"]),
                                 generateModel: TSGenerateModel(json: ptp_Mythos)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EmpireDash","discover_1_EmpireDash"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EmpireDash", "discover_1_EmpireDash"]),
                                 generateModel: TSGenerateModel(json: ptp_EmpireDash)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PocketBeasts","discover_1_PocketBeasts"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PocketBeasts", "discover_1_PocketBeasts"]),
                                 generateModel: TSGenerateModel(json: ptp_PocketBeasts)),
         ]]
-        
+
         return section
     }()
-    
-    
-    
+
     lazy var ttpCardSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .fullCard
@@ -389,73 +378,70 @@ class TSDiscoverViewModel {
                                 ),
                                 generateModel: nil),
         ]
-        
+
         return section
     }()
-    
-    
+
     lazy var trendingSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Trending".localized,imageNamed:"🚀",colors: ["#4887BB","#FFFFFF"])
+        section.setTitle(title: "Trending".localized, imageNamed: "🚀", colors: ["#4887BB", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Fairy","discover_1_Fairy"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Fairy", "discover_1_Fairy"]),
                                 generateModel: TSGenerateModel(json: ptp_Fairy)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_CyberFairy","discover_1_CyberFairy"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_CyberFairy", "discover_1_CyberFairy"]),
                                 generateModel: TSGenerateModel(json: ptp_CyberFairy)),
-            
+
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_Mermaid"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid", "discover_1_Mermaid"]),
                                 generateModel: TSGenerateModel(json: ptp_Mermaid)),
 
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CyberMermaid"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid", "discover_1_CyberMermaid"]),
                                 generateModel: TSGenerateModel(json: ptp_CyberpunkMermaid)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CuteMermaid"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid", "discover_1_CuteMermaid"]),
                                 generateModel: TSGenerateModel(json: ptp_CuteMermaid)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_DarckMermaid"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid", "discover_1_DarckMermaid"]),
                                 generateModel: TSGenerateModel(json: ptp_DarkMermaid)),
         ]]
-        
+
         return section
     }()
-    
-
 
     lazy var processPhotoSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Process Photo".localized,imageNamed:"🚀",colors: ["#DEA94E","#FFFFFF"])
+        section.setTitle(title: "Process Photo".localized, imageNamed: "🚀", colors: ["#DEA94E", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .photoLive,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .gif, imageNameds: ["discover_0_AnimatePhoto1"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", style: .gif, imageNameds: ["discover_0_AnimatePhoto1"]),
                                 generateModel: TSGenerateModel(json: photoLive)),
-            
+
             TSDiscoverItemModel(style: .photoQuality,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EnhancerPhoto","discover_1_EnhancerPhoto"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EnhancerPhoto", "discover_1_EnhancerPhoto"]),
                                 generateModel: TSGenerateModel(json: photoQuality)),
-            
+
             TSDiscoverItemModel(style: .process,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RecreatePhoto","discover_1_RecreatePhoto"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RecreatePhoto", "discover_1_RecreatePhoto"]),
                                 generateModel: TSGenerateModel(json: recreatePhoto)),
-            
+
             TSDiscoverItemModel(style: .oldPhoto,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RestorPhoto","discover_1_RestorPhoto"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RestorPhoto", "discover_1_RestorPhoto"]),
                                 generateModel: TSGenerateModel(json: oldPhoto)),
-            
+
             TSDiscoverItemModel(style: .process,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Colorize","discover_1_Colorize"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Colorize", "discover_1_Colorize"]),
                                 generateModel: TSGenerateModel(json: colorize)),
 
             TSDiscoverItemModel(style: .photoExpand,
                                 viewModel: TSDiscoverBaseItemVM(title: "", imageNamed: "discover_0_ExpandPhoto"),
                                 generateModel: TSGenerateModel(json: photoExpand)),
         ]]
-        
+
         return section
     }()
 
@@ -471,82 +457,80 @@ class TSDiscoverViewModel {
                                 ),
                                 generateModel: nil),
         ]
-        
+
         return section
     }()
-    
+
     lazy var artFilterSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Art Filter".localized,imageNamed:"🖼️",colors: ["#6CCC2B","#FFFFFF"])
+        section.setTitle(title: "Art Filter".localized, imageNamed: "🖼️", colors: ["#6CCC2B", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_OilPainting","discover_1_OilPainting"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_OilPainting", "discover_1_OilPainting"]),
                                 generateModel: TSGenerateModel(json: ptp_OilPainting)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MonaLisa","discover_1_MonaLisa"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MonaLisa", "discover_1_MonaLisa"]),
                                 generateModel: TSGenerateModel(json: ptp_MonaLisa)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pixel","discover_1_Pixel"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pixel", "discover_1_Pixel"]),
                                 generateModel: TSGenerateModel(json: ptp_Pixel)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Sketch","discover_1_Sketch"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Sketch", "discover_1_Sketch"]),
                                 generateModel: TSGenerateModel(json: ptp_Sketch)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Watercolor","discover_1_Watercolor"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Watercolor", "discover_1_Watercolor"]),
                                 generateModel: TSGenerateModel(json: ptp_Watercolor)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_VanGogh","discover_1_VanGogh"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_VanGogh", "discover_1_VanGogh"]),
                                 generateModel: TSGenerateModel(json: ptp_VanGogh)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dreamcore","discover_1_Dreamcore"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dreamcore", "discover_1_Dreamcore"]),
                                 generateModel: TSGenerateModel(json: ptp_Dreamcore)),
             TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Doodle","discover_1_Doodle"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Doodle", "discover_1_Doodle"]),
                                 generateModel: TSGenerateModel(json: ptp_Doodle)),
         ]]
         return section
     }()
 
-    
     lazy var bePrettySection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .styleMore
-        section.setTitle(title:"Be Pretty".localized,imageNamed:"🥰",colors: ["#FFA537","#FFFFFF"])
+        section.setTitle(title: "Be Pretty".localized, imageNamed: "🥰", colors: ["#FFA537", "#FFFFFF"])
         section.items = [[
             TSDiscoverItemModel(style: .changehair,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairSalon","discover_1_HairSalon","discover_2_HairSalon"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairSalon", "discover_1_HairSalon", "discover_2_HairSalon"]),
                                 generateModel: TSGenerateModel(json: hairSalon)),
-            
+
             TSDiscoverItemModel(style: .changehairColor,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairColor","discover_1_HairColor","discover_2_HairColor"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairColor", "discover_1_HairColor", "discover_2_HairColor"]),
                                 generateModel: TSGenerateModel(json: hairColor)),
-            
+
             TSDiscoverItemModel(style: .pretty,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pretty","discover_1_Pretty"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pretty", "discover_1_Pretty"]),
                                 generateModel: TSGenerateModel(json: pretty)),
-            
+
             TSDiscoverItemModel(style: .eyeOpen,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FaceFix","discover_1_FaceFix"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FaceFix", "discover_1_FaceFix"]),
                                 generateModel: TSGenerateModel(json: eyeOpen)),
-            
+
             TSDiscoverItemModel(style: .changeEmote,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FacialExpression","discover_1_FacialExpression"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FacialExpression", "discover_1_FacialExpression"]),
                                 generateModel: TSGenerateModel(json: changeEmotion)),
- 
+
             TSDiscoverItemModel(style: .ageChild,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BackToBaby","discover_1_BackToBaby"]),
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BackToBaby", "discover_1_BackToBaby"]),
                                 generateModel: TSGenerateModel(json: ageChild)),
         ]]
-        
+
         return section
     }()
-    
-    
+
     lazy var oldAgeCardSection: TSDiscoverSectionModel = {
         let section = TSDiscoverSectionModel()
         section.style = .fullCard
-        section.setTitle(title:"More AI Tools".localized,imageNamed:"🪄",colors: ["#FFFF73","#FFFFFF"])
+        section.setTitle(title: "More AI Tools".localized, imageNamed: "🪄", colors: ["#FFFF73", "#FFFFFF"])
         section.items = [
             TSDiscoverItemModel(style: .ageOld,
                                 viewModel: TSDiscoverBaseItemVM(
@@ -556,14 +540,12 @@ class TSDiscoverViewModel {
                                 ),
                                 generateModel: TSGenerateModel(json: ageOld)),
         ]
-        
+
         return section
     }()
-    
-    
-    
+
     lazy var discoverDatas: [TSDiscoverSectionModel] = {
-        return [
+        [
             bannerSection,
             videoEffectSection,
             popularStylesSection,
@@ -581,7 +563,4 @@ class TSDiscoverViewModel {
             chatCardSection,
         ]
     }()
-    
-
-
 }

+ 127 - 132
AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateVC.swift

@@ -6,40 +6,42 @@
 //
 
 class TSAIGenerateVC: TSAIGenerateBaseVC {
-    var reloadViewBlock:(()->Void)?
-    var changeImageBlock:((UIImage)->Void)?
+    var reloadViewBlock: (() -> Void)?
+    var changeImageBlock: ((UIImage) -> Void)?
     var progressState = TSProgressState.none
 
-    var isSavePhotoMark:Bool = false
-    var isNeedSavePhoto:Bool {
-        if isSavePhotoMark == false,let _ = infoModel {
+    var isSavePhotoMark: Bool = false
+    var isNeedSavePhoto: Bool {
+        if isSavePhotoMark == false, let _ = infoModel {
             return true
         }
         return false
     }
-    var uuidString:String = UUID().uuidString
-    var operation:TSGenerateBaseOperation?
-    
+
+    var uuidString: String = UUID().uuidString
+    var operation: TSGenerateBaseOperation?
+
     lazy var photoPickerManager: TSPhotoPickerManager = {
         let photoPickerManager = TSPhotoPickerManager(viewController: self)
         return photoPickerManager
     }()
-    lazy var generateInView : TSGeneratorView = {
+
+    lazy var generateInView: TSGeneratorView = {
         let generateInView = TSGeneratorView()
 //        if generatorModel.advance {
-            generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
+        generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
 //        }else{
 //            generateInView.animationView.setText(time: String(format: "~ %d seconds".localized, 20), info: "")
 //        }
-        
-        generateInView.clickBackstageBlock = { [weak self]  in
+
+        generateInView.clickBackstageBlock = { [weak self] in
             guard let self = self else { return }
             clickBackstageBtn()
         }
-        
+
         generateInView.clickErrorBlock = { [weak self] style in
             guard let self = self else { return }
-            
+
             switch style {
             case .netWorkError:
                 clickTryAgainBtn()
@@ -52,67 +54,66 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
         }
         return generateInView
     }()
-    
 
     override func createView() {
         view.insertSubview(generateInView, at: 0)
         generateInView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
-        
+
         super.createView()
         contentView.isHidden = true
     }
-    
+
     override func closePage() {
         if progressState.isResult {
-            if isNeedSavePhoto{
+            if isNeedSavePhoto {
                 TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
                     message: "You haven't saved the photo yet. Are you sure to quit?".localized,
                     messageColor: .white,
                     messageFont: .systemFont(ofSize: 16),
-                    
+
                     cancelTitle: "Quit".localized,
                     cancelColor: .white,
-                    
+
                     confirmTitle: "Save".localized,
                     confirmColor: .themeColor,
-                    
-                    cancelAction: { [weak self]  in
+
+                    cancelAction: { [weak self] in
                         guard let self = self else { return }
                         print("用户点击了Leave")
                         cancelDidmiss()
                     },
-                    confirmAction: { [weak self]  in
+                    confirmAction: { [weak self] in
                         guard let self = self else { return }
                         print("用户点击了Stay")
                         clickSaveBtn()
                     }
                 ))
-            }else{
+            } else {
                 cancelDidmiss()
             }
-        }else{
+        } else {
             TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
                 message: "As you leave, your generation will be interrupted and no result.".localized,
                 messageColor: .white,
                 messageFont: .systemFont(ofSize: 16),
-                
+
                 cancelTitle: "Leave".localized,
                 cancelColor: .white,
-                
+
                 confirmTitle: "Wait".localized,
                 confirmColor: .themeColor,
-                
-                cancelAction: { [weak self]  in
+
+                cancelAction: { [weak self] in
                     guard let self = self else { return }
                     print("用户点击了Leave")
-                    
-                    if let model = infoModel{
-                        TSRMShared.aiGenerateDB.deleteListModel(uuid:model.uuid)
+
+                    if let model = infoModel {
+                        TSRMShared.aiGenerateDB.deleteListModel(uuid: model.uuid)
                         NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
                     }
-        
+
                     cancelDidmiss()
                 },
                 confirmAction: {
@@ -121,42 +122,42 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
             ))
         }
     }
-    
-    func cancelDidmiss(){
+
+    func cancelDidmiss() {
         operation?.cancel()
-        self.dismiss(animated: true, completion: nil)
+        dismiss(animated: true, completion: nil)
     }
-    
-    //重试
-    @objc override func clickTryAgainBtn(){
+
+    // 重试
+    @objc override func clickTryAgainBtn() {
         clickRegenerateBtn()
     }
-    
-    //后台生成
+
+    // 后台生成
     @objc func clickBackstageBtn() {
-        self.operation?.backstageGeneration()
+        operation?.backstageGeneration()
         NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
         NotificationCenter.default.post(name: .kAIComeInBackstage, object: nil)
-        self.dismiss(animated: true, completion: nil)
+        dismiss(animated: true, completion: nil)
     }
-    
-    //重新生成
-    @objc override func clickRegenerateBtn(){
-        //判断 vip
+
+    // 重新生成
+    @objc override func clickRegenerateBtn() {
+        // 判断 vip
 //        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .aiGenerate) == false, vc: self) { return }
         if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: generatorModel.generatorStyle.vipFreeNumType) == false, vc: self) { return }
-        self.infoModel?.actionStatus = .failed//状态设为失败,走generatorCreat
-        self.uuidString = UUID().uuidString//设置新的uuid,新的储存数据
-        generatorOperation()//开始生成
+        infoModel?.actionStatus = .failed // 状态设为失败,走generatorCreat
+        uuidString = UUID().uuidString // 设置新的uuid,新的储存数据
+        generatorOperation() // 开始生成
     }
-    
-    //保存功能
+
+    // 保存功能
 //    @objc override func clickSaveBtn(){
 //        if let image = getSuccessImage() {
 //            PhotoManagerShared.saveImageToAlbum(image) { success, error in
 //                if success {
 //                    kSaveSuccesswShared.show(atView:self.view)
-//                    
+//
 //                    self.isSavePhotoMark = true
 //                }else{
 //                    debugPrint(error)
@@ -164,11 +165,11 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
 //            }
 //        }
 //    }
-    
-    //保存功能
-    @objc override func clickSaveBtn(){
-        self.isSavePhotoMark = true
-        if kJudgeVip(externalBool: true,vc: self) {
+
+    // 保存功能
+    @objc override func clickSaveBtn() {
+        isSavePhotoMark = true
+        if kJudgeVip(externalBool: true, vc: self) {
             return
         }
 
@@ -181,28 +182,28 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
                     PhotoManagerShared.saveVideoToAlbum(videoURL: url) { success, error in
                         if success {
                             kSaveSuccesswShared.show(atView: self.view)
-                        }else{
+                        } else {
                             debugPrint(error)
                         }
                     }
                 }
             }
-        }else{
+        } else {
             TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { image in
-                if let image = image{
+                if let image = image {
                     PhotoManagerShared.saveImageToAlbum(image) { success, error in
                         if success {
                             kSaveSuccesswShared.show(atView: self.view)
-                        }else{
+                        } else {
                             debugPrint(error)
                         }
                     }
-                }else{//如果服务器取不到,直接保存当前显示的图片
+                } else { // 如果服务器取不到,直接保存当前显示的图片
                     if let currentImage = self.getSuccessImage() {
                         PhotoManagerShared.saveImageToAlbum(currentImage) { success, error in
                             if success {
                                 kSaveSuccesswShared.show(atView: self.view)
-                            }else{
+                            } else {
                                 debugPrint(error)
                             }
                         }
@@ -211,17 +212,15 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
             }
         }
     }
-    
-    
-    
+
 //    override func clickShare() {
 //        guard let image = getSuccessImage() else { return }
 //        kShareContent(target: self, anyData: image)
 //    }
-    
+
     override func clickShare() {
-        self.isSavePhotoMark = true
-        if kJudgeVip(externalBool: true,vc: self) {
+        isSavePhotoMark = true
+        if kJudgeVip(externalBool: true, vc: self) {
             return
         }
         guard let currentModel = infoModel else { return }
@@ -233,11 +232,11 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
                     kShareContent(target: self, anyData: url)
                 }
             }
-        }else{
+        } else {
             TSImageStoreTool.downloadImageWithProgress(urlString: urlString) { image in
-                if let image = image{
+                if let image = image {
                     kShareContent(target: self, anyData: image)
-                }else{//如果服务器取不到,直接保存当前显示的图片
+                } else { // 如果服务器取不到,直接保存当前显示的图片
                     if let currentImage = self.getSuccessImage() {
                         kShareContent(target: self, anyData: currentImage)
                     }
@@ -245,54 +244,56 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
             }
         }
     }
-    
+
     override func dealThings() {
-        self.uuidString = UUID().uuidString
+        uuidString = UUID().uuidString
         generatorOperation()
     }
-    
-    
+
     func generatorOperation() {
-        if let model = self.infoModel{
-            if model.actionStatus == .failed{
+        if let model = infoModel {
+            if model.actionStatus == .failed {
                 generatorCreat(oldModel: model)
-            }else if model.response.resultUrl.count > 0 {
+            } else if model.response.resultUrl.count > 0 {
                 upDateView(state: .success(model), model: model)
                 return
             }
-        }else{
+        } else {
             generatorNew()
         }
     }
 }
 
-extension TSAIGenerateVC{
-    
+extension TSAIGenerateVC {
     func generatorNew() {
-
-        let operation:TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: self.uuidString)
+        let operation: TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: uuidString)
         self.operation = operation
-        operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
+        operation.$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)
-        
-        operation.uploadImage(generateStyleModel: self.generatorModel)  { [weak self] actionInfoModel in
-            guard let self = self else { return }
-            guard let oldModel = actionInfoModel else {return}
-            generatorCreat(oldModel: oldModel)
+
+        if generatorModel.generatorStyle == .textToVideo {
+            guard let actionInfoModel = operation.createActionInfoModel(generateStyleModel: generatorModel) else { return }
+            generatorCreat(oldModel: actionInfoModel)
+        } else {
+            operation.uploadImage(generateStyleModel: generatorModel) { [weak self] actionInfoModel in
+                guard let self = self else { return }
+                guard let oldModel = actionInfoModel else { return }
+                generatorCreat(oldModel: oldModel)
+            }
         }
     }
-    
-    func generatorCreat(oldModel:TSActionInfoModel) {
-        let operation:TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: self.uuidString)
+
+    func generatorCreat(oldModel: TSActionInfoModel) {
+        let operation: TSGenerateBasePhotoOperation = TSGenerateBasePhotoOperationQueue.shared.creatOperation(uuid: uuidString)
         self.operation = operation
-        operation.$stateDatauPblished.receive(on: DispatchQueue.main).sink {[weak self]  (state,model) in
+        operation.$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)
-        operation.generateStyleModel = self.generatorModel
-        operation.creatImage(oldModel: oldModel){ [weak self]  success in
+        operation.generateStyleModel = generatorModel
+        operation.creatImage(oldModel: oldModel) { [weak self] success in
             guard let self = self else { return }
             if success {
                 generateInView.setBackgroundGenerateBtnHidden(false)
@@ -302,7 +303,6 @@ extension TSAIGenerateVC{
 }
 
 extension TSAIGenerateVC {
-    
     func pickSinglePhoto() {
         photoPickerManager.pickCustomSinglePhoto { [weak self] image, errorString in
             guard let self = self else { return }
@@ -321,69 +321,64 @@ extension TSAIGenerateVC {
             }
         }
     }
-    
-    func getSuccessImage()->UIImage?{
+
+    func getSuccessImage() -> UIImage? {
         if let image = netWorkImageView.image {
             return image.pngImage
         }
         return nil
     }
-    
 }
+
 extension TSAIGenerateVC {
-    
-    func upDateView(state:TSProgressState,model:TSActionInfoModel?){
+    func upDateView(state: TSProgressState, model: TSActionInfoModel?) {
         progressState = state
         switch state {
-            case .failed(let errorStr,let code):
-                showError(text: errorStr,code:code)
-            case .success:
-                if let model = model {
-                    showSuccess(model: model)
-                }else{
-                    showError(text: "")
-                }
-            case .progressString(let string):
-                showProgress(text: string)
-            case .none:
-                break
-            default:
-                showLoading()
+        case let .failed(errorStr, code):
+            showError(text: errorStr, code: code)
+        case .success:
+            if let model = model {
+                showSuccess(model: model)
+            } else {
+                showError(text: "")
+            }
+        case let .progressString(string):
+            showProgress(text: string)
+        case .none:
+            break
+        default:
+            showLoading()
         }
     }
-    
-    func showProgress(text:String) {
+
+    func showProgress(text: String) {
         generateInView.updateShowProgress(text: text)
         contentView.isHidden = true
     }
-    
-    func showLoading(){
+
+    func showLoading() {
         generateInView.updateShowLoading(text: "Generating".localized + " " + kPercentlocalized(0))
         contentView.isHidden = true
-
     }
-    
-    func showError(text:String,code:Int = 0){
-        generateInView.updateShowError(text: text,code: code)
+
+    func showError(text: String, code: Int = 0) {
+        generateInView.updateShowError(text: text, code: code)
         contentView.isHidden = true
         xBtn.isHidden = false
-
     }
-    
-    func showSuccess(model:TSActionInfoModel){
+
+    func showSuccess(model: TSActionInfoModel) {
         generateInView.updateShowSuccess()
         contentView.isHidden = false
         xBtn.isHidden = false
-        
+
         switchOriginalPictureBtn.isHidden = isHiddenSwitch
         infoModel = model
         if let model = infoModel {
             model.request.inputText = generatorModel.inputText
             complete(model)
         }
-        
-        
+
         kFirstSaveRateAction()
     }
-    
 }

+ 1 - 1
AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBannerItemCell.swift

@@ -16,7 +16,7 @@ class TSDiscoverBannerItemCell : UIView {
     }()
     
     lazy var iconView : UIImageView = .init(image: .icImg2Video)
-    lazy var titleLabel = UILabel.createLabel(text: "Text to Video".localized,font: .font(size: 14.0,weight: .medium),textColor: .white,textAlignment: .center)
+    lazy var titleLabel = UILabel.createLabel(text: "Image to Video".localized,font: .font(size: 14.0,weight: .medium),textColor: .white,textAlignment: .center)
 
     override init(frame: CGRect) {
         super.init(frame: frame)

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

@@ -38,7 +38,8 @@ enum TSNeURLType:String {
     
     
     case videoV2 = "/api/video/create/v2"          //换衣服
-    case text2Video = "api/video/text2video" // 文生视频
+    case text2Video = "/api/video/text2video" // 文生视频
+    case img2video = "/api/video/img2video"  //图生视频
     
     func getUrlString() -> String {
         if Locale.current.identifier.contains("_CN") {//中国区

+ 2 - 1
AIEmoji/Common/TSRealmManager/TSRealmManager.swift

@@ -19,9 +19,10 @@ class TSRealmManager {
          3.6.1  ->4   //将UserDefaults 的历史记录迁移到数据库中
          ui大改版 - >5
          3.6.23 - >7
+         3.6.26 - >8
          **/
    
-        let newSchemaVersion: UInt64 = 7
+        let newSchemaVersion: UInt64 = 8
         // 获取默认配置
         var config = Realm.Configuration.defaultConfiguration
         // 设置新版本号

+ 4 - 1
AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBaseOperation.swift

@@ -209,7 +209,10 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
                 }
             }
             
-        }else if currentActionInfoModel.request.generatorStyle == .videoV2{
+        }else if [TSFuncStyle.videoV2 ,
+                  TSFuncStyle.textToVideo,
+                  TSFuncStyle.pictureToVideo].contains(currentActionInfoModel.request.generatorStyle)
+        {
             downloadVideo(urlString: infoModel.response.resultUrl) { [weak self] url in
                 guard let self = self else { return }
                 if let url = url {

+ 154 - 138
AIEmoji/Common/Tool/OperationQueue/V2/TSGenerateBasePhotoOperation.swift

@@ -5,33 +5,30 @@
 //  Created by 100Years on 2025/3/24.
 //
 
-import Combine
 import Alamofire
-import ObjectMapper
+import Combine
 import Kingfisher
+import ObjectMapper
 class TSGenerateBasePhotoOperationQueue: TSGenerateBaseOperationQueue {
-    static let shared:TSGenerateBasePhotoOperationQueue = TSGenerateBasePhotoOperationQueue()
+    static let shared: TSGenerateBasePhotoOperationQueue = TSGenerateBasePhotoOperationQueue()
 
     func creatOperation(uuid: String) -> TSGenerateBasePhotoOperation {
         let operation = super.creatOperation(uuid: uuid, type: TSGenerateBasePhotoOperation.self)
         handleStateDatauPblished(uuid: uuid, generateOperation: operation as! TSGenerateBaseOperation, notificationName: .kGenerateBasePhotoOperation)
         return operation as! TSGenerateBasePhotoOperation
     }
-    
-    override func getUUIDData(uuid:String)->(TSProgressState,TSActionInfoModel?){
+
+    override func getUUIDData(uuid: String) -> (TSProgressState, TSActionInfoModel?) {
         if let PosterOperation = TSGenerateBasePhotoOperationQueue.shared.findOperation(uuid: uuid) as? TSGenerateBasePhotoOperation {
             dePrint("TSBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
-            return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
+            return (PosterOperation.stateDatauPblished.0, PosterOperation.currentActionInfoModel)
         }
-        return (.none,TSActionInfoModel())
+        return (.none, TSActionInfoModel())
     }
-    
-    
-    
-    static func isAvailabilityHandle(view:UIView)->Bool{
-        
+
+    static func isAvailabilityHandle(view: UIView) -> Bool {
         if TSGenerateBasePhotoOperationQueue.shared.isAvailability == false {
-            kTextToastShared.show(atView: view,text: String(format: "%d task is processing".localized, 1)){
+            kTextToastShared.show(atView: view, text: String(format: "%d task is processing".localized, 1)) {
                 TSGenerateHistoryVC.showPosition()
             }
             return true
@@ -40,18 +37,17 @@ class TSGenerateBasePhotoOperationQueue: TSGenerateBaseOperationQueue {
     }
 }
 
-class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendable{
-
-    override func replaceSaveInfoModel(model:TSActionInfoModel){
+class TSGenerateBasePhotoOperation: TSGenerateBaseOperation, @unchecked Sendable {
+    override func replaceSaveInfoModel(model: TSActionInfoModel) {
         model.uuid = uuid
         model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
         model.request.generatorStyle = currentActionInfoModel.request.generatorStyle
         model.request.model = currentActionInfoModel.request.model
-        
-        if model.request.imageUrl.isEmpty ,model.request.imageUrls.count > 0 {
+
+        if model.request.imageUrl.isEmpty, model.request.imageUrls.count > 0 {
             model.request.imageUrl = model.request.imageUrls.first ?? ""
         }
-        
+
         if isSaveProcessToDB {
             saveDataDB()
         }
@@ -64,8 +60,9 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
         if currentActionInfoModel.id == 0 {
             return
         }
-        TSRMShared.aiGenerateDB.updateData(currentActionInfoModel,uuid: uuid)
+        TSRMShared.aiGenerateDB.updateData(currentActionInfoModel, uuid: uuid)
     }
+
     override func handleGenerateSuccess() {
         kPurchaseDefault.useOnceForFree(type: currentActionInfoModel.request.generatorStyle.vipFreeNumType)
         saveDataDB()
@@ -73,11 +70,11 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
 //        //生成成功后,不再提示用户上传规则弹窗
 //        UserDefaults.standard.set("1", forKey: currentActionInfoModel.request.generatorStyle.userDefaultsKey)
 //        UserDefaults.standard.synchronize()
-        
+
         showSuccessView()
     }
-    
-    func showSuccessView(){
+
+    func showSuccessView() {
         if isShowSuccessView == false {
             return
         }
@@ -85,28 +82,27 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
             debugPrint("getKeyWindow nil")
             return
         }
-        
+
         guard let rootVC = WindowHelper.topViewController() else {
             debugPrint("handleGenerateSuccess topViewController nil")
             return
         }
-        
-        let copyModel = self.currentActionInfoModel.copy()
+
+        let copyModel = currentActionInfoModel.copy()
         if let cyModel = copyModel as? TSActionInfoModel {
-            let topY = k_Nav_Height+10
+            let topY = k_Nav_Height + 10
             debugPrint("topY=\(topY)")
-            kSaveSuccesswShared.show(atView: window,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: topY)) {
+            kSaveSuccesswShared.show(atView: window, text: "Successfully generated".localized, deadline: 5.0, bottom: kSaveSuccesswShared.getBottom(topY: topY)) {
                 let generatorModel = self.generateStyleModel ?? TSAIGeneratorModel(upLoadImage: UIImage(), generatorStyle: .ptp)
-                let gennerateVC = TSAIGenerateVC(generatorModel:generatorModel, infoModel: cyModel){ model in }
+                let gennerateVC = TSAIGenerateVC(generatorModel: generatorModel, infoModel: cyModel) { _ in }
                 gennerateVC.modalPresentationStyle = .overFullScreen
                 gennerateVC.modalTransitionStyle = .crossDissolve
                 rootVC.present(gennerateVC, animated: true)
             }
-        }else{
+        } else {
             debugPrint("copyModel as? TSActionInfoModel error")
         }
     }
-    
 
     /**
         1.用户上传图片
@@ -114,92 +110,100 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
         3.后台返回查询 id,根据 id 不断查询进度和结果.(此时才允许进度后台)
         利用3后台返回的TSActionRequestModel中存着关键的请求接口数据,请求数据
      */
-    
-    private var uploadRequest:Request?
-    private var creatRequest:Request?
-    var generateStyleModel:TSAIGeneratorModel?
-    func createActionInfoModel(generateStyleModel:TSAIGeneratorModel) -> TSActionInfoModel? {
-        guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
 
+    private var uploadRequest: Request?
+    private var creatRequest: Request?
+    var generateStyleModel: TSAIGeneratorModel?
+    func createActionInfoModel(generateStyleModel: TSAIGeneratorModel) -> TSActionInfoModel? {
         let infoModel = TSActionInfoModel()
         infoModel.id = Date.timestampInt
         infoModel.request = TSActionRequestModel()
-        infoModel.request.imageUrl = upLoadImageUrl
+        infoModel.request.imageUrl = generateStyleModel.upLoadImageUrl ?? ""
         infoModel.request.imageUrlTimestamp = Date.timestampInt
         infoModel.request.imageUrls = generateStyleModel.upLoadImageUrls
-        
+
         infoModel.request.prompt = generateStyleModel.prompt
         infoModel.request.inputText = generateStyleModel.inputText
         infoModel.request.generatorStyle = generateStyleModel.generatorStyle
         infoModel.request.model = generateStyleModel.model
         infoModel.request.template = generateStyleModel.template
+
+        infoModel.request.resolution = generateStyleModel.diyVideoGenerateModel?.resolution ?? ""
+        infoModel.request.style = generateStyleModel.diyVideoGenerateModel?.style ?? ""
+        infoModel.request.duration = generateStyleModel.diyVideoGenerateModel?.duration ?? 0
+        infoModel.request.bgm = generateStyleModel.diyVideoGenerateModel?.bgm ?? true
+        infoModel.request.aspectRatio = generateStyleModel.diyVideoGenerateModel?.aspectRatio ?? ""
+
+        if generateStyleModel.generatorStyle == .textToVideo {
+            infoModel.request.prompt = generateStyleModel.diyVideoGenerateModel?.prompt ?? ""
+        }
         return infoModel
     }
-    
-    func creatImage(oldModel:TSActionInfoModel,complete:@escaping (Bool)->Void) {
+
+    func creatImage(oldModel: TSActionInfoModel, complete: @escaping (Bool) -> Void) {
         initializeActionInfoModel(oldModel: oldModel)
-        if oldModel.upImageURLExpired { return  }
+        if oldModel.upImageURLExpired { return }
         guard let getPostContent = getPostContent() else { return }
-        
+
         generatingProgress = 0
         stopNetwork = false
-        stateDatauPblished = (.start,nil)
+        stateDatauPblished = (.start, nil)
 
         currentActionInfoModel.status = "running"
         currentActionInfoModel.actionStatus = .running
         currentActionInfoModel.percent = 0
         replaceSaveInfoModel(model: currentActionInfoModel)
-        
-        stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
-        creatRequest = TSNetworkShared.post(urlType: getPostContent.0,parameters: getPostContent.1) { [weak self] data,error in
+
+        stateDatauPblished = (.progressString(generating(progress: 0.0)), currentActionInfoModel)
+        creatRequest = TSNetworkShared.post(urlType: getPostContent.0, parameters: getPostContent.1) { [weak self] data, error in
             guard let self = self else { return }
             if stopNetwork == true { return }
-            
+
             if let error = error {
-                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                handleFailInfoModel(errorString: error.tsDesc, code: error.tsCode)
                 complete(false)
-            }else{
+            } else {
                 if let dataDict = kNetWorkCodeSuccess(data: data),
-                   let actionId = dataDict["actionId"] as? Int{
+                   let actionId = dataDict["actionId"] as? Int {
                     if stopNetwork == false {
                         complete(true)
-                        self.stateDatauPblished = (.pending,nil) //通知首页进行更新
-                        self.getActionInfo(action_id:actionId)
+                        self.stateDatauPblished = (.pending, nil) // 通知首页进行更新
+                        self.getActionInfo(action_id: actionId)
                     }
-                }else{
-                    handleFailInfoModel(errorString: "",code: 0)
+                } else {
+                    handleFailInfoModel(errorString: "", code: 0)
                     complete(false)
                 }
             }
         }
     }
+
     override func generating(progress: Float) -> String {
-        let progress = Float(progress)*(kPercentScale) // 预留 10% 进度给图片下载
-        //Generating 0%-100%
-        var progressInt = Int(progress*100)
+        let progress = Float(progress) * kPercentScale // 预留 10% 进度给图片下载
+        // Generating 0%-100%
+        var progressInt = Int(progress * 100)
 
         if progressInt > 99 {
             progressInt = 99
         }
-        
+
         generatingProgress = progressInt
         return "Generating".localized + " " + kPercentlocalized(progressInt)
     }
 
-    var imageMaxKb:Int{
-        return 10*1024
+    var imageMaxKb: Int {
+        return 10 * 1024
     }
-    
-    func uploadingPhoto(progress:Float) -> String {
-        //Uploading Photo 0%-100%
-        var progressInt = Int(progress*100)
+
+    func uploadingPhoto(progress: Float) -> String {
+        // Uploading Photo 0%-100%
+        var progressInt = Int(progress * 100)
         if progressInt > 99 {
             progressInt = 99
         }
         return "Uploading Photo".localized + " " + kPercentlocalized(progressInt)
     }
-    
-    
+
     override func cancelCleanContent() {
         super.cancelCleanContent()
         debugPrint("cancelCleanContent")
@@ -207,78 +211,78 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
         creatRequest?.cancel()
     }
 }
-extension TSGenerateBasePhotoOperation {
-    
-    //上传一张图片
-    func uploadImage(generateStyleModel:TSAIGeneratorModel,complete:@escaping (TSActionInfoModel?)->Void) {
 
-        //走多张图片上传逻辑
-        if let upLoadImages = generateStyleModel.upLoadImages ,upLoadImages.count > 0{
+extension TSGenerateBasePhotoOperation {
+    // 上传一张图片
+    func uploadImage(generateStyleModel: TSAIGeneratorModel, complete: @escaping (TSActionInfoModel?) -> Void) {
+        // 走多张图片上传逻辑
+        if let upLoadImages = generateStyleModel.upLoadImages, upLoadImages.count > 0 {
             uploadImages(generateStyleModel: generateStyleModel, complete: complete)
             return
         }
-        
+
         self.generateStyleModel = generateStyleModel
-        if let imageUrl = generateStyleModel.upLoadImageUrl,imageUrl.contains("http") {
+        if let imageUrl = generateStyleModel.upLoadImageUrl, imageUrl.contains("http") {
             complete(createActionInfoModel(generateStyleModel: generateStyleModel))
             return
         }
-        
+
         let upLoadImage = generateStyleModel.upLoadImage
-        
+
         stopNetwork = false
-        stateDatauPblished = (.start,nil)
-        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),currentActionInfoModel)
-        
-        uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb,vipFreeNumType: generateStyleModel.generatorStyle.vipFreeNumType) { [weak self]  progress in
+        stateDatauPblished = (.start, nil)
+        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)), currentActionInfoModel)
+
+        uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb, vipFreeNumType: generateStyleModel.generatorStyle.vipFreeNumType) { [weak self] progress in
             guard let self = self else { return }
             if generatingProgress == 0 {
-                stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),currentActionInfoModel)
+                stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)), currentActionInfoModel)
             }
-        } completion: { [weak self]  data, error in
+        } completion: { [weak self] data, error in
             guard let self = self else { return }
             if stopNetwork == true { return }
             if let error = error {
                 generateStyleModel.upLoadImageUrl = nil
-                self.stateDatauPblished = (TSProgressState.getFailed(error.tsDesc,error.tsCode),nil)
+                self.stateDatauPblished = (TSProgressState.getFailed(error.tsDesc, error.tsCode), nil)
                 complete(nil)
-            }else{
+            } else {
                 if let string = data as? String {
                     generateStyleModel.upLoadImageUrl = string
                     generateStyleModel.upLoadImageUrls = [string]
                     TSImageStoreTool.storeImage(image: upLoadImage, urlString: string)
 
                     complete(createActionInfoModel(generateStyleModel: generateStyleModel))
-                }else{
+                } else {
                     complete(nil)
                 }
             }
         }
     }
-    //上传多张图片
-    func uploadImages(generateStyleModel:TSAIGeneratorModel,complete:@escaping (TSActionInfoModel?)->Void) {
+
+    // 上传多张图片
+    func uploadImages(generateStyleModel: TSAIGeneratorModel, complete: @escaping (TSActionInfoModel?) -> Void) {
         self.generateStyleModel = generateStyleModel
         guard let upLoadImages = generateStyleModel.upLoadImages else { return }
-        var uploadImageUrls:[String] = []
-        let progressRatio:Float = 1.0/Float(upLoadImages.count)//进度分割比例
-        var totalProgress:Float = 0.0//总进度
-        
+        var uploadImageUrls: [String] = []
+        let progressRatio: Float = 1.0 / Float(upLoadImages.count) // 进度分割比例
+        var totalProgress: Float = 0.0 // 总进度
+
         stopNetwork = false
-        stateDatauPblished = (.start,nil)
-        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),nil)
-        
+        stateDatauPblished = (.start, nil)
+        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)), nil)
+
         let group = DispatchGroup()
         for image in upLoadImages {
             group.enter()
-            uploadRequest = TSNetworkShared.uploadImage(upLoadImage: image, maxKb: generateStyleModel.generatorStyle.imageMaxKb,vipFreeNumType: generateStyleModel.generatorStyle.vipFreeNumType) { [weak self]  progress in
+            uploadRequest = TSNetworkShared.uploadImage(upLoadImage: image, maxKb: generateStyleModel.generatorStyle.imageMaxKb, vipFreeNumType: generateStyleModel.generatorStyle.vipFreeNumType) { [weak self] progress in
                 guard let self = self else { return }
-                totalProgress+=progress*progressRatio
-                stateDatauPblished = (.progressString(uploadingPhoto(progress: totalProgress)),nil)
-            } completion: { [weak self]  data, error in
+                totalProgress += progress * progressRatio
+                stateDatauPblished = (.progressString(uploadingPhoto(progress: totalProgress)), nil)
+            } completion: { [weak self] data, error in
                 guard let self = self else { return }
                 if let error = error {
-                    self.stateDatauPblished = (TSProgressState.getFailed(error.tsDesc,error.tsCode),nil)
-                }else{
+                    self.stateDatauPblished = (TSProgressState.getFailed(error.tsDesc, error.tsCode), nil)
+                } else {
                     if let string = data as? String {
                         uploadImageUrls.append(string)
                     }
@@ -291,12 +295,12 @@ extension TSGenerateBasePhotoOperation {
             if uploadImageUrls.count == upLoadImages.count {
                 generateStyleModel.upLoadImageUrl = uploadImageUrls.first
                 generateStyleModel.upLoadImageUrls = uploadImageUrls
-                for i in 0..<uploadImageUrls.count{
+                for i in 0 ..< uploadImageUrls.count {
                     TSImageStoreTool.storeImage(image: upLoadImages[i], urlString: uploadImageUrls[i])
                 }
                 complete(self.createActionInfoModel(generateStyleModel: generateStyleModel))
-            }else{
-                self.stateDatauPblished = (TSProgressState.generalNormalFailed,nil)
+            } else {
+                self.stateDatauPblished = (TSProgressState.generalNormalFailed, nil)
                 complete(nil)
             }
         }
@@ -304,25 +308,23 @@ extension TSGenerateBasePhotoOperation {
 }
 
 extension TSGenerateBasePhotoOperation {
-
-    func getPostContent()->(TSNeURLType,[String:Any])?{
-    
+    func getPostContent() -> (TSNeURLType, [String: Any])? {
         let request = currentActionInfoModel.request
-        
-        var urlType:TSNeURLType = .changeAge
-        var postDict:[String:Any] = [:]
+
+        var urlType: TSNeURLType = .changeAge
+        var postDict: [String: Any] = [:]
         switch request.generatorStyle {
         case .ageOld:
-        postDict = ["targetAge":70]
+            postDict = ["targetAge": 70]
         case .ageChild:
-        postDict = ["targetAge":5]
+            postDict = ["targetAge": 5]
         case .oldPhoto:
-        urlType = .imageRestore
+            urlType = .imageRestore
         case .eyeOpen:
-        urlType = .eyeOpen
+            urlType = .eyeOpen
         case .pretty:
-        urlType = .pretty
-        postDict = ["level":1.0]
+            urlType = .pretty
+            postDict = ["level": 1.0]
         case .photoLive:
             urlType = .createVideo
             postDict["prompt"] = request.prompt
@@ -330,44 +332,58 @@ extension TSGenerateBasePhotoOperation {
             postDict["quality"] = "720p"
         case .photoExpand:
             urlType = .photoExpand
-            guard let generatorModel = generateStyleModel else { return nil}
-            postDict = ["prompt":request.prompt,
-                        "top":generatorModel.expandEdge.top,
-                        "left":generatorModel.expandEdge.left,
-                        "bottom":generatorModel.expandEdge.bottom,
-                        "right":generatorModel.expandEdge.right
-                       ]
-        case .photoQuality,.motherDay,.catTohuman,.ptp,.process:
+            guard let generatorModel = generateStyleModel else { return nil }
+            postDict = ["prompt": request.prompt,
+                        "top": generatorModel.expandEdge.top,
+                        "left": generatorModel.expandEdge.left,
+                        "bottom": generatorModel.expandEdge.bottom,
+                        "right": generatorModel.expandEdge.right,
+            ]
+        case .photoQuality, .motherDay, .catTohuman, .ptp, .process:
             urlType = .imageRewrite
-            postDict = ["prompt":request.prompt,
+            postDict = ["prompt": request.prompt,
                         "model": request.model]
         case .futureBaby:
-            guard request.imageUrls.count > 0 else { return nil}
+            guard request.imageUrls.count > 0 else { return nil }
             urlType = .imageRewrite
-            postDict = ["prompt":request.prompt,
+            postDict = ["prompt": request.prompt,
                         "model": request.model,
-                        "imageUrls":request.imageUrls
-                        ]
+                        "imageUrls": request.imageUrls,
+            ]
             postDict.removeValue(forKey: "imageUrl")
-            
+
         case .videoV2:
-            guard request.imageUrls.count > 0 else { return nil}
+            guard request.imageUrls.count > 0 else { return nil }
             urlType = .videoV2
-            postDict = ["prompt":request.prompt,
-                        "template":request.template,
+            postDict = ["prompt": request.prompt,
+                        "template": request.template,
                         "bgm": true,
-                        "imageUrls":request.imageUrls
-                        ]
+                        "imageUrls": request.imageUrls,
+            ]
             postDict.removeValue(forKey: "imageUrl")
+        case .textToVideo:
+            guard let generatorModel = generateStyleModel,
+                  let param = generatorModel.diyVideoGenerateModel?.asDict else {
+                return nil
+            }
+            urlType = .text2Video
+            postDict = param
+        case .pictureToVideo:
+            guard request.imageUrls.count > 0, let generatorModel = generateStyleModel,
+                  var param = generatorModel.diyVideoGenerateModel?.asDict else {
+                return nil
+            }
+            urlType = .img2video
+            param["imageUrls"] = request.imageUrls
+            postDict = param
         default:
-            break;
+            break
         }
         postDict["device"] = getUserInfoJsonString()
         postDict["imageUrl"] = request.imageUrl
 
-        return (urlType,postDict)
+        return (urlType, postDict)
     }
-    
 }
 
 //    override var actionInfoDict:[String:Any]{