Browse Source

4.3a改造:网路请求改造完毕

kln 1 week ago
parent
commit
36738cc43e

+ 18 - 26
AIPlayRingtones.xcodeproj/project.pbxproj

@@ -56,6 +56,9 @@
 		3DBEA1822DE7152C000C6859 /* ASMediaDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA1812DE71529000C6859 /* ASMediaDownloader.swift */; };
 		3DBEA1842DE71703000C6859 /* ASMediaPlayerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA1832DE71700000C6859 /* ASMediaPlayerController.swift */; };
 		3DBEA1892DE728F8000C6859 /* ASGarageBandHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA1882DE728F8000C6859 /* ASGarageBandHelper.m */; };
+		3DBEA18B2DE7EF5C000C6859 /* ASNetworkCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA18A2DE7EF57000C6859 /* ASNetworkCoordinator.swift */; };
+		3DBEA18D2DE7F0BC000C6859 /* ASNetworkCoordinator+Bns.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA18C2DE7F0B3000C6859 /* ASNetworkCoordinator+Bns.swift */; };
+		3DBEA18F2DE7F2AD000C6859 /* ASNetworkCoordinator+error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBEA18E2DE7F2A8000C6859 /* ASNetworkCoordinator+error.swift */; };
 		3DCD56F32DDAE3E3004AAB5B /* ASRingToneCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCD56F22DDAE3DF004AAB5B /* ASRingToneCellView.swift */; };
 		3DCD56F52DDAE42A004AAB5B /* ASViewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DCD56F42DDAE421004AAB5B /* ASViewTool.swift */; };
 		3DCD57182DDB1158004AAB5B /* libmp3lame.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DCD57092DDB1158004AAB5B /* libmp3lame.a */; };
@@ -73,7 +76,6 @@
 		A800FEB22DDAC100009DABDC /* ASGeneratorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB12DDAC0FC009DABDC /* ASGeneratorView.swift */; };
 		A800FEB42DDAC73E009DABDC /* ASGeneratorLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB32DDAC738009DABDC /* ASGeneratorLoadingView.swift */; };
 		A800FEB62DDAC764009DABDC /* ASGeneratorErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB52DDAC75D009DABDC /* ASGeneratorErrorView.swift */; };
-		A800FEB82DDAC826009DABDC /* TSNetWork+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */; };
 		A800FEBB2DDACAF3009DABDC /* ASRingGeneratorVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEBA2DDACAF2009DABDC /* ASRingGeneratorVC.swift */; };
 		A800FEBD2DDACCD4009DABDC /* ASRingGeneratorBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A800FEBC2DDACCCF009DABDC /* ASRingGeneratorBaseVC.swift */; };
 		A848F8822DD6D1AF00B746EC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A848F8792DD6D1AF00B746EC /* Assets.xcassets */; };
@@ -81,8 +83,6 @@
 		A848F8862DD6D1AF00B746EC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8782DD6D1AF00B746EC /* AppDelegate.swift */; };
 		A848F88E2DD6D38600B746EC /* APLaunchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F88D2DD6D38300B746EC /* APLaunchVC.swift */; };
 		A848F8912DD6D50000B746EC /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8902DD6D4FD00B746EC /* Common.swift */; };
-		A848F89E2DD6D59C00B746EC /* TSNetWork+Business.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */; };
-		A848F89F2DD6D59C00B746EC /* TSNetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */; };
 		A848F8A42DD6D67000B746EC /* APRingTonesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8A32DD6D66D00B746EC /* APRingTonesVC.swift */; };
 		A848F8A92DD6D74A00B746EC /* APAudioToRingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8A82DD6D74900B746EC /* APAudioToRingVC.swift */; };
 		A848F8AB2DD6D75300B746EC /* ASMyRingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A848F8AA2DD6D75200B746EC /* ASMyRingVC.swift */; };
@@ -182,6 +182,9 @@
 		3DBEA1832DE71700000C6859 /* ASMediaPlayerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASMediaPlayerController.swift; sourceTree = "<group>"; };
 		3DBEA1872DE728F8000C6859 /* ASGarageBandHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASGarageBandHelper.h; sourceTree = "<group>"; };
 		3DBEA1882DE728F8000C6859 /* ASGarageBandHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ASGarageBandHelper.m; sourceTree = "<group>"; };
+		3DBEA18A2DE7EF57000C6859 /* ASNetworkCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASNetworkCoordinator.swift; sourceTree = "<group>"; };
+		3DBEA18C2DE7F0B3000C6859 /* ASNetworkCoordinator+Bns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ASNetworkCoordinator+Bns.swift"; sourceTree = "<group>"; };
+		3DBEA18E2DE7F2A8000C6859 /* ASNetworkCoordinator+error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ASNetworkCoordinator+error.swift"; sourceTree = "<group>"; };
 		3DCD56F22DDAE3DF004AAB5B /* ASRingToneCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingToneCellView.swift; sourceTree = "<group>"; };
 		3DCD56F42DDAE421004AAB5B /* ASViewTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASViewTool.swift; sourceTree = "<group>"; };
 		3DCD57062DDB1158004AAB5B /* AudioConverter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioConverter.h; sourceTree = "<group>"; };
@@ -204,7 +207,6 @@
 		A800FEB12DDAC0FC009DABDC /* ASGeneratorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorView.swift; sourceTree = "<group>"; };
 		A800FEB32DDAC738009DABDC /* ASGeneratorLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorLoadingView.swift; sourceTree = "<group>"; };
 		A800FEB52DDAC75D009DABDC /* ASGeneratorErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASGeneratorErrorView.swift; sourceTree = "<group>"; };
-		A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetWork+Error.swift"; sourceTree = "<group>"; };
 		A800FEBA2DDACAF2009DABDC /* ASRingGeneratorVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingGeneratorVC.swift; sourceTree = "<group>"; };
 		A800FEBC2DDACCCF009DABDC /* ASRingGeneratorBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASRingGeneratorBaseVC.swift; sourceTree = "<group>"; };
 		A848F8602DD6D19100B746EC /* AIPlayRingtones.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AIPlayRingtones.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -214,8 +216,6 @@
 		A848F87B2DD6D1AF00B746EC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
 		A848F88D2DD6D38300B746EC /* APLaunchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APLaunchVC.swift; sourceTree = "<group>"; };
 		A848F8902DD6D4FD00B746EC /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
-		A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSNetworkManager.swift; sourceTree = "<group>"; };
-		A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetWork+Business.swift"; sourceTree = "<group>"; };
 		A848F8A32DD6D66D00B746EC /* APRingTonesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APRingTonesVC.swift; sourceTree = "<group>"; };
 		A848F8A82DD6D74900B746EC /* APAudioToRingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APAudioToRingVC.swift; sourceTree = "<group>"; };
 		A848F8AA2DD6D75200B746EC /* ASMyRingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASMyRingVC.swift; sourceTree = "<group>"; };
@@ -492,7 +492,9 @@
 				3DBEA17F2DE7149E000C6859 /* ASResourceCacheHandler.swift */,
 				3DBEA1812DE71529000C6859 /* ASMediaDownloader.swift */,
 				3DBEA1832DE71700000C6859 /* ASMediaPlayerController.swift */,
-				A848F89D2DD6D59C00B746EC /* TSNetWork */,
+				3DBEA18A2DE7EF57000C6859 /* ASNetworkCoordinator.swift */,
+				3DBEA18C2DE7F0B3000C6859 /* ASNetworkCoordinator+Bns.swift */,
+				3DBEA18E2DE7F2A8000C6859 /* ASNetworkCoordinator+error.swift */,
 				A848F8902DD6D4FD00B746EC /* Common.swift */,
 				3DBEA1632DE6F390000C6859 /* ASRandomTextTool.h */,
 				3DBEA1642DE6F390000C6859 /* ASRandomTextTool.m */,
@@ -506,16 +508,6 @@
 			path = Common;
 			sourceTree = "<group>";
 		};
-		A848F89D2DD6D59C00B746EC /* TSNetWork */ = {
-			isa = PBXGroup;
-			children = (
-				A800FEB72DDAC81D009DABDC /* TSNetWork+Error.swift */,
-				A848F8992DD6D59C00B746EC /* TSNetworkManager.swift */,
-				A848F89A2DD6D59C00B746EC /* TSNetWork+Business.swift */,
-			);
-			path = TSNetWork;
-			sourceTree = "<group>";
-		};
 		A848F8A22DD6D65900B746EC /* APRingTonesVC */ = {
 			isa = PBXGroup;
 			children = (
@@ -830,6 +822,7 @@
 				A848F88E2DD6D38600B746EC /* APLaunchVC.swift in Sources */,
 				A848F8CA2DD6E82B00B746EC /* APRingTonesVC+StackView.swift in Sources */,
 				A848F8C22DD6E70000B746EC /* APRingTonesVC+Duration.swift in Sources */,
+				3DBEA18F2DE7F2AD000C6859 /* ASNetworkCoordinator+error.swift in Sources */,
 				A848F8A42DD6D67000B746EC /* APRingTonesVC.swift in Sources */,
 				3DBEA15C2DE6EEBC000C6859 /* UIImageView+AS.swift in Sources */,
 				A848F8BD2DD6E38900B746EC /* ASLeftHeaderView.swift in Sources */,
@@ -837,11 +830,9 @@
 				3DB4D4A32DDC34100082596A /* ASRTRFileView.swift in Sources */,
 				3DBEA1652DE6F390000C6859 /* ASRandomTextTool.m in Sources */,
 				A848F8E82DD74DFD00B746EC /* ASDBHistoryManager.swift in Sources */,
-				A848F89E2DD6D59C00B746EC /* TSNetWork+Business.swift in Sources */,
 				3DBEA1802DE714A1000C6859 /* ASResourceCacheHandler.swift in Sources */,
 				3DB4D4B52DE025920082596A /* ASTutorialsVC.swift in Sources */,
 				A848F8AB2DD6D75300B746EC /* ASMyRingVC.swift in Sources */,
-				A848F89F2DD6D59C00B746EC /* TSNetworkManager.swift in Sources */,
 				A848F8E32DD7286A00B746EC /* ASGenerateStyleModel.swift in Sources */,
 				3DBEA1782DE6FC66000C6859 /* ASTLLabel.swift in Sources */,
 				3DB4D4992DDC28E70082596A /* APAudioToRingVC+StackView.swift in Sources */,
@@ -853,8 +844,8 @@
 				A800FEBD2DDACCD4009DABDC /* ASRingGeneratorBaseVC.swift in Sources */,
 				A800FEB62DDAC764009DABDC /* ASGeneratorErrorView.swift in Sources */,
 				3DBEA1602DE6F322000C6859 /* GlobalImports.swift in Sources */,
-				A800FEB82DDAC826009DABDC /* TSNetWork+Error.swift in Sources */,
 				A848F8FA2DD7536700B746EC /*  Notification+Ex.swift in Sources */,
+				3DBEA18D2DE7F0BC000C6859 /* ASNetworkCoordinator+Bns.swift in Sources */,
 				A848F8C02DD6E6FA00B746EC /* APRingTonesVC+TextView.swift in Sources */,
 				3DB4D49D2DDC29AC0082596A /* ASRTRStyleView.swift in Sources */,
 				3DCD57312DDB2A66004AAB5B /* ASGenerateRingToRingOperation.swift in Sources */,
@@ -887,6 +878,7 @@
 				3DB4D4B22DDF0B960082596A /* FakeBlurView.swift in Sources */,
 				3DCD56F32DDAE3E3004AAB5B /* ASRingToneCellView.swift in Sources */,
 				3DBEA15E2DE6F008000C6859 /* UIFont+AS.swift in Sources */,
+				3DBEA18B2DE7EF5C000C6859 /* ASNetworkCoordinator.swift in Sources */,
 				3DBEA1762DE6FB18000C6859 /* ASFileManager.swift in Sources */,
 				A848F8C42DD6E70500B746EC /* APRingTonesVC+Style.swift in Sources */,
 				A848F8F82DD752E700B746EC /* ASGenerateTextToRingOperation.swift in Sources */,
@@ -943,7 +935,7 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 6;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = HR2R5NZ2MG;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIPlayRingtones/Info.plist;
@@ -958,9 +950,9 @@
 				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"$(PROJECT_DIR)/AIPlayRingtones/Common/TSBandRingTool/libmp3",
+					"$(PROJECT_DIR)/AIPlayRingtones/Common/ASGarageBandHelper/libmp3",
 				);
-				MARKETING_VERSION = 1.0;
+				MARKETING_VERSION = 1.1;
 				PRODUCT_BUNDLE_IDENTIFIER = com.musicdownloader.ringtones;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -981,7 +973,7 @@
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 6;
+				CURRENT_PROJECT_VERSION = 1;
 				DEVELOPMENT_TEAM = HR2R5NZ2MG;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIPlayRingtones/Info.plist;
@@ -996,9 +988,9 @@
 				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"$(PROJECT_DIR)/AIPlayRingtones/Common/TSBandRingTool/libmp3",
+					"$(PROJECT_DIR)/AIPlayRingtones/Common/ASGarageBandHelper/libmp3",
 				);
-				MARKETING_VERSION = 1.0;
+				MARKETING_VERSION = 1.1;
 				PRODUCT_BUNDLE_IDENTIFIER = com.musicdownloader.ringtones;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

+ 1 - 1
AIPlayRingtones/Common/ASMediaDownloader.swift

@@ -68,7 +68,7 @@ class ASMediaDownloader {
         }
         
         // 启动下载任务
-        return TSNetworkShared.downloadFile(urlString: sourceURL,to: saveLocation, progressHandler:progressTracker,completion: onCompletion)
+        return ASNetworkShared.retrieveFile(from: sourceURL,saveTo: saveLocation, progressTracker:progressTracker,completion: onCompletion)
     }
 }
 

+ 3 - 3
AIPlayRingtones/Common/ASMediaPlayerController.swift

@@ -99,12 +99,12 @@ class ASMediaPlayerController {
     ) {
         stopPlayback()
         
-        guard let mediaURL = urlString else { return }
+//        guard let mediaURL = urlString else { return }
         
-        activeMediaURL = mediaURL
+        activeMediaURL = urlString ?? ""
         localMediaPath = localPath
         mediaIndex = index
-        
+        let mediaURL = activeMediaURL
         let playbackHandler: (URL) -> Void = { [weak self] url in
             guard let self = self else { return }
             

+ 220 - 0
AIPlayRingtones/Common/ASNetworkCoordinator+Bns.swift

@@ -0,0 +1,220 @@
+//
+//  ASNetworkCoordinator+Bns.swift
+//  AIPlayRingtones
+//
+//  Created by mini on 2025/5/28.
+//
+
+import Alamofire
+import ObjectMapper
+private let kServiceBasePath = "http://ai.soundmove.cn"
+
+enum XHAPIEndpoint: String {
+    case generateAudio = "/api/music/create"          // 音频生成接口
+    case checkProgress = "/api/action/info"          // 进度查询接口
+    case fileTransfer = "/api/upload"                // 文件传输接口
+    
+    var fullPath: String {
+        return kServiceBasePath + self.rawValue
+    }
+}
+
+struct ASDeviceInfo {
+    static var identifier: String {
+        let storageKey = "deviceUniqueID"
+        if let storedID = UserDefaults.standard.string(forKey: storageKey), !storedID.isEmpty {
+            return storedID
+        }
+        let newID = UUID().uuidString
+        UserDefaults.standard.set(newID, forKey: storageKey)
+        return newID
+    }
+    
+    static var systemMetadata: [String: Any] {
+        return [
+            "device": deviceName,
+            "deviceId": identifier,
+            "iosVersion": UIDevice.current.systemVersion,
+            "appVersion": appShortVersion()
+        ]
+    }
+}
+
+
+extension ASNetworkCoordinator {
+    
+    // MARK: - 基础请求方法
+    
+    func executeGET<T: ASBaseModel>(
+        endpoint: XHAPIEndpoint,
+        params: [String: Any]? = nil,
+        modelType: T.Type? = nil,
+        completion: @escaping (Any?, Error?) -> Void
+    ) -> Request {
+        let targetURL = endpoint.fullPath
+        return performRequest(
+            method: .get,
+            endpoint: targetURL,
+            parameters: params
+        ) { result in
+            switch result {
+            case .success(let responseData):
+                completion(responseData, nil)
+            case .failure(let requestError):
+                completion(nil, requestError)
+            }
+        }
+    }
+    
+    func executePOST<T: ASBaseModel>(
+        endpoint: XHAPIEndpoint,
+        params: [String: Any]? = nil,
+        modelType: T.Type? = nil,
+        completion: @escaping (Any?, Error?) -> Void
+    ) -> Request {
+        let targetURL = endpoint.fullPath
+        return performRequest(
+            method: .post,
+            endpoint: targetURL,
+            parameters: params
+        ) { result in
+            switch result {
+            case .success(let responseData):
+                completion(responseData, nil)
+            case .failure(let requestError):
+                completion(nil, requestError)
+            }
+        }
+    }
+    
+//    // MARK: - 文件传输方法
+//    func fetchRemoteFile(
+//        from endpoint: XHAPIEndpoint,
+//        saveTo location: URL,
+//        progressUpdate: ((Double) -> Void)? = nil,
+//        completion: @escaping (URL?, Error?) -> Void
+//    ) -> DownloadRequest? {
+//        let targetURL = endpoint.fullPath
+//        return retrieveFile(
+//            from: targetURL,
+//            saveTo: location,
+//            progressTracker: progressUpdate
+//        ) { result in
+//            switch result {
+//            case .success(let fileURL):
+//                completion(fileURL, nil)
+//            case .failure(let error):
+//                completion(nil, error)
+//            }
+//        }
+//    }
+    
+    // MARK: - 音频上传专用方法
+    
+    func sendAudioFile(
+        audioFileURL: URL,
+        uploadProgress: @escaping (Float) -> Void,
+        completion: @escaping (Any?, Error?) -> Void
+    ) -> Request? {
+        let targetURL = XHAPIEndpoint.fileTransfer.fullPath
+        
+        debugPrint("准备上传音频文件: \(targetURL)")
+        guard let validURL = URL(string: targetURL) else {
+            completion(nil, NSError(domain: "NetworkError", code: 1001))
+            return nil
+        }
+        
+        return AF.upload(
+            multipartFormData: { formData in
+                formData.append(
+                    audioFileURL,
+                    withName: "file",
+                    fileName: "audio.mp3",
+                    mimeType: "audio/mp3"
+                )
+            },
+            to: validURL
+        )
+        .uploadProgress { progress in
+            debugPrint("上传进度: \(progress.fractionCompleted * 100)%")
+            uploadProgress(Float(progress.fractionCompleted))
+        }
+        .responseString { [weak self] response in
+            self?.processResponse(response) { result in
+                switch result {
+                case .success(let data):
+                    if let json = data as? [String: Any],
+                       let resultData = json["result"] as? String {
+                        completion(resultData, nil)
+                    } else {
+                        completion(nil, NSError(domain: "DataError", code: 1002))
+                    }
+                case .failure(let error):
+                    completion(nil, error)
+                }
+            }
+        }
+    }
+}
+
+func kNetWorkCodeSuccess(data:Any?) -> [String:Any]? {
+    guard let data = data else { return nil }
+    if let dataDict = data as? [String:Any],
+        let code = dataDict["code"] as? Int{
+        switch code {
+        case 200://成功®
+            return dataDict
+//        case 400://机器人提示
+//            TSAbnormalPopUpAlertVC.showRobotWarning()
+//            return nil
+        default:
+            return nil
+        }
+    }
+    return nil
+}
+
+
+
+func kNetWorkResultSuccess(data:Any?) -> [String:Any]? {
+    guard let dict = kNetWorkCodeSuccess(data: data) else { return nil }
+    if let result = dict["result"] as? [String:Any]{
+        return result
+    }
+    return nil
+}
+
+func kNetWorkMessage(data:Any?) -> String? {
+    guard let data = data else { return nil }
+    if let dict = data as? [String:Any] ,
+       let msg = dict["message"] as? String{
+        return msg
+    }
+    return nil
+}
+
+  
+
+class JsonStringTransform<T:Mappable>: TransformType {
+    typealias Object = T
+    typealias JSON = [String: Any]
+    
+    func transformFromJSON(_ value: Any?) -> T? {
+    
+        if let jsonString = value as? String {
+            let obj = T(JSONString: jsonString)
+            return obj
+        }
+        
+        if let dict = value as? [String: Any] {
+            let obj = T(JSON: dict)
+            return obj
+        }
+
+        return nil
+    }
+    
+    func transformToJSON(_ value: T?) -> [String : Any]? {
+        return value?.toJSON() as? [String: Any]
+    }
+}

+ 84 - 0
AIPlayRingtones/Common/ASNetworkCoordinator+error.swift

@@ -0,0 +1,84 @@
+//
+//  ASNetworkCoordinator+error.swift
+//  AIPlayRingtones
+//
+//  Created by mini on 2025/5/28.
+//
+
+import Alamofire
+
+let kDefaultErrorMessage = "Sorry there was a slight problem with the image processing, please try again later.".localized
+
+enum ASErrorCode: Int {
+    case operationSuccess = 200
+    case generalFailure = 0
+    case contentRestriction = -10003
+    case mediaRestriction = -10004
+    case connectivityIssue = -1005
+    
+    var localizedDescription: String {
+        switch self {
+        case .contentRestriction, .mediaRestriction:
+            return "Your content may contain restricted material. Please modify and retry.".localized
+        case .connectivityIssue:
+            return "Network unavailable. Check connection and retry.".localized
+        default:
+            return "Processing error occurred. Please retry later.".localized
+        }
+    }
+    
+    static func message(for statusCode: Int) -> String {
+        return ASErrorCode(rawValue: statusCode)?.localizedDescription ?? ASErrorCode.generalFailure.localizedDescription
+    }
+    //敏感错误
+    static func isContentFlagged(_ statusCode: Int) -> Bool {
+        guard let code = ASErrorCode(rawValue: statusCode) else { return false }
+        return code == .contentRestriction || code == .mediaRestriction
+    }
+    //网络错误
+    static func isNetworkRelated(_ statusCode: Int) -> Bool {
+        return ASErrorCode(rawValue: statusCode) == .connectivityIssue
+    }
+    
+    static func statusCode(from error: Error) -> Int {
+        if let afError = error as? AFError, let urlError = afError.underlyingError as? URLError {
+            return urlError.code.networkStatusCode
+        }
+        if let urlError = error as? URLError {
+            return urlError.code.networkStatusCode
+        }
+        return ASErrorCode.generalFailure.rawValue
+    }
+    
+    static func interfaceStyle(for statusCode: Int) -> ASGeneratorView.Style {
+        switch ASErrorCode(rawValue: statusCode) {
+        case .contentRestriction, .mediaRestriction:
+            return ASGeneratorView.Style.sensitiveError
+        case .connectivityIssue:
+            return ASGeneratorView.Style.netWorkError
+        default:
+            return ASGeneratorView.Style.generalError
+        }
+    }
+}
+
+extension URLError.Code {
+    var networkStatusCode: Int {
+        switch self {
+        case .notConnectedToInternet, .networkConnectionLost, .timedOut:
+            return ASErrorCode.connectivityIssue.rawValue
+        default:
+            return self.rawValue
+        }
+    }
+}
+
+extension Error {
+    var xhStatusCode: Int {
+        return ASErrorCode.statusCode(from: self)
+    }
+    
+    var xhLocalizedMessage: String {
+        return ASErrorCode.message(for: self.xhStatusCode)
+    }
+}

+ 227 - 0
AIPlayRingtones/Common/ASNetworkCoordinator.swift

@@ -0,0 +1,227 @@
+//
+//  ASNetworkCoordinator.swift
+//  AIPlayRingtones
+//
+//  Created by mini on 2025/5/28.
+//
+
+import Alamofire
+import ObjectMapper
+
+let ASNetworkShared = ASNetworkCoordinator.shared
+
+/// 网络请求协调器
+class ASNetworkCoordinator {
+    
+    static let shared = ASNetworkCoordinator()
+    private init() {}
+    
+    // MARK: - 配置属性
+    
+    private var standardHeaders: HTTPHeaders {
+        return [
+            "Content-Type": "application/json",
+            "accept": "application/json"
+        ]
+    }
+    
+    lazy var sessionManager: Session = AF
+    
+    lazy var jsonEncoder: JSONEncoding = {
+        return JSONEncoding(options: .withoutEscapingSlashes)
+    }()
+    
+    // MARK: - 核心请求方法
+    func performRequest(
+        method: HTTPMethod,
+        endpoint: String,
+        parameters: [String: Any]? = nil,
+        completion: @escaping (Result<Any, Error>) -> Void
+    ) -> Request {
+        debugPrint("发起网络请求: \(endpoint)")
+        debugPrint("请求参数: \(parameters ?? [:])")
+        
+        let encoding: ParameterEncoding = method == .post ? jsonEncoder : URLEncoding.default
+        
+        let request = sessionManager.request(
+            endpoint,
+            method: method,
+            parameters: parameters,
+            encoding: encoding,
+            headers: standardHeaders
+        )
+        
+        request.responseString { response in
+            self.processResponse(response, completion: completion)
+        }
+        
+        return request
+    }
+    
+    // MARK: - 文件传输方法
+    func transferFile(
+        endpoint: String,
+        fileLocation: URL,
+        formDataBuilder: @escaping (MultipartFormData) -> Void,
+        progressTracker: @escaping (Progress) -> Void,
+        completion: @escaping (Result<Any, Error>) -> Void
+    ) -> Request? {
+        debugPrint("文件传输请求: \(endpoint)")
+        
+        guard let targetURL = URL(string: endpoint) else {
+            completion(.failure(NSError(domain: "Invalid URL", code: 1003)))
+            return nil
+        }
+        
+        return AF.upload(
+            multipartFormData: formDataBuilder,
+            to: targetURL
+        )
+        .uploadProgress { progress in
+            debugPrint("传输进度: \(progress.fractionCompleted * 100)%")
+            progressTracker(progress)
+        }
+        .responseString { response in
+            self.processResponse(response, completion: completion)
+        }
+    }
+    
+    func retrieveFile(
+        from endpoint: String,
+        saveTo destination: URL? = nil,
+        progressTracker: ((Double) -> Void)? = nil,
+        completion: @escaping (URL?, Error?) -> Void
+    ) -> DownloadRequest? {
+        
+        guard let sourceURL = URL(string: endpoint) else {
+            completion(nil,NSError(domain: "Invalid URL", code: 1004))
+            return nil
+        }
+        
+        let destination: DownloadRequest.Destination = { tempURL, response in
+            if let dest = destination {
+                let dir = dest.deletingLastPathComponent()
+                try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
+                return (dest, [.removePreviousFile, .createIntermediateDirectories])
+            }
+            
+            let docsURL = FileManager.default.temporaryDirectory
+            let filename = response.suggestedFilename ?? sourceURL.lastPathComponent
+            return (docsURL.appendingPathComponent(filename), [.removePreviousFile, .createIntermediateDirectories])
+        }
+        
+        let request = sessionManager.download(sourceURL, to: destination)
+            .downloadProgress { progress in
+                DispatchQueue.main.async {
+                    progressTracker?(progress.fractionCompleted)
+                }
+            }
+            .response { response in
+                DispatchQueue.main.async {
+                    switch response.result {
+                    case .success(let url):
+                        if let url = url {
+                            completion(url,nil)
+                        } else {
+                            completion(nil,NSError(domain: "DownloadError", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效文件路径"]))
+                        }
+                    case .failure(let error):
+                        completion(nil,error)
+                    }
+                }
+            }
+        
+        return request
+    }
+    
+    // MARK: - 响应处理
+    
+    func processResponse(
+        _ response: AFDataResponse<String>,
+        completion: @escaping (Result<Any, Error>) -> Void
+    ) {
+        switch response.result {
+        case .success(let value):
+            if let json = convertToJSON(data: response.data) as? [String: Any] {
+                handleSuccessfulResponse(data: json, response: response, completion: completion)
+            } else {
+                handleFailedResponse(error: NSError(domain: "DataError", code: 1005), response: response, completion: completion)
+            }
+        case .failure(let error):
+            handleFailedResponse(error: error, response: response, completion: completion)
+        }
+    }
+    
+    private func handleSuccessfulResponse(
+        data: Any,
+        response: AFDataResponse<String>,
+        completion: @escaping (Result<Any, Error>) -> Void
+    ) {
+        debugPrint("请求成功: \(response.request?.url?.absoluteString ?? "")")
+        debugPrint("响应详情: \(response)")
+        completion(.success(data))
+    }
+    
+    private func handleFailedResponse(
+        error: Error,
+        response: AFDataResponse<String>,
+        completion: @escaping (Result<Any, Error>) -> Void
+    ) {
+        debugPrint("请求失败: \(response.request?.url?.absoluteString ?? "")")
+        debugPrint("错误详情: \(response)")
+        completion(.failure(error))
+    }
+    
+    private func convertToJSON(data: Data?) -> Any? {
+        guard let data = data else { return nil }
+        do {
+            return try JSONSerialization.jsonObject(with: data, options: [])
+        } catch {
+            debugPrint("JSON转换失败: \(error.localizedDescription)")
+            return nil
+        }
+    }
+}
+
+
+struct ASResponseParser {
+    
+    // MARK: - 响应验证
+    
+    /// 验证响应数据是否有效
+    /// - Parameter responseData: 原始响应数据
+    /// - Returns: 验证通过的字典数据
+    static func validateResponsePayload(_ responseData: Any?) -> [String: Any]? {
+        guard let payload = responseData,
+              let jsonDict = payload as? [String: Any],
+              let statusCode = jsonDict["code"] as? Int else {
+            return nil
+        }
+        
+        return statusCode == 200 ? jsonDict : nil
+    }
+    
+    // MARK: - 数据提取
+    
+    /// 提取响应中的结果数据
+    /// - Parameter responseData: 原始响应数据
+    /// - Returns: 结果字典
+    static func extractResultPayload(from responseData: Any?) -> [String: Any]? {
+        guard let validResponse = validateResponsePayload(responseData),
+              let resultData = validResponse["result"] as? [String: Any] else {
+            return nil
+        }
+        return resultData
+    }
+    
+    /// 提取响应中的消息文本
+    /// - Parameter responseData: 原始响应数据
+    /// - Returns: 消息字符串
+    static func extractMessageText(from responseData: Any?) -> String? {
+        guard let payload = responseData,
+              let jsonDict = payload as? [String: Any] else {
+            return nil
+        }
+        return jsonDict["notification"] as? String
+    }
+}

+ 0 - 199
AIPlayRingtones/Common/TSNetWork/TSNetWork+Business.swift

@@ -1,199 +0,0 @@
-//
-//  TSNetWork+Business.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/16.
-//
-
-private let baseURL = "http://ai.soundmove.cn"
-import Alamofire
-enum TSNeURLType:String {
-    
-    case musicCreate = "/api/music/create"         //音乐生成
-    case actionInfo = "/api/action/info"         //查询生成过程接口
-    case upload = "/api/upload"                  //上传
-
-    
-    func getUrlString() -> String {
-        return baseURL + self.rawValue
-    }
-}
-
-
-func getUserInfoJsonString()->[String:Any] {
-    let uuid: String
-    let uuidUdKey = "my_UUID"
-    if let saved = UserDefaults.standard.string(forKey: uuidUdKey),
-       !saved.isEmpty {
-        uuid = saved
-    } else {
-        let newUuid = UUID().uuidString
-        UserDefaults.standard.set(newUuid, forKey: uuidUdKey)
-        UserDefaults.standard.synchronize()
-        uuid = newUuid
-    }
-    
-    let dic:[String:Any] = [
-        "device":deviceName,
-        "deviceId":uuid,
-        "iosVersion":UIDevice.current.systemVersion,
-        "appVersion":appShortVersion(),
-//        "subscriptionStatus":kPurchaseDefault.isVip ? "active" : "fallow",
-    ]
-
-    return dic
-}
-
-
-func getLanguageCode()->String{
-    if Locale.current.identifier.contains("zh-Hant"){
-        return "zh-Hant"
-    }
-    if let languageCode = Locale.current.languageCode {
-        return languageCode
-    }
-    return "en"
-}
-
-
-extension TSNetworkManager {
-    
-    /// 通用 get 请求
-    func get<T: ASBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        completion: @escaping (Any?, Error?) -> Void
-    ) -> Request  {
-        let urlString = urlType.getUrlString()
-        return request(method: .get, urlString: urlString, parameters:parameters) { result in
-            switch result {
-            case .success(let data):
-                completion(data,nil)
-            case .failure(let error):
-                completion(nil,error)
-            }
-        }
-    }
-
-
-    /// 通用 POST 请求
-    /// - Parameters:
-    ///   - endpoint: 接口路径
-    ///   - parameters: 请求参数
-    ///   - responseType: 响应数据模型(可选)
-    ///   - completion: 请求完成的回调
-    func post<T: ASBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        completion: @escaping (Any?, Error?) -> Void
-    ) -> Request {
-        let urlString = urlType.getUrlString()
-        return request(method: .post, urlString: urlString, parameters:parameters) { result in
-            switch result {
-            case .success(let data):
-                completion(data,nil)
-            case .failure(let error):
-                completion(nil,error)
-            }
-        }
-    }
-    
-    /// 上传多个 Data 数据
-    /// - Parameters:
-    ///   - urlType: TSNeURLType
-    ///   - dataArray: Data 数组,每个元素是一个字典,包含 Data 和字段名
-    ///   - parameters: 其他参数(可选)
-    ///   - headers: 自定义请求头(可选)
-    ///   - completion: 完成回调,返回结果或错误
-    func uploadData<T: ASBaseModel>(
-        urlType: TSNeURLType,
-        dataArray: [[String: Any]], // Data 数组,每个元素包含 Data 和字段名
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        progressHandler: @escaping (Float) -> Void, // 上传进度回调
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) -> Request?{
-        let urlString = urlType.getUrlString()
-        let request = uploadData(urlString: urlString,dataArray:dataArray, parameters: parameters, progressHandler: { progress in
-            progressHandler(Float(progress.fractionCompleted))
-        },completion: completion)
-        return request
-    }
-    
-    func downloadFile(
-        urlString: String,
-        to destination: URL,
-        progressHandler: ((Double) -> Void)? = nil,
-        completion: @escaping (URL?, Error?) -> Void
-    ) -> DownloadRequest? {
-        let request = self.downloadFile(
-            urlString: urlString,
-            to: destination,
-            progressHandler: { progress in
-                print("下载进度: \(progress * 100)%")
-                progressHandler?(progress)
-            },
-            completion: { result in
-                switch result {
-                case .success(let fileURL):
-                    logPrint("下载完成,文件保存在: \(fileURL.path)")
-                    completion(fileURL,nil)
-                case .failure(let error):
-                    logPrint("下载失败: \(error.localizedDescription)")
-                    completion(nil,error)
-                }
-            }
-        )
-        return request
-    }
-
-}
-
-extension TSNetworkManager {
-
-    func uploadAudio(
-        fileURL:URL,
-        progressHandler: @escaping (Float) -> Void, // 上传进度回调
-        completion: @escaping (Any?, Error?) -> Void)
-    -> Request?{
-
-        let urlString = TSNeURLType.upload.getUrlString()
-        
-        
-        logPrint("✈️✈️✈️网络请求:\(urlString)")
-        guard let url = URL(string: urlString) else {
-            completion(nil,NSError(domain: "url nil", code: 0))
-            return nil
-        }
-        return AF.upload(
-            multipartFormData: { multipart in
-                multipart.append(fileURL, withName: "file", fileName: "audio.mp3", mimeType: "audio/mp3")
-            },
-            to: url
-        )
-        .uploadProgress { progress in
-            logPrint("✈️✈️✈️进度: \(progress.fractionCompleted * 100)%")
-            progressHandler(Float(progress.fractionCompleted))
-        }
-        .responseString { response in
-            self.handleResponse(response) { [weak self] result in
-                guard let self = self else { return }
-                switch result {
-                case .success(let data):
-                    if let dataDict = kNetWorkCodeSuccess(data: data),
-                       let picUrl = dataDict["result"] as? String{
-                        completion(picUrl,nil)
-                    }else{
-                        let error = NSError(domain: "Service exception", code: 0)
-                        completion(nil,error)
-                    }
-                case .failure(let error):
-                    completion(nil,error)
-                }
-            }
-        }
-    }
-}
-

+ 0 - 111
AIPlayRingtones/Common/TSNetWork/TSNetWork+Error.swift

@@ -1,111 +0,0 @@
-//
-//  TSNetWork+Error.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/18.
-//
-
-
-import Alamofire
-let kGenerateFailed:String = "Sorry there was a slight problem with the image processing, please try again later.".localized
-
-enum TSNetWorkCode : Int {
-    case success = 200
-    case fail = 0   //通用错误
-    case textSensitive = -10003    //文生图敏感错误
-    case imageSensitive = -10004   //图生图敏感错误
-    case networkError = -1005   //网络错误
-    
-    
-    var errorMsg:String {
-        switch self {
-        case .textSensitive,.imageSensitive:
-            return "Your ringtone or text may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again.".localized
-        case .networkError:
-            return "No network, please check your network and try again.".localized
-        default:
-            return "Sorry there was a slight problem with the ringtone processing, please try again later.".localized
-        }
-        
-    }
-    
-    //获取生成错误 code 对应的文案
-    static func errorMsg(code:Int)->String{
-        let netCode = TSNetWorkCode(rawValue: code) ?? .fail
-        return netCode.errorMsg
-    }
-    //敏感错误
-    static func sensitiveError(code:Int)->Bool{
-        let netCode = TSNetWorkCode(rawValue: code)
-        switch netCode {
-        case .textSensitive,.imageSensitive:
-            return true
-        default:
-            return false
-        }
-    }
-    
-    //网络错误错误
-    static func networkError(code:Int)->Bool{
-        let netCode = TSNetWorkCode(rawValue: code)
-        switch netCode {
-        case .networkError:
-            return true
-        default:
-            return false
-        }
-    }
-    
-    //网络错误错误
-    static func getErrorCode(_ error: Error) -> Int {
-        if let urlError = error as? URLError {
-            switch urlError.code {
-            case .notConnectedToInternet, .networkConnectionLost:
-                return TSNetWorkCode.networkError.rawValue
-            default:
-                return urlError.code.rawValue
-            }
-        }
-        return 0
-    }
-    //获取生成错误 code 对应的文案
-    static func getGeneratorStyle(code:Int)->ASGeneratorView.Style{
-        let netCode = TSNetWorkCode(rawValue: code)
-        switch netCode {
-        case .textSensitive,.imageSensitive:
-            return ASGeneratorView.Style.sensitiveError
-        case .networkError:
-            return ASGeneratorView.Style.netWorkError
-        default:
-            return ASGeneratorView.Style.generalError
-        }
-    }
-}
-
-
-extension Error {
-    
-    var tsCode:Int {
-        if let error = self as? AFError, let underlyingError = error.underlyingError as? URLError {
-            switch underlyingError.code {
-            case .notConnectedToInternet, .networkConnectionLost,.timedOut:
-                return TSNetWorkCode.networkError.rawValue
-            default:
-                return underlyingError.code.rawValue
-            }
-        }else
-        if let urlError = self as? URLError {
-            switch urlError.code {
-            case .notConnectedToInternet, .networkConnectionLost,.timedOut:
-                return TSNetWorkCode.networkError.rawValue
-            default:
-                return urlError.code.rawValue
-            }
-        }
-        return 0
-    }
-    
-    var tsDesc:String {
-        return TSNetWorkCode.errorMsg(code: tsCode)
-    }
-}

+ 0 - 397
AIPlayRingtones/Common/TSNetWork/TSNetworkManager.swift

@@ -1,397 +0,0 @@
-//
-//  NetworkManager.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/16.
-//
-
-import Alamofire
-import ObjectMapper
-
-
-let TSNetworkShared = TSNetworkManager.shared
-
-/// 网络工具类
-class TSNetworkManager {
-    
-    static let shared = TSNetworkManager()
-    private init() {}
-    
-    /// 通用 Headers
-    private var defaultHeaders: HTTPHeaders {
-        return ["Content-Type": "application/json",
-                "accept": "application/json",
-        ]
-    }
-    
-    lazy var afSession: Session = {
-        return AF
-    }()
-    lazy var encoder: JSONEncoding = {
-        return JSONEncoding(options: .withoutEscapingSlashes)// 关键:禁用斜杠转义
-    }()
-
-    func postStreamRequest(
-        urlString: String,
-        parameters: [String: Any]? = nil,
-        streamHandler:@escaping (String) -> Void,
-        completion: @escaping (Result<Any, Error>) -> Void
-    )-> Request? {
-        
-        guard let url = URL(string: urlString) else {
-            completion(.failure(NSError(domain: "url nil", code: 0)))
-            return nil
-        }
-        
-        // 1. 创建 URLRequest
-        var urlRequest = URLRequest(url:URL(string: urlString)!)
-        urlRequest.httpMethod = "POST"
-        urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
-        
-        // 2. 将字典参数转换为 JSON 数据并设置为请求体
-        do {
-            let jsonData = try JSONSerialization.data(withJSONObject: parameters, options: [.withoutEscapingSlashes])//去掉转义
-            urlRequest.httpBody = jsonData
-        } catch {
-            logPrint("Failed to encode parameters: \(error)")
-            completion(.failure(error))
-            return nil
-        }
-        
-        // 3. 使用 streamRequest 发起流式请求
-        let request = afSession.streamRequest(urlRequest)
-        request.responseStreamString{ stream in
-            switch stream.event {
-            case .stream(let result):
-                switch result {
-                case .success(let string):
-                    logPrint("🚰🚰🚰Stream Received string string: \(string)")
-                    streamHandler(string)
-                case .failure(let error):
-                    logPrint("Stream error: \(error)")
-                    completion(.failure(error))
-                }
-            case .complete(let cpl):
-                if let error = cpl.error {
-                    logPrint("Stream Request failed with error: \(error)")
-                    completion(.failure(error))
-                } else {
-                    logPrint("Stream success")
-                    completion(.success("Stream success"))
-                }
-            }
-        }
-        return request
-    }
-
-    func request(
-        method:HTTPMethod,
-        urlString: String,
-        parameters: [String: any Any & Sendable]? = nil,
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) -> Request{
-        logPrint("✈️✈️✈️网络请求:\(urlString)")
-        logPrint("✈️✈️✈️参数:\(String(describing: parameters))")
-        
-        var encoding: ParameterEncoding = URLEncoding.default
-        if method == .post {
-            encoding = encoder
-        }
-        let request = afSession.request(urlString, method: method, parameters: parameters, encoding: encoding, headers: defaultHeaders, interceptor: nil)
-        request.responseString { response in
-                self.handleResponse(response, completion: completion)
-            }
-        return request
-    }
-    
-
-    
-}
-
-extension TSNetworkManager {
-    
-    /// 上传多个 Data 数据
-    /// - Parameters:
-    ///   - url: 上传地址
-    ///   - dataArray: Data 数组,每个元素是一个字典,包含 Data 和字段名
-    ///   - parameters: 其他参数(可选)
-    ///   - headers: 自定义请求头(可选)
-    ///   - completion: 完成回调,返回结果或错误
-    func uploadData(
-        urlString: String,
-        dataArray: [[String: Any]], // Data 数组,每个元素包含 Data 和字段名
-        parameters: [String: Any]? = nil, // 其他参数
-        headers: HTTPHeaders? = nil, // 自定义请求头
-        progressHandler: @escaping (Progress) -> Void, // 上传进度回调
-        completion: @escaping (Result<Any, Error>) -> Void
-    )-> Request? {
-        
-        guard let url = URL(string: urlString) else {
-            completion(.failure(NSError(domain: "url nil", code: 0)))
-            return nil
-        }
-        
-        // 1. 设置默认请求头
-        var defaultHeaders: HTTPHeaders = [
-            "accept": "application/json",
-            "Content-Type": "multipart/form-data"
-        ]
-        // 合并自定义请求头
-        if let customHeaders = headers {
-            customHeaders.forEach { defaultHeaders[$0.name] = $0.value }
-        }
-        
-        logPrint("✈️✈️✈️网络请求:\(urlString)")
-        logPrint("✈️✈️✈️dataArray:\(String(describing: dataArray))")
-        logPrint("✈️✈️✈️参数:\(String(describing: parameters))")
-        // 2. 使用 Alamofire 上传 Data
-        let request = afSession.upload(
-            multipartFormData: { multipartFormData in
-                // 添加 Data
-                for dataItem in dataArray {
-                    if let data = dataItem["data"] as? Data,
-                       let fieldName = dataItem["fieldName"] as? String,
-                       let fileName = dataItem["fileName"] as? String,
-                       let mimeType = dataItem["mimeType"] as? String {
-                        multipartFormData.append(
-                            data,
-                            withName: fieldName,
-                            fileName: fileName,
-                            mimeType: mimeType
-                        )
-                    }
-                }
-
-                // 添加其他参数
-                if let parameters = parameters {
-                    for (key, value) in parameters {
-                        if let data = "\(value)".data(using: .utf8) {
-                            multipartFormData.append(data, withName: key)
-                        }
-                    }
-                }
-            },
-            to: url, // 上传地址
-            headers: defaultHeaders // 请求头
-        )
-        
-        request
-            .uploadProgress{ progress in
-                // 3. 上传进度回调
-                // 上传进度回调
-                logPrint("✈️✈️✈️进度: \(progress.fractionCompleted * 100)%")
-                progressHandler(progress)
-            }
-            .responseString{ response in
-                // 4. 处理响应
-                self.handleResponse(response, completion: completion)
-        }
-        
-        return request
-    }
-    
-    //上传文件地址到服务器
-    func uploadFile(
-        urlString: String,
-        fileURL:URL,
-        multipartBuilder: @escaping (MultipartFormData) -> Void, // 闭包参数
-        progressHandler: @escaping (Progress) -> Void, // 上传进度回调
-        completion: @escaping (Result<Any, Error>) -> Void
-    )-> Request?{
-        logPrint("✈️✈️✈️网络请求:\(urlString)")
-        guard let url = URL(string: urlString) else {
-            completion(.failure(NSError(domain: "url nil", code: 0)))
-            return nil
-        }
-        return AF.upload(
-            multipartFormData: multipartBuilder,
-            to: url
-        )
-        .uploadProgress { progress in
-            logPrint("✈️✈️✈️进度: \(progress.fractionCompleted * 100)%")
-            progressHandler(progress)
-        }
-        .responseString { response in
-            self.handleResponse(response, completion: completion)
-        }
-    }
-    
-    
-    /// 下载文件
-    /// - Parameters:
-    ///   - url: 下载URL
-    ///   - destination: 目标保存路径 (可选,不传则使用临时目录)
-    ///   - progressHandler: 进度回调 (0.0~1.0)
-    ///   - completion: 完成回调 (返回文件URL或错误)
-    func downloadFile(
-        urlString: String,
-        to destination: URL? = nil,
-        progressHandler: ((Double) -> Void)? = nil,
-        completion: @escaping (Result<URL, Error>) -> Void
-    ) -> DownloadRequest? {
-        
-        
-        guard let url = URL(string: urlString) else {
-            completion(.failure(NSError(domain: "url nil", code: 0)))
-            return nil
-        }
-        
-        // 设置下载目标路径
-        let destination: DownloadRequest.Destination = { temporaryURL, response in
-            // 如果用户指定了目标路径
-            if let destination = destination {
-                // 确保目录存在
-                let directory = destination.deletingLastPathComponent()
-                try? FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
-                return (destination, [.removePreviousFile, .createIntermediateDirectories])
-            }
-            
-            // 否则使用临时目录
-            let documentsURL = FileManager.default.temporaryDirectory
-            let suggestedFilename = response.suggestedFilename ?? url.lastPathComponent
-            let fileURL = documentsURL.appendingPathComponent(suggestedFilename)
-            
-            return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
-        }
-        
-        // 开始下载
-        let request = afSession.download(url, to: destination)
-            .downloadProgress { progress in
-                // 主线程回调进度
-                DispatchQueue.main.async {
-                    progressHandler?(progress.fractionCompleted)
-                }
-            }
-            .response { response in
-                // 主线程回调结果
-                DispatchQueue.main.async {
-                    switch response.result {
-                    case .success(let fileURL):
-                        if let fileURL = fileURL {
-                            completion(.success(fileURL))
-                        } else {
-                            completion(.failure(NSError(domain: "DownloadError", code: -1, userInfo: [NSLocalizedDescriptionKey: "文件路径无效"])))
-                        }
-                    case .failure(let error):
-                        completion(.failure(error))
-                    }
-                }
-            }
-        
-        return request
-    }
-
-}
-
-extension TSNetworkManager {
-    
-    func handleResponse(
-        _ response: AFDataResponse<String>,
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) {
-        
-        switch response.result {
-        case .success(let value):
-            if let resultDict = dataToJSONObject(data:response.data) as? [String:Any] {
-                handleSuccess(data: resultDict, response: response, completion: completion)
-            }else{
-                handleFail(error: NSError(domain: "Unable to parse data", code: 0), response: response, completion: completion)
-            }
-
-        case .failure(let error):
-            handleFail(error: error, response: response, completion: completion)
-        }
-    }
-    
-    func handleSuccess(data:Any,
-                       response: AFDataResponse<String>,
-                       completion: @escaping (Result<Any, Error>) -> Void){
-        logPrint("🚗🚗🚗网络请求成功:\(String(describing: response.request?.url?.absoluteString))")
-        logPrint("🚗🚗🚗网络请求成功:\(response)")
-        completion(.success(data))
-       }
-    
-    func handleFail(error:Error,
-                    response: AFDataResponse<String>,
-                    completion: @escaping (Result<Any, Error>) -> Void){
-        logPrint("🚗🚗🚗网络请求失败:\(String(describing: response.request?.url?.absoluteString))")
-        logPrint("🚗🚗🚗网络请求失败:\(response)")
-        completion(.failure(error))
-    }
-    
-    func dataToJSONObject(data: Data?) -> Any? {
-        guard let data = data else { return nil }
-        do {
-            let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
-            return jsonObject
-        } catch {
-            print("Failed to convert Data to JSON object: \(error.localizedDescription)")
-            return nil
-        }
-    }
-    
-}
-
-
-
-func kNetWorkCodeSuccess(data:Any?) -> [String:Any]? {
-    guard let data = data else { return nil }
-    if let dataDict = data as? [String:Any],
-        let code = dataDict["code"] as? Int{
-        switch code {
-        case 200://成功
-            return dataDict
-//        case 400://机器人提示
-//            TSAbnormalPopUpAlertVC.showRobotWarning()
-//            return nil
-        default:
-            return nil
-        }
-    }
-    return nil
-}
-
-
-
-func kNetWorkResultSuccess(data:Any?) -> [String:Any]? {
-    guard let dataDict = kNetWorkCodeSuccess(data: data) else { return nil }
-    if let result = dataDict["result"] as? [String:Any]{
-        return result
-    }
-    return nil
-}
-
-func kNetWorkMessage(data:Any?) -> String? {
-    guard let data = data else { return nil }
-    if let dataDict = data as? [String:Any] ,
-       let message = dataDict["message"] as? String{
-        return message
-    }
-    return nil
-}
-
-  
-
-class JsonStringTransform<T:Mappable>: TransformType {
-    typealias Object = T
-    typealias JSON = [String: Any]
-    
-    func transformFromJSON(_ value: Any?) -> T? {
-    
-        if let jsonString = value as? String {
-            let obj = T(JSONString: jsonString)
-            return obj
-        }
-        
-        if let dict = value as? [String: Any] {
-            let obj = T(JSON: dict)
-            return obj
-        }
-
-        return nil
-    }
-    
-    func transformToJSON(_ value: T?) -> [String : Any]? {
-        return value?.toJSON() as? [String: Any]
-    }
-}

+ 2 - 2
AIPlayRingtones/CommonView/ASGeneratorView/ASGeneratorView.swift

@@ -173,9 +173,9 @@ extension ASGeneratorView{
     }
     
     func updateShowError(text:String,code:Int){
-        self.style = TSNetWorkCode.getGeneratorStyle(code: code)
+        self.style = ASErrorCode.interfaceStyle(for: code)
         isHidden = false
-        showError(text: text.isEmpty ? kGenerateFailed : text)
+        showError(text: text.isEmpty ? kDefaultErrorMessage : text)
         isRotating = false
         setBackgroundGenerateBtnHidden(true)
     }

+ 2 - 2
AIPlayRingtones/Data/ASActionInfoModel.swift

@@ -148,11 +148,11 @@ class ASActionResponseModel : ASBaseModel {
     
     //获取生成错误 code 对应的文案
     var codeErrorMsg:String {
-        TSNetWorkCode.errorMsg(code: code)
+        ASErrorCode.message(for: code)
     }
     //敏感错误
     var sensitiveError:Bool {
-        return TSNetWorkCode.sensitiveError(code: code)
+        return ASErrorCode.isContentFlagged(code)
     }
 }
 

+ 1 - 1
AIPlayRingtones/OperationQueue/ASProgressState.swift

@@ -60,6 +60,6 @@ enum ASProgressState  {
     }
     
     static var generalNormalFailed:ASProgressState {
-        return .failed(TSNetWorkCode.fail.errorMsg, TSNetWorkCode.fail.rawValue)
+        return .failed(ASErrorCode.generalFailure.localizedDescription, ASErrorCode.generalFailure.rawValue)
     }
 }

+ 2 - 2
AIPlayRingtones/OperationQueue/Generate/ASGenerateBaseOperation.swift

@@ -121,7 +121,7 @@ class ASGenerateBaseOperation: ASBaseOperation , @unchecked Sendable{
         self.action_id = action_id
         
               
-        queryRequest = TSNetworkShared.get(urlType: .actionInfo,parameters: ["action_id":action_id]) { [weak self] data,error in
+        queryRequest = ASNetworkShared.executeGET(endpoint: .checkProgress,params: ["action_id":action_id]) { [weak self] data,error in
             guard let self = self else { return }
             
             if stopNetwork == true {
@@ -130,7 +130,7 @@ class ASGenerateBaseOperation: ASBaseOperation , @unchecked Sendable{
             
             if let error = error {
                 logPrint("getActionInfo error error = \(error)")
-                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                handleFailInfoModel(errorString: error.xhLocalizedMessage,code: error.xhStatusCode)
                 return
             }
             

+ 2 - 2
AIPlayRingtones/OperationQueue/Generate/ASGenerateRingToRingOperation.swift

@@ -46,7 +46,7 @@ class ASGenerateRingToRingOperation: ASGenerateTextToRingOperation , @unchecked
         stateDatauPblished = (.start,nil)
         
         stateDatauPblished = (.progress(0.0,uploadingString(progress: 0.0)),currentActionInfoModel)
-        uploadRequest = TSNetworkShared.uploadAudio(fileURL: upLoadFilePath, progressHandler: { [weak self]  progress in
+        uploadRequest = ASNetworkShared.sendAudioFile(audioFileURL: upLoadFilePath, uploadProgress: { [weak self]  progress in
             guard let self = self else { return }
             if generatingProgress == 0 {
                 stateDatauPblished = (.progress(progress,uploadingString(progress: progress)),currentActionInfoModel)
@@ -56,7 +56,7 @@ class ASGenerateRingToRingOperation: ASGenerateTextToRingOperation , @unchecked
             if stopNetwork == true { return }
             if let error = error {
                 generateStyleModel.upLoadUrl = nil
-                self.stateDatauPblished = (ASProgressState.getFailed(error.tsDesc,error.tsCode),nil)
+                self.stateDatauPblished = (ASProgressState.getFailed(error.xhLocalizedMessage,error.xhStatusCode),nil)
                 complete(nil)
             }else{
                 if let string = data as? String {

+ 3 - 3
AIPlayRingtones/OperationQueue/Generate/ASGenerateTextToRingOperation.swift

@@ -225,18 +225,18 @@ class ASGenerateTextToRingOperation: ASGenerateBaseOperation , @unchecked Sendab
         
         var parameters:[String:Any] = ["prompt":prompt,
                                        "duration":request.duration,
-                                       "device":getUserInfoJsonString()
+                                       "device":ASDeviceInfo.systemMetadata
                                        ]
         if request.uploadUrl.count > 0 {
             parameters["audioUrl"] = request.uploadUrl
         }
         
-        creatRequest = TSNetworkShared.post(urlType: .musicCreate,parameters:parameters) { [weak self] data,error in
+        creatRequest = ASNetworkShared.executePOST(endpoint: .generateAudio,params:parameters) { [weak self] data,error in
             guard let self = self else { return }
             if stopNetwork == true { return }
             
             if let error = error {
-                handleFailInfoModel(errorString: error.tsDesc,code: error.tsCode)
+                handleFailInfoModel(errorString: error.xhLocalizedMessage,code: error.xhStatusCode)
                 complete(false)
             }else{
                 if let dataDict = kNetWorkCodeSuccess(data: data),