// // COSManagerAdapter.swift // yana // // Created by P on 2025/7/31. // import Foundation import UIKit import ComposableArchitecture // MARK: - COSManager 适配器 /// COSManager 适配器 /// /// 保持与现有 COSManager 相同的接口,但内部使用新的 TCCos 组件 /// 这样可以无缝替换现有的 COSManager,无需修改其他代码 @MainActor class COSManagerAdapter: ObservableObject { static let shared = COSManagerAdapter() private init() { // 使用默认的 TCCos 服务依赖 self.tokenService = COSTokenService(apiService: LiveAPIService()) self.uploadService = COSUploadService( tokenService: self.tokenService, configurationService: COSConfigurationService() ) self.configurationService = COSConfigurationService() debugInfoSync("�� COSManagerAdapter 已初始化,使用 TCCos 组件") } // MARK: - 内部 TCCos 组件 private let tokenService: COSTokenServiceProtocol private let uploadService: COSUploadServiceProtocol private let configurationService: COSConfigurationServiceProtocol // MARK: - 兼容性接口(与 COSManager 保持一致) /// 获取腾讯云 COS Token /// - Parameter apiService: API 服务实例 /// - Returns: Token 数据,如果获取失败返回 nil func getToken(apiService: any APIServiceProtocol & Sendable) async -> TcTokenData? { do { debugInfoSync("🔐 开始请求腾讯云 COS Token...") let tokenData = try await tokenService.getValidToken() debugInfoSync("✅ COS Token 获取成功") debugInfoSync(" - 存储桶: \(tokenData.bucket)") debugInfoSync(" - 地域: \(tokenData.region)") debugInfoSync(" - 过期时间: \(tokenData.expirationDate)") debugInfoSync(" - 剩余时间: \(tokenData.remainingTime)秒") return tokenData } catch { debugErrorSync("❌ COS Token 获取失败: \(error.localizedDescription)") return nil } } /// 强制刷新 Token func refreshToken(apiService: any APIServiceProtocol & Sendable) async -> TcTokenData? { do { debugInfoSync("🔄 开始刷新腾讯云 COS Token...") let tokenData = try await tokenService.refreshToken() debugInfoSync("✅ COS Token 刷新成功") debugInfoSync(" - 存储桶: \(tokenData.bucket)") debugInfoSync(" - 地域: \(tokenData.region)") debugInfoSync(" - 过期时间: \(tokenData.expirationDate)") return tokenData } catch { debugErrorSync("❌ COS Token 刷新失败: \(error.localizedDescription)") return nil } } /// 上传图片到腾讯云 COS /// - Parameters: /// - imageData: 图片数据 /// - apiService: API 服务实例 /// - Returns: 上传成功的云地址,如果失败返回 nil func uploadImage(_ imageData: Data, apiService: any APIServiceProtocol & Sendable) async -> String? { // 生成唯一文件名 let fileExtension = "jpg" let fileName = "images/\(UUID().uuidString).\(fileExtension)" do { debugInfoSync("🚀 开始上传图片,数据大小: \(imageData.count) bytes") let url = try await uploadService.uploadImage(imageData, fileName: fileName) debugInfoSync("✅ 图片上传成功: \(url)") return url } catch { debugErrorSync("❌ 图片上传失败: \(error.localizedDescription)") return nil } } /// 上传 UIImage 到腾讯云 COS,自动压缩为 JPEG(0.7) /// - Parameters: /// - image: UIImage 实例 /// - apiService: API 服务实例 /// - Returns: 上传成功的云地址,如果失败返回 nil func uploadUIImage(_ image: UIImage, apiService: any APIServiceProtocol & Sendable) async -> String? { // 生成唯一文件名 let fileExtension = "jpg" let fileName = "images/\(UUID().uuidString).\(fileExtension)" do { debugInfoSync("�� 开始上传 UIImage,自动压缩为 JPEG(0.7)") let url = try await uploadService.uploadUIImage(image, fileName: fileName) debugInfoSync("✅ UIImage 上传成功: \(url)") return url } catch { debugErrorSync("❌ UIImage 上传失败: \(error.localizedDescription)") return nil } } // MARK: - 只读属性(与 COSManager 保持一致) /// 外部安全访问 Token var token: TcTokenData? { get async { do { return try await tokenService.getValidToken() } catch { debugErrorSync("❌ 获取 Token 失败: \(error.localizedDescription)") return nil } } } // MARK: - 调试信息(与 COSManager 保持一致) /// 获取当前 Token 状态信息 func getTokenStatus() async -> String { return await tokenService.getTokenStatus() } /// 测试 Token 获取功能(仅用于调试) func testTokenRetrieval(apiService: any APIServiceProtocol & Sendable) async { #if DEBUG debugInfoSync("\n�� 开始测试腾讯云 COS Token 获取功能") let token = await getToken(apiService: apiService) if let tokenData = token { debugInfoSync("✅ Token 获取成功") debugInfoSync(" bucket: \(tokenData.bucket)") debugInfoSync(" Expiration: \(tokenData.expireTime)") debugInfoSync(" Token: \(tokenData.sessionToken.prefix(20))...") debugInfoSync(" SecretId: \(tokenData.secretId.prefix(20))...") } else { debugInfoSync("❌ Token 获取失败") } let status = await getTokenStatus() debugInfoSync("📊 Token 状态: \(status)") debugInfoSync("✅ 腾讯云 COS Token 测试完成\n") #endif } // MARK: - 内部方法(与 COSManager 保持一致) /// 清除缓存的 Token(内部方法,保持兼容性) private func clearCachedToken() { tokenService.clearCachedToken() debugInfoSync("🗑️ 清除缓存的 COS Token") } } // MARK: - 依赖注入扩展 extension COSManagerAdapter { /// 使用依赖注入创建实例(用于测试) static func createWithDependencies( tokenService: COSTokenServiceProtocol, uploadService: COSUploadServiceProtocol, configurationService: COSConfigurationServiceProtocol ) -> COSManagerAdapter { let adapter = COSManagerAdapter() // 注意:这里需要修改为使用依赖注入的初始化方式 // 由于当前设计,我们使用默认的 shared 实例 return adapter } } // MARK: - 类型别名(保持向后兼容) /// 为了保持向后兼容,将 COSManager 重命名为 COSManagerAdapter /// 这样现有代码无需修改即可使用新的实现 typealias COSManager = COSManagerAdapter