瀏覽代碼

数据迁移开发完毕

100Years 1 月之前
父節點
當前提交
ae0b893a58
共有 27 個文件被更改,包括 786 次插入562 次删除
  1. 16 4
      AIEmoji.xcodeproj/project.pbxproj
  2. 1 8
      AIEmoji/AppDelegate.swift
  3. 1 0
      AIEmoji/Business/Data/TSBaseHistoryManager.swift
  4. 259 0
      AIEmoji/Business/Data/TSDBHistoryManager.swift
  5. 0 315
      AIEmoji/Business/Data/TSUserDefaultData.swift
  6. 13 1
      AIEmoji/Business/LaunchVC/TSLaunchVC.swift
  7. 1 1
      AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/TSAIExpandImageVC.swift
  8. 2 0
      AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseCell.swift
  9. 20 18
      AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVC.swift
  10. 0 43
      AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVM.swift
  11. 6 6
      AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift
  12. 3 3
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift
  13. 167 0
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSDBActionInfoModel.swift
  14. 167 27
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift
  15. 2 2
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiCollectionViewModel.swift
  16. 3 42
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiViewModel.swift
  17. 36 38
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift
  18. 15 5
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/VM/TSPTPInputVM.swift
  19. 1 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/VM/TSPhotoToPhotoVM.swift
  20. 3 1
      AIEmoji/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift
  21. 1 1
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/VM/TSTTPInputVM.swift
  22. 2 2
      AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift
  23. 14 39
      AIEmoji/Common/TSRealmManager/TSRealmManager.swift
  24. 45 0
      AIEmoji/Common/Tool/MemoryLeakChecker.swift
  25. 1 2
      AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift
  26. 1 1
      Podfile
  27. 6 2
      Podfile.lock

+ 16 - 4
AIEmoji.xcodeproj/project.pbxproj

@@ -104,6 +104,7 @@
 		A82D609B2DB9D83600596190 /* TSBaseHistoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D609A2DB9D83500596190 /* TSBaseHistoryManager.swift */; };
 		A82D609E2DBA0FEA00596190 /* TSAppBtnView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D609D2DBA0FE300596190 /* TSAppBtnView.swift */; };
 		A82D60A02DBA1B0500596190 /* TSImageGenerateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D609F2DBA1B0400596190 /* TSImageGenerateView.swift */; };
+		A82D60A92DBB9A6300596190 /* TSDBActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60A82DBB9A5E00596190 /* TSDBActionInfoModel.swift */; };
 		A83404C82D9BEC0E00C140E4 /* UIFont+TSEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83404C72D9BEC0700C140E4 /* UIFont+TSEx.swift */; };
 		A83404CC2D9BEED800C140E4 /* Poppins-BlackItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A83404CB2D9BEED800C140E4 /* Poppins-BlackItalic.ttf */; };
 		A83404D12D9D16FA00C140E4 /* TSAIPhotoGeneratorBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83404D02D9D16F800C140E4 /* TSAIPhotoGeneratorBaseVC.swift */; };
@@ -131,6 +132,7 @@
 		A87587122D81702700286A66 /* TSUserDefaultData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87587102D81702700286A66 /* TSUserDefaultData.swift */; };
 		A87587162D81734300286A66 /* text_to_photo_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A87587152D81733C00286A66 /* text_to_photo_style.json */; };
 		A87587182D81814500286A66 /* TSAIThinkingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87587172D81812C00286A66 /* TSAIThinkingView.swift */; };
+		A88508882DBCD944000FBCEC /* MemoryLeakChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A88508872DBCD940000FBCEC /* MemoryLeakChecker.swift */; };
 		A899D34A2D827A0E00AB9C1C /* TSChatThinkingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A899D3492D8279FB00AB9C1C /* TSChatThinkingModel.swift */; };
 		A89EA64B2D59A588000EB181 /* MessageKit in Frameworks */ = {isa = PBXBuildFile; productRef = A89EA64A2D59A588000EB181 /* MessageKit */; };
 		A89EA6542D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */; };
@@ -178,6 +180,7 @@
 		A8BA76722DA65A95000B6707 /* TSAIUploadPhotoBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76712DA65A94000B6707 /* TSAIUploadPhotoBaseVC.swift */; };
 		A8BA76752DA67E66000B6707 /* TSAIListHistoryBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76742DA67E65000B6707 /* TSAIListHistoryBaseVC.swift */; };
 		A8BA76772DA68619000B6707 /* TSAIListHistoryBaseVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76762DA68617000B6707 /* TSAIListHistoryBaseVM.swift */; };
+		A8BE26E82DBC6A9F00A1DD18 /* TSDBHistoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BE26E72DBC6A9700A1DD18 /* TSDBHistoryManager.swift */; };
 		A8D638352DB10BAC00A96C0E /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D638342DB10BAB00A96C0E /* CrashReporter.swift */; };
 		A8D6383C2DB1FC8D00A96C0E /* TSAIListVideoPlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D6383B2DB1FC8A00A96C0E /* TSAIListVideoPlayerVC.swift */; };
 		A8D638472DB21FAD00A96C0E /* TSBusinessFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D638452DB21FAD00A96C0E /* TSBusinessFileManager.swift */; };
@@ -221,7 +224,7 @@
 		A8F775452D39347100AA6E93 /* TSSetingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775442D39346700AA6E93 /* TSSetingViewModel.swift */; };
 		A8F775492D3935D600AA6E93 /* TSBusinessWebVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775472D3935D600AA6E93 /* TSBusinessWebVC.swift */; };
 		A8F7754B2D39376800AA6E93 /* TSSettingListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7754A2D39376700AA6E93 /* TSSettingListView.swift */; };
-		A8F7754E2D39E59100AA6E93 /* TSGenmojiModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7754D2D39E58B00AA6E93 /* TSGenmojiModel.swift */; };
+		A8F7754E2D39E59100AA6E93 /* TSActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7754D2D39E58B00AA6E93 /* TSActionInfoModel.swift */; };
 		A8F775502D39ECED00AA6E93 /* PhotoManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7754F2D39ECED00AA6E93 /* PhotoManager.swift */; };
 		A8F776212D3A3F0200AA6E93 /* TSEmojisChildVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F776202D3A3F0100AA6E93 /* TSEmojisChildVC.swift */; };
 		A8F7762B2D3A70B200AA6E93 /* PaddedLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7762A2D3A70AF00AA6E93 /* PaddedLabel.swift */; };
@@ -351,6 +354,7 @@
 		A82D609A2DB9D83500596190 /* TSBaseHistoryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseHistoryManager.swift; sourceTree = "<group>"; };
 		A82D609D2DBA0FE300596190 /* TSAppBtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAppBtnView.swift; sourceTree = "<group>"; };
 		A82D609F2DBA1B0400596190 /* TSImageGenerateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSImageGenerateView.swift; sourceTree = "<group>"; };
+		A82D60A82DBB9A5E00596190 /* TSDBActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBActionInfoModel.swift; sourceTree = "<group>"; };
 		A83404C72D9BEC0700C140E4 /* UIFont+TSEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+TSEx.swift"; sourceTree = "<group>"; };
 		A83404CB2D9BEED800C140E4 /* Poppins-BlackItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Poppins-BlackItalic.ttf"; sourceTree = "<group>"; };
 		A83404D02D9D16F800C140E4 /* TSAIPhotoGeneratorBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoGeneratorBaseVC.swift; sourceTree = "<group>"; };
@@ -398,6 +402,7 @@
 		A87587102D81702700286A66 /* TSUserDefaultData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSUserDefaultData.swift; sourceTree = "<group>"; };
 		A87587152D81733C00286A66 /* text_to_photo_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = text_to_photo_style.json; sourceTree = "<group>"; };
 		A87587172D81812C00286A66 /* TSAIThinkingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIThinkingView.swift; sourceTree = "<group>"; };
+		A88508872DBCD940000FBCEC /* MemoryLeakChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryLeakChecker.swift; sourceTree = "<group>"; };
 		A899D3492D8279FB00AB9C1C /* TSChatThinkingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatThinkingModel.swift; sourceTree = "<group>"; };
 		A89EA64C2D59A9F4000EB181 /* CustomMessageFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageFlowLayout.swift; sourceTree = "<group>"; };
 		A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLayoutSizeCalculator.swift; sourceTree = "<group>"; };
@@ -446,6 +451,7 @@
 		A8BA76712DA65A94000B6707 /* TSAIUploadPhotoBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUploadPhotoBaseVC.swift; sourceTree = "<group>"; };
 		A8BA76742DA67E65000B6707 /* TSAIListHistoryBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryBaseVC.swift; sourceTree = "<group>"; };
 		A8BA76762DA68617000B6707 /* TSAIListHistoryBaseVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryBaseVM.swift; sourceTree = "<group>"; };
+		A8BE26E72DBC6A9700A1DD18 /* TSDBHistoryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBHistoryManager.swift; sourceTree = "<group>"; };
 		A8D638342DB10BAB00A96C0E /* CrashReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporter.swift; sourceTree = "<group>"; };
 		A8D6383B2DB1FC8A00A96C0E /* TSAIListVideoPlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListVideoPlayerVC.swift; sourceTree = "<group>"; };
 		A8D638452DB21FAD00A96C0E /* TSBusinessFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBusinessFileManager.swift; sourceTree = "<group>"; };
@@ -491,7 +497,7 @@
 		A8F775442D39346700AA6E93 /* TSSetingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSSetingViewModel.swift; sourceTree = "<group>"; };
 		A8F775472D3935D600AA6E93 /* TSBusinessWebVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBusinessWebVC.swift; sourceTree = "<group>"; };
 		A8F7754A2D39376700AA6E93 /* TSSettingListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSSettingListView.swift; sourceTree = "<group>"; };
-		A8F7754D2D39E58B00AA6E93 /* TSGenmojiModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenmojiModel.swift; sourceTree = "<group>"; };
+		A8F7754D2D39E58B00AA6E93 /* TSActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSActionInfoModel.swift; sourceTree = "<group>"; };
 		A8F7754F2D39ECED00AA6E93 /* PhotoManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoManager.swift; sourceTree = "<group>"; };
 		A8F776202D3A3F0100AA6E93 /* TSEmojisChildVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSEmojisChildVC.swift; sourceTree = "<group>"; };
 		A8F7762A2D3A70AF00AA6E93 /* PaddedLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddedLabel.swift; sourceTree = "<group>"; };
@@ -1238,6 +1244,7 @@
 		A87587112D81702700286A66 /* Data */ = {
 			isa = PBXGroup;
 			children = (
+				A8BE26E72DBC6A9700A1DD18 /* TSDBHistoryManager.swift */,
 				A82D609A2DB9D83500596190 /* TSBaseHistoryManager.swift */,
 				A87587102D81702700286A66 /* TSUserDefaultData.swift */,
 			);
@@ -1620,6 +1627,7 @@
 		A8F774CE2D38EA8C00AA6E93 /* Tool */ = {
 			isa = PBXGroup;
 			children = (
+				A88508872DBCD940000FBCEC /* MemoryLeakChecker.swift */,
 				A82D60932DB9D45900596190 /* OperationQueue */,
 				A8D638452DB21FAD00A96C0E /* TSBusinessFileManager.swift */,
 				A8D638462DB21FAD00A96C0E /* TSDownloadManager.swift */,
@@ -1780,7 +1788,8 @@
 		A8F7754C2D39E57B00AA6E93 /* Model */ = {
 			isa = PBXGroup;
 			children = (
-				A8F7754D2D39E58B00AA6E93 /* TSGenmojiModel.swift */,
+				A82D60A82DBB9A5E00596190 /* TSDBActionInfoModel.swift */,
+				A8F7754D2D39E58B00AA6E93 /* TSActionInfoModel.swift */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -2159,6 +2168,7 @@
 				A80EDD4D2D6C3F82003CD332 /* MarkdownStrikethrough.swift in Sources */,
 				A80EDD4E2D6C3F82003CD332 /* MarkdownUnescaping.swift in Sources */,
 				A80EDD4F2D6C3F82003CD332 /* MarkdownParser+UIKit.swift in Sources */,
+				A88508882DBCD944000FBCEC /* MemoryLeakChecker.swift in Sources */,
 				A8F4134A2DA75863001E715A /* TSUploadPhotoPrivacyAlertVC.swift in Sources */,
 				A80EDD502D6C3F82003CD332 /* MarkdownFont+Traits.swift in Sources */,
 				A80EDD512D6C3F82003CD332 /* MarkdownCode.swift in Sources */,
@@ -2195,7 +2205,7 @@
 				A80EDD632D6C3F82003CD332 /* MarkdownAutomaticLink.swift in Sources */,
 				A80EDD642D6C3F82003CD332 /* MarkdownStyle.swift in Sources */,
 				A89EA6CF2D6430F3000EB181 /* TSChatViewController+Keyboard.swift in Sources */,
-				A8F7754E2D39E59100AA6E93 /* TSGenmojiModel.swift in Sources */,
+				A8F7754E2D39E59100AA6E93 /* TSActionInfoModel.swift in Sources */,
 				A8F776452D3DE8A800AA6E93 /* TSSmallIconBrowseVC.swift in Sources */,
 				A80E72632D40925000C64288 /* TSDiyKeyboardVM.swift in Sources */,
 				A8F775432D39346400AA6E93 /* TSSetingModel.swift in Sources */,
@@ -2218,6 +2228,7 @@
 				A80E722F2D3F3E1400C64288 /* TSDiyCanvasView.swift in Sources */,
 				A8F4134E2DA75E9E001E715A /* TSAboutDataVC.swift in Sources */,
 				A80E72672D409C7D00C64288 /* Template+More.swift in Sources */,
+				A82D60A92DBB9A6300596190 /* TSDBActionInfoModel.swift in Sources */,
 				A82D609E2DBA0FEA00596190 /* TSAppBtnView.swift in Sources */,
 				A82D608B2DB9CE7E00596190 /* MXParallaxHeader+Ex.swift in Sources */,
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
@@ -2279,6 +2290,7 @@
 				A89EA66C2D59AA31000EB181 /* TSMessageContentCell.swift in Sources */,
 				A87587122D81702700286A66 /* TSUserDefaultData.swift in Sources */,
 				A8BA76422DA4C924000B6707 /* TSPTPInputVM.swift in Sources */,
+				A8BE26E82DBC6A9F00A1DD18 /* TSDBHistoryManager.swift in Sources */,
 				A8D6383C2DB1FC8D00A96C0E /* TSAIListVideoPlayerVC.swift in Sources */,
 				A89EA66D2D59AA31000EB181 /* TableViewCells.swift in Sources */,
 				A8BA76472DA4CC70000B6707 /* TSPTPSelectStyleView.swift in Sources */,

+ 1 - 8
AIEmoji/AppDelegate.swift

@@ -18,14 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         window?.backgroundColor = UIColor.black
         window?.makeKeyAndVisible()
         initPlatform()
-        //首次安装需要等待网络权限弹窗
-        if AppDelegate.isFirstInstallApp() {
-            goToLoadVC()
-        }else{
-            PurchaseManager.default.requestProducts()
-            JudgmentSkipPage()
-        }
-
+        goToLoadVC()
         return true
     }
 

+ 1 - 0
AIEmoji/Business/Data/TSBaseHistoryManager.swift

@@ -6,6 +6,7 @@
 //
 
 import ObjectMapper
+
 // MARK: - 基础历史记录类
 class TSBaseHistoryManager<ModelType: TSBaseModel> {
     // 子类必须重写的属性

+ 259 - 0
AIEmoji/Business/Data/TSDBHistoryManager.swift

@@ -0,0 +1,259 @@
+//
+//  TSDBHistoryManager.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/25.
+//
+
+
+
+import RealmSwift
+import ObjectMapper
+
+// 1. 定义历史记录类型枚举
+enum TSDBHistoryType: String,CaseIterable {
+    case ptp = "photoToPhotoHistoryListString"  //图生图
+    case ttp = "textPicHistoryListString"       //文生图
+    case ttEnmoji = "enmojiHistoryListString"   //文生表情
+
+    case pretty = "kTSAIPhotoPrettyHistoryListString"   //美容
+    case oldAge = "kTSChangeOldAgeHistoryListString"   //变老
+    case babyAge = "kTSChangeBabyAgeHistoryListString"   //变年轻
+    case oldPhoto = "kTSChangeOldPhotoHistoryListString"   //旧照片修复
+    case openEyes = "kTSAIEyeOpenHistoryListString"   //睁眼
+    case photoLive = "kTSAIPhotoLiveHistoryListString"   //活照片
+    case photoExpand = "kTSAIPhotoExpandHistoryListString"   //照片扩展
+}
+
+
+//MARK: TSDBAIChatList - 用于存储会话及消息列表
+class TSDBHistory: Object {
+    @Persisted(primaryKey: true) var primaryKey: String = ""
+    @Persisted var listModels = List<TSDBActionInfoModel>()
+    
+    var type: TSDBHistoryType {
+        get { TSDBHistoryType(rawValue: primaryKey) ?? .ptp }
+        set { primaryKey = newValue.rawValue }
+    }
+    
+    convenience init(type: TSDBHistoryType) {
+        self.init()
+        self.primaryKey = type.rawValue
+    }
+    
+    
+    //获取 App 层的 TSChatMessage 数组
+    func getModelList() -> [TSActionInfoModel] {
+        var msgModel:[TSActionInfoModel] = []
+        for msgDBModel in listModels {
+            msgModel.append(msgDBModel.getModel())
+        }
+        return msgModel
+    }
+    
+    //获取 App 层的 TSChatMessage 数组
+    func getModelList(count:Int) -> [TSActionInfoModel] {
+        let listModels = Array(listModels.prefix(count))
+        var msgModel:[TSActionInfoModel] = []
+        for msgDBModel in listModels {
+            msgModel.append(msgDBModel.getModel())
+        }
+        return msgModel
+    }
+    
+    func delete() {
+        TSRMShared.delete(self)
+    }
+    
+    func deleteListModel(id:Int) {
+        TSRMShared.writeThread {
+            if let dbModel = listModels.first(where: { $0.id == id }) {
+                TSRMShared.realm.delete(dbModel)
+            }
+        }
+    }
+    
+    static func deleteAll() {
+        do {
+            let realm = try Realm()
+            try realm.write {
+                let allPersons = realm.objects(TSDBHistory.self)
+                realm.delete(allPersons)
+            }
+        } catch {
+            print("删除 TSDBPTPHistory 模型数据时出错: \(error)")
+        }
+    }
+    
+    func updateData(_ actionInfoModel:TSActionInfoModel,id:Int? = nil){
+            let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: actionInfoModel)
+            var replaceID = dbModel.id
+            if let id = id {
+                replaceID = id
+            }
+            
+            let frozenList = self.listModels.freeze()
+            if let index = frozenList.firstIndex(where: { $0.id == replaceID }) {
+                TSRMShared.writeThread {
+                    listModels[index] = dbModel// 如果找到,替换该元素
+                }
+            } else {
+                TSRMShared.writeThread {
+                    listModels.insert(dbModel, at: 0)// 如果没有找到,添加到末尾
+                }
+            }
+    }
+    
+    func updateDatas(_ actionInfoModels:[TSActionInfoModel]){
+        for actionInfoModel in actionInfoModels {
+            updateData(actionInfoModel)
+        }
+    }
+}
+
+
+extension TSDBHistory {
+    //是否需要迁移历史记录
+    static var isMigrationUserDefaultsHistory:Bool{
+        for type in TSDBHistoryType.allCases {
+            if let _ = UserDefaults.standard.string(forKey: type.rawValue){
+                debugPrint("需要迁移\(type.rawValue)")
+                return true
+            }
+        }
+        return false
+    }
+
+    static func migrationUserDefaultsHistory(complete:@escaping ()->Void){
+        DispatchQueue.global(qos: .userInitiated).async {
+            for type in TSDBHistoryType.allCases {
+                if let historyString = UserDefaults.standard.string(forKey: type.rawValue){
+                    if let models = Mapper<TSActionInfoModel>().mapArray(JSONString: historyString) {
+                        debugPrint("TSDBHistory 需要迁移\(type.rawValue)\(models.count)条")
+                        let dbHistory = TSRMShared.getDBHistory(type:type)
+                        dbHistory.updateDatas(models)
+                        debugPrint("TSDBHistory 迁移完毕\(type.rawValue)")
+                        UserDefaults.standard.set(nil, forKey: type.rawValue)
+                        UserDefaults.standard.synchronize()
+                    }
+                }
+            }
+            DispatchQueue.main.async {
+                complete()
+            }
+        }
+    }
+}
+
+
+extension TSRealmManager {
+    func getDBHistory(type:TSDBHistoryType) -> TSDBHistory {
+        let predicate = NSPredicate(format: "primaryKey == %@",type.rawValue)
+        let historys = TSRMShared.realm.objects(TSDBHistory.self).filter(predicate)
+        if let history = historys.first {
+            return history
+        }else {
+            let dbHistory = TSDBHistory(type: type)
+            TSRMShared.update(dbHistory)
+            return dbHistory
+        }
+    }
+    
+    func createExampleModel(id:Int,imageName:String)->TSActionInfoModel{
+        let model = TSActionInfoModel()
+        model.id = id
+        model.modelType = .example
+        model.request.prompt = "Example"
+        model.request.promptSort = "Example"
+        model.request.width = 330
+        model.request.height = 440
+        model.response.resultUrl = imageName
+        model.status = "success"
+        return model
+    }
+    
+    //测试 5万条数据
+    func textPtpDBHistory(){
+        DispatchQueue.global(qos: .userInteractive).async {
+            let id = Date.timestampInt
+            var array:[TSDBActionInfoModel] = []
+            debugPrint("创建 5万条数据 前")
+            for i in 0...50000 {
+                let dbModel = TSDBActionInfoModel.createDBModel(actionInfoModel: self.createExampleModel(id:id+i, imageName: "ptp_example_image0"))
+                array.append(dbModel)
+            }
+            debugPrint("创建 5万条数据 后")
+            
+            TSRMShared.writeThread {
+                debugPrint("写入 5万条数据")
+//                TSRMShared.photoExpandDBHistory.listModels.append(objectsIn: array)
+                TSRMShared.ptpDBHistory.listModels.append(objectsIn: array)
+                debugPrint("写完 5万条数据")
+            }
+        }
+    }
+    
+    //图生图
+    var ptpDBHistory:TSDBHistory {
+        let ptpHistory = getDBHistory(type: TSDBHistoryType.ptp)
+        
+        if ptpHistory.listModels.count == 0,UserDefaults.standard.string(forKey: "insertPTPExampleData") == nil {
+            let id = Date.timestampInt
+            ptpHistory.updateDatas([
+                createExampleModel(id:id, imageName: "ptp_example_image0"),
+                createExampleModel(id:id+1, imageName: "ptp_example_image1")
+            ])
+            UserDefaults.standard.set("1", forKey: "insertPTPExampleData")
+            UserDefaults.standard.synchronize()
+        }
+        
+        return ptpHistory
+    }
+    
+    //文生图
+    var ttpDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.ttp)
+    }
+
+    //文生表情
+    var ttEnmojiDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.ttEnmoji)
+    }
+
+    //美容
+    var oldAgeDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.oldAge)
+    }
+    
+    //变老
+    var prettyDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.pretty)
+    }
+    
+    //变年轻
+    var babyAgeDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.babyAge)
+    }
+    
+    //老照片修复
+    var oldPhotoDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.oldPhoto)
+    }
+    
+    //睁眼
+    var openEyesDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.openEyes)
+    }
+    
+    //活照片
+    var photoLiveDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.photoLive)
+    }
+    
+    //扩图
+    var photoExpandDBHistory:TSDBHistory {
+        return getDBHistory(type: TSDBHistoryType.photoExpand)
+    }
+
+}
+

+ 0 - 315
AIEmoji/Business/Data/TSUserDefaultData.swift

@@ -33,318 +33,3 @@ func getUserInfoJsonString()->String {
     
     return ""
 }
-
-func kHandleTSHistory(){
-
-    for model in TSPTPHistory.shared.listModels {
-        if model.modelType != .example {
-            switch model.actionStatus {
-            case .running:
-                TSGeneratePTPOperationQueue.shared.creatOperation(uuid: model.uuid).getActionInfo(oldModel: model)
-            default:break
-            }
-        }
-    }
-}
-
-
-// MARK: - 图生图
-final class TSPTPHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSPTPHistory()
-    override var historyKey: String { "photoToPhotoHistoryListString" }
-    override var exampleDataKey: String { "insertPTPExampleData" }
-    
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        [
-            createExampleModel(imageName: "ptp_example_image0"),
-            createExampleModel(imageName: "ptp_example_image1")
-        ]
-    }
-    
-    func createExampleModel(imageName:String)->TSActionInfoModel{
-        let model = TSActionInfoModel()
-        model.modelType = .example
-        model.request.prompt = "Example"
-        model.request.promptSort = "Example"
-        model.request.width = 330
-        model.request.height = 440
-        model.response.resultUrl = imageName
-        return model
-    }
-    
-    
-    func insTestData(){
-        var array:[TSActionInfoModel] = []
-        debugPrint("array.count = \(array.count)")
-        for i in 0...20000 {
-            array.append(createExampleModel(imageName: "ptp_example_image0"))
-        }
-        debugPrint("array.count = \(array.count)")
-        
-        debugPrint("listModels.count = \(listModels.count)")
-        listModels.append(contentsOf: array)
-        debugPrint("listModels.count = \(listModels.count)")
-        
-        debugPrint("saveHistory 前")
-        saveHistory()
-        debugPrint("saveHistory 后")
-    }
-}
-
-
-
-// MARK: - 新的储存方法
-// MARK: - 变老
-final class TSChangeOldAgeHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSChangeOldAgeHistory()
-    override var historyKey: String { "kTSChangeOldAgeHistoryListString" }
-//    override var exampleDataKey: String { "insertPosterExampleData" }
-    
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-//
-//    private func createExampleModel(imageName: String) -> TSActionInfoModel {
-//        let model = TSActionInfoModel()
-//        model.modelType = .example
-//        model.request.prompt = "Example"
-//        model.request.promptSort = "Example"
-//        model.response.resultUrl = imageName
-//        return model
-//    }
-}
-
-// MARK: - 变年轻
-final class TSChangeBabyAgeHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSChangeBabyAgeHistory()
-    override var historyKey: String { "kTSChangeBabyAgeHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-}
-
-// MARK: - 旧照片修复
-final class TSChangeOldPhotoHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSChangeOldPhotoHistory()
-    override var historyKey: String { "kTSChangeOldPhotoHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-}
-
-// MARK: - 睁眼
-final class TSAIEyeOpenHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSAIEyeOpenHistory()
-    override var historyKey: String { "kTSAIEyeOpenHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-}
-
-// MARK: - 美容
-final class TSAIPhotoPrettyHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSAIPhotoPrettyHistory()
-    override var historyKey: String { "kTSAIPhotoPrettyHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-}
-
-// MARK: - 照片变活
-final class TSAIPhotoLiveHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSAIPhotoLiveHistory()
-    override var historyKey: String { "kTSAIPhotoLiveHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-}
-
-
-// MARK: - 照片扩展
-final class TSAIPhotoExpandHistory: TSBaseHistoryManager<TSActionInfoModel> {
-    static let shared = TSAIPhotoExpandHistory()
-    override var historyKey: String { "kTSAIPhotoExpandHistoryListString" }
-    
-    override var exampleModels: [TSActionInfoModel] {
-        []
-    }
-    override func findModelID(modelID: Int) -> Int? {
-        return listModels.firstIndex(where: {$0.id == modelID})
-    }
-    
-    func insTestData(){
-        var array:[TSActionInfoModel] = []
-        debugPrint("array.count = \(array.count)")
-        for i in 0...20000 {
-            array.append(createExampleModel(imageName: "ptp_example_image0"))
-        }
-        debugPrint("array.count = \(array.count)")
-        
-        debugPrint("listModels.count = \(listModels.count)")
-        listModels.append(contentsOf: array)
-        debugPrint("listModels.count = \(listModels.count)")
-        
-        debugPrint("saveHistory 前")
-        saveHistory()
-        debugPrint("saveHistory 后")
-    }
-    
-    func createExampleModel(imageName:String)->TSActionInfoModel{
-        let model = TSActionInfoModel()
-        model.modelType = .example
-        model.request.prompt = "Example"
-        model.request.promptSort = "Example"
-        model.request.width = 330
-        model.request.height = 440
-        model.response.resultUrl = imageName
-        return model
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// MARK: - 旧的储存方法
-//海报历史记录
-class TSTextToPicHistory{
-    @UserDefault(key: "textPicHistoryListString", defaultValue: "")
-    static private var historyString: String
-    static var listModelArray: [TSActionInfoModel] = {
-        
-//        if UserDefaults.standard.string(forKey: "insertPosterExampleData") == nil {
-//            insertExampleData()
-//            UserDefaults.standard.set("1", forKey: "insertPosterExampleData")
-//            UserDefaults.standard.synchronize()
-//        }
-        
-        if let listModelArray = Mapper<TSActionInfoModel>().mapArray(JSONString: historyString){
-            return listModelArray
-        }
-        return []
-    }()
-    
-    static func saveModel(model:TSActionInfoModel){
-        listModelArray.insert(model, at: 0)
-        saveHistoryString()
-    }
-    
-    static func removeModel(model:TSActionInfoModel){
-        listModelArray.removeAll { $0 === model }
-        saveHistoryString()
-    }
-    
-    static func removeIndex(index:Int){
-        listModelArray.remove(at: index)
-        saveHistoryString()
-    }
-    
-    static func removeAll(){
-        listModelArray.removeAll()
-        saveHistoryString()
-    }
-    
-    static func saveHistoryString(){
-        if let jsonString = listModelArray.toJSONString() {
-            historyString = jsonString
-        }
-    }
-    
-//    private static func insertExampleData(){
-//        let array = [
-//            createExampleModel(imageName: "poster_example_0"),
-//            createExampleModel(imageName: "poster_example_1"),
-//            createExampleModel(imageName: "poster_example_2")
-//        ]
-//        if let jsonString = array.toJSONString() {
-//            historyString = jsonString
-//        }
-//    }
-    
-//    private static func createExampleModel(imageName:String)->TSActionInfoModel{
-//        let model = TSActionInfoModel()
-//        model.modelType = .example
-//        model.request.prompt = "Example"
-//        model.request.promptSort = "Example"
-//        model.request.width = kTextPicW
-//        model.request.height = kTextPicH
-//        model.response.resultUrl = imageName
-//        return model
-//    }
-}
-

+ 13 - 1
AIEmoji/Business/LaunchVC/TSLaunchVC.swift

@@ -23,6 +23,19 @@ class TSLaunchVC: UIViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         setupLaunchScreenView()
+        addNotifiy()
+        
+        if AppDelegate.isFirstInstallApp() {//首次安装需要等待网络权限弹窗
+            startTimer()
+        }else if TSDBHistory.isMigrationUserDefaultsHistory{ //迁移UserDefaultsHistory数据到数据库
+            TSDBHistory.migrationUserDefaultsHistory {
+                self.enterApp()
+            }
+        }else {
+            self.enterApp()
+        }
+
+        
         startTimer()
         addNotifiy()
     }
@@ -71,7 +84,6 @@ class TSLaunchVC: UIViewController {
                 // App活跃时,计时有效;如网络授权弹窗唤起时,计时失效
                 DispatchQueue.main.async {
                     guard let self = self  else {
-                        
                         return
                     }
                     

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/TSAIExpandImageVC.swift

@@ -239,6 +239,6 @@ extension TSAIExpandImageVC {
     }
     
     func saveModel(model:TSActionInfoModel){
-        TSAIPhotoExpandHistory.shared.saveModel(model: model)
+        TSRMShared.photoExpandDBHistory.updateData(model)
     }
 }

+ 2 - 0
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseCell.swift

@@ -11,6 +11,7 @@ class TSAIListHistoryBaseCell: TSBaseCollectionCell,TSSimpleConfigurableView {
     var indexPath: IndexPath?
     var data: Any? {
         didSet {
+            debugPrint("TSAIListHistoryBaseCell data didSet")
             if let dataModel = data as? TSActionInfoModel{
                 videoIconImageView.isHidden = true
                 exampleView.isHidden = true
@@ -67,6 +68,7 @@ class TSAIListHistoryBaseCell: TSBaseCollectionCell,TSSimpleConfigurableView {
     
     
     override func creatUI() {
+        debugPrint("TSAIListHistoryBaseCell creatUI")
         contentView.addSubview(showImageView)
         showImageView.snp.makeConstraints { make in
             make.top.equalTo(0)

+ 20 - 18
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVC.swift

@@ -17,8 +17,9 @@ class TSAIListHistoryBaseVC: TSBaseVC {
         fatalError("init(coder:) has not been implemented")
     }
     
-    private let kPTPHistoryW = (k_ScreenWidth-32.0-12.0-2)/2.0
-    
+    lazy var listModelArray: [TSActionInfoModel] = {
+        return getlistModelArray
+    }()
     //###################################### 集合视图 ######################################
     let collectionViewBtootm:CGFloat = 80
     lazy var collectionView: TSSimpleCollectionView = {
@@ -51,6 +52,7 @@ class TSAIListHistoryBaseVC: TSBaseVC {
     override func createData() {
         
     }
+    
     var navRightBtn = UIButton()
     override func createView() {
         
@@ -80,7 +82,7 @@ class TSAIListHistoryBaseVC: TSBaseVC {
     }
     
     func updateView() {
-        collectionView.reload(with: [listModelArray])
+        collectionView.reload(with:[TSSimpleSectionData(items: listModelArray)])
         
         navRightBtn.isHidden = listModelArray.count <= 0
         pageNullView.isHidden = listModelArray.count > 0
@@ -115,38 +117,38 @@ extension TSAIListHistoryBaseVC{
     func removeAllHistoryList(){
         switch generatorStyle {
         case .ageOld:
-            TSChangeOldAgeHistory.shared.removeALLModel()
+            TSRMShared.oldAgeDBHistory.delete()
         case .ageChild:
-            TSChangeBabyAgeHistory.shared.removeALLModel()
+            TSRMShared.babyAgeDBHistory.delete()
         case .oldPhoto:
-            TSChangeOldPhotoHistory.shared.removeALLModel()
+            TSRMShared.oldPhotoDBHistory.delete()
         case .eyeOpen:
-            TSAIEyeOpenHistory.shared.removeALLModel()
+            TSRMShared.openEyesDBHistory.delete()
         case .pretty:
-            TSAIPhotoPrettyHistory.shared.removeALLModel()
+            TSRMShared.prettyDBHistory.delete()
         case .photoLive:
-            TSAIPhotoLiveHistory.shared.removeALLModel()
+            TSRMShared.photoLiveDBHistory.delete()
         case .photoExpand:
-            TSAIPhotoExpandHistory.shared.removeALLModel()
+            TSRMShared.photoExpandDBHistory.delete()
         }
     }
     
-    var listModelArray:[TSActionInfoModel]{
+    var getlistModelArray:[TSActionInfoModel]{
         switch generatorStyle {
         case .ageOld:
-            TSChangeOldAgeHistory.shared.listModels
+            TSRMShared.oldAgeDBHistory.getModelList()
         case .ageChild:
-            TSChangeBabyAgeHistory.shared.listModels
+            TSRMShared.babyAgeDBHistory.getModelList()
         case .oldPhoto:
-            TSChangeOldPhotoHistory.shared.listModels
+            TSRMShared.oldPhotoDBHistory.getModelList()
         case .eyeOpen:
-            TSAIEyeOpenHistory.shared.listModels
+            TSRMShared.openEyesDBHistory.getModelList()
         case .pretty:
-            TSAIPhotoPrettyHistory.shared.listModels
+            TSRMShared.prettyDBHistory.getModelList()
         case .photoLive:
-            TSAIPhotoLiveHistory.shared.listModels
+            TSRMShared.photoLiveDBHistory.getModelList()
         case .photoExpand:
-            TSAIPhotoExpandHistory.shared.listModels
+            TSRMShared.photoExpandDBHistory.getModelList()
         }
     }
 }

+ 0 - 43
AIEmoji/Business/TSAILIstVC/TSAIListHistoryBaseVC/TSAIListHistoryBaseVM.swift

@@ -8,53 +8,10 @@
 import Alamofire
 import ObjectMapper
 class TSAIListHistoryBaseVM {
-
-
     var generatorStyle:TSGeneratorImageStyle
     init(generatorStyle:TSGeneratorImageStyle) {
         self.generatorStyle = generatorStyle
     }
-    
-    func removeAllHistoryList(){
-        switch generatorStyle {
-        case .ageOld:
-            TSChangeOldAgeHistory.shared.removeALLModel()
-        case .ageChild:
-            TSChangeBabyAgeHistory.shared.removeALLModel()
-        case .oldPhoto:
-            TSChangeOldPhotoHistory.shared.removeALLModel()
-        case .eyeOpen:
-            TSAIEyeOpenHistory.shared.removeALLModel()
-        case .pretty:
-            TSAIPhotoPrettyHistory.shared.removeALLModel()
-        case .photoLive:
-            TSAIPhotoLiveHistory.shared.removeALLModel()
-        case .photoExpand:
-            TSAIPhotoExpandHistory.shared.removeALLModel()
-        }
-    }
-    
 }
  
-extension TSAIListHistoryBaseVM {
-    var listModelArray:[TSActionInfoModel]{
-        switch generatorStyle {
-        case .ageOld:
-            TSChangeOldAgeHistory.shared.listModels
-        case .ageChild:
-            TSChangeBabyAgeHistory.shared.listModels
-        case .oldPhoto:
-            TSChangeOldPhotoHistory.shared.listModels
-        case .eyeOpen:
-            TSAIEyeOpenHistory.shared.listModels
-        case .pretty:
-            TSAIPhotoPrettyHistory.shared.listModels
-        case .photoLive:
-            TSAIPhotoLiveHistory.shared.listModels
-        case .photoExpand:
-            TSAIPhotoExpandHistory.shared.listModels
-        }
-    }
-}
-
 

+ 6 - 6
AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift

@@ -279,17 +279,17 @@ extension TSAIUploadPhotoBaseVC {
     func saveModel(model:TSActionInfoModel){
         switch generatorStyle {
         case .ageOld:
-            TSChangeOldAgeHistory.shared.saveModel(model: model)
+            TSRMShared.oldAgeDBHistory.updateData(model)
         case .ageChild:
-            TSChangeBabyAgeHistory.shared.saveModel(model: model)
+            TSRMShared.babyAgeDBHistory.updateData(model)
         case .oldPhoto:
-            TSChangeOldPhotoHistory.shared.saveModel(model: model)
+            TSRMShared.oldPhotoDBHistory.updateData(model)
         case .eyeOpen:
-            TSAIEyeOpenHistory.shared.saveModel(model: model)
+            TSRMShared.openEyesDBHistory.updateData(model)
         case .pretty:
-            TSAIPhotoPrettyHistory.shared.saveModel(model: model)
+            TSRMShared.prettyDBHistory.updateData(model)
         case .photoLive:
-            TSAIPhotoLiveHistory.shared.saveModel(model: model)
+            TSRMShared.photoLiveDBHistory.updateData(model)
         case .photoExpand:
             dePrint("photoExpand")
         }

+ 3 - 3
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSGenmojiModel.swift → AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/Model/TSActionInfoModel.swift

@@ -9,7 +9,7 @@ import ObjectMapper
 class TSActionInfoModel: TSBaseModel {
     
     enum ModelType:Int {
-        case normal
+        case normal = 0
         case example
     }
     
@@ -81,8 +81,8 @@ extension TSActionInfoModel {
         if request.imageUrlTimestamp <= 0 {
             return true
         }
-        
-        if Date.timestampInt - request.imageUrlTimestamp > 10{//86400 {
+        //86400=24小时
+        if Date.timestampInt - request.imageUrlTimestamp > 86400 {
             return true
         }
         

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

@@ -0,0 +1,167 @@
+//
+//  TSDBActionInfoModel.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/25.
+//
+
+import RealmSwift
+
+class TSDBActionInfoModel: Object {
+ 
+    @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
+    @Persisted var createdAt: Date = Date()
+    
+    @Persisted var modelType:Int = 0
+    @Persisted var id:Int = 0
+    @Persisted var actionType:String = ""
+    @Persisted var comments:String = ""
+    @Persisted var request:TSDBActionRequestModel?
+    @Persisted var response:TSDBActionResponseModel?
+    @Persisted var createdTimestamp:Int = 0
+    @Persisted var status:String = ""
+    @Persisted var costTime:Int = 0
+    @Persisted var percent:Float = 0.0
+    
+    @Persisted var videoThumbnailPath:String = ""
+    @Persisted var videoPath:String = ""
+    @Persisted var uuid:String = UUID().uuidString
+    
+    static func createDBModel(actionInfoModel:TSActionInfoModel) -> TSDBActionInfoModel{
+        let dbModel = TSDBActionInfoModel()
+        dbModel.saveData(infoModel: actionInfoModel)
+        return dbModel
+    }
+    
+    func saveData(infoModel:TSActionInfoModel) {
+        self.modelType = infoModel.modelType.rawValue
+        self.id = infoModel.id
+        self.actionType = infoModel.actionType
+        self.comments = infoModel.comments
+
+        self.createdTimestamp = infoModel.createdTimestamp
+        self.status = infoModel.status
+        self.costTime = infoModel.costTime
+        self.percent = infoModel.percent
+        self.videoThumbnailPath = infoModel.videoThumbnailPath
+        self.videoPath = infoModel.videoPath
+        self.uuid = infoModel.uuid
+        
+        self.request = TSDBActionRequestModel.createDBModel(requestModel: infoModel.request)
+        self.response = TSDBActionResponseModel.createDBModel(responseModel: infoModel.response)
+        
+    }
+    
+    func getModel()->TSActionInfoModel{
+        let infoModel = TSActionInfoModel()
+        
+        infoModel.modelType = TSActionInfoModel.ModelType.init(rawValue: self.modelType) ?? .normal
+        infoModel.id = self.id
+        infoModel.actionType = self.actionType
+        infoModel.comments = self.comments
+
+        infoModel.createdTimestamp = self.createdTimestamp
+        infoModel.status = self.status
+        infoModel.costTime = self.costTime
+        infoModel.percent = self.percent
+        infoModel.videoThumbnailPath = self.videoThumbnailPath
+        infoModel.videoPath = self.videoPath
+        infoModel.uuid = self.uuid
+
+        if let request = self.request {
+            infoModel.request = request.getModel()
+        }
+        
+        if let response = self.response {
+            infoModel.response = response.getModel()
+        }
+        
+        infoModel.actionStatus = TSActionInfoModel.ActionStatus.from(infoModel.status)
+        return infoModel
+    }
+
+}
+
+
+
+class TSDBActionRequestModel : Object {
+    
+    @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
+    @Persisted var createdAt: Date = Date()
+    
+    @Persisted var prompt:String = ""
+    @Persisted var promptSort:String = ""  //用户自己输入的内容
+    @Persisted var width:Int = 0
+    @Persisted var height:Int = 0
+    
+    @Persisted var imageUrl:String = ""
+    @Persisted var imageUrlTimestamp:Int = 0
+    @Persisted var style:String = ""
+    @Persisted var advance:Bool = false
+    
+    static func createDBModel(requestModel:TSActionRequestModel) -> TSDBActionRequestModel{
+        let dbModel = TSDBActionRequestModel()
+        dbModel.saveData(requestModel: requestModel)
+        return dbModel
+    }
+    
+    func saveData(requestModel:TSActionRequestModel) {
+        self.prompt = requestModel.prompt
+        self.promptSort = requestModel.promptSort
+        self.width = requestModel.width
+        self.height = requestModel.height
+        
+        self.imageUrl = requestModel.imageUrl
+        self.imageUrlTimestamp = requestModel.imageUrlTimestamp
+        self.style = requestModel.style
+        self.advance = requestModel.advance
+    }
+    
+    
+    func getModel()->TSActionRequestModel{
+        let model = TSActionRequestModel()
+        model.prompt = self.prompt
+        model.promptSort = self.promptSort
+        model.width = self.width
+        model.height = self.height
+        
+        model.imageUrl = self.imageUrl
+        model.imageUrlTimestamp = self.imageUrlTimestamp
+        model.style = self.style
+        model.advance = self.advance
+        
+        return model
+    }
+
+}
+
+class TSDBActionResponseModel : Object {
+    @Persisted(primaryKey: true) var primaryKey: String = UUID().uuidString
+    @Persisted var createdAt: Date = Date()
+    
+    @Persisted var resultUrl:String = ""
+    @Persisted var code:Int = 0
+    @Persisted var vip:Bool = false
+    
+    static func createDBModel(responseModel:TSActionResponseModel) -> TSDBActionResponseModel{
+        let dbModel = TSDBActionResponseModel()
+        dbModel.saveData(responseModel: responseModel)
+        return dbModel
+    }
+    
+    func saveData(responseModel:TSActionResponseModel) {
+        self.resultUrl = responseModel.resultUrl
+        self.code = responseModel.code
+        self.vip = responseModel.vip
+    }
+    
+    
+    func getModel()->TSActionResponseModel{
+        let model = TSActionResponseModel()
+        model.resultUrl = self.resultUrl
+        model.code = self.code
+        model.vip = self.vip
+        return model
+    }
+    
+}

+ 167 - 27
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift

@@ -5,8 +5,32 @@
 //  Created by 100Years on 2025/1/17.
 //
 
-class TSGenmojiItemCell: TSBaseCollectionCell {
-    var itemModel:TSGenmojiCoLItemModel = TSGenmojiCoLItemModel()
+
+class TSGenmojiItemCell: TSBaseCollectionCell ,TSSimpleConfigurableView {
+    
+    var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
+    var indexPath: IndexPath?
+    var data: Any? {
+        didSet {
+            debugPrint("TSGenmojiItemCell renderView")
+            if let dataModel = data as? TSActionInfoModel{
+                self.dataModel = dataModel
+                self.updataActionInfoModelView(model: dataModel)
+                if let operation = TSGeneratePTPOperationQueue.shared.findOperation(uuid: dataModel.uuid) as? TSGeneratePTPOperation {
+                    DispatchQueue.main.async {
+                        operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
+                            guard let self = self else { return }
+                            DispatchQueue.main.async {
+                                self.updataActionInfoModelView(model: actionInfoModel)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    var dataModel:TSActionInfoModel = TSActionInfoModel()
     lazy var textLabel: UILabel = {
         let textLabel = UILabel.createLabel(
             text: "Example".localized,
@@ -41,17 +65,18 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
         generateView.isHidden = true
         generateView.refreshHandel = { [weak self]  in
             guard let self = self else { return }
-            if itemModel.dataModel.upImageURLExpired { //任务已经过期了
+            if dataModel.upImageURLExpired { //任务已经过期了
                 self.actionHandler(any: "delete_task_expired")
             }else{
                 if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
-                TSGeneratePTPOperationQueue.shared.creatOperation(uuid: itemModel.dataModel.uuid).creatImage(oldModel: itemModel.dataModel)
+                TSGeneratePTPOperationQueue.shared.creatOperation(uuid: dataModel.uuid).creatImage(oldModel: dataModel)
             }
         }
         return generateView
     }()
     
     override func creatUI() {
+        debugPrint("TSGenmojiItemCell creatUI")
         contentView.cornerRadius = 16.0
         contentView.addSubview(showImageView)
         showImageView.snp.makeConstraints { make in
@@ -73,26 +98,6 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
         }
     }
     
-    
-    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
-        super.renderView(with: object, component: component, attributes: attributes)
-        if let itemModel = object as? TSGenmojiCoLItemModel{
-            self.itemModel = itemModel
-            self.updataActionInfoModelView(model: itemModel.dataModel)
-            if let operation = TSGeneratePTPOperationQueue.shared.findOperation(uuid: itemModel.dataModel.uuid) as? TSGeneratePTPOperation {
-                DispatchQueue.main.async {
-                    operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
-                        guard let self = self else { return }
-                        DispatchQueue.main.async {
-                            self.updataActionInfoModelView(model: actionInfoModel)
-                        }
-                    }
-                }
-            }
-        }
-    }
-    
-    
     func updataActionInfoModelView(model:TSActionInfoModel){
         
         if model.modelType == .example {
@@ -107,9 +112,9 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
         case .success:
             generateView.isHidden = true
             
-            if itemModel.dataModel.modelType == .example {
+            if dataModel.modelType == .example {
 
-                if itemModel.style == .ptpPicHistory {
+                if dataModel.modelType == .example {
                     textLabel.text = "Example".localized
                 }
 
@@ -122,7 +127,7 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
             
         case .failed:
             generateView.isHidden = false
-            if itemModel.dataModel.upImageURLExpired { //任务已经过期了
+            if dataModel.upImageURLExpired { //任务已经过期了
                 generateView.setTaskExpired()
             }else{
                 generateView.setFail()
@@ -136,3 +141,138 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
     }
 
 }
+
+
+//class TSGenmojiItemCell: TSBaseCollectionCell {
+//    var itemModel:TSGenmojiCoLItemModel = TSGenmojiCoLItemModel()
+//    lazy var textLabel: UILabel = {
+//        let textLabel = UILabel.createLabel(
+//            text: "Example".localized,
+//            font: .font(size: 12),
+//            textColor: .white
+//        )
+//        return textLabel
+//    }()
+//    
+//    lazy var exampleView: UIView = {
+//        let exampleView = UIView()
+//        exampleView.backgroundColor = "#232323".uiColor.withAlphaComponent(0.3)
+//        
+//        exampleView.addSubview(textLabel)
+//        textLabel.snp.makeConstraints { make in
+//            make.top.edges.equalTo(UIEdgeInsets(top: 4, left: 6, bottom: 4, right: 6))
+//        }
+//        exampleView.isHidden = true
+//        exampleView.cornerRadius = 10.0
+//        return exampleView
+//    }()
+//    
+//    lazy var showImageView: UIImageView = {
+//        let showImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+//        showImageView.backgroundColor = .gray
+//        showImageView.layer.cornerRadius = 18
+//        return showImageView
+//    }()
+//    
+//    lazy var generateView: TSImageGenerateView = {
+//        let generateView = TSImageGenerateView()
+//        generateView.isHidden = true
+//        generateView.refreshHandel = { [weak self]  in
+//            guard let self = self else { return }
+//            if itemModel.dataModel.upImageURLExpired { //任务已经过期了
+//                self.actionHandler(any: "delete_task_expired")
+//            }else{
+//                if kJudgeVipFreeType(vipFreeNumType: .picToPic){ return }
+//                TSGeneratePTPOperationQueue.shared.creatOperation(uuid: itemModel.dataModel.uuid).creatImage(oldModel: itemModel.dataModel)
+//            }
+//        }
+//        return generateView
+//    }()
+//    
+//    override func creatUI() {
+//        debugPrint("TSGenmojiItemCell creatUI")
+//        contentView.cornerRadius = 16.0
+//        contentView.addSubview(showImageView)
+//        showImageView.snp.makeConstraints { make in
+//            make.top.equalTo(0)
+//            make.leading.equalTo(0)
+//            make.trailing.bottom.equalTo(0)
+//        }
+//        
+//        contentView.addSubview(exampleView)
+//        exampleView.snp.makeConstraints { make in
+//            make.top.equalTo(8)
+//            make.leading.equalTo(8)
+//            make.height.equalTo(20)
+//        }
+//        
+//        contentView.addSubview(generateView)
+//        generateView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
+//    }
+//    
+//    
+//    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
+//        super.renderView(with: object, component: component, attributes: attributes)
+//        debugPrint("TSGenmojiItemCell renderView")
+//        if let itemModel = object as? TSGenmojiCoLItemModel{
+//            self.itemModel = itemModel
+//            self.updataActionInfoModelView(model: itemModel.dataModel)
+//            if let operation = TSGeneratePTPOperationQueue.shared.findOperation(uuid: itemModel.dataModel.uuid) as? TSGeneratePTPOperation {
+//                DispatchQueue.main.async {
+//                    operation.currentActionInfoModelChanged = { [weak self] actionInfoModel in
+//                        guard let self = self else { return }
+//                        DispatchQueue.main.async {
+//                            self.updataActionInfoModelView(model: actionInfoModel)
+//                        }
+//                    }
+//                }
+//            }
+//        }
+//    }
+//    
+//    
+//    func updataActionInfoModelView(model:TSActionInfoModel){
+//        
+//        if model.modelType == .example {
+//            model.actionStatus = .success
+//        }
+//        showImageView.image = nil
+////        dePrint("updataActionInfoModelView model.actionStatus 收到 = \(model.actionStatus)")
+//        switch model.actionStatus {
+//        case .pending,.running:
+//            generateView.isHidden = false
+//            generateView.setProgress(progress: model.percent)
+//        case .success:
+//            generateView.isHidden = true
+//            
+//            if itemModel.dataModel.modelType == .example {
+//
+//                if itemModel.style == .ptpPicHistory {
+//                    textLabel.text = "Example".localized
+//                }
+//
+//                exampleView.isHidden = false
+//                showImageView.image = UIImage(named: model.response.resultUrl)
+//            }else{
+//                exampleView.isHidden = true
+//                showImageView.setAsyncImage(urlString: model.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+//            }
+//            
+//        case .failed:
+//            generateView.isHidden = false
+//            if itemModel.dataModel.upImageURLExpired { //任务已经过期了
+//                generateView.setTaskExpired()
+//            }else{
+//                generateView.setFail()
+//            }
+//            
+//        }
+//        
+//        if generateView.isHidden == false {
+//            generateView.setBgImageViewURLString(bgImageURLString: model.request.imageUrl)
+//        }
+//    }
+//
+//}

+ 2 - 2
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiCollectionViewModel.swift

@@ -15,8 +15,8 @@ private let kTextPicHistoryH = kTextPicHistoryW/kTextWHScale
 let kPTPHistoryDesignW = 165.0
 let kPTPHistoryDesignH = 220.0
 let kPTPHistoryDesignScale = kPTPHistoryDesignW/kPTPHistoryDesignH
-private let kPTPHistoryW = (k_ScreenWidth-32.0-14.0)/2.0
-private let kPTPHistoryH = kPTPHistoryW/kPTPHistoryDesignScale
+ let kPTPHistoryW = (k_ScreenWidth-32.0-14.0)/2.0
+ let kPTPHistoryH = kPTPHistoryW/kPTPHistoryDesignScale
 
 
 

+ 3 - 42
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiViewModel.swift

@@ -18,23 +18,11 @@ class TSGenmojiViewModel {
         return generateSectionModel
     }()
     
-    //历史记录
-    @UserDefault(key: "enmojiHistoryListString", defaultValue: "")
-    private var enmojiHistoryListString: String
-    
-    
-    lazy var listModelArray: [TSActionInfoModel] = {
-        if let listModelArray = Mapper<TSActionInfoModel>().mapArray(JSONString: enmojiHistoryListString){
-            return listModelArray
-        }
-        return []
-    }()
-    
     lazy var enmojiHistorySeciton: TSGenmojiCoLSectionModel = {
         let sectionModel = TSGenmojiCoLSectionModel()
         sectionModel.style = .history
         sectionModel.name = "History".localized
-        for model in listModelArray {
+        for model in TSRMShared.ttEnmojiDBHistory.getModelList() {
             let itemModel = TSGenmojiCoLItemModel()
             itemModel.style = sectionModel.style
             itemModel.dataModel = model
@@ -60,31 +48,9 @@ class TSGenmojiViewModel {
 }
  
 extension TSGenmojiViewModel {
-    //历史记录
-    var modelArray:[TSActionInfoModel]{
-        get{
-            let sectionModel = TSGenmojiCoLSectionModel()
-            sectionModel.style = .history
-            sectionModel.name = "History".localized
-        
-            if let modelArray = Mapper<TSActionInfoModel>().mapArray(JSONString: enmojiHistoryListString){
-                return modelArray
-            }
-            return []
-        }
-        set{
-            if let jsonString = newValue.toJSONString() {
-                enmojiHistoryListString = jsonString
-            }
-        }
-    }
-    
     //返回值,是否需要清空后刷新
     func saveModel(model:TSActionInfoModel)->Bool{
-        listModelArray.insert(model, at: 0)
-        if let jsonString = listModelArray.toJSONString() {
-            enmojiHistoryListString = jsonString
-        }
+        TSRMShared.ttEnmojiDBHistory.updateData(model)
         var isNeed = false
         if enmojiHistorySeciton.items.count == 0 {
             colDataArray.append(enmojiHistorySeciton)
@@ -98,13 +64,8 @@ extension TSGenmojiViewModel {
         return isNeed
     }
     
-    
-    
     func removeAllHistoryList(){
-        listModelArray.removeAll()
-        if let jsonString = listModelArray.toJSONString() {
-            enmojiHistoryListString = jsonString
-        }
+        TSRMShared.ttEnmojiDBHistory.delete()
         
         enmojiHistorySeciton.items.removeAll()
         colDataArray.removeLast()

+ 36 - 38
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/TSPTPInputVC.swift

@@ -191,9 +191,7 @@ class TSPTPInputVC: TSBaseVC {
           } else {
               automaticallyAdjustsScrollViewInsets = false
           }
-        
-     
-        
+
         cp.sectionActionHandler = { [weak self] cellCp, indexPath in
             guard let self = self else { return }
             if let cmd = cellCp as? String, cmd == "delete"  {
@@ -209,50 +207,26 @@ class TSPTPInputVC: TSBaseVC {
             guard let self = self else { return }
             //删除过期的任务
             if let cmd = object as? String, cmd == "delete_task_expired"  {
-//                TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
-//                    message: "This task has expired".localized,
-//                    messageColor: .white,
-//                    messageFont: .systemFont(ofSize: 16),
-//                    
-//                    cancelTitle: "Cancel".localized,
-//                    cancelColor: .white,
-//                    
-//                    confirmTitle: "Delete".localized,
-//                    confirmColor: .themeColor,
-//                    
-//                    cancelAction: {},
-//                    confirmAction: {
-                        TSPTPHistory.shared.removeModel(index: indexPath.item)
-                        self.viewModel.updateRecentData()
-                        self.collectionComponent.clear()
-                        self.collectionComponent.reloadView(with: self.viewModel.colDataArray)
-//                    }
-//                ))
-                return
+                if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel,
+                   let currentActionInfoModel = sections.items.safeObj(At: indexPath.item) {
+                    TSRMShared.ptpDBHistory.deleteListModel(id: currentActionInfoModel.dataModel.id)
+                    self.viewModel.updateRecentData()
+                    self.collectionComponent.clear()
+                    self.collectionComponent.reloadView(with: self.viewModel.colDataArray)
+                }
             }
         }
         
-        
-        
         cp.itemDidSelectedHandler = { [weak self] (object, indexPath) in
             guard let self = self else { return }
-//            if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
-//                if let currentActionInfoModel = sections.items.safeObj(At: indexPath.item) {
-//                    let gennerateVC = TSPTPGeneratorVC(generateStyleModel: TSGenerateStyleModel(),infoModel: currentActionInfoModel.dataModel) { model in }
-//                        gennerateVC.modalPresentationStyle = .overFullScreen
-//                        gennerateVC.modalTransitionStyle = .crossDissolve
-//                    self.present(gennerateVC, animated: true)
-//                    
-//                }
-//                
-//            }
-
             if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
                 var dataModelArray:[TSActionInfoModel] = []
                 for itemModel in sections.items {
-                    dataModelArray.append(itemModel.dataModel)
+                    if itemModel.dataModel.status == "success"{
+                        dataModelArray.append(itemModel.dataModel)
+                    }
                 }
-                
+    
                 let browseVC = TSAIPhotoBrowseVC()
                 browseVC.dataModelArray = dataModelArray
                 browseVC.currentIndex = indexPath.item
@@ -263,6 +237,30 @@ class TSPTPInputVC: TSBaseVC {
         return cp
     }()
     
+    //###################################### 集合视图 ######################################
+    lazy var collectionView: TSSimpleCollectionView = {
+        let identifier = "TSGenmojiItemCell"
+        
+//        let itemW = (k_ScreenWidth-32.0-12.0-2.0)/2.0
+//        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 293.0), width: itemW)
+        
+        let itemW = kPTPHistoryW
+        let itemH = kPTPHistoryH
+        
+        let layout = UICollectionViewFlowLayout()
+        let cp = TSSimpleCollectionView()
+        cp.layout.itemSize = CGSize(width: itemW, height: itemH)
+        cp.layout.minimumLineSpacing = 12
+        cp.layout.minimumInteritemSpacing = 12
+        cp.collectionView.contentInset = UIEdgeInsets(top: 16, left: 16, bottom: collectionViewBtootm, right: 16)
+        cp.registerCell(TSGenmojiItemCell.self,identifier:identifier)
+        cp.cellIdentifierForItem = { data in
+            return identifier
+        }
+
+        return cp
+    }()
+    
     //###################################### Button ######################################
     lazy var creatBtnView:TSAppBtnView  = {
         let creatBtnView = TSAppBtnView()

+ 15 - 5
AIEmoji/Business/TSPTPGeneratorVC/TSPTPInputVC/VM/TSPTPInputVM.swift

@@ -39,12 +39,19 @@ class TSPTPInputVM {
         return ptpStyleModels
     }()
     
+    
+    var listModels:[TSActionInfoModel]{
+        debugPrint("listModels.count = 前")
+        let array = TSRMShared.ptpDBHistory.getModelList()
+        debugPrint("listModels.count = \(array.count)")
+        return array
+//        return TSRMShared.ptpDBHistory.getModelList(count: 50)
+    }
+    
     lazy var historySeciton: TSGenmojiCoLSectionModel = {
         let sectionModel = TSGenmojiCoLSectionModel()
         sectionModel.style = .ptpPicHistory
         sectionModel.name = "History".localized
-        let listModels = TSPTPHistory.shared.listModels
-//        let listModels = Array(TSPTPHistory.shared.listModels.prefix(10000))
         for model in listModels {
             let itemModel = TSGenmojiCoLItemModel()
             itemModel.style = sectionModel.style
@@ -72,9 +79,12 @@ class TSPTPInputVM {
     func combinedData(){
         colDataArray.removeAll()
         
+        debugPrint("historySeciton start")
         if historySeciton.items.count > 0 {
             colDataArray.append(historySeciton)
         }
+        
+        debugPrint("historySeciton end")
     }
     
     func gennerateChange(){
@@ -85,7 +95,7 @@ class TSPTPInputVM {
 extension TSPTPInputVM {
     //返回值,是否需要清空后刷新
     func saveModel(model:TSActionInfoModel)->Bool{
-        TSPTPHistory.shared.saveModel(model: model, at: 0)
+        TSRMShared.ptpDBHistory.updateData(model)
         
         var isNeed = false
         if historySeciton.items.count == 0 {
@@ -110,14 +120,14 @@ extension TSPTPInputVM {
     }
 
     func removeAllHistoryList(){
-        TSPTPHistory.shared.removeALLModel()
+        TSRMShared.ptpDBHistory.delete()
         historySeciton.items.removeAll()
         colDataArray.removeLast()
     }
     
     func updateRecentData() {
         var items:[TSGenmojiCoLItemModel] = []
-        for model in TSPTPHistory.shared.listModels {
+        for model in listModels {
             let itemModel = TSGenmojiCoLItemModel()
             itemModel.style = historySeciton.style
             itemModel.dataModel = model

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/VM/TSPhotoToPhotoVM.swift

@@ -49,7 +49,7 @@ class TSPhotoToPhotoVM {
         return ptpStyleModels
     }()
     //历史记录
-    @UserDefault(key: "photoToPhotoHistoryListString", defaultValue: "")
+    @UserDefault(key: TSDBHistoryType.ptp.rawValue, defaultValue: "")
     private var historyListString: String
     
     

+ 3 - 1
AIEmoji/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift

@@ -94,10 +94,12 @@ class TSSetingViewModel: ObservableObject {
     }
     
     func removeCloudData(parent: UIViewController) {
+        TSRMShared.textPtpDBHistory()
+        
         TSToastShared.showLoading(containerView: parent.view)
         kDelayOnMainThread(5) {
             TSToastShared.hideLoading()
-            kSavePhotoSuccesswShared.show(atView: parent.view,text: "Removed Successfully".localized,showViewBtn: false)
+            kSaveSuccesswShared.show(atView: parent.view,text: "Removed Successfully".localized,showViewBtn: false)
         }
     }
     

+ 1 - 1
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/VM/TSTTPInputVM.swift

@@ -78,7 +78,7 @@ extension TSTTPInputVM {
     }
 
     func saveModel(model:TSActionInfoModel){
-        TSTextToPicHistory.saveModel(model: model)
+        TSRMShared.ttpDBHistory.updateData(model)
     }
 }
 

+ 2 - 2
AIEmoji/Business/TSTextGeneralPictureVC/TSTextGeneralPictureVC/ViewModel/TSTextGeneralPictureVM.swift

@@ -37,7 +37,7 @@ class TSTextGeneralPictureVM {
     
     
     func updateRecentData() {
-        let listModelArray = TSTextToPicHistory.listModelArray
+        let listModelArray = TSRMShared.ttpDBHistory.getModelList()
         if listModelArray.count == 0 {
             colDataArray = []
         }else{
@@ -58,7 +58,7 @@ class TSTextGeneralPictureVM {
  
 extension TSTextGeneralPictureVM {
     func removeAllHistoryList(){
-        TSTextToPicHistory.removeAll()
+        TSRMShared.ttpDBHistory.delete()
     }
 }
 

+ 14 - 39
AIEmoji/Common/TSRealmManager/TSRealmManager.swift

@@ -14,16 +14,15 @@ let TSRMShared = TSRealmManager.shared
 
 class TSRealmManager {
     static let shared = TSRealmManager()
-    var realm: Realm
-
     private init() {
         /*设置新的版本号
          1.0 ->1
          1.9 ->2    //新增
          2.1 ->3    //新增ai思考
+         3.6.1  ->4   //将UserDefaults 的历史记录迁移到数据库中
          **/
    
-        let newSchemaVersion: UInt64 = 3
+        let newSchemaVersion: UInt64 = 4
         // 获取默认配置
         var config = Realm.Configuration.defaultConfiguration
         // 设置新版本号
@@ -36,19 +35,14 @@ class TSRealmManager {
         }
         // 将修改后的配置设置为默认配置
         Realm.Configuration.defaultConfiguration = config
-        
-        
-        do {
-            // 使用新配置打开 Realm 数据库
-            realm = try Realm()
-            print("Realm 数据库已成功打开,版本号: \(realm.configuration.schemaVersion)")
-        } catch {
-            fatalError("打开 Realm 数据库时出错: \(error)")
-        }
-        
-        
+        debugPrint("Realm 数据库已成功打开,版本号: \(newSchemaVersion)")
+    }
+    
+    var realm:Realm {
+        return try! Realm()
     }
 
+
     // 创建数据
     func create<T: Object>(_ object: T) {
         do {
@@ -65,22 +59,11 @@ class TSRealmManager {
         return realm.objects(type)
     }
 
-    // 更新数据
-//    func update<T: Object>(_ object: T, with block: (T) -> Void) {
-//        do {
-//            try realm.write {
-//                block(object)
-//            }
-//        } catch {
-//            print("Failed to update object: \(error)")
-//        }
-//    }
-    
-    
+
     func update<T: Object>(_ object: T) {
         do {
-            try realm.write {
-                realm.add(object,update: .modified)
+            try Realm().write {
+                try Realm().add(object,update: .modified)
             }
         } catch {
             print("Failed to update object: \(error)")
@@ -90,8 +73,9 @@ class TSRealmManager {
     // 删除数据
     func delete<T: Object>(_ object: T) {
         do {
-            try realm.write {
-                realm.delete(object)
+      
+            try Realm().write {
+                try Realm().delete(object)
             }
         } catch {
             print("Failed to delete object: \(error)")
@@ -100,15 +84,6 @@ class TSRealmManager {
     
     
     func writeThread(wt: ()->Void) {
- 
-//            do {
-//                try self.realm.write {
-//                    wt()
-//                }
-//            } catch {
-//                print("Failed to writeThread: \(error)")
-//            }
-        
         do {
             try Realm().write {
                 wt()

+ 45 - 0
AIEmoji/Common/Tool/MemoryLeakChecker.swift

@@ -0,0 +1,45 @@
+//
+//  11.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/26.
+//
+
+//import Foundation
+//import FBRetainCycleDetector
+//class MemoryLeakChecker {
+//    
+//    /// 检测指定对象的循环引用
+//    static func checkRetainCycle(for object: AnyObject) {
+//        let detector = FBRetainCycleDetector()
+//        detector.addCandidate(object)
+//        
+//        // 设置过滤条件(可选)
+//        let configuration = FBObjectGraphConfiguration(
+//            filterBlocks: [defaultFilterBlock()],
+//            shouldInspectTimers: true
+//        )
+//        
+//        // 开始检测
+//        let retainCycles = detector.findRetainCycles(with: configuration)
+//        
+//        if retainCycles.isEmpty {
+//            print("✅ 未检测到循环引用")
+//        } else {
+//            print("⚠️ 检测到 \(retainCycles.count) 个循环引用:")
+//            for cycle in retainCycles {
+//                print("🔗 循环引用链:")
+//                print(cycle)
+//            }
+//        }
+//    }
+//    
+//    /// 默认过滤器(过滤系统类)
+//    private static func defaultFilterBlock() -> FBGraphEdgeFilterBlock {
+//        return { obj in
+//            // 过滤掉系统类
+//            let className = NSStringFromClass(object_getClass(obj)!)
+//            return !className.starts(with: "NS") && !className.starts(with: "_")
+//        }
+//    }
+//}

+ 1 - 2
AIEmoji/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGeneratePosterOperation.swift

@@ -46,9 +46,8 @@ class TSGeneratePTPOperation: TSGenerateBaseOperation , @unchecked Sendable{
     override func replaceSaveInfoModel(model:TSActionInfoModel){
         model.uuid = uuid
         model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
-        TSPTPHistory.shared.replaceModel(oldID: currentActionInfoModel.id, newModel: model)
+        TSRMShared.ptpDBHistory.updateData(model,id: currentActionInfoModel.id)
         currentActionInfoModel = model
-        dePrint("TSPosterHistory.shared.listModels.count=\(TSPTPHistory.shared.listModels.count)")
         dePrint("model actionStatus 发出=\(model.actionStatus)")
         currentActionInfoModelChanged?(currentActionInfoModel)
     }

+ 1 - 1
Podfile

@@ -15,7 +15,7 @@ target 'AIEmoji' do
   pod 'MJRefresh'
   pod 'IQKeyboardManagerSwift'
   pod 'JXSegmentedView'
-  pod 'JXPagingView/Paging'
+  pod 'JXPagingView'
   pod 'Masonry'
   pod 'RealmSwift', '~>10'
   pod 'SwipeCellKit'

+ 6 - 2
Podfile.lock

@@ -40,6 +40,10 @@ PODS:
     - IQKeyboardCore
   - IQTextView (1.0.5):
     - IQKeyboardToolbar/Placeholderable
+  - JXPagingView (2.1.3):
+    - JXPagingView/Pager (= 2.1.3)
+    - JXPagingView/Paging (= 2.1.3)
+  - JXPagingView/Pager (2.1.3)
   - JXPagingView/Paging (2.1.3)
   - JXSegmentedView (1.4.1)
   - Kingfisher (7.10.0)
@@ -67,7 +71,7 @@ PODS:
 DEPENDENCIES:
   - Alamofire
   - IQKeyboardManagerSwift
-  - JXPagingView/Paging
+  - JXPagingView
   - JXSegmentedView
   - Kingfisher (= 7.10.0)
   - Masonry
@@ -131,6 +135,6 @@ SPEC CHECKSUMS:
   SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
   TSSmalCoacopods: 6aa97167f0c76b16fc7d1fd1eb198bb6aece4f68
 
-PODFILE CHECKSUM: aba7d93ac7e74d02fbfcbcd27303cc272aa99d13
+PODFILE CHECKSUM: 4f653860b88b70f3e7ec03b90aa9ac7a25c03d10
 
 COCOAPODS: 1.16.2