Browse Source

图生图代码用扩展分拆-2

100Years 5 days ago
parent
commit
7e822598a0

BIN
.DS_Store


+ 4 - 0
AIEmoji.xcodeproj/project.pbxproj

@@ -154,6 +154,7 @@
 		A8990E0A2DE1A98E00DD55FE /* TSPTPInputVC+Col.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8990E092DE1A98D00DD55FE /* TSPTPInputVC+Col.swift */; };
 		A8990E0C2DE1AA9100DD55FE /* TSPTPInputVC+TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8990E0B2DE1AA9000DD55FE /* TSPTPInputVC+TextView.swift */; };
 		A8990E0E2DE1AD2000DD55FE /* TSPTPInputVC+BtnView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8990E0D2DE1AD1E00DD55FE /* TSPTPInputVC+BtnView.swift */; };
+		A8990E102DE1C51D00DD55FE /* TSPTPInputVC+Vip.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8990E0F2DE1C51C00DD55FE /* TSPTPInputVC+Vip.swift */; };
 		A899D34A2D827A0E00AB9C1C /* TSChatThinkingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D3492D8279FB00AB9C1C /* TSChatThinkingModel.swift */; };
 		A89EA64B2D59A588000EB181 /* MessageKit in Frameworks */ = {isa = PBXBuildFile; productRef = A89EA64A2D59A588000EB181 /* MessageKit */; };
 		A89EA6542D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */; };
@@ -449,6 +450,7 @@
 		A8990E092DE1A98D00DD55FE /* TSPTPInputVC+Col.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSPTPInputVC+Col.swift"; sourceTree = "<group>"; };
 		A8990E0B2DE1AA9000DD55FE /* TSPTPInputVC+TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSPTPInputVC+TextView.swift"; sourceTree = "<group>"; };
 		A8990E0D2DE1AD1E00DD55FE /* TSPTPInputVC+BtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSPTPInputVC+BtnView.swift"; sourceTree = "<group>"; };
+		A8990E0F2DE1C51C00DD55FE /* TSPTPInputVC+Vip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSPTPInputVC+Vip.swift"; sourceTree = "<group>"; };
 		A899D3492D8279FB00AB9C1C /* TSChatThinkingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatThinkingModel.swift; sourceTree = "<group>"; };
 		A89EA64C2D59A9F4000EB181 /* CustomMessageFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageFlowLayout.swift; sourceTree = "<group>"; };
 		A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLayoutSizeCalculator.swift; sourceTree = "<group>"; };
@@ -1503,6 +1505,7 @@
 				A8990E092DE1A98D00DD55FE /* TSPTPInputVC+Col.swift */,
 				A8990E0B2DE1AA9000DD55FE /* TSPTPInputVC+TextView.swift */,
 				A8990E0D2DE1AD1E00DD55FE /* TSPTPInputVC+BtnView.swift */,
+				A8990E0F2DE1C51C00DD55FE /* TSPTPInputVC+Vip.swift */,
 			);
 			path = TSPTPInputVC;
 			sourceTree = "<group>";
@@ -2366,6 +2369,7 @@
 				A8F4134E2DA75E9E001E715A /* TSAboutDataVC.swift in Sources */,
 				A80E72672D409C7D00C64288 /* Template+More.swift in Sources */,
 				A82D60A92DBB9A6300596190 /* TSDBActionInfoModel.swift in Sources */,
+				A8990E102DE1C51D00DD55FE /* TSPTPInputVC+Vip.swift in Sources */,
 				A82D609E2DBA0FEA00596190 /* TSAppBtnView.swift in Sources */,
 				A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */,
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,

+ 1 - 1
AIEmoji/Business/Data/TSUserDefaultData.swift

@@ -12,7 +12,7 @@ func kHandleDBHistoryOperation(){
         if model.modelType != 1 {
             if model.isResult == false,model.id > 0 {
                 let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: model.uuid)
-                generatePTPOperation.isSaveDB = true
+                generatePTPOperation.isSaveProcessToDB = true
                 generatePTPOperation.getActionInfo(oldModel: model.getModel())
             }
         }

+ 5 - 7
AIEmoji/Business/General/TSAppBtnView/TSAppBtnView.swift

@@ -43,13 +43,11 @@ class TSAppBtnView: TSBaseView {
     
     
     var loading:Bool = false{
-        willSet {
-            if loading != newValue {
-                loadingAnimation(loading: newValue)
-                
-                if loading == false {
-                    self.resetBtnText()
-                }
+        didSet {
+            loadingAnimation(loading: loading)
+            
+            if loading == false {
+                self.resetBtnText()
             }
         }
     }

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiGennerateVC/TSGenmojiGennerateViewModel.swift

@@ -97,7 +97,7 @@ enum TSProgressState  {
     
     var reloadNewData:Bool{
         switch self {
-        case .pending,.success(_),.failed(_,_):
+        case .start,.pending,.success(_),.failed(_,_):
             return true
         default:
             return false

+ 50 - 11
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift

@@ -22,16 +22,27 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
         didSet{
             self.updataActionInfoModelView(model: dataModel)
             if let operation = TSGeneratePTPOperationQueue.shared.findOperation(uuid: dataModel.uuid) as? TSGeneratePTPOperation {
-                DispatchQueue.main.async {
-                    operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
-                        guard let self = self else { return }
-                        DispatchQueue.main.async {
-                            print("actionInfoModel.toJSONString()=\(actionInfoModel.toJSONString())")
-                            self.updataActionInfoModelView(model: actionInfoModel)
-                        }
+//                //处理生成任务
+//                    operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
+//                        guard let self = self else { return }
+//                        DispatchQueue.main.async {
+////                            print("actionInfoModel.toJSONString()=\(actionInfoModel.toJSONString())")
+//                            self.updataActionInfoModelView(model: actionInfoModel)
+//                        }
+//                    }
+
+                //处理生成任务
+                operation.stateDataPblishedChanged = { [weak self] state, actionInfoModel in
+                    guard let self = self else { return }
+                    if operation.uuid != self.dataModel.uuid {
+                        return
                     }
-                    self.operation = operation
+                    handleStateDataPblishedChanged(state: state, actionInfoModel: actionInfoModel)
                 }
+                dePrint("\(self.indexPath.item),刷新进度真handleStateDataPblishedChanged=\(operation.stateDatauPblished)")
+                handleStateDataPblishedChanged(state: operation.stateDatauPblished.0, actionInfoModel: operation.stateDatauPblished.1)
+                
+                self.operation = operation
             }else{
                 self.operation?.currentActionInfoModelChanged = nil
                 self.operation = nil
@@ -83,8 +94,8 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
                 if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
                 if TSGeneratePTPOperationQueue.shared.isAvailability {
                     let generatePTPOperation = TSGeneratePTPOperationQueue.shared.creatOperation(uuid: dataModel.uuid)
-                    generatePTPOperation.isSaveDB = true
-                    generatePTPOperation.creatImage(oldModel: dataModel)
+                    generatePTPOperation.isSaveProcessToDB = true
+                    generatePTPOperation.creatImage(oldModel: dataModel){ success in }
                     generateView.setProgress(progress: 0)
                 }
             }
@@ -122,6 +133,12 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
         }
     }
     
+
+
+}
+
+
+extension TSGenmojiItemCell {
     func updataActionInfoModelView(model:TSActionInfoModel){
         
         if model.modelType == .example {
@@ -132,7 +149,7 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
         switch model.actionStatus {
         case .pending,.running:
             generateView.isHidden = false
-            generateView.setProgress(progress: model.percent)
+            generateView.setProgress(progress: model.percent*kPercentScale)
         case .success:
             generateView.isHidden = true
             
@@ -165,5 +182,27 @@ class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
             generateView.bgImageView.image = nil
         }
     }
+}
 
+extension TSGenmojiItemCell {
+    
+    func handleStateDataPblishedChanged(state:TSProgressState,actionInfoModel:TSActionInfoModel?){
+        switch state {
+            case .failed(let errorStr,let code):
+            generateView.isHidden = false
+            generateView.setFailText(text: errorStr,refresh: false )
+            case .success:
+            if let model = actionInfoModel {
+                updataActionInfoModelView(model: model)
+            }
+            case .progress(let string):
+            generateView.isHidden = false
+//            generateView.setProgress(progress: progress)
+            default:
+            generateView.isHidden = false
+            generateView.setProgress(progress: 0)
+        }
+    }
+    
+    
 }

+ 12 - 15
AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift

@@ -141,15 +141,8 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
     
     //后台生成
     @objc func clickBackstageBtn() {
-        self.operation.isSaveDB = true //后台生成,让数据库保存数据
-        if let model = infoModel {
-            TSRMShared.ptpDBHistory.updateData(model)
-            debugPrint("图生图进入后台,保存数据listModels.first=\(TSRMShared.ptpDBHistory.listModels.first)")
-            NotificationCenter.default.post(name: .kPTPDataChanged, object: nil)
-        }else{
-            debugPrint("进入后台,但是没有新数据")
-        }
-
+        self.operation.backstageGeneration()
+        NotificationCenter.default.post(name: .kPTPDataChanged, object: nil)
         self.dismiss(animated: true, completion: nil)
     }
     
@@ -206,9 +199,11 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
             guard let self = self else { return }
             self.upDateView(state: state, model: model)
         }.store(in: &cancellable)
-        operation.creatImage(oldModel: infoModel)
-        generateInView.setBackgroundGenerateBtnHidden(false)
-        xBtn.isHidden = false
+        operation.creatImage(oldModel: infoModel){ [weak self] success in
+            guard let self = self else { return }
+            generateInView.setBackgroundGenerateBtnHidden(false)
+            xBtn.isHidden = false
+        }
     }
     
     func uploadImageCreatOperation() {
@@ -220,9 +215,11 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
         operation.uploadImage(generateStyleModel: viewModel.generateStyleModel) {[weak self] actionInfoModel in
             guard let self = self else { return }
             if let actionInfoModel = actionInfoModel{
-                operation.creatImage(oldModel: actionInfoModel)
-                generateInView.setBackgroundGenerateBtnHidden(false)
-                xBtn.isHidden = false
+                operation.creatImage(oldModel: actionInfoModel){ [weak self] success in
+                    guard let self = self else { return }
+                    generateInView.setBackgroundGenerateBtnHidden(false)
+                    xBtn.isHidden = false
+                }
             }
         }
     }

+ 15 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC+Col.swift

@@ -85,6 +85,21 @@ extension TSPTPInputVC {
     }
     
     
+    func handleColLogic(){
+        
+        updataCollectionView()
+   
+        // 监听collectionView 的 contentSize
+        collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
+        collectionViewObserver.onContentSizeChange = { [weak self] size in
+            guard let self = self else { return }
+            print("collectionViewObserver 内容大小变化: \(size)")
+            self.collectionComponent.collectionView.snp.updateConstraints { make in
+                make.height.equalTo(size.height)
+            }
+        }
+    }
+    
     
     func updataCollectionView() {
         viewModel.updateRecentData()

+ 7 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC+TextView.swift

@@ -109,6 +109,13 @@ extension TSPTPInputVC {
 }
 
 extension TSPTPInputVC {
+    
+    func handleTextFiledLogic(){
+        // 监听键盘事件
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
+    }
+    
     func updateTextFiledView() {
         if viewModel.selectedPTPStyleModel.input {
             promptTextView.isHidden = false

+ 3 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC+Upload.swift

@@ -55,5 +55,7 @@ extension TSPTPInputVC {
         kPresentModalVC(target: self, modelVC: hintBaseVC, transitionStyle: .crossDissolve)
     }
 
-   
+    func handleUploadLogic(){
+        TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
+    }
 }

+ 131 - 0
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC+Vip.swift

@@ -0,0 +1,131 @@
+//
+//  TSPTPInputVC+Vip.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/5/24.
+//
+
+extension TSPTPInputVC {
+    
+    func creatVipBtn() -> UIButton {
+        let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self] in
+            guard let self = self else { return }
+            TSPurchaseVC.show(target: self) {}
+        }
+        return vipBtn
+    }
+    
+    
+    func creatNavBarView() -> TSBaseNavContentBarView {
+        let navBarView = TSBaseNavContentBarView()
+
+        let titleImageView = UIImageView.createImageView(imageName: "nav_title_pic", contentMode: .scaleToFill)
+        navBarView.barView.addSubview(titleImageView)
+        titleImageView.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.left.equalTo(16)
+        }
+
+        navBarView.barView.addSubview(vipBtn)
+        vipBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-16) // (-60)
+            make.width.height.equalTo(24)
+        }
+
+        return navBarView
+    }
+    
+    
+    
+    func creatSelectStyleView() -> TSPTPSelectStyleView {
+        let selectStyleView = TSPTPSelectStyleView()
+        selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
+        selectStyleView.dataArray = viewModel.ptpStyleModels
+        selectStyleView.clickHandle = { [weak self] indexPath, model in
+            guard let self = self else { return }
+            viewModel.selectedPTPStyleModel = model
+            viewModel.selectedStyleIndex = indexPath.item
+            updateVipView()
+            updateTextFiledView()
+        }
+        return selectStyleView
+    }
+    
+}
+
+extension TSPTPInputVC {
+    
+    func creatAppBtnView() -> TSAppBtnView {
+        let creatBtnView = TSAppBtnView()
+        creatBtnView.setUpButton(style: .generate, vipFreeNumType: .picToPic) { [weak self] in
+            guard let self = self else { return }
+            generateImage()
+        }
+        creatBtnView.setBtnEnabled(isEnabled: false)
+        creatBtnView.isIconVipBlock = { [weak self] in
+            guard let self = self else { return false }
+            var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
+            if showVip == false {
+                showVip = self.viewModel.selectedPTPStyleModel.isVip
+            }
+            return showVip
+        }
+        creatBtnView.isClickVipBlock = { [weak self] in
+            guard let self = self else { return false }
+            var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
+            if viewModel.selectedPTPStyleModel.isVip == true {
+                isVip = true
+            }
+            return isVip
+        }
+        return creatBtnView
+    }
+    
+    
+}
+extension TSPTPInputVC {
+    
+    func handleVipLogic(){
+        // 监听 vip 变化
+        NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
+        updateVipView()
+    }
+    
+    
+    @objc func vipInfoChanged() {
+        kExecuteOnMainThread {
+            self.updateVipView()
+        }
+    }
+
+    func updateVipView() {
+        kExecuteOnMainThread {
+            self.vipBtn.isHidden = PurchaseManager.default.isVip
+            self.creatBtnView.updateVipView()
+        }
+    }
+
+    func getVipText() -> String {
+        return "Generate".localized
+    }
+    
+    func setCreatBtnEnabled() {
+        let isAvailability = TSGeneratePTPOperationQueue.shared.isAvailability
+        if viewModel.isCanGennerate, isAvailability {
+            creatBtnView.setBtnEnabled(isEnabled: true)
+            creatBtnView.loading = false
+            dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
+        } else {
+            dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
+            creatBtnView.setBtnEnabled(isEnabled: false)
+            
+            let loading = !isAvailability
+            if creatBtnView.loading != loading {
+                creatBtnView.loading = loading
+            }
+        }
+
+        updateVipView()
+    }
+}

+ 15 - 136
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift

@@ -25,53 +25,14 @@ class TSPTPInputVC: TSBaseVC {
     var hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
 
     // ###################################### 导航栏 view ######################################
-
-    lazy var vipBtn: UIButton = {
-        let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self] in
-            guard let self = self else { return }
-            TSPurchaseVC.show(target: self) {}
-        }
-        return vipBtn
-    }()
-
-    lazy var navBarView: TSBaseNavContentBarView = {
-        let navBarView = TSBaseNavContentBarView()
-
-        let titleImageView = UIImageView.createImageView(imageName: "nav_title_pic", contentMode: .scaleToFill)
-        navBarView.barView.addSubview(titleImageView)
-        titleImageView.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.left.equalTo(16)
-        }
-
-        navBarView.barView.addSubview(vipBtn)
-        vipBtn.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.trailing.equalTo(-16) // (-60)
-            make.width.height.equalTo(24)
-        }
-
-        return navBarView
-    }()
-
+    lazy var vipBtn: UIButton = creatVipBtn()
+    lazy var navBarView: TSBaseNavContentBarView = creatNavBarView()
 
     lazy var cusStackView: TSCustomStackView = creatStackView()
     lazy var uploadView: TSPTPUploadView = creatUploadView()//上传图片
 
     // ###################################### 选择风格 ######################################
-    lazy var selectStyleView: TSPTPSelectStyleView = {
-        let selectStyleView = TSPTPSelectStyleView()
-        selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
-        selectStyleView.dataArray = viewModel.ptpStyleModels
-        selectStyleView.clickHandle = { [weak self] indexPath, model in
-            guard let self = self else { return }
-            viewModel.selectedPTPStyleModel = model
-            viewModel.selectedStyleIndex = indexPath.item
-            updateVipView()
-            updateTextFiledView()
-        }
-        return selectStyleView
-    }()
+    lazy var selectStyleView: TSPTPSelectStyleView = creatSelectStyleView()
 
     // ###################################### 输入框 ######################################
     lazy var customTextView: TSPlaceholderTextView = creatCustomTextView()
@@ -80,36 +41,12 @@ class TSPTPInputVC: TSBaseVC {
     lazy var promptTextView: UIView = creatPromptTextView()
 
     // ###################################### 集合视图 ######################################
-    private var collectionViewObserver: CollectionViewObserver!
+    var collectionViewObserver: CollectionViewObserver!
     let collectionViewBtootm: CGFloat = 80
     lazy var collectionComponent: TSCollectionViewComponent = creatCollectionComponent()
 
     // ###################################### Button ######################################
-    lazy var creatBtnView: TSAppBtnView = {
-        let creatBtnView = TSAppBtnView()
-        creatBtnView.setUpButton(style: .generate, vipFreeNumType: .picToPic) { [weak self] in
-            guard let self = self else { return }
-            generateImage()
-        }
-        creatBtnView.setBtnEnabled(isEnabled: false)
-        creatBtnView.isIconVipBlock = { [weak self] in
-            guard let self = self else { return false }
-            var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
-            if showVip == false {
-                showVip = self.viewModel.selectedPTPStyleModel.isVip
-            }
-            return showVip
-        }
-        creatBtnView.isClickVipBlock = { [weak self] in
-            guard let self = self else { return false }
-            var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
-            if viewModel.selectedPTPStyleModel.isVip == true {
-                isVip = true
-            }
-            return isVip
-        }
-        return creatBtnView
-    }()
+    lazy var creatBtnView: TSAppBtnView = creatAppBtnView()
 
     override func createView() {
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
@@ -138,26 +75,10 @@ class TSPTPInputVC: TSBaseVC {
     }
 
     override func dealThings() {
-        updataCollectionView()
-        // 监听 vip 变化
-        NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
-        updateVipView()
-
-        TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
-
-        // 监听键盘事件
-        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
-
-        // 监听collectionView 的 contentSize
-        collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
-        collectionViewObserver.onContentSizeChange = { [weak self] size in
-            guard let self = self else { return }
-            print("collectionViewObserver 内容大小变化: \(size)")
-            self.collectionComponent.collectionView.snp.updateConstraints { make in
-                make.height.equalTo(size.height)
-            }
-        }
+        handleColLogic()
+        handleVipLogic()
+        handleUploadLogic()
+        handleTextFiledLogic()
 
         // 监听按钮任务生成中
         NotificationCenter.default.addObserver(forName: .kBaseOperationQueueCountChanged, object: nil, queue: nil) { [weak self] _ in
@@ -171,25 +92,17 @@ class TSPTPInputVC: TSBaseVC {
 
             if let userInfo = notification.userInfo as? [String: Any], let state = userInfo["state"] as? TSProgressState {
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
-//                if state.isResult {//有结果,一定要刷新
-//                    updataCollectionView()
-//                }else if self.isViewVisible == false {
-                ////                    dePrint("TSBaseOperation 视图不可见")
-//                    return
-//                }else
-//                if state.reloadNewData {//主要是给pending用,让他再视图中有个位置占着
-                updataCollectionView()
-//                }
+                if state.reloadNewData {
+                    updataCollectionView()
+                }
             }
         }
 
         // 同时 VC主动刷新UI界面
-        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: nil) { [weak self] _ in
+        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: .main) { [weak self] _ in
             guard let self = self else { return }
-            DispatchQueue.main.async {
-                debugPrint("kPTPDataChanged listModels.first=\(self.viewModel.listModels.first?.toJSONString())")
-                self.updataCollectionView()
-            }
+            debugPrint("kPTPDataChanged listModels.first=\(self.viewModel.listModels.first?.toJSONString())")
+            self.updataCollectionView()
         }
 
         NotificationCenter.default.addObserver(self, selector: #selector(autoSelectImageToImageStyle(notify:)), name: .schemeImageToImageStylePick, object: nil)
@@ -197,24 +110,7 @@ class TSPTPInputVC: TSBaseVC {
 }
 
 
-extension TSPTPInputVC {
-    @objc func vipInfoChanged() {
-        kExecuteOnMainThread {
-            self.updateVipView()
-        }
-    }
-
-    func updateVipView() {
-        kExecuteOnMainThread {
-            self.vipBtn.isHidden = PurchaseManager.default.isVip
-            self.creatBtnView.updateVipView()
-        }
-    }
 
-    func getVipText() -> String {
-        return "Generate".localized
-    }
-}
 
 extension TSPTPInputVC {
     @objc func clickView() {
@@ -246,25 +142,8 @@ extension TSPTPInputVC {
 
         kPresentModalVC(target: self, modelVC: gennerateVC, transitionStyle: .crossDissolve)
     }
-
-    func setCreatBtnEnabled() {
-        let isAvailability = TSGeneratePTPOperationQueue.shared.isAvailability
-        if viewModel.isCanGennerate, isAvailability {
-            creatBtnView.setBtnEnabled(isEnabled: true)
-            creatBtnView.loading = false
-            dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
-        } else {
-            dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
-            creatBtnView.setBtnEnabled(isEnabled: false)
-            creatBtnView.loading = !isAvailability
-        }
-
-        updateVipView()
-    }
 }
 
-
-
 extension TSPTPInputVC {
     @objc func autoSelectImageToImageStyle(notify: Notification) {
         if let objc = notify.userInfo as? [String: String] {

+ 6 - 3
AIEmoji/Common/Purchase/TSPurchaseManager.swift

@@ -23,6 +23,9 @@ public enum PremiumPeriod: String, CaseIterable {
         case .year:
             return 60
         case .none:
+#if DEBUG
+    return 60
+#endif
             return 0
         default:
             return 30
@@ -167,9 +170,9 @@ public class PurchaseManager: NSObject {
     }
 
     @objc public var isVip: Bool {
-//        #if DEBUG
-//            return true
-//        #endif
+        #if DEBUG
+            return true
+        #endif
         guard let expiresDate = expiredDate else {
             return false
         }

+ 3 - 0
AIEmoji/Common/Tool/OperationQueue/TSBaseOperationQueue.swift

@@ -27,6 +27,8 @@ class TSBaseOperationQueue {
         return false
     }
     
+    weak var latestOperation:TSBaseOperation? //最新的任务
+    
     init(maxConcurrentOperationCount: Int = 1) {
         queue.maxConcurrentOperationCount = maxConcurrentOperationCount
         dePrint("TSBaseOperationQueue operationCountObservation")
@@ -65,6 +67,7 @@ class TSBaseOperationQueue {
                 
                 dePrint("TSBaseOperationQueue $operationStatePblished =\(state)")
             }
+            latestOperation = operation
             return operation
         }
     }

+ 39 - 10
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift

@@ -13,13 +13,25 @@ class TSGenerateBaseOperationQueue: TSBaseOperationQueue {
     
     var generateOperationStateChanged:((String)->Void)?
     
-    
-    override func cancelOperations(uuid: String) {
-        super.cancelOperations(uuid: uuid)
+    override func clearOperationsData(uuid: String) {
+        super.clearOperationsData(uuid: uuid)
+        
+        dePrint("TSGenerateBaseOperationQueue stateables 前=\(stateables)")
         stateables.removeValue(forKey: uuid)
+        dePrint("TSGenerateBaseOperationQueue stateables 后=\(stateables)")
+        
     }
+//    override func cancelOperations(uuid: String) {
+//        super.cancelOperations(uuid: uuid)
+//        stateables.removeValue(forKey: uuid)
+//    }
 
     func handleStateDatauPblished(uuid:String,generateOperation: TSGenerateBaseOperation,notificationName:Notification.Name) {
+        
+        if let _ = stateables[uuid] {
+            return
+        }
+        dePrint("handleStateDatauPblished uuid=\(uuid)")
         stateables[uuid] = generateOperation.$stateDatauPblished.sink { [weak self] state in
             guard let self = self else { return }
             DispatchQueue.main.async {
@@ -33,7 +45,7 @@ class TSGenerateBaseOperationQueue: TSBaseOperationQueue {
                         "uuid": uuid,
                         "count":self.queue.maxConcurrentOperationCount,
                         "state":uuidData.0,
-                        "actionInfo":uuidData.1,
+                        "actionInfo":uuidData.1 as Any,
                     ])
             }
         }
@@ -54,6 +66,11 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
     @Published var stateDatauPblished:(TSProgressState,TSActionInfoModel?) = (TSProgressState.none,nil){
         didSet{
             dePrint("TSBaseOperation stateDatauPblished didSet = \(stateDatauPblished)")
+            
+            DispatchQueue.main.async {
+                self.stateDataPblishedChanged?(self.stateDatauPblished.0,self.stateDatauPblished.1)
+            }
+            
             if case .start = stateDatauPblished.0 {
                 start()
             }else if stateDatauPblished.0.isResult {
@@ -68,8 +85,17 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
     var stopNetwork = false
     var generatingProgress = 0
     var action_id:Int = 0
-    var isSaveDB:Bool = false //是否保存到数据库
+    var isSaveProcessToDB:Bool = false //是否保存到数据库
+    {
+        didSet{
+            if isSaveProcessToDB == true {
+                saveDataDB()
+            }
+        }
+    }
+    
     var currentActionInfoModelChanged:((TSActionInfoModel)->Void)?
+    var stateDataPblishedChanged:((TSProgressState,TSActionInfoModel?)->Void)?
     @Published var currentActionInfoModel: TSActionInfoModel = TSActionInfoModel()
     
     func initializeActionInfoModel(oldModel:TSActionInfoModel) {
@@ -80,10 +106,10 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
     
     func replaceSaveInfoModel(model:TSActionInfoModel){ }
     
-    func handleGenerateSuccess(){
-        
-    }
-
+    func handleGenerateSuccess(){}
+    func saveDataDB(){}
+    func backstageGeneration(){}
+    
     func handleFailInfoModel(errorString:String?,code:Int = 0){
         self.currentActionInfoModel.actionStatus = .failed
         self.currentActionInfoModel.status = "failed"
@@ -134,7 +160,7 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
                             UIImageView.downloadImageWithProgress(urlString: genmojiModel.response.resultUrl) { [weak self]  progress in
                                 guard let self = self else { return }
                                 let progressInt = Int(progress*10.0)
-                                let progressString = "Generating".localized + " \(90 + progressInt)%"
+                                let progressString = "Generating".localized + " \(Int(kPercentScale*100) + progressInt)%"
                                 stateDatauPblished = (.progressString(progressString),currentActionInfoModel)
                                 dePrint("生成后图片下载进度 \(progress)")
                             } completion: { image in
@@ -193,6 +219,9 @@ class TSGenerateBaseOperation: TSBaseOperation , @unchecked Sendable{
         queryRequest?.cancel()
     }
 }
+
+let kPercentScale:Float = 0.9 //下载进度的缩减比例
+
  var kRandomBoolLastResult:Bool = true
 func kRandomBool() -> Bool {
     if !kRandomBoolLastResult {

+ 22 - 5
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift

@@ -50,7 +50,7 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
     override func replaceSaveInfoModel(model:TSActionInfoModel){
         model.uuid = uuid
         model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
-        if isSaveDB {
+        if isSaveProcessToDB {
             TSRMShared.ptpDBHistory.updateData(model,id: currentActionInfoModel.id)
         }
         currentActionInfoModel = model
@@ -58,6 +58,20 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         currentActionInfoModelChanged?(currentActionInfoModel)
     }
 
+    override func backstageGeneration(){
+        isSaveProcessToDB = true
+        isShowSuccessView = true
+    }
+    
+    override func saveDataDB() {
+        if currentActionInfoModel.id == 0 {
+            return
+        }
+        debugPrint("saveDataDB ASRMShared.ringDBHistory.listModels.count = \(TSRMShared.ptpDBHistory.listModels.count),currentActionInfoModel.id = \(currentActionInfoModel.id)")
+        TSRMShared.ptpDBHistory.updateData(currentActionInfoModel,id: currentActionInfoModel.id)
+        debugPrint("saveDataDB ASRMShared.ringDBHistory.listModels.count = \(TSRMShared.ptpDBHistory.listModels.count)")
+    }
+    
     override func handleGenerateSuccess() {
         kPurchaseDefault.useOnceForFree(type: .picToPic)
         
@@ -161,14 +175,14 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         }
     }
     
-    func creatImage(oldModel:TSActionInfoModel) {
+    func creatImage(oldModel:TSActionInfoModel,complete:@escaping (Bool)->Void) {
         
         initializeActionInfoModel(oldModel: oldModel)
         if oldModel.upImageURLExpired { return  }
 
         generatingProgress = 0
         stopNetwork = false
-        stateDatauPblished = (.start,nil)
+
         
         
         currentActionInfoModel.status = "running"
@@ -176,7 +190,7 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
         currentActionInfoModel.percent = 0
         replaceSaveInfoModel(model: currentActionInfoModel)
         
-        stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
+//        stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
  
         
         let request = currentActionInfoModel.request
@@ -203,21 +217,24 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
             
             if let error = error {
                 handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                complete(false)
             }else{
                 if let dataDict = kNetWorkCodeSuccess(data: data),
                    let actionId = dataDict["actionId"] as? Int{
                     if stopNetwork == false {
+                        complete(true)
                         self.stateDatauPblished = (.pending,nil) //通知首页进行更新
                         self.getActionInfo(action_id:actionId)
                     }
                 }else{
                     handleFailInfoModel(errorString: "",code: 0)
+                    complete(false)
                 }
             }
         }
     }
     override func generating(progress: Float) -> String {
-        let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
+        let progress = Float(progress)*(kPercentScale) // 预留 10% 进度给图片下载
         //Generating 0%-100%
         var progressInt = Int(progress*100)