100Years 4 өдөр өмнө
parent
commit
161ddc3147

+ 4 - 0
AIEmoji.xcodeproj/project.pbxproj

@@ -271,6 +271,7 @@
 		A8D638482DB21FAD00A96C0E /* TSDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D638462DB21FAD00A96C0E /* TSDownloadManager.swift */; };
 		A8D6384A2DB252F100A96C0E /* TSAIListHistoryBaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D638492DB252F000A96C0E /* TSAIListHistoryBaseCell.swift */; };
 		A8DFCDAF2E445C4E005A6D44 /* TSAIPhotoBrowsePageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8DFCDAE2E445C4D005A6D44 /* TSAIPhotoBrowsePageVC.swift */; };
+		A8DFCDB22E45ECDE005A6D44 /* TSPurchaseManager+Judge.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8DFCDB12E45E9FA005A6D44 /* TSPurchaseManager+Judge.swift */; };
 		A8EB1A642E30EA24001F58D7 /* KeychainManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EB1A632E30EA22001F58D7 /* KeychainManager.swift */; };
 		A8EB1A662E30FA78001F58D7 /* TSAppOtherAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EB1A652E30FA71001F58D7 /* TSAppOtherAlertVC.swift */; };
 		A8EB1AA02E320438001F58D7 /* Pixel World.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A8EB1A982E320438001F58D7 /* Pixel World.mp4 */; };
@@ -684,6 +685,7 @@
 		A8D638462DB21FAD00A96C0E /* TSDownloadManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDownloadManager.swift; sourceTree = "<group>"; };
 		A8D638492DB252F000A96C0E /* TSAIListHistoryBaseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryBaseCell.swift; sourceTree = "<group>"; };
 		A8DFCDAE2E445C4D005A6D44 /* TSAIPhotoBrowsePageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoBrowsePageVC.swift; sourceTree = "<group>"; };
+		A8DFCDB12E45E9FA005A6D44 /* TSPurchaseManager+Judge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSPurchaseManager+Judge.swift"; sourceTree = "<group>"; };
 		A8EB1A632E30EA22001F58D7 /* KeychainManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainManager.swift; sourceTree = "<group>"; };
 		A8EB1A652E30FA71001F58D7 /* TSAppOtherAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAppOtherAlertVC.swift; sourceTree = "<group>"; };
 		A8EB1A852E320438001F58D7 /* Animal Diving Show.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Animal Diving Show.mp4"; sourceTree = "<group>"; };
@@ -1077,6 +1079,7 @@
 				A8EE84382E3318AC00CA04F0 /* TSPurchaseManager+Limit.swift */,
 				A8F413502DA7B711001E715A /* TSPurchaseManager+DataReport.swift */,
 				A880ECEF2E41E61600222C47 /* TSPurchaseManager+PurchasedNum.swift */,
+				A8DFCDB12E45E9FA005A6D44 /* TSPurchaseManager+Judge.swift */,
 			);
 			path = Purchase;
 			sourceTree = "<group>";
@@ -3187,6 +3190,7 @@
 				A85E47982D672AE70018D62D /* TSTextPicGennerateVM.swift in Sources */,
 				A89EA65F2D59AA11000EB181 /* TSChatViewController.swift in Sources */,
 				A8708A232E0A46BC00601686 /* ts111.swift in Sources */,
+				A8DFCDB22E45ECDE005A6D44 /* TSPurchaseManager+Judge.swift in Sources */,
 				A89EA6C62D5F5C22000EB181 /* TSChatInputFullScreenVC.swift in Sources */,
 				60B384612E39C33200D77E20 /* TSDiyVideoPopoverViewController.swift in Sources */,
 				A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */,

+ 3 - 3
AIEmoji/Business/TSPTPGeneratorVC/TSAIPhotoBrowsePageVC/TSAIPhotoBrowsePageVC.swift

@@ -325,11 +325,11 @@ class TSAIPhotoDetailsBrowserVideoVC: TSAIPhotoDetailsBrowserBaseVC {
         self.videoPlayerVC!.view.snp.remakeConstraints { make in
             make.edges.equalToSuperview()
         }
-        self.videoPlayerVC?.runloppPlay()
     }
     
-    override func viewDidAppear(_ animated: Bool) {
-        super.viewDidAppear(animated)
+    
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
         self.videoPlayerVC?.runloppPlay()
     }
     

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

@@ -97,7 +97,7 @@ class TSSetingViewModel: ObservableObject {
     }
     
     func purchaseVideoTimesVC(parent: UIViewController) {
-        kPresentModalVC(target: parent, modelVC: TSPurchaseVideoTimesVC(isShowAlertModel: true))
+        kPresentModalVC(target: parent, modelVC: TSPurchaseVideoTimesVC(isShowAlertModel: false))
     }
 }
 

+ 2 - 2
AIEmoji/Business2/DIYVideo/TSAIDiyVideoVC.swift

@@ -75,7 +75,7 @@ class TSAIDiyVideoVC: TSBaseVC {
 
     lazy var creatBtnView: TSAppBtnView = {
         let creatBtnView = TSAppBtnView()
-        let vipFreeNumType = VipFreeNumType.videoV2
+        let vipFreeNumType = VipFreeNumType.videoType//视频的次数
         creatBtnView.setUpButton(style: .generate, vipFreeNumType: vipFreeNumType) { [weak self] in
             guard let self = self else { return }
             generateVideo()
@@ -178,7 +178,7 @@ extension TSAIDiyVideoVC: JXSegmentedListContainerViewDataSource {
 
 extension TSAIDiyVideoVC {
     func generateVideo() {
-        if kJudgeVip(externalBool: true, vc: self) { return }  //判断 vip
+        if kJudgeVip(externalBool: true, vc: self) { return }  //判断 vip,不给 diy 视频试用册书
         if segmentedView.selectedIndex == 0 {
             guard let img = ptvVc.viewModel.uploadImage else {
                 return

+ 0 - 17
AIEmoji/Business2/DisCover/Data/TSFuncStyle.swift

@@ -51,10 +51,6 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
         }
     }
     
-//    var userDefaultsKey:String{
-//
-//    }
-
     func getHintKey(hintType:Int)->String {
         switch self {
         case .ageOld:
@@ -123,10 +119,6 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
         }
     }
     
-//    var config:TSAIListHintBaseVC.Config{
-//       
-//    }
-    
     var advance:Bool{
         switch self {
         case .catTohuman,.motherDay,.futureBaby:
@@ -135,15 +127,6 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
             return false
         }
     }
-    
-    var vipFreeNumType:VipFreeNumType{
-        switch self {
-        case .videoV2,.photoLive,.futureBaby,.textToVideo,.pictureToVideo:
-            return .videoV2
-        default:
-            return .aiGenerate
-        }
-    }
 }
 
 

+ 2 - 3
AIEmoji/Business2/DisCover/TSDiscoverVC/TSDiscoverVC.swift

@@ -352,9 +352,8 @@ extension TSDiscoverVC{
     static var hintBaseVC:TSAIListHintBaseVC?
     static var photoPickerManager:TSPhotoPickerManager?
     
-    static func showHintBaseVC(target:UIViewController,style:TSFuncStyle,hintType:Int = 0){
-        let hintBaseVC = TSAIListHintBaseVC(config: style.getConfig(hintType: hintType))
-        kPresentModalVC(target: target, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
+    static func showHintBaseVC(target:UIViewController,style:TSFuncStyle,hintType:Int = 0,isOnlyShow:Bool = false){
+        kPresentModalVC(target: target, modelVC: TSAIListHintBaseVC(config: style.getConfig(hintType: hintType),isOnlyShow: isOnlyShow),transitionStyle: .crossDissolve)
     }
     
     

+ 5 - 2
AIEmoji/Business2/DisCover/TSPTPUploadImageVC/TSPTPUploadImageVC.swift

@@ -72,8 +72,11 @@ class TSPTPUploadImageVC: TSBaseVC {
 extension TSPTPUploadImageVC {
     func generateImage() {
 
+        //判断图片尺寸
         if judgeVideoImagesizeError(image: viewModel.generatorModel.upLoadImage){ return }
-        
+        //判断是否需要购买视频加油包
+        if kPurchaseDefault.judgePurchaseVideoPackage(vipFreeNumType: viewModel.style.vipFreeNumType, target: self){ return }
+  
         let gennerateVC = TSAIGenerateVC(generatorModel: viewModel.generatorModel) { [weak self] _ in
             guard let self = self else { return }
             updateVipView()
@@ -119,7 +122,7 @@ extension TSPTPUploadImageVC {
     }
     
     @objc func clickNavTitleBtn(){
-        TSDiscoverVC.showHintBaseVC(target: self, style: viewModel.style, hintType: viewModel.selectedPTPStyleModel.hintType)
+        TSDiscoverVC.showHintBaseVC(target: self, style: viewModel.style, hintType: viewModel.selectedPTPStyleModel.hintType,isOnlyShow: true)
     }
 
 }

+ 5 - 60
AIEmoji/Common/NetworkManager/TSNetWork/TSNetWork+Business.swift

@@ -49,45 +49,6 @@ enum TSNeURLType:String {
          }
     }
     
-    var needValidate : Bool {
-        return validateURLTypeList.contains(self)
-    }
-    
-    var isVideo:Bool{
-        switch self {
-        case .createVideo,.videoV2,.photoAnimation,.text2Video,.img2video:
-            return true
-        default:
-            return false
-        }
-    }
-    
-    var vipFreeNumType:VipFreeNumType {
-        isVideo ? .videoV2 : .aiGenerate
-    }
-    
-    ///需要进行次数验证的接口
-    var validateURLTypeList : [TSNeURLType] {
-        [.textPicCreate,
-         .upload,
-         .imageRewrite,
-         .changeAge,
-         .subscriptionApple,
-         .changeEmotion,
-         .changeHair,
-         .imageRestore,
-         .eyeOpen,
-         .pretty,
-         .photoAnimation,
-         .photoExpand,
-         .overResolution,
-         .changeClothes,
-         .createVideo,
-         .videoV2,
-         .text2Video,
-         .img2video,
-        ]
-    }
 }
 
 
@@ -275,16 +236,8 @@ extension TSNetworkManager {
         responseType: T.Type? = nil,
         completion: @escaping (Result<Any, Error>) -> Void
     ) -> Request? {
-        let vipFreeNumType:VipFreeNumType = urlType.isVideo ? .videoV2 : .aiGenerate
-        ///需要校验。且需要判断是否超过最大次数
-        if urlType.needValidate,urlType.isVideo,PurchaseManager.default.isExceedsVipGeneratedNum(vipFreeNumType: .videoV2) {
-            completion(.failure(NSError(domain: "", code: TSNetWorkCode.generateToMax.rawValue)))
-            return nil
-        }
-        
-        ///需要校验。且需要判断是否超过最大次数
-        if urlType.needValidate,PurchaseManager.default.isExceedsDayGeneratedNum(vipFreeNumType: vipFreeNumType) {
-            completion(.failure(NSError(domain: "", code: TSNetWorkCode.generateTooMuch.rawValue)))
+        //检验生成次数,判断是否合规
+        if kPurchaseDefault.judgeUsedNumUrlType(urlType: urlType, completion: completion){
             return nil
         }
         
@@ -373,20 +326,12 @@ extension TSNetworkManager {
         progressHandler: @escaping (Float) -> Void, // 上传进度回调
         completion: @escaping (Any?, Error?) -> Void)
     -> Request?{
-        let vipFreeNumType:VipFreeNumType = vipFreeNumType == .videoV2 ? .videoV2 : .aiGenerate
-        ///需要校验,是否超出了 vip 生成的次数,且需要判断是否超过最大次数
-        if vipFreeNumType == .videoV2, PurchaseManager.default.isExceedsVipGeneratedNum(vipFreeNumType: .videoV2) {
-            completion(nil,NSError(domain: "", code: TSNetWorkCode.generateToMax.rawValue))
-            return nil
-        }
         
-        ///需要校验。且需要判断是否超过每天生成的最大次数
-        if PurchaseManager.default.isExceedsDayGeneratedNum(vipFreeNumType: vipFreeNumType) {
-            completion(nil,NSError(domain: "", code: TSNetWorkCode.generateTooMuch.rawValue))
+        //检验生成次数,判断是否合规
+        if kPurchaseDefault.judgeUsedNumType(vipFreeNumType: vipFreeNumType, completion: completion){
             return nil
         }
-
-        
+  
         guard let imageData = TSImageCompress.compressImageToTargetSize(upLoadImage, targetSizeKB: maxKb, preserveTransparency: false) else {
             completion(nil,NSError(domain: "image nil", code: 0))
             return nil

+ 1 - 2
AIEmoji/Common/Purchase/TSPurchaseManager+Free.swift

@@ -103,8 +103,7 @@ extension PurchaseManager {
 
     /// 免费次数是否可用
     func freeNumAvailable(type: VipFreeNumType) -> Bool {
-//        if isVip == true {
-        if isVip == true ||  (type == .videoV2 && videoAvailableNum > 0) {
+        if isVip == true ||  (type.isVideo && videoAvailableNum > 0) {
             return true
         } else {
             if freeNum(type: type) > 0 {

+ 140 - 0
AIEmoji/Common/Purchase/TSPurchaseManager+Judge.swift

@@ -0,0 +1,140 @@
+//
+//  TSPurchaseManager+Judge.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/8/1.
+//
+
+extension TSNeURLType {
+    
+    var needValidate : Bool {
+        return validateURLTypeList.contains(self)
+    }
+    //判断是否是生成视频,每次新增类型,必须配置
+    var isVideo:Bool{
+        switch self {
+        case .createVideo,.videoV2,.photoAnimation,.text2Video,.img2video:
+            return true
+        default:
+            return false
+        }
+    }
+    
+    //对应的 生成次数限制,每次新增类型,必须配置
+    var vipFreeNumType:VipFreeNumType {
+        isVideo ? .videoV2 : .aiGenerate
+    }
+    
+    ///需要进行次数验证的接口,每次新增生成接口,必须配置
+    var validateURLTypeList : [TSNeURLType] {
+        [.textPicCreate,
+         .upload,
+         .imageRewrite,
+         .changeAge,
+         .subscriptionApple,
+         .changeEmotion,
+         .changeHair,
+         .imageRestore,
+         .eyeOpen,
+         .pretty,
+         .photoAnimation,
+         .photoExpand,
+         .overResolution,
+         .changeClothes,
+         .createVideo,
+         .videoV2,
+         .text2Video,
+         .img2video,
+        ]
+    }
+}
+
+extension VipFreeNumType {
+    var isVideo:Bool{
+        switch self {
+        case .videoV2:
+            return true
+        default:
+            return false
+        }
+    }
+    
+    
+    static var videoType:VipFreeNumType{
+        return .videoV2
+    }
+}
+extension TSFuncStyle {
+    //对应的 生成次数限制,每次新增类型,必须配置
+    var vipFreeNumType:VipFreeNumType{
+        switch self {
+        case .videoV2,.photoLive,.futureBaby,.textToVideo,.pictureToVideo:
+            return .videoV2
+        default:
+            return .aiGenerate
+        }
+    }
+}
+
+
+extension PurchaseManager {
+    
+    func getDayGeneratedNum(type: VipFreeNumType) -> VipFreeNumType{
+        if type.isVideo {
+            return VipFreeNumType.videoType
+        }else{
+            return .aiGenerate
+        }
+    }
+
+    //判断视频是否超出限制
+    func judgeVideoV2ExceedLimit(vipFreeNumType:VipFreeNumType) -> Bool{
+        if vipFreeNumType.isVideo {
+            return isExceedsVipGeneratedNum(vipFreeNumType:VipFreeNumType.videoType)
+        }
+        return false
+    }
+    
+    func judgeUsedNumType(vipFreeNumType:VipFreeNumType,completion: @escaping (Any?, Error?) -> Void) -> Bool{
+        ///需要校验,是否超出了 vip 生成的次数,且需要判断是否超过最大次数
+        if judgeVideoV2ExceedLimit(vipFreeNumType: vipFreeNumType) {
+            completion(nil,NSError(domain: "", code: TSNetWorkCode.generateToMax.rawValue))
+            return true
+        }
+        
+        ///需要校验。且需要判断是否超过每天生成的最大次数
+        if PurchaseManager.default.isExceedsDayGeneratedNum(vipFreeNumType: vipFreeNumType) {
+            completion(nil,NSError(domain: "", code: TSNetWorkCode.generateTooMuch.rawValue))
+            return true
+        }
+        
+        return false
+    }
+    
+    func judgeUsedNumUrlType(urlType:TSNeURLType,completion:@escaping (Result<Any, Error>) -> Void) -> Bool{
+        let vipFreeNumType:VipFreeNumType = urlType.isVideo ? VipFreeNumType.videoType : .aiGenerate
+        ///需要校验,是否超出了 vip 生成的次数,且需要判断是否超过最大次数
+        if urlType.needValidate,judgeVideoV2ExceedLimit(vipFreeNumType: vipFreeNumType) {
+            completion(.failure(NSError(domain: "", code: TSNetWorkCode.generateToMax.rawValue)))
+            return true
+        }
+        
+        ///需要校验。且需要判断是否超过最大次数
+        if urlType.needValidate,PurchaseManager.default.isExceedsDayGeneratedNum(vipFreeNumType: vipFreeNumType) {
+            completion(.failure(NSError(domain: "", code: TSNetWorkCode.generateTooMuch.rawValue)))
+            return true
+        }
+        
+        return false
+    }
+
+    //判断试用的视频次数,是否超出了最大数量,如果超出,提示用户购买加油宝
+    func judgePurchaseVideoPackage(vipFreeNumType:VipFreeNumType,target:UIViewController) -> Bool{
+        ///需要校验,是否超出了 vip 生成的次数,且需要判断是否超过最大次数
+        if judgeVideoV2ExceedLimit(vipFreeNumType: vipFreeNumType)  {
+            kPresentModalVC(target: target, modelVC: TSPurchaseVideoTimesVC(isShowAlertModel: true),transitionStyle:.crossDissolve)
+            return true
+        }
+        return false
+    }
+}

+ 1 - 55
AIEmoji/Common/Purchase/TSPurchaseManager+Limit.swift

@@ -10,18 +10,11 @@ let kDayGeneratedNumKey = "kDayGeneratedNumKey"
 let kVipGeneratedNumKey = "kVipGeneratedNumKey"
 
 extension PurchaseManager {
-    func getDayGeneratedNum(type: VipFreeNumType) -> VipFreeNumType{
-        if type != .videoV2 {
-            return .aiGenerate
-        }
-        return .videoV2
-    }
-
     //是否超出每天使用的次数
     public func isExceedsDayGeneratedNum(vipFreeNumType:VipFreeNumType) -> Bool {
         if isVip {
             let dayNum = loadDayGeneratedNum(type: vipFreeNumType)
-            if vipFreeNumType == .videoV2 {
+            if vipFreeNumType.isVideo {
                 return dayNum >= vipType.dayGeneratedVideoNumber
             }
             return dayNum >= vipType.dayGeneratedNumber
@@ -105,51 +98,4 @@ extension PurchaseManager {
         // 有记录,读取已经使用次数
         return typeDict.safeInt(forKey: "times")
     }
-    
 }
-
-
-//extension PurchaseManager {
-//    
-//    //是否超出Vip期间使用的次数
-//    public func isExceedsVipGeneratedNum(vipFreeNumType:VipFreeNumType) -> Bool {
-//        if isVip {
-//            let dayNum = loadVipGeneratedNum(type: vipFreeNumType)
-//            if vipFreeNumType == .videoV2 {
-//                return dayNum >= vipType.creatVideoMaxNum
-//            }
-//            return false
-//        }
-//        return false
-//    }
-//
-//    func saveForVipGeneratedNum(type: VipFreeNumType) {
-//        let type = getDayGeneratedNum(type: type)
-//        
-//        var dayNum = loadVipGeneratedNum(type: type)
-//        dayNum = dayNum + 1
-//        // 保存新的记录
-//        var dict: [String: [String: Any]] = [:]
-//        if var saveDict = UserDefaults.standard.dictionary(forKey: kVipGeneratedNumKey) as? [String: [String: Any]]{
-//            dict = saveDict
-//        }
-//        dict[type.rawValue] = ["times": dayNum,"expireTime":expireTime]
-//        
-//        saveForUserKeychain(data: dict,key: kVipGeneratedNumKey)
-//    }
-//
-//    func loadVipGeneratedNum(type: VipFreeNumType)-> Int {
-//        let type = getDayGeneratedNum(type: type)
-//        // 当天没记录,设置默认次数
-//        guard let dict = UserDefaults.standard.dictionary(forKey: kVipGeneratedNumKey),
-//              let typeDict = dict.safeDictionary(forKey: type.rawValue) as? [String: Any],
-//              typeDict.safeString(forKey: "expireTime") == expireTime
-//        else {
-//            return 0
-//        }
-//        dePrint("从钥匙串 loadVipGeneratedNum=\(dict)")
-//        // 有记录,设置已经使用次数
-//        return typeDict.safeInt(forKey: "times")
-//    }
-//    
-//}

+ 2 - 2
AIEmoji/Common/Purchase/TSPurchaseManager+PurchasedNum.swift

@@ -38,14 +38,14 @@ extension PurchaseManager {
     
     //消耗购买的视频次数
     func reduceVideoPurchasedNum(type: VipFreeNumType) {
-        if type == .videoV2 {
+        if type.isVideo {
             TSDBTimesManager.purchaseVideo.reduceTimes()
         }
     }
     
     //视频生成可用的次数
     var videoAvailableNum:Int {
-        let vipFreeNumType:VipFreeNumType = .videoV2
+        let vipFreeNumType:VipFreeNumType = VipFreeNumType.videoType
         var vipNum = vipType.creatVideoMaxNum - loadVipGeneratedNum(type:vipFreeNumType) //会员自身带的额度
         vipNum = max(0, vipNum)
         let purchaseNum = TSDBTimesManager.purchaseVideo.times //用户后面购买的次数