From d0f0b09f8abd29c9643e006c2189fdbd2914f324 Mon Sep 17 00:00:00 2001 From: jinyaqiu Date: Tue, 19 Aug 2025 18:53:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=B4=A0=E6=9D=90=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wake/View/Components/Upload/Avatar.swift | 131 ++++++++++++++++++----- 1 file changed, 105 insertions(+), 26 deletions(-) diff --git a/wake/View/Components/Upload/Avatar.swift b/wake/View/Components/Upload/Avatar.swift index 9f665fb..a08cd04 100644 --- a/wake/View/Components/Upload/Avatar.swift +++ b/wake/View/Components/Upload/Avatar.swift @@ -1,6 +1,7 @@ import SwiftUI import PhotosUI +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD // MARK: - Photo Picker @@ -165,6 +166,14 @@ class ImageUploader: ObservableObject { ======= >>>>>>> a207b78 (feat: 确认上传) +======= +/// 上传结果,包含原图和压缩图的上传信息 +struct UploadResults { + let original: ImageUploaderGetID.UploadResult + let compressed: ImageUploaderGetID.UploadResult +} + +>>>>>>> 5611df8 (feat: 素材上传成) /// 照片选择器,封装了系统相册选择功能 /// 使用UIViewControllerRepresentable包装PHPickerViewController,提供SwiftUI兼容的图片选择界面 struct PhotoPicker: UIViewControllerRepresentable { @@ -189,8 +198,12 @@ struct PhotoPicker: UIViewControllerRepresentable { private let uploader = ImageUploader() ======= /// 图片上传完成回调,返回上传结果或错误 +<<<<<<< HEAD var onImageUploaded: ((Result) -> Void)? >>>>>>> a207b78 (feat: 确认上传) +======= + var onImageUploaded: ((Result) -> Void)? +>>>>>>> 5611df8 (feat: 素材上传成) // MARK: - Initialization @@ -208,7 +221,7 @@ struct PhotoPicker: UIViewControllerRepresentable { selectedImages: Binding<[UIImage]>, selectionLimit: Int = 1, filter: PHPickerFilter = .images, - onImageUploaded: ((Result) -> Void)? = nil + onImageUploaded: ((Result) -> Void)? = nil ) { >>>>>>> a207b78 (feat: 确认上传) self._selectedImages = selectedImages @@ -269,14 +282,11 @@ struct PhotoPicker: UIViewControllerRepresentable { } /// 当用户完成图片选择时调用 - /// - Parameters: - /// - picker: 图片选择器实例 - /// - results: 用户选择的图片结果数组 func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { // 清空已选图片 parent.selectedImages.removeAll() - // 使用DispatchGroup管理多个异步图片加载任务 + // 使用DispatchGroup管理多个异步任务 let group = DispatchGroup() <<<<<<< HEAD var loadedImages: [Int: UIImage] = [:] @@ -284,53 +294,97 @@ struct PhotoPicker: UIViewControllerRepresentable { var lastError: Error? ======= var loadedImages: [Int: UIImage] = [:] // 用于保持图片顺序的字典 +<<<<<<< HEAD >>>>>>> a207b78 (feat: 确认上传) +======= + var uploadResults: [Int: (original: ImageUploaderGetID.UploadResult?, + compressed: ImageUploaderGetID.UploadResult?)] = [:] +>>>>>>> 5611df8 (feat: 素材上传成) // 遍历所有选中的图片 for (index, result) in results.enumerated() { group.enter() // 进入组 - // 检查是否可以加载图片 if result.itemProvider.canLoadObject(ofClass: UIImage.self) { - // 异步加载图片 result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (image, error) in +<<<<<<< HEAD if let image = image as? UIImage { <<<<<<< HEAD ======= // 将加载的图片存入字典,保持原始顺序 >>>>>>> a207b78 (feat: 确认上传) loadedImages[index] = image +======= + guard let self = self, let image = image as? UIImage else { + group.leave() + return + } + + // 1. 保存原始图片 + loadedImages[index] = image + + // 2. 压缩图片(质量压缩到50%) + guard let compressedImage = image.jpegData(compressionQuality: 0.5).flatMap(UIImage.init(data:)) else { + group.leave() + return + } + + // 3. 上传原图 + self.uploader.uploadImage(image) { [weak self] originalResult in + guard let self = self else { + group.leave() + return + } +>>>>>>> 5611df8 (feat: 素材上传成) - // 上传图片 - self?.uploader.uploadImage(image) { result in - // 在主线程中调用上传完成回调 - DispatchQueue.main.async { - switch result { - case .success(let uploadResult): - print("✅ 上传成功!fileId: \(uploadResult.fileId)") - print("📂 文件信息:") - print(" - 文件名: \(uploadResult.fileName)") - print(" - 文件大小: \(uploadResult.fileSize) 字节") - print(" - 文件URL: \(uploadResult.fileUrl)") + switch originalResult { + case .success(let originalUploadResult): + // 4. 原图上传成功后上传压缩图 + self.uploader.uploadImage(compressedImage) { compressedResult in + defer { group.leave() } + + switch compressedResult { + case .success(let compressedUploadResult): + // 保存两个上传结果 + uploadResults[index] = (originalUploadResult, compressedUploadResult) + print("✅ 原图和压缩图上传成功!") + print("📂 原图信息:") + print(" - 文件ID: \(originalUploadResult.fileId)") + print(" - 文件大小: \(originalUploadResult.fileSize) 字节") + print("📦 压缩图信息:") + print(" - 文件ID: \(compressedUploadResult.fileId)") + print(" - 文件大小: \(compressedUploadResult.fileSize) 字节") - // 调用上传完成回调 - self?.parent.onImageUploaded?(.success(uploadResult)) + // 使用MaterialService上传文件信息到后端 + MaterialService.shared.uploadMaterialInfo( + fileId: originalUploadResult.fileId, + previewFileId: compressedUploadResult.fileId + ) { success, errorMessage in + if success { + print("✅ 文件信息上传成功 素材上传成功!!!!!") + } else if let errorMessage = errorMessage { + print("❌ 文件信息上传失败: \(errorMessage)") + } + } case .failure(let error): - print("❌ 上传失败: \(error.localizedDescription)") - // 调用上传完成回调,传递错误 - self?.parent.onImageUploaded?(.failure(error)) + print("❌ 压缩图上传失败: \(error.localizedDescription)") + uploadResults[index] = (originalUploadResult, nil) } } + + case .failure(let error): + print("❌ 原图上传失败: \(error.localizedDescription)") + group.leave() } } - group.leave() // 离开组 } } else { - group.leave() // 如果无法加载图片,也离开组 + group.leave() } } +<<<<<<< HEAD // 所有图片加载完成后的处理 group.notify(queue: .main) { <<<<<<< HEAD @@ -351,6 +405,31 @@ struct PhotoPicker: UIViewControllerRepresentable { // 关闭图片选择器 >>>>>>> a207b78 (feat: 确认上传) +======= + // 所有上传任务完成后的处理 + group.notify(queue: .main) { [weak self] in + guard let self = self else { return } + + // 1. 更新选中的图片(只显示原图) + let sortedImages = loadedImages.sorted { $0.key < $1.key }.map { $0.value } + self.parent.selectedImages.append(contentsOf: sortedImages) + + // 2. 检查是否所有上传都成功 + if let firstResult = uploadResults.first?.value, + let original = firstResult.original, + let compressed = firstResult.compressed { + // 3. 如果成功,返回上传结果 + let results = UploadResults(original: original, compressed: compressed) + self.parent.onImageUploaded?(.success(results)) + } else { + // 4. 如果失败,返回错误 + self.parent.onImageUploaded?(.failure(NSError(domain: "com.wake.upload", + code: -1, + userInfo: [NSLocalizedDescriptionKey: "上传过程中出现错误"]))) + } + + // 5. 关闭图片选择器 +>>>>>>> 5611df8 (feat: 素材上传成) picker.dismiss(animated: true) } } @@ -376,7 +455,7 @@ struct AvatarUploader: View { var onUploadComplete: ((Result) -> Void)? /// 上传完成回调,返回上传结果或错误 - var onUploadComplete: ((Result) -> Void)? + var onUploadComplete: ((Result) -> Void)? // MARK: - State