Browse Source

新增scheme解析,新增多语言,新增ext,调整风格本地模型,新增styleid

kailen 3 weeks ago
parent
commit
c2ffee6794

BIN
.DS_Store


+ 20 - 0
AIEmoji.xcodeproj/project.pbxproj

@@ -7,6 +7,9 @@
 	objects = {
 	objects = {
 
 
 /* Begin PBXBuildFile section */
 /* Begin PBXBuildFile section */
+		605E20552DCC90CE0069F4B6 /* SchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 605E20542DCC90CE0069F4B6 /* SchemeHandler.swift */; };
+		605E20592DCCAF3C0069F4B6 /* SchemeHandler+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 605E20582DCCAF3C0069F4B6 /* SchemeHandler+Ext.swift */; };
+		605E205B2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 605E205A2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift */; };
 		A80327B02D813A0200AF7878 /* TSTTPSelectStyleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */; };
 		A80327B02D813A0200AF7878 /* TSTTPSelectStyleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */; };
 		A80327B32D813D4900AF7878 /* TSTTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B22D813D4800AF7878 /* TSTTPInputVC.swift */; };
 		A80327B32D813D4900AF7878 /* TSTTPInputVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B22D813D4800AF7878 /* TSTTPInputVC.swift */; };
 		A80327B62D813D8700AF7878 /* TSTTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B52D813D8100AF7878 /* TSTTPInputVM.swift */; };
 		A80327B62D813D8700AF7878 /* TSTTPInputVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80327B52D813D8100AF7878 /* TSTTPInputVM.swift */; };
@@ -254,6 +257,9 @@
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
+		605E20542DCC90CE0069F4B6 /* SchemeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchemeHandler.swift; sourceTree = "<group>"; };
+		605E20582DCCAF3C0069F4B6 /* SchemeHandler+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SchemeHandler+Ext.swift"; sourceTree = "<group>"; };
+		605E205A2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSCustomAlertController+Ext.swift"; sourceTree = "<group>"; };
 		6E77A292B548CD79E381757E /* Pods-AIEmoji.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIEmoji.release.xcconfig"; path = "Target Support Files/Pods-AIEmoji/Pods-AIEmoji.release.xcconfig"; sourceTree = "<group>"; };
 		6E77A292B548CD79E381757E /* Pods-AIEmoji.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIEmoji.release.xcconfig"; path = "Target Support Files/Pods-AIEmoji/Pods-AIEmoji.release.xcconfig"; sourceTree = "<group>"; };
 		86FB4D6AEFDDA7A2017F307C /* Pods_AIEmoji.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIEmoji.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		86FB4D6AEFDDA7A2017F307C /* Pods_AIEmoji.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIEmoji.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPSelectStyleCell.swift; sourceTree = "<group>"; };
 		A80327AF2D8139FC00AF7878 /* TSTTPSelectStyleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPSelectStyleCell.swift; sourceTree = "<group>"; };
@@ -555,6 +561,15 @@
 			path = Pods;
 			path = Pods;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		605E20532DCC90BE0069F4B6 /* SchemeHandler */ = {
+			isa = PBXGroup;
+			children = (
+				605E20542DCC90CE0069F4B6 /* SchemeHandler.swift */,
+				605E20582DCCAF3C0069F4B6 /* SchemeHandler+Ext.swift */,
+			);
+			path = SchemeHandler;
+			sourceTree = "<group>";
+		};
 		97C7E956DF0731529C52523E /* Frameworks */ = {
 		97C7E956DF0731529C52523E /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1193,6 +1208,7 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				A83404C72D9BEC0700C140E4 /* UIFont+TSEx.swift */,
 				A83404C72D9BEC0700C140E4 /* UIFont+TSEx.swift */,
+				605E205A2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift */,
 			);
 			);
 			path = Ex;
 			path = Ex;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1693,6 +1709,7 @@
 		A8F774D82D38EA8C00AA6E93 /* Common */ = {
 		A8F774D82D38EA8C00AA6E93 /* Common */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				605E20532DCC90BE0069F4B6 /* SchemeHandler */,
 				A83404C62D9BEC0300C140E4 /* Ex */,
 				A83404C62D9BEC0300C140E4 /* Ex */,
 				A89EA6AA2D5B3EE8000EB181 /* TSRealmManager */,
 				A89EA6AA2D5B3EE8000EB181 /* TSRealmManager */,
 				A80E73E32D533EB000C64288 /* Purchase */,
 				A80E73E32D533EB000C64288 /* Purchase */,
@@ -2326,6 +2343,7 @@
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
+				605E205B2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift in Sources */,
 				A804B98F2DC0F0F700C494C7 /* TSTTPRatioView.swift in Sources */,
 				A804B98F2DC0F0F700C494C7 /* TSTTPRatioView.swift in Sources */,
 				A83404D52D9D28D700C140E4 /* TSAIPhotoBrowseVC.swift in Sources */,
 				A83404D52D9D28D700C140E4 /* TSAIPhotoBrowseVC.swift in Sources */,
 				A89EA66C2D59AA31000EB181 /* TSMessageContentCell.swift in Sources */,
 				A89EA66C2D59AA31000EB181 /* TSMessageContentCell.swift in Sources */,
@@ -2337,9 +2355,11 @@
 				A8BA76472DA4CC70000B6707 /* TSPTPSelectStyleView.swift in Sources */,
 				A8BA76472DA4CC70000B6707 /* TSPTPSelectStyleView.swift in Sources */,
 				A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */,
 				A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */,
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
+				605E20552DCC90CE0069F4B6 /* SchemeHandler.swift in Sources */,
 				A89EA6BC2D5DFB12000EB181 /* TSViewController.swift in Sources */,
 				A89EA6BC2D5DFB12000EB181 /* TSViewController.swift in Sources */,
 				A85E479D2D6809DC0018D62D /* TSBigIconBrowseCell.swift in Sources */,
 				A85E479D2D6809DC0018D62D /* TSBigIconBrowseCell.swift in Sources */,
 				A89EA6832D59F4F9000EB181 /* TSChatViewController+ChatDelegate.swift in Sources */,
 				A89EA6832D59F4F9000EB181 /* TSChatViewController+ChatDelegate.swift in Sources */,
+				605E20592DCCAF3C0069F4B6 /* SchemeHandler+Ext.swift in Sources */,
 				A89EA6A32D5B26E3000EB181 /* TSDBAIChatList.swift in Sources */,
 				A89EA6A32D5B26E3000EB181 /* TSDBAIChatList.swift in Sources */,
 				A8F7753F2D39340E00AA6E93 /* TSSetingVC.swift in Sources */,
 				A8F7753F2D39340E00AA6E93 /* TSSetingVC.swift in Sources */,
 				A8F7762B2D3A70B200AA6E93 /* PaddedLabel.swift in Sources */,
 				A8F7762B2D3A70B200AA6E93 /* PaddedLabel.swift in Sources */,

+ 25 - 30
AIEmoji/AppDelegate.swift

@@ -9,10 +9,9 @@ import UIKit
 var kAppNewVerison = ""
 var kAppNewVerison = ""
 @main
 @main
 class AppDelegate: UIResponder, UIApplicationDelegate {
 class AppDelegate: UIResponder, UIApplicationDelegate {
-
     var window: UIWindow?
     var window: UIWindow?
     var backgroundTaskIdentifier: UIBackgroundTaskIdentifier = .invalid
     var backgroundTaskIdentifier: UIBackgroundTaskIdentifier = .invalid
-    
+
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
         window = UIWindow(frame: UIScreen.main.bounds)
         window = UIWindow(frame: UIScreen.main.bounds)
         window?.backgroundColor = UIColor.black
         window?.backgroundColor = UIColor.black
@@ -24,21 +23,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
 
     func goToLoadVC() {
     func goToLoadVC() {
         let launchVC = TSLaunchVC()
         let launchVC = TSLaunchVC()
-        launchVC.dismissHandler = { [weak self]  in
+        launchVC.dismissHandler = { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             JudgmentSkipPage()
             JudgmentSkipPage()
         }
         }
         window?.rootViewController = launchVC
         window?.rootViewController = launchVC
     }
     }
 
 
-    func goToTab(){
+    func goToTab() {
         window?.rootViewController = TSTabBarController()
         window?.rootViewController = TSTabBarController()
     }
     }
-    
 
 
     func JudgmentSkipPage() {
     func JudgmentSkipPage() {
         if AppDelegate.isFirstInstallApp() {
         if AppDelegate.isFirstInstallApp() {
-            let bootPageVC  = TSBootPageVC { [weak self]  in
+            let bootPageVC = TSBootPageVC { [weak self] in
                 guard let self = self else { return }
                 guard let self = self else { return }
                 UserDefaults.standard.set("1", forKey: "isFirstInstallApp")
                 UserDefaults.standard.set("1", forKey: "isFirstInstallApp")
                 UserDefaults.standard.synchronize()
                 UserDefaults.standard.synchronize()
@@ -46,65 +44,63 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
             }
             }
             let navi = TSBaseNavigationC(rootViewController: bootPageVC)
             let navi = TSBaseNavigationC(rootViewController: bootPageVC)
             window?.rootViewController = navi
             window?.rootViewController = navi
-        }else{
+        } else {
             goToTab()
             goToTab()
         }
         }
     }
     }
-    
 
 
     func initPlatform() {
     func initPlatform() {
         TSCrashReporterTool.shared.setup()
         TSCrashReporterTool.shared.setup()
         TSCrashReporterTool.shared.printCrashReports()
         TSCrashReporterTool.shared.printCrashReports()
         TSColorConfigShared.naviMianTextColor = .white
         TSColorConfigShared.naviMianTextColor = .white
         checkAppConfig()
         checkAppConfig()
-        
+
         kHandleDBHistoryOperation()
         kHandleDBHistoryOperation()
     }
     }
-
 }
 }
 
 
 extension AppDelegate {
 extension AppDelegate {
-
     func applicationWillTerminate(_ application: UIApplication) {
     func applicationWillTerminate(_ application: UIApplication) {
         // 当应用即将被终止时,这里也可以添加数据保存逻辑,但系统留给的时间很有限
         // 当应用即将被终止时,这里也可以添加数据保存逻辑,但系统留给的时间很有限
         NotificationCenter.default.post(name: .kApplicationWillTerminate, object: nil)
         NotificationCenter.default.post(name: .kApplicationWillTerminate, object: nil)
     }
     }
-    
+
     func applicationDidEnterBackground(_ application: UIApplication) {
     func applicationDidEnterBackground(_ application: UIApplication) {
         beginBackgroundTask()
         beginBackgroundTask()
 //        ///添加测试数据
 //        ///添加测试数据
 //        let userDefaults = UserDefaults.standard
 //        let userDefaults = UserDefaults.standard
 //        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
 //        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
 //        userDefaults.set(String(Int(lastGreetingDateString!)!+1), forKey: "kEveryDayPopPurchase")//测试用的
 //        userDefaults.set(String(Int(lastGreetingDateString!)!+1), forKey: "kEveryDayPopPurchase")//测试用的
-
     }
     }
-    
+
     func beginBackgroundTask() {
     func beginBackgroundTask() {
         backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask { [weak self] in
         backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask { [weak self] in
             self?.endBackgroundTask()
             self?.endBackgroundTask()
         }
         }
     }
     }
-    
+
     func endBackgroundTask() {
     func endBackgroundTask() {
         if backgroundTaskIdentifier != .invalid {
         if backgroundTaskIdentifier != .invalid {
             UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
             UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
             backgroundTaskIdentifier = .invalid
             backgroundTaskIdentifier = .invalid
         }
         }
     }
     }
-    
+
     func applicationWillEnterForeground(_ application: UIApplication) {
     func applicationWillEnterForeground(_ application: UIApplication) {
 //        handleShowEveryDayPopPurchase()
 //        handleShowEveryDayPopPurchase()
         checkAppConfig()
         checkAppConfig()
     }
     }
-}
 
 
+    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
+        return SchemeHandler.shared.handle(url: url)
+    }
+}
 
 
 extension AppDelegate {
 extension AppDelegate {
-    
-    static func isFirstInstallApp() -> Bool{
+    static func isFirstInstallApp() -> Bool {
         return UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil
         return UserDefaults.standard.string(forKey: "isFirstInstallApp") == nil
     }
     }
-    
+
 //    func handleShowEveryDayPopPurchase() {
 //    func handleShowEveryDayPopPurchase() {
 //        AppDelegate.showEveryDayPopPurchase { vc in
 //        AppDelegate.showEveryDayPopPurchase { vc in
 //            if let vc = vc ,let rootvc = self.window?.rootViewController {
 //            if let vc = vc ,let rootvc = self.window?.rootViewController {
@@ -114,27 +110,27 @@ extension AppDelegate {
 //        }
 //        }
 //    }
 //    }
 //    static func showEveryDayPopPurchase(showVCHandle:@escaping (UIViewController?)->Void) {
 //    static func showEveryDayPopPurchase(showVCHandle:@escaping (UIViewController?)->Void) {
-//        
+//
 //        if Self.isFirstInstallApp() || kPurchaseDefault.isVip {
 //        if Self.isFirstInstallApp() || kPurchaseDefault.isVip {
 //            //启动页->引导图->会员购买
 //            //启动页->引导图->会员购买
 //            showVCHandle(nil)
 //            showVCHandle(nil)
 //            return
 //            return
 //        }
 //        }
-//        
+//
 //        //启动页->会员购买
 //        //启动页->会员购买
 //        // 1. 获取当前日期
 //        // 1. 获取当前日期
 //        let currentDate = Date()
 //        let currentDate = Date()
 //        let dateFormatter = DateFormatter()
 //        let dateFormatter = DateFormatter()
 //        dateFormatter.dateFormat = "yyyyMMdd"
 //        dateFormatter.dateFormat = "yyyyMMdd"
 //        let currentDateString = dateFormatter.string(from: currentDate)
 //        let currentDateString = dateFormatter.string(from: currentDate)
-//        
+//
 //        // 2. 获取上次弹窗的日期
 //        // 2. 获取上次弹窗的日期
 //        let userDefaults = UserDefaults.standard
 //        let userDefaults = UserDefaults.standard
 //        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
 //        let lastGreetingDateString = userDefaults.string(forKey: "kEveryDayPopPurchase")
-//        
+//
 //        // 3. 检查是否需要显示弹窗 "20250319"
 //        // 3. 检查是否需要显示弹窗 "20250319"
 //        if lastGreetingDateString != currentDateString {
 //        if lastGreetingDateString != currentDateString {
-//            
+//
 //            // 4. 弹窗付费引导
 //            // 4. 弹窗付费引导
 //            let vc = TSPurchaseVC()
 //            let vc = TSPurchaseVC()
 //            vc.closePageBlock = {
 //            vc.closePageBlock = {
@@ -155,15 +151,14 @@ extension AppDelegate {
         let currentDateString = dateFormatter.string(from: currentDate)
         let currentDateString = dateFormatter.string(from: currentDate)
         UserDefaults.standard.set(currentDateString, forKey: "kEveryDayPopPurchase")
         UserDefaults.standard.set(currentDateString, forKey: "kEveryDayPopPurchase")
     }
     }
-    
-    func checkAppConfig(){
-        _ = TSNetworkShared.get(urlType: .config) { data,error in
-            
+
+    func checkAppConfig() {
+        _ = TSNetworkShared.get(urlType: .config) { data, _ in
+
             if let result = kNetWorkResultSuccess(data: data) {
             if let result = kNetWorkResultSuccess(data: data) {
                 kAppNewVerison = result.safeString(forKey: "version")
                 kAppNewVerison = result.safeString(forKey: "version")
                 NotificationCenter.default.post(name: .kRefreshSettingView, object: nil)
                 NotificationCenter.default.post(name: .kRefreshSettingView, object: nil)
             }
             }
         }
         }
     }
     }
-    
 }
 }

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseCell.swift

@@ -8,7 +8,7 @@
 class TSAIListHistoryBaseCell: TSBaseCollectionCell,TSSimpleConfigurableView {
 class TSAIListHistoryBaseCell: TSBaseCollectionCell,TSSimpleConfigurableView {
     
     
     weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
     weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
-    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
+    var indexPath: IndexPath? = IndexPath(item: 0, section: 0)
     var data: Any? {
     var data: Any? {
         didSet {
         didSet {
 //            debugPrint("TSAIListHistoryBaseCell data didSet")
 //            debugPrint("TSAIListHistoryBaseCell data didSet")

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift

@@ -9,7 +9,7 @@
 class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
 class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
     
     
     weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
     weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
-    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
+    var indexPath: IndexPath? = IndexPath(item: 0, section: 0)
     var data: Any? {
     var data: Any? {
         didSet {
         didSet {
             if let dataModel = data as? TSActionInfoModel{
             if let dataModel = data as? TSActionInfoModel{

+ 164 - 169
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift

@@ -7,90 +7,87 @@
 
 
 import PhotosUI
 import PhotosUI
 class TSPTPInputVC: TSBaseVC {
 class TSPTPInputVC: TSBaseVC {
-
     lazy var viewModel: TSPTPInputVM = {
     lazy var viewModel: TSPTPInputVM = {
         let viewModel = TSPTPInputVM()
         let viewModel = TSPTPInputVM()
-        viewModel.isCanGennerateBlock = { [weak self] isCan in
+        viewModel.isCanGennerateBlock = { [weak self] _ in
             guard let self = self else { return }
             guard let self = self else { return }
             setCreatBtnEnabled()
             setCreatBtnEnabled()
         }
         }
         return viewModel
         return viewModel
     }()
     }()
-    
+
     lazy var photoPickerManager: TSPhotoPickerManager = {
     lazy var photoPickerManager: TSPhotoPickerManager = {
         let photoPickerManager = TSPhotoPickerManager(viewController: self)
         let photoPickerManager = TSPhotoPickerManager(viewController: self)
         return photoPickerManager
         return photoPickerManager
     }()
     }()
-    
+
     private var keyboardHeight: CGFloat = 0
     private var keyboardHeight: CGFloat = 0
     var hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
     var hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
-    
-    //###################################### 导航栏 view ######################################
+
+    // ###################################### 导航栏 view ######################################
 
 
     lazy var vipBtn: UIButton = {
     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
-   }()
-    
+        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 = {
     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
-   }()
-    
-    //###################################### cusStackView ######################################
+        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
+    }()
+
+    // ###################################### cusStackView ######################################
     lazy var cusStackView: TSCustomStackView = {
     lazy var cusStackView: TSCustomStackView = {
-        let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
+        let cusStackView = TSCustomStackView(axis: .vertical, spacing: 0)
         cusStackView.scrollView.isScrollEnabled = true
         cusStackView.scrollView.isScrollEnabled = true
         return cusStackView
         return cusStackView
     }()
     }()
 
 
-    //###################################### 上传图片 ######################################
+    // ###################################### 上传图片 ######################################
     lazy var uploadView: TSPTPUploadView = {
     lazy var uploadView: TSPTPUploadView = {
         let uploadView = TSPTPUploadView()
         let uploadView = TSPTPUploadView()
         uploadView.clickHandel = { [weak self] index in
         uploadView.clickHandel = { [weak self] index in
             guard let self = self else { return }
             guard let self = self else { return }
-            
-            if index == 0 {//删除
+
+            if index == 0 { // 删除
                 viewModel.upLoadImage = nil
                 viewModel.upLoadImage = nil
                 uploadView.upLoadImage = nil
                 uploadView.upLoadImage = nil
-            }else{//添加
-                if TSAIListHintBaseVC.isShowUploadImageHint{
+            } else { // 添加
+                if TSAIListHintBaseVC.isShowUploadImageHint {
                     TSAIListHintBaseVC.isShowUploadImageHint = false
                     TSAIListHintBaseVC.isShowUploadImageHint = false
                     presentModalHintVC()
                     presentModalHintVC()
-                }else {
+                } else {
                     pickSinglePhoto()
                     pickSinglePhoto()
                 }
                 }
             }
             }
         }
         }
         return uploadView
         return uploadView
     }()
     }()
-    
-    
-    func pickSinglePhoto()  {
-        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+
+    func pickSinglePhoto() {
+        photoPickerManager.pickCustomSinglePhoto { [weak self] image, errorString in
             guard let self = self else { return }
             guard let self = self else { return }
             if let errorString = errorString {
             if let errorString = errorString {
                 TSToastShared.showToast(text: errorString)
                 TSToastShared.showToast(text: errorString)
-            }else{
+            } else {
                 viewModel.upLoadImage = image
                 viewModel.upLoadImage = image
                 uploadView.upLoadImage = image
                 uploadView.upLoadImage = image
             }
             }
@@ -99,13 +96,13 @@ class TSPTPInputVC: TSBaseVC {
             }
             }
         }
         }
     }
     }
-    
-    //###################################### 选择风格 ######################################
+
+    // ###################################### 选择风格 ######################################
     lazy var selectStyleView: TSPTPSelectStyleView = {
     lazy var selectStyleView: TSPTPSelectStyleView = {
         let selectStyleView = TSPTPSelectStyleView()
         let selectStyleView = TSPTPSelectStyleView()
         selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
         selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
         selectStyleView.dataArray = viewModel.ptpStyleModels
         selectStyleView.dataArray = viewModel.ptpStyleModels
-        selectStyleView.clickHandle = { [weak self] indexPath ,model in
+        selectStyleView.clickHandle = { [weak self] indexPath, model in
             guard let self = self else { return }
             guard let self = self else { return }
             viewModel.selectedPTPStyleModel = model
             viewModel.selectedPTPStyleModel = model
             viewModel.selectedStyleIndex = indexPath.item
             viewModel.selectedStyleIndex = indexPath.item
@@ -114,9 +111,8 @@ class TSPTPInputVC: TSBaseVC {
         }
         }
         return selectStyleView
         return selectStyleView
     }()
     }()
-    
-    
-    //###################################### 输入框 ######################################
+
+    // ###################################### 输入框 ######################################
     lazy var customTextView: TSPlaceholderTextView = {
     lazy var customTextView: TSPlaceholderTextView = {
         let customTextView = TSPlaceholderTextView(
         let customTextView = TSPlaceholderTextView(
             placeholder: "Describe how you want to transform".localized,
             placeholder: "Describe how you want to transform".localized,
@@ -129,13 +125,12 @@ class TSPTPInputVC: TSBaseVC {
         customTextView.returnKeyType = .done
         customTextView.returnKeyType = .done
         return customTextView
         return customTextView
     }()
     }()
-    
+
     lazy var clearBtn: TSUIExpandedTouchButton = {
     lazy var clearBtn: TSUIExpandedTouchButton = {
         let clearBtn = TSUIExpandedTouchButton()
         let clearBtn = TSUIExpandedTouchButton()
         clearBtn.setUpButton(
         clearBtn.setUpButton(
             image: UIImage(named: "clear_text")
             image: UIImage(named: "clear_text")
-        )
-        { [weak self]  in
+        ) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             customTextView.text = ""
             customTextView.text = ""
             textViewDidChange(customTextView)
             textViewDidChange(customTextView)
@@ -143,9 +138,9 @@ class TSPTPInputVC: TSBaseVC {
         clearBtn.isHidden = true
         clearBtn.isHidden = true
         return clearBtn
         return clearBtn
     }()
     }()
-    
-    var promptTextViewH:CGFloat = 96.0
-    lazy var promptTextView:UIView =  {
+
+    var promptTextViewH: CGFloat = 96.0
+    lazy var promptTextView: UIView = {
         let promptTextView = UIView()
         let promptTextView = UIView()
         promptTextView.isHidden = true
         promptTextView.isHidden = true
         promptTextView.clipsToBounds = true
         promptTextView.clipsToBounds = true
@@ -156,10 +151,10 @@ class TSPTPInputVC: TSBaseVC {
         bgView.snp.makeConstraints { make in
         bgView.snp.makeConstraints { make in
             make.edges.equalTo(UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16))
             make.edges.equalTo(UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16))
         }
         }
-        
+
         bgView.addSubview(customTextView)
         bgView.addSubview(customTextView)
         bgView.addSubview(clearBtn)
         bgView.addSubview(clearBtn)
-        
+
         customTextView.snp.makeConstraints { make in
         customTextView.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
             make.centerY.equalToSuperview()
             make.leading.equalTo(12.0)
             make.leading.equalTo(12.0)
@@ -167,50 +162,51 @@ class TSPTPInputVC: TSBaseVC {
             make.bottom.equalTo(-12.0)
             make.bottom.equalTo(-12.0)
             make.trailing.equalTo(-20)
             make.trailing.equalTo(-20)
         }
         }
-        
+
         clearBtn.snp.makeConstraints { make in
         clearBtn.snp.makeConstraints { make in
             make.width.height.equalTo(16.0)
             make.width.height.equalTo(16.0)
             make.trailing.equalTo(-12)
             make.trailing.equalTo(-12)
             make.bottom.equalTo(-12.0)
             make.bottom.equalTo(-12.0)
         }
         }
-        
+
         return promptTextView
         return promptTextView
     }()
     }()
-    //###################################### 集合视图 ######################################
+
+    // ###################################### 集合视图 ######################################
     private var collectionViewObserver: CollectionViewObserver!
     private var collectionViewObserver: CollectionViewObserver!
-    let collectionViewBtootm:CGFloat = 80
+    let collectionViewBtootm: CGFloat = 80
     lazy var collectionComponent: TSCollectionViewComponent = {
     lazy var collectionComponent: TSCollectionViewComponent = {
         let layout = UICollectionViewFlowLayout()
         let layout = UICollectionViewFlowLayout()
         let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [:])
         let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [:])
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: collectionViewBtootm, right: 0)
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: collectionViewBtootm, right: 0)
         cp.collectionView.isScrollEnabled = false
         cp.collectionView.isScrollEnabled = false
- 
+
         // 禁用自动 contentInset 调整
         // 禁用自动 contentInset 调整
-          if #available(iOS 11.0, *) {
-              cp.collectionView.contentInsetAdjustmentBehavior = .never
-          } else {
-              automaticallyAdjustsScrollViewInsets = false
-          }
+        if #available(iOS 11.0, *) {
+            cp.collectionView.contentInsetAdjustmentBehavior = .never
+        } else {
+            automaticallyAdjustsScrollViewInsets = false
+        }
 
 
-        cp.sectionActionHandler = { [weak self] cellCp, indexPath in
+        cp.sectionActionHandler = { [weak self] cellCp, _ in
             guard let self = self else { return }
             guard let self = self else { return }
             if let cmd = cellCp as? String {
             if let cmd = cellCp as? String {
                 if cmd == "delete" {
                 if cmd == "delete" {
-                    showCustomAlert(message: "Are you sure to delete".localized, deleteHandler:  {
+                    showCustomAlert(message: "Are you sure to delete".localized, deleteHandler: {
                         self.viewModel.removeAllHistoryList()
                         self.viewModel.removeAllHistoryList()
                         self.updataCollectionView()
                         self.updataCollectionView()
                     })
                     })
-                }else if cmd == "more" {
+                } else if cmd == "more" {
                     let historyVC = TSPTPHistoryVC()
                     let historyVC = TSPTPHistoryVC()
                     kPushVC(target: self, modelVC: historyVC)
                     kPushVC(target: self, modelVC: historyVC)
                 }
                 }
             }
             }
         }
         }
-        
-        cp.itemActionHandler = { [weak self] (object, indexPath) in
+
+        cp.itemActionHandler = { [weak self] object, indexPath in
             guard let self = self else { return }
             guard let self = self else { return }
-            //删除过期的任务
-            if let cmd = object as? String, cmd == "delete_task_expired"  {
+            // 删除过期的任务
+            if let cmd = object as? String, cmd == "delete_task_expired" {
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
                 if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
                    let currentActionInfoModel = sections.items.safeObj(At: indexPath.item) {
                    let currentActionInfoModel = sections.items.safeObj(At: indexPath.item) {
                     TSRMShared.ptpDBHistory.deleteListModel(id: currentActionInfoModel.dataModel.id)
                     TSRMShared.ptpDBHistory.deleteListModel(id: currentActionInfoModel.dataModel.id)
@@ -218,48 +214,46 @@ class TSPTPInputVC: TSBaseVC {
                 }
                 }
             }
             }
         }
         }
-        
-        cp.itemDidSelectedHandler = { [weak self] (object, indexPath) in
+
+        cp.itemDidSelectedHandler = { [weak self] _, indexPath in
             guard let self = self else { return }
             guard let self = self else { return }
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
-               let dataModel = sections.items.safeObj(At: indexPath.item)?.dataModel
-            {
-
-                var dataModelArray:[TSActionInfoModel] = []
+               let dataModel = sections.items.safeObj(At: indexPath.item)?.dataModel {
+                var dataModelArray: [TSActionInfoModel] = []
                 for itemModel in sections.items {
                 for itemModel in sections.items {
-                    if itemModel.dataModel.status == "success" || itemModel.dataModel.modelType == .example{
+                    if itemModel.dataModel.status == "success" || itemModel.dataModel.modelType == .example {
                         dataModelArray.append(itemModel.dataModel)
                         dataModelArray.append(itemModel.dataModel)
                     }
                     }
                 }
                 }
-  
+
                 let browseVC = TSAIPhotoBrowseVC()
                 let browseVC = TSAIPhotoBrowseVC()
                 browseVC.dataModelArray = dataModelArray
                 browseVC.dataModelArray = dataModelArray
                 browseVC.currentIndex = dataModelArray.firstIndex(of: dataModel) ?? 0
                 browseVC.currentIndex = dataModelArray.firstIndex(of: dataModel) ?? 0
-                kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
+                kPresentModalVC(target: self, modelVC: browseVC, transitionStyle: .crossDissolve)
             }
             }
         }
         }
         cp.collectionView.keyboardDismissMode = .interactive
         cp.collectionView.keyboardDismissMode = .interactive
         return cp
         return cp
     }()
     }()
-    
-    //###################################### Button ######################################
-    lazy var creatBtnView:TSAppBtnView  = {
+
+    // ###################################### Button ######################################
+    lazy var creatBtnView: TSAppBtnView = {
         let creatBtnView = TSAppBtnView()
         let creatBtnView = TSAppBtnView()
         creatBtnView.setUpButton(style: .generate, vipFreeNumType: .picToPic) { [weak self] in
         creatBtnView.setUpButton(style: .generate, vipFreeNumType: .picToPic) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             generateImage()
             generateImage()
         }
         }
         creatBtnView.setBtnEnabled(isEnabled: false)
         creatBtnView.setBtnEnabled(isEnabled: false)
-        creatBtnView.isIconVipBlock = { [weak self]  in
-            guard let self = self else { return false}
+        creatBtnView.isIconVipBlock = { [weak self] in
+            guard let self = self else { return false }
             var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
             var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
             if showVip == false {
             if showVip == false {
                 showVip = self.viewModel.selectedPTPStyleModel.isVip
                 showVip = self.viewModel.selectedPTPStyleModel.isVip
             }
             }
             return showVip
             return showVip
         }
         }
-        creatBtnView.isClickVipBlock = { [weak self]  in
-            guard let self = self else { return false}
+        creatBtnView.isClickVipBlock = { [weak self] in
+            guard let self = self else { return false }
             var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
             var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
             if viewModel.selectedPTPStyleModel.isVip == true {
             if viewModel.selectedPTPStyleModel.isVip == true {
                 isVip = true
                 isVip = true
@@ -268,19 +262,17 @@ class TSPTPInputVC: TSBaseVC {
         }
         }
         return creatBtnView
         return creatBtnView
     }()
     }()
-    
-    
+
     override func createView() {
     override func createView() {
-        
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
         tapGesture.cancelsTouchesInView = false
         tapGesture.cancelsTouchesInView = false
         view.addGestureRecognizer(tapGesture)
         view.addGestureRecognizer(tapGesture)
-        
+
         navBarContentView.addSubview(navBarView)
         navBarContentView.addSubview(navBarView)
         navBarView.snp.makeConstraints { make in
         navBarView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
             make.edges.equalToSuperview()
         }
         }
-        
+
         contentView.addSubview(cusStackView)
         contentView.addSubview(cusStackView)
         cusStackView.snp.makeConstraints { make in
         cusStackView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
             make.edges.equalToSuperview()
@@ -293,89 +285,87 @@ class TSPTPInputVC: TSBaseVC {
             make.trailing.equalTo(-16)
             make.trailing.equalTo(-16)
             make.height.equalTo(48)
             make.height.equalTo(48)
         }
         }
-        
-        setUpCusStackView()
 
 
+        setUpCusStackView()
     }
     }
-    
+
     override func dealThings() {
     override func dealThings() {
         updataCollectionView()
         updataCollectionView()
-        //监听 vip 变化
+        // 监听 vip 变化
         NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
         updateVipView()
         updateVipView()
-        
+
         TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
         TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
 
 
         // 监听键盘事件
         // 监听键盘事件
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
-        
-        //监听collectionView 的 contentSize
+
+        // 监听collectionView 的 contentSize
         collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
         collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
-        collectionViewObserver.onContentSizeChange = {[weak self]  size in
+        collectionViewObserver.onContentSizeChange = { [weak self] size in
             guard let self = self else { return }
             guard let self = self else { return }
             print("collectionViewObserver 内容大小变化: \(size)")
             print("collectionViewObserver 内容大小变化: \(size)")
             self.collectionComponent.collectionView.snp.updateConstraints { make in
             self.collectionComponent.collectionView.snp.updateConstraints { make in
-               make.height.equalTo(size.height)
+                make.height.equalTo(size.height)
             }
             }
         }
         }
-        
-        //监听按钮任务生成中
-        NotificationCenter.default.addObserver(forName: .kBaseOperationQueueCountChanged, object: nil, queue: nil) { [weak self] notification in
+
+        // 监听按钮任务生成中
+        NotificationCenter.default.addObserver(forName: .kBaseOperationQueueCountChanged, object: nil, queue: nil) { [weak self] _ in
             guard let self = self else { return }
             guard let self = self else { return }
             setCreatBtnEnabled()
             setCreatBtnEnabled()
         }
         }
-        
-        //后台生成 UI 任务,刷新 UI界面
+
+        // 后台生成 UI 任务,刷新 UI界面
         NotificationCenter.default.addObserver(forName: .kGeneratePTPOperationChanged, object: nil, queue: nil) { [weak self] notification in
         NotificationCenter.default.addObserver(forName: .kGeneratePTPOperationChanged, object: nil, queue: nil) { [weak self] notification in
             guard let self = self else { return }
             guard let self = self else { return }
 
 
-            if let userInfo = notification.userInfo as? [String: Any],let state = userInfo["state"] as? TSProgressState {
+            if let userInfo = notification.userInfo as? [String: Any], let state = userInfo["state"] as? TSProgressState {
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
 //                if state.isResult {//有结果,一定要刷新
 //                if state.isResult {//有结果,一定要刷新
 //                    updataCollectionView()
 //                    updataCollectionView()
 //                }else if self.isViewVisible == false {
 //                }else if self.isViewVisible == false {
-////                    dePrint("TSBaseOperation 视图不可见")
+                ////                    dePrint("TSBaseOperation 视图不可见")
 //                    return
 //                    return
 //                }else
 //                }else
 //                if state.reloadNewData {//主要是给pending用,让他再视图中有个位置占着
 //                if state.reloadNewData {//主要是给pending用,让他再视图中有个位置占着
-                    updataCollectionView()
+                updataCollectionView()
 //                }
 //                }
             }
             }
         }
         }
-        
-        //同时 VC主动刷新UI界面
-        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: nil) { [weak self] notification in
+
+        // 同时 VC主动刷新UI界面
+        NotificationCenter.default.addObserver(forName: .kPTPDataChanged, object: nil, queue: nil) { [weak self] _ in
             guard let self = self else { return }
             guard let self = self else { return }
             DispatchQueue.main.async {
             DispatchQueue.main.async {
                 debugPrint("kPTPDataChanged listModels.first=\(self.viewModel.listModels.first?.toJSONString())")
                 debugPrint("kPTPDataChanged listModels.first=\(self.viewModel.listModels.first?.toJSONString())")
                 self.updataCollectionView()
                 self.updataCollectionView()
             }
             }
         }
         }
+
+        NotificationCenter.default.addObserver(self, selector: #selector(autoSelectImageToImageStyle(notify:)), name: .schemeImageToImageStylePick, object: nil)
     }
     }
-    
-    func updataCollectionView(){
-        self.viewModel.updateRecentData()
+
+    func updataCollectionView() {
+        viewModel.updateRecentData()
         collectionComponent.clear()
         collectionComponent.clear()
-        collectionComponent.reloadView(with:viewModel.colDataArray)
+        collectionComponent.reloadView(with: viewModel.colDataArray)
     }
     }
-
 }
 }
 
 
 extension TSPTPInputVC {
 extension TSPTPInputVC {
-    
-    func presentModalHintVC(){
+    func presentModalHintVC() {
         hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig) { [weak self] image in
         hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig) { [weak self] image in
             guard let self = self else { return }
             guard let self = self else { return }
             viewModel.upLoadImage = image
             viewModel.upLoadImage = image
             uploadView.upLoadImage = image
             uploadView.upLoadImage = image
             hintBaseVC.dismissPageVC()
             hintBaseVC.dismissPageVC()
         }
         }
-        kPresentModalVC(target: self, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
+        kPresentModalVC(target: self, modelVC: hintBaseVC, transitionStyle: .crossDissolve)
     }
     }
-    
-    func setUpCusStackView(){
 
 
+    func setUpCusStackView() {
         let uploadPhotoTitleView = TSTitleView.creatTitleView(title: "Upload Photo".localized, subTitle: "")
         let uploadPhotoTitleView = TSTitleView.creatTitleView(title: "Upload Photo".localized, subTitle: "")
         cusStackView.addSubviewToStack(uploadPhotoTitleView)
         cusStackView.addSubviewToStack(uploadPhotoTitleView)
         uploadPhotoTitleView.snp.makeConstraints { make in
         uploadPhotoTitleView.snp.makeConstraints { make in
@@ -384,7 +374,7 @@ extension TSPTPInputVC {
         }
         }
 
 
         let hintBtn = TSUIExpandedTouchButton()
         let hintBtn = TSUIExpandedTouchButton()
-        hintBtn.setUpButton(image: UIImage(named: "ptp_hint")){ [weak self]  in
+        hintBtn.setUpButton(image: UIImage(named: "ptp_hint")) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             presentModalHintVC()
             presentModalHintVC()
         }
         }
@@ -394,39 +384,39 @@ extension TSPTPInputVC {
             make.trailing.equalTo(-16)
             make.trailing.equalTo(-16)
             make.width.height.equalTo(16)
             make.width.height.equalTo(16)
         }
         }
- 
+
         cusStackView.addSubviewToStack(uploadView)
         cusStackView.addSubviewToStack(uploadView)
         uploadView.snp.makeConstraints { make in
         uploadView.snp.makeConstraints { make in
             make.height.equalTo(uploadView.viewH)
             make.height.equalTo(uploadView.viewH)
             make.width.equalTo(k_ScreenWidth)
             make.width.equalTo(k_ScreenWidth)
         }
         }
-        
+
         let selectStyleTitleView = TSTitleMoreView()
         let selectStyleTitleView = TSTitleMoreView()
-        selectStyleTitleView.setTitle(title: "Select Style".localized) { [weak self]  in
+        selectStyleTitleView.setTitle(title: "Select Style".localized) { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             let selectStyleVC = TSGennertatorSelectStyleVC()
             let selectStyleVC = TSGennertatorSelectStyleVC()
             selectStyleVC.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
             selectStyleVC.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
             selectStyleVC.dataArray = viewModel.ptpStyleModels
             selectStyleVC.dataArray = viewModel.ptpStyleModels
-            selectStyleVC.selectedValueBlock = { [weak self] indexPath ,model in
+            selectStyleVC.selectedValueBlock = { [weak self] indexPath, _ in
                 guard let self = self else { return }
                 guard let self = self else { return }
                 selectStyleView.collectionView(selectStyleView.styleCollectionView, didSelectItemAt: indexPath)
                 selectStyleView.collectionView(selectStyleView.styleCollectionView, didSelectItemAt: indexPath)
             }
             }
-            kPresentModalVC(target: self, modelVC: selectStyleVC,transitionStyle: .coverVertical)
+            kPresentModalVC(target: self, modelVC: selectStyleVC, transitionStyle: .coverVertical)
         }
         }
         cusStackView.addSubviewToStack(selectStyleTitleView)
         cusStackView.addSubviewToStack(selectStyleTitleView)
         selectStyleTitleView.snp.makeConstraints { make in
         selectStyleTitleView.snp.makeConstraints { make in
             make.height.equalTo(selectStyleTitleView.viewH)
             make.height.equalTo(selectStyleTitleView.viewH)
             make.width.equalTo(k_ScreenWidth)
             make.width.equalTo(k_ScreenWidth)
         }
         }
-        
+
         cusStackView.addSubviewToStack(selectStyleView)
         cusStackView.addSubviewToStack(selectStyleView)
         selectStyleView.snp.makeConstraints { make in
         selectStyleView.snp.makeConstraints { make in
             make.height.equalTo(selectStyleView.viewH)
             make.height.equalTo(selectStyleView.viewH)
             make.width.equalTo(k_ScreenWidth)
             make.width.equalTo(k_ScreenWidth)
         }
         }
-        
-        cusStackView.addSubviewToStack(promptTextView,length: promptTextViewH)
-        
+
+        cusStackView.addSubviewToStack(promptTextView, length: promptTextViewH)
+
         promptTextView.isHidden = !viewModel.selectedPTPStyleModel.input
         promptTextView.isHidden = !viewModel.selectedPTPStyleModel.input
 
 
         cusStackView.addSubviewToStack(collectionComponent.collectionView)
         cusStackView.addSubviewToStack(collectionComponent.collectionView)
@@ -434,95 +424,90 @@ extension TSPTPInputVC {
             make.height.equalTo(0)
             make.height.equalTo(0)
             make.width.equalTo(k_ScreenWidth)
             make.width.equalTo(k_ScreenWidth)
         }
         }
-        
+
         cusStackView.addSpacing(length: collectionViewBtootm)
         cusStackView.addSpacing(length: collectionViewBtootm)
     }
     }
 }
 }
 
 
-extension TSPTPInputVC: UITextViewDelegate{
+extension TSPTPInputVC: UITextViewDelegate {
     // 实现 UITextViewDelegate 协议方法,控制 return 键行为
     // 实现 UITextViewDelegate 协议方法,控制 return 键行为
     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
         if text == "\n" {
         if text == "\n" {
             // 当输入为换行符(即按下 return 键)时,执行相应操作
             // 当输入为换行符(即按下 return 键)时,执行相应操作
-            //sendBolck?(textView.text)
+            // sendBolck?(textView.text)
             clickView()
             clickView()
             return false
             return false
         }
         }
         return true
         return true
     }
     }
-    
-    func textViewDidChange(_ textView: UITextView){
+
+    func textViewDidChange(_ textView: UITextView) {
         clearBtn.isHidden = textView.text.count <= 0
         clearBtn.isHidden = textView.text.count <= 0
         viewModel.selectedPTPStyleModel.inputText = textView.text
         viewModel.selectedPTPStyleModel.inputText = textView.text
         viewModel.gennerateChange()
         viewModel.gennerateChange()
     }
     }
-   
 }
 }
 
 
 extension TSPTPInputVC {
 extension TSPTPInputVC {
-    
     @objc func vipInfoChanged() {
     @objc func vipInfoChanged() {
         kExecuteOnMainThread {
         kExecuteOnMainThread {
             self.updateVipView()
             self.updateVipView()
         }
         }
     }
     }
+
     func updateVipView() {
     func updateVipView() {
         kExecuteOnMainThread {
         kExecuteOnMainThread {
             self.vipBtn.isHidden = PurchaseManager.default.isVip
             self.vipBtn.isHidden = PurchaseManager.default.isVip
             self.creatBtnView.updateVipView()
             self.creatBtnView.updateVipView()
         }
         }
     }
     }
-    
-    func getVipText()->String{
+
+    func getVipText() -> String {
         return "Generate".localized
         return "Generate".localized
     }
     }
- 
-
 }
 }
+
 extension TSPTPInputVC {
 extension TSPTPInputVC {
-    
     @objc func clickView() {
     @objc func clickView() {
         view.endEditing(true)
         view.endEditing(true)
     }
     }
-    
+
     func generateImage() {
     func generateImage() {
-        
         viewModel.selectedPTPStyleModel.upLoadImage = viewModel.upLoadImage
         viewModel.selectedPTPStyleModel.upLoadImage = viewModel.upLoadImage
         viewModel.selectedPTPStyleModel.upLoadImageUrl = nil
         viewModel.selectedPTPStyleModel.upLoadImageUrl = nil
-        let gennerateVC = TSPTPGeneratorVC(generateStyleModel: viewModel.selectedPTPStyleModel) { [weak self] model in
+        let gennerateVC = TSPTPGeneratorVC(generateStyleModel: viewModel.selectedPTPStyleModel) { [weak self] _ in
             guard let self = self else { return }
             guard let self = self else { return }
             updateVipView()
             updateVipView()
         }
         }
-        
-        gennerateVC.reloadViewBlock = { [weak self]  in
+
+        gennerateVC.reloadViewBlock = { [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             updataCollectionView()
             updataCollectionView()
         }
         }
-        
+
         gennerateVC.closePageComplete = {
         gennerateVC.closePageComplete = {
-            [weak self]  in
+            [weak self] in
             guard let self = self else { return }
             guard let self = self else { return }
             updataCollectionView()
             updataCollectionView()
         }
         }
-        
-        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+
+        kPresentModalVC(target: self, modelVC: gennerateVC, transitionStyle: .crossDissolve)
     }
     }
-    
+
     func setCreatBtnEnabled() {
     func setCreatBtnEnabled() {
         let isAvailability = TSGeneratePTPOperationQueue.shared.isAvailability
         let isAvailability = TSGeneratePTPOperationQueue.shared.isAvailability
-        if viewModel.isCanGennerate,isAvailability {
+        if viewModel.isCanGennerate, isAvailability {
             creatBtnView.setBtnEnabled(isEnabled: true)
             creatBtnView.setBtnEnabled(isEnabled: true)
             creatBtnView.loading = false
             creatBtnView.loading = false
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled false")
-        }else{
+        } else {
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
             dePrint("TSTextGeneralPicVC setCreatBtnEnabled = \(isAvailability)")
             creatBtnView.setBtnEnabled(isEnabled: false)
             creatBtnView.setBtnEnabled(isEnabled: false)
             creatBtnView.loading = !isAvailability
             creatBtnView.loading = !isAvailability
         }
         }
-        
+
         updateVipView()
         updateVipView()
     }
     }
-
 }
 }
 
 
 extension TSPTPInputVC {
 extension TSPTPInputVC {
@@ -533,26 +518,36 @@ extension TSPTPInputVC {
         let textViewFrame = scrollView.convert(customTextView.frame, from: customTextView.superview)
         let textViewFrame = scrollView.convert(customTextView.frame, from: customTextView.superview)
         let scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
         let scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
         let y = scrollDistance
         let y = scrollDistance
-        scrollView.setContentOffset(CGPoint(x: 0, y: y),animated: true)
+        scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
     }
     }
-    
+
     // MARK: - 键盘隐藏时恢复
     // MARK: - 键盘隐藏时恢复
+
     @objc private func keyboardWillHide(_ notification: Notification) {
     @objc private func keyboardWillHide(_ notification: Notification) {
         cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
         cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
     }
     }
 }
 }
+
 extension TSPTPInputVC {
 extension TSPTPInputVC {
-    
-    func updateTextFiledView () {
+    func updateTextFiledView() {
         if viewModel.selectedPTPStyleModel.input {
         if viewModel.selectedPTPStyleModel.input {
             promptTextView.isHidden = false
             promptTextView.isHidden = false
-        }else{
+        } else {
             promptTextView.isHidden = true
             promptTextView.isHidden = true
         }
         }
-        
+
         UIView.animate(withDuration: 0.3) {
         UIView.animate(withDuration: 0.3) {
             self.cusStackView.layoutIfNeeded()
             self.cusStackView.layoutIfNeeded()
         }
         }
     }
     }
 }
 }
 
 
+extension TSPTPInputVC {
+    @objc func autoSelectImageToImageStyle(notify: Notification) {
+        if let objc = notify.userInfo as? [String: String] {
+            WindowHelper.resetToTabBarController(at: 0)
+            let styleId = objc.safeString(forKey: "styleId")
+            selectStyleView.selectStyle(styleId: styleId)
+        }
+    }
+}

+ 28 - 22
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/View/TSPTPSelectStyleView.swift

@@ -5,33 +5,32 @@
 //  Created by 100Years on 2025/4/7.
 //  Created by 100Years on 2025/4/7.
 //
 //
 
 
-class TSPTPSelectStyleView : TSBaseView{
+class TSPTPSelectStyleView: TSBaseView {
     var viewH: CGFloat = 108.0
     var viewH: CGFloat = 108.0
-    var dataArray: [TSGenerateStyleModel] = [TSGenerateStyleModel](){
-        didSet{
+    var dataArray: [TSGenerateStyleModel] = [TSGenerateStyleModel]() {
+        didSet {
             styleCollectionView.reloadData()
             styleCollectionView.reloadData()
-            
+
             if dataArray.count > 0 {
             if dataArray.count > 0 {
 //                DispatchQueue.main.async {
 //                DispatchQueue.main.async {
-                self.styleCollectionView.selectItem(at: self.currentIndexPath, animated: false, scrollPosition: .centeredHorizontally)
+                styleCollectionView.selectItem(at: currentIndexPath, animated: false, scrollPosition: .centeredHorizontally)
 //                }
 //                }
             }
             }
         }
         }
     }
     }
-    
-    var clickHandle:((IndexPath,TSGenerateStyleModel)->Void)?
+
+    var clickHandle: ((IndexPath, TSGenerateStyleModel) -> Void)?
     lazy var layout: UICollectionViewFlowLayout = {
     lazy var layout: UICollectionViewFlowLayout = {
         let layout = UICollectionViewFlowLayout()
         let layout = UICollectionViewFlowLayout()
         layout.scrollDirection = .horizontal
         layout.scrollDirection = .horizontal
-        let w = (k_ScreenWidth-32.0-30.0-2.0)/4.0
+        let w = (k_ScreenWidth - 32.0 - 30.0 - 2.0) / 4.0
         layout.itemSize = CGSize(width: w, height: viewH)
         layout.itemSize = CGSize(width: w, height: viewH)
         layout.minimumInteritemSpacing = 0.0
         layout.minimumInteritemSpacing = 0.0
         layout.minimumLineSpacing = 10.0
         layout.minimumLineSpacing = 10.0
         layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
         layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
         return layout
         return layout
     }()
     }()
-    
-    
+
     lazy var styleCollectionView: UICollectionView = {
     lazy var styleCollectionView: UICollectionView = {
         let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
         let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
         collectionView.delegate = self
         collectionView.delegate = self
@@ -46,7 +45,7 @@ class TSPTPSelectStyleView : TSBaseView{
         return collectionView
         return collectionView
     }()
     }()
 
 
-    var currentIndexPath:IndexPath = IndexPath(item: 0, section: 0)
+    var currentIndexPath: IndexPath = IndexPath(item: 0, section: 0)
 
 
     override func creatUI() {
     override func creatUI() {
         currentIndexPath = IndexPath(item: 0, section: 0)
         currentIndexPath = IndexPath(item: 0, section: 0)
@@ -55,36 +54,43 @@ class TSPTPSelectStyleView : TSBaseView{
             make.edges.equalToSuperview()
             make.edges.equalToSuperview()
         }
         }
     }
     }
-    
-    func unCheck(){
+
+    func selectStyle(styleId: String) {
+        let index = dataArray.firstIndex {
+            $0.style == styleId
+        } ?? 0
+
+        let indexPath = IndexPath(item: index, section: 0)
+        collectionView(styleCollectionView, didSelectItemAt: indexPath)
+    }
+
+    func unCheck() {
         styleCollectionView.deselectItem(at: currentIndexPath, animated: true)
         styleCollectionView.deselectItem(at: currentIndexPath, animated: true)
     }
     }
 }
 }
 
 
-extension TSPTPSelectStyleView: UICollectionViewDataSource ,UICollectionViewDelegate {
-    
+extension TSPTPSelectStyleView: UICollectionViewDataSource, UICollectionViewDelegate {
     public func numberOfSections(in collectionView: UICollectionView) -> Int {
     public func numberOfSections(in collectionView: UICollectionView) -> Int {
         return 1
         return 1
     }
     }
-    
+
     public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
     public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
         return dataArray.count
         return dataArray.count
     }
     }
-    
+
     public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSGennertatorSelectStyleCell.cellID, for: indexPath)
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSGennertatorSelectStyleCell.cellID, for: indexPath)
-        if let cell = cell as? TSGennertatorSelectStyleCell,let itemModel = dataArray.safeObj(At: indexPath.item){
+        if let cell = cell as? TSGennertatorSelectStyleCell, let itemModel = dataArray.safeObj(At: indexPath.item) {
             cell.itemModel = itemModel
             cell.itemModel = itemModel
         }
         }
         return cell
         return cell
     }
     }
 
 
     public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
     public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-        if let model = dataArray.safeObj(At: indexPath.item){
+        if let model = dataArray.safeObj(At: indexPath.item) {
             currentIndexPath = indexPath
             currentIndexPath = indexPath
-            self.styleCollectionView.selectItem(at: self.currentIndexPath, animated: true, scrollPosition: .centeredHorizontally)
-            clickHandle?(indexPath,model)
+            styleCollectionView.selectItem(at: currentIndexPath, animated: true, scrollPosition: .centeredHorizontally)
+            clickHandle?(indexPath, model)
         }
         }
     }
     }
 }
 }

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/TSPTPStyleModel.swift

@@ -27,7 +27,7 @@ class TSGenerateStyleModel: TSBaseModel {
         isVip                   <- map["isVip"]
         isVip                   <- map["isVip"]
         specialStyle            <- map["specialStyle"]
         specialStyle            <- map["specialStyle"]
         clickType               <- map["clickType"]
         clickType               <- map["clickType"]
-        style                   <- map["style"]
+        style                   <- map["styleId"]
         input                   <- map["input"]
         input                   <- map["input"]
         advance                 <- map["advance"]
         advance                 <- map["advance"]
     }
     }

+ 22 - 0
AIEmoji/Common/Ex/TSCustomAlertController+Ext.swift

@@ -0,0 +1,22 @@
+//
+//  TSCustomAlert+Ext.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/5/8.
+//
+
+import Foundation
+
+extension TSCustomAlertController {
+    /// 确认弹窗
+    public static func showAlert(on viewController: UIViewController, title: String?, message: String?, confirmTitle: String = "OK", confirmHandler: (() -> Void)? = nil) {
+        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+        let confirmAction = UIAlertAction(title: confirmTitle, style: .default) { _ in
+            confirmHandler?()
+        }
+
+        alert.addAction(confirmAction)
+        viewController.present(alert, animated: true, completion: nil)
+    }
+}

+ 53 - 0
AIEmoji/Common/SchemeHandler/SchemeHandler+Ext.swift

@@ -0,0 +1,53 @@
+//
+//  SchemeHandler+Open.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/5/8.
+//
+
+import Foundation
+
+extension SchemeHandler {
+    // MARK: - 私有处理方法
+
+    func handleDefault() {
+        // 处理默认情况(无路径或未知路径)
+        guard let topVc = WindowHelper.topViewController() else {
+            debugPrint("🙅scheme 没有相应匹配,检查scheme 路由及参数")
+            return
+        }
+        TSCustomAlertController.showAlert(on: topVc, title: "The activity has expired, come next time".localized, message: nil)
+    }
+
+    func handleImageToImagePick(params: [URLQueryItem]?) {
+        var info: [String: Any]?
+        if let styleId = params?.first(where: { $0.name == "styleId" })?.value {
+            info = ["styleId": styleId]
+        }
+
+        NotificationCenter.default.post(
+            name: .schemeImageToImageStylePick,
+            object: nil,
+            userInfo: info)
+    }
+
+    /// 打开文生图页面
+    func handleTextToImageOpen(params: [URLQueryItem]?) {
+        WindowHelper.resetToTabBarController(at: 1)
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
+            if let top = WindowHelper.topViewController() {
+                kPushVC(target: top, modelVC: TSTextGeneralPictureVC())
+            }
+        }
+    }
+
+    /// 打开母亲节活动页面
+    func handleMotherPolaroidOpen(params: [URLQueryItem]?) {
+        // TODO: 跳转 母亲节页面,参考文生图
+    }
+
+    /// 打开猫咪拟人化页面
+    func handlePetHumanizationOpen(params: [URLQueryItem]?) {
+        // TODO: 跳转猫咪拟人化页面,参考文生图
+    }
+}

+ 56 - 0
AIEmoji/Common/SchemeHandler/SchemeHandler.swift

@@ -0,0 +1,56 @@
+//
+//  SchemeHandler.swift
+//  AIEmoji
+//
+//  Created by nkl on 2025/5/8.
+//
+
+/**
+ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
+ shceme 定义规则
+ 参考:
+ aiemoji://ImageToImage?style=Y2K
+ 路径 ImageToImage
+
+ 复杂逻辑发送对应通知,在对应位置处理相应逻辑,这里只做参数解析(注意:做好兜底逻辑)
+ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️
+ */
+
+import Foundation
+
+class SchemeHandler {
+    static let shared = SchemeHandler()
+
+    private init() {}
+    
+    func handle(url: URL) -> Bool {
+        guard url.scheme == "aiemoji" else { return false }
+
+        let path = url.host ?? ""
+        let params = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
+
+        print("Scheme received - Path: \(path), Params: \(params ?? [])")
+
+        switch path {
+        case "ImageToImage":
+            handleImageToImagePick(params: params)
+        case "TextToImage":
+            handleTextToImageOpen(params: params)
+        case "MotherPolaroid":
+            handleMotherPolaroidOpen(params: params)
+        case "PetHumanization":
+            handlePetHumanizationOpen(params: params)
+        default:
+            handleDefault()
+        }
+
+        return true
+    }
+}
+
+// MARK: - 通知扩展
+
+// 命名规则 Scheme+(功能)+Notification
+extension Notification.Name {
+    static let schemeImageToImageStylePick = Notification.Name("SchemeImageToImageStylePickNotification")
+}

+ 18 - 0
AIEmoji/Common/Tool/WindowHelper.swift

@@ -68,4 +68,22 @@ class WindowHelper {
         debugPrint("当前顶层 VC 是: \(String(describing: base))")
         debugPrint("当前顶层 VC 是: \(String(describing: base))")
         return base
         return base
     }
     }
+    
+    static func resetToTabBarController(at index: Int) {
+        guard let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }),
+              let tabBarController = window.rootViewController as? UITabBarController else {
+            return
+        }
+
+        // 关闭所有模态视图
+        window.rootViewController?.dismiss(animated: false) {
+            // 获取当前选中的 navigationController
+            if let nav = tabBarController.selectedViewController as? UINavigationController {
+                nav.popToRootViewController(animated: false)
+            }
+
+            // 切换到目标 tab
+            tabBarController.selectedIndex = index
+        }
+    }
 }
 }

+ 13 - 0
AIEmoji/Info.plist

@@ -2,6 +2,19 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <plist version="1.0">
 <dict>
 <dict>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLName</key>
+			<string>com.girl.music.wallpaper</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>aiemoji</string>
+			</array>
+		</dict>
+	</array>
 	<key>NSAppTransportSecurity</key>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>
 		<key>NSAllowsArbitraryLoads</key>

+ 38 - 6
AIEmoji/Res/photo_to_photo_style.json

@@ -5,6 +5,7 @@
         "prompt":"Turn uploaded photos into ghibli style",
         "prompt":"Turn uploaded photos into ghibli style",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-02",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -12,6 +13,7 @@
         "imageText": "Anime Lite",
         "imageText": "Anime Lite",
         "prompt":"Studio Ghibli-inspired anime aesthetic, Hayao Miyazaki style, vibrant yet soft color palette, detailed hand-painted textures, whimsical dreamlike atmosphere, soft cel-shading, watercolor wash effect, subtle grain texture, preserving original composition. Style strength: 85%",
         "prompt":"Studio Ghibli-inspired anime aesthetic, Hayao Miyazaki style, vibrant yet soft color palette, detailed hand-painted textures, whimsical dreamlike atmosphere, soft cel-shading, watercolor wash effect, subtle grain texture, preserving original composition. Style strength: 85%",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-01",
         "isVip": false
         "isVip": false
     },
     },
     {
     {
@@ -21,12 +23,14 @@
         "input":true,
         "input":true,
         "specialStyle":1,
         "specialStyle":1,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-04",
         "advance":true
         "advance":true
     },
     },
     {
     {
         "imageName": "ptp_style_7",
         "imageName": "ptp_style_7",
         "imageText": "Fantasy Illustration",
         "imageText": "Fantasy Illustration",
         "prompt":"将图片转化成精美插画手绘风格,保留人物主体和背景",
         "prompt":"将图片转化成精美插画手绘风格,保留人物主体和背景",
+        "styleId": "ImageToImage-05",
         "isVip": false
         "isVip": false
     },
     },
     {
     {
@@ -35,12 +39,14 @@
         "prompt":"用 irasutoya 风格绘制上传的照片,保留关键内容和构图,色彩丰富明亮",
         "prompt":"用 irasutoya 风格绘制上传的照片,保留关键内容和构图,色彩丰富明亮",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-09",
         "advance":true
         "advance":true
     },{
     },{
         "imageName": "ptp_style_chibi",
         "imageName": "ptp_style_chibi",
         "imageText": "Chibi",
         "imageText": "Chibi",
         "prompt":"Turn the uploaded photo into a chibi sticker set of 4 pictures,every sticker should not cover the other stickers",
         "prompt":"Turn the uploaded photo into a chibi sticker set of 4 pictures,every sticker should not cover the other stickers",
         "specialStyle":2,
         "specialStyle":2,
+        "styleId": "ImageToImage-03",
         "isVip": true,
         "isVip": true,
         "advance":true
         "advance":true
     },
     },
@@ -50,6 +56,7 @@
         "prompt":"Q版人物形象,3D黏土风,是真实世界的光影,保留原始人物细节,包括服装和造型。整体放在一张拍立得照片中,有一只手握着拍立得相纸。图中角色从拍立得相纸中,突破边框,延伸进入现实世界的二维空间。背景延续拍立得中的背景,Q版风格,背景不需要再有人物出现,仅作为拍立得中背景的延展,与照片原始场景一致。拍立得底部文字是“Life Moment”。",
         "prompt":"Q版人物形象,3D黏土风,是真实世界的光影,保留原始人物细节,包括服装和造型。整体放在一张拍立得照片中,有一只手握着拍立得相纸。图中角色从拍立得相纸中,突破边框,延伸进入现实世界的二维空间。背景延续拍立得中的背景,Q版风格,背景不需要再有人物出现,仅作为拍立得中背景的延展,与照片原始场景一致。拍立得底部文字是“Life Moment”。",
         "specialStyle":2,
         "specialStyle":2,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-07",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -58,6 +65,7 @@
         "prompt":"A soft, high-quality plush toy of the uploaded photo's mainperson, with an oversized head, small body, and stubby limbs. It's made of fuzzy fabric, has embroidered facial features, and is shown sitting or standing against a neutral background. The expression is cute or expressive, and it wears simple clothes or iconic accessories if relevant. The lighting is soft and even, with a realistic, collectible toy look. Centered, full-body view.",
         "prompt":"A soft, high-quality plush toy of the uploaded photo's mainperson, with an oversized head, small body, and stubby limbs. It's made of fuzzy fabric, has embroidered facial features, and is shown sitting or standing against a neutral background. The expression is cute or expressive, and it wears simple clothes or iconic accessories if relevant. The lighting is soft and even, with a realistic, collectible toy look. Centered, full-body view.",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-06",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -66,6 +74,7 @@
         "prompt":"根据照片上的内容打造一款细致精美、萌趣可爱的3D渲染收藏摆件,装置在柔和粉彩色调、温馨浪漫的展示盒中。展示盒为浅奶油色搭配柔和的金色装饰,形似精致的便携珠宝盒。打开盒盖,呈现出一幕温暖浪漫的场景:两位Q版角色正甜蜜相望。盒顶雕刻着“FOREVER TOGETHER”(永远在一起)的字样,周围点缀着小巧精致的星星与爱心图案。两人都拥有充满表现力的眼睛,以及柔和、温暖的微笑,传递出浓浓的爱意和迷人的气质。他们身后有一扇圆形窗户,透过窗户能看到阳光明媚的中国古典小镇天际线和轻柔飘浮的云朵。盒内以温暖的柔和光线进行照明,背景中漂浮着花瓣点缀气氛。整个展示盒和角色的色调优雅和谐,营造出一个奢华而梦幻的迷你纪念品场景。",
         "prompt":"根据照片上的内容打造一款细致精美、萌趣可爱的3D渲染收藏摆件,装置在柔和粉彩色调、温馨浪漫的展示盒中。展示盒为浅奶油色搭配柔和的金色装饰,形似精致的便携珠宝盒。打开盒盖,呈现出一幕温暖浪漫的场景:两位Q版角色正甜蜜相望。盒顶雕刻着“FOREVER TOGETHER”(永远在一起)的字样,周围点缀着小巧精致的星星与爱心图案。两人都拥有充满表现力的眼睛,以及柔和、温暖的微笑,传递出浓浓的爱意和迷人的气质。他们身后有一扇圆形窗户,透过窗户能看到阳光明媚的中国古典小镇天际线和轻柔飘浮的云朵。盒内以温暖的柔和光线进行照明,背景中漂浮着花瓣点缀气氛。整个展示盒和角色的色调优雅和谐,营造出一个奢华而梦幻的迷你纪念品场景。",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-10",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -74,6 +83,7 @@
         "prompt":"将照片中的人物生成泡泡玛特风格手办,为泡泡玛特盲盒形式,3d 公仔在包装盒外面,采用正面视角,精致可爱O版的潮玩风格,公仔旁边放着正方形包装盒,和公仔有一点距离,包装盒为2d公仔的设计,包装盒正面图案为公仔正面形象。包装上带有文字 FunPop,图片背景根据上传图片的颜色自适应",
         "prompt":"将照片中的人物生成泡泡玛特风格手办,为泡泡玛特盲盒形式,3d 公仔在包装盒外面,采用正面视角,精致可爱O版的潮玩风格,公仔旁边放着正方形包装盒,和公仔有一点距离,包装盒为2d公仔的设计,包装盒正面图案为公仔正面形象。包装上带有文字 FunPop,图片背景根据上传图片的颜色自适应",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-11",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -82,6 +92,7 @@
         "prompt":"请根据上传的照片生成AirPods充电盒手办,照片的人物探出AirPods充电盒,一只手扶着盒子边缘,一只手拿着咖啡杯(或者打招呼),营造可爱且俏皮的感觉。充电盒细节 :Apple AirPods充电盒设计,摆放角度为45度角摆放,让内部结构更清楚。内部摆放顺序: 照片中的人物,AirPods 耳机(只保留一个耳机,摆放于盒内)。整体风格要可爱3D盲盒风格,人物相似度高",
         "prompt":"请根据上传的照片生成AirPods充电盒手办,照片的人物探出AirPods充电盒,一只手扶着盒子边缘,一只手拿着咖啡杯(或者打招呼),营造可爱且俏皮的感觉。充电盒细节 :Apple AirPods充电盒设计,摆放角度为45度角摆放,让内部结构更清楚。内部摆放顺序: 照片中的人物,AirPods 耳机(只保留一个耳机,摆放于盒内)。整体风格要可爱3D盲盒风格,人物相似度高",
         "specialStyle":2,
         "specialStyle":2,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-13",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -90,6 +101,7 @@
         "prompt":"把照片变成梵高的画风,保留人物和背景,要符合梵高风格的色彩手法,整体和谐好看",
         "prompt":"把照片变成梵高的画风,保留人物和背景,要符合梵高风格的色彩手法,整体和谐好看",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-22",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -98,6 +110,7 @@
         "prompt":"请把上传的照片生成 switch 版动物森友会的风格,要和游戏中一样有立体质感,保留照片人物本身的表情和动作",
         "prompt":"请把上传的照片生成 switch 版动物森友会的风格,要和游戏中一样有立体质感,保留照片人物本身的表情和动作",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-14",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -106,6 +119,7 @@
         "prompt":"将这张照片生成为 chiikawa 画风,并让吉伊小八乌萨奇围绕在人物身边,耳朵要圆的,不要把人物变成 chiikawa",
         "prompt":"将这张照片生成为 chiikawa 画风,并让吉伊小八乌萨奇围绕在人物身边,耳朵要圆的,不要把人物变成 chiikawa",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-15",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -124,6 +138,7 @@
         "prompt":"把上传的照片转化成Y2K千禧风格,保留原本人物主体",
         "prompt":"把上传的照片转化成Y2K千禧风格,保留原本人物主体",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-24",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -133,6 +148,7 @@
         "prompt":"把上传的图片转换成中式剪纸风格,保留人物主体",
         "prompt":"把上传的图片转换成中式剪纸风格,保留人物主体",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-35",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -141,6 +157,7 @@
         "prompt":"把上传的图片转换成治愈系简笔画风格,保留人物主体",
         "prompt":"把上传的图片转换成治愈系简笔画风格,保留人物主体",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-18",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -149,6 +166,7 @@
         "prompt":"把上传的图片转换成手绘水彩风格,保留人物主体",
         "prompt":"把上传的图片转换成手绘水彩风格,保留人物主体",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-29",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -158,6 +176,7 @@
         "prompt":"Turn uploaded photos into Neon style",
         "prompt":"Turn uploaded photos into Neon style",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-32",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -167,6 +186,7 @@
         "prompt":"把上传的图片变成黑白日本漫画风格,不要改变人物主体",
         "prompt":"把上传的图片变成黑白日本漫画风格,不要改变人物主体",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-23",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -175,6 +195,7 @@
         "prompt":"把图片转换成儿童蜡笔风格,线条歪歪扭扭、色彩鲜艳丰富、充满童趣和表现力,像小朋友自由涂鸦出来的画",
         "prompt":"把图片转换成儿童蜡笔风格,线条歪歪扭扭、色彩鲜艳丰富、充满童趣和表现力,像小朋友自由涂鸦出来的画",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-30",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -183,6 +204,7 @@
         "prompt":"把上传的照片转化成针织娃娃风格,四肢使用彩虹色毛线编织,其他部位保持原画色编织,质感柔软",
         "prompt":"把上传的照片转化成针织娃娃风格,四肢使用彩虹色毛线编织,其他部位保持原画色编织,质感柔软",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-31",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -192,6 +214,7 @@
         "prompt":"把上传的照片转化为手工纸艺风,温暖略带超现实感,用纸板、瓶盖和贴纸等材料拼贴而成,温暖俏皮的色调",
         "prompt":"把上传的照片转化为手工纸艺风,温暖略带超现实感,用纸板、瓶盖和贴纸等材料拼贴而成,温暖俏皮的色调",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-34",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -201,6 +224,7 @@
         "prompt":"色彩鲜艳、表现力强的 riso 印刷(Risograph)风格,保留人物本身的表情动作",
         "prompt":"色彩鲜艳、表现力强的 riso 印刷(Risograph)风格,保留人物本身的表情动作",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-36",
         "advance":true
         "advance":true
     },
     },
     
     
@@ -210,6 +234,7 @@
         "prompt":"把上传的图片转化成黑白简笔画风格,使用粗线条勾勒轮廓,图像无阴影无填色,线条干净,边缘柔和,图片背景用白色不要透明",
         "prompt":"把上传的图片转化成黑白简笔画风格,使用粗线条勾勒轮廓,图像无阴影无填色,线条干净,边缘柔和,图片背景用白色不要透明",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-37",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -218,6 +243,7 @@
         "prompt":"Turn uploaded photo into sketch style",
         "prompt":"Turn uploaded photo into sketch style",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-25",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -225,12 +251,14 @@
         "imageText": "Claymation",
         "imageText": "Claymation",
         "prompt":"粘土动画风特征",
         "prompt":"粘土动画风特征",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-26",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
         "imageName": "ptp_style_6",
         "imageName": "ptp_style_6",
         "imageText": "Classical Painting",
         "imageText": "Classical Painting",
         "prompt":"Baroque oil painting conversion:  Rembrandt chiaroscuro lighting (3:1 contrast ratio)  Vermeer's ultramarine glaze technique  Impasto brushwork (0.8mm relief depth)  Aged varnish patina simulation  17th-century earth pigment palette (ochre/umber/lead-tin yellow)  Canvas weave retention (100% texture mapping)  Max 2% anatomical adjustment",
         "prompt":"Baroque oil painting conversion:  Rembrandt chiaroscuro lighting (3:1 contrast ratio)  Vermeer's ultramarine glaze technique  Impasto brushwork (0.8mm relief depth)  Aged varnish patina simulation  17th-century earth pigment palette (ochre/umber/lead-tin yellow)  Canvas weave retention (100% texture mapping)  Max 2% anatomical adjustment",
+        "styleId": "ImageToImage-08",
         "isVip": false
         "isVip": false
     },
     },
     {
     {
@@ -238,6 +266,7 @@
         "imageText": "Disney",
         "imageText": "Disney",
         "prompt":"把图片变成disney风格",
         "prompt":"把图片变成disney风格",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-21",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
@@ -246,6 +275,7 @@
         "prompt":"Transform this photo into a Snoopy cartoon style, including Snoopy and Woodstock, with the same color and frame size as the original photo, don't change my face to Snoopy",
         "prompt":"Transform this photo into a Snoopy cartoon style, including Snoopy and Woodstock, with the same color and frame size as the original photo, don't change my face to Snoopy",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-19",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -254,6 +284,7 @@
         "prompt":"Please turn this picture into Hello Kitty cartoon style and add Hello Kitty, don't change my face to hello kitty",
         "prompt":"Please turn this picture into Hello Kitty cartoon style and add Hello Kitty, don't change my face to hello kitty",
         "specialStyle":0,
         "specialStyle":0,
         "isVip": true,
         "isVip": true,
+        "styleId": "ImageToImage-20",
         "advance":true
         "advance":true
     },
     },
     {
     {
@@ -267,6 +298,7 @@
         "imageText": "3D",
         "imageText": "3D",
         "prompt":"把图片变成 Pixar 风格",
         "prompt":"把图片变成 Pixar 风格",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-12",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
@@ -274,12 +306,14 @@
         "imageText": "Pixel",
         "imageText": "Pixel",
         "prompt":"超精细等距像素艺术,严格16x16像素网格,怀旧游戏机调色板,智能选择性抗锯齿+邻近插值算法,点阵抖动优化",
         "prompt":"超精细等距像素艺术,严格16x16像素网格,怀旧游戏机调色板,智能选择性抗锯齿+邻近插值算法,点阵抖动优化",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-27",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
         "imageName": "ptp_style_4",
         "imageName": "ptp_style_4",
         "imageText": "Pop Art",
         "imageText": "Pop Art",
         "prompt":"波普艺术肖像:1.3, [上传的图片], 鲜明本戴圆点, 半调网格纹, 粗黑轮廓线, 高饱和霓虹色块, 安迪沃霍尔风格, 罗伊·利希滕斯坦影响, 丝网印刷质感, 漫画美学, 平面色彩过渡, 电光青|荧光粉|酸性黄配色方案, 原始表情保留, 无阴影 --no 渐变, 写实, 立体感",
         "prompt":"波普艺术肖像:1.3, [上传的图片], 鲜明本戴圆点, 半调网格纹, 粗黑轮廓线, 高饱和霓虹色块, 安迪沃霍尔风格, 罗伊·利希滕斯坦影响, 丝网印刷质感, 漫画美学, 平面色彩过渡, 电光青|荧光粉|酸性黄配色方案, 原始表情保留, 无阴影 --no 渐变, 写实, 立体感",
+        "styleId": "ImageToImage-38",
         "isVip": false
         "isVip": false
     },
     },
     {
     {
@@ -287,18 +321,14 @@
         "imageText": "Ukiyoe",
         "imageText": "Ukiyoe",
         "prompt":"整体转换为浮世绘风格,保留原始人物面部细节",
         "prompt":"整体转换为浮世绘风格,保留原始人物面部细节",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-33",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
         "imageName": "ptp_style_1",
         "imageName": "ptp_style_1",
         "imageText": "Cyberpunk",
         "imageText": "Cyberpunk",
         "prompt":"保留上传的图片人物表情和动作,不改变主体形状,添加霓虹灯光(蓝紫色)、机械义体细节、全息投影,背景改为雨夜未来都市,高饱和度强对比,发光边缘,轻微故障艺术,--保持构图与原图一致",
         "prompt":"保留上传的图片人物表情和动作,不改变主体形状,添加霓虹灯光(蓝紫色)、机械义体细节、全息投影,背景改为雨夜未来都市,高饱和度强对比,发光边缘,轻微故障艺术,--保持构图与原图一致",
-        "isVip": false
-    },
-    {
-        "imageName": "ptp_style_8",
-        "imageText": "Photorealism",
-        "prompt":"上传的照片变成超写实照片级细节:1.5,皮肤毛孔/发丝/织物纤维高清刻画,自然光影立体感,4K电影质感,蔡司85mm f/1.4镜头焦外虚化,100%原图主体保留,面部零修改 --no 卡通化 艺术化 模糊 噪点",
+        "styleId": "ImageToImage-17",
         "isVip": false
         "isVip": false
     },
     },
     {
     {
@@ -306,6 +336,7 @@
         "imageText": "Toy",
         "imageText": "Toy",
         "prompt":"把图片变成LEGO风格",
         "prompt":"把图片变成LEGO风格",
         "specialStyle":0,
         "specialStyle":0,
+        "styleId": "ImageToImage-39",
         "isVip": true
         "isVip": true
     },
     },
     {
     {
@@ -315,6 +346,7 @@
         "specialStyle":0,
         "specialStyle":0,
         "input":true,
         "input":true,
         "isVip": false,
         "isVip": false,
+        "styleId": "ImageToImage-40",
         "advance":true
         "advance":true
     }
     }
 ]
 ]

+ 2 - 0
AIEmoji/de.lproj/Localizable.strings

@@ -292,3 +292,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Es wurde ungewöhnlich hohe Generierungsaktivität festgestellt. Sie könnten ein Bot sein. Bitte versuchen Sie es morgen erneut.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Es wurde ungewöhnlich hohe Generierungsaktivität festgestellt. Sie könnten ein Bot sein. Bitte versuchen Sie es morgen erneut.";
 "Got it" = "Verstanden";
 "Got it" = "Verstanden";
 "Aspect Ratio" = "Seitenverhältnis";
 "Aspect Ratio" = "Seitenverhältnis";
+
+"The activity has expired, come next time" = "Die Aktivität ist abgelaufen, kommen Sie das nächste Mal";

+ 3 - 0
AIEmoji/en.lproj/Localizable.strings

@@ -289,3 +289,6 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow.";
 "Got it" = "Got it";
 "Got it" = "Got it";
 "Aspect Ratio" = "Aspect Ratio";
 "Aspect Ratio" = "Aspect Ratio";
+
+
+"The activity has expired, come next time" = "The activity has expired, come next time";

+ 2 - 0
AIEmoji/es.lproj/Localizable.strings

@@ -289,3 +289,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Se ha detectado una frecuencia de generación inusualmente alta. Podría ser un bot. Por favor, inténtelo de nuevo mañana.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Se ha detectado una frecuencia de generación inusualmente alta. Podría ser un bot. Por favor, inténtelo de nuevo mañana.";
 "Got it" = "Entendido";
 "Got it" = "Entendido";
 "Aspect Ratio" = "Relación de aspecto";
 "Aspect Ratio" = "Relación de aspecto";
+
+"The activity has expired, come next time" = "La actividad ha caducado, ven la próxima vez.";

+ 2 - 0
AIEmoji/ja.lproj/Localizable.strings

@@ -288,3 +288,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "生成頻度が異常に高いと検知されました。ボットの可能性があります。明日再度お試しください。";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "生成頻度が異常に高いと検知されました。ボットの可能性があります。明日再度お試しください。";
 "Got it" = "了解しました";
 "Got it" = "了解しました";
 "Aspect Ratio" = "アスペクト比";
 "Aspect Ratio" = "アスペクト比";
+
+"The activity has expired, come next time" = "アクティビティの有効期限が切れました。次回に来てください";

+ 2 - 0
AIEmoji/ko.lproj/Localizable.strings

@@ -294,3 +294,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "생성 빈도가 비정상적으로 높게 감지되었습니다. 봇일 가능성이 있습니다. 내일 다시 시도해 주세요.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "생성 빈도가 비정상적으로 높게 감지되었습니다. 봇일 가능성이 있습니다. 내일 다시 시도해 주세요.";
 "Got it" = "확인했습니다";
 "Got it" = "확인했습니다";
 "Aspect Ratio" = "종횡비";
 "Aspect Ratio" = "종횡비";
+
+"The activity has expired, come next time" = "활동이 만료되었습니다. 다음에 오세요.";

+ 2 - 0
AIEmoji/pt-BR.lproj/Localizable.strings

@@ -288,3 +288,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Detectamos uma frequência de geração anormalmente alta. Você pode ser um bot. Por favor, tente novamente amanhã.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Detectamos uma frequência de geração anormalmente alta. Você pode ser um bot. Por favor, tente novamente amanhã.";
 "Got it" = "Entendido";
 "Got it" = "Entendido";
 "Aspect Ratio" = "Proporção";
 "Aspect Ratio" = "Proporção";
+
+"The activity has expired, come next time" = "A atividade expirou, venha na próxima vez";

+ 2 - 0
AIEmoji/pt-PT.lproj/Localizable.strings

@@ -288,3 +288,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Detectamos uma frequência de geração anormalmente alta. Você pode ser um bot. Por favor, tente novamente amanhã.";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "Detectamos uma frequência de geração anormalmente alta. Você pode ser um bot. Por favor, tente novamente amanhã.";
 "Got it" = "Entendido";
 "Got it" = "Entendido";
 "Aspect Ratio" = "Proporção";
 "Aspect Ratio" = "Proporção";
+
+"The activity has expired, come next time" = "A atividade expirou, venha na próxima vez";

+ 2 - 0
AIEmoji/zh-Hans.lproj/Localizable.strings

@@ -289,3 +289,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "检测到您的生成频率过高,您可能是机器人,请明日再来";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "检测到您的生成频率过高,您可能是机器人,请明日再来";
 "Got it" = "知道了";
 "Got it" = "知道了";
 "Aspect Ratio" = "宽高比";
 "Aspect Ratio" = "宽高比";
+
+"The activity has expired, come next time" = "活动已结束,下次再来";

+ 2 - 0
AIEmoji/zh-Hant.lproj/Localizable.strings

@@ -280,3 +280,5 @@
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "檢測到您的生成頻率過高,您可能是機器人,請明日再來";
 "We've detected unusually high generation activity. You may be a bot. Please try again tomorrow." = "檢測到您的生成頻率過高,您可能是機器人,請明日再來";
 "Got it" = "知道了";
 "Got it" = "知道了";
 "Aspect Ratio" = "寬高比";
 "Aspect Ratio" = "寬高比";
+
+"The activity has expired, come next time" = "活動結束,下次再來";

+ 2 - 2
Podfile.lock

@@ -137,8 +137,8 @@ SPEC CHECKSUMS:
   SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
   SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
   SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
   SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
   SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
   SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
-  TSSmalCoacopods: 6aa97167f0c76b16fc7d1fd1eb198bb6aece4f68
+  TSSmalCoacopods: b168e4c8870d2c5593476237ac94ebe2e7de492a
 
 
 PODFILE CHECKSUM: 2b99c499d2d0b8510ec7508631defa3f2e7debab
 PODFILE CHECKSUM: 2b99c499d2d0b8510ec7508631defa3f2e7debab
 
 
-COCOAPODS: 1.16.2
+COCOAPODS: 1.15.2