Browse Source

补充剩下的提交

kln 2 weeks ago
parent
commit
f7656709a6

+ 0 - 10
AIPlayRingtones/AppPage/APMyRingVC/APMyRingVC.swift

@@ -1,10 +0,0 @@
-//
-//  APMyRingVC.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/15.
-//
-
-class APMyRingVC: TSBaseVC {
-    
-}

+ 0 - 22
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/Contents.json

@@ -1,22 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "filename" : "nav_titile_audioRingtone@2x.png",
-      "idiom" : "universal",
-      "scale" : "2x"
-    },
-    {
-      "filename" : "nav_titile_audioRingtone@3x.png",
-      "idiom" : "universal",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "author" : "xcode",
-    "version" : 1
-  }
-}

BIN
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@2x.png


BIN
AIPlayRingtones/Assets.xcassets/AudioToRingtone/nav_titile_audioRingtone.imageset/nav_titile_audioRingtone@3x.png


+ 0 - 21
AIPlayRingtones/Assets.xcassets/MyRing/nav_title_ringtones.imageset/Contents.json

@@ -1,21 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "filename" : "nav_title_ringtones@2x.png",
-      "idiom" : "universal",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "author" : "xcode",
-    "version" : 1
-  }
-}

BIN
AIPlayRingtones/Assets.xcassets/MyRing/nav_title_ringtones.imageset/nav_title_ringtones@2x.png


+ 0 - 21
AIPlayRingtones/Common/ Notification+Ex.swift

@@ -1,21 +0,0 @@
-//
-//   Notification+Ex.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/16.
-//
-
-import Foundation
-
-extension Notification.Name {
-    static let kApplicationWillTerminate = Notification.Name("applicationWillTerminate")
-    static let kVipFreeNumChanged = Notification.Name("kVipFreeNumChanged")   //Vip免费次数发生变化
-    static let kRefreshSettingView = Notification.Name("kRefreshSettingView")   //刷新设置按钮
-    
-    static let kBaseOperationQueueCountChanged = Notification.Name("kBaseOperationQueueCountChanged") //任务数量放生变化
-    static let kGeneratePTPOperationChanged = Notification.Name("kGeneratePTPOperationChanged") //生成图生图任务发生变化
-    
-    static let kTextToRingDataChanged = Notification.Name("kTextToRingDataChanged") //文生铃声数据改变
-    static let kRingToRingDataChanged = Notification.Name("kRingToRingDataChanged") //铃声生铃声数据改变
-
-}

+ 0 - 7
AIPlayRingtones/Common/AIEnums.swift

@@ -1,7 +0,0 @@
-//
-//  AIEnums.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/15.
-//
-

+ 0 - 8
AIPlayRingtones/Common/Common.swift

@@ -1,8 +0,0 @@
-//
-//  Common.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/15.
-//
-
-@_exported import TSSmalCoacopods

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

@@ -1,231 +0,0 @@
-//
-//  TSNetWork+Business.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/16.
-//
-
-/// 基础 URL(根据需求修改)
-private let baseURL = "http://ai.100yearslater.com"
-private let baseChinaURL = "http://ai.100yearslater100.com"
-import Alamofire
-enum TSNeURLType:String {
-    
-    case imageEmoji = "/api/image/emoji"         //文生emoji
-    case actionInfo = "/api/action/info"         //查询生成过程接口
-    case chat = "/api/text/chat"                 //AI 对话接口
-    case textPicCreate = "/api/image/create"     //文生图
-    case upload = "/api/upload"                  //上传图片
-    case imageRewrite = "/api/image/rewrite"     //图生图
-    case imageToImageStyle = "/api/ops/aichat-img2img-config"     //图生图 风格列表
-    case chatV2 = "/api/text/chat/v2"             //AI 对话接口V2,扩展了 DeepSeek 深度思考
-    
-    case config = "/api/ops/aichat-config"       //App配置
-    
-    case changeAge = "/api/image/change-age"       //换年龄
-    case subscriptionApple = "/api/subscription/apple"       //苹果订阅
-    case changeEmotion = "/api/image/change-emotion"       //更换表情
-    case changeHair = "/api/image/change-hair"       //更换头发
-    case imageRestore = "/api/image/restore"          //老照片修复
-    case eyeOpen = "/api/image/eye-open"          //睁眼
-    case pretty = "/api/image/pretty"          //美容
-    case photoAnimation = "/api/image/animation"          //照片变活
-    case photoExpand = "/api/image/outpaint"          //照片扩展
-    
-    case overResolution = "/api/image/over-resolution"          //图片超分辨率
-    case changeClothes = "/api/image/change-clothes"          //换衣服
-
-    
-    func getUrlString() -> String {
-        if Locale.current.identifier.contains("_CN") {//中国区
-            return baseChinaURL + self.rawValue
-        }else{
-            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":UIDevice.current.modelName,
-//        "deviceId":uuid,
-//        "iosVersion":UIDevice.current.systemVersion,
-//        "appVersion":appShortVersion(),
-//        "subscriptionStatus":kPurchaseDefault.isVip ? "active" : "fallow",
-//    ]
-
-    return [String:Any]()
-}
-
-
-func getLanguageCode()->String{
-    if Locale.current.identifier.contains("zh-Hant"){
-        return "zh-Hant"
-    }
-    if let languageCode = Locale.current.languageCode {
-//        print("当前设备语言简写: \(languageCode)") // 输出如 "en", "ja", "zh" 等
-        return languageCode
-    }
-    return "en"
-}
-
-
-extension TSNetworkManager {
-    
-    /// 通用 get 请求
-    func get<T: TSBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) -> Request  {
-        let urlString = urlType.getUrlString()
-        return request(method: .get, urlString: urlString, parameters:parameters) { result in
-            completion(result)
-        }
-    }
-
-
-    /// 通用 POST 请求
-    /// - Parameters:
-    ///   - endpoint: 接口路径
-    ///   - parameters: 请求参数
-    ///   - responseType: 响应数据模型(可选)
-    ///   - completion: 请求完成的回调
-    func post<T: TSBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) -> Request {
-        let urlString = urlType.getUrlString()
-        return request(method: .post, urlString: urlString, parameters:parameters) { result in
-            completion(result)
-        }
-    }
-    
-    /// 通用 POST Stream 请求
-    /// - Parameters:
-    ///   - endpoint: 接口路径
-    ///   - parameters: 请求参数
-    ///   - responseType: 响应数据模型(可选)
-    ///   - completion: 请求完成的回调
-    func postStream<T: TSBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        streamHandler:@escaping (String) -> Void,
-        completion: @escaping (Result<Any, Error>) -> Void
-    ) -> Request?{
-        let urlString = urlType.getUrlString()
-        let streamRequest = postStreamRequest(urlString: urlString, parameters: parameters, streamHandler: streamHandler, completion: completion)
-        return streamRequest
-    }
-
-    
-    /// 上传多个 Data 数据
-    /// - Parameters:
-    ///   - urlType: TSNeURLType
-    ///   - dataArray: Data 数组,每个元素是一个字典,包含 Data 和字段名
-    ///   - parameters: 其他参数(可选)
-    ///   - headers: 自定义请求头(可选)
-    ///   - completion: 完成回调,返回结果或错误
-    func uploadData<T: TSBaseModel>(
-        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):
-                    dePrint("下载完成,文件保存在: \(fileURL.path)")
-                    completion(fileURL,nil)
-                case .failure(let error):
-                    dePrint("下载失败: \(error.localizedDescription)")
-                    completion(nil,error)
-                }
-            }
-        )
-        return request
-    }
-
-}
-
-extension TSNetworkManager {
-    
-    func uploadData(
-        upLoadData:Data,
-        maxKb:Int,
-        progressHandler: @escaping (Float) -> Void, // 上传进度回调
-        completion: @escaping (Any?, Error?) -> Void)
-    -> Request?{
-        
-        var dataArray:[[String:Any]] = []
-        dataArray = [
-            ["data": upLoadData,
-             "fieldName": "file", // 字段名
-             "fileName": "audio.mp3", // 文件名
-             "mimeType": "audio/mpeg" // MIME 类型
-            ]
-        ]
-        
-        return TSNetworkShared.uploadData(
-            urlType: .upload,
-            dataArray: dataArray,
-            progressHandler: { progress in
-                progressHandler(progress)
-            },completion: { [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 photo 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 image 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 - 86
AIPlayRingtones/Common/TSNetWork/TSNetworkManager+Loading.swift

@@ -1,86 +0,0 @@
-//
-//  TSNetworkManager+Loading.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/16.
-//
-import Alamofire
-extension TSNetworkManager {
-    
-    /// 通用 get 请求
-    func get<T: TSBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        animationView:UIView? = nil,
-        completion: @escaping (Any?, Error?) -> Void
-    ) -> Request {
-        
-        var isShowAnimation = false
-        if animationView != nil {
-            isShowAnimation = true
-        }
-        
-        if isShowAnimation,let view = animationView {
-            TSToastShared.showLoading(containerView: view)
-        }
-
-        return get(urlType: urlType, parameters:parameters,responseType:responseType) { result in
-            
-            if isShowAnimation {
-                TSToastShared.hideLoading()
-            }
-    
-            switch result {
-            case .success(let data):
-//                print("Response data: \(data)")
-                completion(data,nil)
-            case .failure(let error):
-//                print("Error: \(error)")
-                completion(nil,error)
-            }
-        }
-    }
-
-
-    /// 通用 POST 请求
-    /// - Parameters:
-    ///   - endpoint: 接口路径
-    ///   - parameters: 请求参数
-    ///   - responseType: 响应数据模型(可选)
-    ///   - completion: 请求完成的回调
-    func post<T: TSBaseModel>(
-        urlType: TSNeURLType,
-        parameters: [String: Any]? = nil,
-        responseType: T.Type? = nil,
-        animationView:UIView? = nil,
-        completion: @escaping (Any?, Error?) -> Void
-    ) -> Request {
-        var isShowAnimation = false
-        if animationView != nil {
-            isShowAnimation = true
-        }
-        
-        if isShowAnimation,let view = animationView {
-            TSToastShared.showLoading(containerView: view)
-        }
-
-        return post(urlType: urlType, parameters:parameters,responseType:responseType){ result in
-            
-            if isShowAnimation {
-                TSToastShared.hideLoading()
-            }
-    
-            switch result {
-            case .success(let data):
-//                print("Response data: \(data)")
-                completion(data,nil)
-            case .failure(let error):
-//                print("Error: \(error)")
-                completion(nil,error)
-            }
-        }
-    
-    }
-    
-}

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

@@ -1,412 +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",
-//            "Authorization": "Bearer YOUR_ACCESS_TOKEN" // 按需修改
-        ]
-    }
-    
-    lazy var afSession: Session = {
-//        let configuration = URLSessionConfiguration.af.default
-//        configuration.timeoutIntervalForRequest = 15  // 请求超时时间(秒)
-//        configuration.timeoutIntervalForResource = 30 // 资源超时时间(秒)
-//        let session = Session(configuration: configuration)
-//        return 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 {
-            dePrint("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):
-                    dePrint("🚰🚰🚰Stream Received string string: \(string)")
-                    streamHandler(string)
-                case .failure(let error):
-                    dePrint("Stream error: \(error)")
-                    completion(.failure(error))
-                }
-            case .complete(let cpl):
-                if let error = cpl.error {
-                    dePrint("Stream Request failed with error: \(error)")
-                    completion(.failure(error))
-                } else {
-                    dePrint("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{
-        dePrint("✈️✈️✈️网络请求:\(urlString)")
-        dePrint("✈️✈️✈️参数:\(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 数组
-     let dataArray: [[String: Any]] = [
-         [
-             "data": imageData,
-             "fieldName": "file1", // 字段名
-             "fileName": "App-Icon.png", // 文件名
-             "mimeType": "image/png" // MIME 类型
-         ],
-         [
-             "data": textData,
-             "fieldName": "file2", // 字段名
-             "fileName": "hello.txt", // 文件名
-             "mimeType": "text/plain" // MIME 类型
-         ]
-     ]
-     */
-    
-    /// 上传多个 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 }
-        }
-        
-        dePrint("✈️✈️✈️网络请求:\(urlString)")
-        dePrint("✈️✈️✈️dataArray:\(String(describing: dataArray))")
-        dePrint("✈️✈️✈️参数:\(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. 上传进度回调
-                // 上传进度回调
-                dePrint("✈️✈️✈️进度: \(progress.fractionCompleted * 100)%")
-                progressHandler(progress)
-            }
-            .responseString{ response in
-                // 4. 处理响应
-                self.handleResponse(response, completion: completion)
-        }
-        
-        return request
-    }
-    
-    
-    /// 下载文件
-    /// - 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 {
-    
-    private 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] {
-                
-//                let code = resultDict.safeInt(forKey: "code")
-//                if responseType != nil {
-//                    if let model = T(JSONString: value) {
-//                        handleSuccess(data: model, response: response, completion: completion)
-//                    } else {
-//                        let models = Mapper<T>().mapArray(JSONString: value)
-//                        handleSuccess(data: models ?? [], response: response, completion: completion)
-//                    }
-//                } else {
-                    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){
-        dePrint("🚗🚗🚗网络请求成功:\(String(describing: response.request?.url?.absoluteString))")
-        dePrint("🚗🚗🚗网络请求成功:\(response)")
-        completion(.success(data))
-       }
-    
-    func handleFail(error:Error,
-                    response: AFDataResponse<String>,
-                    completion: @escaping (Result<Any, Error>) -> Void){
-        dePrint("🚗🚗🚗网络请求失败:\(String(describing: response.request?.url?.absoluteString))")
-        dePrint("🚗🚗🚗网络请求失败:\(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.safeInt(forKey: "code")
-        
-        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]
-    }
-}

+ 0 - 249
AIPlayRingtones/OperationQueue/Generate/ASGeneratePosterOperation.swift

@@ -1,249 +0,0 @@
-//
-//  ASGeneratePosterOperation.swift
-//  AIPlayRingtones
-//
-//  Created by 100Years on 2025/5/16.
-//
-
-import Combine
-import Alamofire
-import ObjectMapper
-import Kingfisher
-class ASGeneratePTPOperationQueue: ASGenerateBaseOperationQueue {
-    static let shared:ASGeneratePTPOperationQueue = ASGeneratePTPOperationQueue()
-
-    func creatOperation(uuid: String) -> ASGeneratePTPOperation {
-        let operation = super.creatOperation(uuid: uuid, type: ASGeneratePTPOperation.self)
-        handleStateDatauPblished(uuid: uuid, generateOperation: operation as! ASGenerateBaseOperation, notificationName: .kGeneratePTPOperationChanged)
-        return operation as! ASGeneratePTPOperation
-    }
-    
-    override func getUUIDData(uuid:String)->(ASProgressState,ASActionInfoModel?){
-        if let PosterOperation = ASGeneratePTPOperationQueue.shared.findOperation(uuid: uuid) as? ASGeneratePTPOperation {
-            dePrint("ASBaseOperation stateDatauPblished 发送 = \(PosterOperation.stateDatauPblished)")
-            return (PosterOperation.stateDatauPblished.0,PosterOperation.currentActionInfoModel)
-        }
-        return (.none,ASActionInfoModel())
-    }
-    
-}
-
-class ASGeneratePTPOperation: ASGenerateBaseOperation , @unchecked Sendable{
-    
-    //是否展示成功后的 View 提醒
-    public var isShowSuccessView:Bool = false
-    
-    override var actionInfoDict:[String:Any]{
-        return [
-            "actionType":"image_create",
-            "comments": "Success",
-            "costTime":9,
-            "createdTimestamp":1742183242,
-            "id":2449,
-            "percent":1,
-            "request":"{\"prompt\": \"Traditional Chinese ink painting style phoenix soaring through misty mountain peaks, dynamic black brushstrokes with crimson accents on rice paper texture, Googie architecture space station, 1950s atomic age aesthetic, curved aluminum panels, starburst patterns, glass dome observatory --edge_threshold 0.5 --atomic_age_style 0.8 --chrome_reflection 1.2\", \"width\": 800, \"height\": 1440, \"countryCode\": \"FR\"}",
-            "response": "{\"resultUrl\": \"https://be-aigc.s3-accelerate.amazonaws.com/4c946f78-b1e7-4ffe-ba18-fff26b10178c.png\"}",
-            "status":"success"
-        ]
-    }
-
-    override func replaceSaveInfoModel(model:ASActionInfoModel){
-        model.uuid = uuid
-        model.request.imageUrlTimestamp = currentActionInfoModel.request.imageUrlTimestamp
-        if isSaveDB {
-            ASRMShared.texToRingDBHistory.updateData(model,id: currentActionInfoModel.id)
-        }
-        currentActionInfoModel = model
-        dePrint("model actionStatus 发出=\(model.actionStatus)")
-        currentActionInfoModelChanged?(currentActionInfoModel)
-    }
-
-    override func handleGenerateSuccess() {
-//        kPurchaseDefault.useOnceForFree(type: .picToPic)
-        
-        if isShowSuccessView == false {
-            return
-        }
-        
-        
-        guard let window = WindowHelper.getKeyWindow() else {
-            debugPrint("getKeyWindow nil")
-            return
-        }
-        
-        guard let rootVC = WindowHelper.topViewController() else {
-            debugPrint("handleGenerateSuccess topViewController nil")
-            return
-        }
-        
-        let copyModel = self.currentActionInfoModel.copy()
-        if let cyModel = copyModel as? ASActionInfoModel {
-            let topY = k_Nav_Height+10
-            debugPrint("topY=\(topY)")
-            kSaveSuccesswShared.show(atView: window,text: "Successfully generated".localized,deadline: 5.0,bottom: kSaveSuccesswShared.getBottom(topY: topY)) {
-//                let gennerateVC = ASPTPGeneratorVC(generateStyleModel: ASGenerateStyleModel(),infoModel: cyModel) { model in }
-//                gennerateVC.modalPresentationStyle = .overFullScreen
-//                gennerateVC.modalTransitionStyle = .crossDissolve
-//                rootVC.present(gennerateVC, animated: true)
-            }
-        }else{
-            debugPrint("copyModel as? ASActionInfoModel error")
-        }
-    }
-    
-
-    /**
-        1.用户上传图片
-        2.调用生成接口
-        3.后台返回查询 id,根据 id 不断查询进度和结果.(此时才允许进度后台)
-     
-        利用3后台返回的ASActionRequestModel中存着关键的请求接口数据,请求数据
-     
-     */
-    
-    private var uploadRequest:Request?
-    private var creatRequest:Request?
-    
-    private func createActionInfoModel(generateStyleModel:ASGenerateStyleModel) -> ASActionInfoModel? {
-
-        guard let upLoadData = generateStyleModel.upLoadData else { return nil }
-
-        let infoModel = ASActionInfoModel()
-        infoModel.id = Date.timestampInt
-        infoModel.request = ASActionRequestModel()
-        infoModel.request.imageUrl = ""
-        infoModel.request.imageUrlTimestamp = Date.timestampInt
-        
-        infoModel.request.prompt = generateStyleModel.prompt
-  
-        return infoModel
-    }
-    
-    func uploadImage(generateStyleModel:ASGenerateStyleModel,complete:@escaping (ASActionInfoModel?)->Void) {
-        
-        guard let upLoadData = generateStyleModel.upLoadData else { return  }
-        if let uploadUrl = generateStyleModel.upLoadRingUrl,uploadUrl.contains("http") {
-            complete(createActionInfoModel(generateStyleModel: generateStyleModel))
-            return
-        }
-        
-        stopNetwork = false
-        stateDatauPblished = (.start,nil)
-        
-        stateDatauPblished = (.progressString(uploadingPhoto(progress: 0.0)),currentActionInfoModel)
-//        uploadRequest = TSNetworkShared.uploadImage(upLoadImage: upLoadImage, maxKb: imageMaxKb) { [weak self]  progress in
-//            guard let self = self else { return }
-//            if generatingProgress == 0 {
-//                stateDatauPblished = (.progressString(uploadingPhoto(progress: progress)),currentActionInfoModel)
-//            }
-//        } completion: { [weak self]  data, error in
-//            guard let self = self else { return }
-//            if stopNetwork == true { return }
-//            if let error = error {
-//                generateStyleModel.upLoadImageUrl = nil
-//                self.stateDatauPblished = (ASProgressState.getFailed(error.tsDesc,error.tsCode),nil)
-//                complete(nil)
-//            }else{
-//                if let string = data as? String {
-//                    generateStyleModel.upLoadImageUrl = string
-//                    if let url = URL(string: string){//上传成功后,就将图片缓存到本地
-//                        ImageCache.default.store(upLoadImage, forKey: url.cacheKey)
-//                    }
-//                    
-//                    complete(createActionInfoModel(generateStyleModel: generateStyleModel))
-//                }else{
-//                    complete(nil)
-//                }
-//            }
-//        }
-    }
-    
-    func creatImage(oldModel:ASActionInfoModel) {
-        
-        initializeActionInfoModel(oldModel: oldModel)
-        if oldModel.isExpired { return  }
-
-        generatingProgress = 0
-        stopNetwork = false
-        stateDatauPblished = (.start,nil)
-        
-        
-        currentActionInfoModel.status = "running"
-        currentActionInfoModel.actionStatus = .running
-        currentActionInfoModel.percent = 0
-        replaceSaveInfoModel(model: currentActionInfoModel)
-        
-        stateDatauPblished = (.progressString(generating(progress: 0.0)),currentActionInfoModel)
- 
-        
-        let request = currentActionInfoModel.request
-        var prompt = request.prompt
-        let promptSort = request.promptSort
-        
-        if promptSort.count>0{
-            if prompt.count > 0 {
-                prompt = prompt + ", " + promptSort
-            }else {
-                prompt = promptSort
-            }
-        }
-        
-        creatRequest = TSNetworkShared.post(urlType: .imageRewrite,parameters:
-                                                ["prompt":prompt,
-                                                 "imageUrl":request.imageUrl,
-                                                 "style":request.style,
-                                                 "device":getUserInfoJsonString(),
-                                                 "advance": request.advance
-                                                ]) { [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)
-            }else{
-                if let dataDict = kNetWorkCodeSuccess(data: data),
-                   let actionId = dataDict["actionId"] as? Int{
-                    if stopNetwork == false {
-                        self.stateDatauPblished = (.pending,nil) //通知首页进行更新
-                        self.getActionInfo(action_id:actionId)
-                    }
-                }else{
-                    handleFailInfoModel(errorString: "",code: 0)
-                }
-            }
-        }
-    }
-    override func generating(progress: Float) -> String {
-        let progress = Float(progress)*(0.9) // 预留 10% 进度给图片下载
-        //Generating 0%-100%
-        var progressInt = Int(progress*100)
-
-        if progressInt > 99 {
-            progressInt = 99
-        }
-        
-        generatingProgress = progressInt
-        return "Generating".localized + " \(progressInt)%"
-    }
-
-    var imageMaxKb:Int{
-        return 10*1024
-    }
-    
-    func uploadingPhoto(progress:Float) -> String {
-        //Uploading Photo 0%-100%
-        var progressInt = Int(progress*100)
-        if progressInt > 99 {
-            progressInt = 99
-        }
-        return "Uploading Photo".localized + " \(progressInt)%"
-    }
-    
-    
-    override func cancelCleanContent() {
-        super.cancelCleanContent()
-        debugPrint("cancelCleanContent")
-        uploadRequest?.cancel()
-        creatRequest?.cancel()
-    }
-}

BIN
AIPlayRingtones/Resources/GentleRingtoneExample.mp3


BIN
AIPlayRingtones/Resources/ringAnimation.gif


+ 0 - 57
AIPlayRingtones/Resources/ring_style.json

@@ -1,57 +0,0 @@
-[
-    {
-        "imageName": "ring_style_Normal",
-        "imageText": "Normal",
-        "prompt":"Dynamic ringtone, memorable hook, balanced highs and lows, versatile for any phone",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Pop",
-        "imageText": "Pop",
-        "prompt":"Upbeat pop ringtone, catchy melody, bright synths, energetic vocals, radio-friendly, modern production",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Rock",
-        "imageText": "Rock",
-        "prompt":"Electric guitar-driven rock ringtone, powerful drums, anthemic chords, energetic solo, stadium sound",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_HipHop",
-        "imageText": "Hip Hop",
-        "prompt":"Boom bap hip hop ringtone, hard-hitting drums, smooth bassline, old-school vinyl crackle",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Funk",
-        "imageText": "Funk",
-        "prompt":"Groovy funk ringtone, slap bass, tight drum breaks, wah-wah guitar, brass stabs",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Jazz",
-        "imageText": "Jazz",
-        "prompt":"Smooth jazz ringtone, relaxing piano, walking bass, brushed drums, late-night vibe",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Disco",
-        "imageText": "Disco",
-        "prompt":"Classic disco ringtone, four-on-the-floor beat, funky bassline, shimmering strings, retro vibe",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Electro",
-        "imageText": "Electro",
-        "prompt":"EDM-style electro ringtone, pulsating synths, sidechain compression, festival energy",
-        "vip": false
-    },
-    {
-        "imageName": "ring_style_Dubstep",
-        "imageText": "Dubstep",
-        "prompt":"Heavy dubstep ringtone, aggressive wobble bass, punchy drops, dark atmosphere",
-        "vip": false
-    }
-]
-